diff --git a/CMakeLists.txt b/CMakeLists.txt index 42daa74c1..e5d875244 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,10 +70,10 @@ set(AWE_SRCS ${SOURCE_DIR}/common/xutil.c ${SOURCE_DIR}/objects/button.c ${SOURCE_DIR}/objects/client.c + ${SOURCE_DIR}/objects/drawin.c ${SOURCE_DIR}/objects/key.c ${SOURCE_DIR}/objects/tag.c ${SOURCE_DIR}/objects/timer.c - ${SOURCE_DIR}/objects/wibox.c ${SOURCE_DIR}/objects/window.c) set(AWE_MAN_SRCS diff --git a/event.c b/event.c index c6e9183b0..34963df8b 100644 --- a/event.c +++ b/event.c @@ -29,6 +29,7 @@ #include "event.h" #include "property.h" #include "objects/tag.h" +#include "objects/drawin.h" #include "xwindow.h" #include "ewmh.h" #include "objects/client.h" @@ -162,7 +163,7 @@ static void event_handle_button(xcb_button_press_event_t *ev) { client_t *c; - wibox_t *wibox; + drawin_t *drawin; globalconf.timestamp = ev->time; @@ -175,23 +176,23 @@ event_handle_button(xcb_button_press_event_t *ev) * drop them */ ev->state &= 0x00ff; - if((wibox = wibox_getbywin(ev->event)) - || (wibox = wibox_getbywin(ev->child))) + if((drawin = drawin_getbywin(ev->event)) + || (drawin = drawin_getbywin(ev->child))) { - /* If the wibox is child, then x,y are + /* If the drawin is child, then x,y are * relative to root window */ - if(wibox->window == ev->child) + if(drawin->window == ev->child) { - ev->event_x -= wibox->geometry.x; - ev->event_y -= wibox->geometry.y; + ev->event_x -= drawin->geometry.x; + ev->event_y -= drawin->geometry.y; } - /* Push the wibox */ - luaA_object_push(globalconf.L, wibox); - /* Duplicate the wibox */ + /* Push the drawin */ + luaA_object_push(globalconf.L, drawin); + /* Duplicate the drawin */ lua_pushvalue(globalconf.L, -1); /* Handle the button event on it */ - event_button_callback(ev, &wibox->buttons, -1, 1, NULL); + event_button_callback(ev, &drawin->buttons, -1, 1, NULL); /* And handle the button event on it again */ event_emit_button(ev); @@ -352,7 +353,7 @@ event_handle_motionnotify(xcb_motion_notify_event_t *ev) static void event_handle_leavenotify(xcb_leave_notify_event_t *ev) { - wibox_t *wibox; + drawin_t *drawin; client_t *c; globalconf.timestamp = ev->time; @@ -367,9 +368,9 @@ event_handle_leavenotify(xcb_leave_notify_event_t *ev) lua_pop(globalconf.L, 1); } - if((wibox = wibox_getbywin(ev->event))) + if((drawin = drawin_getbywin(ev->event))) { - luaA_object_push(globalconf.L, wibox); + luaA_object_push(globalconf.L, drawin); luaA_object_emit_signal(globalconf.L, -1, "mouse::leave", 0); lua_pop(globalconf.L, 1); } @@ -382,16 +383,16 @@ static void event_handle_enternotify(xcb_enter_notify_event_t *ev) { client_t *c; - wibox_t *wibox; + drawin_t *drawin; globalconf.timestamp = ev->time; if(ev->mode != XCB_NOTIFY_MODE_NORMAL) return; - if((wibox = wibox_getbywin(ev->event))) + if((drawin = drawin_getbywin(ev->event))) { - luaA_object_push(globalconf.L, wibox); + luaA_object_push(globalconf.L, drawin); luaA_object_emit_signal(globalconf.L, -1, "mouse::enter", 0); lua_pop(globalconf.L, 1); } @@ -441,12 +442,12 @@ event_handle_focusin(xcb_focus_in_event_t *ev) static void event_handle_expose(xcb_expose_event_t *ev) { - wibox_t *wibox; + drawin_t *drawin; - if((wibox = wibox_getbywin(ev->window))) - wibox_refresh_pixmap_partial(wibox, - ev->x, ev->y, - ev->width, ev->height); + if((drawin = drawin_getbywin(ev->window))) + drawin_refresh_pixmap_partial(drawin, + ev->x, ev->y, + ev->width, ev->height); } /** The key press event handler. diff --git a/event.h b/event.h index 9946e8050..db3995d97 100644 --- a/event.h +++ b/event.h @@ -23,7 +23,6 @@ #define AWESOME_EVENT_H #include "systray.h" -#include "objects/wibox.h" #include "objects/client.h" static inline int diff --git a/ewmh.c b/ewmh.c index ab932fcfc..236c941a4 100644 --- a/ewmh.c +++ b/ewmh.c @@ -29,7 +29,6 @@ #include "objects/tag.h" #include "screen.h" #include "objects/client.h" -#include "objects/wibox.h" #include "luaa.h" #include "common/atoms.h" #include "common/buffer.h" diff --git a/globalconf.h b/globalconf.h index 481aa0bc3..55ce00916 100644 --- a/globalconf.h +++ b/globalconf.h @@ -35,7 +35,7 @@ #include "font.h" #include "common/xembed.h" -typedef struct wibox_t wibox_t; +typedef struct drawin_t drawin_t; typedef struct a_screen screen_t; typedef struct button_t button_t; typedef struct widget_t widget_t; @@ -46,7 +46,7 @@ ARRAY_TYPE(button_t *, button) ARRAY_TYPE(tag_t *, tag) ARRAY_TYPE(screen_t, screen) ARRAY_TYPE(client_t *, client) -ARRAY_TYPE(wibox_t *, wibox) +ARRAY_TYPE(drawin_t *, drawin) /** Main configuration structure */ typedef struct @@ -92,8 +92,8 @@ typedef struct client_t *prev_client_focus; /** Focused client */ client_t *client_focus; - /** Wiboxes */ - wibox_array_t wiboxes; + /** Drawins */ + drawin_array_t drawins; /** The startup notification display struct */ SnDisplay *sndisplay; /** Latest timestamp we got from the X server */ diff --git a/luaa.c b/luaa.c index a19ac3643..8551b0005 100644 --- a/luaa.c +++ b/luaa.c @@ -41,6 +41,7 @@ #include "spawn.h" #include "objects/tag.h" #include "objects/client.h" +#include "objects/drawin.h" #include "screen.h" #include "event.h" #include "selection.h" @@ -599,8 +600,8 @@ luaA_init(xdgHandle* xdg) /* Export window */ window_class_setup(L); - /* Export wibox */ - wibox_class_setup(L); + /* Export drawin */ + drawin_class_setup(L); /* Export client */ client_class_setup(L); diff --git a/mouse.c b/mouse.c index f21623d18..a1779aa15 100644 --- a/mouse.c +++ b/mouse.c @@ -23,7 +23,7 @@ #include "screen.h" #include "objects/client.h" #include "globalconf.h" -#include "objects/wibox.h" +#include "objects/drawin.h" #include "luaa.h" #include "common/xutil.h" @@ -228,11 +228,11 @@ luaA_mouse_object_under_pointer(lua_State *L) if(!mouse_query_pointer_root(&mouse_x, &mouse_y, &child, NULL)) return 0; - wibox_t *wibox; + drawin_t *drawin; client_t *client; - if((wibox = wibox_getbywin(child))) + if((drawin = drawin_getbywin(child))) { - luaA_object_push(L, wibox); + luaA_object_push(L, drawin); return 1; } diff --git a/objects/client.c b/objects/client.c index d0f3efa5a..3b69b5212 100644 --- a/objects/client.c +++ b/objects/client.c @@ -25,7 +25,6 @@ #include "objects/tag.h" #include "ewmh.h" #include "screen.h" -#include "wibox.h" #include "systray.h" #include "property.h" #include "spawn.h" diff --git a/objects/drawin.c b/objects/drawin.c new file mode 100644 index 000000000..6714bedea --- /dev/null +++ b/objects/drawin.c @@ -0,0 +1,903 @@ +/* + * drawin.c - drawin functions + * + * Copyright © 2008-2009 Julien Danjou + * Copyright © 2010 Uli Schlachter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "screen.h" +#include "drawin.h" +#include "objects/client.h" +#include "screen.h" +#include "xwindow.h" +#include "luaa.h" +#include "ewmh.h" +#include "common/xcursor.h" +#include "common/xutil.h" + +LUA_OBJECT_FUNCS(drawin_class, drawin_t, drawin) + +/** Kick out systray windows. + */ +static void +drawin_systray_kickout(void) +{ + xcb_screen_t *s = globalconf.screen; + + if(globalconf.systray.parent != s->root) + { + /* Who! Check that we're not deleting a drawin with a systray, because it + * may be its parent. If so, we reparent to root before, otherwise it will + * hurt very much. */ + xcb_reparent_window(globalconf.connection, + globalconf.systray.window, + s->root, -512, -512); + + globalconf.systray.parent = s->root; + } +} + +/** Destroy all X resources of a drawin. + * \param w The drawin to wipe. + */ +static void +drawin_wipe_resources(drawin_t *w) +{ + if(w->window) + { + /* Activate BMA */ + client_ignore_enterleave_events(); + /* Make sure we don't accidentally kill the systray window */ + if(globalconf.systray.parent == w->window) + drawin_systray_kickout(); + xcb_destroy_window(globalconf.connection, w->window); + /* Deactivate BMA */ + client_restore_enterleave_events(); + w->window = XCB_NONE; + } + if(w->pixmap) + { + xcb_free_pixmap(globalconf.connection, w->pixmap); + w->pixmap = XCB_NONE; + } + draw_context_wipe(&w->ctx); +} + +static void +drawin_wipe(drawin_t *drawin) +{ + p_delete(&drawin->cursor); + drawin_wipe_resources(drawin); + if(drawin->bg_image) + cairo_surface_destroy(drawin->bg_image); +} + +void +drawin_unref_simplified(drawin_t **item) +{ + luaA_object_unref(globalconf.L, *item); +} + +static void +drawin_draw_context_update(drawin_t *w) +{ + xcb_screen_t *s = globalconf.screen; + xcolor_t fg = w->ctx.fg, bg = w->ctx.bg; + + draw_context_wipe(&w->ctx); + + /* update draw context */ + switch(w->orientation) + { + case South: + case North: + /* we need a new pixmap this way [ ] to render */ + w->ctx.pixmap = xcb_generate_id(globalconf.connection); + xcb_create_pixmap(globalconf.connection, + globalconf.default_depth, + w->ctx.pixmap, s->root, + w->geometry.height, + w->geometry.width); + draw_context_init(&w->ctx, + w->geometry.height, + w->geometry.width, + w->ctx.pixmap, &fg, &bg); + break; + case East: + draw_context_init(&w->ctx, + w->geometry.width, + w->geometry.height, + w->pixmap, &fg, &bg); + break; + } +} + +/** Initialize a drawin. + * \param w The drawin to initialize. + */ +static void +drawin_init(drawin_t *w) +{ + xcb_screen_t *s = globalconf.screen; + + w->window = xcb_generate_id(globalconf.connection); + xcb_create_window(globalconf.connection, globalconf.default_depth, w->window, s->root, + w->geometry.x, w->geometry.y, + w->geometry.width, w->geometry.height, + w->border_width, XCB_COPY_FROM_PARENT, globalconf.visual->visual_id, + XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY + | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP, + (const uint32_t []) + { + w->ctx.bg.pixel, + w->border_color.pixel, + XCB_GRAVITY_NORTH_WEST, + 1, + XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT + | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_ENTER_WINDOW + | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_STRUCTURE_NOTIFY + | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE + | XCB_EVENT_MASK_PROPERTY_CHANGE, + globalconf.default_cmap + }); + + /* Create a pixmap. */ + w->pixmap = xcb_generate_id(globalconf.connection); + xcb_create_pixmap(globalconf.connection, globalconf.default_depth, w->pixmap, s->root, + w->geometry.width, w->geometry.height); + + /* Update draw context physical screen, important for Zaphod. */ + drawin_draw_context_update(w); + + /* Set the right type property */ + ewmh_update_window_type(w->window, window_translate_type(w->type)); +} + +/** Refresh the window content by copying its pixmap data to its window. + * \param w The drawin to refresh. + */ +static inline void +drawin_refresh_pixmap(drawin_t *w) +{ + drawin_refresh_pixmap_partial(w, 0, 0, w->geometry.width, w->geometry.height); +} + +/** Move and/or resize a drawin + * \param L The Lua VM state. + * \param udx The index of the drawin. + * \param geometry The new geometry. + */ +static void +drawin_moveresize(lua_State *L, int udx, area_t geometry) +{ + drawin_t *w = luaA_checkudata(L, udx, &drawin_class); + if(w->window) + { + int number_of_vals = 0; + uint32_t moveresize_win_vals[4], mask_vals = 0; + + if(w->geometry.x != geometry.x) + { + w->geometry.x = moveresize_win_vals[number_of_vals++] = geometry.x; + mask_vals |= XCB_CONFIG_WINDOW_X; + } + + if(w->geometry.y != geometry.y) + { + w->geometry.y = moveresize_win_vals[number_of_vals++] = geometry.y; + mask_vals |= XCB_CONFIG_WINDOW_Y; + } + + if(geometry.width > 0 && w->geometry.width != geometry.width) + { + w->geometry.width = moveresize_win_vals[number_of_vals++] = geometry.width; + mask_vals |= XCB_CONFIG_WINDOW_WIDTH; + } + + if(geometry.height > 0 && w->geometry.height != geometry.height) + { + w->geometry.height = moveresize_win_vals[number_of_vals++] = geometry.height; + mask_vals |= XCB_CONFIG_WINDOW_HEIGHT; + } + + if(mask_vals & (XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT)) + { + xcb_free_pixmap(globalconf.connection, w->pixmap); + /* orientation != East */ + if(w->pixmap != w->ctx.pixmap) + xcb_free_pixmap(globalconf.connection, w->ctx.pixmap); + w->pixmap = xcb_generate_id(globalconf.connection); + xcb_screen_t *s = globalconf.screen; + xcb_create_pixmap(globalconf.connection, globalconf.default_depth, w->pixmap, s->root, + w->geometry.width, w->geometry.height); + drawin_draw_context_update(w); + } + + /* Activate BMA */ + client_ignore_enterleave_events(); + + if(mask_vals) + xcb_configure_window(globalconf.connection, w->window, mask_vals, moveresize_win_vals); + + /* Deactivate BMA */ + client_restore_enterleave_events(); + + w->screen = screen_getbycoord(w->geometry.x, w->geometry.y); + + if(mask_vals & XCB_CONFIG_WINDOW_X) + luaA_object_emit_signal(L, udx, "property::x", 0); + if(mask_vals & XCB_CONFIG_WINDOW_Y) + luaA_object_emit_signal(L, udx, "property::y", 0); + if(mask_vals & XCB_CONFIG_WINDOW_WIDTH) + luaA_object_emit_signal(L, udx, "property::width", 0); + if(mask_vals & XCB_CONFIG_WINDOW_HEIGHT) + luaA_object_emit_signal(L, udx, "property::height", 0); + } + else + { +#define DO_drawin_GEOMETRY_CHECK_AND_EMIT(prop) \ + if(w->geometry.prop != geometry.prop) \ + { \ + w->geometry.prop = geometry.prop; \ + luaA_object_emit_signal(L, udx, "property::" #prop, 0); \ + } + DO_drawin_GEOMETRY_CHECK_AND_EMIT(x) + DO_drawin_GEOMETRY_CHECK_AND_EMIT(y) + DO_drawin_GEOMETRY_CHECK_AND_EMIT(width) + DO_drawin_GEOMETRY_CHECK_AND_EMIT(height) +#undef DO_drawin_GEOMETRY_CHECK_AND_EMIT + } +} + +/** Refresh the window content by copying its pixmap data to its window. + * \param drawin The drawin to refresh. + * \param x The copy starting point x component. + * \param y The copy starting point y component. + * \param w The copy width from the x component. + * \param h The copy height from the y component. + */ +void +drawin_refresh_pixmap_partial(drawin_t *drawin, + int16_t x, int16_t y, + uint16_t w, uint16_t h) +{ + xcb_copy_area(globalconf.connection, drawin->pixmap, + drawin->window, globalconf.gc, x, y, x, y, + w, h); +} + +/** Set drawin orientation. + * \param L The Lua VM state. + * \param udx The drawin to change orientation. + * \param o The new orientation. + */ +static void +drawin_set_orientation(lua_State *L, int udx, orientation_t o) +{ + drawin_t *w = luaA_checkudata(L, udx, &drawin_class); + if(o != w->orientation) + { + w->orientation = o; + /* orientation != East */ + if(w->pixmap != w->ctx.pixmap) + xcb_free_pixmap(globalconf.connection, w->ctx.pixmap); + drawin_draw_context_update(w); + luaA_object_emit_signal(L, udx, "property::orientation", 0); + } +} + +static void +drawin_map(drawin_t *drawin) +{ + /* Activate BMA */ + client_ignore_enterleave_events(); + /* Map the drawin */ + xcb_map_window(globalconf.connection, drawin->window); + /* Deactivate BMA */ + client_restore_enterleave_events(); + /* Stack this drawin correctly */ + stack_windows(); +} + +/** Get a drawin by its window. + * \param win The window id. + * \return A drawin if found, NULL otherwise. + */ +drawin_t * +drawin_getbywin(xcb_window_t win) +{ + foreach(w, globalconf.drawins) + if((*w)->window == win) + return *w; + return NULL; +} + +/** Set a drawin visible or not. + * \param L The Lua VM state. + * \param udx The drawin. + * \param v The visible value. + */ +static void +drawin_set_visible(lua_State *L, int udx, bool v) +{ + drawin_t *drawin = luaA_checkudata(L, udx, &drawin_class); + if(v != drawin->visible) + { + drawin->visible = v; + + if(drawin->screen) + { + if(drawin->visible) + drawin_map(drawin); + else + { + /* Active BMA */ + client_ignore_enterleave_events(); + /* Unmap window */ + xcb_unmap_window(globalconf.connection, drawin->window); + /* Active BMA */ + client_restore_enterleave_events(); + } + } + + luaA_object_emit_signal(L, udx, "property::visible", 0); + } +} + +/** Remove a drawin from a screen. + * \param L The Lua VM state. + * \param udx drawin to detach from screen. + */ +static void +drawin_detach(lua_State *L, int udx) +{ + drawin_t *drawin = luaA_checkudata(L, udx, &drawin_class); + if(drawin->screen) + { + bool v; + + /* save visible state */ + v = drawin->visible; + drawin->visible = false; + /* restore visibility */ + drawin->visible = v; + + drawin_wipe_resources(drawin); + + foreach(item, globalconf.drawins) + if(*item == drawin) + { + drawin_array_remove(&globalconf.drawins, item); + break; + } + + if(strut_has_value(&drawin->strut)) + screen_emit_signal(L, drawin->screen, "property::workarea", 0); + + drawin->screen = NULL; + luaA_object_emit_signal(L, udx, "property::screen", 0); + + luaA_object_unref(globalconf.L, drawin); + } +} + +/** Attach a drawin that is on top of the stack. + * \param L The Lua VM state. + * \param udx The drawin to attach. + * \param s The screen to attach the drawin to. + */ +static void +drawin_attach(lua_State *L, int udx, screen_t *s) +{ + /* duplicate drawin */ + lua_pushvalue(L, udx); + /* ref it */ + drawin_t *drawin = luaA_object_ref_class(globalconf.L, -1, &drawin_class); + + drawin_detach(L, udx); + + /* Set the drawin screen */ + drawin->screen = s; + + /* Check that the drawin coordinates matches the screen. */ + screen_t *cscreen = + screen_getbycoord(drawin->geometry.x, drawin->geometry.y); + + /* If it does not match, move it to the screen coordinates */ + if(cscreen != drawin->screen) + drawin_moveresize(L, udx, (area_t) { .x = s->geometry.x, + .y = s->geometry.y, + .width = drawin->geometry.width, + .height = drawin->geometry.height }); + + drawin_array_append(&globalconf.drawins, drawin); + + drawin_init(drawin); + + xwindow_set_cursor(drawin->window, + xcursor_new(globalconf.connection, xcursor_font_fromstr(drawin->cursor))); + + if(drawin->opacity != -1) + xwindow_set_opacity(drawin->window, drawin->opacity); + + ewmh_update_strut(drawin->window, &drawin->strut); + + if(drawin->visible) + drawin_map(drawin); + + luaA_object_emit_signal(L, udx, "property::screen", 0); + + if(strut_has_value(&drawin->strut)) + screen_emit_signal(L, drawin->screen, "property::workarea", 0); +} + +/** Create a new drawin. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + */ +static int +luaA_drawin_new(lua_State *L) +{ + luaA_class_new(L, &drawin_class); + + drawin_t *w = luaA_checkudata(L, -1, &drawin_class); + + if(!w->ctx.fg.initialized) + w->ctx.fg = globalconf.colors.fg; + + if(!w->ctx.bg.initialized) + w->ctx.bg = globalconf.colors.bg; + + w->visible = true; + + if(!w->opacity) + w->opacity = -1; + + if(!w->cursor) + w->cursor = a_strdup("left_ptr"); + + if(!w->geometry.width) + w->geometry.width = 1; + + if(!w->geometry.height) + w->geometry.height = 1; + + if(w->type == 0) + w->type = _NET_WM_WINDOW_TYPE_NORMAL; + + return 1; +} + + +/* Set or get the drawin geometry. + * \param L The Lua VM state. + * \return The number of elements pushed on stack. + * \luastack + * \lparam An optional table with drawin geometry. + * \lreturn The drawin geometry. + */ +static int +luaA_drawin_geometry(lua_State *L) +{ + drawin_t *drawin = luaA_checkudata(L, 1, &drawin_class); + + if(lua_gettop(L) == 2) + { + area_t wingeom; + + luaA_checktable(L, 2); + wingeom.x = luaA_getopt_number(L, 2, "x", drawin->geometry.x); + wingeom.y = luaA_getopt_number(L, 2, "y", drawin->geometry.y); + wingeom.width = luaA_getopt_number(L, 2, "width", drawin->geometry.width); + wingeom.height = luaA_getopt_number(L, 2, "height", drawin->geometry.height); + + if(wingeom.width > 0 && wingeom.height > 0) + drawin_moveresize(L, 1, wingeom); + } + + return luaA_pusharea(L, drawin->geometry); +} + +LUA_OBJECT_EXPORT_PROPERTY(drawin, drawin_t, ontop, lua_pushboolean) +LUA_OBJECT_EXPORT_PROPERTY(drawin, drawin_t, cursor, lua_pushstring) +LUA_OBJECT_EXPORT_PROPERTY(drawin, drawin_t, visible, lua_pushboolean) + +static int +luaA_drawin_set_x(lua_State *L, drawin_t *drawin) +{ + drawin_moveresize(L, -3, (area_t) { .x = luaL_checknumber(L, -1), + .y = drawin->geometry.y, + .width = drawin->geometry.width, + .height = drawin->geometry.height }); + return 0; +} + +static int +luaA_drawin_get_x(lua_State *L, drawin_t *drawin) +{ + lua_pushnumber(L, drawin->geometry.x); + return 1; +} + +static int +luaA_drawin_set_y(lua_State *L, drawin_t *drawin) +{ + drawin_moveresize(L, -3, (area_t) { .x = drawin->geometry.x, + .y = luaL_checknumber(L, -1), + .width = drawin->geometry.width, + .height = drawin->geometry.height }); + return 0; +} + +static int +luaA_drawin_get_y(lua_State *L, drawin_t *drawin) +{ + lua_pushnumber(L, drawin->geometry.y); + return 1; +} + +static int +luaA_drawin_set_width(lua_State *L, drawin_t *drawin) +{ + int width = luaL_checknumber(L, -1); + if(width <= 0) + luaL_error(L, "invalid width"); + drawin_moveresize(L, -3, (area_t) { .x = drawin->geometry.x, + .y = drawin->geometry.y, + .width = width, + .height = drawin->geometry.height }); + return 0; +} + +static int +luaA_drawin_get_width(lua_State *L, drawin_t *drawin) +{ + lua_pushnumber(L, drawin->geometry.width); + return 1; +} + +static int +luaA_drawin_set_height(lua_State *L, drawin_t *drawin) +{ + int height = luaL_checknumber(L, -1); + if(height <= 0) + luaL_error(L, "invalid height"); + drawin_moveresize(L, -3, (area_t) { .x = drawin->geometry.x, + .y = drawin->geometry.y, + .width = drawin->geometry.width, + .height = height }); + return 0; +} + +static int +luaA_drawin_get_height(lua_State *L, drawin_t *drawin) +{ + lua_pushnumber(L, drawin->geometry.height); + return 1; +} + +/** Set the drawin foreground color. + * \param L The Lua VM state. + * \param drawin The drawin object. + * \return The number of elements pushed on stack. + */ +static int +luaA_drawin_set_fg(lua_State *L, drawin_t *drawin) +{ + size_t len; + const char *buf = luaL_checklstring(L, -1, &len); + xcolor_init_reply(xcolor_init_unchecked(&drawin->ctx.fg, buf, len)); + luaA_object_emit_signal(L, -3, "property::fg", 0); + return 0; +} + +/** Get the drawin foreground color. + * \param L The Lua VM state. + * \param drawin The drawin object. + * \return The number of elements pushed on stack. + */ +static int +luaA_drawin_get_fg(lua_State *L, drawin_t *drawin) +{ + return luaA_pushxcolor(L, drawin->ctx.fg); +} + +/** Set the drawin background color. + * \param L The Lua VM state. + * \param drawin The drawin object. + * \return The number of elements pushed on stack. + */ +static int +luaA_drawin_set_bg(lua_State *L, drawin_t *drawin) +{ + size_t len; + const char *buf = luaL_checklstring(L, -1, &len); + if(xcolor_init_reply(xcolor_init_unchecked(&drawin->ctx.bg, buf, len))) + { + uint32_t mask = XCB_CW_BACK_PIXEL; + uint32_t values[] = { drawin->ctx.bg.pixel }; + + if (drawin->window != XCB_NONE) + xcb_change_window_attributes(globalconf.connection, + drawin->window, + mask, + values); + } + luaA_object_emit_signal(L, -3, "property::bg", 0); + return 0; +} + +/** Get the drawin background color. + * \param L The Lua VM state. + * \param drawin The drawin object. + * \return The number of elements pushed on stack. + */ +static int +luaA_drawin_get_bg(lua_State *L, drawin_t *drawin) +{ + return luaA_pushxcolor(L, drawin->ctx.bg); +} + +/** Set the drawin background image. + * \param L The Lua VM state. + * \param drawin The drawin object. + * \return The number of elements pushed on stack. + */ +static int +luaA_drawin_set_bg_image(lua_State *L, drawin_t *drawin) +{ + if(lua_isnil(L, -1)) + { + if(drawin->bg_image) + cairo_surface_destroy(drawin->bg_image); + drawin->bg_image = NULL; + } else { + cairo_surface_t **cairo_surface = (cairo_surface_t **)luaL_checkudata(L, -1, OOCAIRO_MT_NAME_SURFACE); + if(drawin->bg_image) + cairo_surface_destroy(drawin->bg_image); + drawin->bg_image = draw_dup_image_surface(*cairo_surface); + } + luaA_object_emit_signal(L, -3, "property::bg_image", 0); + return 0; +} + +/** Get the drawin background image. + * \param L The Lua VM state. + * \param drawin The drawin object. + * \return The number of elements pushed on stack. + */ +static int +luaA_drawin_get_bg_image(lua_State *L, drawin_t *drawin) +{ + if(drawin->bg_image) + return oocairo_surface_push(L, drawin->bg_image); + return 0; +} + +/** Set the drawin on top status. + * \param L The Lua VM state. + * \param drawin The drawin object. + * \return The number of elements pushed on stack. + */ +static int +luaA_drawin_set_ontop(lua_State *L, drawin_t *drawin) +{ + bool b = luaA_checkboolean(L, -1); + if(b != drawin->ontop) + { + drawin->ontop = b; + stack_windows(); + luaA_object_emit_signal(L, -3, "property::ontop", 0); + } + return 0; +} + +/** Set the drawin cursor. + * \param L The Lua VM state. + * \param drawin The drawin object. + * \return The number of elements pushed on stack. + */ +static int +luaA_drawin_set_cursor(lua_State *L, drawin_t *drawin) +{ + const char *buf = luaL_checkstring(L, -1); + if(buf) + { + uint16_t cursor_font = xcursor_font_fromstr(buf); + if(cursor_font) + { + xcb_cursor_t cursor = xcursor_new(globalconf.connection, cursor_font); + p_delete(&drawin->cursor); + drawin->cursor = a_strdup(buf); + xwindow_set_cursor(drawin->window, cursor); + luaA_object_emit_signal(L, -3, "property::cursor", 0); + } + } + return 0; +} + +/** Set the drawin screen. + * \param L The Lua VM state. + * \param drawin The drawin object. + * \return The number of elements pushed on stack. + */ +static int +luaA_drawin_set_screen(lua_State *L, drawin_t *drawin) +{ + if(lua_isnil(L, -1)) + drawin_detach(L, -3); + else + { + int screen = luaL_checknumber(L, -1) - 1; + luaA_checkscreen(screen); + if(!drawin->screen || screen != screen_array_indexof(&globalconf.screens, drawin->screen)) + drawin_attach(L, -3, &globalconf.screens.tab[screen]); + } + return 0; +} + +/** Get the drawin screen. + * \param L The Lua VM state. + * \param drawin The drawin object. + * \return The number of elements pushed on stack. + */ +static int +luaA_drawin_get_screen(lua_State *L, drawin_t *drawin) +{ + if(!drawin->screen) + return 0; + lua_pushnumber(L, screen_array_indexof(&globalconf.screens, drawin->screen) + 1); + return 1; +} + +/** Set the drawin orientation. + * \param L The Lua VM state. + * \param drawin The drawin object. + * \return The number of elements pushed on stack. + */ +static int +luaA_drawin_set_orientation(lua_State *L, drawin_t *drawin) +{ + const char *buf = luaL_checkstring(L, -1); + if(buf) + { + drawin_set_orientation(L, -3, orientation_fromstr(buf)); + } + return 0; +} + +/** Get the drawin orientation. + * \param L The Lua VM state. + * \param drawin The drawin object. + * \return The number of elements pushed on stack. + */ +static int +luaA_drawin_get_orientation(lua_State *L, drawin_t *drawin) +{ + lua_pushstring(L, orientation_tostr(drawin->orientation)); + return 1; +} + +/** Set the drawin visibility. + * \param L The Lua VM state. + * \param drawin The drawin object. + * \return The number of elements pushed on stack. + */ +static int +luaA_drawin_set_visible(lua_State *L, drawin_t *drawin) +{ + drawin_set_visible(L, -3, luaA_checkboolean(L, -1)); + return 0; +} + +void +drawin_class_setup(lua_State *L) +{ + static const struct luaL_reg drawin_methods[] = + { + LUA_CLASS_METHODS(drawin) + { "__call", luaA_drawin_new }, + { NULL, NULL } + }; + + static const struct luaL_reg drawin_meta[] = + { + LUA_OBJECT_META(drawin) + LUA_CLASS_META + { "geometry", luaA_drawin_geometry }, + { NULL, NULL }, + }; + + luaA_class_setup(L, &drawin_class, "drawin", &window_class, + (lua_class_allocator_t) drawin_new, + (lua_class_collector_t) drawin_wipe, + NULL, + luaA_class_index_miss_property, luaA_class_newindex_miss_property, + drawin_methods, drawin_meta); + luaA_class_add_property(&drawin_class, "visible", + (lua_class_propfunc_t) luaA_drawin_set_visible, + (lua_class_propfunc_t) luaA_drawin_get_visible, + (lua_class_propfunc_t) luaA_drawin_set_visible); + luaA_class_add_property(&drawin_class, "orientation", + (lua_class_propfunc_t) luaA_drawin_set_orientation, + (lua_class_propfunc_t) luaA_drawin_get_orientation, + (lua_class_propfunc_t) luaA_drawin_set_orientation); + luaA_class_add_property(&drawin_class, "ontop", + (lua_class_propfunc_t) luaA_drawin_set_ontop, + (lua_class_propfunc_t) luaA_drawin_get_ontop, + (lua_class_propfunc_t) luaA_drawin_set_ontop); + luaA_class_add_property(&drawin_class, "screen", + NULL, + (lua_class_propfunc_t) luaA_drawin_get_screen, + (lua_class_propfunc_t) luaA_drawin_set_screen); + luaA_class_add_property(&drawin_class, "cursor", + (lua_class_propfunc_t) luaA_drawin_set_cursor, + (lua_class_propfunc_t) luaA_drawin_get_cursor, + (lua_class_propfunc_t) luaA_drawin_set_cursor); + luaA_class_add_property(&drawin_class, "fg", + (lua_class_propfunc_t) luaA_drawin_set_fg, + (lua_class_propfunc_t) luaA_drawin_get_fg, + (lua_class_propfunc_t) luaA_drawin_set_fg); + luaA_class_add_property(&drawin_class, "bg", + (lua_class_propfunc_t) luaA_drawin_set_bg, + (lua_class_propfunc_t) luaA_drawin_get_bg, + (lua_class_propfunc_t) luaA_drawin_set_bg); + luaA_class_add_property(&drawin_class, "bg_image", + (lua_class_propfunc_t) luaA_drawin_set_bg_image, + (lua_class_propfunc_t) luaA_drawin_get_bg_image, + (lua_class_propfunc_t) luaA_drawin_set_bg_image); + luaA_class_add_property(&drawin_class, "x", + (lua_class_propfunc_t) luaA_drawin_set_x, + (lua_class_propfunc_t) luaA_drawin_get_x, + (lua_class_propfunc_t) luaA_drawin_set_x); + luaA_class_add_property(&drawin_class, "y", + (lua_class_propfunc_t) luaA_drawin_set_y, + (lua_class_propfunc_t) luaA_drawin_get_y, + (lua_class_propfunc_t) luaA_drawin_set_y); + luaA_class_add_property(&drawin_class, "width", + (lua_class_propfunc_t) luaA_drawin_set_width, + (lua_class_propfunc_t) luaA_drawin_get_width, + (lua_class_propfunc_t) luaA_drawin_set_width); + luaA_class_add_property(&drawin_class, "height", + (lua_class_propfunc_t) luaA_drawin_set_height, + (lua_class_propfunc_t) luaA_drawin_get_height, + (lua_class_propfunc_t) luaA_drawin_set_height); + luaA_class_add_property(&drawin_class, "type", + (lua_class_propfunc_t) luaA_window_set_type, + (lua_class_propfunc_t) luaA_window_get_type, + (lua_class_propfunc_t) luaA_window_set_type); + + signal_add(&drawin_class.signals, "mouse::enter"); + signal_add(&drawin_class.signals, "mouse::leave"); + signal_add(&drawin_class.signals, "property::bg"); + signal_add(&drawin_class.signals, "property::bg_image"); + signal_add(&drawin_class.signals, "property::border_width"); + signal_add(&drawin_class.signals, "property::cursor"); + signal_add(&drawin_class.signals, "property::fg"); + signal_add(&drawin_class.signals, "property::height"); + signal_add(&drawin_class.signals, "property::ontop"); + signal_add(&drawin_class.signals, "property::orientation"); + signal_add(&drawin_class.signals, "property::screen"); + signal_add(&drawin_class.signals, "property::visible"); + signal_add(&drawin_class.signals, "property::widgets"); + signal_add(&drawin_class.signals, "property::width"); + signal_add(&drawin_class.signals, "property::x"); + signal_add(&drawin_class.signals, "property::y"); +} + +// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/objects/wibox.h b/objects/drawin.h similarity index 74% rename from objects/wibox.h rename to objects/drawin.h index 6ff711ee2..12338bcc0 100644 --- a/objects/wibox.h +++ b/objects/drawin.h @@ -1,7 +1,8 @@ /* - * wibox.h - wibox functions header + * drawin.h - drawin functions header * * Copyright © 2007-2009 Julien Danjou + * Copyright © 2010 Uli Schlachter * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,15 +20,15 @@ * */ -#ifndef AWESOME_OBJECTS_WIBOX_H -#define AWESOME_OBJECTS_WIBOX_H +#ifndef AWESOME_OBJECTS_DRAWIN_H +#define AWESOME_OBJECTS_DRAWIN_H #include "objects/window.h" #include "common/luaobject.h" #include "draw.h" -/** Wibox type */ -struct wibox_t +/** Drawin type */ +struct drawin_t { WINDOW_OBJECT_HEADER /** Ontop */ @@ -48,17 +49,17 @@ struct wibox_t orientation_t orientation; }; -void wibox_unref_simplified(wibox_t **); +void drawin_unref_simplified(drawin_t **); -ARRAY_FUNCS(wibox_t *, wibox, wibox_unref_simplified) +ARRAY_FUNCS(drawin_t *, drawin, drawin_unref_simplified) -wibox_t * wibox_getbywin(xcb_window_t); +drawin_t * drawin_getbywin(xcb_window_t); -void wibox_refresh_pixmap_partial(wibox_t *, int16_t, int16_t, uint16_t, uint16_t); +void drawin_refresh_pixmap_partial(drawin_t *, int16_t, int16_t, uint16_t, uint16_t); -void wibox_class_setup(lua_State *); +void drawin_class_setup(lua_State *); -lua_class_t wibox_class; +lua_class_t drawin_class; #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/objects/wibox.c b/objects/wibox.c deleted file mode 100644 index a87777050..000000000 --- a/objects/wibox.c +++ /dev/null @@ -1,902 +0,0 @@ -/* - * wibox.c - wibox functions - * - * Copyright © 2008-2009 Julien Danjou - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include "screen.h" -#include "wibox.h" -#include "objects/client.h" -#include "screen.h" -#include "xwindow.h" -#include "luaa.h" -#include "ewmh.h" -#include "common/xcursor.h" -#include "common/xutil.h" - -LUA_OBJECT_FUNCS(wibox_class, wibox_t, wibox) - -/** Kick out systray windows. - */ -static void -wibox_systray_kickout(void) -{ - xcb_screen_t *s = globalconf.screen; - - if(globalconf.systray.parent != s->root) - { - /* Who! Check that we're not deleting a wibox with a systray, because it - * may be its parent. If so, we reparent to root before, otherwise it will - * hurt very much. */ - xcb_reparent_window(globalconf.connection, - globalconf.systray.window, - s->root, -512, -512); - - globalconf.systray.parent = s->root; - } -} - -/** Destroy all X resources of a wibox. - * \param w The wibox to wipe. - */ -static void -wibox_wipe_resources(wibox_t *w) -{ - if(w->window) - { - /* Activate BMA */ - client_ignore_enterleave_events(); - /* Make sure we don't accidentally kill the systray window */ - if(globalconf.systray.parent == w->window) - wibox_systray_kickout(); - xcb_destroy_window(globalconf.connection, w->window); - /* Deactivate BMA */ - client_restore_enterleave_events(); - w->window = XCB_NONE; - } - if(w->pixmap) - { - xcb_free_pixmap(globalconf.connection, w->pixmap); - w->pixmap = XCB_NONE; - } - draw_context_wipe(&w->ctx); -} - -static void -wibox_wipe(wibox_t *wibox) -{ - p_delete(&wibox->cursor); - wibox_wipe_resources(wibox); - if(wibox->bg_image) - cairo_surface_destroy(wibox->bg_image); -} - -void -wibox_unref_simplified(wibox_t **item) -{ - luaA_object_unref(globalconf.L, *item); -} - -static void -wibox_draw_context_update(wibox_t *w) -{ - xcb_screen_t *s = globalconf.screen; - xcolor_t fg = w->ctx.fg, bg = w->ctx.bg; - - draw_context_wipe(&w->ctx); - - /* update draw context */ - switch(w->orientation) - { - case South: - case North: - /* we need a new pixmap this way [ ] to render */ - w->ctx.pixmap = xcb_generate_id(globalconf.connection); - xcb_create_pixmap(globalconf.connection, - globalconf.default_depth, - w->ctx.pixmap, s->root, - w->geometry.height, - w->geometry.width); - draw_context_init(&w->ctx, - w->geometry.height, - w->geometry.width, - w->ctx.pixmap, &fg, &bg); - break; - case East: - draw_context_init(&w->ctx, - w->geometry.width, - w->geometry.height, - w->pixmap, &fg, &bg); - break; - } -} - -/** Initialize a wibox. - * \param w The wibox to initialize. - */ -static void -wibox_init(wibox_t *w) -{ - xcb_screen_t *s = globalconf.screen; - - w->window = xcb_generate_id(globalconf.connection); - xcb_create_window(globalconf.connection, globalconf.default_depth, w->window, s->root, - w->geometry.x, w->geometry.y, - w->geometry.width, w->geometry.height, - w->border_width, XCB_COPY_FROM_PARENT, globalconf.visual->visual_id, - XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY - | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP, - (const uint32_t []) - { - w->ctx.bg.pixel, - w->border_color.pixel, - XCB_GRAVITY_NORTH_WEST, - 1, - XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT - | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_ENTER_WINDOW - | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_STRUCTURE_NOTIFY - | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE - | XCB_EVENT_MASK_PROPERTY_CHANGE, - globalconf.default_cmap - }); - - /* Create a pixmap. */ - w->pixmap = xcb_generate_id(globalconf.connection); - xcb_create_pixmap(globalconf.connection, globalconf.default_depth, w->pixmap, s->root, - w->geometry.width, w->geometry.height); - - /* Update draw context physical screen, important for Zaphod. */ - wibox_draw_context_update(w); - - /* Set the right type property */ - ewmh_update_window_type(w->window, window_translate_type(w->type)); -} - -/** Refresh the window content by copying its pixmap data to its window. - * \param w The wibox to refresh. - */ -static inline void -wibox_refresh_pixmap(wibox_t *w) -{ - wibox_refresh_pixmap_partial(w, 0, 0, w->geometry.width, w->geometry.height); -} - -/** Move and/or resize a wibox - * \param L The Lua VM state. - * \param udx The index of the wibox. - * \param geometry The new geometry. - */ -static void -wibox_moveresize(lua_State *L, int udx, area_t geometry) -{ - wibox_t *w = luaA_checkudata(L, udx, &wibox_class); - if(w->window) - { - int number_of_vals = 0; - uint32_t moveresize_win_vals[4], mask_vals = 0; - - if(w->geometry.x != geometry.x) - { - w->geometry.x = moveresize_win_vals[number_of_vals++] = geometry.x; - mask_vals |= XCB_CONFIG_WINDOW_X; - } - - if(w->geometry.y != geometry.y) - { - w->geometry.y = moveresize_win_vals[number_of_vals++] = geometry.y; - mask_vals |= XCB_CONFIG_WINDOW_Y; - } - - if(geometry.width > 0 && w->geometry.width != geometry.width) - { - w->geometry.width = moveresize_win_vals[number_of_vals++] = geometry.width; - mask_vals |= XCB_CONFIG_WINDOW_WIDTH; - } - - if(geometry.height > 0 && w->geometry.height != geometry.height) - { - w->geometry.height = moveresize_win_vals[number_of_vals++] = geometry.height; - mask_vals |= XCB_CONFIG_WINDOW_HEIGHT; - } - - if(mask_vals & (XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT)) - { - xcb_free_pixmap(globalconf.connection, w->pixmap); - /* orientation != East */ - if(w->pixmap != w->ctx.pixmap) - xcb_free_pixmap(globalconf.connection, w->ctx.pixmap); - w->pixmap = xcb_generate_id(globalconf.connection); - xcb_screen_t *s = globalconf.screen; - xcb_create_pixmap(globalconf.connection, globalconf.default_depth, w->pixmap, s->root, - w->geometry.width, w->geometry.height); - wibox_draw_context_update(w); - } - - /* Activate BMA */ - client_ignore_enterleave_events(); - - if(mask_vals) - xcb_configure_window(globalconf.connection, w->window, mask_vals, moveresize_win_vals); - - /* Deactivate BMA */ - client_restore_enterleave_events(); - - w->screen = screen_getbycoord(w->geometry.x, w->geometry.y); - - if(mask_vals & XCB_CONFIG_WINDOW_X) - luaA_object_emit_signal(L, udx, "property::x", 0); - if(mask_vals & XCB_CONFIG_WINDOW_Y) - luaA_object_emit_signal(L, udx, "property::y", 0); - if(mask_vals & XCB_CONFIG_WINDOW_WIDTH) - luaA_object_emit_signal(L, udx, "property::width", 0); - if(mask_vals & XCB_CONFIG_WINDOW_HEIGHT) - luaA_object_emit_signal(L, udx, "property::height", 0); - } - else - { -#define DO_WIBOX_GEOMETRY_CHECK_AND_EMIT(prop) \ - if(w->geometry.prop != geometry.prop) \ - { \ - w->geometry.prop = geometry.prop; \ - luaA_object_emit_signal(L, udx, "property::" #prop, 0); \ - } - DO_WIBOX_GEOMETRY_CHECK_AND_EMIT(x) - DO_WIBOX_GEOMETRY_CHECK_AND_EMIT(y) - DO_WIBOX_GEOMETRY_CHECK_AND_EMIT(width) - DO_WIBOX_GEOMETRY_CHECK_AND_EMIT(height) -#undef DO_WIBOX_GEOMETRY_CHECK_AND_EMIT - } -} - -/** Refresh the window content by copying its pixmap data to its window. - * \param wibox The wibox to refresh. - * \param x The copy starting point x component. - * \param y The copy starting point y component. - * \param w The copy width from the x component. - * \param h The copy height from the y component. - */ -void -wibox_refresh_pixmap_partial(wibox_t *wibox, - int16_t x, int16_t y, - uint16_t w, uint16_t h) -{ - xcb_copy_area(globalconf.connection, wibox->pixmap, - wibox->window, globalconf.gc, x, y, x, y, - w, h); -} - -/** Set wibox orientation. - * \param L The Lua VM state. - * \param udx The wibox to change orientation. - * \param o The new orientation. - */ -static void -wibox_set_orientation(lua_State *L, int udx, orientation_t o) -{ - wibox_t *w = luaA_checkudata(L, udx, &wibox_class); - if(o != w->orientation) - { - w->orientation = o; - /* orientation != East */ - if(w->pixmap != w->ctx.pixmap) - xcb_free_pixmap(globalconf.connection, w->ctx.pixmap); - wibox_draw_context_update(w); - luaA_object_emit_signal(L, udx, "property::orientation", 0); - } -} - -static void -wibox_map(wibox_t *wibox) -{ - /* Activate BMA */ - client_ignore_enterleave_events(); - /* Map the wibox */ - xcb_map_window(globalconf.connection, wibox->window); - /* Deactivate BMA */ - client_restore_enterleave_events(); - /* Stack this wibox correctly */ - stack_windows(); -} - -/** Get a wibox by its window. - * \param win The window id. - * \return A wibox if found, NULL otherwise. - */ -wibox_t * -wibox_getbywin(xcb_window_t win) -{ - foreach(w, globalconf.wiboxes) - if((*w)->window == win) - return *w; - return NULL; -} - -/** Set a wibox visible or not. - * \param L The Lua VM state. - * \param udx The wibox. - * \param v The visible value. - */ -static void -wibox_set_visible(lua_State *L, int udx, bool v) -{ - wibox_t *wibox = luaA_checkudata(L, udx, &wibox_class); - if(v != wibox->visible) - { - wibox->visible = v; - - if(wibox->screen) - { - if(wibox->visible) - wibox_map(wibox); - else - { - /* Active BMA */ - client_ignore_enterleave_events(); - /* Unmap window */ - xcb_unmap_window(globalconf.connection, wibox->window); - /* Active BMA */ - client_restore_enterleave_events(); - } - } - - luaA_object_emit_signal(L, udx, "property::visible", 0); - } -} - -/** Remove a wibox from a screen. - * \param L The Lua VM state. - * \param udx Wibox to detach from screen. - */ -static void -wibox_detach(lua_State *L, int udx) -{ - wibox_t *wibox = luaA_checkudata(L, udx, &wibox_class); - if(wibox->screen) - { - bool v; - - /* save visible state */ - v = wibox->visible; - wibox->visible = false; - /* restore visibility */ - wibox->visible = v; - - wibox_wipe_resources(wibox); - - foreach(item, globalconf.wiboxes) - if(*item == wibox) - { - wibox_array_remove(&globalconf.wiboxes, item); - break; - } - - if(strut_has_value(&wibox->strut)) - screen_emit_signal(L, wibox->screen, "property::workarea", 0); - - wibox->screen = NULL; - luaA_object_emit_signal(L, udx, "property::screen", 0); - - luaA_object_unref(globalconf.L, wibox); - } -} - -/** Attach a wibox that is on top of the stack. - * \param L The Lua VM state. - * \param udx The wibox to attach. - * \param s The screen to attach the wibox to. - */ -static void -wibox_attach(lua_State *L, int udx, screen_t *s) -{ - /* duplicate wibox */ - lua_pushvalue(L, udx); - /* ref it */ - wibox_t *wibox = luaA_object_ref_class(globalconf.L, -1, &wibox_class); - - wibox_detach(L, udx); - - /* Set the wibox screen */ - wibox->screen = s; - - /* Check that the wibox coordinates matches the screen. */ - screen_t *cscreen = - screen_getbycoord(wibox->geometry.x, wibox->geometry.y); - - /* If it does not match, move it to the screen coordinates */ - if(cscreen != wibox->screen) - wibox_moveresize(L, udx, (area_t) { .x = s->geometry.x, - .y = s->geometry.y, - .width = wibox->geometry.width, - .height = wibox->geometry.height }); - - wibox_array_append(&globalconf.wiboxes, wibox); - - wibox_init(wibox); - - xwindow_set_cursor(wibox->window, - xcursor_new(globalconf.connection, xcursor_font_fromstr(wibox->cursor))); - - if(wibox->opacity != -1) - xwindow_set_opacity(wibox->window, wibox->opacity); - - ewmh_update_strut(wibox->window, &wibox->strut); - - if(wibox->visible) - wibox_map(wibox); - - luaA_object_emit_signal(L, udx, "property::screen", 0); - - if(strut_has_value(&wibox->strut)) - screen_emit_signal(L, wibox->screen, "property::workarea", 0); -} - -/** Create a new wibox. - * \param L The Lua VM state. - * \return The number of elements pushed on stack. - */ -static int -luaA_wibox_new(lua_State *L) -{ - luaA_class_new(L, &wibox_class); - - wibox_t *w = luaA_checkudata(L, -1, &wibox_class); - - if(!w->ctx.fg.initialized) - w->ctx.fg = globalconf.colors.fg; - - if(!w->ctx.bg.initialized) - w->ctx.bg = globalconf.colors.bg; - - w->visible = true; - - if(!w->opacity) - w->opacity = -1; - - if(!w->cursor) - w->cursor = a_strdup("left_ptr"); - - if(!w->geometry.width) - w->geometry.width = 1; - - if(!w->geometry.height) - w->geometry.height = 1; - - if(w->type == 0) - w->type = _NET_WM_WINDOW_TYPE_NORMAL; - - return 1; -} - - -/* Set or get the wibox geometry. - * \param L The Lua VM state. - * \return The number of elements pushed on stack. - * \luastack - * \lparam An optional table with wibox geometry. - * \lreturn The wibox geometry. - */ -static int -luaA_wibox_geometry(lua_State *L) -{ - wibox_t *wibox = luaA_checkudata(L, 1, &wibox_class); - - if(lua_gettop(L) == 2) - { - area_t wingeom; - - luaA_checktable(L, 2); - wingeom.x = luaA_getopt_number(L, 2, "x", wibox->geometry.x); - wingeom.y = luaA_getopt_number(L, 2, "y", wibox->geometry.y); - wingeom.width = luaA_getopt_number(L, 2, "width", wibox->geometry.width); - wingeom.height = luaA_getopt_number(L, 2, "height", wibox->geometry.height); - - if(wingeom.width > 0 && wingeom.height > 0) - wibox_moveresize(L, 1, wingeom); - } - - return luaA_pusharea(L, wibox->geometry); -} - -LUA_OBJECT_EXPORT_PROPERTY(wibox, wibox_t, ontop, lua_pushboolean) -LUA_OBJECT_EXPORT_PROPERTY(wibox, wibox_t, cursor, lua_pushstring) -LUA_OBJECT_EXPORT_PROPERTY(wibox, wibox_t, visible, lua_pushboolean) - -static int -luaA_wibox_set_x(lua_State *L, wibox_t *wibox) -{ - wibox_moveresize(L, -3, (area_t) { .x = luaL_checknumber(L, -1), - .y = wibox->geometry.y, - .width = wibox->geometry.width, - .height = wibox->geometry.height }); - return 0; -} - -static int -luaA_wibox_get_x(lua_State *L, wibox_t *wibox) -{ - lua_pushnumber(L, wibox->geometry.x); - return 1; -} - -static int -luaA_wibox_set_y(lua_State *L, wibox_t *wibox) -{ - wibox_moveresize(L, -3, (area_t) { .x = wibox->geometry.x, - .y = luaL_checknumber(L, -1), - .width = wibox->geometry.width, - .height = wibox->geometry.height }); - return 0; -} - -static int -luaA_wibox_get_y(lua_State *L, wibox_t *wibox) -{ - lua_pushnumber(L, wibox->geometry.y); - return 1; -} - -static int -luaA_wibox_set_width(lua_State *L, wibox_t *wibox) -{ - int width = luaL_checknumber(L, -1); - if(width <= 0) - luaL_error(L, "invalid width"); - wibox_moveresize(L, -3, (area_t) { .x = wibox->geometry.x, - .y = wibox->geometry.y, - .width = width, - .height = wibox->geometry.height }); - return 0; -} - -static int -luaA_wibox_get_width(lua_State *L, wibox_t *wibox) -{ - lua_pushnumber(L, wibox->geometry.width); - return 1; -} - -static int -luaA_wibox_set_height(lua_State *L, wibox_t *wibox) -{ - int height = luaL_checknumber(L, -1); - if(height <= 0) - luaL_error(L, "invalid height"); - wibox_moveresize(L, -3, (area_t) { .x = wibox->geometry.x, - .y = wibox->geometry.y, - .width = wibox->geometry.width, - .height = height }); - return 0; -} - -static int -luaA_wibox_get_height(lua_State *L, wibox_t *wibox) -{ - lua_pushnumber(L, wibox->geometry.height); - return 1; -} - -/** Set the wibox foreground color. - * \param L The Lua VM state. - * \param wibox The wibox object. - * \return The number of elements pushed on stack. - */ -static int -luaA_wibox_set_fg(lua_State *L, wibox_t *wibox) -{ - size_t len; - const char *buf = luaL_checklstring(L, -1, &len); - xcolor_init_reply(xcolor_init_unchecked(&wibox->ctx.fg, buf, len)); - luaA_object_emit_signal(L, -3, "property::fg", 0); - return 0; -} - -/** Get the wibox foreground color. - * \param L The Lua VM state. - * \param wibox The wibox object. - * \return The number of elements pushed on stack. - */ -static int -luaA_wibox_get_fg(lua_State *L, wibox_t *wibox) -{ - return luaA_pushxcolor(L, wibox->ctx.fg); -} - -/** Set the wibox background color. - * \param L The Lua VM state. - * \param wibox The wibox object. - * \return The number of elements pushed on stack. - */ -static int -luaA_wibox_set_bg(lua_State *L, wibox_t *wibox) -{ - size_t len; - const char *buf = luaL_checklstring(L, -1, &len); - if(xcolor_init_reply(xcolor_init_unchecked(&wibox->ctx.bg, buf, len))) - { - uint32_t mask = XCB_CW_BACK_PIXEL; - uint32_t values[] = { wibox->ctx.bg.pixel }; - - if (wibox->window != XCB_NONE) - xcb_change_window_attributes(globalconf.connection, - wibox->window, - mask, - values); - } - luaA_object_emit_signal(L, -3, "property::bg", 0); - return 0; -} - -/** Get the wibox background color. - * \param L The Lua VM state. - * \param wibox The wibox object. - * \return The number of elements pushed on stack. - */ -static int -luaA_wibox_get_bg(lua_State *L, wibox_t *wibox) -{ - return luaA_pushxcolor(L, wibox->ctx.bg); -} - -/** Set the wibox background image. - * \param L The Lua VM state. - * \param wibox The wibox object. - * \return The number of elements pushed on stack. - */ -static int -luaA_wibox_set_bg_image(lua_State *L, wibox_t *wibox) -{ - if(lua_isnil(L, -1)) - { - if(wibox->bg_image) - cairo_surface_destroy(wibox->bg_image); - wibox->bg_image = NULL; - } else { - cairo_surface_t **cairo_surface = (cairo_surface_t **)luaL_checkudata(L, -1, OOCAIRO_MT_NAME_SURFACE); - if(wibox->bg_image) - cairo_surface_destroy(wibox->bg_image); - wibox->bg_image = draw_dup_image_surface(*cairo_surface); - } - luaA_object_emit_signal(L, -3, "property::bg_image", 0); - return 0; -} - -/** Get the wibox background image. - * \param L The Lua VM state. - * \param wibox The wibox object. - * \return The number of elements pushed on stack. - */ -static int -luaA_wibox_get_bg_image(lua_State *L, wibox_t *wibox) -{ - if(wibox->bg_image) - return oocairo_surface_push(L, wibox->bg_image); - return 0; -} - -/** Set the wibox on top status. - * \param L The Lua VM state. - * \param wibox The wibox object. - * \return The number of elements pushed on stack. - */ -static int -luaA_wibox_set_ontop(lua_State *L, wibox_t *wibox) -{ - bool b = luaA_checkboolean(L, -1); - if(b != wibox->ontop) - { - wibox->ontop = b; - stack_windows(); - luaA_object_emit_signal(L, -3, "property::ontop", 0); - } - return 0; -} - -/** Set the wibox cursor. - * \param L The Lua VM state. - * \param wibox The wibox object. - * \return The number of elements pushed on stack. - */ -static int -luaA_wibox_set_cursor(lua_State *L, wibox_t *wibox) -{ - const char *buf = luaL_checkstring(L, -1); - if(buf) - { - uint16_t cursor_font = xcursor_font_fromstr(buf); - if(cursor_font) - { - xcb_cursor_t cursor = xcursor_new(globalconf.connection, cursor_font); - p_delete(&wibox->cursor); - wibox->cursor = a_strdup(buf); - xwindow_set_cursor(wibox->window, cursor); - luaA_object_emit_signal(L, -3, "property::cursor", 0); - } - } - return 0; -} - -/** Set the wibox screen. - * \param L The Lua VM state. - * \param wibox The wibox object. - * \return The number of elements pushed on stack. - */ -static int -luaA_wibox_set_screen(lua_State *L, wibox_t *wibox) -{ - if(lua_isnil(L, -1)) - wibox_detach(L, -3); - else - { - int screen = luaL_checknumber(L, -1) - 1; - luaA_checkscreen(screen); - if(!wibox->screen || screen != screen_array_indexof(&globalconf.screens, wibox->screen)) - wibox_attach(L, -3, &globalconf.screens.tab[screen]); - } - return 0; -} - -/** Get the wibox screen. - * \param L The Lua VM state. - * \param wibox The wibox object. - * \return The number of elements pushed on stack. - */ -static int -luaA_wibox_get_screen(lua_State *L, wibox_t *wibox) -{ - if(!wibox->screen) - return 0; - lua_pushnumber(L, screen_array_indexof(&globalconf.screens, wibox->screen) + 1); - return 1; -} - -/** Set the wibox orientation. - * \param L The Lua VM state. - * \param wibox The wibox object. - * \return The number of elements pushed on stack. - */ -static int -luaA_wibox_set_orientation(lua_State *L, wibox_t *wibox) -{ - const char *buf = luaL_checkstring(L, -1); - if(buf) - { - wibox_set_orientation(L, -3, orientation_fromstr(buf)); - } - return 0; -} - -/** Get the wibox orientation. - * \param L The Lua VM state. - * \param wibox The wibox object. - * \return The number of elements pushed on stack. - */ -static int -luaA_wibox_get_orientation(lua_State *L, wibox_t *wibox) -{ - lua_pushstring(L, orientation_tostr(wibox->orientation)); - return 1; -} - -/** Set the wibox visibility. - * \param L The Lua VM state. - * \param wibox The wibox object. - * \return The number of elements pushed on stack. - */ -static int -luaA_wibox_set_visible(lua_State *L, wibox_t *wibox) -{ - wibox_set_visible(L, -3, luaA_checkboolean(L, -1)); - return 0; -} - -void -wibox_class_setup(lua_State *L) -{ - static const struct luaL_reg wibox_methods[] = - { - LUA_CLASS_METHODS(wibox) - { "__call", luaA_wibox_new }, - { NULL, NULL } - }; - - static const struct luaL_reg wibox_meta[] = - { - LUA_OBJECT_META(wibox) - LUA_CLASS_META - { "geometry", luaA_wibox_geometry }, - { NULL, NULL }, - }; - - luaA_class_setup(L, &wibox_class, "wibox", &window_class, - (lua_class_allocator_t) wibox_new, - (lua_class_collector_t) wibox_wipe, - NULL, - luaA_class_index_miss_property, luaA_class_newindex_miss_property, - wibox_methods, wibox_meta); - luaA_class_add_property(&wibox_class, "visible", - (lua_class_propfunc_t) luaA_wibox_set_visible, - (lua_class_propfunc_t) luaA_wibox_get_visible, - (lua_class_propfunc_t) luaA_wibox_set_visible); - luaA_class_add_property(&wibox_class, "orientation", - (lua_class_propfunc_t) luaA_wibox_set_orientation, - (lua_class_propfunc_t) luaA_wibox_get_orientation, - (lua_class_propfunc_t) luaA_wibox_set_orientation); - luaA_class_add_property(&wibox_class, "ontop", - (lua_class_propfunc_t) luaA_wibox_set_ontop, - (lua_class_propfunc_t) luaA_wibox_get_ontop, - (lua_class_propfunc_t) luaA_wibox_set_ontop); - luaA_class_add_property(&wibox_class, "screen", - NULL, - (lua_class_propfunc_t) luaA_wibox_get_screen, - (lua_class_propfunc_t) luaA_wibox_set_screen); - luaA_class_add_property(&wibox_class, "cursor", - (lua_class_propfunc_t) luaA_wibox_set_cursor, - (lua_class_propfunc_t) luaA_wibox_get_cursor, - (lua_class_propfunc_t) luaA_wibox_set_cursor); - luaA_class_add_property(&wibox_class, "fg", - (lua_class_propfunc_t) luaA_wibox_set_fg, - (lua_class_propfunc_t) luaA_wibox_get_fg, - (lua_class_propfunc_t) luaA_wibox_set_fg); - luaA_class_add_property(&wibox_class, "bg", - (lua_class_propfunc_t) luaA_wibox_set_bg, - (lua_class_propfunc_t) luaA_wibox_get_bg, - (lua_class_propfunc_t) luaA_wibox_set_bg); - luaA_class_add_property(&wibox_class, "bg_image", - (lua_class_propfunc_t) luaA_wibox_set_bg_image, - (lua_class_propfunc_t) luaA_wibox_get_bg_image, - (lua_class_propfunc_t) luaA_wibox_set_bg_image); - luaA_class_add_property(&wibox_class, "x", - (lua_class_propfunc_t) luaA_wibox_set_x, - (lua_class_propfunc_t) luaA_wibox_get_x, - (lua_class_propfunc_t) luaA_wibox_set_x); - luaA_class_add_property(&wibox_class, "y", - (lua_class_propfunc_t) luaA_wibox_set_y, - (lua_class_propfunc_t) luaA_wibox_get_y, - (lua_class_propfunc_t) luaA_wibox_set_y); - luaA_class_add_property(&wibox_class, "width", - (lua_class_propfunc_t) luaA_wibox_set_width, - (lua_class_propfunc_t) luaA_wibox_get_width, - (lua_class_propfunc_t) luaA_wibox_set_width); - luaA_class_add_property(&wibox_class, "height", - (lua_class_propfunc_t) luaA_wibox_set_height, - (lua_class_propfunc_t) luaA_wibox_get_height, - (lua_class_propfunc_t) luaA_wibox_set_height); - luaA_class_add_property(&wibox_class, "type", - (lua_class_propfunc_t) luaA_window_set_type, - (lua_class_propfunc_t) luaA_window_get_type, - (lua_class_propfunc_t) luaA_window_set_type); - - signal_add(&wibox_class.signals, "mouse::enter"); - signal_add(&wibox_class.signals, "mouse::leave"); - signal_add(&wibox_class.signals, "property::bg"); - signal_add(&wibox_class.signals, "property::bg_image"); - signal_add(&wibox_class.signals, "property::border_width"); - signal_add(&wibox_class.signals, "property::cursor"); - signal_add(&wibox_class.signals, "property::fg"); - signal_add(&wibox_class.signals, "property::height"); - signal_add(&wibox_class.signals, "property::ontop"); - signal_add(&wibox_class.signals, "property::orientation"); - signal_add(&wibox_class.signals, "property::screen"); - signal_add(&wibox_class.signals, "property::visible"); - signal_add(&wibox_class.signals, "property::widgets"); - signal_add(&wibox_class.signals, "property::width"); - signal_add(&wibox_class.signals, "property::x"); - signal_add(&wibox_class.signals, "property::y"); -} - -// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/property.c b/property.c index ed45c8c0c..4cf122849 100644 --- a/property.c +++ b/property.c @@ -25,7 +25,7 @@ #include "property.h" #include "objects/client.h" #include "ewmh.h" -#include "objects/wibox.h" +#include "objects/drawin.h" #include "xwindow.h" #include "luaa.h" #include "common/atoms.h" @@ -334,7 +334,7 @@ property_handle_xrootpmap_id(uint8_t state, { #warning #if 0 - foreach(w, globalconf.wiboxes) + foreach(w, globalconf.drawins) (*w)->need_update = true; #endif @@ -345,12 +345,12 @@ static int property_handle_net_wm_opacity(uint8_t state, xcb_window_t window) { - wibox_t *wibox = wibox_getbywin(window); + drawin_t *drawin = drawin_getbywin(window); - if(wibox) + if(drawin) { - luaA_object_push(globalconf.L, wibox); - window_set_opacity(globalconf.L, -1, xwindow_get_opacity(wibox->window)); + luaA_object_push(globalconf.L, drawin); + window_set_opacity(globalconf.L, -1, xwindow_get_opacity(drawin->window)); lua_pop(globalconf.L, -1); } else diff --git a/root.c b/root.c index bbcce6031..9a699f1de 100644 --- a/root.c +++ b/root.c @@ -23,7 +23,7 @@ #include "globalconf.h" #include "objects/button.h" -#include "objects/wibox.h" +#include "objects/drawin.h" #include "luaa.h" #include "xwindow.h" #include "common/xcursor.h" @@ -202,20 +202,20 @@ luaA_root_cursor(lua_State *L) return 0; } -/** Get the wiboxes attached to a screen. +/** Get the drawins attached to a screen. * \param L The Lua VM state. * \return The number of element pushed on stack. * \luastack - * \lreturn A table with all wiboxes. + * \lreturn A table with all drawins. */ static int -luaA_root_wiboxes(lua_State *L) +luaA_root_drawins(lua_State *L) { - lua_createtable(L, globalconf.wiboxes.len, 0); + lua_createtable(L, globalconf.drawins.len, 0); - for(int i = 0; i < globalconf.wiboxes.len; i++) + for(int i = 0; i < globalconf.drawins.len; i++) { - luaA_object_push(L, globalconf.wiboxes.tab[i]); + luaA_object_push(L, globalconf.drawins.tab[i]); lua_rawseti(L, -2, i + 1); } @@ -228,7 +228,7 @@ const struct luaL_reg awesome_root_lib[] = { "keys", luaA_root_keys }, { "cursor", luaA_root_cursor }, { "fake_input", luaA_root_fake_input }, - { "wiboxes", luaA_root_wiboxes }, + { "drawins", luaA_root_drawins }, { NULL, NULL } }; diff --git a/screen.c b/screen.c index 651efa610..2c0838f57 100644 --- a/screen.c +++ b/screen.c @@ -29,7 +29,7 @@ #include "ewmh.h" #include "objects/tag.h" #include "objects/client.h" -#include "objects/wibox.h" +#include "objects/drawin.h" #include "luaa.h" #include "common/xutil.h" @@ -298,10 +298,10 @@ screen_area_get(screen_t *screen, bool strut) if(client_isvisible(*c, screen)) COMPUTE_STRUT(*c) - foreach(wibox, globalconf.wiboxes) - if((*wibox)->visible - && (*wibox)->screen == screen) - COMPUTE_STRUT(*wibox) + foreach(drawin, globalconf.drawins) + if((*drawin)->visible + && (*drawin)->screen == screen) + COMPUTE_STRUT(*drawin) #undef COMPUTE_STRUT diff --git a/stack.c b/stack.c index 3758c13c3..33f4365ba 100644 --- a/stack.c +++ b/stack.c @@ -23,7 +23,7 @@ #include "screen.h" #include "stack.h" #include "objects/client.h" -#include "objects/wibox.h" +#include "objects/drawin.h" void stack_client_remove(client_t *c) @@ -174,12 +174,12 @@ stack_refresh() if(client_layer_translator(*node) == layer) next = stack_client_above(*node, next); - /* first stack not ontop wibox window */ - foreach(wibox, globalconf.wiboxes) - if(!(*wibox)->ontop) + /* first stack not ontop drawin window */ + foreach(drawin, globalconf.drawins) + if(!(*drawin)->ontop) { - stack_window_above((*wibox)->window, next); - next = (*wibox)->window; + stack_window_above((*drawin)->window, next); + next = (*drawin)->window; } /* then stack clients */ @@ -188,12 +188,12 @@ stack_refresh() if(client_layer_translator(*node) == layer) next = stack_client_above(*node, next); - /* then stack ontop wibox window */ - foreach(wibox, globalconf.wiboxes) - if((*wibox)->ontop) + /* then stack ontop drawin window */ + foreach(drawin, globalconf.drawins) + if((*drawin)->ontop) { - stack_window_above((*wibox)->window, next); - next = (*wibox)->window; + stack_window_above((*drawin)->window, next); + next = (*drawin)->window; } need_stack_refresh = false; diff --git a/systray.c b/systray.c index 66ad6d914..1b55cc082 100644 --- a/systray.c +++ b/systray.c @@ -26,7 +26,6 @@ #include "screen.h" #include "systray.h" #include "xwindow.h" -#include "objects/wibox.h" #include "common/array.h" #include "common/atoms.h" #include "common/xutil.h"