From: Michael Stapelberg Date: Sun, 23 Oct 2011 21:37:11 +0000 (+0100) Subject: Add libi3/load_font, use it everywhere X-Git-Tag: 4.1~52 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=a58018cf66108a81fc7e9ab0f7e47b29969184a0;p=i3%2Fi3 Add libi3/load_font, use it everywhere …except for i3bar, which needs slightly more information about the font --- diff --git a/i3-config-wizard/main.c b/i3-config-wizard/main.c index fb916daf..896574e5 100644 --- a/i3-config-wizard/main.c +++ b/i3-config-wizard/main.c @@ -59,11 +59,9 @@ enum { MOD_Mod1, MOD_Mod4 } modifier = MOD_Mod4; static char *config_path; xcb_connection_t *conn; static xcb_get_modifier_mapping_reply_t *modmap_reply; -static uint32_t font_id; -static uint32_t font_bold_id; +static i3Font font; +static i3Font bold_font; static char *socket_path; -static int font_height; -static int font_bold_height; static xcb_window_t win; static xcb_pixmap_t pixmap; static xcb_gcontext_t pixmap_gc; @@ -112,13 +110,13 @@ static char *resolve_tilde(const char *path) { */ static int handle_expose() { /* re-draw the background */ - xcb_rectangle_t border = {0, 0, 300, (15*font_height) + 8}; + xcb_rectangle_t border = {0, 0, 300, (15 * font.height) + 8}; xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#000000") }); xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &border); - xcb_change_gc(conn, pixmap_gc, XCB_GC_FONT, (uint32_t[]){ font_id }); + xcb_change_gc(conn, pixmap_gc, XCB_GC_FONT, (uint32_t[]){ font.id }); -#define txt(x, row, text) xcb_image_text_8(conn, strlen(text), pixmap, pixmap_gc, x, (row * font_height) + 2, text) +#define txt(x, row, text) xcb_image_text_8(conn, strlen(text), pixmap, pixmap_gc, x, (row * font.height) + 2, text) if (current_step == STEP_WELCOME) { /* restore font color */ @@ -154,14 +152,14 @@ static int handle_expose() { else txt(31, 4, ""); /* the selected modifier */ - xcb_change_gc(conn, pixmap_gc, XCB_GC_FONT, (uint32_t[]){ font_bold_id }); + xcb_change_gc(conn, pixmap_gc, XCB_GC_FONT, (uint32_t[]){ bold_font.id }); if (modifier == MOD_Mod4) txt(31, 4, ""); else txt(31, 5, ""); /* green */ xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_FONT, - (uint32_t[]) { get_colorpixel("#00FF00"), font_id }); + (uint32_t[]) { get_colorpixel("#00FF00"), font.id }); txt(25, 9, ""); @@ -440,8 +438,8 @@ int main(int argc, char *argv[]) { xcb_numlock_mask = get_mod_mask_for(XCB_NUM_LOCK, symbols, modmap_reply); - font_id = get_font_id(conn, pattern, &font_height); - font_bold_id = get_font_id(conn, patternbold, &font_bold_height); + font = load_font(pattern, true); + bold_font = load_font(patternbold, true); /* Open an input window */ win = open_input_window(conn, 300, 205); diff --git a/i3-config-wizard/xcb.c b/i3-config-wizard/xcb.c index 753568e3..cabc0926 100644 --- a/i3-config-wizard/xcb.c +++ b/i3-config-wizard/xcb.c @@ -73,34 +73,3 @@ xcb_window_t open_input_window(xcb_connection_t *conn, uint32_t width, uint32_t return win; } - -/* - * Returns the ID of the font matching the given pattern and stores the height - * of the font (in pixels) in *font_height. die()s if no font matches. - * - */ -int get_font_id(xcb_connection_t *conn, char *pattern, int *font_height) { - xcb_void_cookie_t font_cookie; - xcb_list_fonts_with_info_cookie_t info_cookie; - - /* Send all our requests first */ - int result; - result = xcb_generate_id(conn); - font_cookie = xcb_open_font_checked(conn, result, strlen(pattern), pattern); - info_cookie = xcb_list_fonts_with_info(conn, 1, strlen(pattern), pattern); - - xcb_generic_error_t *error = xcb_request_check(conn, font_cookie); - if (error != NULL) { - fprintf(stderr, "ERROR: Could not open font: %d\n", error->error_code); - exit(1); - } - - /* Get information (height/name) for this font */ - xcb_list_fonts_with_info_reply_t *reply = xcb_list_fonts_with_info_reply(conn, info_cookie, NULL); - if (reply == NULL) - errx(1, "Could not load font \"%s\"\n", pattern); - - *font_height = reply->font_ascent + reply->font_descent; - - return result; -} diff --git a/i3-config-wizard/xcb.h b/i3-config-wizard/xcb.h index 1e5d2d2a..4e273f66 100644 --- a/i3-config-wizard/xcb.h +++ b/i3-config-wizard/xcb.h @@ -11,6 +11,5 @@ extern unsigned int xcb_numlock_mask; xcb_window_t open_input_window(xcb_connection_t *conn, uint32_t width, uint32_t height); -int get_font_id(xcb_connection_t *conn, char *pattern, int *font_height); #endif diff --git a/i3-input/i3-input.h b/i3-input/i3-input.h index 981e5067..ae0e0fc0 100644 --- a/i3-input/i3-input.h +++ b/i3-input/i3-input.h @@ -17,6 +17,5 @@ extern xcb_window_t root; char *convert_ucs_to_utf8(char *input); char *convert_utf8_to_ucs2(char *input, int *real_strlen); xcb_window_t open_input_window(xcb_connection_t *conn, uint32_t width, uint32_t height); -int get_font_id(xcb_connection_t *conn, char *pattern, int *font_height); #endif diff --git a/i3-input/main.c b/i3-input/main.c index c74e4779..0e3a3f7b 100644 --- a/i3-input/main.c +++ b/i3-input/main.c @@ -51,11 +51,12 @@ static xcb_gcontext_t pixmap_gc; static char *glyphs_ucs[512]; static char *glyphs_utf8[512]; static int input_position; -static int font_height; +static i3Font font; static char *prompt; static int prompt_len; static int limit; xcb_window_t root; +xcb_connection_t *conn; /* * Concats the glyphs (either UCS-2 or UTF-8) to a single string, suitable for @@ -89,7 +90,7 @@ static int handle_expose(void *data, xcb_connection_t *conn, xcb_expose_event_t printf("expose!\n"); /* re-draw the background */ - xcb_rectangle_t border = {0, 0, 500, font_height + 8}, inner = {2, 2, 496, font_height + 8 - 4}; + xcb_rectangle_t border = {0, 0, 500, font.height + 8}, inner = {2, 2, 496, font.height + 8 - 4}; xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#FF0000") }); xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &border); xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#000000") }); @@ -107,10 +108,10 @@ static int handle_expose(void *data, xcb_connection_t *conn, xcb_expose_event_t memcpy(full_text + (prompt_len * 2), con, input_position * 2); } xcb_image_text_16(conn, input_position + prompt_len, pixmap, pixmap_gc, 4 /* X */, - font_height + 2 /* Y = baseline of font */, (xcb_char2b_t*)full_text); + font.height + 2 /* Y = baseline of font */, (xcb_char2b_t*)full_text); /* 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); xcb_flush(conn); free(con); if (prompt != NULL) @@ -353,8 +354,8 @@ int main(int argc, char *argv[]) { prompt = convert_utf8_to_ucs2(prompt, &prompt_len); int screens; - xcb_connection_t *conn = xcb_connect(NULL, &screens); - if (xcb_connection_has_error(conn)) + conn = xcb_connect(NULL, &screens); + if (!conn || xcb_connection_has_error(conn)) die("Cannot open display\n"); xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screens); @@ -362,15 +363,15 @@ int main(int argc, char *argv[]) { symbols = xcb_key_symbols_alloc(conn); - uint32_t font_id = get_font_id(conn, pattern, &font_height); + font = load_font(pattern, true); /* Open an input window */ - win = open_input_window(conn, 500, font_height + 8); + win = open_input_window(conn, 500, font.height + 8); /* Create pixmap */ pixmap = xcb_generate_id(conn); pixmap_gc = xcb_generate_id(conn); - 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); /* Set input focus (we have override_redirect=1, so the wm will not do @@ -378,7 +379,7 @@ int main(int argc, char *argv[]) { 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 }); + 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-input/xcb.c b/i3-input/xcb.c index ca0a7e76..d6e73307 100644 --- a/i3-input/xcb.c +++ b/i3-input/xcb.c @@ -71,34 +71,3 @@ xcb_window_t open_input_window(xcb_connection_t *conn, uint32_t width, uint32_t return win; } - -/* - * Returns the ID of the font matching the given pattern and stores the height - * of the font (in pixels) in *font_height. die()s if no font matches. - * - */ -int get_font_id(xcb_connection_t *conn, char *pattern, int *font_height) { - xcb_void_cookie_t font_cookie; - xcb_list_fonts_with_info_cookie_t info_cookie; - - /* Send all our requests first */ - int result; - result = xcb_generate_id(conn); - font_cookie = xcb_open_font_checked(conn, result, strlen(pattern), pattern); - info_cookie = xcb_list_fonts_with_info(conn, 1, strlen(pattern), pattern); - - xcb_generic_error_t *error = xcb_request_check(conn, font_cookie); - if (error != NULL) { - fprintf(stderr, "ERROR: Could not open font: %d\n", error->error_code); - exit(1); - } - - /* Get information (height/name) for this font */ - xcb_list_fonts_with_info_reply_t *reply = xcb_list_fonts_with_info_reply(conn, info_cookie, NULL); - if (reply == NULL) - die("Could not load font \"%s\"\n", pattern); - - *font_height = reply->font_ascent + reply->font_descent; - - return result; -} diff --git a/i3-nagbar/i3-nagbar.h b/i3-nagbar/i3-nagbar.h index 951e264f..b1375840 100644 --- a/i3-nagbar/i3-nagbar.h +++ b/i3-nagbar/i3-nagbar.h @@ -19,6 +19,5 @@ while (0) extern xcb_window_t root; xcb_window_t open_input_window(xcb_connection_t *conn, uint32_t width, uint32_t height); -int get_font_id(xcb_connection_t *conn, char *pattern, int *font_height); #endif diff --git a/i3-nagbar/main.c b/i3-nagbar/main.c index 71225c1a..43b17553 100644 --- a/i3-nagbar/main.c +++ b/i3-nagbar/main.c @@ -42,7 +42,7 @@ static xcb_window_t win; static xcb_pixmap_t pixmap; static xcb_gcontext_t pixmap_gc; static xcb_rectangle_t rect = { 0, 0, 600, 20 }; -static int font_height; +static i3Font font; static char *prompt = "Please do not run this program."; static button_t *buttons; static int buttoncnt; @@ -55,6 +55,7 @@ static uint32_t color_border_bottom; /* color of the bottom border */ static uint32_t color_text; /* color of the text */ xcb_window_t root; +xcb_connection_t *conn; /* * Starts the given application by passing it through a shell. We use double fork @@ -137,7 +138,7 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) { values[1] = color_background; xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND, values); xcb_image_text_8(conn, strlen(prompt), pixmap, pixmap_gc, 4 + 4/* X */, - font_height + 2 + 4 /* Y = baseline of font */, prompt); + font.height + 2 + 4 /* Y = baseline of font */, prompt); /* render close button */ int line_width = 4; @@ -165,7 +166,7 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) { values[2] = 1; xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_LINE_WIDTH, values); xcb_image_text_8(conn, strlen("x"), pixmap, pixmap_gc, y - w - line_width + (w / 2) - 4/* X */, - font_height + 2 + 4 - 1/* Y = baseline of font */, "X"); + font.height + 2 + 4 - 1/* Y = baseline of font */, "X"); y -= w; y -= 20; @@ -196,7 +197,7 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) { values[1] = color_button_background; xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND, values); xcb_image_text_8(conn, strlen(buttons[c].label), pixmap, pixmap_gc, y - w - line_width + 6/* X */, - font_height + 2 + 3/* Y = baseline of font */, buttons[c].label); + font.height + 2 + 3/* Y = baseline of font */, buttons[c].label); y -= w; } @@ -272,7 +273,6 @@ int main(int argc, char *argv[]) { } int screens; - xcb_connection_t *conn; if ((conn = xcb_connect(NULL, &screens)) == NULL || xcb_connection_has_error(conn)) die("Cannot open display\n"); @@ -302,10 +302,10 @@ int main(int argc, char *argv[]) { color_border_bottom = get_colorpixel("#ab7100"); } - uint32_t font_id = get_font_id(conn, pattern, &font_height); + font = load_font(pattern, true); /* Open an input window */ - win = open_input_window(conn, 500, font_height + 8 + 8 /* 8px padding */); + win = open_input_window(conn, 500, font.height + 8 + 8 /* 8px padding */); /* Setup NetWM atoms */ #define xmacro(name) \ @@ -346,7 +346,7 @@ int main(int argc, char *argv[]) { uint32_t bottom_end_x; } __attribute__((__packed__)) strut_partial = {0,}; - strut_partial.top = font_height + 6; + strut_partial.top = font.height + 6; strut_partial.top_start_x = 0; strut_partial.top_end_x = 800; @@ -362,11 +362,11 @@ int main(int argc, char *argv[]) { /* Create pixmap */ pixmap = xcb_generate_id(conn); pixmap_gc = xcb_generate_id(conn); - 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); /* Create graphics context */ - xcb_change_gc(conn, pixmap_gc, XCB_GC_FONT, (uint32_t[]){ font_id }); + xcb_change_gc(conn, pixmap_gc, XCB_GC_FONT, (uint32_t[]){ font.id }); /* Grab the keyboard to get all input */ xcb_flush(conn); @@ -411,7 +411,7 @@ int main(int argc, char *argv[]) { 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 }); + xcb_change_gc(conn, pixmap_gc, XCB_GC_FONT, (uint32_t[]){ font.id }); break; } } diff --git a/i3-nagbar/xcb.c b/i3-nagbar/xcb.c index 8c70875f..b38cd9a4 100644 --- a/i3-nagbar/xcb.c +++ b/i3-nagbar/xcb.c @@ -71,34 +71,3 @@ xcb_window_t open_input_window(xcb_connection_t *conn, uint32_t width, uint32_t return win; } - -/* - * Returns the ID of the font matching the given pattern and stores the height - * of the font (in pixels) in *font_height. die()s if no font matches. - * - */ -int get_font_id(xcb_connection_t *conn, char *pattern, int *font_height) { - xcb_void_cookie_t font_cookie; - xcb_list_fonts_with_info_cookie_t info_cookie; - - /* Send all our requests first */ - int result; - result = xcb_generate_id(conn); - font_cookie = xcb_open_font_checked(conn, result, strlen(pattern), pattern); - info_cookie = xcb_list_fonts_with_info(conn, 1, strlen(pattern), pattern); - - xcb_generic_error_t *error = xcb_request_check(conn, font_cookie); - if (error != NULL) { - fprintf(stderr, "ERROR: Could not open font: %d\n", error->error_code); - exit(1); - } - - /* Get information (height/name) for this font */ - xcb_list_fonts_with_info_reply_t *reply = xcb_list_fonts_with_info_reply(conn, info_cookie, NULL); - if (reply == NULL) - die("Could not load font \"%s\"\n", pattern); - - *font_height = reply->font_ascent + reply->font_descent; - - return result; -} diff --git a/include/config.h b/include/config.h index c7748c82..8f0b71c9 100644 --- a/include/config.h +++ b/include/config.h @@ -20,6 +20,7 @@ #include #include "queue.h" #include "i3.h" +#include "libi3.h" typedef struct Config Config; typedef struct Barconfig Barconfig; diff --git a/include/data.h b/include/data.h index 60e1ef26..fa866b61 100644 --- a/include/data.h +++ b/include/data.h @@ -33,7 +33,6 @@ */ /* Forward definitions */ -typedef struct Font i3Font; typedef struct Binding Binding; typedef struct Rect Rect; typedef struct xoutput Output; @@ -224,20 +223,6 @@ struct Autostart { TAILQ_ENTRY(Autostart) autostarts_always; }; -/** - * Data structure for cached font information: - * - font id in X11 (load it once) - * - font height (multiple calls needed to get it) - * - */ -struct Font { - /** The height of the font, built from font_ascent + font_descent */ - int height; - /** The xcb-id for the font */ - xcb_font_t id; -}; - - /** * An Output is a physical output on your graphics driver. Outputs which * are currently in use have (output->active == true). Each output has a diff --git a/include/libi3.h b/include/libi3.h index ecb72cb5..2477bd6b 100644 --- a/include/libi3.h +++ b/include/libi3.h @@ -5,11 +5,34 @@ #ifndef _LIBI3_H #define _LIBI3_H +#include #include +#include #include #include #include +typedef struct Font i3Font; + +/** + * Data structure for cached font information: + * - font id in X11 (load it once) + * - font height (multiple calls needed to get it) + * + */ +struct Font { + /** The height of the font, built from font_ascent + font_descent */ + int height; + /** The xcb-id for the font */ + xcb_font_t id; +}; + +/* Since this file also gets included by utilities which don’t use the i3 log + * infrastructure, we define a fallback. */ +#if !defined(ELOG) +#define ELOG(fmt, ...) fprintf(stderr, "ERROR: " fmt, ##__VA_ARGS__) +#endif + /** * Try to get the socket path from X11 and return NULL if it doesn’t work. * @@ -143,4 +166,11 @@ uint32_t get_mod_mask_for(uint32_t keysym, xcb_key_symbols_t *symbols, xcb_get_modifier_mapping_reply_t *modmap_reply); +/** + * Loads a font for usage, also getting its height. If fallback is true, + * the fonts 'fixed' or '-misc-*' will be loaded instead of exiting. + * + */ +i3Font load_font(const char *pattern, bool fallback); + #endif diff --git a/include/xcb.h b/include/xcb.h index 3670bbcd..16e444f9 100644 --- a/include/xcb.h +++ b/include/xcb.h @@ -52,14 +52,6 @@ extern unsigned int xcb_numlock_mask; -/** - * Loads a font for usage, also getting its height. If fallback is true, - * i3 loads 'fixed' or '-misc-*' if the font cannot be found instead of - * exiting. - * - */ -i3Font load_font(const char *pattern, bool fallback); - /** * Convenience wrapper around xcb_create_window which takes care of depth, * generating an ID and checking for errors. diff --git a/libi3/load_font.c b/libi3/load_font.c new file mode 100644 index 00000000..13a121c8 --- /dev/null +++ b/libi3/load_font.c @@ -0,0 +1,74 @@ +/* + * vim:ts=4:sw=4:expandtab + * + * i3 - an improved dynamic tiling window manager + * + * © 2009-2011 Michael Stapelberg and contributors + * + * See file LICENSE for license information. + * + */ +#include +#include +#include +#include +#include + +#include "libi3.h" + +extern xcb_connection_t *conn; + +/* + * Loads a font for usage, also getting its height. If fallback is true, + * the fonts 'fixed' or '-misc-*' will be loaded instead of exiting. + * + */ +i3Font load_font(const char *pattern, bool fallback) { + i3Font font; + xcb_void_cookie_t font_cookie; + xcb_list_fonts_with_info_cookie_t info_cookie; + xcb_list_fonts_with_info_reply_t *info_reply; + xcb_generic_error_t *error; + + /* Send all our requests first */ + font.id = xcb_generate_id(conn); + font_cookie = xcb_open_font_checked(conn, font.id, strlen(pattern), pattern); + info_cookie = xcb_list_fonts_with_info(conn, 1, strlen(pattern), pattern); + + /* Check for errors. If errors, fall back to default font. */ + error = xcb_request_check(conn, font_cookie); + + /* If we fail to open font, fall back to 'fixed' */ + if (fallback && error != NULL) { + ELOG("Could not open font %s (X error %d). Trying fallback to 'fixed'.\n", + pattern, error->error_code); + pattern = "fixed"; + font_cookie = xcb_open_font_checked(conn, font.id, strlen(pattern), pattern); + info_cookie = xcb_list_fonts_with_info(conn, 1, strlen(pattern), pattern); + + /* Check if we managed to open 'fixed' */ + error = xcb_request_check(conn, font_cookie); + + /* Fall back to '-misc-*' if opening 'fixed' fails. */ + if (error != NULL) { + ELOG("Could not open fallback font 'fixed', trying with '-misc-*'.\n"); + pattern = "-misc-*"; + font_cookie = xcb_open_font_checked(conn, font.id, strlen(pattern), pattern); + info_cookie = xcb_list_fonts_with_info(conn, 1, strlen(pattern), pattern); + + if ((error = xcb_request_check(conn, font_cookie)) != NULL) + errx(EXIT_FAILURE, "Could open neither requested font nor fallbacks " + "(fixed or -misc-*): X11 error %d", error->error_code); + } + } + + /* Get information (height/name) for this font */ + if (!(info_reply = xcb_list_fonts_with_info_reply(conn, info_cookie, NULL))) + errx(EXIT_FAILURE, "Could not load font \"%s\"", pattern); + + font.height = info_reply->font_ascent + info_reply->font_descent; + + free(info_reply); + + return font; +} diff --git a/src/cfgparse.l b/src/cfgparse.l index 8c853dbf..2bab9d6a 100644 --- a/src/cfgparse.l +++ b/src/cfgparse.l @@ -13,9 +13,9 @@ #include #include +#include "log.h" #include "data.h" #include "config.h" -#include "log.h" #include "util.h" #include "libi3.h" diff --git a/src/xcb.c b/src/xcb.c index 741760f8..aa761cac 100644 --- a/src/xcb.c +++ b/src/xcb.c @@ -11,57 +11,6 @@ unsigned int xcb_numlock_mask; -/* - * Loads a font for usage, also getting its height. If fallback is true, - * i3 loads 'fixed' or '-misc-*' if the font cannot be found instead of - * exiting. - * - */ -i3Font load_font(const char *pattern, bool fallback) { - i3Font new; - xcb_void_cookie_t font_cookie; - xcb_list_fonts_with_info_cookie_t info_cookie; - - /* Send all our requests first */ - new.id = xcb_generate_id(conn); - font_cookie = xcb_open_font_checked(conn, new.id, strlen(pattern), pattern); - info_cookie = xcb_list_fonts_with_info(conn, 1, strlen(pattern), pattern); - - /* Check for errors. If errors, fall back to default font. */ - xcb_generic_error_t *error = xcb_request_check(conn, font_cookie); - - /* If we fail to open font, fall back to 'fixed'. If opening 'fixed' fails fall back to '-misc-*' */ - if (fallback && error != NULL) { - ELOG("Could not open font %s (X error %d). Reverting to backup font.\n", pattern, error->error_code); - pattern = "fixed"; - font_cookie = xcb_open_font_checked(conn, new.id, strlen(pattern), pattern); - info_cookie = xcb_list_fonts_with_info(conn, 1, strlen(pattern), pattern); - - /* Check if we managed to open 'fixed' */ - xcb_generic_error_t *error = xcb_request_check(conn, font_cookie); - - /* Fall back to '-misc-*' if opening 'fixed' fails. */ - if (error != NULL) { - ELOG("Could not open fallback font '%s', trying with '-misc-*'\n",pattern); - pattern = "-misc-*"; - font_cookie = xcb_open_font_checked(conn, new.id, strlen(pattern), pattern); - info_cookie = xcb_list_fonts_with_info(conn, 1, strlen(pattern), pattern); - - check_error(conn, font_cookie, "Could open neither requested font nor fallback (fixed or -misc-*"); - } - } - - /* Get information (height/name) for this font */ - xcb_list_fonts_with_info_reply_t *reply = xcb_list_fonts_with_info_reply(conn, info_cookie, NULL); - exit_if_null(reply, "Could not load font \"%s\"\n", pattern); - - new.height = reply->font_ascent + reply->font_descent; - - free(reply); - - return new; -} - /* * Convenience wrapper around xcb_create_window which takes care of depth, generating an ID and checking * for errors.