/** 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. * 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; } const char *stype = luaL_checkstring(L, 1); uint8_t type, detail; int x = 0, y = 0; if (A_STREQ(stype, "key_press")) { type = XCB_KEY_PRESS; if(lua_type(L, 2) == LUA_TSTRING) { detail = _string_to_key_code(lua_tostring(L, 2)); /* keysym */ } else { detail = luaL_checknumber(L, 2); /* keycode */ } } else if(A_STREQ(stype, "key_release")) { type = XCB_KEY_RELEASE; if(lua_type(L, 2) == LUA_TSTRING) { detail = _string_to_key_code(lua_tostring(L, 2)); /* keysym */ } else { detail = luaL_checknumber(L, 2); /* keycode */ } } else if(A_STREQ(stype, "button_press")) { type = XCB_BUTTON_PRESS; detail = luaL_checknumber(L, 2); /* button number */ } else if(A_STREQ(stype, "button_release")) { type = XCB_BUTTON_RELEASE; detail = luaL_checknumber(L, 2); /* button number */ } else if(A_STREQ(stype, "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); } else return 0; xcb_test_fake_input(globalconf.connection, type, detail, XCB_CURRENT_TIME, XCB_NONE, x, y, 0); return 0; }
/** Get or set the mouse coords. * \param L The Lua VM state. * \return The number of elements pushed on stack. */ static int luaA_mouse_coords(lua_State *L) { uint16_t mask; int x, y; int16_t mouse_x, mouse_y; if(lua_gettop(L) >= 1) { 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)) return 0; x = luaA_getopt_number(L, 1, "x", mouse_x); y = luaA_getopt_number(L, 1, "y", mouse_y); if(ignore_enter_notify) client_ignore_enterleave_events(); mouse_warp_pointer(globalconf.screen->root, x, y); if(ignore_enter_notify) client_restore_enterleave_events(); lua_pop(L, 1); } if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL, &mask)) return 0; return luaA_mouse_pushstatus(L, mouse_x, mouse_y, mask); }
/** 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; }
/** 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; }
int window_set_xproperty(lua_State *L, xcb_window_t window, int prop_idx, int value_idx) { xproperty_t *prop = luaA_find_xproperty(L, prop_idx); xcb_atom_t type; uint8_t format; size_t len; uint32_t number; const void *data; if(lua_isnil(L, value_idx)) { xcb_delete_property(globalconf.connection, window, prop->atom); } else { if(prop->type == PROP_STRING) { data = luaL_checklstring(L, value_idx, &len); type = UTF8_STRING; format = 8; } else if(prop->type == PROP_NUMBER || prop->type == PROP_BOOLEAN) { if (prop->type == PROP_NUMBER) number = luaA_checkinteger_range(L, value_idx, 0, UINT32_MAX); else number = luaA_checkboolean(L, value_idx); data = &number; len = 1; type = XCB_ATOM_CARDINAL; format = 32; } else fatal("Got an xproperty with invalid type"); xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, window, prop->atom, type, format, len, data); } 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 = 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; }
/** The __newindex method for a textbox object. * \param L The Lua VM state. * \param token The key token. * \return The number of elements pushed on stack. */ static int luaA_textbox_newindex(lua_State *L, awesome_token_t token) { size_t len = 0; widget_t *widget = luaA_checkudata(L, 1, &widget_class); const char *buf = NULL; textbox_data_t *d = widget->data; switch(token) { case A_TK_BG_ALIGN: buf = luaL_checklstring(L, 3, &len); d->bg_align = draw_align_fromstr(buf, len); break; case A_TK_BG_RESIZE: d->bg_resize = luaA_checkboolean(L, 3); break; case A_TK_BG_IMAGE: luaA_checkudataornil(L, -1, &image_class); luaA_object_unref_item(L, 1, d->bg_image); d->bg_image = luaA_object_ref_item(L, 1, 3); break; case A_TK_BG: if(lua_isnil(L, 3)) p_clear(&d->bg, 1); else if((buf = luaL_checklstring(L, 3, &len))) color_init_reply(color_init_unchecked(&d->bg, buf, len)); break; case A_TK_ALIGN: if((buf = luaL_checklstring(L, 3, &len))) d->align = draw_align_fromstr(buf, len); break; case A_TK_VALIGN: if((buf = luaL_checklstring(L, 3, &len))) d->valign = draw_align_fromstr(buf, len); break; case A_TK_BORDER_COLOR: if((buf = luaL_checklstring(L, 3, &len))) color_init_reply(color_init_unchecked(&d->border.color, buf, len)); break; case A_TK_BORDER_WIDTH: d->border.width = luaL_checknumber(L, 3); break; case A_TK_TEXT: if(lua_isnil(L, 3) || (buf = luaL_checklstring(L, 3, &len))) { /* delete */ draw_text_context_wipe(&d->data); p_clear(&d->data, 1); if(buf) { char *text; ssize_t tlen; /* if text has been converted to UTF-8 */ if(draw_iso2utf8(buf, len, &text, &tlen)) { draw_text_context_init(&d->data, text, tlen); p_delete(&text); } else draw_text_context_init(&d->data, buf, len); d->extents = draw_text_extents(&d->data); } else p_clear(&d->extents, 1); } break; case A_TK_WIDTH: d->width = luaL_checknumber(L, 3); break; case A_TK_HEIGHT: d->height = luaL_checknumber(L, 3); break; case A_TK_WRAP: if((buf = luaL_checklstring(L, 3, &len))) switch(a_tokenize(buf, len)) { case A_TK_WORD: d->wrap = PANGO_WRAP_WORD; break; case A_TK_CHAR: d->wrap = PANGO_WRAP_CHAR; break; case A_TK_WORD_CHAR: d->wrap = PANGO_WRAP_WORD_CHAR; break; default: break; } break; case A_TK_ELLIPSIZE: if((buf = luaL_checklstring(L, 3, &len))) switch(a_tokenize(buf, len)) { case A_TK_START: d->ellip = PANGO_ELLIPSIZE_START; break; case A_TK_MIDDLE: d->ellip = PANGO_ELLIPSIZE_MIDDLE; break; case A_TK_END: d->ellip = PANGO_ELLIPSIZE_END; break; default: break; } break; default: return 0; } widget_invalidate_bywidget(widget); return 0; }