Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/ois/linux/LinuxMouse.cpp @ 2227

Last change on this file since 2227 was 1505, checked in by rgrieder, 16 years ago

f* svn: It doesn't even inform you if you attempt to set a non existing property. It is svn:eol-style and not eol-style when using the command by the way…

  • 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                        mState.X.rel = event.xmotion.x - oldXMouseX;
176                        mState.Y.rel = 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 += mState.X.rel;
183                        mState.Y.abs += mState.Y.rel;
184
185                        //Check to see if we are grabbing the mouse to the window (requires clipping and warping)
186                        if( grabMouse )
187                        {
188                                if( mState.X.abs < 0 )
189                                        mState.X.abs = 0;
190                                else if( mState.X.abs > mState.width )
191                                        mState.X.abs = mState.width;
192
193                                if( mState.Y.abs < 0 )
194                                        mState.Y.abs = 0;
195                                else if( mState.Y.abs > mState.height )
196                                        mState.Y.abs = mState.height;
197
198                                if( mouseFocusLost == false )
199                                {
200                                        //Keep mouse in window (fudge factor)
201                                        if(event.xmotion.x < 5 || event.xmotion.x > mState.width - 5 ||
202                                           event.xmotion.y < 5 || event.xmotion.y > mState.height - 5 )
203                                        {
204                                                oldXMouseX = mState.width >> 1;  //center x
205                                                oldXMouseY = mState.height >> 1; //center y
206                                                XWarpPointer(display, None, window, 0, 0, 0, 0, oldXMouseX, oldXMouseY);
207                                                mWarped = true;
208                                        }
209                                }
210                        }
211                        mMoved = true;
212                }
213                else if( event.type == ButtonPress )
214                {       //Button down
215                        static_cast<LinuxInputManager*>(mCreator)->_setGrabState(true);
216
217                        if( event.xbutton.button < 4 )
218                        {
219                                mState.buttons |= mask[event.xbutton.button];
220                                if( mBuffered && mListener )
221                                        if( mListener->mousePressed( MouseEvent( this, mState ),
222                                                (MouseButtonID)(mask[event.xbutton.button] >> 1)) == false )
223                                                return;
224                        }
225                }
226                else if( event.type == ButtonRelease )
227                {       //Button up
228                        if( event.xbutton.button < 4 )
229                        {
230                                mState.buttons &= ~mask[event.xbutton.button];
231                                if( mBuffered && mListener )
232                                        if( mListener->mouseReleased( MouseEvent( this, mState ),
233                                                (MouseButtonID)(mask[event.xbutton.button] >> 1)) == false )
234                                                return;
235                        }
236                        //The Z axis gets pushed/released pair message (this is up)
237                        else if( event.xbutton.button == 4 )
238                        {
239                                mState.Z.rel += 120;
240                                mState.Z.abs += 120;
241                                mMoved = true;
242                        }
243                        //The Z axis gets pushed/released pair message (this is down)
244                        else if( event.xbutton.button == 5 )
245                        {
246                                mState.Z.rel -= 120;
247                                mState.Z.abs -= 120;
248                                mMoved = true;
249                        }
250                }
251        }
252}
253
254//-------------------------------------------------------------------//
255void LinuxMouse::grab(bool grab)
256{
257        if( grab )
258                XGrabPointer(display, window, True, 0, GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
259        else
260                XUngrabPointer(display, CurrentTime);
261}
262
263//-------------------------------------------------------------------//
264void LinuxMouse::hide(bool hide)
265{
266        if( hide )
267                XDefineCursor(display, window, cursor);
268        else
269                XUndefineCursor(display, window);
270}
Note: See TracBrowser for help on using the repository browser.