int luaA_object_tostring(lua_State *L) { lua_class_t *lua_class = luaA_class_get(L, 1); lua_object_t *object = luaA_checkudata(L, 1, lua_class); int offset = 0; for(; lua_class; lua_class = lua_class->parent) { if(offset) { lua_pushliteral(L, "/"); lua_insert(L, -++offset); } lua_pushstring(L, NONULL(lua_class->name)); lua_insert(L, -++offset); if (lua_class->tostring) { int k, n; lua_pushliteral(L, "("); n = 2 + lua_class->tostring(L, object); lua_pushliteral(L, ")"); for (k = 0; k < n; k++) lua_insert(L, -offset); offset += n; } } lua_pushfstring(L, ": %p", object); lua_concat(L, offset + 1); return 1; }
/** Append a tag to a screen. * \param L The Lua VM state. * \param udx The tag index on the stack. * \param s The screen. */ void tag_append_to_screen(lua_State *L, int udx, screen_t *s) { tag_t *tag = luaA_checkudata(globalconf.L, udx, &tag_class); /* can't attach a tag twice */ if(tag->screen) { lua_remove(L, udx); return; } int screen_index = screen_array_indexof(&globalconf.screens, s); int phys_screen = screen_virttophys(screen_index); tag->screen = s; tag_array_append(&s->tags, luaA_object_ref_class(globalconf.L, udx, &tag_class)); ewmh_update_net_numbers_of_desktop(phys_screen); ewmh_update_net_desktop_names(phys_screen); luaA_object_push(globalconf.L, tag); luaA_object_emit_signal(L, -1, "property::screen", 0); lua_pop(L, 1); /* call hook */ if(globalconf.hooks.tags != LUA_REFNIL) { lua_pushnumber(globalconf.L, screen_index + 1); luaA_object_push(globalconf.L, tag); lua_pushliteral(globalconf.L, "add"); luaA_dofunction_from_registry(globalconf.L, globalconf.hooks.tags, 3, 0); } luaA_object_push(globalconf.L, tag); screen_emit_signal(globalconf.L, s, "tag::attach", 1); }
/** Get drawable geometry. The geometry consists of x, y, width and height. * * @return A table with drawable coordinates and geometry. * @function geometry */ static int luaA_drawable_geometry(lua_State *L) { drawable_t *d = luaA_checkudata(L, 1, &drawable_class); return luaA_pusharea(L, d->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; }
/** 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; }
/** Textbox widget. * \param L The Lua VM state. * \param token The key token. * \return The number of elements pushed on stack. * \luastack * \lfield text The text to display. * \lfield width The width of the textbox. Set to 0 for auto. * \lfield wrap The wrap mode: word, char, word_char. * \lfield ellipsize The ellipsize mode: start, middle or end. * \lfield border_width The border width to draw around. * \lfield border_color The border color. * \lfield align Text alignment, left, center or right. * \lfield margin Method to pass text margin: a table with top, left, right and bottom keys. * \lfield bg Background color. * \lfield bg_image Background image. * \lfield bg_align Background image alignment, left, center, right, bottom, top or middle * \lfield bg_resize Background resize. */ static int luaA_textbox_index(lua_State *L, awesome_token_t token) { widget_t *widget = luaA_checkudata(L, 1, &widget_class); textbox_data_t *d = widget->data; switch(token) { case A_TK_BG_RESIZE: lua_pushboolean(L, d->bg_resize); return 1; case A_TK_BG_ALIGN: lua_pushstring(L, draw_align_tostr(d->bg_align)); return 1; case A_TK_BG_IMAGE: return luaA_object_push(L, d->bg_image); case A_TK_BG: return luaA_pushcolor(L, &d->bg); case A_TK_MARGIN: lua_pushcfunction(L, luaA_textbox_margin); return 1; case A_TK_ALIGN: lua_pushstring(L, draw_align_tostr(d->align)); return 1; case A_TK_VALIGN: lua_pushstring(L, draw_align_tostr(d->valign)); return 1; case A_TK_BORDER_WIDTH: lua_pushnumber(L, d->border.width); return 1; case A_TK_BORDER_COLOR: luaA_pushcolor(L, &d->border.color); return 1; case A_TK_TEXT: if(d->data.len > 0) { lua_pushlstring(L, d->data.text, d->data.len); return 1; } return 0; case A_TK_WIDTH: lua_pushnumber(L, d->width); return 1; case A_TK_HEIGHT: lua_pushnumber(L, d->height); return 1; case A_TK_WRAP: switch(d->wrap) { default: lua_pushliteral(L, "word"); break; case A_TK_CHAR: lua_pushliteral(L, "char"); break; case A_TK_WORD_CHAR: lua_pushliteral(L, "word_char"); break; } return 1; case A_TK_ELLIPSIZE: switch(d->ellip) { case A_TK_START: lua_pushliteral(L, "start"); break; case A_TK_MIDDLE: lua_pushliteral(L, "middle"); break; default: lua_pushliteral(L, "end"); break; } return 1; default: return 0; } }
static void luaA_keystore(lua_State *L, int ud, const char *str, ssize_t len) { if(len <= 0 || !str) return; keyb_t *key = luaA_checkudata(L, ud, &key_class); if(len == 1) { key->keycode = 0; key->keysym = str[0]; } else if(str[0] == '#') { key->keycode = atoi(str + 1); key->keysym = 0; } else { key->keycode = 0; if((key->keysym = XStringToKeysym(str)) == NoSymbol ) { glong length; gunichar unicode; if(!g_utf8_validate(str, -1, NULL)) { luaA_warn(L, "failed to convert \"%s\" into keysym (invalid UTF-8 string)", str); return; } length = g_utf8_strlen(str, -1); /* This function counts combining characters. */ if(length <= 0) { luaA_warn(L, "failed to convert \"%s\" into keysym (empty UTF-8 string)", str); return; } else if(length > 1) { gchar *composed = g_utf8_normalize(str, -1, G_NORMALIZE_DEFAULT_COMPOSE); if(g_utf8_strlen(composed, -1) != 1) { p_delete(&composed); luaA_warn(L, "failed to convert \"%s\" into keysym (failed to compose a single character)", str); return; } unicode = g_utf8_get_char(composed); p_delete(&composed); } else unicode = g_utf8_get_char(str); if(unicode == (gunichar)-1 || unicode == (gunichar)-2) { luaA_warn(L, "failed to convert \"%s\" into keysym (neither keysym nor single unicode)", str); return; } /* Unicode-to-Keysym Conversion * * http://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html#keysym_encoding */ if(unicode <= 0x0ff) key->keysym = unicode; else if(unicode >= 0x100 && unicode <= 0x10ffff) key->keysym = unicode | (1 << 24); else { luaA_warn(L, "failed to convert \"%s\" into keysym (unicode out of range): \"%u\"", str, unicode); return; } } } luaA_object_emit_signal(L, ud, "property::key", 0); }
/** Newindex function for graph widget. * \param L The Lua VM state. * \param token The key token. * \return The number of elements pushed on stack. */ static int luaA_graph_newindex(lua_State *L, awesome_token_t token) { size_t len; widget_t *widget = luaA_checkudata(L, 1, &widget_class); graph_data_t *d = widget->data; const char *buf; int width; position_t pos; color_t color; switch(token) { case A_TK_HEIGHT: d->height = luaL_checknumber(L, 3); break; case A_TK_WIDTH: width = luaL_checknumber(L, 3); if(width >= 2 && width != d->width) { d->width = width; d->size = d->width - 2; p_realloc(&d->draw_from, d->size); p_realloc(&d->draw_to, d->size); for(int i = 0; i < d->plots.len; i++) { plot_t *plot = &d->plots.tab[i]; p_realloc(&plot->values, d->size); p_realloc(&plot->lines, d->size); p_clear(plot->values, d->size); p_clear(plot->lines, d->size); plot->index = 0; plot->current_max = 0; plot->max_index = 0; } } else return 0; break; case A_TK_BG: if((buf = luaL_checklstring(L, 3, &len))) { if(color_init_reply(color_init_unchecked(&color, buf, len))) d->bg = color; else return 0; } break; case A_TK_BORDER_COLOR: if((buf = luaL_checklstring(L, 3, &len))) { if(color_init_reply(color_init_unchecked(&color, buf, len))) d->border_color = color; else return 0; } break; case A_TK_GROW: buf = luaL_checklstring(L, 3, &len); switch((pos = position_fromstr(buf, len))) { case Left: case Right: d->grow = pos; break; default: return 0; } break; default: return 0; } widget_invalidate_bywidget(widget); return 0; }
/** Add data to a plot. * \param l The Lua VM state. * \return The number of elements pushed on stack. * \luastack * \lvalue A widget. * \lparam A plot name. * \lparam A data value. */ static int luaA_graph_plot_data_add(lua_State *L) { widget_t *widget = luaA_checkudata(L, 1, &widget_class); graph_data_t *d = widget->data; plot_t *plot = NULL; const char *title = luaL_checkstring(L, 2); float value; int i; if(!d->size) return 0; plot = graph_plot_get(d, title); /* assign incoming value */ value = MAX(luaL_checknumber(L, 3), 0); if(++plot->index >= d->size) /* cycle inside the array */ plot->index = 0; if(plot->scale) /* scale option is true */ { plot->values[plot->index] = value; if(value > plot->current_max) /* a new maximum value found */ { plot->max_index = plot->index; plot->current_max = value; /* recalculate */ for (i = 0; i < d->size; i++) plot->lines[i] = round(plot->values[i] * d->box_height / plot->current_max); } /* old max_index reached + current_max > normal, re-check/generate */ else if(plot->max_index == plot->index && plot->current_max > plot->max_value) { /* find the new max */ for(i = 0; i < d->size; i++) if(plot->values[i] > plot->values[plot->max_index]) plot->max_index = i; plot->current_max = MAX(plot->values[plot->max_index], plot->max_value); /* recalculate */ for(i = 0; i < d->size; i++) plot->lines[i] = round(plot->values[i] * d->box_height / plot->current_max); } else plot->lines[plot->index] = round(value * d->box_height / plot->current_max); } else /* scale option is false - limit to d->box_height */ { if(value < plot->max_value) plot->lines[plot->index] = round(value * d->box_height / plot->max_value); else plot->lines[plot->index] = d->box_height; } widget_invalidate_bywidget(widget); return 0; }
/** Get the value of a xproperty. * * @param name The name of the X11 property * @function get_xproperty */ static int luaA_window_get_xproperty(lua_State *L) { window_t *w = luaA_checkudata(L, 1, &window_class); return window_get_xproperty(L, w->window, 2); }