From c52f74124c4c60c074b5a6e4524ca34dd6fd308d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fernando=20Tarl=C3=A1=20Cardoso=20Lemos?=
<fernandotcl@gmail.com>
Date: Mon, 14 Nov 2011 21:39:03 -0200
Subject: [PATCH 1/2] Implement Pango rendering.
---
common.mk | 9 ++
i3-config-wizard/main.c | 2 +
i3-input/main.c | 2 +
i3-nagbar/main.c | 2 +
i3bar/src/xcb.c | 30 +++---
include/libi3.h | 42 ++++++--
libi3/font.c | 258 ++++++++++++++++++++++++++++++++++++++++++-----
libi3/get_visualtype.c | 24 +++++
src/config.c | 2 +-
src/main.c | 2 +
src/xcb.c | 10 +-
11 files changed, 331 insertions(+), 52 deletions(-)
create mode 100644 libi3/get_visualtype.c
diff --git a/common.mk b/common.mk
index 4394905..a09e496 100644
--- a/common.mk
+++ b/common.mk
@@ -92,6 +92,15 @@ LIBS += $(call ldflags_for_lib, libev,ev)
LIBS += $(call ldflags_for_lib, libpcre,pcre)
LIBS += $(call ldflags_for_lib, libstartup-notification-1.0,startup-notification-1)
+# Enable Pango support if available
+ifeq ($(shell pkg-config --exists cairo pangocairo && echo 1),1)
+CPPFLAGS += -DPANGO_SUPPORT=1
+CFLAGS += $(shell pkg-config --cflags cairo pangocairo)
+LIBS += $(shell pkg-config --libs cairo pangocairo)
+else
+CPPFLAGS += -DPANGO_SUPPORT=0
+endif
+
# Please test if -Wl,--as-needed works on your platform and send me a patch.
# it is known not to work on Darwin (Mac OS X)
ifneq (,$(filter Linux GNU GNU/%, $(UNAME)))
diff --git a/i3-config-wizard/main.c b/i3-config-wizard/main.c
index be04267..a5b9ed5 100644
--- a/i3-config-wizard/main.c
+++ b/i3-config-wizard/main.c
@@ -77,6 +77,7 @@ static xcb_window_t win;
static xcb_pixmap_t pixmap;
static xcb_gcontext_t pixmap_gc;
static xcb_key_symbols_t *symbols;
+xcb_visualtype_t *root_visual_type;
xcb_window_t root;
Display *dpy;
@@ -457,6 +458,7 @@ int main(int argc, char *argv[]) {
#undef xmacro
xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screens);
+ root_visual_type = get_visualtype(root_screen);
root = root_screen->root;
if (!(modmap_reply = xcb_get_modifier_mapping_reply(conn, modmap_cookie, NULL)))
diff --git a/i3-input/main.c b/i3-input/main.c
index b570952..2f88052 100644
--- a/i3-input/main.c
+++ b/i3-input/main.c
@@ -52,6 +52,7 @@ static i3Font font;
static char *prompt;
static size_t prompt_len;
static int limit;
+xcb_visualtype_t *root_visual_type;
xcb_window_t root;
xcb_connection_t *conn;
@@ -358,6 +359,7 @@ int main(int argc, char *argv[]) {
die("Cannot open display\n");
xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screens);
+ root_visual_type = get_visualtype(root_screen);
root = root_screen->root;
symbols = xcb_key_symbols_alloc(conn);
diff --git a/i3-nagbar/main.c b/i3-nagbar/main.c
index 1dbd773..1bdb8d6 100644
--- a/i3-nagbar/main.c
+++ b/i3-nagbar/main.c
@@ -52,6 +52,7 @@ static uint32_t color_border; /* color of the button border */
static uint32_t color_border_bottom; /* color of the bottom border */
static uint32_t color_text; /* color of the text */
+xcb_visualtype_t *root_visual_type;
xcb_window_t root;
xcb_connection_t *conn;
@@ -281,6 +282,7 @@ int main(int argc, char *argv[]) {
#undef xmacro
xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screens);
+ root_visual_type = get_visualtype(root_screen);
root = root_screen->root;
if (bar_type == TYPE_ERROR) {
diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c
index 87926d3..683c6b6 100644
--- a/i3bar/src/xcb.c
+++ b/i3bar/src/xcb.c
@@ -48,10 +48,11 @@ xcb_atom_t atoms[NUM_ATOMS];
xcb_connection_t *xcb_connection;
int screen;
xcb_screen_t *xcb_screen;
-xcb_window_t xcb_root;
+xcb_window_t root;
/* This is needed for integration with libi3 */
xcb_connection_t *conn;
+xcb_visualtype_t *root_visual_type;
/* The font we'll use */
static i3Font font;
@@ -827,7 +828,8 @@ char *init_xcb_early() {
#include "xcb_atoms.def"
xcb_screen = xcb_aux_get_screen(xcb_connection, screen);
- xcb_root = xcb_screen->root;
+ root_visual_type = get_visualtype(xcb_screen);
+ root = xcb_screen->root;
/* We draw the statusline to a seperate pixmap, because it looks the same on all bars and
* this way, we can choose to crop it */
@@ -837,14 +839,14 @@ char *init_xcb_early() {
statusline_clear = xcb_generate_id(xcb_connection);
xcb_void_cookie_t clear_ctx_cookie = xcb_create_gc_checked(xcb_connection,
statusline_clear,
- xcb_root,
+ root,
mask,
vals);
statusline_ctx = xcb_generate_id(xcb_connection);
xcb_void_cookie_t sl_ctx_cookie = xcb_create_gc_checked(xcb_connection,
statusline_ctx,
- xcb_root,
+ root,
0,
NULL);
@@ -852,7 +854,7 @@ char *init_xcb_early() {
xcb_void_cookie_t sl_pm_cookie = xcb_create_pixmap_checked(xcb_connection,
xcb_screen->root_depth,
statusline_pm,
- xcb_root,
+ root,
xcb_screen->width_in_pixels,
xcb_screen->height_in_pixels);
@@ -876,7 +878,7 @@ char *init_xcb_early() {
xcb_get_property_cookie_t path_cookie;
path_cookie = xcb_get_property_unchecked(xcb_connection,
0,
- xcb_root,
+ root,
atoms[I3_SOCKET_PATH],
XCB_GET_PROPERTY_TYPE_ANY,
0, PATH_MAX);
@@ -984,7 +986,7 @@ void init_tray() {
xcb_create_window(xcb_connection,
xcb_screen->root_depth,
selwin,
- xcb_root,
+ root,
-1, -1,
1, 1,
1,
@@ -1037,7 +1039,7 @@ void init_tray() {
void *event = scalloc(32);
xcb_client_message_event_t *ev = event;
ev->response_type = XCB_CLIENT_MESSAGE;
- ev->window = xcb_root;
+ ev->window = root;
ev->type = atoms[MANAGER];
ev->format = 32;
ev->data.data32[0] = XCB_CURRENT_TIME;
@@ -1045,7 +1047,7 @@ void init_tray() {
ev->data.data32[2] = selwin;
xcb_send_event(xcb_connection,
0,
- xcb_root,
+ root,
XCB_EVENT_MASK_STRUCTURE_NOTIFY,
(char*)ev);
free(event);
@@ -1116,7 +1118,7 @@ void kick_tray_clients(i3_output *output) {
xcb_unmap_window(xcb_connection, trayclient->win);
xcb_reparent_window(xcb_connection,
trayclient->win,
- xcb_root,
+ root,
0,
0);
@@ -1155,7 +1157,7 @@ void realloc_sl_buffer() {
xcb_void_cookie_t sl_pm_cookie = xcb_create_pixmap_checked(xcb_connection,
xcb_screen->root_depth,
statusline_pm,
- xcb_root,
+ root,
MAX(xcb_screen->width_in_pixels, statusline_width),
xcb_screen->height_in_pixels);
@@ -1165,7 +1167,7 @@ void realloc_sl_buffer() {
statusline_clear = xcb_generate_id(xcb_connection);
xcb_void_cookie_t clear_ctx_cookie = xcb_create_gc_checked(xcb_connection,
statusline_clear,
- xcb_root,
+ root,
mask,
vals);
@@ -1175,7 +1177,7 @@ void realloc_sl_buffer() {
xcb_free_gc(xcb_connection, statusline_ctx);
xcb_void_cookie_t sl_ctx_cookie = xcb_create_gc_checked(xcb_connection,
statusline_ctx,
- xcb_root,
+ root,
mask,
vals);
@@ -1229,7 +1231,7 @@ void reconfig_windows() {
xcb_void_cookie_t win_cookie = xcb_create_window_checked(xcb_connection,
xcb_screen->root_depth,
walk->bar,
- xcb_root,
+ root,
walk->rect.x, walk->rect.y + walk->rect.h - font.height - 6,
walk->rect.w, font.height + 6,
1,
diff --git a/include/libi3.h b/include/libi3.h
index b88bcb6..1de92d4 100644
--- a/include/libi3.h
+++ b/include/libi3.h
@@ -18,6 +18,10 @@
#include <xcb/xproto.h>
#include <xcb/xcb_keysyms.h>
+#if PANGO_SUPPORT
+#include <pango/pango.h>
+#endif
+
typedef struct Font i3Font;
/**
@@ -27,17 +31,33 @@ typedef struct Font i3Font;
*
*/
struct Font {
- /** The xcb-id for the font */
- xcb_font_t id;
-
- /** Font information gathered from the server */
- xcb_query_font_reply_t *info;
-
- /** Font table for this font (may be NULL) */
- xcb_charinfo_t *table;
+ /** The type of font */
+ enum {
+ FONT_TYPE_NONE = 0,
+ FONT_TYPE_XCB,
+ FONT_TYPE_PANGO
+ } type;
/** The height of the font, built from font_ascent + font_descent */
int height;
+
+ union {
+ struct {
+ /** The xcb-id for the font */
+ xcb_font_t id;
+
+ /** Font information gathered from the server */
+ xcb_query_font_reply_t *info;
+
+ /** Font table for this font (may be NULL) */
+ xcb_charinfo_t *table;
+ } xcb;
+
+#if PANGO_SUPPORT
+ /** The pango font description */
+ PangoFontDescription *pango_desc;
+#endif
+ } specific;
};
/* Since this file also gets included by utilities which don’t use the i3 log
@@ -242,4 +262,10 @@ void draw_text(char *text, size_t text_len, bool is_ucs2, xcb_drawable_t drawabl
*/
int predict_text_width(char *text, size_t text_len, bool is_ucs2);
+/*
+ * Returns the visual type associated with the given screen.
+ *
+ */
+xcb_visualtype_t *get_visualtype(xcb_screen_t *s);
+
#endif
diff --git a/libi3/font.c b/libi3/font.c
index 0b276b0..88ee915 100644
--- a/libi3/font.c
+++ b/libi3/font.c
@@ -12,11 +12,131 @@
#include <stdbool.h>
#include <err.h>
+#if PANGO_SUPPORT
+#include <cairo/cairo-xcb.h>
+#include <pango/pangocairo.h>
+#endif
+
#include "libi3.h"
extern xcb_connection_t *conn;
+extern xcb_visualtype_t *root_visual_type;
+extern xcb_window_t root;
+
static const i3Font *savedFont = NULL;
+#if PANGO_SUPPORT
+static double pango_font_red;
+static double pango_font_green;
+static double pango_font_blue;
+
+/*
+ * Loads a Pango font description into an i3Font structure. Returns true
+ * on success, false otherwise.
+ *
+ */
+static bool load_pango_font(i3Font *font, const char *desc) {
+ /* Load the font description */
+ font->specific.pango_desc = pango_font_description_from_string(desc);
+ if (!font->specific.pango_desc)
+ return false;
+
+ /* Create a dummy Pango layout */
+ cairo_surface_t *surface = cairo_xcb_surface_create(conn, root, root_visual_type, 100, 100);
+ cairo_t *cr = cairo_create(surface);
+ PangoLayout *layout = pango_cairo_create_layout(cr);
+ pango_layout_set_font_description(layout, font->specific.pango_desc);
+
+ /* Get the font height */
+ gint height;
+ pango_layout_get_pixel_size(layout, NULL, &height);
+ font->height = height;
+
+ /* Free resources */
+ g_object_unref(layout);
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+
+ /* Set the font type and return successfully */
+ font->type = FONT_TYPE_PANGO;
+ return true;
+}
+
+/*
+ * Draws text using Pango rendering.
+ *
+ */
+void draw_text_pango(char *text, size_t text_len, bool is_ucs2,
+ xcb_drawable_t drawable, int x, int y, int max_width) {
+ /* Create the Pango layout */
+ cairo_surface_t *surface = cairo_xcb_surface_create(conn, drawable,
+ root_visual_type, x + max_width, y + savedFont->height);
+ cairo_t *cr = cairo_create(surface);
+ PangoLayout *layout = pango_cairo_create_layout(cr);
+ pango_layout_set_font_description(layout, savedFont->specific.pango_desc);
+ pango_layout_set_width(layout, max_width * PANGO_SCALE);
+ pango_layout_set_wrap(layout, PANGO_WRAP_CHAR);
+ pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
+
+ /* If the text is UCS-2, convert it to UTF-8 and get the number
+ * of bytes into text_len */
+ if (is_ucs2) {
+ text = convert_ucs2_to_utf8((xcb_char2b_t*)text, text_len);
+ if (!text)
+ return;
+ text_len = strlen(text);
+ }
+
+ /* Do the drawing */
+ cairo_set_source_rgb(cr, pango_font_red, pango_font_green, pango_font_blue);
+ cairo_move_to(cr, x, y);
+ pango_layout_set_text(layout, text, text_len);
+ pango_cairo_update_layout(cr, layout);
+ pango_cairo_show_layout(cr, layout);
+
+ /* Free resources */
+ g_object_unref(layout);
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+ if (is_ucs2)
+ free(text);
+}
+
+/*
+ * Calculate the text width using Pango rendering.
+ *
+ */
+int predict_text_width_pango(char *text, size_t text_len, bool is_ucs2) {
+ /* If the text is UCS-2, convert it to UTF-8 */
+ if (is_ucs2) {
+ text = convert_ucs2_to_utf8((xcb_char2b_t*)text, text_len);
+ if (!text)
+ return 10 * text_len;
+ }
+
+ /* Create a dummy Pango layout */
+ cairo_surface_t *surface = cairo_xcb_surface_create(conn, root, root_visual_type, 100, 100);
+ cairo_t *cr = cairo_create(surface);
+ PangoLayout *layout = pango_cairo_create_layout(cr);
+
+ /* Get the font height */
+ gint width;
+ pango_layout_set_font_description(layout, savedFont->specific.pango_desc);
+ pango_layout_set_text(layout, text, text_len);
+ pango_cairo_update_layout(cr, layout);
+ pango_layout_get_pixel_size(layout, &width, NULL);
+
+ /* Free resources */
+ g_object_unref(layout);
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+ if (is_ucs2)
+ free(text);
+
+ return width;
+}
+#endif
+
/*
* Loads a font for usage, also getting its metrics. If fallback is true,
* the fonts 'fixed' or '-misc-*' will be loaded instead of exiting.
@@ -24,12 +144,22 @@ static const i3Font *savedFont = NULL;
*/
i3Font load_font(const char *pattern, const bool fallback) {
i3Font font;
+ font.type = FONT_TYPE_NONE;
+
+#if PANGO_SUPPORT
+ /* Try to load a pango font if specified */
+ if (strlen(pattern) > 6 && !strncmp(pattern, "xft:", 4)) {
+ pattern += 4;
+ if (load_pango_font(&font, pattern))
+ return font;
+ }
+#endif
/* Send all our requests first */
- font.id = xcb_generate_id(conn);
- xcb_void_cookie_t font_cookie = xcb_open_font_checked(conn, font.id,
+ font.specific.xcb.id = xcb_generate_id(conn);
+ xcb_void_cookie_t font_cookie = xcb_open_font_checked(conn, font.specific.xcb.id,
strlen(pattern), pattern);
- xcb_query_font_cookie_t info_cookie = xcb_query_font(conn, font.id);
+ xcb_query_font_cookie_t info_cookie = xcb_query_font(conn, font.specific.xcb.id);
/* Check for errors. If errors, fall back to default font. */
xcb_generic_error_t *error;
@@ -40,8 +170,9 @@ i3Font load_font(const char *pattern, const bool fallback) {
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_query_font(conn, font.id);
+ font_cookie = xcb_open_font_checked(conn, font.specific.xcb.id,
+ strlen(pattern), pattern);
+ info_cookie = xcb_query_font(conn, font.specific.xcb.id);
/* Check if we managed to open 'fixed' */
error = xcb_request_check(conn, font_cookie);
@@ -50,8 +181,9 @@ i3Font load_font(const char *pattern, const bool fallback) {
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_query_font(conn, font.id);
+ font_cookie = xcb_open_font_checked(conn, font.specific.xcb.id,
+ strlen(pattern), pattern);
+ info_cookie = xcb_query_font(conn, font.specific.xcb.id);
if ((error = xcb_request_check(conn, font_cookie)) != NULL)
errx(EXIT_FAILURE, "Could open neither requested font nor fallbacks "
@@ -60,18 +192,20 @@ i3Font load_font(const char *pattern, const bool fallback) {
}
/* Get information (height/name) for this font */
- if (!(font.info = xcb_query_font_reply(conn, info_cookie, NULL)))
+ if (!(font.specific.xcb.info = xcb_query_font_reply(conn, info_cookie, NULL)))
errx(EXIT_FAILURE, "Could not load font \"%s\"", pattern);
/* Get the font table, if possible */
- if (xcb_query_font_char_infos_length(font.info) == 0)
- font.table = NULL;
+ if (xcb_query_font_char_infos_length(font.specific.xcb.info) == 0)
+ font.specific.xcb.table = NULL;
else
- font.table = xcb_query_font_char_infos(font.info);
+ font.specific.xcb.table = xcb_query_font_char_infos(font.specific.xcb.info);
/* Calculate the font height */
- font.height = font.info->font_ascent + font.info->font_descent;
+ font.height = font.specific.xcb.info->font_ascent + font.specific.xcb.info->font_descent;
+ /* Set the font type and return successfully */
+ font.type = FONT_TYPE_XCB;
return font;
}
@@ -88,10 +222,27 @@ void set_font(i3Font *font) {
*
*/
void free_font(void) {
- /* Close the font and free the info */
- xcb_close_font(conn, savedFont->id);
- if (savedFont->info)
- free(savedFont->info);
+ switch (savedFont->type) {
+ case FONT_TYPE_NONE:
+ /* Nothing to do */
+ break;
+ case FONT_TYPE_XCB: {
+ /* Close the font and free the info */
+ xcb_close_font(conn, savedFont->specific.xcb.id);
+ if (savedFont->specific.xcb.info)
+ free(savedFont->specific.xcb.info);
+ break;
+ }
+#if PANGO_SUPPORT
+ case FONT_TYPE_PANGO:
+ /* Free the font description */
+ pango_font_description_free(savedFont->specific.pango_desc);
+ break;
+#endif
+ default:
+ assert(false);
+ break;
+ }
}
/*
@@ -100,9 +251,30 @@ void free_font(void) {
*/
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);
+
+ switch (savedFont->type) {
+ case FONT_TYPE_NONE:
+ /* Nothing to do */
+ break;
+ case FONT_TYPE_XCB: {
+ /* Change the font and colors in the GC */
+ uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
+ uint32_t values[] = { foreground, background, savedFont->specific.xcb.id };
+ xcb_change_gc(conn, gc, mask, values);
+ break;
+ }
+#if PANGO_SUPPORT
+ case FONT_TYPE_PANGO:
+ /* Save the foreground font */
+ pango_font_red = ((foreground >> 16) & 0xff) / 255.0;
+ pango_font_green = ((foreground >> 8) & 0xff) / 255.0;
+ pango_font_blue = (foreground & 0xff) / 255.0;
+ break;
+#endif
+ default:
+ assert(false);
+ break;
+ }
}
/*
@@ -121,8 +293,25 @@ void draw_text(char *text, size_t text_len, bool is_ucs2, xcb_drawable_t drawabl
assert(savedFont != NULL);
assert(text_len != 0);
+ switch (savedFont->type) {
+ case FONT_TYPE_NONE:
+ /* Nothing to do */
+ return;
+ case FONT_TYPE_XCB:
+ /* Continue below */
+ break;
+#if PANGO_SUPPORT
+ case FONT_TYPE_PANGO:
+ /* Render the text using Pango */
+ draw_text_pango(text, text_len, is_ucs2, drawable, x, y, max_width);
+ return;
+#endif
+ default:
+ assert(false);
+ }
+
/* X11 coordinates for fonts start at the baseline */
- int pos_y = y + savedFont->info->font_ascent;
+ int pos_y = y + savedFont->specific.xcb.info->font_ascent;
/* As an optimization, check if we can bypass conversion */
if (!is_ucs2 && text_len <= 255) {
@@ -173,7 +362,7 @@ static int xcb_query_text_width(xcb_char2b_t *text, size_t text_len) {
/* Query the text width */
xcb_generic_error_t *error;
xcb_query_text_extents_cookie_t cookie = xcb_query_text_extents(conn,
- savedFont->id, text_len, (xcb_char2b_t*)text);
+ savedFont->specific.xcb.id, text_len, (xcb_char2b_t*)text);
xcb_query_text_extents_reply_t *reply = xcb_query_text_extents_reply(conn,
cookie, &error);
if (reply == NULL) {
@@ -181,7 +370,7 @@ static int xcb_query_text_width(xcb_char2b_t *text, size_t text_len) {
* a crash. Plus, the user will see the error in his log. */
fprintf(stderr, "Could not get text extents (X error code %d)\n",
error->error_code);
- return savedFont->info->max_bounds.character_width * text_len;
+ return savedFont->specific.xcb.info->max_bounds.character_width * text_len;
}
int width = reply->overall_width;
@@ -195,6 +384,25 @@ static int xcb_query_text_width(xcb_char2b_t *text, size_t text_len) {
*
*/
int predict_text_width(char *text, size_t text_len, bool is_ucs2) {
+ assert(savedFont != NULL);
+
+ switch (savedFont->type) {
+ case FONT_TYPE_NONE:
+ /* Nothing to do */
+ return 0;
+ case FONT_TYPE_XCB:
+ /* Continue below */
+ break;
+#if PANGO_SUPPORT
+ case FONT_TYPE_PANGO:
+ /* Calculate extents using Pango */
+ return predict_text_width_pango(text, text_len, is_ucs2);
+#endif
+ default:
+ assert(false);
+ return 0;
+ }
+
/* Convert the text into UTF-16 so we can do basic pointer math */
xcb_char2b_t *input;
if (is_ucs2)
@@ -203,13 +411,13 @@ int predict_text_width(char *text, size_t text_len, bool is_ucs2) {
input = convert_utf8_to_ucs2(text, &text_len);
int width;
- if (savedFont->table == NULL) {
+ if (savedFont->specific.xcb.table == NULL) {
/* If we don't have a font table, fall back to querying the server */
width = xcb_query_text_width(input, text_len);
} else {
/* Save some pointers for convenience */
- xcb_query_font_reply_t *font_info = savedFont->info;
- xcb_charinfo_t *font_table = savedFont->table;
+ xcb_query_font_reply_t *font_info = savedFont->specific.xcb.info;
+ xcb_charinfo_t *font_table = savedFont->specific.xcb.table;
/* Calculate the width using the font table */
width = 0;
diff --git a/libi3/get_visualtype.c b/libi3/get_visualtype.c
new file mode 100644
index 0000000..c639443
--- /dev/null
+++ b/libi3/get_visualtype.c
@@ -0,0 +1,24 @@
+/*
+ * vim:ts=4:sw=4:expandtab
+ *
+ * i3 - an improved dynamic tiling window manager
+ * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
+ *
+ */
+#include "libi3.h"
+
+/*
+ * Returns the visual type associated with the given screen.
+ *
+ */
+xcb_visualtype_t *get_visualtype(xcb_screen_t *s) {
+ xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(s);
+ for (; depth_iter.rem;xcb_depth_next(&depth_iter)) {
+ xcb_visualtype_iterator_t visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
+ for (; visual_iter.rem;xcb_visualtype_next(&visual_iter)) {
+ if (s->root_visual == visual_iter.data->visual_id)
+ return visual_iter.data;
+ }
+ }
+ return NULL;
+}
diff --git a/src/config.c b/src/config.c
index 50ec282..3542d1c 100644
--- a/src/config.c
+++ b/src/config.c
@@ -392,7 +392,7 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
grab_all_keys(conn, false);
}
- if (config.font.id == 0) {
+ if (config.font.type == FONT_TYPE_NONE) {
ELOG("You did not specify required configuration option \"font\"\n");
config.font = load_font("fixed", true);
set_font(&config.font);
diff --git a/src/main.c b/src/main.c
index 14786d2..e3957aa 100644
--- a/src/main.c
+++ b/src/main.c
@@ -51,6 +51,7 @@ SnDisplay *sndisplay;
* notification). */
xcb_timestamp_t last_timestamp = XCB_CURRENT_TIME;
+xcb_visualtype_t *root_visual_type;
xcb_screen_t *root_screen;
xcb_window_t root;
@@ -517,6 +518,7 @@ int main(int argc, char *argv[]) {
* usually is TrueColor (24 bit depth) and the corresponding visual.
* However, we also check if a 32 bit depth and visual are available (for
* transparency) and use it if so. */
+ root_visual_type = get_visualtype(root_screen);
root_depth = root_screen->root_depth;
visual_id = root_screen->root_visual;
colormap = root_screen->default_colormap;
diff --git a/src/xcb.c b/src/xcb.c
index 4d7a8c4..4bc68c9 100644
--- a/src/xcb.c
+++ b/src/xcb.c
@@ -48,8 +48,9 @@ xcb_window_t create_window(xcb_connection_t *conn, Rect dims,
xcb_cursor_t cursor_id = xcb_generate_id(conn);
i3Font cursor_font = load_font("cursor", false);
int xcb_cursor = xcursor_get_xcb_cursor(cursor);
- xcb_create_glyph_cursor(conn, cursor_id, cursor_font.id, cursor_font.id,
- xcb_cursor, xcb_cursor + 1, 0, 0, 0, 65535, 65535, 65535);
+ xcb_create_glyph_cursor(conn, cursor_id, cursor_font.specific.xcb.id,
+ cursor_font.specific.xcb.id, xcb_cursor, xcb_cursor + 1, 0, 0, 0,
+ 65535, 65535, 65535);
xcb_change_window_attributes(conn, result, XCB_CW_CURSOR, &cursor_id);
xcb_free_cursor(conn, cursor_id);
}
@@ -193,8 +194,9 @@ void xcb_set_root_cursor(int cursor) {
xcb_cursor_t cursor_id = xcb_generate_id(conn);
i3Font cursor_font = load_font("cursor", false);
int xcb_cursor = xcursor_get_xcb_cursor(cursor);
- xcb_create_glyph_cursor(conn, cursor_id, cursor_font.id, cursor_font.id,
- xcb_cursor, xcb_cursor + 1, 0, 0, 0, 65535, 65535, 65535);
+ xcb_create_glyph_cursor(conn, cursor_id, cursor_font.specific.xcb.id,
+ cursor_font.specific.xcb.id, xcb_cursor, xcb_cursor + 1, 0, 0, 0,
+ 65535, 65535, 65535);
xcb_change_window_attributes(conn, root, XCB_CW_CURSOR, &cursor_id);
xcb_free_cursor(conn, cursor_id);
xcb_flush(conn);
--
1.7.10