Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/mac_osx/src/external/ois/linux/LinuxMouse.cpp @ 8060

Last change on this file since 8060 was 7506, checked in by rgrieder, 14 years ago

Updated OIS source files to its current SVN trunk (r26).

  • Property svn:eol-style set to native
File size: 7.3 KB
Line 
1/*
2The zlib/libpng License
3
4Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
5
6This software is provided 'as-is', without any express or implied warranty. In no event will
7the authors be held liable for any damages arising from the use of this software.
8
9Permission is granted to anyone to use this software for any purpose, including commercial
10applications, and to alter it and redistribute it freely, subject to the following
11restrictions:
12
13    1. The origin of this software must not be misrepresented; you must not claim that
14                you wrote the original software. If you use this software in a product,
15                an acknowledgment in the product documentation would be appreciated but is
16                not required.
17
18    2. Altered source versions must be plainly marked as such, and must not be
19                misrepresented as being the original software.
20
21    3. This notice may not be removed or altered friosom any source distribution.
22*/
23#include "linux/LinuxMouse.h"
24#include "linux/LinuxInputManager.h"
25#include "OISException.h"
26#include "OISEvents.h"
27
28using namespace OIS;
29
30//-------------------------------------------------------------------//
31LinuxMouse::LinuxMouse(InputManager* creator, bool buffered, bool grab, bool hide)
32        : Mouse(creator->inputSystemName(), buffered, 0, creator)
33{
34        display = 0;
35        window = 0;
36        cursor = 0;
37
38        grabMouse = grab;
39        hideMouse = hide;
40
41        static_cast<LinuxInputManager*>(mCreator)->_setMouseUsed(true);
42}
43
44//-------------------------------------------------------------------//
45void LinuxMouse::_initialize()
46{
47        //Clear old state
48        mState.clear();
49        mMoved  = false;
50        mWarped = false;
51
52        //6 is just some random value... hardly ever would anyone have a window smaller than 6
53        oldXMouseX = oldXMouseY = 6;
54        oldXMouseZ = 0;
55
56        if( display ) XCloseDisplay(display);
57        display = 0;
58        window = static_cast<LinuxInputManager*>(mCreator)->_getWindow();
59
60        //Create our local X mListener connection
61        if( !(display = XOpenDisplay(0)) )
62                OIS_EXCEPT(E_General, "LinuxMouse::_initialize >> Error opening X!");
63
64        //Set it to recieve Mouse Input events
65        if( XSelectInput(display, window, ButtonPressMask | ButtonReleaseMask | PointerMotionMask) == BadWindow )
66                OIS_EXCEPT(E_General, "LinuxMouse::_initialize >> X error!");
67
68        //Warp mouse inside window
69        XWarpPointer(display,None,window,0,0,0,0, 6,6);
70
71        //Create a blank cursor:
72        Pixmap bm_no;
73        XColor black, dummy;
74        Colormap colormap;
75        static char no_data[] = { 0,0,0,0,0,0,0,0 };
76
77        colormap = DefaultColormap( display, DefaultScreen(display) );
78        XAllocNamedColor( display, colormap, "black", &black, &dummy );
79        bm_no = XCreateBitmapFromData( display, window, no_data, 8, 8 );
80        cursor = XCreatePixmapCursor( display, bm_no, bm_no, &black, &black, 0, 0 );
81
82        grab( grabMouse );
83        hide( hideMouse );
84
85        mouseFocusLost = false;
86}
87
88//-------------------------------------------------------------------//
89LinuxMouse::~LinuxMouse()
90{
91        if( display )
92        {
93                grab(false);
94                hide(false);
95                XFreeCursor(display, cursor);
96                XCloseDisplay(display);
97        }
98
99        static_cast<LinuxInputManager*>(mCreator)->_setMouseUsed(false);
100}
101
102//-------------------------------------------------------------------//
103void LinuxMouse::setBuffered(bool buffered)
104{
105        mBuffered = buffered;
106}
107
108//-------------------------------------------------------------------//
109void LinuxMouse::capture()
110{
111        //Clear out last frames values
112        mState.X.rel = 0;
113        mState.Y.rel = 0;
114        mState.Z.rel = 0;
115
116        _processXEvents();
117
118        mWarped = false;
119
120        if( mMoved == true )
121        {
122                if( mBuffered && mListener )
123                        mListener->mouseMoved( MouseEvent( this, mState ) );
124
125                mMoved = false;
126        }
127
128        //Check for losing/gaining mouse grab focus (alt-tab, etc)
129        if( grabMouse )
130        {
131                if( static_cast<LinuxInputManager*>(mCreator)->_getGrabState() )
132                {
133                        if( mouseFocusLost )    //We just regained mouse grab focus
134                        {
135                                grab( true );
136                                hide( hideMouse );
137                                mouseFocusLost = false;
138                        }
139                }
140                else
141                {
142                        if( mouseFocusLost == false )   //We just lost mouse grab focus
143                        {
144                                grab( false );
145                                hide( false );
146                                mouseFocusLost = true;
147                        }
148                }
149        }
150}
151
152//-------------------------------------------------------------------//
153void LinuxMouse::_processXEvents()
154{
155        //X11 Button Events: 1=left 2=middle 3=right; Our Bit Postion: 1=Left 2=Right 3=Middle
156        char mask[4] = {0,1,4,2};
157        XEvent event;
158
159        //Poll x11 for events mouse events
160        while( XPending(display) > 0 ) 
161        {
162                XNextEvent(display, &event);
163
164                if( event.type == MotionNotify )
165                {       //Mouse moved
166                        //Ignore out of bounds mouse if we just warped
167                        if( mWarped )
168                        {
169                                if(event.xmotion.x < 5 || event.xmotion.x > mState.width - 5 ||
170                                   event.xmotion.y < 5 || event.xmotion.y > mState.height - 5)
171                                        continue;
172                        }
173
174                        //Compute this frames Relative X & Y motion
175                        int dx = event.xmotion.x - oldXMouseX;
176                        int dy = event.xmotion.y - oldXMouseY;
177               
178                        //Store old values for next time to compute relative motion
179                        oldXMouseX = event.xmotion.x;
180                        oldXMouseY = event.xmotion.y;
181
182                        mState.X.abs += dx;
183                        mState.Y.abs += dy;
184                        mState.X.rel += dx;
185                        mState.Y.rel += dy;
186
187                        //Check to see if we are grabbing the mouse to the window (requires clipping and warping)
188                        if( grabMouse )
189                        {
190                                if( mState.X.abs < 0 )
191                                        mState.X.abs = 0;
192                                else if( mState.X.abs > mState.width )
193                                        mState.X.abs = mState.width;
194
195                                if( mState.Y.abs < 0 )
196                                        mState.Y.abs = 0;
197                                else if( mState.Y.abs > mState.height )
198                                        mState.Y.abs = mState.height;
199
200                                if( mouseFocusLost == false )
201                                {
202                                        //Keep mouse in window (fudge factor)
203                                        if(event.xmotion.x < 5 || event.xmotion.x > mState.width - 5 ||
204                                           event.xmotion.y < 5 || event.xmotion.y > mState.height - 5 )
205                                        {
206                                                oldXMouseX = mState.width >> 1;  //center x
207                                                oldXMouseY = mState.height >> 1; //center y
208                                                XWarpPointer(display, None, window, 0, 0, 0, 0, oldXMouseX, oldXMouseY);
209                                                mWarped = true;
210                                        }
211                                }
212                        }
213                        mMoved = true;
214                }
215                else if( event.type == ButtonPress )
216                {       //Button down
217                        static_cast<LinuxInputManager*>(mCreator)->_setGrabState(true);
218
219                        if( event.xbutton.button < 4 )
220                        {
221                                mState.buttons |= mask[event.xbutton.button];
222                                if( mBuffered && mListener )
223                                        if( mListener->mousePressed( MouseEvent( this, mState ),
224                                                (MouseButtonID)(mask[event.xbutton.button] >> 1)) == false )
225                                                return;
226                        }
227                }
228                else if( event.type == ButtonRelease )
229                {       //Button up
230                        if( event.xbutton.button < 4 )
231                        {
232                                mState.buttons &= ~mask[event.xbutton.button];
233                                if( mBuffered && mListener )
234                                        if( mListener->mouseReleased( MouseEvent( this, mState ),
235                                                (MouseButtonID)(mask[event.xbutton.button] >> 1)) == false )
236                                                return;
237                        }
238                        //The Z axis gets pushed/released pair message (this is up)
239                        else if( event.xbutton.button == 4 )
240                        {
241                                mState.Z.rel += 120;
242                                mState.Z.abs += 120;
243                                mMoved = true;
244                        }
245                        //The Z axis gets pushed/released pair message (this is down)
246                        else if( event.xbutton.button == 5 )
247                        {
248                                mState.Z.rel -= 120;
249                                mState.Z.abs -= 120;
250                                mMoved = true;
251                        }
252                }
253        }
254}
255
256//-------------------------------------------------------------------//
257void LinuxMouse::grab(bool grab)
258{
259        if( grab )
260                XGrabPointer(display, window, True, 0, GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
261        else
262                XUngrabPointer(display, CurrentTime);
263}
264
265//-------------------------------------------------------------------//
266void LinuxMouse::hide(bool hide)
267{
268        if( hide )
269                XDefineCursor(display, window, cursor);
270        else
271                XUndefineCursor(display, window);
272}
Note: See TracBrowser for help on using the repository browser.