int hide_on_modifier;
dockpos_t dockpos;
int verbose;
- xcb_colors_t *colors;
+ struct xcb_color_strings_t colors;
int disable_ws;
+ char *bar_id;
+ char *command;
+ char *fontname;
} config_t;
config_t config;
+/**
+ * Start parsing the received bar configuration json-string
+ *
+ */
+void parse_config_json(char *json);
+
+/**
+ * free()s the color strings as soon as they are not needed anymore.
+ *
+ */
+void free_colors(struct xcb_color_strings_t *colors);
+
#endif
typedef struct xcb_colors_t xcb_colors_t;
/*
- * Initialize xcb and use the specified fontname for text-rendering
+ * Early initialization of the connection to X11: Everything which does not
+ * depend on 'config'.
*
*/
-char *init_xcb(char *fontname);
+char *init_xcb_early();
+
+/**
+ * Initialization which depends on 'config' being usable. Called after the
+ * configuration has arrived.
+ *
+ */
+void init_xcb_late(char *fontname);
/*
* Initialize the colors
--- /dev/null
+/*
+ * vim:ts=4:sw=4:expandtab
+ *
+ * i3bar - an xcb-based status- and ws-bar for i3
+ *
+ * © 2010-2011 Axel Wagner and contributors
+ *
+ * See file LICENSE for license information
+ *
+ * src/outputs.c: Maintaining the output-list
+ *
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <i3/ipc.h>
+#include <yajl/yajl_parse.h>
+#include <yajl/yajl_version.h>
+
+#include "common.h"
+
+static char *cur_key;
+
+/*
+ * Parse a key.
+ *
+ * Essentially we just save it in cur_key.
+ *
+ */
+#if YAJL_MAJOR >= 2
+static int config_map_key_cb(void *params_, const unsigned char *keyVal, size_t keyLen) {
+#else
+static int config_map_key_cb(void *params_, const unsigned char *keyVal, unsigned keyLen) {
+#endif
+ FREE(cur_key);
+
+ cur_key = malloc(sizeof(unsigned char) * (keyLen + 1));
+ strncpy(cur_key, (const char*) keyVal, keyLen);
+ cur_key[keyLen] = '\0';
+
+ return 1;
+}
+
+/*
+ * Parse a string
+ *
+ */
+#if YAJL_MAJOR >= 2
+static int config_string_cb(void *params_, const unsigned char *val, size_t len) {
+#else
+static int config_string_cb(void *params_, const unsigned char *val, unsigned int len) {
+#endif
+ /* The id is ignored, we already have it in config.bar_id */
+ if (!strcmp(cur_key, "id"))
+ return 1;
+
+ if (!strcmp(cur_key, "mode")) {
+ DLOG("mode = %.*s, len = %d\n", len, val, len);
+ config.hide_on_modifier = (len == 4 && !strncmp((const char*)val, "hide", strlen("hide")));
+ return 1;
+ }
+
+ if (!strcmp(cur_key, "position")) {
+ DLOG("position = %.*s\n", len, val);
+ config.dockpos = (len == 3 && !strncmp((const char*)val, "top", strlen("top")) ? DOCKPOS_TOP : DOCKPOS_BOT);
+ return 1;
+ }
+
+ if (!strcmp(cur_key, "status_command")) {
+ /* We cannot directly start the child here, because start_child() also
+ * needs to be run when no command was specified (to setup stdin).
+ * Therefore we save the command in 'config' and access it later in
+ * got_bar_config() */
+ DLOG("command = %.*s\n", len, val);
+ asprintf(&config.command, "%.*s", len, val);
+ return 1;
+ }
+
+ if (!strcmp(cur_key, "font")) {
+ DLOG("font = %.*s\n", len, val);
+ asprintf(&config.fontname, "%.*s", len, val);
+ return 1;
+ }
+
+ if (!strcmp(cur_key, "outputs")) {
+ printf("+output %.*s\n", len, val);
+ /* XXX: these are not implemented yet */
+ return 1;
+ }
+
+ if (!strcmp(cur_key, "tray_output")) {
+ printf("tray_output %.*s\n", len, val);
+ /* XXX: these are not implemented yet */
+ return 1;
+ }
+
+#define COLOR(json_name, struct_name) \
+ do { \
+ if (!strcmp(cur_key, #json_name)) { \
+ DLOG(#json_name " = " #struct_name " = %.*s\n", len, val); \
+ asprintf(&(config.colors.struct_name), "%.*s", len, val); \
+ return 1; \
+ } \
+ } while (0)
+
+ COLOR(statusline, bar_fg);
+ COLOR(background, bar_bg);
+ COLOR(focused_workspace_text, focus_ws_fg);
+ COLOR(focused_workspace_bg, focus_ws_bg);
+ COLOR(active_workspace_text, active_ws_fg);
+ COLOR(active_workspace_bg, active_ws_bg);
+ COLOR(inactive_workspace_text, inactive_ws_fg);
+ COLOR(inactive_workspace_bg, inactive_ws_bg);
+ COLOR(urgent_workspace_text, urgent_ws_fg);
+ COLOR(urgent_workspace_bg, urgent_ws_bg);
+
+ printf("got unexpected string %.*s for cur_key = %s\n", len, val, cur_key);
+
+ return 0;
+}
+
+/*
+ * Parse a boolean value
+ *
+ */
+static int config_boolean_cb(void *params_, int val) {
+ if (!strcmp(cur_key, "workspace_buttons")) {
+ DLOG("workspace_buttons = %d\n", val);
+ config.disable_ws = !val;
+ return 1;
+ }
+
+ if (!strcmp(cur_key, "verbose")) {
+ DLOG("verbose = %d\n", val);
+ config.verbose = val;
+ return 1;
+ }
+
+ return 0;
+}
+
+/* A datastructure to pass all these callbacks to yajl */
+static yajl_callbacks outputs_callbacks = {
+ NULL,
+ &config_boolean_cb,
+ NULL,
+ NULL,
+ NULL,
+ &config_string_cb,
+ NULL,
+ &config_map_key_cb,
+ NULL,
+ NULL,
+ NULL
+};
+
+/*
+ * Start parsing the received bar configuration json-string
+ *
+ */
+void parse_config_json(char *json) {
+ yajl_handle handle;
+ yajl_status state;
+#if YAJL_MAJOR < 2
+ yajl_parser_config parse_conf = { 0, 0 };
+
+ handle = yajl_alloc(&outputs_callbacks, &parse_conf, NULL, NULL);
+#else
+ handle = yajl_alloc(&outputs_callbacks, NULL, NULL);
+#endif
+
+ state = yajl_parse(handle, (const unsigned char*) json, strlen(json));
+
+ /* FIXME: Proper errorhandling for JSON-parsing */
+ switch (state) {
+ case yajl_status_ok:
+ break;
+ case yajl_status_client_canceled:
+#if YAJL_MAJOR < 2
+ case yajl_status_insufficient_data:
+#endif
+ case yajl_status_error:
+ ELOG("Could not parse config-reply!\n");
+ exit(EXIT_FAILURE);
+ break;
+ }
+
+ yajl_free(handle);
+}
+
+/*
+ * free()s the color strings as soon as they are not needed anymore.
+ *
+ */
+void free_colors(struct xcb_color_strings_t *colors) {
+#define FREE_COLOR(x) \
+ do { \
+ if (colors->x) \
+ free(colors->x); \
+ } while (0)
+ FREE_COLOR(bar_fg);
+ FREE_COLOR(bar_bg);
+ FREE_COLOR(active_ws_fg);
+ FREE_COLOR(active_ws_bg);
+ FREE_COLOR(inactive_ws_fg);
+ FREE_COLOR(inactive_ws_bg);
+ FREE_COLOR(urgent_ws_fg);
+ FREE_COLOR(urgent_ws_bg);
+ FREE_COLOR(focus_ws_fg);
+ FREE_COLOR(focus_ws_bg);
+#undef FREE_COLOR
+}
+
reconfig_windows();
}
+/*
+ * Called when we get the configuration for our bar instance
+ *
+ */
+void got_bar_config(char *reply) {
+ DLOG("Received bar config \"%s\"\n", reply);
+ /* We initiate the main-function by requesting infos about the outputs and
+ * workspaces. Everything else (creating the bars, showing the right workspace-
+ * buttons and more) is taken care of by the event-drivenness of the code */
+ i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
+ parse_config_json(reply);
+
+ /* Now we can actually use 'config', so let's subscribe to the appropriate
+ * events and request the workspaces if necessary. */
+ subscribe_events();
+ if (!config.disable_ws)
+ i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
+
+ /* Initialize the rest of XCB */
+ init_xcb_late(config.fontname);
+
+ /* Resolve color strings to colorpixels and save them, then free the strings. */
+ init_colors(&(config.colors));
+ free_colors(&(config.colors));
+
+ /* The name of this function is actually misleading. Even if no command is
+ * specified, this function initiates the watchers to listen on stdin and
+ * react accordingly */
+ start_child(config.command);
+ FREE(config.command);
+}
+
/* Data-structure to easily call the reply-handlers later */
handler_t reply_handlers[] = {
&got_command_reply,
&got_workspace_reply,
&got_subscribe_reply,
&got_output_reply,
+ NULL,
+ NULL,
+ &got_bar_config,
};
/*
type ^= 1 << 31;
event_handlers[type](buffer);
} else {
- reply_handlers[type](buffer);
+ if (reply_handlers[type])
+ reply_handlers[type](buffer);
}
FREE(header);
#include <glob.h>
#include "common.h"
+#include "libi3.h"
/*
* Glob path, i.e. expand ~
return result;
}
-static void read_color(char **color) {
- int len = strlen(optarg);
- if (len == 6 || (len == 7 && optarg[0] == '#')) {
- int offset = len - 6;
- int good = 1, i;
- for (i = offset; good && i < 6 + offset; ++i) {
- char c = optarg[i];
- if (!(c >= 'a' && c <= 'f')
- && !(c >= 'A' && c <= 'F')
- && !(c >= '0' && c <= '9')) {
- good = 0;
- break;
- }
- }
- if (good) {
- *color = strdup(optarg + offset);
- return;
- }
- }
-
- fprintf(stderr, "Bad color value \"%s\"\n", optarg);
- exit(EXIT_FAILURE);
-}
-
-static void free_colors(struct xcb_color_strings_t *colors) {
-#define FREE_COLOR(x) \
- do { \
- if (colors->x) \
- free(colors->x); \
- } while (0)
- FREE_COLOR(bar_fg);
- FREE_COLOR(bar_bg);
- FREE_COLOR(active_ws_fg);
- FREE_COLOR(active_ws_bg);
- FREE_COLOR(inactive_ws_fg);
- FREE_COLOR(inactive_ws_bg);
- FREE_COLOR(urgent_ws_fg);
- FREE_COLOR(urgent_ws_bg);
- FREE_COLOR(focus_ws_fg);
- FREE_COLOR(focus_ws_bg);
-#undef FREE_COLOR
-}
-
void print_usage(char *elf_name) {
- printf("Usage: %s [-s sock_path] [-c command] [-m|-d[pos]] [-f font] [-V] [-h]\n", elf_name);
+ printf("Usage: %s [-s sock_path] [-h] [-v]\n", elf_name);
printf("-s <sock_path>\tConnect to i3 via <sock_path>\n");
- printf("-c <command>\tExecute <command> to get stdin\n");
- printf("-m\t\tHide the bars, when mod4 is not pressed.\n");
- printf("-d[<pos>]\tEnable dockmode. <pos> is \"top\" or \"bottom\". Default is bottom\n");
- printf("\t\tIf -c is specified, the childprocess is sent a SIGSTOP on hiding,\n");
- printf("\t\tand a SIGCONT on unhiding of the bars\n");
- printf("-f <font>\tUse X-Core-Font <font> for display\n");
- printf("-w\t\tDisable workspace-buttons\n");
- printf("-V\t\tBe (very) verbose with the debug-output\n");
printf("-h\t\tDisplay this help-message and exit\n");
+ printf("-v\t\tDisplay version number and exit\n");
}
/*
int opt;
int option_index = 0;
char *socket_path = getenv("I3SOCK");
- char *command = NULL;
- char *fontname = NULL;
char *i3_default_sock_path = "/tmp/i3-ipc.sock";
- struct xcb_color_strings_t colors = { NULL, };
- /* Definition of the standard-config */
- config.hide_on_modifier = 0;
- config.dockpos = DOCKPOS_NONE;
- config.disable_ws = 0;
+ /* Initialize the standard config to use 0 as default */
+ memset(&config, '\0', sizeof(config_t));
static struct option long_opt[] = {
{ "socket", required_argument, 0, 's' },
- { "command", required_argument, 0, 'c' },
- { "hide", no_argument, 0, 'm' },
- { "dock", optional_argument, 0, 'd' },
- { "font", required_argument, 0, 'f' },
- { "nows", no_argument, 0, 'w' },
+ { "bar_id", required_argument, 0, 0 },
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'v' },
- { "verbose", no_argument, 0, 'V' },
- { "color-bar-fg", required_argument, 0, 'A' },
- { "color-bar-bg", required_argument, 0, 'B' },
- { "color-active-ws-fg", required_argument, 0, 'C' },
- { "color-active-ws-bg", required_argument, 0, 'D' },
- { "color-inactive-ws-fg", required_argument, 0, 'E' },
- { "color-inactive-ws-bg", required_argument, 0, 'F' },
- { "color-urgent-ws-bg", required_argument, 0, 'G' },
- { "color-urgent-ws-fg", required_argument, 0, 'H' },
- { "color-focus-ws-bg", required_argument, 0, 'I' },
- { "color-focus-ws-fg", required_argument, 0, 'J' },
{ NULL, 0, 0, 0}
};
- while ((opt = getopt_long(argc, argv, "s:c:d::mf:whvVA:B:C:D:E:F:G:H:I:J:", long_opt, &option_index)) != -1) {
+ while ((opt = getopt_long(argc, argv, "s:hv", long_opt, &option_index)) != -1) {
switch (opt) {
case 's':
socket_path = expand_path(optarg);
break;
- case 'c':
- command = strdup(optarg);
- break;
- case 'm':
- config.hide_on_modifier = 1;
- break;
- case 'd':
- config.hide_on_modifier = 0;
- if (optarg == NULL) {
- config.dockpos = DOCKPOS_BOT;
- break;
- }
- if (!strcmp(optarg, "top")) {
- config.dockpos = DOCKPOS_TOP;
- } else if (!strcmp(optarg, "bottom")) {
- config.dockpos = DOCKPOS_BOT;
- } else {
- print_usage(argv[0]);
- exit(EXIT_FAILURE);
- }
- break;
- case 'f':
- fontname = strdup(optarg);
- break;
- case 'w':
- config.disable_ws = 1;
- break;
case 'v':
printf("i3bar version " I3_VERSION " © 2010-2011 Axel Wagner and contributors\n");
exit(EXIT_SUCCESS);
break;
- case 'V':
- config.verbose = 1;
- break;
- case 'A':
- read_color(&colors.bar_fg);
- break;
- case 'B':
- read_color(&colors.bar_bg);
- break;
- case 'C':
- read_color(&colors.active_ws_fg);
- break;
- case 'D':
- read_color(&colors.active_ws_bg);
- break;
- case 'E':
- read_color(&colors.inactive_ws_fg);
- break;
- case 'F':
- read_color(&colors.inactive_ws_bg);
- break;
- case 'G':
- read_color(&colors.urgent_ws_bg);
- break;
- case 'H':
- read_color(&colors.urgent_ws_fg);
- break;
- case 'I':
- read_color(&colors.focus_ws_bg);
- break;
- case 'J':
- read_color(&colors.focus_ws_fg);
+ case 0:
+ if (!strcmp(long_opt[option_index].name, "bar_id")) {
+ FREE(config.bar_id);
+ config.bar_id = sstrdup(optarg);
+ }
break;
default:
print_usage(argv[0]);
}
}
- if (fontname == NULL) {
- /* This is a very restrictive default. More sensefull would be something like
- * "-misc-*-*-*-*--*-*-*-*-*-*-*-*". But since that produces very ugly results
- * on my machine, let's stick with this until we have a configfile */
- fontname = "-misc-fixed-medium-r-semicondensed--12-110-75-75-c-60-iso10646-1";
- }
-
- if (config.dockpos != DOCKPOS_NONE) {
- if (config.hide_on_modifier) {
- ELOG("--dock and --hide are mutually exclusive!\n");
- exit(EXIT_FAILURE);
- }
- } else {
- config.hide_on_modifier = 1;
+ if (!config.bar_id) {
+ /* TODO: maybe we want -f which will automatically ask i3 for the first
+ * configured bar (and error out if there are too many)? */
+ ELOG("No bar_id passed. Please let i3 start i3bar or specify --bar_id\n");
+ exit(EXIT_FAILURE);
}
main_loop = ev_default_loop(0);
- init_colors(&colors);
- char *atom_sock_path = init_xcb(fontname);
+ char *atom_sock_path = init_xcb_early();
if (socket_path == NULL) {
socket_path = atom_sock_path;
socket_path = expand_path(i3_default_sock_path);
}
- free_colors(&colors);
-
init_outputs();
if (init_connection(socket_path)) {
- /* We subscribe to the i3-events we need */
- subscribe_events();
-
- /* We initiate the main-function by requesting infos about the outputs and
- * workspaces. Everything else (creating the bars, showing the right workspace-
- * buttons and more) is taken care of by the event-driveniness of the code */
- i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
- if (!config.disable_ws) {
- i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
- }
+ /* Request the bar configuration. When it arrives, we fill the config array. */
+ i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG, config.bar_id);
}
- /* The name of this function is actually misleading. Even if no -c is specified,
- * this function initiates the watchers to listen on stdin and react accordingly */
- start_child(command);
- FREE(command);
-
/* We listen to SIGTERM/QUIT/INT and try to exit cleanly, by stopping the main-loop.
* We only need those watchers on the stack, so putting them on the stack saves us
* some calls to free() */
}
/*
- * Initialize xcb and use the specified fontname for text-rendering
+ * Early initialization of the connection to X11: Everything which does not
+ * depend on 'config'.
*
*/
-char *init_xcb(char *fontname) {
+char *init_xcb_early() {
/* FIXME: xcb_connect leaks Memory */
xcb_connection = xcb_connect(NULL, &screen);
if (xcb_connection_has_error(xcb_connection)) {
xcb_screen = xcb_setup_roots_iterator(xcb_get_setup(xcb_connection)).data;
xcb_root = xcb_screen->root;
- /* We load and allocate the font */
- xcb_font = xcb_generate_id(xcb_connection);
- xcb_void_cookie_t open_font_cookie;
- open_font_cookie = xcb_open_font_checked(xcb_connection,
- xcb_font,
- strlen(fontname),
- fontname);
-
- /* We need to save info about the font, because we need the font's height and
- * information about the width of characters */
- xcb_query_font_cookie_t query_font_cookie;
- query_font_cookie = xcb_query_font(xcb_connection,
- xcb_font);
-
- /* To grab modifiers without blocking other applications from receiving key-events
- * involving that modifier, we sadly have to use xkb which is not yet fully supported
- * in xcb */
- if (config.hide_on_modifier) {
- int xkb_major, xkb_minor, xkb_errbase, xkb_err;
- xkb_major = XkbMajorVersion;
- xkb_minor = XkbMinorVersion;
-
- xkb_dpy = XkbOpenDisplay(NULL,
- &xkb_event_base,
- &xkb_errbase,
- &xkb_major,
- &xkb_minor,
- &xkb_err);
-
- if (xkb_dpy == NULL) {
- ELOG("No XKB!\n");
- exit(EXIT_FAILURE);
- }
-
- if (fcntl(ConnectionNumber(xkb_dpy), F_SETFD, FD_CLOEXEC) == -1) {
- ELOG("Could not set FD_CLOEXEC on xkbdpy: %s\n", strerror(errno));
- exit(EXIT_FAILURE);
- }
-
- int i1;
- if (!XkbQueryExtension(xkb_dpy, &i1, &xkb_event_base, &xkb_errbase, &xkb_major, &xkb_minor)) {
- ELOG("XKB not supported by X-server!\n");
- exit(EXIT_FAILURE);
- }
-
- if (!XkbSelectEvents(xkb_dpy, XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask)) {
- ELOG("Could not grab Key!\n");
- exit(EXIT_FAILURE);
- }
-
- xkb_io = malloc(sizeof(ev_io));
- ev_io_init(xkb_io, &xkb_io_cb, ConnectionNumber(xkb_dpy), EV_READ);
- ev_io_start(main_loop, xkb_io);
- XFlush(xkb_dpy);
- }
-
/* 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 */
uint32_t mask = XCB_GC_FOREGROUND;
- uint32_t vals[3] = { colors.bar_bg, colors.bar_bg, xcb_font };
+ uint32_t vals[] = { colors.bar_bg, colors.bar_bg };
statusline_clear = xcb_generate_id(xcb_connection);
xcb_void_cookie_t clear_ctx_cookie = xcb_create_gc_checked(xcb_connection,
mask,
vals);
- mask |= XCB_GC_BACKGROUND | XCB_GC_FONT;
+ mask |= XCB_GC_BACKGROUND;
vals[0] = colors.bar_fg;
statusline_ctx = xcb_generate_id(xcb_connection);
xcb_void_cookie_t sl_ctx_cookie = xcb_create_gc_checked(xcb_connection,
}
}
+
+ if (xcb_request_failed(sl_pm_cookie, "Could not allocate statusline-buffer") ||
+ xcb_request_failed(clear_ctx_cookie, "Could not allocate statusline-buffer-clearcontext") ||
+ xcb_request_failed(sl_ctx_cookie, "Could not allocate statusline-buffer-context")) {
+ exit(EXIT_FAILURE);
+ }
+
+ return path;
+}
+
+/*
+ * Initialization which depends on 'config' being usable. Called after the
+ * configuration has arrived.
+ *
+ */
+void init_xcb_late(char *fontname) {
+ if (fontname == NULL) {
+ /* This is a very restrictive default. More sensefull would be something like
+ * "-misc-*-*-*-*--*-*-*-*-*-*-*-*". But since that produces very ugly results
+ * on my machine, let's stick with this until we have a configfile */
+ fontname = "-misc-fixed-medium-r-semicondensed--12-110-75-75-c-60-iso10646-1";
+ }
+
+ /* We load and allocate the font */
+ xcb_font = xcb_generate_id(xcb_connection);
+ xcb_void_cookie_t open_font_cookie;
+ open_font_cookie = xcb_open_font_checked(xcb_connection,
+ xcb_font,
+ strlen(fontname),
+ fontname);
+
+ /* We need to save info about the font, because we need the font's height and
+ * information about the width of characters */
+ xcb_query_font_cookie_t query_font_cookie;
+ query_font_cookie = xcb_query_font(xcb_connection,
+ xcb_font);
+
+ xcb_change_gc(xcb_connection,
+ statusline_ctx,
+ XCB_GC_FONT,
+ (uint32_t[]){ xcb_font });
+
+ xcb_flush(xcb_connection);
+
+ /* To grab modifiers without blocking other applications from receiving key-events
+ * involving that modifier, we sadly have to use xkb which is not yet fully supported
+ * in xcb */
+ if (config.hide_on_modifier) {
+ int xkb_major, xkb_minor, xkb_errbase, xkb_err;
+ xkb_major = XkbMajorVersion;
+ xkb_minor = XkbMinorVersion;
+
+ xkb_dpy = XkbOpenDisplay(NULL,
+ &xkb_event_base,
+ &xkb_errbase,
+ &xkb_major,
+ &xkb_minor,
+ &xkb_err);
+
+ if (xkb_dpy == NULL) {
+ ELOG("No XKB!\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (fcntl(ConnectionNumber(xkb_dpy), F_SETFD, FD_CLOEXEC) == -1) {
+ ELOG("Could not set FD_CLOEXEC on xkbdpy: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ int i1;
+ if (!XkbQueryExtension(xkb_dpy, &i1, &xkb_event_base, &xkb_errbase, &xkb_major, &xkb_minor)) {
+ ELOG("XKB not supported by X-server!\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (!XkbSelectEvents(xkb_dpy, XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask)) {
+ ELOG("Could not grab Key!\n");
+ exit(EXIT_FAILURE);
+ }
+
+ xkb_io = malloc(sizeof(ev_io));
+ ev_io_init(xkb_io, &xkb_io_cb, ConnectionNumber(xkb_dpy), EV_READ);
+ ev_io_start(main_loop, xkb_io);
+ XFlush(xkb_dpy);
+ }
+
/* Now we save the font-infos */
font_info = xcb_query_font_reply(xcb_connection,
query_font_cookie,
}
DLOG("Calculated Font-height: %d\n", font_height);
-
- if (xcb_request_failed(sl_pm_cookie, "Could not allocate statusline-buffer") ||
- xcb_request_failed(clear_ctx_cookie, "Could not allocate statusline-buffer-clearcontext") ||
- xcb_request_failed(sl_ctx_cookie, "Could not allocate statusline-buffer-context")) {
- exit(EXIT_FAILURE);
- }
-
- return path;
}
/*