Mirror of Awesome WM window manager
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mousegrabber.c 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * mousegrabber.c - mouse pointer grabbing
  3. *
  4. * Copyright © 2008-2009 Julien Danjou <julien@danjou.info>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. */
  21. /** awesome mousegrabber API
  22. * @author Julien Danjou &lt;julien@danjou.info&gt;
  23. * @copyright 2008-2009 Julien Danjou
  24. * @coreclassmod mousegrabber
  25. */
  26. #include "mousegrabber.h"
  27. #include "common/xcursor.h"
  28. #include "mouse.h"
  29. #include "globalconf.h"
  30. #include <unistd.h>
  31. #include <stdbool.h>
  32. /** Grab the mouse.
  33. * \param cursor The cursor to use while grabbing.
  34. * \return True if mouse was grabbed.
  35. */
  36. static bool
  37. mousegrabber_grab(xcb_cursor_t cursor)
  38. {
  39. xcb_window_t root = globalconf.screen->root;
  40. for(int i = 1000; i; i--)
  41. {
  42. xcb_grab_pointer_reply_t *grab_ptr_r;
  43. xcb_grab_pointer_cookie_t grab_ptr_c =
  44. xcb_grab_pointer_unchecked(globalconf.connection, false, root,
  45. XCB_EVENT_MASK_BUTTON_PRESS
  46. | XCB_EVENT_MASK_BUTTON_RELEASE
  47. | XCB_EVENT_MASK_POINTER_MOTION,
  48. XCB_GRAB_MODE_ASYNC,
  49. XCB_GRAB_MODE_ASYNC,
  50. root, cursor, XCB_CURRENT_TIME);
  51. if((grab_ptr_r = xcb_grab_pointer_reply(globalconf.connection, grab_ptr_c, NULL)))
  52. {
  53. p_delete(&grab_ptr_r);
  54. return true;
  55. }
  56. usleep(1000);
  57. }
  58. return false;
  59. }
  60. /** Handle mouse motion events.
  61. * \param L Lua stack to push the pointer motion.
  62. * \param x The received mouse event x component.
  63. * \param y The received mouse event y component.
  64. * \param mask The received mouse event bit mask.
  65. */
  66. void
  67. mousegrabber_handleevent(lua_State *L, int x, int y, uint16_t mask)
  68. {
  69. luaA_mouse_pushstatus(L, x, y, mask);
  70. }
  71. /** Grab the mouse pointer and list motions, calling callback function at each
  72. * motion. The callback function must return a boolean value: true to
  73. * continue grabbing, false to stop.
  74. * The function is called with one argument:
  75. * a table containing modifiers pointer coordinates.
  76. *
  77. * The list of valid cusrors are:
  78. *
  79. *@DOC_cursor_c_COMMON@
  80. *
  81. *
  82. * @param func A callback function as described above.
  83. * @param cursor The name of a X cursor to use while grabbing.
  84. * @staticfct run
  85. */
  86. static int
  87. luaA_mousegrabber_run(lua_State *L)
  88. {
  89. if(globalconf.mousegrabber != LUA_REFNIL)
  90. luaL_error(L, "mousegrabber already running");
  91. uint16_t cfont = xcursor_font_fromstr(luaL_checkstring(L, 2));
  92. if(cfont)
  93. {
  94. xcb_cursor_t cursor = xcursor_new(globalconf.cursor_ctx, cfont);
  95. luaA_registerfct(L, 1, &globalconf.mousegrabber);
  96. if(!mousegrabber_grab(cursor))
  97. {
  98. luaA_unregister(L, &globalconf.mousegrabber);
  99. luaL_error(L, "unable to grab mouse pointer");
  100. }
  101. }
  102. else
  103. luaA_warn(L, "invalid cursor");
  104. return 0;
  105. }
  106. /** Stop grabbing the mouse pointer.
  107. *
  108. * @staticfct stop
  109. */
  110. int
  111. luaA_mousegrabber_stop(lua_State *L)
  112. {
  113. xcb_ungrab_pointer(globalconf.connection, XCB_CURRENT_TIME);
  114. luaA_unregister(L, &globalconf.mousegrabber);
  115. return 0;
  116. }
  117. /** Check if mousegrabber is running.
  118. *
  119. * @treturn boolean True if running, false otherwise.
  120. * @staticfct isrunning
  121. */
  122. static int
  123. luaA_mousegrabber_isrunning(lua_State *L)
  124. {
  125. lua_pushboolean(L, globalconf.mousegrabber != LUA_REFNIL);
  126. return 1;
  127. }
  128. const struct luaL_Reg awesome_mousegrabber_lib[] =
  129. {
  130. { "run", luaA_mousegrabber_run },
  131. { "stop", luaA_mousegrabber_stop },
  132. { "isrunning", luaA_mousegrabber_isrunning },
  133. { "__index", luaA_default_index },
  134. { "__newindex", luaA_default_newindex },
  135. { NULL, NULL }
  136. };
  137. // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80