Implement set_font_colors.

This paves the way for other font rendering backends. Fonts and
colors shouldn't be specified manually from now on.
This commit is contained in:
Fernando Tarlá Cardoso Lemos 2011-11-14 20:20:18 -02:00 committed by Michael Stapelberg
parent eafc7af606
commit 344c04af12
8 changed files with 63 additions and 68 deletions

View File

@ -115,11 +115,12 @@ static int handle_expose() {
set_font(&font); set_font(&font);
#define txt(x, row, text) \ #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) { if (current_step == STEP_WELCOME) {
/* restore font color */ /* 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, 2, "You have not configured i3 yet.");
txt(10, 3, "Do you want me to generate ~/.i3/config?"); 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"); txt(85, 7, "No, I will use the defaults");
/* green */ /* 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>"); txt(25, 5, "<Enter>");
/* red */ /* 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>"); txt(31, 7, "<ESC>");
} }
if (current_step == STEP_GENERATE) { 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(10, 2, "Please choose either:");
txt(85, 4, "Win as default modifier"); txt(85, 4, "Win as default modifier");
@ -152,20 +153,18 @@ static int handle_expose() {
/* the selected modifier */ /* the selected modifier */
set_font(&bold_font); 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) if (modifier == MOD_Mod4)
txt(31, 4, "<Win>"); txt(31, 4, "<Win>");
else txt(31, 5, "<Alt>"); else txt(31, 5, "<Alt>");
/* green */ /* green */
set_font(&font); set_font(&font);
xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_FONT, set_font_colors(pixmap_gc, get_colorpixel("#00FF00"), get_colorpixel("#000000"));
(uint32_t[]) { get_colorpixel("#00FF00"), font.id });
txt(25, 9, "<Enter>"); txt(25, 9, "<Enter>");
/* red */ /* 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>"); 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); xcb_numlock_mask = get_mod_mask_for(XCB_NUM_LOCK, symbols, modmap_reply);
font = load_font(pattern, true); font = load_font(pattern, true);
set_font(&font);
bold_font = load_font(patternbold, true); bold_font = load_font(patternbold, true);
/* Open an input window */ /* Open an input window */

View 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); xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &inner);
/* restore font color */ /* 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); uint8_t *con = concat_strings(glyphs_ucs, input_position);
char *full_text = (char*)con; char *full_text = (char*)con;
if (prompt != NULL) { 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); memcpy(full_text + (prompt_len * 2), con, input_position * 2);
} }
if (input_position + prompt_len != 0) 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 */ /* 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); 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) */ * this for us) */
xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, win, XCB_CURRENT_TIME); 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 */ /* Grab the keyboard to get all input */
xcb_flush(conn); xcb_flush(conn);

View 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); xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &rect);
/* restore font color */ /* restore font color */
uint32_t values[3]; set_font_colors(pixmap_gc, color_text, color_background);
values[0] = color_text; draw_text(prompt, strlen(prompt), false, pixmap, pixmap_gc,
values[1] = color_background; 4 + 4, 4 + 4, rect.width - 4 - 4);
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);
/* render close button */ /* render close button */
int line_width = 4; int line_width = 4;
int w = 20; int w = 20;
int y = rect.width; int y = rect.width;
uint32_t values[3];
values[0] = color_button_background; values[0] = color_button_background;
values[1] = line_width; values[1] = line_width;
xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_LINE_WIDTH, values); 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); xcb_poly_line(conn, XCB_COORD_MODE_ORIGIN, pixmap, pixmap_gc, 5, points);
values[0] = color_text; values[0] = 1;
values[1] = color_button_background; set_font_colors(pixmap_gc, color_text, color_button_background);
values[2] = 1; draw_text("X", 1, false, pixmap, pixmap_gc, y - w - line_width + w / 2 - 4,
xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_LINE_WIDTH, values); 4 + 4 - 1, rect.width - y + w + line_width - w / 2 + 4);
draw_text("X", 1, false, pixmap, pixmap_gc, y - w - line_width + w / 2 - 4, 4 + 4 - 1);
y -= w; y -= w;
y -= 20; y -= 20;
@ -191,9 +189,9 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) {
values[0] = color_text; values[0] = color_text;
values[1] = color_button_background; 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, 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; 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_pixmap(conn, root_screen->root_depth, pixmap, win, 500, font.height + 8);
xcb_create_gc(conn, pixmap_gc, pixmap, 0, 0); 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 */ /* Grab the keyboard to get all input */
xcb_flush(conn); 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_pixmap(conn, root_screen->root_depth, pixmap, win, rect.width, rect.height);
xcb_create_gc(conn, pixmap_gc, pixmap, 0, 0); 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; break;
} }
} }

View File

@ -121,7 +121,9 @@ void refresh_statusline() {
xcb_rectangle_t rect = { 0, 0, xcb_screen->width_in_pixels, font.height }; 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); 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); FREE(text);
} }
@ -731,14 +733,12 @@ char *init_xcb_early() {
mask, mask,
vals); vals);
mask |= XCB_GC_BACKGROUND;
vals[0] = colors.bar_fg;
statusline_ctx = xcb_generate_id(xcb_connection); statusline_ctx = xcb_generate_id(xcb_connection);
xcb_void_cookie_t sl_ctx_cookie = xcb_create_gc_checked(xcb_connection, xcb_void_cookie_t sl_ctx_cookie = xcb_create_gc_checked(xcb_connection,
statusline_ctx, statusline_ctx,
xcb_root, xcb_root,
mask, 0,
vals); NULL);
statusline_pm = xcb_generate_id(xcb_connection); statusline_pm = xcb_generate_id(xcb_connection);
xcb_void_cookie_t sl_pm_cookie = xcb_create_pixmap_checked(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); set_font(&font);
DLOG("Calculated Font-height: %d\n", font.height); 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); xcb_flush(xcb_connection);
/* To grab modifiers without blocking other applications from receiving key-events /* To grab modifiers without blocking other applications from receiving key-events
@ -1036,7 +1033,7 @@ void realloc_sl_buffer() {
xcb_screen->height_in_pixels); xcb_screen->height_in_pixels);
uint32_t mask = XCB_GC_FOREGROUND; 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); xcb_free_gc(xcb_connection, statusline_clear);
statusline_clear = xcb_generate_id(xcb_connection); statusline_clear = xcb_generate_id(xcb_connection);
xcb_void_cookie_t clear_ctx_cookie = xcb_create_gc_checked(xcb_connection, xcb_void_cookie_t clear_ctx_cookie = xcb_create_gc_checked(xcb_connection,
@ -1045,7 +1042,7 @@ void realloc_sl_buffer() {
mask, mask,
vals); vals);
mask |= XCB_GC_BACKGROUND | XCB_GC_FONT; mask |= XCB_GC_BACKGROUND;
vals[0] = colors.bar_fg; vals[0] = colors.bar_fg;
statusline_ctx = xcb_generate_id(xcb_connection); statusline_ctx = xcb_generate_id(xcb_connection);
xcb_free_gc(xcb_connection, statusline_ctx); 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 /* We also want a graphics-context for the bars (it defines the properties
* with which we draw to them) */ * with which we draw to them) */
walk->bargc = xcb_generate_id(xcb_connection); 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, xcb_void_cookie_t gc_cookie = xcb_create_gc_checked(xcb_connection,
walk->bargc, walk->bargc,
walk->bar, walk->bar,
mask, 0,
values); NULL);
/* We finally map the bar (display it on screen), unless the modifier-switch is on */ /* We finally map the bar (display it on screen), unless the modifier-switch is on */
xcb_void_cookie_t map_cookie; xcb_void_cookie_t map_cookie;
@ -1372,12 +1367,9 @@ void draw_bars() {
outputs_walk->bargc, outputs_walk->bargc,
1, 1,
&rect); &rect);
xcb_change_gc(xcb_connection, set_font_colors(outputs_walk->bargc, fg_color, bg_color);
outputs_walk->bargc,
XCB_GC_FOREGROUND,
&fg_color);
draw_text((char*)ws_walk->ucs2_name, ws_walk->name_glyphs, true, 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; i += 10 + ws_walk->name_width;
} }

View File

@ -209,14 +209,20 @@ xcb_char2b_t *convert_utf8_to_ucs2(char *input, int *real_strlen);
*/ */
void set_font(i3Font *font); 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 * Draws text onto the specified X drawable (normally a pixmap) at the
* specified coordinates (from the top left corner of the leftmost, uppermost * 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. * 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, void draw_text(char *text, size_t text_len, bool is_ucs2, xcb_drawable_t drawable,
xcb_drawable_t drawable, xcb_gcontext_t gc, int x, int y); 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 * Predict the text width in pixels for the given text. Text can be specified

View File

@ -81,14 +81,25 @@ void set_font(i3Font *font) {
savedFont = 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 * Draws text onto the specified X drawable (normally a pixmap) at the
* specified coordinates (from the top left corner of the leftmost, uppermost * 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. * 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, void draw_text(char *text, size_t text_len, bool is_ucs2, xcb_drawable_t drawable,
xcb_drawable_t drawable, xcb_gcontext_t gc, int x, int y) { xcb_gcontext_t gc, int x, int y, int max_width) {
assert(savedFont != NULL); assert(savedFont != NULL);
assert(text_len != 0); assert(text_len != 0);

View 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); xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &inner);
/* restore font color */ /* 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++) { for (int i = 0; i < sizeof(crash_text) / sizeof(char*); i++) {
draw_text(crash_text[i], strlen(crash_text[i]), false, draw_text(crash_text[i], strlen(crash_text[i]), false, pixmap, pixmap_gc,
pixmap, pixmap_gc, 8, 3 + (i - 1) * font_height); 8, 3 + (i - 1) * font_height, width - 16);
} }
/* Copy the contents of the pixmap to the real window */ /* 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_pixmap(conn, root_depth, pixmap, win, width, height);
xcb_create_gc(conn, pixmap_gc, pixmap, 0, 0); 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 */ /* Grab the keyboard to get all input */
xcb_grab_keyboard(conn, false, win, XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); xcb_grab_keyboard(conn, false, win, XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);

10
src/x.c
View File

@ -408,9 +408,7 @@ void x_draw_decoration(Con *con) {
xcb_poly_segment(conn, parent->pixmap, parent->pm_gc, 2, segments); xcb_poly_segment(conn, parent->pixmap, parent->pm_gc, 2, segments);
/* 6: draw the title */ /* 6: draw the title */
uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT; set_font_colors(parent->pm_gc, p->color->text, p->color->background);
uint32_t values[] = { p->color->text, p->color->background, config.font.id };
xcb_change_gc(conn, parent->pm_gc, mask, values);
int text_offset_y = (con->deco_rect.height - config.font.height) / 2; int text_offset_y = (con->deco_rect.height - config.font.height) / 2;
struct Window *win = con->window; 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" // TODO: use a good description instead of just "another container"
draw_text("another container", strlen("another container"), false, draw_text("another container", strlen("another container"), false,
parent->pixmap, parent->pm_gc, 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; 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, draw_text(win->name_x, win->name_len, win->uses_net_wm_name,
parent->pixmap, parent->pm_gc, 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: copy_pixmaps:
xcb_copy_area(conn, con->pixmap, con->frame, con->pm_gc, 0, 0, 0, 0, con->rect.width, con->rect.height); xcb_copy_area(conn, con->pixmap, con->frame, con->pm_gc, 0, 0, 0, 0, con->rect.width, con->rect.height);