]> git.sur5r.net Git - i3/i3/commitdiff
Implement set_font_colors.
authorFernando Tarlá Cardoso Lemos <fernandotcl@gmail.com>
Mon, 14 Nov 2011 22:20:18 +0000 (20:20 -0200)
committerMichael Stapelberg <michael@stapelberg.de>
Mon, 21 Nov 2011 20:52:32 +0000 (20:52 +0000)
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
i3-input/main.c
i3-nagbar/main.c
i3bar/src/xcb.c
include/libi3.h
libi3/font.c
src/sighandler.c
src/x.c

index a6cd760d3af1738ff0ea516b4fd4febd6be8e6c6..84a7f77ee22f3f76b688c89aed0e8d0c7cfa9a1b 100644 (file)
@@ -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, "<Enter>");
 
         /* 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, "<ESC>");
     }
 
     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, "<Win>");
         else txt(31, 5, "<Alt>");
 
         /* 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, "<Enter>");
 
         /* 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, "<ESC>");
     }
 
@@ -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 */
index 3d45206d0ed0c61c032bdd813bffc553c443c15c..7602e32b208abf5ca84b1279b60f4010fc58ebce 100644 (file)
@@ -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);
 
index 525e32210c0ab0c4e209d133d8f043df9037fc21..742039e2693e95611c7dadaae8273c81b0b95441 100644 (file)
@@ -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;
             }
         }
index df8c119965d9421e807170b214703a6c37855db1..d907d083e433d5010858617b4231582f3593da21 100644 (file)
@@ -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;
         }
 
index c08bbd81dde5a152b832572edea30d83df20ce14..4fb727179271d426ddf342db8a75a8b7dc6717ca 100644 (file)
@@ -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
index 394567badc6a7375865a5e4f1c475afa3fe55f98..c6bdc09378d066e82d81706bb99dc61547dd1ec1 100644 (file)
@@ -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);
 
index c0abed9a74c795201a1db32de97e1049cf0a3a08..e2cd15a12d4846d53f7337fa359f8e6032e6f704 100644 (file)
@@ -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 f67de0ca0b4ccfe6c55d96ea75d29f931a9954a8..aaa5b188e50691bf753295fefc087a45d52cd008 100644 (file)
--- 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);