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.

keygrabber.c 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * keygrabber.c - key 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. /*
  22. * @author Julien Danjou &lt;julien@danjou.info&gt;
  23. * @copyright 2008-2009 Julien Danjou
  24. * @module keygrabber
  25. */
  26. #include <unistd.h>
  27. #include <xkbcommon/xkbcommon.h>
  28. #include <xkbcommon/xkbcommon-x11.h>
  29. #include "keygrabber.h"
  30. #include "globalconf.h"
  31. /** Grab the keyboard.
  32. * \return True if keyboard was grabbed.
  33. */
  34. static bool
  35. keygrabber_grab(void)
  36. {
  37. int i;
  38. xcb_grab_keyboard_reply_t *xgb;
  39. for(i = 1000; i; i--)
  40. {
  41. if((xgb = xcb_grab_keyboard_reply(globalconf.connection,
  42. xcb_grab_keyboard(globalconf.connection, true,
  43. globalconf.screen->root,
  44. XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC,
  45. XCB_GRAB_MODE_ASYNC),
  46. NULL)))
  47. {
  48. p_delete(&xgb);
  49. return true;
  50. }
  51. usleep(1000);
  52. }
  53. return false;
  54. }
  55. /** Returns, whether the \0-terminated char in UTF8 is control char.
  56. * Control characters are either characters without UTF8 representation like XF86MonBrightnessUp
  57. * or backspace and the other characters in ASCII table before space
  58. *
  59. * \param buf input buffer
  60. * \return True if the input buffer is control character.
  61. */
  62. static bool
  63. is_control(char *buf)
  64. {
  65. return (buf[0] >= 0 && buf[0] < 0x20) || buf[0] == 0x7f;
  66. }
  67. /** Handle keypress event.
  68. * \param L Lua stack to push the key pressed.
  69. * \param e Received XKeyEvent.
  70. * \return True if a key was successfully retrieved, false otherwise.
  71. */
  72. bool
  73. keygrabber_handlekpress(lua_State *L, xcb_key_press_event_t *e)
  74. {
  75. /* convert keysym to string */
  76. char buf[MAX(MB_LEN_MAX, 32)];
  77. /* snprintf-like return value could be used here, but that should not be
  78. * necessary, as we have buffer big enough */
  79. xkb_state_key_get_utf8(globalconf.xkb_state, e->detail, buf, countof(buf) );
  80. if (is_control(buf))
  81. {
  82. /* Use text names for control characters, ignoring all modifiers. */
  83. xcb_keysym_t keysym = xcb_key_symbols_get_keysym(globalconf.keysyms,
  84. e->detail, 0);
  85. xkb_keysym_get_name(keysym, buf, countof(buf));
  86. }
  87. luaA_pushmodifiers(L, e->state);
  88. lua_pushstring(L, buf);
  89. switch(e->response_type)
  90. {
  91. case XCB_KEY_PRESS:
  92. lua_pushliteral(L, "press");
  93. break;
  94. case XCB_KEY_RELEASE:
  95. lua_pushliteral(L, "release");
  96. break;
  97. }
  98. return true;
  99. }
  100. /* Grab keyboard input and read pressed keys, calling a callback function at
  101. * each keypress, until `keygrabber.stop` is called.
  102. * The callback function receives three arguments:
  103. *
  104. * @param callback A callback function as described above.
  105. * @deprecated keygrabber.run
  106. */
  107. static int
  108. luaA_keygrabber_run(lua_State *L)
  109. {
  110. if(globalconf.keygrabber != LUA_REFNIL)
  111. luaL_error(L, "keygrabber already running");
  112. luaA_registerfct(L, 1, &globalconf.keygrabber);
  113. if(!keygrabber_grab())
  114. {
  115. luaA_unregister(L, &globalconf.keygrabber);
  116. luaL_error(L, "unable to grab keyboard");
  117. }
  118. return 0;
  119. }
  120. /** Stop grabbing the keyboard.
  121. * @deprecated keygrabber.stop
  122. */
  123. int
  124. luaA_keygrabber_stop(lua_State *L)
  125. {
  126. xcb_ungrab_keyboard(globalconf.connection, XCB_CURRENT_TIME);
  127. luaA_unregister(L, &globalconf.keygrabber);
  128. return 0;
  129. }
  130. /** Check if keygrabber is running.
  131. * @deprecated keygrabber.isrunning
  132. * @treturn bool A boolean value, true if keygrabber is running, false otherwise.
  133. * @see keygrabber.is_running
  134. */
  135. static int
  136. luaA_keygrabber_isrunning(lua_State *L)
  137. {
  138. lua_pushboolean(L, globalconf.keygrabber != LUA_REFNIL);
  139. return 1;
  140. }
  141. const struct luaL_Reg awesome_keygrabber_lib[] =
  142. {
  143. { "run", luaA_keygrabber_run },
  144. { "stop", luaA_keygrabber_stop },
  145. { "isrunning", luaA_keygrabber_isrunning },
  146. { "__index", luaA_default_index },
  147. { "__newindex", luaA_default_newindex },
  148. { NULL, NULL }
  149. };
  150. // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80