diff --git a/awesome.c b/awesome.c index 90c05fd62..9f53a25df 100644 --- a/awesome.c +++ b/awesome.c @@ -228,7 +228,7 @@ setup_screen(awesome_config *awesomeconf, int screen) setup(awesomeconf, screen); statusbar_init(awesomeconf->display, screen, &awesomeconf->screens[screen].statusbar, awesomeconf->cursor[CurNormal], awesomeconf->screens[screen].font, - awesomeconf->screens[screen].layouts, &awesomeconf->screens[screen].padding); + &awesomeconf->screens[screen].padding); } /** Startup Error handler to check if another window manager diff --git a/draw.c b/draw.c index 61c4d71cf..6b3069e65 100644 --- a/draw.c +++ b/draw.c @@ -27,8 +27,33 @@ #include "util.h" #include "draw.h" + +DrawCtx * +draw_get_context(Display *display, int phys_screen, int width, int height) +{ + DrawCtx *d; + d = p_new(DrawCtx, 1); + d->phys_screen = phys_screen; + d->display = display; + d->width = width; + d->height = height; + d->depth = DefaultDepth(display, phys_screen); + d->visual = DefaultVisual(display, phys_screen); + d->drawable = XCreatePixmap(display, + RootWindow(display, phys_screen), + width, height, d->depth); + return d; +}; + +void +draw_free_context(DrawCtx *ctx) +{ + XFreePixmap(ctx->display, ctx->drawable); + p_delete(&ctx); +} + void -drawtext(Display *disp, int screen, int x, int y, int w, int h, Drawable drawable, int dw, int dh, XftFont *font, const char *text, XColor color[ColLast]) +drawtext(DrawCtx *ctx, int x, int y, int w, int h, XftFont *font, const char *text, XColor color[ColLast]) { int nw = 0; static char buf[256]; @@ -37,11 +62,11 @@ drawtext(Display *disp, int screen, int x, int y, int w, int h, Drawable drawabl cairo_surface_t *surface; cairo_t *cr; - drawrectangle(disp, screen, x, y, w, h, drawable, dw, dh, True, color[ColBG]); + drawrectangle(ctx, x, y, w, h, True, color[ColBG]); if(!a_strlen(text)) return; - surface = cairo_xlib_surface_create(disp, drawable, DefaultVisual(disp, screen), dw, dh); + surface = cairo_xlib_surface_create(ctx->display, ctx->drawable, ctx->visual, ctx->width, ctx->height); cr = cairo_create(surface); font_face = cairo_ft_font_face_create_for_pattern(font->pattern); cairo_set_font_face(cr, font_face); @@ -53,7 +78,7 @@ drawtext(Display *disp, int screen, int x, int y, int w, int h, Drawable drawabl len = sizeof(buf) - 1; memcpy(buf, text, len); buf[len] = 0; - while(len && (nw = textwidth(disp, font, buf)) > w) + while(len && (nw = textwidth(ctx, font, buf)) > w) buf[--len] = 0; if(nw > w) return; /* too long */ @@ -67,7 +92,7 @@ drawtext(Display *disp, int screen, int x, int y, int w, int h, Drawable drawabl buf[len - 3] = '.'; } - cairo_move_to(cr, x + font->height / 2, y + font->ascent + (dh - font->height) / 2); + cairo_move_to(cr, x + font->height / 2, y + font->ascent + (ctx->height - font->height) / 2); cairo_show_text(cr, buf); cairo_font_face_destroy(font_face); @@ -76,12 +101,12 @@ drawtext(Display *disp, int screen, int x, int y, int w, int h, Drawable drawabl } void -drawrectangle(Display *disp, int screen, int x, int y, int w, int h, Drawable drawable, int dw, int dh, Bool filled, XColor color) +drawrectangle(DrawCtx *ctx, int x, int y, int w, int h, Bool filled, XColor color) { cairo_surface_t *surface; cairo_t *cr; - surface = cairo_xlib_surface_create(disp, drawable, DefaultVisual(disp, screen), dw, dh); + surface = cairo_xlib_surface_create(ctx->display, ctx->drawable, ctx->visual, ctx->width, ctx->height); cr = cairo_create (surface); cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); @@ -102,12 +127,12 @@ drawrectangle(Display *disp, int screen, int x, int y, int w, int h, Drawable dr } void -drawcircle(Display *disp, int screen, int x, int y, int r, Drawable drawable, int dw, int dh, Bool filled, XColor color) +drawcircle(DrawCtx *ctx, int x, int y, int r, Bool filled, XColor color) { cairo_surface_t *surface; cairo_t *cr; - surface = cairo_xlib_surface_create(disp, drawable, DefaultVisual(disp, screen), dw, dh); + surface = cairo_xlib_surface_create(ctx->display, ctx->drawable, ctx->visual, ctx->width, ctx->height); cr = cairo_create (surface); cairo_set_line_width(cr, 1.0); cairo_set_source_rgb(cr, color.red / 65535.0, color.green / 65535.0, color.blue / 65535.0); @@ -126,18 +151,18 @@ drawcircle(Display *disp, int screen, int x, int y, int r, Drawable drawable, in } Drawable -draw_rotate(Display *disp, int screen, Drawable drawable, int dw, int dh, double angle, int tx, int ty) +draw_rotate(DrawCtx *ctx, int screen, double angle, int tx, int ty) { cairo_surface_t *surface, *source; cairo_t *cr; Drawable newdrawable; - newdrawable = XCreatePixmap(disp, - RootWindow(disp, screen), - dh, dw, - DefaultDepth(disp, screen)); - surface = cairo_xlib_surface_create(disp, newdrawable, DefaultVisual(disp, screen), dh, dw); - source = cairo_xlib_surface_create(disp, drawable, DefaultVisual(disp, screen), dw, dh); + newdrawable = XCreatePixmap(ctx->display, + RootWindow(ctx->display, screen), + ctx->height, ctx->width, + ctx->depth); + surface = cairo_xlib_surface_create(ctx->display, newdrawable, ctx->visual, ctx->height, ctx->width); + source = cairo_xlib_surface_create(ctx->display, ctx->drawable, ctx->visual, ctx->width, ctx->height); cr = cairo_create (surface); cairo_translate(cr, tx, ty); @@ -153,18 +178,19 @@ draw_rotate(Display *disp, int screen, Drawable drawable, int dw, int dh, double return newdrawable; } + unsigned short -textwidth(Display *disp, XftFont *font, char *text) +textwidth_primitive(Display *display, XftFont *font, char *text) { cairo_surface_t *surface; cairo_t *cr; cairo_font_face_t *font_face; cairo_text_extents_t te; - surface = cairo_xlib_surface_create(disp, DefaultScreen(disp), - DefaultVisual(disp, DefaultScreen(disp)), - DisplayWidth(disp, DefaultScreen(disp)), - DisplayHeight(disp, DefaultScreen(disp))); + surface = cairo_xlib_surface_create(display, DefaultScreen(display), + DefaultVisual(display, DefaultScreen(display)), + DisplayWidth(display, DefaultScreen(display)), + DisplayHeight(display, DefaultScreen(display))); cr = cairo_create(surface); font_face = cairo_ft_font_face_create_for_pattern(font->pattern); cairo_set_font_face(cr, font_face); @@ -177,4 +203,10 @@ textwidth(Display *disp, XftFont *font, char *text) return MAX(te.x_advance, te.width) + font->height; } +unsigned short +textwidth(DrawCtx *ctx, XftFont *font, char *text) +{ + return textwidth_primitive(ctx->display, font, text); +} + // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 diff --git a/draw.h b/draw.h index f001481c8..60e21bb64 100644 --- a/draw.h +++ b/draw.h @@ -24,10 +24,25 @@ #include "config.h" -void drawtext(Display *, int, int, int, int, int, Drawable, int, int, XftFont *, const char *, XColor []); -void drawrectangle(Display *, int, int, int, int, int, Drawable, int, int, Bool, XColor); -void drawcircle(Display *, int, int, int, int, Drawable, int, int, Bool, XColor); -Drawable draw_rotate(Display *, int, Drawable, int, int, double, int, int); -unsigned short textwidth(Display *, XftFont *, char *); +typedef struct DrawCtx DrawCtx; +struct DrawCtx +{ + Display *display; + Drawable drawable; + Visual *visual; + int width; + int height; + int phys_screen; + int depth; +}; + +DrawCtx *draw_get_context(Display*, int, int, int); +void draw_free_context(DrawCtx*); +void drawtext(DrawCtx *, int, int, int, int, XftFont *, const char *, XColor []); +void drawrectangle(DrawCtx *, int, int, int, int, Bool, XColor); +void drawcircle(DrawCtx *, int, int, int, Bool, XColor); +Drawable draw_rotate(DrawCtx *, int, double, int, int); +unsigned short textwidth(DrawCtx *, XftFont *, char *); +unsigned short textwidth_primitive(Display*, XftFont*, char*); #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 diff --git a/event.c b/event.c index f770c962d..0064a136a 100644 --- a/event.c +++ b/event.c @@ -73,7 +73,7 @@ handle_event_buttonpress(XEvent * e, awesome_config *awesomeconf) { for(i = 1, tag = awesomeconf->screens[screen].tags; tag; tag = tag->next, i++) { - x += textwidth(e->xany.display, awesomeconf->screens[screen].font, tag->name); + x += textwidth_primitive(e->xany.display, awesomeconf->screens[screen].font, awesomeconf->screens[screen].tags[i].name); if(((awesomeconf->screens[screen].statusbar.position == BarTop || awesomeconf->screens[screen].statusbar.position == BarBot) && ev->x < x) diff --git a/statusbar.c b/statusbar.c index 08a2c22f5..900597d89 100644 --- a/statusbar.c +++ b/statusbar.c @@ -52,157 +52,122 @@ statusbar_draw(awesome_config *awesomeconf, int screen) { int z, x = 0, y = 0, w; Client *sel = awesomeconf->focus->client; - Drawable drawable; int phys_screen = get_phys_screen(awesomeconf->display, screen); + Statusbar sbar; Tag *tag; - + Layout *layout; + + sbar = awesomeconf->screens[screen].statusbar; + DrawCtx *ctx = draw_get_context(awesomeconf->display, phys_screen, sbar.width, sbar.height); /* don't waste our time */ - if(awesomeconf->screens[screen].statusbar.position == BarOff) + if(sbar.position == BarOff) return; - drawable = XCreatePixmap(awesomeconf->display, - RootWindow(awesomeconf->display, phys_screen), - awesomeconf->screens[screen].statusbar.width, - awesomeconf->screens[screen].statusbar.height, - DefaultDepth(awesomeconf->display, phys_screen)); - for(tag = awesomeconf->screens[screen].tags; tag; tag = tag->next) { - w = textwidth(awesomeconf->display, awesomeconf->screens[screen].font, tag->name); + w = textwidth(ctx, awesomeconf->screens[screen].font, tag->name); if(tag->selected) { - drawtext(awesomeconf->display, phys_screen, - x, y, w, - awesomeconf->screens[screen].statusbar.height, - drawable, - awesomeconf->screens[screen].statusbar.width, - awesomeconf->screens[screen].statusbar.height, + drawtext(ctx, x, y, w, + sbar.height, awesomeconf->screens[screen].font, - tag->name, awesomeconf->screens[screen].colors_selected); + tag->name, + awesomeconf->screens[screen].colors_selected); if(isoccupied(awesomeconf->screens[screen].tclink, screen, awesomeconf->clients, tag)) - drawrectangle(awesomeconf->display, phys_screen, - x, y, + drawrectangle(ctx, x, y, (awesomeconf->screens[screen].font->height + 2) / 4, (awesomeconf->screens[screen].font->height + 2) / 4, - drawable, - awesomeconf->screens[screen].statusbar.width, - awesomeconf->screens[screen].statusbar.height, sel && is_client_tagged(awesomeconf->screens[screen].tclink, sel, tag), awesomeconf->screens[screen].colors_selected[ColFG]); } else { - drawtext(awesomeconf->display, phys_screen, - x, y, w, - awesomeconf->screens[screen].statusbar.height, - drawable, - awesomeconf->screens[screen].statusbar.width, - awesomeconf->screens[screen].statusbar.height, + drawtext(ctx, x, y, w, + sbar.height, awesomeconf->screens[screen].font, - tag->name, awesomeconf->screens[screen].colors_normal); + tag->name, + awesomeconf->screens[screen].colors_normal); if(isoccupied(awesomeconf->screens[screen].tclink, screen, awesomeconf->clients, tag)) - drawrectangle(awesomeconf->display, phys_screen, - x, y, + drawrectangle(ctx, x, y, (awesomeconf->screens[screen].font->height + 2) / 4, (awesomeconf->screens[screen].font->height + 2) / 4, - drawable, - awesomeconf->screens[screen].statusbar.width, - awesomeconf->screens[screen].statusbar.height, sel && is_client_tagged(awesomeconf->screens[screen].tclink, sel, tag), awesomeconf->screens[screen].colors_normal[ColFG]); } x += w; } - drawtext(awesomeconf->display, phys_screen, - x, y, awesomeconf->screens[screen].statusbar.txtlayoutwidth, - awesomeconf->screens[screen].statusbar.height, - drawable, - awesomeconf->screens[screen].statusbar.width, - awesomeconf->screens[screen].statusbar.height, + + /* This is only here until we refactor this function. */ + for(layout = awesomeconf->screens[screen].layouts; layout; layout = layout->next) + sbar.txtlayoutwidth = MAX(sbar.txtlayoutwidth, + textwidth(ctx, awesomeconf->screens[screen].font, layout->symbol)); + drawtext(ctx, x, y, + sbar.txtlayoutwidth, + sbar.height, awesomeconf->screens[screen].font, get_current_layout(awesomeconf->screens[screen])->symbol, awesomeconf->screens[screen].colors_normal); - z = x + awesomeconf->screens[screen].statusbar.txtlayoutwidth; - w = textwidth(awesomeconf->display, awesomeconf->screens[screen].font, awesomeconf->screens[screen].statustext); - x = awesomeconf->screens[screen].statusbar.width - w; + z = x + sbar.txtlayoutwidth; + w = textwidth(ctx, awesomeconf->screens[screen].font, awesomeconf->screens[screen].statustext); + x = sbar.width - w; if(x < z) { x = z; - w = awesomeconf->screens[screen].statusbar.width - z; + w = sbar.width - z; } - drawtext(awesomeconf->display, phys_screen, - x, y, w, - awesomeconf->screens[screen].statusbar.height, - drawable, - awesomeconf->screens[screen].statusbar.width, - awesomeconf->screens[screen].statusbar.height, + drawtext(ctx, x, y, w, + sbar.height, awesomeconf->screens[screen].font, - awesomeconf->screens[screen].statustext, awesomeconf->screens[screen].colors_normal); - if((w = x - z) > awesomeconf->screens[screen].statusbar.height) + awesomeconf->screens[screen].statustext, + awesomeconf->screens[screen].colors_normal); + if((w = x - z) > sbar.height) { x = z; if(sel && sel->screen == screen) { - drawtext(awesomeconf->display, phys_screen, - x, y, w, - awesomeconf->screens[screen].statusbar.height, - drawable, - awesomeconf->screens[screen].statusbar.width, - awesomeconf->screens[screen].statusbar.height, + drawtext(ctx, x, y, w, + sbar.height, awesomeconf->screens[screen].font, - sel->name, awesomeconf->screens[screen].colors_selected); + sel->name, + awesomeconf->screens[screen].colors_selected); if(sel->isfloating) - drawcircle(awesomeconf->display, phys_screen, - x, y, + drawcircle(ctx, x, y, (awesomeconf->screens[screen].font->height + 2) / 4, - drawable, - awesomeconf->screens[screen].statusbar.width, - awesomeconf->screens[screen].statusbar.height, sel->ismax, awesomeconf->screens[screen].colors_selected[ColFG]); } else - drawtext(awesomeconf->display, phys_screen, - x, y, w, - awesomeconf->screens[screen].statusbar.height, - drawable, - awesomeconf->screens[screen].statusbar.width, - awesomeconf->screens[screen].statusbar.height, + drawtext(ctx, x, y, w, + sbar.height, awesomeconf->screens[screen].font, NULL, awesomeconf->screens[screen].colors_normal); } - if(awesomeconf->screens[screen].statusbar.position == BarRight - || awesomeconf->screens[screen].statusbar.position == BarLeft) + if(sbar.position == BarRight || sbar.position == BarLeft) { Drawable d; - if(awesomeconf->screens[screen].statusbar.position == BarRight) - d = draw_rotate(awesomeconf->display, phys_screen, drawable, - awesomeconf->screens[screen].statusbar.width, awesomeconf->screens[screen].statusbar.height, - M_PI_2, awesomeconf->screens[screen].statusbar.height, 0); + if(sbar.position == BarRight) + d = draw_rotate(ctx, phys_screen, M_PI_2, sbar.height, 0); else - d = draw_rotate(awesomeconf->display, phys_screen, drawable, - awesomeconf->screens[screen].statusbar.width, awesomeconf->screens[screen].statusbar.height, - - M_PI_2, 0, awesomeconf->screens[screen].statusbar.width); + d = draw_rotate(ctx, phys_screen, - M_PI_2, 0, sbar.width); XCopyArea(awesomeconf->display, d, - awesomeconf->screens[screen].statusbar.window, + sbar.window, DefaultGC(awesomeconf->display, phys_screen), 0, 0, - awesomeconf->screens[screen].statusbar.height, awesomeconf->screens[screen].statusbar.width, 0, 0); + sbar.height, + sbar.width, 0, 0); XFreePixmap(awesomeconf->display, d); } else - XCopyArea(awesomeconf->display, drawable, - awesomeconf->screens[screen].statusbar.window, + XCopyArea(awesomeconf->display, ctx->drawable, + sbar.window, DefaultGC(awesomeconf->display, phys_screen), 0, 0, - awesomeconf->screens[screen].statusbar.width, awesomeconf->screens[screen].statusbar.height, 0, 0); - XFreePixmap(awesomeconf->display, drawable); + sbar.width, sbar.height, 0, 0); + draw_free_context(ctx); XSync(awesomeconf->display, False); } void -statusbar_init(Display *disp, int screen, Statusbar *statusbar, - Cursor cursor, XftFont *font, Layout *layouts, Padding *padding) +statusbar_init(Display *disp, int screen, Statusbar *statusbar, Cursor cursor, XftFont *font, Padding *padding) { - Layout *l; XSetWindowAttributes wa; int phys_screen = get_phys_screen(disp, screen); ScreenInfo *si = get_screen_info(disp, screen, NULL, padding); @@ -241,10 +206,6 @@ statusbar_init(Display *disp, int screen, Statusbar *statusbar, XDefineCursor(disp, statusbar->window, cursor); statusbar_update_position(disp, *statusbar, padding); XMapRaised(disp, statusbar->window); - - for(l = layouts ; l; l = l->next) - statusbar->txtlayoutwidth = MAX(statusbar->txtlayoutwidth, - (textwidth(disp, font, l->symbol))); } void diff --git a/statusbar.h b/statusbar.h index cc599a7e7..c69472e36 100644 --- a/statusbar.h +++ b/statusbar.h @@ -24,7 +24,7 @@ #include "common.h" -void statusbar_init(Display *, int, Statusbar *, Cursor, XftFont *, Layout *, Padding *); +void statusbar_init(Display *, int, Statusbar *, Cursor, XftFont *, Padding *); void statusbar_draw(awesome_config *, int); int statusbar_get_position_from_str(const char *); void statusbar_update_position(Display *, Statusbar, Padding *);