00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "cxutils/mouse.h"
00042 #include <limits.h>
00043 #ifdef WIN32
00044 #define _WIN32_WINNT 0x0501
00045 #include <windows.h>
00046 #else
00047 #include <X11/Xlib.h>
00048 #include <X11/Xutil.h>
00049 #include <X11/extensions/XTest.h>
00050 #endif
00051
00052 using namespace CxUtils;
00053
00063 bool Mouse::IsButtonDown(const Mouse::Button button)
00064 {
00065 bool result = false;
00066 #ifdef WIN32
00067 SHORT _button = 0;
00068 if(button == Any)
00069 {
00070
00071 for(int b = 0x01; b <= 0x06; b++)
00072 {
00073 if(b != 0x03)
00074 {
00075 if(IsButtonDown((Button)b))
00076 {
00077 result = true;
00078 }
00079 }
00080 }
00081 }
00082 else
00083 {
00084 _button = ::GetAsyncKeyState(button);
00085 if( (_button & 0x8000) != 0 )
00086 {
00087 result = true;
00088 }
00089 }
00090 #else
00091 Window root, child;
00092 int dummyx, dummyy;
00093 int _x, _y;
00094 unsigned int mask = 0;
00095 Display* display = XOpenDisplay(NULL);
00096 if(XQueryPointer(display,
00097 DefaultRootWindow(display),
00098 &root,
00099 &child,
00100 &_x,
00101 &_y,
00102 &dummyx,
00103 &dummyy,
00104 &mask) != 0)
00105 {
00106 unsigned int bmask = Button1Mask | Button2Mask | Button3Mask;
00107 if( (mask & bmask) > 0)
00108 {
00109 result = true;
00110 }
00111 }
00112 XCloseDisplay(display);
00113 #endif
00114 return result;
00115 }
00116
00117
00125 Mouse::Button Mouse::GetCurrentButton()
00126 {
00127 Mouse::Button pressed = Invalid;
00128 #ifdef WIN32
00129
00130 for(int b = 0x01; b <= 0x06; b++)
00131 {
00132 if(b != 0x03)
00133 {
00134 if(IsButtonDown((Button)b))
00135 {
00136 pressed = (Button)b;
00137 break;
00138 }
00139 }
00140 }
00141 #else
00142 Window root, child;
00143 int dummyx, dummyy;
00144 int _x, _y;
00145 unsigned int mask = 0;
00146 Display* display = XOpenDisplay(NULL);
00147 if(XQueryPointer(display,
00148 DefaultRootWindow(display),
00149 &root,
00150 &child,
00151 &_x,
00152 &_y,
00153 &dummyx,
00154 &dummyy,
00155 &mask) != 0)
00156 {
00157 if( (mask & Button1Mask) > 0)
00158 {
00159 pressed = LeftButton;
00160 }
00161 else if( (mask & Button2Mask) > 0)
00162 {
00163 pressed = MiddleButton;
00164 }
00165 else if( (mask & Button3Mask) > 0)
00166 {
00167 pressed = RightButton;
00168 }
00169 }
00170 XCloseDisplay(display);
00171 #endif
00172
00173 return pressed;
00174 }
00175
00176
00188 bool Mouse::FakeButtonPress(const Mouse::Button button,
00189 const bool releaseFlag)
00190 {
00191 bool result = false;
00192 if(button != Invalid && button != Any)
00193 {
00194 #ifdef WIN32
00195 ::INPUT m;
00196 m.type = INPUT_MOUSE;
00197 m.mi.dx = 0;
00198 m.mi.dy = 0;
00199 m.mi.mouseData = 0;
00200 m.mi.time = 0;
00201 switch(button)
00202 {
00203 case Mouse::RightButton:
00204 m.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
00205 break;
00206 case Mouse::MiddleButton:
00207 m.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
00208 break;
00209 default:
00210 m.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
00211 break;
00212 };
00213 m.mi.dwExtraInfo = 0;
00214 if(::SendInput(1, &m, sizeof(::INPUT)) > 0)
00215 {
00216 result = true;
00217 if(releaseFlag)
00218 {
00219 FakeButtonRelease(button);
00220 }
00221 }
00222 #else
00223 Display* display = XOpenDisplay(NULL);
00224 if(display)
00225 {
00226 unsigned int _button = 1;
00227 switch(button)
00228 {
00229 case LeftButton:
00230 _button = 1;
00231 break;
00232 case RightButton:
00233 _button = 3;
00234 break;
00235 case MiddleButton:
00236 _button = 2;
00237 break;
00238 default:
00239 _button = 1;
00240 break;
00241 };
00242 if(XTestFakeButtonEvent(display, _button, true, CurrentTime) != 0)
00243 {
00244 result = true;
00245 if(releaseFlag)
00246 {
00247 XTestFakeButtonEvent(display, _button, false, CurrentTime);
00248 }
00249 }
00250 XCloseDisplay(display);
00251 }
00252 #endif
00253 }
00254 return result;
00255 }
00256
00257
00267 bool Mouse::FakeButtonRelease(const Mouse::Button button)
00268 {
00269 bool result = false;
00270 if(button != Invalid && button != Any)
00271 {
00272 #ifdef WIN32
00273 ::INPUT m;
00274 m.type = INPUT_MOUSE;
00275 m.mi.dx = 0;
00276 m.mi.dy = 0;
00277 m.mi.mouseData = 0;
00278 m.mi.time = 0;
00279 switch(button)
00280 {
00281 case Mouse::RightButton:
00282 m.mi.dwFlags = MOUSEEVENTF_RIGHTUP;
00283 break;
00284 case Mouse::MiddleButton:
00285 m.mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
00286 break;
00287 default:
00288 m.mi.dwFlags = MOUSEEVENTF_LEFTUP;
00289 break;
00290 };
00291 m.mi.dwExtraInfo = 0;
00292 if(::SendInput(1, &m, sizeof(::INPUT)) > 0)
00293 {
00294 result = true;
00295 }
00296 #else
00297 Display* display = XOpenDisplay(NULL);
00298 if(display)
00299 {
00300 unsigned int _button = 1;
00301 switch(button)
00302 {
00303 case LeftButton:
00304 _button = 1;
00305 break;
00306 case RightButton:
00307 _button = 3;
00308 break;
00309 case MiddleButton:
00310 _button = 2;
00311 break;
00312 default:
00313 _button = 1;
00314 break;
00315 };
00316 if(XTestFakeButtonEvent(display, _button, false, CurrentTime) != 0)
00317 {
00318 result = true;
00319 }
00320 XCloseDisplay(display);
00321 }
00322 #endif
00323 }
00324 return result;
00325 }
00326
00327
00347 bool Mouse::SetCursorPosition(const double dx,
00348 const double dy,
00349 const bool absoluteFlag)
00350 {
00351 bool result = false;
00352 #ifdef WIN32
00353 ::INPUT in;
00354 in.type = INPUT_MOUSE;
00355 in.mi.dx = (LONG)dx;
00356 in.mi.dy = (LONG)dy;
00357 in.mi.mouseData = 0;
00358 in.mi.dwFlags = MOUSEEVENTF_MOVE;
00359 if(absoluteFlag)
00360 {
00361 in.mi.dx = (USHORT)(dx*USHRT_MAX);
00362 in.mi.dy = (USHORT)(dy*USHRT_MAX);
00363 in.mi.dwFlags |= MOUSEEVENTF_ABSOLUTE;
00364 }
00365 in.mi.time = 0;
00366 in.mi.dwExtraInfo = 0;
00367 if(::SendInput(1, &in, sizeof(::INPUT)) > 0)
00368 {
00369 result = true;
00370 }
00371 #else
00372 Display* display = XOpenDisplay(NULL);
00373 if(display)
00374 {
00375 if(absoluteFlag)
00376 {
00377 int _x, _y;
00378 unsigned int w, h;
00379 GetScreenResolution(w, h);
00380 _x = (int)(dx*w);
00381 _y = (int)(dy*h);
00382 if(XTestFakeMotionEvent(display, DefaultScreen(display), _x, _y, CurrentTime) > 0)
00383 {
00384 result = true;
00385 }
00386 }
00387 else
00388 {
00389 if(XTestFakeRelativeMotionEvent(display, dx, dy, CurrentTime) > 0)
00390 {
00391 result = true;
00392 }
00393 }
00394
00395 XCloseDisplay(display);
00396 }
00397 #endif
00398 return result;
00399 }
00400
00401
00416 bool Mouse::GetCursorPosition(double& x,
00417 double& y,
00418 const bool normalized)
00419 {
00420 bool result = false;
00421 x = y = 0;
00422 #ifdef WIN32
00423 ::POINT pos;
00424 if(::GetCursorPos(&pos))
00425 {
00426 x = pos.x;
00427 y = pos.y;
00428 if(normalized)
00429 {
00430 unsigned int w = 1, h = 1;
00431 GetScreenResolution(w, h);
00432 x = x/w;
00433 y = y/h;
00434 }
00435 result = true;
00436 }
00437 #else
00438 Window root, child;
00439 int dummyx, dummyy;
00440 int _x, _y;
00441 unsigned int mask = 0;
00442 Display* display = XOpenDisplay(NULL);
00443 if(XQueryPointer(display,
00444 DefaultRootWindow(display),
00445 &root,
00446 &child,
00447 &_x,
00448 &_y,
00449 &dummyx,
00450 &dummyy,
00451 &mask) != 0)
00452 {
00453 x = _x;
00454 y = _y;
00455 if(normalized)
00456 {
00457 unsigned int w = 1, h = 1;
00458 GetScreenResolution(w, h);
00459 x = x/w;
00460 y = y/h;
00461 }
00462 result = true;
00463 }
00464 XCloseDisplay(display);
00465 #endif
00466 return result;
00467 }
00468
00469
00480 bool Mouse::GetScreenResolution(unsigned int& width, unsigned int& height)
00481 {
00482 #ifdef WIN32
00483 RECT desktop;
00484
00485 const HWND hDesktop = GetDesktopWindow();
00486
00487 GetWindowRect(hDesktop, &desktop);
00488
00489
00490
00491 width = (unsigned int)desktop.right;
00492 height = (unsigned int)desktop.bottom;
00493 return true;
00494 #else
00495 Display* display;
00496 display = XOpenDisplay(NULL);
00497 width = (unsigned int)XDisplayWidth(display, 0);
00498 height = (unsigned int)XDisplayHeight(display, 0);
00499 XCloseDisplay(display);
00500 return false;
00501 #endif
00502 }
00503
00504