/** Send fake events. Usually the current focused client will get it. * \param L The Lua VM state. * \return The number of element pushed on stack. * \luastack * \lparam The event type: key_press, key_release, button_press, button_release * or motion_notify. * \lparam The detail: in case of a key event, this is the keycode to send, in * case of a button event this is the number of the button. In case of a motion * event, this is a boolean value which if true make the coordinates relatives. * \lparam In case of a motion event, this is the X coordinate. * \lparam In case of a motion event, this is the Y coordinate. * \lparam In case of a motion event, this is the screen number to move on. * If not specified, the current one is used. */ static int luaA_root_fake_input(lua_State *L) { if(!globalconf.have_xtest) { luaA_warn(L, "XTest extension is not available, cannot fake input."); return 0; } size_t tlen; const char *stype = luaL_checklstring(L, 1, &tlen); uint8_t type, detail; int x = 0, y = 0; xcb_window_t root = XCB_NONE; switch(a_tokenize(stype, tlen)) { case A_TK_KEY_PRESS: type = XCB_KEY_PRESS; detail = luaL_checknumber(L, 2); /* keycode */ break; case A_TK_KEY_RELEASE: type = XCB_KEY_RELEASE; detail = luaL_checknumber(L, 2); /* keycode */ break; case A_TK_BUTTON_PRESS: type = XCB_BUTTON_PRESS; detail = luaL_checknumber(L, 2); /* button number */ break; case A_TK_BUTTON_RELEASE: type = XCB_BUTTON_RELEASE; detail = luaL_checknumber(L, 2); /* button number */ break; case A_TK_MOTION_NOTIFY: type = XCB_MOTION_NOTIFY; detail = luaA_checkboolean(L, 2); /* relative to the current position or not */ x = luaL_checknumber(L, 3); y = luaL_checknumber(L, 4); if(lua_gettop(L) == 5 && !globalconf.xinerama_is_active) { int screen = luaL_checknumber(L, 5) - 1; luaA_checkscreen(screen); root = xutil_screen_get(globalconf.connection, screen)->root; } break; default: return 0; } xcb_test_fake_input(globalconf.connection, type, detail, XCB_CURRENT_TIME, root, x, y, 0); return 0; }
/** Newindex for mouse. * \param L The Lua VM state. * \return The number of elements pushed on stack. */ static int luaA_mouse_newindex(lua_State *L) { const char *attr = luaL_checkstring(L, 2); screen_t *screen; if (A_STRNEQ(attr, "screen")) return luaA_default_newindex(L); screen = luaA_checkscreen(L, 3); mouse_warp_pointer(globalconf.screen->root, screen->geometry.x, screen->geometry.y); return 0; }
/** Tag newindex. * \param L The Lua VM state. * \return The number of elements pushed on stack. */ static int luaA_tag_newindex(lua_State *L) { size_t len; tag_t *tag = luaL_checkudata(L, 1, "tag"); const char *attr = luaL_checklstring(L, 2, &len); switch(a_tokenize(attr, len)) { int screen; case A_TK_NAME: { const char *buf = luaL_checklstring(L, 3, &len); p_delete(&tag->name); a_iso2utf8(buf, len, &tag->name, NULL); } break; case A_TK_SCREEN: if(!lua_isnil(L, 3)) { screen = luaL_checknumber(L, 3) - 1; luaA_checkscreen(screen); } else screen = SCREEN_UNDEF; if(tag->screen != SCREEN_UNDEF) tag_remove_from_screen(tag); if(screen != SCREEN_UNDEF) { /* push tag on top of the stack */ lua_pushvalue(L, 1); tag_append_to_screen(&globalconf.screens[screen]); } break; case A_TK_SELECTED: if(tag->screen != SCREEN_UNDEF) tag_view(tag, luaA_checkboolean(L, 3)); return 0; default: return 0; } if(tag->screen != SCREEN_UNDEF && tag->selected) globalconf.screens[tag->screen].need_arrange = true; return 0; }
/** Newindex for mouse. * \param L The Lua VM state. * \return The number of elements pushed on stack. */ static int luaA_mouse_newindex(lua_State *L) { const char *attr = luaL_checkstring(L, 2); int x, y = 0; int screen; if (A_STRNEQ(attr, "screen")) return 0; screen = luaL_checknumber(L, 3) - 1; luaA_checkscreen(screen); x = globalconf.screens.tab[screen].geometry.x; y = globalconf.screens.tab[screen].geometry.y; mouse_warp_pointer(globalconf.screen->root, x, y); return 0; }
static area_t systray_extents(lua_State *L, widget_t *widget) { int screen = luaL_optnumber(L, -1, 1) - 1; luaA_checkscreen(screen); area_t geometry; int phys_screen = screen_virttophys(screen), n = 0; systray_data_t *d = widget->data; for(int i = 0; i < globalconf.embedded.len; i++) if(globalconf.embedded.tab[i].phys_screen == phys_screen) n++; /** \todo use class hints */ geometry.width = d->height * n; geometry.height = d->height; geometry.x = geometry.y = 0; return geometry; }
/** Tag newindex. * \param L The Lua VM state. * \return The number of elements pushed on stack. */ static int luaA_tag_newindex(lua_State *L) { size_t len; tag_t **tag = luaA_checkudata(L, 1, "tag"); const char *buf, *attr = luaL_checklstring(L, 2, &len); double d; int i, screen; layout_t *l; switch(a_tokenize(attr, len)) { case A_TK_NAME: buf = luaL_checklstring(L, 3, &len); p_delete(&(*tag)->name); a_iso2utf8(&(*tag)->name, buf, len); break; case A_TK_SCREEN: if(!lua_isnil(L, 3)) { screen = luaL_checknumber(L, 3) - 1; luaA_checkscreen(screen); } else screen = SCREEN_UNDEF; if((*tag)->screen != SCREEN_UNDEF) tag_remove_from_screen(*tag); if(screen != SCREEN_UNDEF) tag_append_to_screen(*tag, &globalconf.screens[screen]); break; case A_TK_LAYOUT: buf = luaL_checkstring(L, 3); l = name_func_lookup(buf, LayoutList); if(l) (*tag)->layout = l; else { luaA_warn(L, "unknown layout: %s", buf); return 0; } break; case A_TK_SELECTED: if((*tag)->screen != SCREEN_UNDEF) tag_view(*tag, luaA_checkboolean(L, 3)); return 0; case A_TK_MWFACT: d = luaL_checknumber(L, 3); if(d > 0 && d < 1) (*tag)->mwfact = d; else { luaA_warn(L, "bad value, must be between 0 and 1"); return 0; } break; case A_TK_NMASTER: i = luaL_checknumber(L, 3); if(i >= 0) (*tag)->nmaster = i; else { luaA_warn(L, "bad value, must be greater than 0"); return 0; } break; case A_TK_NCOL: i = luaL_checknumber(L, 3); if(i >= 1) (*tag)->ncol = i; else { luaA_warn(L, "bad value, must be greater than 1"); return 0; } break; default: return 0; } if((*tag)->screen != SCREEN_UNDEF && (*tag)->selected) globalconf.screens[(*tag)->screen].need_arrange = true; return 0; }