E:/Download/ois-1.0RC1/src/linux/LinuxMouse.cpp

Go to the documentation of this file.
00001 /*
00002 The zlib/libpng License
00003 
00004 Copyright (c) 2006 Phillip Castaneda (pjcast -- www.wreckedgames.com)
00005 
00006 This software is provided 'as-is', without any express or implied warranty. In no event will
00007 the authors be held liable for any damages arising from the use of this software.
00008 
00009 Permission is granted to anyone to use this software for any purpose, including commercial 
00010 applications, and to alter it and redistribute it freely, subject to the following
00011 restrictions:
00012 
00013     1. The origin of this software must not be misrepresented; you must not claim that 
00014                 you wrote the original software. If you use this software in a product, 
00015                 an acknowledgment in the product documentation would be appreciated but is 
00016                 not required.
00017 
00018     2. Altered source versions must be plainly marked as such, and must not be 
00019                 misrepresented as being the original software.
00020 
00021     3. This notice may not be removed or altered friosom any source distribution.
00022 */
00023 #include "linux/LinuxMouse.h"
00024 #include "linux/LinuxInputManager.h"
00025 #include "OISException.h"
00026 #include "OISEvents.h"
00027 
00028 using namespace OIS;
00029 
00030 //-------------------------------------------------------------------//
00031 LinuxMouse::LinuxMouse(InputManager* creator, bool buffered, bool grab, bool hide)
00032 {
00033         mCreator = creator;
00034         mBuffered = buffered;
00035         mType = OISMouse;
00036         listener = 0;
00037         display = 0;
00038         window = 0;
00039         cursor = 0;
00040 
00041         grabMouse = grab;
00042         hideMouse = hide;
00043 }
00044 
00045 //-------------------------------------------------------------------//
00046 void LinuxMouse::_initialize()
00047 {
00048         //Clear old state
00049         mState.clear();
00050         mMoved  = false;
00051         mWarped = false;
00052 
00053         oldXMouseX = oldXMouseY = XMouseX = XMouseY = 6;
00054         oldXMouseZ = 0;
00055 
00056         if( display ) XCloseDisplay(display);
00057         display = 0;
00058         window = static_cast<LinuxInputManager*>(mCreator)->_getWindow();
00059 
00060         //Create our local X listener connection
00061         if( !(display = XOpenDisplay(0)) )
00062                 OIS_EXCEPT(E_General, "LinuxMouse::_initialize >> Error opening X!");
00063 
00064         //Set it to recieve Mouse Input events
00065         if( XSelectInput(display, window, ButtonPressMask | ButtonReleaseMask | PointerMotionMask) == BadWindow )
00066                 OIS_EXCEPT(E_General, "LinuxMouse::_initialize >> X error!");
00067 
00068         //Warp mouse inside window
00069         XWarpPointer(display,None,window,0,0,0,0, 6,6);
00070 
00071         //Create a blank cursor:
00072         Pixmap bm_no;
00073         XColor black, dummy;
00074         Colormap colormap;
00075         static char no_data[] = { 0,0,0,0,0,0,0,0 };
00076 
00077         colormap = DefaultColormap( display, DefaultScreen(display) );
00078         XAllocNamedColor( display, colormap, "black", &black, &dummy );
00079         bm_no = XCreateBitmapFromData( display, window, no_data, 8, 8 );
00080         cursor = XCreatePixmapCursor( display, bm_no, bm_no, &black, &black, 0, 0 );
00081 
00082         grab( grabMouse );
00083         hide( hideMouse );
00084 
00085         mouseFocusLost = false;
00086 }
00087 
00088 //-------------------------------------------------------------------//
00089 LinuxMouse::~LinuxMouse()
00090 {
00091         if( display )
00092         {
00093                 grab(false);
00094                 hide(false);
00095                 XFreeCursor(display, cursor);
00096                 XCloseDisplay(display);
00097         }
00098 }
00099 
00100 //-------------------------------------------------------------------//
00101 void LinuxMouse::setBuffered(bool buffered)
00102 {
00103         mBuffered = buffered;
00104 }
00105 
00106 //-------------------------------------------------------------------//
00107 void LinuxMouse::capture()
00108 {
00109         //Clear out last frames values
00110         mState.X.rel = 0;
00111         mState.Y.rel = 0;
00112         mState.Z.rel = 0;
00113 
00114         _processXEvents();
00115 
00116         mWarped = false;
00117 
00118         if( mMoved == true )
00119         {
00120                 //Compute this frames Relative X & Y motion
00121                 mState.X.rel = XMouseX - oldXMouseX;
00122                 mState.Y.rel = XMouseY - oldXMouseY;
00123                 
00124                 //Store old values for next time to compute relative motion
00125                 oldXMouseX = XMouseX;
00126                 oldXMouseY = XMouseY;
00127 
00128                 mState.X.abs += mState.X.rel;
00129                 mState.Y.abs += mState.Y.rel;
00130                 mState.Z.abs += mState.Z.rel;
00131 
00132                 if( grabMouse )
00133                 {
00134                         //We only need to clip when we are warping mouse around
00135                         if( mState.X.abs < 0 ) mState.X.abs = 0;
00136                         else if( mState.X.abs > mState.width ) mState.X.abs = mState.width;
00137 
00138                         if( mState.Y.abs < 0 ) mState.Y.abs = 0;
00139                         else if( mState.Y.abs > mState.height ) mState.Y.abs = mState.height;
00140 
00141                         if( mouseFocusLost == false )
00142                         {
00143                                 //Keep mouse in window (fudge factor)
00144                                 if(XMouseX<5 || XMouseX>mState.width-5 || XMouseY<5 || XMouseY>mState.height-5 )
00145                                 {
00146                                         oldXMouseX = XMouseX = mState.width >> 1;
00147                                         oldXMouseY = XMouseY = mState.height >> 1;
00148                                         XWarpPointer(display,None,window,0,0,0,0,XMouseX, XMouseY);
00149                                         mWarped = true;
00150                                 }
00151                         }
00152                 }
00153 
00154                 if( mBuffered && listener )
00155                         listener->mouseMoved( MouseEvent( this, mState ) );
00156 
00157                 mMoved = false;
00158         }
00159 
00160         //Check for losing/gaining mouse grab focus (alt-tab, etc)
00161         if( grabMouse ) {
00162                 if( static_cast<LinuxInputManager*>(mCreator)->_getGrabState() ) {
00163                         if( mouseFocusLost ) { //We just regained mouse grab focus
00164                                 grab( true );
00165                                 hide( hideMouse );
00166                                 mouseFocusLost = false;
00167                         }
00168                 }
00169                 else {
00170                         if( mouseFocusLost == false ) {//We just lost mouse grab focus
00171                                 grab( false );
00172                                 hide( false );
00173                                 mouseFocusLost = true;
00174                         }
00175                 }
00176         }
00177 }
00178 
00179 //-------------------------------------------------------------------//
00180 void LinuxMouse::_processXEvents()
00181 {
00182         //X11 Button Events: 1=left 2=middle 3=right; Our Bit Postion: 1=Left 2=Right 3=Middle
00183         char mask[4] = {0,1,4,2};
00184         XEvent event;
00185 
00186         //Poll x11 for events mouse events
00187         while( XPending(display) > 0 ) 
00188         {
00189 
00190                 XNextEvent(display, &event);
00191                 if( event.type == MotionNotify )
00192                 {
00193                         XMouseX = event.xmotion.x;
00194                         XMouseY = event.xmotion.y;
00195 
00196                         //Mouse can sometimes get bad data when warping,
00197                         // so compensate (kindof a hack.. happens with long delays between capture's)
00198                         if( mWarped && grabMouse )
00199                         {
00200                                 if(XMouseX<5 || XMouseX>mState.width-5) {
00201                                         XMouseX = oldXMouseX;
00202                                         continue;
00203                                 }
00204                                 else if(XMouseY<5 || XMouseY>mState.height-5) {
00205                                         XMouseY = oldXMouseY;
00206                                         continue;
00207                                 }
00208                         }
00209 
00210                         mMoved = true;
00211                 }
00212                 else if( event.type == ButtonPress )
00213                 {
00214                         static_cast<LinuxInputManager*>(mCreator)->_setGrabState(true);
00215 
00216                         if( event.xbutton.button < 4 )
00217                         {
00218                                 mState.buttons |= mask[event.xbutton.button];
00219                                 if( mBuffered && listener )
00220                                         if( listener->mousePressed( MouseEvent( this, mState ),
00221                                                 (MouseButtonID)(mask[event.xbutton.button] >> 1)) == false )
00222                                                 return;
00223                         }
00224                 }
00225                 else if( event.type == ButtonRelease )
00226                 {
00227                         if( event.xbutton.button < 4 )
00228                         {
00229                                 mState.buttons &= ~mask[event.xbutton.button];
00230                                 if( mBuffered && listener )
00231                                         if( listener->mouseReleased( MouseEvent( this, mState ),
00232                                                 (MouseButtonID)(mask[event.xbutton.button] >> 1)) == false )
00233                                                 return;
00234                         }
00235                         //The Z axis gets pushed/released pair message (this is up)
00236                         else if( event.xbutton.button == 4 )
00237                         {
00238                                 mState.Z.rel += 120;
00239                                 mMoved = true;
00240                         }
00241                         //The Z axis gets pushed/released pair message (this is down)
00242                         else if( event.xbutton.button == 5 )
00243                         {
00244                                 mState.Z.rel -= 120;
00245                                 mMoved = true;
00246                         }
00247                 }
00248         }
00249 }
00250 
00251 //-------------------------------------------------------------------//
00252 void LinuxMouse::grab(bool grab)
00253 {
00254         if( grab )
00255                 XGrabPointer(display, window, True, 0, GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
00256         else
00257                 XUngrabPointer(display, CurrentTime);
00258 }
00259 
00260 //-------------------------------------------------------------------//
00261 void LinuxMouse::hide(bool hide)
00262 {
00263         if( hide )
00264                 XDefineCursor(display, window, cursor);
00265         else
00266                 XUndefineCursor(display, window);
00267 }

Generated on Sat Dec 1 20:13:51 2007 for OIS by  doxygen 1.5.4