keygrabber: use XStringToKeysym()
[awesome.git] / button.c
blobab3186434da46c5164be8211cc32a91a52e50b0f
1 /*
2 * button.c - button managing
4 * Copyright © 2007-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 "button.h"
24 #include "common/tokenize.h"
26 DO_LUA_TOSTRING(button_t, button, "button")
27 LUA_OBJECT_FUNCS(button_t, button, "button")
29 void
30 button_unref_simplified(button_t **b)
32 button_unref(globalconf.L, *b);
35 /** Collect a button.
36 * \param L The Lua VM state.
37 * \return 0.
39 static int
40 luaA_button_gc(lua_State *L)
42 button_t *button = luaL_checkudata(L, 1, "button");
43 luaL_unref(globalconf.L, LUA_REGISTRYINDEX, button->press);
44 luaL_unref(globalconf.L, LUA_REGISTRYINDEX, button->release);
45 return 0;
48 /** Create a new mouse button bindings.
49 * \param L The Lua VM state.
50 * \return The number of elements pushed on stack.
51 * \luastack
52 * \lparam A table with modifiers keys, or a button to clone.
53 * \lparam A mouse button number, or 0 to match any button.
54 * \lparam A function to execute on click events.
55 * \lparam A function to execute on release events.
56 * \lreturn A mouse button binding.
58 static int
59 luaA_button_new(lua_State *L)
61 xcb_button_t xbutton;
62 button_t *button, *orig;
63 luaA_ref press = LUA_REFNIL, release = LUA_REFNIL;
65 if((orig = luaA_toudata(L, 2, "button")))
67 button_t *copy = button_new(L);
68 copy->mod = orig->mod;
69 copy->button = orig->button;
70 if(orig->press != LUA_REFNIL)
72 lua_rawgeti(L, LUA_REGISTRYINDEX, orig->press);
73 luaA_registerfct(L, -1, &copy->press);
74 lua_pop(L, 1);
76 else
77 copy->press = LUA_REFNIL;
78 if(orig->release != LUA_REFNIL)
80 lua_rawgeti(L, LUA_REGISTRYINDEX, orig->release);
81 luaA_registerfct(L, -1, &copy->release);
82 lua_pop(L, 1);
84 else
85 copy->release = LUA_REFNIL;
86 return 1;
89 luaA_checktable(L, 2);
90 /* arg 3 is mouse button */
91 xbutton = luaL_checknumber(L, 3);
93 /* arg 4 and 5 are callback functions, check they are functions... */
94 if(!lua_isnil(L, 4))
95 luaA_checkfunction(L, 4);
96 if(lua_gettop(L) == 5 && !lua_isnil(L, 5))
97 luaA_checkfunction(L, 5);
99 /* ... then register (can't register before since 5 maybe not nil but not a
100 * function */
101 if(!lua_isnil(L, 4))
102 luaA_registerfct(L, 4, &press);
103 if(lua_gettop(L) == 5 && !lua_isnil(L, 5))
104 luaA_registerfct(L, 5, &release);
106 button = button_new(L);
107 button->press = press;
108 button->release = release;
109 button->button = xbutton;
111 luaA_setmodifiers(L, 2, &button->mod);
113 return 1;
116 /** Set a button array with a Lua table.
117 * \param L The Lua VM state.
118 * \param idx The index of the Lua table.
119 * \param buttons The array button to fill.
121 void
122 luaA_button_array_set(lua_State *L, int idx, button_array_t *buttons)
124 luaA_checktable(L, idx);
125 button_array_wipe(buttons);
126 button_array_init(buttons);
127 lua_pushnil(L);
128 while(lua_next(L, idx))
129 button_array_append(buttons, button_ref(L));
132 /** Push an array of button as an Lua table onto the stack.
133 * \param L The Lua VM state.
134 * \param buttons The button array to push.
135 * \return The number of elements pushed on stack.
138 luaA_button_array_get(lua_State *L, button_array_t *buttons)
140 lua_createtable(L, buttons->len, 0);
141 for(int i = 0; i < buttons->len; i++)
143 button_push(L, buttons->tab[i]);
144 lua_rawseti(L, -2, i + 1);
146 return 1;
149 /** Button object.
150 * \param L The Lua VM state.
151 * \return The number of elements pushed on stack.
152 * \luastack
153 * \lfield press The function called when button press event is received.
154 * \lfield release The function called when button release event is received.
155 * \lfield button The mouse button number, or 0 for any button.
156 * \lfield modifiers The modifier key table that should be pressed while the
157 * button is pressed.
159 static int
160 luaA_button_index(lua_State *L)
162 if(luaA_usemetatable(L, 1, 2))
163 return 1;
165 size_t len;
166 button_t *button = luaL_checkudata(L, 1, "button");
167 const char *attr = luaL_checklstring(L, 2, &len);
169 switch(a_tokenize(attr, len))
171 case A_TK_PRESS:
172 if(button->press != LUA_REFNIL)
173 lua_rawgeti(L, LUA_REGISTRYINDEX, button->press);
174 else
175 lua_pushnil(L);
176 break;
177 case A_TK_RELEASE:
178 if(button->release != LUA_REFNIL)
179 lua_rawgeti(L, LUA_REGISTRYINDEX, button->release);
180 else
181 lua_pushnil(L);
182 break;
183 case A_TK_BUTTON:
184 lua_pushnumber(L, button->button);
185 break;
186 case A_TK_MODIFIERS:
187 luaA_pushmodifiers(L, button->mod);
188 break;
189 default:
190 return 0;
193 return 1;
196 /** Button object.
197 * \param L The Lua VM state.
198 * \return The number of elements pushed on stack.
199 * \luastack
201 static int
202 luaA_button_newindex(lua_State *L)
204 if(luaA_usemetatable(L, 1, 2))
205 return 1;
207 size_t len;
208 button_t *button = luaL_checkudata(L, 1, "button");
209 const char *attr = luaL_checklstring(L, 2, &len);
211 switch(a_tokenize(attr, len))
213 case A_TK_PRESS:
214 luaA_registerfct(L, 3, &button->press);
215 break;
216 case A_TK_RELEASE:
217 luaA_registerfct(L, 3, &button->release);
218 break;
219 case A_TK_BUTTON:
220 button->button = luaL_checknumber(L, 3);
221 break;
222 case A_TK_MODIFIERS:
223 luaA_setmodifiers(L, 3, &button->mod);
224 default:
225 break;
228 return 0;
231 const struct luaL_reg awesome_button_methods[] =
233 { "__call", luaA_button_new },
234 { NULL, NULL }
236 const struct luaL_reg awesome_button_meta[] =
238 { "__index", luaA_button_index },
239 { "__newindex", luaA_button_newindex },
240 { "__gc", luaA_button_gc },
241 { "__tostring", luaA_button_tostring },
242 { NULL, NULL }
245 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80