From 344c04af1267303d42e5dd6d258b4ebb6b644c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Tarl=C3=A1=20Cardoso=20Lemos?= Date: Mon, 14 Nov 2011 20:20:18 -0200 Subject: [PATCH] Implement set_font_colors. This paves the way for other font rendering backends. Fonts and colors shouldn't be specified manually from now on. --- i3-config-wizard/main.c | 20 +++++++++----------- i3-input/main.c | 9 ++++----- i3-nagbar/main.c | 28 ++++++++++------------------ i3bar/src/xcb.c | 30 +++++++++++------------------- include/libi3.h | 10 ++++++++-- libi3/font.c | 15 +++++++++++++-- src/sighandler.c | 9 +++------ src/x.c | 10 +++++----- 8 files changed, 63 insertions(+), 68 deletions(-) diff --git a/i3-config-wizard/main.c b/i3-config-wizard/main.c index a6cd760d..84a7f77e 100644 --- a/i3-config-wizard/main.c +++ b/i3-config-wizard/main.c @@ -115,11 +115,12 @@ static int handle_expose() { set_font(&font); #define txt(x, row, text) \ - draw_text(text, strlen(text), false, pixmap, pixmap_gc, x, (row - 1) * font.height + 4) + draw_text(text, strlen(text), false, pixmap, pixmap_gc,\ + x, (row - 1) * font.height + 4, 300 - x * 2) if (current_step == STEP_WELCOME) { /* restore font color */ - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#FFFFFF") }); + set_font_colors(pixmap_gc, get_colorpixel("#FFFFFF"), get_colorpixel("#000000")); txt(10, 2, "You have not configured i3 yet."); txt(10, 3, "Do you want me to generate ~/.i3/config?"); @@ -127,16 +128,16 @@ static int handle_expose() { txt(85, 7, "No, I will use the defaults"); /* green */ - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#00FF00") }); + set_font_colors(pixmap_gc, get_colorpixel("#00FF00"), get_colorpixel("#000000")); txt(25, 5, ""); /* red */ - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#FF0000") }); + set_font_colors(pixmap_gc, get_colorpixel("#FF0000"), get_colorpixel("#000000")); txt(31, 7, ""); } if (current_step == STEP_GENERATE) { - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#FFFFFF") }); + set_font_colors(pixmap_gc, get_colorpixel("#FFFFFF"), get_colorpixel("#000000")); txt(10, 2, "Please choose either:"); txt(85, 4, "Win as default modifier"); @@ -152,20 +153,18 @@ static int handle_expose() { /* the selected modifier */ set_font(&bold_font); - xcb_change_gc(conn, pixmap_gc, XCB_GC_FONT, (uint32_t[]){ bold_font.id }); + set_font_colors(pixmap_gc, get_colorpixel("#FFFFFF"), get_colorpixel("#000000")); if (modifier == MOD_Mod4) txt(31, 4, ""); else txt(31, 5, ""); /* green */ set_font(&font); - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_FONT, - (uint32_t[]) { get_colorpixel("#00FF00"), font.id }); - + set_font_colors(pixmap_gc, get_colorpixel("#00FF00"), get_colorpixel("#000000")); txt(25, 9, ""); /* red */ - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#FF0000") }); + set_font_colors(pixmap_gc, get_colorpixel("#FF0000"), get_colorpixel("#000000")); txt(31, 10, ""); } @@ -440,7 +439,6 @@ int main(int argc, char *argv[]) { xcb_numlock_mask = get_mod_mask_for(XCB_NUM_LOCK, symbols, modmap_reply); font = load_font(pattern, true); - set_font(&font); bold_font = load_font(patternbold, true); /* Open an input window */ diff --git a/i3-input/main.c b/i3-input/main.c index 3d45206d..7602e32b 100644 --- a/i3-input/main.c +++ b/i3-input/main.c @@ -94,7 +94,9 @@ static int handle_expose(void *data, xcb_connection_t *conn, xcb_expose_event_t xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &inner); /* restore font color */ - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#FFFFFF") }); + set_font_colors(pixmap_gc, get_colorpixel("#FFFFFF"), get_colorpixel("#000000")); + + /* draw the text */ uint8_t *con = concat_strings(glyphs_ucs, input_position); char *full_text = (char*)con; if (prompt != NULL) { @@ -105,7 +107,7 @@ static int handle_expose(void *data, xcb_connection_t *conn, xcb_expose_event_t memcpy(full_text + (prompt_len * 2), con, input_position * 2); } if (input_position + prompt_len != 0) - draw_text(full_text, input_position + prompt_len, true, pixmap, pixmap_gc, 4, 4); + draw_text(full_text, input_position + prompt_len, true, pixmap, pixmap_gc, 4, 4, 492); /* Copy the contents of the pixmap to the real window */ xcb_copy_area(conn, pixmap, win, pixmap_gc, 0, 0, 0, 0, /* */ 500, font.height + 8); @@ -394,9 +396,6 @@ int main(int argc, char *argv[]) { * this for us) */ xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, win, XCB_CURRENT_TIME); - /* Create graphics context */ - xcb_change_gc(conn, pixmap_gc, XCB_GC_FONT, (uint32_t[]){ font.id }); - /* Grab the keyboard to get all input */ xcb_flush(conn); diff --git a/i3-nagbar/main.c b/i3-nagbar/main.c index 525e3221..742039e2 100644 --- a/i3-nagbar/main.c +++ b/i3-nagbar/main.c @@ -131,16 +131,15 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) { xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &rect); /* restore font color */ - uint32_t values[3]; - values[0] = color_text; - values[1] = color_background; - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND, values); - draw_text(prompt, strlen(prompt), false, pixmap, pixmap_gc, 4 + 4, 4 + 4); + set_font_colors(pixmap_gc, color_text, color_background); + draw_text(prompt, strlen(prompt), false, pixmap, pixmap_gc, + 4 + 4, 4 + 4, rect.width - 4 - 4); /* render close button */ int line_width = 4; int w = 20; int y = rect.width; + uint32_t values[3]; values[0] = color_button_background; values[1] = line_width; xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_LINE_WIDTH, values); @@ -158,11 +157,10 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) { }; xcb_poly_line(conn, XCB_COORD_MODE_ORIGIN, pixmap, pixmap_gc, 5, points); - values[0] = color_text; - values[1] = color_button_background; - values[2] = 1; - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_LINE_WIDTH, values); - draw_text("X", 1, false, pixmap, pixmap_gc, y - w - line_width + w / 2 - 4, 4 + 4 - 1); + values[0] = 1; + set_font_colors(pixmap_gc, color_text, color_button_background); + draw_text("X", 1, false, pixmap, pixmap_gc, y - w - line_width + w / 2 - 4, + 4 + 4 - 1, rect.width - y + w + line_width - w / 2 + 4); y -= w; y -= 20; @@ -191,9 +189,9 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) { values[0] = color_text; values[1] = color_button_background; - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND, values); + set_font_colors(pixmap_gc, color_text, color_button_background); draw_text(buttons[c].label, strlen(buttons[c].label), false, pixmap, pixmap_gc, - y - w - line_width + 6, 4 + 3); + y - w - line_width + 6, 4 + 3, rect.width - y + w + line_width - 6); y -= w; } @@ -386,9 +384,6 @@ int main(int argc, char *argv[]) { xcb_create_pixmap(conn, root_screen->root_depth, pixmap, win, 500, font.height + 8); xcb_create_gc(conn, pixmap_gc, pixmap, 0, 0); - /* Create graphics context */ - xcb_change_gc(conn, pixmap_gc, XCB_GC_FONT, (uint32_t[]){ font.id }); - /* Grab the keyboard to get all input */ xcb_flush(conn); @@ -430,9 +425,6 @@ int main(int argc, char *argv[]) { xcb_create_pixmap(conn, root_screen->root_depth, pixmap, win, rect.width, rect.height); xcb_create_gc(conn, pixmap_gc, pixmap, 0, 0); - - /* Create graphics context */ - xcb_change_gc(conn, pixmap_gc, XCB_GC_FONT, (uint32_t[]){ font.id }); break; } } diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index df8c1199..d907d083 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -121,7 +121,9 @@ void refresh_statusline() { xcb_rectangle_t rect = { 0, 0, xcb_screen->width_in_pixels, font.height }; xcb_poly_fill_rectangle(xcb_connection, statusline_pm, statusline_clear, 1, &rect); - draw_text((char*)text, glyph_count, true, statusline_pm, statusline_ctx, 0, 0); + set_font_colors(statusline_ctx, colors.bar_fg, colors.bar_bg); + draw_text((char*)text, glyph_count, true, statusline_pm, statusline_ctx, + 0, 0, xcb_screen->width_in_pixels); FREE(text); } @@ -731,14 +733,12 @@ char *init_xcb_early() { mask, vals); - mask |= XCB_GC_BACKGROUND; - vals[0] = colors.bar_fg; statusline_ctx = xcb_generate_id(xcb_connection); xcb_void_cookie_t sl_ctx_cookie = xcb_create_gc_checked(xcb_connection, statusline_ctx, xcb_root, - mask, - vals); + 0, + NULL); statusline_pm = xcb_generate_id(xcb_connection); xcb_void_cookie_t sl_pm_cookie = xcb_create_pixmap_checked(xcb_connection, @@ -809,9 +809,6 @@ void init_xcb_late(char *fontname) { set_font(&font); DLOG("Calculated Font-height: %d\n", font.height); - /* Set the font in the gc */ - xcb_change_gc(xcb_connection, statusline_ctx, XCB_GC_FONT, (uint32_t[]){ font.id }); - xcb_flush(xcb_connection); /* To grab modifiers without blocking other applications from receiving key-events @@ -1036,7 +1033,7 @@ void realloc_sl_buffer() { xcb_screen->height_in_pixels); uint32_t mask = XCB_GC_FOREGROUND; - uint32_t vals[3] = { colors.bar_bg, colors.bar_bg, font.id }; + uint32_t vals[2] = { colors.bar_bg, colors.bar_bg }; xcb_free_gc(xcb_connection, statusline_clear); statusline_clear = xcb_generate_id(xcb_connection); xcb_void_cookie_t clear_ctx_cookie = xcb_create_gc_checked(xcb_connection, @@ -1045,7 +1042,7 @@ void realloc_sl_buffer() { mask, vals); - mask |= XCB_GC_BACKGROUND | XCB_GC_FONT; + mask |= XCB_GC_BACKGROUND; vals[0] = colors.bar_fg; statusline_ctx = xcb_generate_id(xcb_connection); xcb_free_gc(xcb_connection, statusline_ctx); @@ -1203,13 +1200,11 @@ void reconfig_windows() { /* We also want a graphics-context for the bars (it defines the properties * with which we draw to them) */ walk->bargc = xcb_generate_id(xcb_connection); - mask = XCB_GC_FONT; - values[0] = font.id; xcb_void_cookie_t gc_cookie = xcb_create_gc_checked(xcb_connection, walk->bargc, walk->bar, - mask, - values); + 0, + NULL); /* We finally map the bar (display it on screen), unless the modifier-switch is on */ xcb_void_cookie_t map_cookie; @@ -1372,12 +1367,9 @@ void draw_bars() { outputs_walk->bargc, 1, &rect); - xcb_change_gc(xcb_connection, - outputs_walk->bargc, - XCB_GC_FOREGROUND, - &fg_color); + set_font_colors(outputs_walk->bargc, fg_color, bg_color); draw_text((char*)ws_walk->ucs2_name, ws_walk->name_glyphs, true, - outputs_walk->buffer, outputs_walk->bargc, i + 5, 2); + outputs_walk->buffer, outputs_walk->bargc, i + 5, 2, ws_walk->name_width); i += 10 + ws_walk->name_width; } diff --git a/include/libi3.h b/include/libi3.h index c08bbd81..4fb72717 100644 --- a/include/libi3.h +++ b/include/libi3.h @@ -209,14 +209,20 @@ xcb_char2b_t *convert_utf8_to_ucs2(char *input, int *real_strlen); */ void set_font(i3Font *font); +/** + * Defines the colors to be used for the forthcoming draw_text calls. + * + */ +void set_font_colors(xcb_gcontext_t gc, uint32_t foreground, uint32_t background); + /** * Draws text onto the specified X drawable (normally a pixmap) at the * specified coordinates (from the top left corner of the leftmost, uppermost * glyph) and using the provided gc. Text can be specified as UCS-2 or UTF-8. * */ -void draw_text(char *text, size_t text_len, bool is_ucs2, - xcb_drawable_t drawable, xcb_gcontext_t gc, int x, int y); +void draw_text(char *text, size_t text_len, bool is_ucs2, xcb_drawable_t drawable, + xcb_gcontext_t gc, int x, int y, int max_width); /** * Predict the text width in pixels for the given text. Text can be specified diff --git a/libi3/font.c b/libi3/font.c index 394567ba..c6bdc093 100644 --- a/libi3/font.c +++ b/libi3/font.c @@ -81,14 +81,25 @@ void set_font(i3Font *font) { savedFont = font; } +/* + * Defines the colors to be used for the forthcoming draw_text calls. + * + */ +void set_font_colors(xcb_gcontext_t gc, uint32_t foreground, uint32_t background) { + assert(savedFont != NULL); + uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT; + uint32_t values[] = { foreground, background, savedFont->id }; + xcb_change_gc(conn, gc, mask, values); +} + /* * Draws text onto the specified X drawable (normally a pixmap) at the * specified coordinates (from the top left corner of the leftmost, uppermost * glyph) and using the provided gc. Text can be specified as UCS-2 or UTF-8. * */ -void draw_text(char *text, size_t text_len, bool is_ucs2, - xcb_drawable_t drawable, xcb_gcontext_t gc, int x, int y) { +void draw_text(char *text, size_t text_len, bool is_ucs2, xcb_drawable_t drawable, + xcb_gcontext_t gc, int x, int y, int max_width) { assert(savedFont != NULL); assert(text_len != 0); diff --git a/src/sighandler.c b/src/sighandler.c index c0abed9a..e2cd15a1 100644 --- a/src/sighandler.c +++ b/src/sighandler.c @@ -47,11 +47,11 @@ static int sig_draw_window(xcb_window_t win, int width, int height, int font_hei xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &inner); /* restore font color */ - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#FFFFFF") }); + set_font_colors(pixmap_gc, get_colorpixel("#FFFFFF"), get_colorpixel("#000000")); for (int i = 0; i < sizeof(crash_text) / sizeof(char*); i++) { - draw_text(crash_text[i], strlen(crash_text[i]), false, - pixmap, pixmap_gc, 8, 3 + (i - 1) * font_height); + draw_text(crash_text[i], strlen(crash_text[i]), false, pixmap, pixmap_gc, + 8, 3 + (i - 1) * font_height, width - 16); } /* Copy the contents of the pixmap to the real window */ @@ -165,9 +165,6 @@ void handle_signal(int sig, siginfo_t *info, void *data) { xcb_create_pixmap(conn, root_depth, pixmap, win, width, height); xcb_create_gc(conn, pixmap_gc, pixmap, 0, 0); - /* Create graphics context */ - xcb_change_gc(conn, pixmap_gc, XCB_GC_FONT, (uint32_t[]){ config.font.id }); - /* Grab the keyboard to get all input */ xcb_grab_keyboard(conn, false, win, XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); diff --git a/src/x.c b/src/x.c index f67de0ca..aaa5b188 100644 --- a/src/x.c +++ b/src/x.c @@ -408,9 +408,7 @@ void x_draw_decoration(Con *con) { xcb_poly_segment(conn, parent->pixmap, parent->pm_gc, 2, segments); /* 6: draw the title */ - uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT; - uint32_t values[] = { p->color->text, p->color->background, config.font.id }; - xcb_change_gc(conn, parent->pm_gc, mask, values); + set_font_colors(parent->pm_gc, p->color->text, p->color->background); int text_offset_y = (con->deco_rect.height - config.font.height) / 2; struct Window *win = con->window; @@ -419,7 +417,8 @@ void x_draw_decoration(Con *con) { // TODO: use a good description instead of just "another container" draw_text("another container", strlen("another container"), false, parent->pixmap, parent->pm_gc, - con->deco_rect.x + 2, con->deco_rect.y + text_offset_y); + con->deco_rect.x + 2, con->deco_rect.y + text_offset_y, + con->deco_rect.width - 2); goto copy_pixmaps; } @@ -442,7 +441,8 @@ void x_draw_decoration(Con *con) { draw_text(win->name_x, win->name_len, win->uses_net_wm_name, parent->pixmap, parent->pm_gc, - con->deco_rect.x + 2 + indent_px, con->deco_rect.y + text_offset_y); + con->deco_rect.x + 2 + indent_px, con->deco_rect.y + text_offset_y, + con->deco_rect.width - 2 - indent_px); copy_pixmaps: xcb_copy_area(conn, con->pixmap, con->frame, con->pm_gc, 0, 0, 0, 0, con->rect.width, con->rect.height);