00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
00061 if( !(display = XOpenDisplay(0)) )
00062 OIS_EXCEPT(E_General, "LinuxMouse::_initialize >> Error opening X!");
00063
00064
00065 if( XSelectInput(display, window, ButtonPressMask | ButtonReleaseMask | PointerMotionMask) == BadWindow )
00066 OIS_EXCEPT(E_General, "LinuxMouse::_initialize >> X error!");
00067
00068
00069 XWarpPointer(display,None,window,0,0,0,0, 6,6);
00070
00071
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
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
00121 mState.X.rel = XMouseX - oldXMouseX;
00122 mState.Y.rel = XMouseY - oldXMouseY;
00123
00124
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
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
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
00161 if( grabMouse ) {
00162 if( static_cast<LinuxInputManager*>(mCreator)->_getGrabState() ) {
00163 if( mouseFocusLost ) {
00164 grab( true );
00165 hide( hideMouse );
00166 mouseFocusLost = false;
00167 }
00168 }
00169 else {
00170 if( mouseFocusLost == false ) {
00171 grab( false );
00172 hide( false );
00173 mouseFocusLost = true;
00174 }
00175 }
00176 }
00177 }
00178
00179
00180 void LinuxMouse::_processXEvents()
00181 {
00182
00183 char mask[4] = {0,1,4,2};
00184 XEvent event;
00185
00186
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
00197
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
00236 else if( event.xbutton.button == 4 )
00237 {
00238 mState.Z.rel += 120;
00239 mMoved = true;
00240 }
00241
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 }