diff --git a/statusbar.c b/statusbar.c index 8d1c9273c..8855d3c92 100644 --- a/statusbar.c +++ b/statusbar.c @@ -19,9 +19,6 @@ * */ -#include -#include - #include #include @@ -40,113 +37,15 @@ extern bool running; static void statusbar_draw(statusbar_t *statusbar) { - xcb_window_t rootwin; - xcb_pixmap_t rootpix; - widget_node_t *w; - int left = 0, right = 0; - char *data; - xcb_get_property_reply_t *prop_r; - xcb_get_property_cookie_t prop_c; - area_t rectangle = { 0, 0, 0, 0, NULL, NULL }, rootsize;; - xcb_atom_t rootpix_atom, pixmap_atom; - xutil_intern_atom_request_t rootpix_atom_req, pixmap_atom_req; - statusbar->need_update = false; if(!statusbar->position) return; - /* Send requests needed for transparency */ - if(statusbar->colors.bg.alpha != 0xffff) - { - pixmap_atom_req = xutil_intern_atom(globalconf.connection, &globalconf.atoms, "PIXMAP"); - rootpix_atom_req = xutil_intern_atom(globalconf.connection, &globalconf.atoms, "_XROOTPMAP_ID"); - } - - rectangle.width = statusbar->width; - rectangle.height = statusbar->height; - - if(statusbar->colors.bg.alpha != 0xffff) - { - rootwin = xcb_aux_get_screen(globalconf.connection, statusbar->phys_screen)->root; - pixmap_atom = xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms, pixmap_atom_req); - rootpix_atom = xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms, rootpix_atom_req); - prop_c = xcb_get_property_unchecked(globalconf.connection, false, rootwin, rootpix_atom, - pixmap_atom, 0, 1); - if((prop_r = xcb_get_property_reply(globalconf.connection, prop_c, NULL))) - { - if((data = xcb_get_property_value(prop_r))) - { - rootpix = *(xcb_pixmap_t *) data; - switch(statusbar->position) - { - case Left: - rootsize = get_display_area(statusbar->phys_screen, NULL, NULL); - draw_rotate(statusbar->ctx, - rootpix, statusbar->ctx->drawable, - rootsize.width, rootsize.height, - statusbar->width, statusbar->height, - M_PI_2, - statusbar->sw->geometry.y + statusbar->width, - - statusbar->sw->geometry.x); - break; - case Right: - rootsize = get_display_area(statusbar->phys_screen, NULL, NULL); - draw_rotate(statusbar->ctx, - rootpix, statusbar->ctx->drawable, - rootsize.width, rootsize.height, - statusbar->width, statusbar->height, - - M_PI_2, - - statusbar->sw->geometry.y, - statusbar->sw->geometry.x + statusbar->height); - break; - default: - xcb_copy_area(globalconf.connection, rootpix, - statusbar->sw->drawable, statusbar->sw->gc, - statusbar->sw->geometry.x, statusbar->sw->geometry.y, - 0, 0, - statusbar->sw->geometry.width, - statusbar->sw->geometry.height); - break; - } - } - p_delete(&prop_r); - } - } - - draw_rectangle(statusbar->ctx, rectangle, 1.0, true, - statusbar->colors.bg); - - for(w = statusbar->widgets; w; w = w->next) - if(w->widget->isvisible && w->widget->align == AlignLeft) - left += w->widget->draw(statusbar->ctx, statusbar->screen, w, left, (left + right), statusbar); - - /* renders right widget from last to first */ - for(w = *widget_node_list_last(&statusbar->widgets); w; w = w->prev) - if(w->widget->isvisible && w->widget->align == AlignRight) - right += w->widget->draw(statusbar->ctx, statusbar->screen, w, right, (left + right), statusbar); - - for(w = statusbar->widgets; w; w = w->next) - if(w->widget->isvisible && w->widget->align == AlignFlex) - left += w->widget->draw(statusbar->ctx, statusbar->screen, w, left, (left + right), statusbar); - - switch(statusbar->position) - { - case Right: - draw_rotate(statusbar->ctx, statusbar->ctx->drawable, statusbar->sw->drawable, - statusbar->ctx->width, statusbar->ctx->height, - statusbar->ctx->height, statusbar->ctx->width, - M_PI_2, statusbar->height, 0); - break; - case Left: - draw_rotate(statusbar->ctx, statusbar->ctx->drawable, statusbar->sw->drawable, - statusbar->ctx->width, statusbar->ctx->height, - statusbar->ctx->height, statusbar->ctx->width, - - M_PI_2, 0, statusbar->width); - break; - default: - break; - } + widget_render(statusbar->widgets, statusbar->ctx, statusbar->sw->drawable, + statusbar->screen, statusbar->position, + statusbar->sw->geometry.x, statusbar->sw->geometry.y, + statusbar); simplewindow_refresh_drawable(statusbar->sw); xcb_aux_sync(globalconf.connection); diff --git a/widget.c b/widget.c index 4b903937f..640ce3d62 100644 --- a/widget.c +++ b/widget.c @@ -20,9 +20,15 @@ * */ +#include + +#include +#include + #include "widget.h" #include "statusbar.h" #include "event.h" +#include "screen.h" #include "lua.h" extern awesome_t globalconf; @@ -102,6 +108,124 @@ widget_common_tell(widget_t *widget, return WIDGET_ERROR_CUSTOM; } +/** Render a list of widgets. + * \param wnode The list of widgets. + * \param ctx The draw context where to render. + * \param rotate_dw The rotate drawable: where to rotate and render the final + * \param screen The logical screen used to render. + * \param position The object position. + * \param x The x coordinates of the object. + * \param y The y coordinates of the object. + * drawable when the object position is right or left. + * \param object The object pointer. + */ +void +widget_render(widget_node_t *wnode, draw_context_t *ctx, xcb_drawable_t rotate_dw, + int screen, position_t position, + int x, int y, void *object) +{ + xcb_window_t rootwin; + xcb_pixmap_t rootpix; + widget_node_t *w; + int left = 0, right = 0; + char *data; + xcb_get_property_reply_t *prop_r; + xcb_get_property_cookie_t prop_c; + area_t rectangle = { 0, 0, 0, 0, NULL, NULL }, rootsize; + xcb_atom_t rootpix_atom, pixmap_atom; + xutil_intern_atom_request_t rootpix_atom_req, pixmap_atom_req; + + /* Send requests needed for transparency */ + if(ctx->bg.alpha != 0xffff) + { + pixmap_atom_req = xutil_intern_atom(globalconf.connection, &globalconf.atoms, "PIXMAP"); + rootpix_atom_req = xutil_intern_atom(globalconf.connection, &globalconf.atoms, "_XROOTPMAP_ID"); + } + + rectangle.width = ctx->width; + rectangle.height = ctx->height; + + if(ctx->bg.alpha != 0xffff) + { + rootwin = xcb_aux_get_screen(globalconf.connection, ctx->phys_screen)->root; + pixmap_atom = xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms, pixmap_atom_req); + rootpix_atom = xutil_intern_atom_reply(globalconf.connection, &globalconf.atoms, rootpix_atom_req); + prop_c = xcb_get_property_unchecked(globalconf.connection, false, rootwin, rootpix_atom, + pixmap_atom, 0, 1); + if((prop_r = xcb_get_property_reply(globalconf.connection, prop_c, NULL))) + { + if((data = xcb_get_property_value(prop_r))) + { + rootpix = *(xcb_pixmap_t *) data; + rootsize = get_display_area(ctx->phys_screen, NULL, NULL); + switch(position) + { + case Left: + draw_rotate(ctx, + rootpix, ctx->drawable, + rootsize.width, rootsize.height, + ctx->width, ctx->height, + M_PI_2, + y + ctx->width, + - x); + break; + case Right: + draw_rotate(ctx, + rootpix, ctx->drawable, + rootsize.width, rootsize.height, + ctx->width, ctx->height, + - M_PI_2, + - y, + x + ctx->height); + break; + default: + draw_rotate(ctx, + rootpix, ctx->drawable, + rootsize.width, rootsize.height, + ctx->width, ctx->height, + 0, x, y); + break; + } + } + p_delete(&prop_r); + } + } + + draw_rectangle(ctx, rectangle, 1.0, true, ctx->bg); + + for(w = wnode; w; w = w->next) + if(w->widget->isvisible && w->widget->align == AlignLeft) + left += w->widget->draw(ctx, screen, w, left, (left + right), object); + + /* renders right widget from last to first */ + for(w = *widget_node_list_last(&wnode); w; w = w->prev) + if(w->widget->isvisible && w->widget->align == AlignRight) + right += w->widget->draw(ctx, screen, w, right, (left + right), object); + + for(w = wnode; w; w = w->next) + if(w->widget->isvisible && w->widget->align == AlignFlex) + left += w->widget->draw(ctx, screen, w, left, (left + right), object); + + switch(position) + { + case Right: + draw_rotate(ctx, ctx->drawable, rotate_dw, + ctx->width, ctx->height, + ctx->height, ctx->width, + M_PI_2, ctx->height, 0); + break; + case Left: + draw_rotate(ctx, ctx->drawable, rotate_dw, + ctx->width, ctx->height, + ctx->height, ctx->width, + - M_PI_2, 0, ctx->width); + break; + default: + break; + } +} + + /** Common function for creating a widget. * \param widget The allocated widget. */ diff --git a/widget.h b/widget.h index fabb8b59d..ef3a6a621 100644 --- a/widget.h +++ b/widget.h @@ -38,6 +38,7 @@ void widget_common_new(widget_t *); widget_t * widget_getbyname(const char *); void widget_invalidate_statusbar_bywidget(widget_t *); void widget_tell_managestatus(widget_t *, widget_tell_status_t, const char *); +void widget_render(widget_node_t *, draw_context_t *, xcb_drawable_t, int, position_t, int, int, void *); widget_constructor_t taglist_new; widget_constructor_t textbox_new;