Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/merge/src/ois/mac/MacMouse.cpp @ 1299

Last change on this file since 1299 was 1219, checked in by rgrieder, 17 years ago

merged input branch back to trunk. Not yet tested on tardis

File size: 10.6 KB
Line 
1#include "mac/MacMouse.h"
2#include "mac/MacInputManager.h"
3#include "mac/MacHelpers.h"
4#include "OISException.h"
5#include "OISEvents.h"
6
7#include <Carbon/Carbon.h>
8
9#include <list>
10
11#include <iostream>
12
13using namespace OIS;
14
15//Events we subscribe to and remove from queue
16const EventTypeSpec mouseEvents[] = {
17        { kEventClassMouse, kEventMouseDown },
18        { kEventClassMouse, kEventMouseUp },
19        { kEventClassMouse, kEventMouseMoved },
20        { kEventClassMouse, kEventMouseDragged },
21        { kEventClassMouse, kEventMouseWheelMoved }             
22};
23
24const EventTypeSpec WinFocusAcquired [] = {{kEventClassApplication, kEventAppDeactivated}};
25
26//-------------------------------------------------------------------//
27MacMouse::MacMouse( InputManager* creator, bool buffered )
28        : Mouse(creator->inputSystemName(), buffered, 0, creator), mNeedsToRegainFocus( false )
29{
30    mouseEventRef = NULL;
31        mWindowFocusHandler = NULL;
32
33    // Get a "Univeral procedure pointer" for our callback
34    mouseUPP = NewEventHandlerUPP(MouseWrapper);
35        mWindowFocusListener = NewEventHandlerUPP(WindowFocusChanged);
36
37        static_cast<MacInputManager*>(mCreator)->_setMouseUsed(true);
38}
39
40MacMouse::~MacMouse()
41{
42    if(mouseEventRef != NULL)
43                RemoveEventHandler(mouseEventRef);
44
45        if(mWindowFocusHandler != NULL)
46                RemoveEventHandler(mWindowFocusHandler);
47       
48        DisposeEventHandlerUPP(mouseUPP);
49        DisposeEventHandlerUPP(mWindowFocusListener);
50       
51        // Restore Mouse
52        CGAssociateMouseAndMouseCursorPosition(TRUE);
53        CGDisplayShowCursor(kCGDirectMainDisplay);
54
55        static_cast<MacInputManager*>(mCreator)->_setMouseUsed(false);
56}
57
58void MacMouse::_initialize()
59{
60        mState.clear();
61        mTempState.clear();
62        mMouseWarped = false;
63       
64        // Hide OS Mouse
65        CGDisplayHideCursor(kCGDirectMainDisplay);
66
67        MacInputManager* im = static_cast<MacInputManager*>(mCreator);
68        WindowRef win = im->_getWindow();
69       
70        if(win)
71        {
72                Rect clipRect = {0.0f, 0.0f, 0.0f, 0.0f};
73                GetWindowBounds(win, kWindowContentRgn, &clipRect);
74               
75                CGPoint warpPoint;
76                warpPoint.x = ((clipRect.right - clipRect.left) / 2) + clipRect.left;
77                warpPoint.y = ((clipRect.bottom - clipRect.top) / 2) + clipRect.top;
78                CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, warpPoint); //Place at display origin
79               
80                mMouseWarped = true;
81        }
82
83        //Now that mouse is warped, start listening for events
84        EventTargetRef event = ((MacInputManager*)mCreator)->_getEventTarget();
85   
86        if(mouseEventRef != NULL)
87                RemoveEventHandler(mouseEventRef);
88               
89        if(mWindowFocusHandler != NULL)
90                RemoveEventHandler(mWindowFocusHandler);
91
92        mouseEventRef = mWindowFocusHandler = NULL;
93
94        if(InstallEventHandler(event, mouseUPP, GetEventTypeCount(mouseEvents), mouseEvents, this, &mouseEventRef) != noErr)
95                OIS_EXCEPT( E_General, "MacMouse::_initialize >> Error loading Mouse event handler" );
96
97        if(InstallEventHandler(event, mWindowFocusListener, GetEventTypeCount(WinFocusAcquired), WinFocusAcquired, this, &mWindowFocusHandler) != noErr)
98                OIS_EXCEPT( E_General, "MacMouse::_initialize >> Error loading Mouse event handler" );         
99
100        //Lock OS Mouse movement
101        mNeedsToRegainFocus = false;
102        CGAssociateMouseAndMouseCursorPosition(FALSE);
103}
104
105OSStatus MacMouse::WindowFocusChanged(EventHandlerCallRef nextHandler, EventRef event, void* macMouse)
106{
107        //std::cout << "Window Focus Changed\n";
108
109        MacMouse* _this = static_cast<MacMouse*>(macMouse);
110    if (_this)
111        {
112                _this->mNeedsToRegainFocus = true;
113                CGAssociateMouseAndMouseCursorPosition(TRUE);
114
115        // propagate the event down the chain
116        return CallNextEventHandler(nextHandler, event);
117    }
118    else
119        OIS_EXCEPT(E_General, "MouseWrapper >> Being called by something other than our event handler!");
120}
121
122void MacMouse::setBuffered( bool buffered )
123{
124        mBuffered = buffered;
125}
126
127void MacMouse::capture()
128{
129        mState.X.rel = 0;
130        mState.Y.rel = 0;
131        mState.Z.rel = 0;
132           
133        if(mTempState.X.rel || mTempState.Y.rel || mTempState.Z.rel)
134        {
135                //printf("%i %i %i\n\n", mTempState.X.rel, mTempState.Y.rel, mTempState.Z.rel);
136
137                //Set new relative motion values
138                mState.X.rel = mTempState.X.rel;
139                mState.Y.rel = mTempState.Y.rel;
140                mState.Z.rel = mTempState.Z.rel;
141               
142                //Update absolute position
143                mState.X.abs += mTempState.X.rel;
144                mState.Y.abs += mTempState.Y.rel;
145               
146                if(mState.X.abs > mState.width)
147                        mState.X.abs = mState.width;
148                else if(mState.X.abs < 0)
149                        mState.X.abs = 0;
150
151                if(mState.Y.abs > mState.height)
152                        mState.Y.abs = mState.height;
153                else if(mState.Y.abs < 0)
154                        mState.Y.abs = 0;
155                       
156                mState.Z.abs += mTempState.Z.rel;
157               
158                //Fire off event
159                if(mListener && mBuffered)
160                        mListener->mouseMoved(MouseEvent(this, mState));
161        }
162
163        mTempState.clear();
164}
165
166void MacMouse::_mouseCallback( EventRef theEvent )
167{
168        OSStatus result = eventNotHandledErr;
169    UInt32 kind = GetEventKind (theEvent);
170
171        switch(kind)
172        {
173                case kEventMouseDragged:
174                case kEventMouseMoved:
175                {
176                        //HIPoint location = {0.0f, 0.0f};
177                        HIPoint delta = {0.0f, 0.0f};
178                        //Rect clipRect = {0.0f, 0.0f, 0.0f, 0.0f};
179                       
180                        if(mNeedsToRegainFocus)
181                                break;
182
183                        // Capture the parameters
184                        // TODO: Look into HIViewNewTrackingArea
185                        //GetEventParameter(theEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(HIPoint), NULL, &location);
186                        GetEventParameter(theEvent, kEventParamMouseDelta, typeHIPoint, NULL, sizeof(HIPoint), NULL, &delta);
187                       
188                        // Mouse X and Y are the position on the screen,
189                        // startng from top-left at 0,0 caps at full monitor resolution
190                       
191                        // If we have a window we need to return adjusted coordinates
192                        // If not, just use raw coordinates - only do this if showing OS mouse
193                        //MacInputManager* im = static_cast<MacInputManager*>(mCreator);
194                        //WindowRef win = im->_getWindow();
195                       
196                        //if(win != NULL)
197                        //{
198                        //      GetWindowBounds(win, kWindowContentRgn, &clipRect);
199                        //}
200            //else
201            //{
202            //    clipRect.right = mState.width;
203            //    clipRect.bottom = mState.height;
204            //}
205               
206            // clip the mouse, absolute positioning
207            //if (location.x <= clipRect.left)
208                        //      mState.X.abs = 0;
209                        //else if(location.x >= clipRect.right)
210                        //      mState.X.abs = clipRect.right - clipRect.left;
211                        //else
212                        //      mState.X.abs = location.x - clipRect.left;
213                       
214                        //if (location.y <= clipRect.top)
215                        //      mState.Y.abs = 0;
216                        //else if(location.y >= clipRect.bottom)
217                        //      mState.Y.abs = clipRect.bottom - clipRect.top;
218                        //else
219                        //      mState.Y.abs = location.y - clipRect.top;
220                       
221                        // relative positioning
222                        if(!mMouseWarped)
223                        {
224                                mTempState.X.rel += delta.x;
225                                mTempState.Y.rel += delta.y;
226                        }
227                       
228                        mMouseWarped = false;
229
230                        break;
231                }
232                case kEventMouseDown:
233                {
234                        EventMouseButton button = 0;
235                        int mouseButton = 3;
236                        UInt32 modifiers = 0;
237                       
238                        if(mNeedsToRegainFocus)
239                                break;
240
241                        // Capture parameters
242                        GetEventParameter(theEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof(EventMouseButton), NULL, &button);
243                        GetEventParameter(theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
244                       
245                        if((button == kEventMouseButtonTertiary) || ((button == kEventMouseButtonPrimary) && (modifiers & optionKey)))
246                        {
247                                mouseButton = 2;
248                                mState.buttons |= 1 << mouseButton;
249                        }
250            else if((button == kEventMouseButtonSecondary) || ((button == kEventMouseButtonPrimary) && (modifiers & controlKey)))
251            {   
252                mouseButton = 1;
253                mState.buttons |= 1 << mouseButton;
254            }
255            else if(button == kEventMouseButtonPrimary)
256            {
257                mouseButton = 0;
258                mState.buttons |= 1 << mouseButton;
259            }
260
261            if( mListener && mBuffered )
262                mListener->mousePressed( MouseEvent( this, mState ), (MouseButtonID)mouseButton );
263
264            break;
265                }
266                case kEventMouseUp:
267                {
268                        EventMouseButton button = 0;
269                        int mouseButton = 3;
270                        UInt32 modifiers = 0;
271                       
272                        if(mNeedsToRegainFocus)
273                        {
274                                mNeedsToRegainFocus = false;
275                                CGAssociateMouseAndMouseCursorPosition(false);
276                               
277                                MacInputManager* im = static_cast<MacInputManager*>(mCreator);
278                                WindowRef win = im->_getWindow();
279                               
280                                if(win)
281                                {
282                                        Rect clipRect = {0.0f, 0.0f, 0.0f, 0.0f};
283                                        GetWindowBounds(win, kWindowContentRgn, &clipRect);
284                                       
285                                        CGPoint warpPoint;
286                                        warpPoint.x = ((clipRect.right - clipRect.left) / 2) + clipRect.left;
287                                        warpPoint.y = ((clipRect.bottom - clipRect.top) / 2) + clipRect.top;
288                                        CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, warpPoint); //Place at display origin
289                                       
290                                        CGDisplayHideCursor(kCGDirectMainDisplay);
291                                       
292                                        mMouseWarped = true;
293                                }
294                               
295                                //Once we regain focus, we do not really know what state all the buttons are in - for now, set to not pressed. todo, check current status
296                                //compare against old status, and send off any needed events
297                                mState.buttons = 0;
298                               
299                                break;
300                        }
301                       
302                        // Capture parameters
303                        GetEventParameter(theEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof(EventMouseButton), NULL, &button);
304                        GetEventParameter(theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
305                       
306                        if ((button == kEventMouseButtonTertiary) || ((button == kEventMouseButtonPrimary) && (modifiers & optionKey)))
307                        {
308                                mouseButton = 2;
309                                mState.buttons &= ~(1 << mouseButton);
310                        }
311            else if ((button == kEventMouseButtonSecondary) || ((button == kEventMouseButtonPrimary) && (modifiers & controlKey)))
312            {   
313                mouseButton = 1;
314                mState.buttons &= ~(1 << mouseButton);
315            }
316            else if (button == kEventMouseButtonPrimary)
317            {
318                mouseButton = 0;
319                mState.buttons &= ~(1 << mouseButton);
320            }
321
322            if( mListener && mBuffered )
323                mListener->mouseReleased( MouseEvent( this, mState ), (MouseButtonID)mouseButton );
324
325            break;
326                }
327                case kEventMouseWheelMoved:
328                {
329                        SInt32 wheelDelta = 0;
330                        EventMouseWheelAxis     wheelAxis = 0; 
331
332                        // Capture parameters
333                        GetEventParameter(theEvent, kEventParamMouseWheelAxis, typeMouseWheelAxis, NULL, sizeof(EventMouseWheelAxis), NULL, &wheelAxis);
334                        GetEventParameter(theEvent, kEventParamMouseWheelDelta, typeSInt32, NULL, sizeof(SInt32), NULL, &wheelDelta);
335                       
336                        // If the Y axis of the wheel changed, then update the Z
337                        // Does OIS care about the X wheel axis?
338                        if(wheelAxis == kEventMouseWheelAxisY)
339                                mTempState.Z.rel += (wheelDelta * 60);
340
341            break;
342                }
343                default:
344                        break;
345        }   
346}
Note: See TracBrowser for help on using the repository browser.