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;
*/
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 */
else txt(31, 4, "<Win>");
/* 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, "<Win>");
else txt(31, 5, "<Alt>");
/* 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, "<Enter>");
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);
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;
-}
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
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
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
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") });
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)
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);
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
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);
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;
-}
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
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;
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
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;
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;
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;
}
}
int screens;
- xcb_connection_t *conn;
if ((conn = xcb_connect(NULL, &screens)) == NULL ||
xcb_connection_has_error(conn))
die("Cannot open display\n");
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) \
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;
/* 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);
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;
}
}
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;
-}
#include <stdbool.h>
#include "queue.h"
#include "i3.h"
+#include "libi3.h"
typedef struct Config Config;
typedef struct Barconfig Barconfig;
*/
/* Forward definitions */
-typedef struct Font i3Font;
typedef struct Binding Binding;
typedef struct Rect Rect;
typedef struct xoutput Output;
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
#ifndef _LIBI3_H
#define _LIBI3_H
+#include <stdbool.h>
#include <stdarg.h>
+#include <stdio.h>
#include <xcb/xcb.h>
#include <xcb/xproto.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.
*
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
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.
--- /dev/null
+/*
+ * 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;
+}
#include <stdint.h>
#include <xcb/xcb.h>
+#include "log.h"
#include "data.h"
#include "config.h"
-#include "log.h"
#include "util.h"
#include "libi3.h"
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.