Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/ois/mac/MacMouse.cpp @ 1495

Last change on this file since 1495 was 1494, checked in by rgrieder, 16 years ago
  • set the svn:eol-style property to all files so, that where ever you check out, you'll get the right line endings (had to change every file with mixed endings to windows in order to set the property)
  • Property svn:eol-style set to native
File size: 10.2 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.