diff --git a/event.c b/event.c index 4dfe2889..3028e32d 100644 --- a/event.c +++ b/event.c @@ -113,7 +113,7 @@ event_handle_mousegrabber(int x, int y, uint16_t mask) if(globalconf.mousegrabber != LUA_REFNIL) { lua_rawgeti(globalconf.L, LUA_REGISTRYINDEX, globalconf.mousegrabber); - mousegrabber_handleevent(globalconf.L, x, y, mask); + luaA_mouse_pushstatus(globalconf.L, x, y); if(lua_pcall(globalconf.L, 1, 1, 0)) { warn("error running function: %s", lua_tostring(globalconf.L, -1)); @@ -156,6 +156,37 @@ event_emit_button(xcb_button_press_event_t *ev) luaA_object_emit_signal(globalconf.L, -5, name, 4); } +/** Update the global button state + * \param response_type XCB_BUTTON_PRESS or XCB_BUTTON_RELEASE + * \param button Button being changed + */ +static void +event_update_button_state(uint8_t response_type, uint8_t button) +{ + /* There is no button 0! */ + const unsigned int max_button = sizeof(globalconf.buttons_pressed) * 8; + uint32_t mask = 1 << (button - 1); + + if (button > max_button) { + warn("Button %d pressed, but we only support %d buttons", button, max_button); + return; + } + + switch(response_type) + { + case XCB_BUTTON_PRESS: + /* Set the (button-1)-st bit */ + globalconf.buttons_pressed |= mask; + break; + case XCB_BUTTON_RELEASE: + /* Clear the (button-1)-st bit */ + globalconf.buttons_pressed &= ~mask; + break; + default: + fatal("Invalid event type"); + } +} + /** The button press event handler. * \param ev The event. */ @@ -167,6 +198,8 @@ event_handle_button(xcb_button_press_event_t *ev) globalconf.timestamp = ev->time; + event_update_button_state(ev->response_type, ev->detail); + if(event_handle_mousegrabber(ev->root_x, ev->root_y, 1 << (ev->detail - 1 + 8))) return; diff --git a/globalconf.h b/globalconf.h index 3d78cfb6..27ba5104 100644 --- a/globalconf.h +++ b/globalconf.h @@ -64,6 +64,8 @@ typedef struct button_array_t buttons; /** Modifiers masks */ uint16_t numlockmask, shiftlockmask, capslockmask, modeswitchmask; + /** Bitmask for currently pressed buttons */ + uint32_t buttons_pressed; /** Check for XTest extension */ bool have_xtest; /** Clients list */ diff --git a/mouse.c b/mouse.c index a1779aa1..6c685644 100644 --- a/mouse.c +++ b/mouse.c @@ -32,11 +32,10 @@ * \param x will be set to the Pointer-x-coordinate relative to window * \param y will be set to the Pointer-y-coordinate relative to window * \param child Will be set to the window under the pointer. - * \param mask will be set to the current buttons state * \return true on success, false if an error occurred **/ -bool -mouse_query_pointer(xcb_window_t window, int16_t *x, int16_t *y, xcb_window_t *child, uint16_t *mask) +static bool +mouse_query_pointer(xcb_window_t window, int16_t *x, int16_t *y, xcb_window_t *child) { xcb_query_pointer_cookie_t query_ptr_c; xcb_query_pointer_reply_t *query_ptr_r; @@ -49,8 +48,6 @@ mouse_query_pointer(xcb_window_t window, int16_t *x, int16_t *y, xcb_window_t *c *x = query_ptr_r->win_x; *y = query_ptr_r->win_y; - if(mask) - *mask = query_ptr_r->mask; if(child) *child = query_ptr_r->child; @@ -67,11 +64,11 @@ mouse_query_pointer(xcb_window_t window, int16_t *x, int16_t *y, xcb_window_t *c * \return True on success, false if an error occurred. */ static bool -mouse_query_pointer_root(int16_t *x, int16_t *y, xcb_window_t *child, uint16_t *mask) +mouse_query_pointer_root(int16_t *x, int16_t *y, xcb_window_t *child) { xcb_window_t root = globalconf.screen->root; - if(mouse_query_pointer(root, x, y, child, mask)) + if(mouse_query_pointer(root, x, y, child)) { return true; } @@ -106,7 +103,7 @@ luaA_mouse_index(lua_State *L) if(a_strcmp(attr, "screen") == 0) { - if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL, NULL)) + if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL)) return 0; screen = screen_getbycoord(mouse_x, mouse_y); @@ -150,7 +147,7 @@ luaA_mouse_newindex(lua_State *L) * \param mask The button mask. */ int -luaA_mouse_pushstatus(lua_State *L, int x, int y, uint16_t mask) +luaA_mouse_pushstatus(lua_State *L, int x, int y) { lua_createtable(L, 0, 2); lua_pushnumber(L, x); @@ -160,15 +157,15 @@ luaA_mouse_pushstatus(lua_State *L, int x, int y, uint16_t mask) lua_createtable(L, 5, 0); - int i = 1; - - for(uint16_t maski = XCB_BUTTON_MASK_1; maski <= XCB_BUTTON_MASK_5; maski <<= 1) + const int max_button = sizeof(globalconf.buttons_pressed) * 8; + int mask = 1; + for (int i = 1; i <= max_button; i++, mask <<= 1) { - if(mask & maski) + if(globalconf.buttons_pressed & mask) lua_pushboolean(L, true); else lua_pushboolean(L, false); - lua_rawseti(L, -2, i++); + lua_rawseti(L, -2, i); } lua_setfield(L, -2, "buttons"); return 1; @@ -181,7 +178,6 @@ luaA_mouse_pushstatus(lua_State *L, int x, int y, uint16_t mask) static int luaA_mouse_coords(lua_State *L) { - uint16_t mask; int x, y; int16_t mouse_x, mouse_y; @@ -190,7 +186,7 @@ luaA_mouse_coords(lua_State *L) luaA_checktable(L, 1); bool ignore_enter_notify = (lua_gettop(L) == 2 && luaA_checkboolean(L, 2)); - if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL, &mask)) + if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL)) return 0; x = luaA_getopt_number(L, 1, "x", mouse_x); @@ -207,10 +203,10 @@ luaA_mouse_coords(lua_State *L) lua_pop(L, 1); } - if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL, &mask)) + if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL)) return 0; - return luaA_mouse_pushstatus(L, mouse_x, mouse_y, mask); + return luaA_mouse_pushstatus(L, mouse_x, mouse_y); } /** Get the client which is under the pointer. @@ -225,7 +221,7 @@ luaA_mouse_object_under_pointer(lua_State *L) int16_t mouse_x, mouse_y; xcb_window_t child; - if(!mouse_query_pointer_root(&mouse_x, &mouse_y, &child, NULL)) + if(!mouse_query_pointer_root(&mouse_x, &mouse_y, &child)) return 0; drawin_t *drawin; diff --git a/mouse.h b/mouse.h index db690984..2a310a70 100644 --- a/mouse.h +++ b/mouse.h @@ -26,8 +26,7 @@ #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); +int luaA_mouse_pushstatus(lua_State *, int, int); #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 f603b3e4..5cac8e91 100644 --- a/mousegrabber.c +++ b/mousegrabber.c @@ -59,18 +59,6 @@ mousegrabber_grab(xcb_cursor_t cursor) return false; } -/** Handle mouse motion events. - * \param L Lua stack to push the pointer motion. - * \param x The received mouse event x component. - * \param y The received mouse event y component. - * \param mask The received mouse event bit mask. - */ -void -mousegrabber_handleevent(lua_State *L, int x, int y, uint16_t mask) -{ - luaA_mouse_pushstatus(L, x, y, mask); -} - /** Grab the mouse pointer and list motions, calling callback function at each * motion. The callback function must return a boolean value: true to * continue grabbing, false to stop. diff --git a/mousegrabber.h b/mousegrabber.h index 87f8d7c6..04eee314 100644 --- a/mousegrabber.h +++ b/mousegrabber.h @@ -26,7 +26,6 @@ #include int luaA_mousegrabber_stop(lua_State *); -void mousegrabber_handleevent(lua_State *, int, int, uint16_t); #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80