Add libi3/load_font, use it everywhere
…except for i3bar, which needs slightly more information about the font
This commit is contained in:
parent
6d01d37b03
commit
a58018cf66
|
@ -59,11 +59,9 @@ enum { MOD_Mod1, MOD_Mod4 } modifier = MOD_Mod4;
|
||||||
static char *config_path;
|
static char *config_path;
|
||||||
xcb_connection_t *conn;
|
xcb_connection_t *conn;
|
||||||
static xcb_get_modifier_mapping_reply_t *modmap_reply;
|
static xcb_get_modifier_mapping_reply_t *modmap_reply;
|
||||||
static uint32_t font_id;
|
static i3Font font;
|
||||||
static uint32_t font_bold_id;
|
static i3Font bold_font;
|
||||||
static char *socket_path;
|
static char *socket_path;
|
||||||
static int font_height;
|
|
||||||
static int font_bold_height;
|
|
||||||
static xcb_window_t win;
|
static xcb_window_t win;
|
||||||
static xcb_pixmap_t pixmap;
|
static xcb_pixmap_t pixmap;
|
||||||
static xcb_gcontext_t pixmap_gc;
|
static xcb_gcontext_t pixmap_gc;
|
||||||
|
@ -112,13 +110,13 @@ static char *resolve_tilde(const char *path) {
|
||||||
*/
|
*/
|
||||||
static int handle_expose() {
|
static int handle_expose() {
|
||||||
/* re-draw the background */
|
/* 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_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#000000") });
|
||||||
xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &border);
|
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) {
|
if (current_step == STEP_WELCOME) {
|
||||||
/* restore font color */
|
/* restore font color */
|
||||||
|
@ -154,14 +152,14 @@ static int handle_expose() {
|
||||||
else txt(31, 4, "<Win>");
|
else txt(31, 4, "<Win>");
|
||||||
|
|
||||||
/* the selected modifier */
|
/* 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)
|
if (modifier == MOD_Mod4)
|
||||||
txt(31, 4, "<Win>");
|
txt(31, 4, "<Win>");
|
||||||
else txt(31, 5, "<Alt>");
|
else txt(31, 5, "<Alt>");
|
||||||
|
|
||||||
/* green */
|
/* green */
|
||||||
xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_FONT,
|
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, "<Enter>");
|
txt(25, 9, "<Enter>");
|
||||||
|
|
||||||
|
@ -440,8 +438,8 @@ 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_id = get_font_id(conn, pattern, &font_height);
|
font = load_font(pattern, true);
|
||||||
font_bold_id = get_font_id(conn, patternbold, &font_bold_height);
|
bold_font = load_font(patternbold, true);
|
||||||
|
|
||||||
/* Open an input window */
|
/* Open an input window */
|
||||||
win = open_input_window(conn, 300, 205);
|
win = open_input_window(conn, 300, 205);
|
||||||
|
|
|
@ -73,34 +73,3 @@ xcb_window_t open_input_window(xcb_connection_t *conn, uint32_t width, uint32_t
|
||||||
|
|
||||||
return win;
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,6 +11,5 @@
|
||||||
extern unsigned int xcb_numlock_mask;
|
extern unsigned int xcb_numlock_mask;
|
||||||
|
|
||||||
xcb_window_t open_input_window(xcb_connection_t *conn, uint32_t width, uint32_t height);
|
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
|
#endif
|
||||||
|
|
|
@ -17,6 +17,5 @@ extern xcb_window_t root;
|
||||||
char *convert_ucs_to_utf8(char *input);
|
char *convert_ucs_to_utf8(char *input);
|
||||||
char *convert_utf8_to_ucs2(char *input, int *real_strlen);
|
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);
|
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
|
#endif
|
||||||
|
|
|
@ -51,11 +51,12 @@ static xcb_gcontext_t pixmap_gc;
|
||||||
static char *glyphs_ucs[512];
|
static char *glyphs_ucs[512];
|
||||||
static char *glyphs_utf8[512];
|
static char *glyphs_utf8[512];
|
||||||
static int input_position;
|
static int input_position;
|
||||||
static int font_height;
|
static i3Font font;
|
||||||
static char *prompt;
|
static char *prompt;
|
||||||
static int prompt_len;
|
static int prompt_len;
|
||||||
static int limit;
|
static int limit;
|
||||||
xcb_window_t root;
|
xcb_window_t root;
|
||||||
|
xcb_connection_t *conn;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Concats the glyphs (either UCS-2 or UTF-8) to a single string, suitable for
|
* 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");
|
printf("expose!\n");
|
||||||
|
|
||||||
/* re-draw the background */
|
/* 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_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#FF0000") });
|
||||||
xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &border);
|
xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &border);
|
||||||
xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#000000") });
|
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);
|
memcpy(full_text + (prompt_len * 2), con, input_position * 2);
|
||||||
}
|
}
|
||||||
xcb_image_text_16(conn, input_position + prompt_len, pixmap, pixmap_gc, 4 /* X */,
|
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 */
|
/* 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);
|
xcb_flush(conn);
|
||||||
free(con);
|
free(con);
|
||||||
if (prompt != NULL)
|
if (prompt != NULL)
|
||||||
|
@ -353,8 +354,8 @@ int main(int argc, char *argv[]) {
|
||||||
prompt = convert_utf8_to_ucs2(prompt, &prompt_len);
|
prompt = convert_utf8_to_ucs2(prompt, &prompt_len);
|
||||||
|
|
||||||
int screens;
|
int screens;
|
||||||
xcb_connection_t *conn = xcb_connect(NULL, &screens);
|
conn = xcb_connect(NULL, &screens);
|
||||||
if (xcb_connection_has_error(conn))
|
if (!conn || xcb_connection_has_error(conn))
|
||||||
die("Cannot open display\n");
|
die("Cannot open display\n");
|
||||||
|
|
||||||
xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screens);
|
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);
|
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 */
|
/* Open an input window */
|
||||||
win = open_input_window(conn, 500, font_height + 8);
|
win = open_input_window(conn, 500, font.height + 8);
|
||||||
|
|
||||||
/* Create pixmap */
|
/* Create pixmap */
|
||||||
pixmap = xcb_generate_id(conn);
|
pixmap = xcb_generate_id(conn);
|
||||||
pixmap_gc = 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);
|
xcb_create_gc(conn, pixmap_gc, pixmap, 0, 0);
|
||||||
|
|
||||||
/* Set input focus (we have override_redirect=1, so the wm will not do
|
/* 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);
|
xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, win, XCB_CURRENT_TIME);
|
||||||
|
|
||||||
/* Create graphics context */
|
/* 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 */
|
/* Grab the keyboard to get all input */
|
||||||
xcb_flush(conn);
|
xcb_flush(conn);
|
||||||
|
|
|
@ -71,34 +71,3 @@ xcb_window_t open_input_window(xcb_connection_t *conn, uint32_t width, uint32_t
|
||||||
|
|
||||||
return win;
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -19,6 +19,5 @@ while (0)
|
||||||
extern xcb_window_t root;
|
extern xcb_window_t root;
|
||||||
|
|
||||||
xcb_window_t open_input_window(xcb_connection_t *conn, uint32_t width, uint32_t height);
|
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
|
#endif
|
||||||
|
|
|
@ -42,7 +42,7 @@ static xcb_window_t win;
|
||||||
static xcb_pixmap_t pixmap;
|
static xcb_pixmap_t pixmap;
|
||||||
static xcb_gcontext_t pixmap_gc;
|
static xcb_gcontext_t pixmap_gc;
|
||||||
static xcb_rectangle_t rect = { 0, 0, 600, 20 };
|
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 char *prompt = "Please do not run this program.";
|
||||||
static button_t *buttons;
|
static button_t *buttons;
|
||||||
static int buttoncnt;
|
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 */
|
static uint32_t color_text; /* color of the text */
|
||||||
|
|
||||||
xcb_window_t root;
|
xcb_window_t root;
|
||||||
|
xcb_connection_t *conn;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Starts the given application by passing it through a shell. We use double fork
|
* 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;
|
values[1] = color_background;
|
||||||
xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND, values);
|
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 */,
|
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 */
|
/* render close button */
|
||||||
int line_width = 4;
|
int line_width = 4;
|
||||||
|
@ -165,7 +166,7 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) {
|
||||||
values[2] = 1;
|
values[2] = 1;
|
||||||
xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_LINE_WIDTH, values);
|
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 */,
|
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 -= w;
|
||||||
|
|
||||||
y -= 20;
|
y -= 20;
|
||||||
|
@ -196,7 +197,7 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) {
|
||||||
values[1] = color_button_background;
|
values[1] = color_button_background;
|
||||||
xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND, values);
|
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 */,
|
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;
|
y -= w;
|
||||||
}
|
}
|
||||||
|
@ -272,7 +273,6 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int screens;
|
int screens;
|
||||||
xcb_connection_t *conn;
|
|
||||||
if ((conn = xcb_connect(NULL, &screens)) == NULL ||
|
if ((conn = xcb_connect(NULL, &screens)) == NULL ||
|
||||||
xcb_connection_has_error(conn))
|
xcb_connection_has_error(conn))
|
||||||
die("Cannot open display\n");
|
die("Cannot open display\n");
|
||||||
|
@ -302,10 +302,10 @@ int main(int argc, char *argv[]) {
|
||||||
color_border_bottom = get_colorpixel("#ab7100");
|
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 */
|
/* 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 */
|
/* Setup NetWM atoms */
|
||||||
#define xmacro(name) \
|
#define xmacro(name) \
|
||||||
|
@ -346,7 +346,7 @@ int main(int argc, char *argv[]) {
|
||||||
uint32_t bottom_end_x;
|
uint32_t bottom_end_x;
|
||||||
} __attribute__((__packed__)) strut_partial = {0,};
|
} __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_start_x = 0;
|
||||||
strut_partial.top_end_x = 800;
|
strut_partial.top_end_x = 800;
|
||||||
|
|
||||||
|
@ -362,11 +362,11 @@ int main(int argc, char *argv[]) {
|
||||||
/* Create pixmap */
|
/* Create pixmap */
|
||||||
pixmap = xcb_generate_id(conn);
|
pixmap = xcb_generate_id(conn);
|
||||||
pixmap_gc = 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);
|
xcb_create_gc(conn, pixmap_gc, pixmap, 0, 0);
|
||||||
|
|
||||||
/* Create graphics context */
|
/* 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 */
|
/* Grab the keyboard to get all input */
|
||||||
xcb_flush(conn);
|
xcb_flush(conn);
|
||||||
|
@ -411,7 +411,7 @@ int main(int argc, char *argv[]) {
|
||||||
xcb_create_gc(conn, pixmap_gc, pixmap, 0, 0);
|
xcb_create_gc(conn, pixmap_gc, pixmap, 0, 0);
|
||||||
|
|
||||||
/* Create graphics context */
|
/* 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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,34 +71,3 @@ xcb_window_t open_input_window(xcb_connection_t *conn, uint32_t width, uint32_t
|
||||||
|
|
||||||
return win;
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
#include "i3.h"
|
#include "i3.h"
|
||||||
|
#include "libi3.h"
|
||||||
|
|
||||||
typedef struct Config Config;
|
typedef struct Config Config;
|
||||||
typedef struct Barconfig Barconfig;
|
typedef struct Barconfig Barconfig;
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Forward definitions */
|
/* Forward definitions */
|
||||||
typedef struct Font i3Font;
|
|
||||||
typedef struct Binding Binding;
|
typedef struct Binding Binding;
|
||||||
typedef struct Rect Rect;
|
typedef struct Rect Rect;
|
||||||
typedef struct xoutput Output;
|
typedef struct xoutput Output;
|
||||||
|
@ -224,20 +223,6 @@ struct Autostart {
|
||||||
TAILQ_ENTRY(Autostart) autostarts_always;
|
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
|
* An Output is a physical output on your graphics driver. Outputs which
|
||||||
* are currently in use have (output->active == true). Each output has a
|
* are currently in use have (output->active == true). Each output has a
|
||||||
|
|
|
@ -5,11 +5,34 @@
|
||||||
#ifndef _LIBI3_H
|
#ifndef _LIBI3_H
|
||||||
#define _LIBI3_H
|
#define _LIBI3_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
#include <xcb/xcb_keysyms.h>
|
#include <xcb/xcb_keysyms.h>
|
||||||
|
|
||||||
|
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.
|
* 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_key_symbols_t *symbols,
|
||||||
xcb_get_modifier_mapping_reply_t *modmap_reply);
|
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
|
#endif
|
||||||
|
|
|
@ -52,14 +52,6 @@
|
||||||
|
|
||||||
extern unsigned int xcb_numlock_mask;
|
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,
|
* Convenience wrapper around xcb_create_window which takes care of depth,
|
||||||
* generating an ID and checking for errors.
|
* generating an ID and checking for errors.
|
||||||
|
|
|
@ -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 <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <err.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -13,9 +13,9 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
#include "data.h"
|
#include "data.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "log.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "libi3.h"
|
#include "libi3.h"
|
||||||
|
|
||||||
|
|
51
src/xcb.c
51
src/xcb.c
|
@ -11,57 +11,6 @@
|
||||||
|
|
||||||
unsigned int xcb_numlock_mask;
|
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
|
* Convenience wrapper around xcb_create_window which takes care of depth, generating an ID and checking
|
||||||
* for errors.
|
* for errors.
|
||||||
|
|
Loading…
Reference in New Issue