mouse.cpp 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include "mouse.hpp"
  2. void slop::Mouse::setButton( int button, int state ) {
  3. for (unsigned int i=0;i<buttons.size();i++ ) {
  4. if ( buttons[i].x == button ) {
  5. buttons[i].y = state;
  6. return;
  7. }
  8. }
  9. buttons.push_back(glm::ivec2(button,state));
  10. }
  11. int slop::Mouse::getButton( int button ) {
  12. for (unsigned int i=0;i<buttons.size();i++ ) {
  13. if ( buttons[i].x == button ) {
  14. return buttons[i].y;
  15. }
  16. }
  17. return 0;
  18. }
  19. glm::vec2 slop::Mouse::getMousePos() {
  20. Window root, child;
  21. int mx, my;
  22. int wx, wy;
  23. unsigned int mask;
  24. XQueryPointer( x11->display, x11->root, &root, &child, &mx, &my, &wx, &wy, &mask );
  25. return glm::vec2( mx, my );
  26. }
  27. void slop::Mouse::setCursor( int cursor ) {
  28. if ( currentCursor == cursor ) {
  29. return;
  30. }
  31. XFreeCursor( x11->display, xcursor );
  32. xcursor = XCreateFontCursor( x11->display, cursor );
  33. XChangeActivePointerGrab( x11->display,
  34. PointerMotionMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask,
  35. xcursor, CurrentTime );
  36. }
  37. slop::Mouse::Mouse(X11* x11, int nodecorations, Window ignoreWindow ) {
  38. this->x11 = x11;
  39. currentCursor = XC_cross;
  40. xcursor = XCreateFontCursor( x11->display, XC_cross );
  41. hoverWindow = None;
  42. XGrabPointer( x11->display, x11->root, True,
  43. PointerMotionMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask,
  44. GrabModeAsync, GrabModeAsync, None, xcursor, CurrentTime );
  45. this->nodecorations = nodecorations;
  46. this->ignoreWindow = ignoreWindow;
  47. hoverWindow = findWindow(x11->root);
  48. }
  49. slop::Mouse::~Mouse() {
  50. XUngrabPointer( x11->display, CurrentTime );
  51. }
  52. void slop::Mouse::update() {
  53. XEvent event;
  54. while ( XCheckTypedEvent( x11->display, ButtonPress, &event ) ) {
  55. setButton( event.xbutton.button, 1 );
  56. }
  57. bool findNewWindow = false;
  58. while ( XCheckTypedEvent( x11->display, MotionNotify, &event ) ) {
  59. findNewWindow = true;
  60. }
  61. if ( findNewWindow ) {
  62. hoverWindow = findWindow(x11->root);
  63. }
  64. while ( XCheckTypedEvent( x11->display, ButtonRelease, &event ) ) {
  65. setButton( event.xbutton.button, 0 );
  66. }
  67. while ( XCheckTypedEvent( x11->display, EnterNotify, &event ) ) {
  68. hoverWindow = event.xcrossing.window;
  69. }
  70. }
  71. Window slop::Mouse::findWindow( Window foo ) {
  72. glm::vec2 pos = getMousePos();
  73. Window root, parent;
  74. Window* children;
  75. unsigned int nchildren;
  76. Window selectedWindow;
  77. XQueryTree( x11->display, foo, &root, &parent, &children, &nchildren );
  78. if ( !children || nchildren <= 0 ) {
  79. return foo;
  80. }
  81. // The children are ordered, so we traverse backwards.
  82. for( int i=nchildren-1;i>=0;i-- ) {
  83. if ( children[i] == ignoreWindow ) {
  84. continue;
  85. }
  86. // We need to make sure the window isn't something that currently isn't mapped.
  87. XWindowAttributes attr;
  88. XGetWindowAttributes( x11->display, children[i], &attr );
  89. if ( attr.map_state != IsViewable ) {
  90. continue;
  91. }
  92. glm::vec4 rect = getWindowGeometry(children[i], false);
  93. float a = pos.x - rect.x;
  94. float b = pos.y - rect.y;
  95. if ( a <= rect.z && a >= 0 ) {
  96. if ( b <= rect.w && b >= 0 ) {
  97. selectedWindow = children[i];
  98. switch( nodecorations ) {
  99. case 0:
  100. XFree(children);
  101. return selectedWindow;
  102. case 1:
  103. XFree(children);
  104. //return findWindow( selectedWindow );
  105. XQueryTree( x11->display, selectedWindow, &root, &parent, &children, &nchildren );
  106. if ( !children || nchildren <= 0 ) {
  107. return selectedWindow;
  108. }
  109. return children[nchildren-1];
  110. case 2:
  111. return findWindow( selectedWindow );
  112. }
  113. }
  114. }
  115. }
  116. return foo;
  117. }