tag: Improve tag property::index support (FS#1229)
[awesome.git] / keygrabber.c
blob3b3c421649caeb9cbf1daa6bf4ae86a1ba83a64e
1 /*
2 * keygrabber.c - key grabbing
4 * Copyright © 2008-2009 Julien Danjou <julien@danjou.info>
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.
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.
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.
22 #include <unistd.h>
24 #include "keygrabber.h"
25 #include "globalconf.h"
26 #include "keyresolv.h"
28 /** Grab the keyboard.
29 * \return True if keyboard was grabbed.
31 static bool
32 keygrabber_grab(void)
34 int i;
35 xcb_grab_keyboard_reply_t *xgb;
37 for(i = 1000; i; i--)
39 if((xgb = xcb_grab_keyboard_reply(globalconf.connection,
40 xcb_grab_keyboard(globalconf.connection, true,
41 globalconf.screen->root,
42 XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC,
43 XCB_GRAB_MODE_ASYNC),
44 NULL)))
46 p_delete(&xgb);
47 return true;
49 usleep(1000);
51 return false;
54 /** Handle keypress event.
55 * \param L Lua stack to push the key pressed.
56 * \param e Received XKeyEvent.
57 * \return True if a key was successfully get, false otherwise.
59 bool
60 keygrabber_handlekpress(lua_State *L, xcb_key_press_event_t *e)
62 /* transfer event (keycode + modifiers) to keysym */
63 xcb_keysym_t ksym = keyresolv_get_keysym(e->detail, e->state);
65 /* convert keysym to string */
66 char buf[MAX(MB_LEN_MAX, 32)];
67 if(!keyresolv_keysym_to_string(ksym, buf, countof(buf)))
68 return false;
70 luaA_pushmodifiers(L, e->state);
72 lua_pushstring(L, buf);
74 switch(e->response_type)
76 case XCB_KEY_PRESS:
77 lua_pushliteral(L, "press");
78 break;
79 case XCB_KEY_RELEASE:
80 lua_pushliteral(L, "release");
81 break;
84 return true;
87 /** Grab keyboard and read pressed keys, calling callback function at each key
88 * press, until keygrabber.stop is called.
89 * The function is called with 3 arguments:
90 * a table containing modifiers keys, a string with the key pressed and a
91 * string with either "press" or "release" to indicate the event type.
93 * \param L The Lua VM state.
94 * \return The number of elements pushed on stack.
96 * \luastack
98 * \lparam A callback function as described above.
100 static int
101 luaA_keygrabber_run(lua_State *L)
103 if(globalconf.keygrabber != LUA_REFNIL)
104 luaL_error(L, "keygrabber already running");
106 luaA_registerfct(L, 1, &globalconf.keygrabber);
108 if(!keygrabber_grab())
110 luaA_unregister(L, &globalconf.keygrabber);
111 luaL_error(L, "unable to grab keyboard");
114 return 0;
117 /** Stop grabbing the keyboard.
118 * \param L The Lua VM state.
119 * \return The number of elements pushed on stack.
122 luaA_keygrabber_stop(lua_State *L)
124 xcb_ungrab_keyboard(globalconf.connection, XCB_CURRENT_TIME);
125 luaA_unregister(L, &globalconf.keygrabber);
126 return 0;
129 /** Check if keygrabber is running.
130 * \param L The Lua VM state.
131 * \return The number of elements pushed on stack.
132 * \luastack
133 * \lreturn A boolean value, true if keygrabber is running, false otherwise.
135 static int
136 luaA_keygrabber_isrunning(lua_State *L)
138 lua_pushboolean(L, globalconf.keygrabber != LUA_REFNIL);
139 return 1;
142 const struct luaL_Reg awesome_keygrabber_lib[] =
144 { "run", luaA_keygrabber_run },
145 { "stop", luaA_keygrabber_stop },
146 { "isrunning", luaA_keygrabber_isrunning },
147 { "__index", luaA_default_index },
148 { "__newindex", luaA_default_newindex },
149 { NULL, NULL }
152 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80