/** 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); }
/** Create a new tag. * \param L The Lua VM state. * * \luastack * \lparam A table with at least a name attribute. * Optional attributes are: mwfact, ncol, nmaster and layout. * \lreturn A new tag object. */ static int luaA_tag_new(lua_State *L) { size_t len; tag_t *tag; int ncol, nmaster; const char *name, *lay; double mwfact; layout_t *layout; luaA_checktable(L, 2); if(!(name = luaA_getopt_lstring(L, 2, "name", NULL, &len))) luaL_error(L, "object tag must have a name"); mwfact = luaA_getopt_number(L, 2, "mwfact", 0.5); ncol = luaA_getopt_number(L, 2, "ncol", 1); nmaster = luaA_getopt_number(L, 2, "nmaster", 1); lay = luaA_getopt_string(L, 2, "layout", "tile"); layout = name_func_lookup(lay, LayoutList); tag = tag_new(name, len, layout, mwfact, nmaster, ncol); return luaA_tag_userdata_new(L, tag); }
/** Get an optional padding table from a Lua table. * \param L The Lua VM state. * \param idx The table index on the stack. * \param dpadding The default padding value to use. */ static inline padding_t luaA_getopt_padding(lua_State *L, int idx, padding_t *dpadding) { padding_t padding; luaA_checktable(L, idx); padding.right = luaA_getopt_number(L, idx, "right", dpadding->right); padding.left = luaA_getopt_number(L, idx, "left", dpadding->left); padding.top = luaA_getopt_number(L, idx, "top", dpadding->top); padding.bottom = luaA_getopt_number(L, idx, "bottom", dpadding->bottom); return padding; }
/** Set various plot graph properties. * \param L The Lua VM state. * \return The number of elements pushed on stack. * \luastack * \lvalue A widget. * \lparam A plot name. * \lparam A table with various properties set. */ static int luaA_graph_plot_properties_set(lua_State *L) { widget_t *widget = luaA_checkudata(L, 1, &widget_class); graph_data_t *d = widget->data; float max_value; const char *title, *buf; size_t len; plot_t *plot = NULL; color_init_cookie_t reqs[3]; int i, reqs_nbr = -1; title = luaL_checkstring(L, 2); luaA_checktable(L, 3); plot = graph_plot_get(d, title); if((buf = luaA_getopt_lstring(L, 3, "fg", NULL, &len))) reqs[++reqs_nbr] = color_init_unchecked(&plot->color_start, buf, len); if((buf = luaA_getopt_lstring(L, 3, "fg_center", NULL, &len))) reqs[++reqs_nbr] = color_init_unchecked(&plot->pcolor_center, buf, len); if((buf = luaA_getopt_lstring(L, 3, "fg_end", NULL, &len))) reqs[++reqs_nbr] = color_init_unchecked(&plot->pcolor_end, buf, len); plot->vertical_gradient = luaA_getopt_boolean(L, 3, "vertical_gradient", plot->vertical_gradient); plot->scale = luaA_getopt_boolean(L, 3, "scale", plot->scale); max_value = luaA_getopt_number(L, 3, "max_value", plot->max_value); if(max_value != plot->max_value) plot->max_value = plot->current_max = max_value; if((buf = luaA_getopt_lstring(L, 3, "style", NULL, &len))) switch (a_tokenize(buf, len)) { case A_TK_BOTTOM: plot->draw_style = Bottom_Style; break; case A_TK_LINE: plot->draw_style = Line_Style; break; case A_TK_TOP: plot->draw_style = Top_Style; break; default: break; } for(i = 0; i <= reqs_nbr; i++) color_init_reply(reqs[i]); widget_invalidate_bywidget(widget); return 0; }
/** Render a list of widgets. * \param wibox The wibox. * \todo Remove GC. */ void widget_render(wibox_t *wibox) { lua_State *L = globalconf.L; draw_context_t *ctx = &wibox->ctx; area_t rectangle = { 0, 0, 0, 0 }; color_t col; rectangle.width = ctx->width; rectangle.height = ctx->height; if (!widget_geometries(wibox)) return; if(ctx->bg.alpha != 0xffff) { int x = wibox->geometry.x + wibox->border_width, y = wibox->geometry.y + wibox->border_width; xcb_get_property_reply_t *prop_r; char *data; xcb_pixmap_t rootpix; xcb_get_property_cookie_t prop_c; xcb_screen_t *s = xutil_screen_get(globalconf.connection, ctx->phys_screen); prop_c = xcb_get_property_unchecked(globalconf.connection, false, s->root, _XROOTPMAP_ID, PIXMAP, 0, 1); if((prop_r = xcb_get_property_reply(globalconf.connection, prop_c, NULL))) { if(prop_r->value_len && (data = xcb_get_property_value(prop_r)) && (rootpix = *(xcb_pixmap_t *) data)) switch(wibox->orientation) { case North: draw_rotate(ctx, rootpix, ctx->pixmap, s->width_in_pixels, s->height_in_pixels, ctx->width, ctx->height, M_PI_2, y + ctx->width, - x); break; case South: draw_rotate(ctx, rootpix, ctx->pixmap, s->width_in_pixels, s->height_in_pixels, ctx->width, ctx->height, - M_PI_2, - y, x + ctx->height); break; case East: xcb_copy_area(globalconf.connection, rootpix, wibox->pixmap, wibox->gc, x, y, 0, 0, ctx->width, ctx->height); break; } p_delete(&prop_r); } } widget_node_array_t *widgets = &wibox->widgets; widget_node_array_wipe(widgets); widget_node_array_init(widgets); /* push wibox */ luaA_object_push(globalconf.L, wibox); /* push widgets table */ luaA_object_push_item(globalconf.L, -1, wibox->widgets_table); /* remove wibox */ lua_remove(globalconf.L, -2); luaA_table2widgets(L, widgets); /* get computed geometries */ for(unsigned int i = 0; i < lua_objlen(L, -1); i++) { lua_pushnumber(L, i + 1); lua_gettable(L, -2); widgets->tab[i].geometry.x = luaA_getopt_number(L, -1, "x", wibox->geometry.x); widgets->tab[i].geometry.y = luaA_getopt_number(L, -1, "y", wibox->geometry.y); widgets->tab[i].geometry.width = luaA_getopt_number(L, -1, "width", 1); widgets->tab[i].geometry.height = luaA_getopt_number(L, -1, "height", 1); lua_pop(L, 1); } lua_pop(L, 1); /* draw background image, only if the background color is not opaque */ if(wibox->bg_image && ctx->bg.alpha != 0xffff) draw_image(ctx, 0, 0, 1.0, wibox->bg_image); /* draw background color */ xcolor_to_color(&ctx->bg, &col); draw_rectangle(ctx, rectangle, 1.0, true, &col); /* draw everything! */ for(int i = 0; i < widgets->len; i++) if(widgets->tab[i].widget->isvisible) widgets->tab[i].widget->draw(widgets->tab[i].widget, ctx, widgets->tab[i].geometry, wibox); switch(wibox->orientation) { case South: draw_rotate(ctx, ctx->pixmap, wibox->pixmap, ctx->width, ctx->height, ctx->height, ctx->width, M_PI_2, ctx->height, 0); break; case North: draw_rotate(ctx, ctx->pixmap, wibox->pixmap, ctx->width, ctx->height, ctx->height, ctx->width, - M_PI_2, 0, ctx->width); break; case East: break; } }