From 308ef7de5d79de9e6c1d17833fd166e4b924dd25 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Sun, 26 Apr 2009 10:46:09 +0200 Subject: [PATCH] mouse: split button out Signed-off-by: Julien Danjou --- CMakeLists.txt | 1 + button.c | 248 +++++++++++++++++++++++++++++++++++++++++++++++++ button.h | 49 ++++++++++ mouse.c | 230 +-------------------------------------------- mouse.h | 25 +---- mousegrabber.c | 1 + root.c | 3 +- widget.h | 4 +- window.c | 2 +- 9 files changed, 311 insertions(+), 252 deletions(-) create mode 100644 button.c create mode 100644 button.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e2a95e96..119061565 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,7 @@ set(AWE_SRCS ${SOURCE_DIR}/spawn.c ${SOURCE_DIR}/hooks.c ${SOURCE_DIR}/mouse.c + ${SOURCE_DIR}/button.c ${SOURCE_DIR}/screen.c ${SOURCE_DIR}/stack.c ${SOURCE_DIR}/selection.c diff --git a/button.c b/button.c new file mode 100644 index 000000000..f0a8d3a68 --- /dev/null +++ b/button.c @@ -0,0 +1,248 @@ +/* + * button.c - button managing + * + * Copyright © 2007-2009 Julien Danjou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "button.h" + +#include "common/xutil.h" +#include "common/tokenize.h" + +DO_LUA_TOSTRING(button_t, button, "button") +LUA_OBJECT_FUNCS(button_t, button, "button") + +void +button_unref_simplified(button_t **b) +{ + button_unref(globalconf.L, *b); +} + +/** Collect a button. + * \param L The Lua VM state. + * \return 0. + */ +static int +luaA_button_gc(lua_State *L) +{ + button_t *button = luaL_checkudata(L, 1, "button"); + luaL_unref(globalconf.L, LUA_REGISTRYINDEX, button->press); + luaL_unref(globalconf.L, LUA_REGISTRYINDEX, button->release); + return 0; +} + +/** Create a new mouse button bindings. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * \luastack + * \lparam A table with modifiers keys, or a button to clone. + * \lparam A mouse button number. + * \lparam A function to execute on click events. + * \lparam A function to execute on release events. + * \lreturn A mouse button binding. + */ +static int +luaA_button_new(lua_State *L) +{ + int i, len; + button_t *button, *orig; + luaA_ref press = LUA_REFNIL, release = LUA_REFNIL; + + if((orig = luaA_toudata(L, 2, "button"))) + { + button_t *copy = button_new(L); + copy->mod = orig->mod; + copy->button = orig->button; + if(orig->press != LUA_REFNIL) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, orig->press); + luaA_registerfct(L, -1, ©->press); + lua_pop(L, 1); + } + else + copy->press = LUA_REFNIL; + if(orig->release != LUA_REFNIL) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, orig->release); + luaA_registerfct(L, -1, ©->release); + lua_pop(L, 1); + } + else + copy->release = LUA_REFNIL; + return 1; + } + + luaA_checktable(L, 2); + /* arg 3 is mouse button */ + i = luaL_checknumber(L, 3); + + /* arg 4 and 5 are callback functions, check they are functions... */ + if(!lua_isnil(L, 4)) + luaA_checkfunction(L, 4); + if(lua_gettop(L) == 5 && !lua_isnil(L, 5)) + luaA_checkfunction(L, 5); + + /* ... then register (can't register before since 5 maybe not nil but not a + * function */ + if(!lua_isnil(L, 4)) + luaA_registerfct(L, 4, &press); + if(lua_gettop(L) == 5 && !lua_isnil(L, 5)) + luaA_registerfct(L, 5, &release); + + button = button_new(L); + button->press = press; + button->release = release; + button->button = xutil_button_fromint(i); + + len = lua_objlen(L, 2); + for(i = 1; i <= len; i++) + { + size_t blen; + const char *buf; + lua_rawgeti(L, 2, i); + buf = luaL_checklstring(L, -1, &blen); + button->mod |= xutil_key_mask_fromstr(buf, blen); + lua_pop(L, 1); + } + + return 1; +} + +/** Set a button array with a Lua table. + * \param L The Lua VM state. + * \param idx The index of the Lua table. + * \param buttons The array button to fill. + */ +void +luaA_button_array_set(lua_State *L, int idx, button_array_t *buttons) +{ + luaA_checktable(L, idx); + button_array_wipe(buttons); + button_array_init(buttons); + lua_pushnil(L); + while(lua_next(L, idx)) + button_array_append(buttons, button_ref(L)); +} + +/** Push an array of button as an Lua table onto the stack. + * \param L The Lua VM state. + * \param buttons The button array to push. + * \return The number of elements pushed on stack. + */ +int +luaA_button_array_get(lua_State *L, button_array_t *buttons) +{ + lua_createtable(L, buttons->len, 0); + for(int i = 0; i < buttons->len; i++) + { + button_push(L, buttons->tab[i]); + lua_rawseti(L, -2, i + 1); + } + return 1; +} + +/** Button object. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * \luastack + * \lfield press The function called when button press event is received. + * \lfield release The function called when button release event is received. + */ +static int +luaA_button_index(lua_State *L) +{ + if(luaA_usemetatable(L, 1, 2)) + return 1; + + size_t len; + button_t *button = luaL_checkudata(L, 1, "button"); + const char *attr = luaL_checklstring(L, 2, &len); + + switch(a_tokenize(attr, len)) + { + case A_TK_PRESS: + if(button->press != LUA_REFNIL) + lua_rawgeti(L, LUA_REGISTRYINDEX, button->press); + else + lua_pushnil(L); + break; + case A_TK_RELEASE: + if(button->release != LUA_REFNIL) + lua_rawgeti(L, LUA_REGISTRYINDEX, button->release); + else + lua_pushnil(L); + break; + case A_TK_BUTTON: + /* works fine, but not *really* neat */ + lua_pushnumber(L, button->button); + break; + default: + break; + } + + return 1; +} + +/** Button object. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * \luastack + */ +static int +luaA_button_newindex(lua_State *L) +{ + if(luaA_usemetatable(L, 1, 2)) + return 1; + + size_t len; + button_t *button = luaL_checkudata(L, 1, "button"); + const char *attr = luaL_checklstring(L, 2, &len); + + switch(a_tokenize(attr, len)) + { + case A_TK_PRESS: + luaA_registerfct(L, 3, &button->press); + break; + case A_TK_RELEASE: + luaA_registerfct(L, 3, &button->release); + break; + case A_TK_BUTTON: + button->button = xutil_button_fromint(luaL_checknumber(L, 3)); + break; + default: + break; + } + + return 0; +} + +const struct luaL_reg awesome_button_methods[] = +{ + { "__call", luaA_button_new }, + { NULL, NULL } +}; +const struct luaL_reg awesome_button_meta[] = +{ + { "__index", luaA_button_index }, + { "__newindex", luaA_button_newindex }, + { "__gc", luaA_button_gc }, + { "__tostring", luaA_button_tostring }, + { NULL, NULL } +}; + +// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/button.h b/button.h new file mode 100644 index 000000000..d4d9eb590 --- /dev/null +++ b/button.h @@ -0,0 +1,49 @@ +/* + * button.h - button header + * + * Copyright © 2007-2009 Julien Danjou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef AWESOME_BUTTON_H +#define AWESOME_BUTTON_H + +#include "structs.h" + +/** Mouse buttons bindings */ +struct button_t +{ + /** Lua references */ + luaA_ref_array_t refs; + /** Key modifiers */ + unsigned long mod; + /** Mouse button number */ + unsigned int button; + /** Lua function to execute on press. */ + luaA_ref press; + /** Lua function to execute on release. */ + luaA_ref release; +}; + +void button_unref_simplified(button_t **); +ARRAY_FUNCS(button_t *, button, button_unref_simplified) + +int luaA_button_array_get(lua_State *, button_array_t *); +void luaA_button_array_set(lua_State *, int idx, button_array_t *); + +#endif +// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/mouse.c b/mouse.c index ef0c805ec..c95979d0f 100644 --- a/mouse.c +++ b/mouse.c @@ -1,7 +1,7 @@ /* * mouse.c - mouse managing * - * Copyright © 2007-2008 Julien Danjou + * Copyright © 2007-2009 Julien Danjou * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,35 +19,12 @@ * */ -#include - +#include "mouse.h" #include "screen.h" -#include "tag.h" -#include "common/xcursor.h" +#include "client.h" +#include "structs.h" #include "common/xutil.h" -DO_LUA_TOSTRING(button_t, button, "button") -LUA_OBJECT_FUNCS(button_t, button, "button") - -void -button_unref_simplified(button_t **b) -{ - button_unref(globalconf.L, *b); -} - -/** Collect a button. - * \param L The Lua VM state. - * \return 0. - */ -static int -luaA_button_gc(lua_State *L) -{ - button_t *button = luaL_checkudata(L, 1, "button"); - luaL_unref(globalconf.L, LUA_REGISTRYINDEX, button->press); - luaL_unref(globalconf.L, LUA_REGISTRYINDEX, button->release); - return 0; -} - /** Get the pointer position. * \param window The window to get position on. * \param x will be set to the Pointer-x-coordinate relative to window @@ -118,205 +95,6 @@ mouse_warp_pointer(xcb_window_t window, int x, int y) 0, 0, 0, 0, x, y ); } -/** Create a new mouse button bindings. - * \param L The Lua VM state. - * \return The number of elements pushed on stack. - * \luastack - * \lparam A table with modifiers keys, or a button to clone. - * \lparam A mouse button number. - * \lparam A function to execute on click events. - * \lparam A function to execute on release events. - * \lreturn A mouse button binding. - */ -static int -luaA_button_new(lua_State *L) -{ - int i, len; - button_t *button, *orig; - luaA_ref press = LUA_REFNIL, release = LUA_REFNIL; - - if((orig = luaA_toudata(L, 2, "button"))) - { - button_t *copy = button_new(L); - copy->mod = orig->mod; - copy->button = orig->button; - if(orig->press != LUA_REFNIL) - { - lua_rawgeti(L, LUA_REGISTRYINDEX, orig->press); - luaA_registerfct(L, -1, ©->press); - lua_pop(L, 1); - } - else - copy->press = LUA_REFNIL; - if(orig->release != LUA_REFNIL) - { - lua_rawgeti(L, LUA_REGISTRYINDEX, orig->release); - luaA_registerfct(L, -1, ©->release); - lua_pop(L, 1); - } - else - copy->release = LUA_REFNIL; - return 1; - } - - luaA_checktable(L, 2); - /* arg 3 is mouse button */ - i = luaL_checknumber(L, 3); - - /* arg 4 and 5 are callback functions, check they are functions... */ - if(!lua_isnil(L, 4)) - luaA_checkfunction(L, 4); - if(lua_gettop(L) == 5 && !lua_isnil(L, 5)) - luaA_checkfunction(L, 5); - - /* ... then register (can't register before since 5 maybe not nil but not a - * function */ - if(!lua_isnil(L, 4)) - luaA_registerfct(L, 4, &press); - if(lua_gettop(L) == 5 && !lua_isnil(L, 5)) - luaA_registerfct(L, 5, &release); - - button = button_new(L); - button->press = press; - button->release = release; - button->button = xutil_button_fromint(i); - - len = lua_objlen(L, 2); - for(i = 1; i <= len; i++) - { - size_t blen; - const char *buf; - lua_rawgeti(L, 2, i); - buf = luaL_checklstring(L, -1, &blen); - button->mod |= xutil_key_mask_fromstr(buf, blen); - lua_pop(L, 1); - } - - return 1; -} - -/** Set a button array with a Lua table. - * \param L The Lua VM state. - * \param idx The index of the Lua table. - * \param buttons The array button to fill. - */ -void -luaA_button_array_set(lua_State *L, int idx, button_array_t *buttons) -{ - luaA_checktable(L, idx); - button_array_wipe(buttons); - button_array_init(buttons); - lua_pushnil(L); - while(lua_next(L, idx)) - button_array_append(buttons, button_ref(L)); -} - -/** Push an array of button as an Lua table onto the stack. - * \param L The Lua VM state. - * \param buttons The button array to push. - * \return The number of elements pushed on stack. - */ -int -luaA_button_array_get(lua_State *L, button_array_t *buttons) -{ - lua_createtable(L, buttons->len, 0); - for(int i = 0; i < buttons->len; i++) - { - button_push(L, buttons->tab[i]); - lua_rawseti(L, -2, i + 1); - } - return 1; -} - -/** Button object. - * \param L The Lua VM state. - * \return The number of elements pushed on stack. - * \luastack - * \lfield press The function called when button press event is received. - * \lfield release The function called when button release event is received. - */ -static int -luaA_button_index(lua_State *L) -{ - if(luaA_usemetatable(L, 1, 2)) - return 1; - - size_t len; - button_t *button = luaL_checkudata(L, 1, "button"); - const char *attr = luaL_checklstring(L, 2, &len); - - switch(a_tokenize(attr, len)) - { - case A_TK_PRESS: - if(button->press != LUA_REFNIL) - lua_rawgeti(L, LUA_REGISTRYINDEX, button->press); - else - lua_pushnil(L); - break; - case A_TK_RELEASE: - if(button->release != LUA_REFNIL) - lua_rawgeti(L, LUA_REGISTRYINDEX, button->release); - else - lua_pushnil(L); - break; - case A_TK_BUTTON: - /* works fine, but not *really* neat */ - lua_pushnumber(L, button->button); - break; - default: - break; - } - - return 1; -} - -/** Button object. - * \param L The Lua VM state. - * \return The number of elements pushed on stack. - * \luastack - */ -static int -luaA_button_newindex(lua_State *L) -{ - if(luaA_usemetatable(L, 1, 2)) - return 1; - - size_t len; - button_t *button = luaL_checkudata(L, 1, "button"); - const char *attr = luaL_checklstring(L, 2, &len); - - switch(a_tokenize(attr, len)) - { - case A_TK_PRESS: - luaA_registerfct(L, 3, &button->press); - break; - case A_TK_RELEASE: - luaA_registerfct(L, 3, &button->release); - break; - case A_TK_BUTTON: - button->button = xutil_button_fromint(luaL_checknumber(L, 3)); - break; - default: - break; - } - - return 0; -} - -const struct luaL_reg awesome_button_methods[] = -{ - { "__call", luaA_button_new }, - { NULL, NULL } -}; -const struct luaL_reg awesome_button_meta[] = -{ - { "__index", luaA_button_index }, - { "__newindex", luaA_button_newindex }, - { "__gc", luaA_button_gc }, - { "__tostring", luaA_button_tostring }, - { NULL, NULL } -}; - /** Mouse library. * \param L The Lua VM state. * \return The number of elements pushed on stack. diff --git a/mouse.h b/mouse.h index 031d6e4bd..db6909846 100644 --- a/mouse.h +++ b/mouse.h @@ -22,31 +22,12 @@ #ifndef AWESOME_MOUSE_H #define AWESOME_MOUSE_H -#include "structs.h" - -/** Mouse buttons bindings */ -struct button_t -{ - /** Lua references */ - luaA_ref_array_t refs; - /** Key modifiers */ - unsigned long mod; - /** Mouse button number */ - unsigned int button; - /** Lua function to execute on press. */ - luaA_ref press; - /** Lua function to execute on release. */ - luaA_ref release; -}; +#include +#include +#include bool mouse_query_pointer(xcb_window_t, int16_t *, int16_t *, xcb_window_t *, uint16_t *); int luaA_mouse_pushstatus(lua_State *, int, int, uint16_t); -void button_unref_simplified(button_t **); -ARRAY_FUNCS(button_t *, button, button_unref_simplified) - -int luaA_button_array_get(lua_State *, button_array_t *); -void luaA_button_array_set(lua_State *, int idx, button_array_t *); - #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/mousegrabber.c b/mousegrabber.c index 4235e9e35..8cd25ff48 100644 --- a/mousegrabber.c +++ b/mousegrabber.c @@ -21,6 +21,7 @@ #include +#include "structs.h" #include "mouse.h" #include "mousegrabber.h" #include "common/xcursor.h" diff --git a/root.c b/root.c index 0d7d408c9..1c4962b18 100644 --- a/root.c +++ b/root.c @@ -21,7 +21,8 @@ #include -#include "mouse.h" +#include "structs.h" +#include "button.h" #include "common/xcursor.h" #include "common/tokenize.h" #include "common/xutil.h" diff --git a/widget.h b/widget.h index ba4c0f031..97c792e86 100644 --- a/widget.h +++ b/widget.h @@ -1,7 +1,7 @@ /* * widget.h - widget managing header * - * Copyright © 2007-2008 Julien Danjou + * Copyright © 2007-2009 Julien Danjou * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,7 +22,7 @@ #ifndef AWESOME_WIDGET_H #define AWESOME_WIDGET_H -#include "mouse.h" +#include "button.h" #include "common/tokenize.h" typedef widget_t *(widget_constructor_t)(widget_t *); diff --git a/window.c b/window.c index 9a3202688..6396329f5 100644 --- a/window.c +++ b/window.c @@ -23,7 +23,7 @@ #include #include "window.h" -#include "mouse.h" +#include "button.h" #include "common/atoms.h" /** Mask shorthands */