summaryrefslogtreecommitdiff
path: root/x11-wm
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--x11-wm/i3-4.10.2/i3bar-icons.patch437
l---------x11-wm/i3-4.10.31
-rw-r--r--x11-wm/i3-4.11/i3bar-icons.patch437
-rw-r--r--x11-wm/i3-4.12/i3bar-xbm-icons.patch501
-rw-r--r--x11-wm/i3-4.6/i3bar-4.6-icons.patch440
l---------x11-wm/i3-4.7.21
-rw-r--r--x11-wm/i3-4.7/i3bar-4.6-icons.patch440
-rw-r--r--x11-wm/i3-4.8/i3bar-icons.patch441
-rw-r--r--x11-wm/i3-4.8/move.patch152
-rw-r--r--x11-wm/i3-4.9.1/i3bar-icons.patch437
10 files changed, 0 insertions, 3287 deletions
diff --git a/x11-wm/i3-4.10.2/i3bar-icons.patch b/x11-wm/i3-4.10.2/i3bar-icons.patch
deleted file mode 100644
index e9cacb8..0000000
--- a/x11-wm/i3-4.10.2/i3bar-icons.patch
+++ /dev/null
@@ -1,437 +0,0 @@
-diff --git a/common.mk b/common.mk
-index b9e15a2..5c9bdf9 100644
---- a/common.mk
-+++ b/common.mk
-@@ -82,6 +82,7 @@ XCB_CFLAGS := $(call cflags_for_lib, xcb)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-event)
- XCB_LIBS := $(call ldflags_for_lib, xcb,xcb)
- XCB_LIBS += $(call ldflags_for_lib, xcb-event,xcb-event)
-+XCB_LIBS += $(call ldflags_for_lib, xcb-image,xcb-image)
- ifeq ($(shell pkg-config --exists xcb-util 2>/dev/null || echo 1),1)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-atom)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-aux)
-diff --git a/i3bar/include/common.h b/i3bar/include/common.h
-index 22b9a28..77072b1 100644
---- a/i3bar/include/common.h
-+++ b/i3bar/include/common.h
-@@ -10,6 +10,7 @@
- #include <stdbool.h>
- #include <xcb/xcb.h>
- #include <xcb/xproto.h>
-+#include <xcb/xcb_image.h>
- #include "libi3.h"
- #include "queue.h"
-
-@@ -38,6 +39,7 @@ struct status_block {
- i3String *short_text;
-
- char *color;
-+ char *icon;
-
- /* min_width can be specified either as a numeric value (in pixels) or as a
- * string. For strings, we set min_width to the measured text width of
-@@ -63,6 +65,7 @@ struct status_block {
- /* Optional */
- char *name;
- char *instance;
-+ xcb_image_t *icon_image;
-
- TAILQ_ENTRY(status_block) blocks;
- };
-@@ -76,6 +79,7 @@ TAILQ_HEAD(statusline_head, status_block) statusline_head;
- #include "workspaces.h"
- #include "mode.h"
- #include "trayclients.h"
-+#include "xbm.h"
- #include "xcb.h"
- #include "config.h"
- #include "libi3.h"
-diff --git a/i3bar/include/xbm.h b/i3bar/include/xbm.h
-new file mode 100644
-index 0000000..f3cc3d5
---- /dev/null
-+++ b/i3bar/include/xbm.h
-@@ -0,0 +1,47 @@
-+/*
-+ * vim:ts=4:sw=4:expandtab
-+ *
-+ * i3bar - an xcb-based status- and ws-bar for i3
-+ * © 2010-2011 Axel Wagner and contributors (see also: LICENSE)
-+ *
-+ * xbm.c: Parsing/Loading xbm data
-+ *
-+ */
-+#ifndef XBM_H_
-+#define XBM_H_
-+
-+#include "queue.h"
-+
-+#define BUFSZ 512
-+
-+struct raw_xbm {
-+ uint32_t w,h;
-+ uint32_t dlen;
-+ uint8_t *data;
-+};
-+
-+struct Cached_Xbm {
-+ char *path;
-+ xcb_image_t *icon;
-+ int used;
-+ SLIST_ENTRY(Cached_Xbm) xbm_cache;
-+};
-+
-+/* Set the format information for loaded icons */
-+void set_format(xcb_connection_t * c, uint8_t depth, uint8_t bpp);
-+
-+/* Set xcb context color for icon, needed with pango patch */
-+void set_icon_color(xcb_connection_t *c, xcb_gcontext_t gc,
-+ uint32_t foreground, uint32_t background);
-+
-+/* get the xcb image for the given icon path */
-+xcb_image_t* get_icon(char* path);
-+
-+/* cache functions */
-+void xbm_clear_cache_used();
-+xcb_image_t* xbm_get_cached_icon(char* path);
-+void xbm_cache_icon(char* path, xcb_image_t* icon);
-+void xbm_free_unused_icons();
-+
-+
-+#endif
-diff --git a/i3bar/src/child.c b/i3bar/src/child.c
-index 9cc50f2..298a4b7 100644
---- a/i3bar/src/child.c
-+++ b/i3bar/src/child.c
-@@ -72,6 +72,7 @@ static void clear_statusline(struct statusline_head *head, bool free_resources)
- I3STRING_FREE(first->full_text);
- I3STRING_FREE(first->short_text);
- FREE(first->color);
-+ FREE(first->icon);
- FREE(first->name);
- FREE(first->instance);
- FREE(first->min_width_str);
-@@ -206,6 +207,9 @@ static int stdin_string(void *context, const unsigned char *val, size_t len) {
- ctx->block.is_markup = (len == strlen("pango") && !strncasecmp((const char *)val, "pango", strlen("pango")));
- return 1;
- }
-+ if (strcasecmp(ctx->last_map_key, "icon") == 0) {
-+ sasprintf(&(ctx->block.icon), "%.*s", len, val);
-+ }
- if (strcasecmp(ctx->last_map_key, "align") == 0) {
- if (len == strlen("center") && !strncmp((const char *)val, "center", strlen("center"))) {
- ctx->block.align = ALIGN_CENTER;
-@@ -301,6 +305,7 @@ static int stdin_end_array(void *context) {
- DLOG("full_text = %s\n", i3string_as_utf8(current->full_text));
- DLOG("short_text = %s\n", (current->short_text == NULL ? NULL : i3string_as_utf8(current->short_text)));
- DLOG("color = %s\n", current->color);
-+ DLOG("icon = %s\n",current->icon);
- }
- DLOG("end of dump\n");
- return 1;
-diff --git a/i3bar/src/xbm.c b/i3bar/src/xbm.c
-new file mode 100644
-index 0000000..b6781e1
---- /dev/null
-+++ b/i3bar/src/xbm.c
-@@ -0,0 +1,238 @@
-+/*
-+ * vim:ts=4:sw=4:expandtab
-+ *
-+ * i3bar - an xcb-based status- and ws-bar for i3
-+ * © 2010-2011 Axel Wagner and contributors (see also: LICENSE)
-+ *
-+ * xbm.c: Parsing/Loading xbm data
-+ *
-+ * set_format from:
-+ * http://vincentsanders.blogspot.de/2010/04/xcb-programming-is-hard.html
-+ */
-+
-+#include <string.h>
-+
-+#include <xcb/xcb.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <sys/types.h>
-+#include <unistd.h>
-+#include <errno.h>
-+#include <string.h>
-+
-+#include "common.h"
-+
-+static xcb_format_t* format = NULL;
-+
-+void set_format(xcb_connection_t * c, uint8_t depth, uint8_t bpp) {
-+ const xcb_setup_t *setup = xcb_get_setup(c);
-+ xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
-+ xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
-+ for(; fmt != fmtend; ++fmt)
-+ if((fmt->depth == depth) && (fmt->bits_per_pixel == bpp))
-+ format = fmt;
-+}
-+
-+/* With pango we need to set colors ourselves, since the pango
-+ * patch only sets font color */
-+void set_icon_color(xcb_connection_t *c, xcb_gcontext_t gc,
-+ uint32_t foreground, uint32_t background) {
-+ uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
-+ uint32_t values[] = {foreground, background };
-+ xcb_change_gc(c, gc, mask, values);
-+}
-+
-+static int
-+parse_xbm(char* file, struct raw_xbm* data) {
-+ FILE *f;
-+ char *str;
-+ int i,p,r,lim;
-+ char *c;
-+ uint8_t *d;
-+
-+ int in_array = 0;
-+
-+ data->w = data->h = -1;
-+
-+ f = fopen(file,"r");
-+ if (!f) {
-+ ELOG("Could not open xbm file: %s",file);
-+ return 1;
-+ }
-+
-+ str=malloc(BUFSZ);
-+ if (!str) {
-+ ELOG("Could not malloc buffer for xbm parsing");
-+ fclose(f);
-+ return 1;
-+ }
-+
-+ while (fscanf(f," #define %s %d",str,&i) == 2) {
-+ if (strstr(str,"width") != NULL)
-+ data->w = i;
-+ else if (strstr(str,"height") != NULL)
-+ data->h = i;
-+ }
-+
-+ if (data->w <= 0 || data->h <= 0) {
-+ ELOG("Could not find height and/or width in xbm: %s\n",file);
-+ fclose(f);
-+ free(str);
-+ return 1;
-+ }
-+
-+ d = malloc(data->w*data->h);
-+ p = 0;
-+
-+ r = fread(str,1,BUFSZ,f);
-+ lim = r;
-+ while(r>0) {
-+ if(in_array) {
-+ while(c < (str+lim)) {
-+ char* t = c;
-+ while (*t && t!=(str+lim-1) && *t!=',' && *t!='}') t++;
-+ if (*t && (*t==',' || *t=='}'))
-+ d[p++] = strtol(c,NULL,16);
-+ else
-+ break;
-+ c=t+1;
-+ }
-+ } else {
-+ c = str;
-+ while (*c && c!=(str+lim) && *c!='{')
-+ c++;
-+ if (*c && c!=(str+lim) && *c=='{') {
-+ in_array=1;
-+ c++;
-+ if (c<(str+lim)) continue;
-+ }
-+ }
-+
-+ i = (str+lim)-c;
-+ if (i > 0) memcpy(str,c,i);
-+
-+ r = fread(str+i,1,BUFSZ-i,f);
-+ c=str;
-+ lim = r+i;
-+ }
-+
-+ fclose(f);
-+ free(str);
-+
-+ /* will free if p==0, so we only have malloced mem
-+ * when p!=0 */
-+ d = realloc(d,p);
-+
-+ data->dlen = p;
-+ data->data = d;
-+ return p==0;
-+}
-+
-+static xcb_image_t *
-+create_icon_image(struct raw_xbm *xbm) {
-+ int i,rowsize,done,di;
-+ unsigned char *imgdata;
-+ if (format == NULL) return NULL;
-+
-+ imgdata = (unsigned char *)calloc(xbm->w,xbm->h);
-+
-+ rowsize = format->scanline_pad;
-+ while(rowsize < xbm->w) rowsize+=format->scanline_pad;
-+
-+ for(done=0,di=0,i=0;i<xbm->dlen;i++) {
-+ imgdata[di] = xbm->data[i];
-+ di++;
-+ done+=8;
-+ if (done >= xbm->w) {
-+ // pad out to rowsize
-+ while (done < rowsize) {
-+ di++;
-+ done+=8;
-+ }
-+ done=0;
-+ }
-+ }
-+
-+ return xcb_image_create(xbm->w,
-+ xbm->h,
-+ XCB_IMAGE_FORMAT_XY_BITMAP,
-+ format->scanline_pad,
-+ format->depth,
-+ format->bits_per_pixel,
-+ 0,
-+ XCB_IMAGE_ORDER_LSB_FIRST,
-+ XCB_IMAGE_ORDER_LSB_FIRST,
-+ imgdata,
-+ xbm->w*xbm->h,
-+ imgdata);
-+}
-+
-+xcb_image_t* get_icon(char* path) {
-+ xcb_image_t* ret;
-+ struct raw_xbm rxbm;
-+
-+ ret = xbm_get_cached_icon(path);
-+ if (ret) return ret;
-+
-+ DLOG("Loading xbm: %s\n",path);
-+
-+ rxbm.data = NULL;
-+ if (parse_xbm(path,&rxbm)) {
-+ ELOG("Cannot parse xbm: %s\n",path);
-+ return NULL;
-+ }
-+ ret = create_icon_image(&rxbm);
-+ xbm_cache_icon(path,ret);
-+ free(rxbm.data);
-+ return ret;
-+}
-+
-+/* Below we implement a cache for parsed xbm icons.
-+ *
-+ * If an icon is used in a draw of the bar, it sticks around until the
-+ * next draw, otherwise we throw it away at the end of a update. The
-+ * idea being that most icons are fairly static, or change rarely
-+ * (like when a battery threshold is reached). Therefore, we are very
-+ * aggresive about throwing things out of the cache.
-+ */
-+
-+static SLIST_HEAD(xbm_cache_head, Cached_Xbm) xbm_cache;
-+
-+void xbm_clear_cache_used() {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ cxbm->used = 0;
-+ }
-+}
-+
-+xcb_image_t* xbm_get_cached_icon(char* path) {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ if (!strcmp(path,cxbm->path)) {
-+ cxbm->used = 1;
-+ return cxbm->icon;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+void xbm_cache_icon(char* path, xcb_image_t* icon) {
-+ struct Cached_Xbm *cxbm = smalloc(sizeof(struct Cached_Xbm));
-+ cxbm->used = 1;
-+ cxbm->path = strdup(path);
-+ cxbm->icon = icon;
-+ SLIST_INSERT_HEAD(&xbm_cache,cxbm,xbm_cache);
-+}
-+
-+void xbm_free_unused_icons() {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ if (!cxbm->used) {
-+ SLIST_REMOVE(&xbm_cache, cxbm, Cached_Xbm, xbm_cache);
-+ free(cxbm->path);
-+ xcb_image_destroy(cxbm->icon);
-+ free(cxbm);
-+ }
-+ }
-+}
-+
-diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c
-index e53b922..5c14977 100644
---- a/i3bar/src/xcb.c
-+++ b/i3bar/src/xcb.c
-@@ -208,6 +208,14 @@ void refresh_statusline(bool use_short_text) {
-
- block->width = predict_text_width(block->full_text);
-
-+ if (block->icon) {
-+ block->icon_image = get_icon(block->icon);
-+ if (!block->icon_image)
-+ ELOG("Could not load icon: %s\n",block->icon);
-+ else
-+ statusline_width += block->icon_image->width+1;
-+ }
-+
- /* Compute offset and append for text aligment in min_width. */
- if (block->min_width <= block->width) {
- block->x_offset = 0;
-@@ -272,6 +280,15 @@ void refresh_statusline(bool use_short_text) {
- }
-
- set_font_colors(statusline_ctx, fg_color, colors.bar_bg);
-+
-+ if (block->icon_image) {
-+ int h = (font.height-block->icon_image->height)/2;
-+ set_icon_color(xcb_connection, statusline_ctx, fg_color, colors.bar_bg);
-+ xcb_image_put(xcb_connection, statusline_pm, statusline_ctx, block->icon_image, x, h, 0);
-+ set_icon_color(xcb_connection, statusline_ctx, get_colorpixel("#666666"), colors.bar_bg);
-+ x += block->icon_image->width+1;
-+ }
-+
- draw_text(block->full_text, statusline_pm, statusline_ctx, x + block->x_offset, logical_px(ws_voff_px), block->width);
- x += block->width + block->sep_block_width + block->x_offset + block->x_append;
-
-@@ -1152,6 +1169,9 @@ char *init_xcb_early() {
- /* Now we get the atoms and save them in a nice data structure */
- get_atoms();
-
-+ /* Set the format for icons */
-+ set_format(xcb_connection,1,1);
-+
- char *path = root_atom_contents("I3_SOCKET_PATH", xcb_connection, screen);
-
- if (xcb_request_failed(sl_pm_cookie, "Could not allocate statusline buffer") ||
-@@ -1796,6 +1816,7 @@ void draw_bars(bool unhide) {
- DLOG("Drawing bars...\n");
- int workspace_width = 0;
-
-+ xbm_clear_cache_used();
- refresh_statusline(false);
-
- i3_output *outputs_walk;
-@@ -1972,6 +1993,8 @@ void draw_bars(bool unhide) {
- hide_bars();
- }
-
-+ xbm_free_unused_icons();
-+
- redraw_bars();
- }
-
diff --git a/x11-wm/i3-4.10.3 b/x11-wm/i3-4.10.3
deleted file mode 120000
index 4974505..0000000
--- a/x11-wm/i3-4.10.3
+++ /dev/null
@@ -1 +0,0 @@
-i3-4.10.2 \ No newline at end of file
diff --git a/x11-wm/i3-4.11/i3bar-icons.patch b/x11-wm/i3-4.11/i3bar-icons.patch
deleted file mode 100644
index a1a56e3..0000000
--- a/x11-wm/i3-4.11/i3bar-icons.patch
+++ /dev/null
@@ -1,437 +0,0 @@
-diff --git a/common.mk b/common.mk
-index d287504..d6b7d92 100644
---- a/common.mk
-+++ b/common.mk
-@@ -85,6 +85,7 @@ XCB_CFLAGS := $(call cflags_for_lib, xcb)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-event)
- XCB_LIBS := $(call ldflags_for_lib, xcb,xcb)
- XCB_LIBS += $(call ldflags_for_lib, xcb-event,xcb-event)
-+XCB_LIBS += $(call ldflags_for_lib, xcb-image,xcb-image)
- ifeq ($(shell $(PKG_CONFIG) --exists xcb-util 2>/dev/null || echo 1),1)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-atom)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-aux)
-diff --git a/i3bar/include/common.h b/i3bar/include/common.h
-index 90da938..c8dda14 100644
---- a/i3bar/include/common.h
-+++ b/i3bar/include/common.h
-@@ -10,6 +10,7 @@
- #include <stdbool.h>
- #include <xcb/xcb.h>
- #include <xcb/xproto.h>
-+#include <xcb/xcb_image.h>
- #include "libi3.h"
- #include "queue.h"
-
-@@ -38,6 +39,7 @@ struct status_block {
- i3String *short_text;
-
- char *color;
-+ char *icon;
-
- /* min_width can be specified either as a numeric value (in pixels) or as a
- * string. For strings, we set min_width to the measured text width of
-@@ -63,6 +65,7 @@ struct status_block {
- /* Optional */
- char *name;
- char *instance;
-+ xcb_image_t *icon_image;
-
- TAILQ_ENTRY(status_block) blocks;
- };
-@@ -76,6 +79,7 @@ TAILQ_HEAD(statusline_head, status_block) statusline_head;
- #include "workspaces.h"
- #include "mode.h"
- #include "trayclients.h"
-+#include "xbm.h"
- #include "xcb.h"
- #include "config.h"
- #include "libi3.h"
-diff --git a/i3bar/include/xbm.h b/i3bar/include/xbm.h
-new file mode 100644
-index 0000000..f3cc3d5
---- /dev/null
-+++ b/i3bar/include/xbm.h
-@@ -0,0 +1,47 @@
-+/*
-+ * vim:ts=4:sw=4:expandtab
-+ *
-+ * i3bar - an xcb-based status- and ws-bar for i3
-+ * © 2010-2011 Axel Wagner and contributors (see also: LICENSE)
-+ *
-+ * xbm.c: Parsing/Loading xbm data
-+ *
-+ */
-+#ifndef XBM_H_
-+#define XBM_H_
-+
-+#include "queue.h"
-+
-+#define BUFSZ 512
-+
-+struct raw_xbm {
-+ uint32_t w,h;
-+ uint32_t dlen;
-+ uint8_t *data;
-+};
-+
-+struct Cached_Xbm {
-+ char *path;
-+ xcb_image_t *icon;
-+ int used;
-+ SLIST_ENTRY(Cached_Xbm) xbm_cache;
-+};
-+
-+/* Set the format information for loaded icons */
-+void set_format(xcb_connection_t * c, uint8_t depth, uint8_t bpp);
-+
-+/* Set xcb context color for icon, needed with pango patch */
-+void set_icon_color(xcb_connection_t *c, xcb_gcontext_t gc,
-+ uint32_t foreground, uint32_t background);
-+
-+/* get the xcb image for the given icon path */
-+xcb_image_t* get_icon(char* path);
-+
-+/* cache functions */
-+void xbm_clear_cache_used();
-+xcb_image_t* xbm_get_cached_icon(char* path);
-+void xbm_cache_icon(char* path, xcb_image_t* icon);
-+void xbm_free_unused_icons();
-+
-+
-+#endif
-diff --git a/i3bar/src/child.c b/i3bar/src/child.c
-index cfc96d5..dff3f36 100644
---- a/i3bar/src/child.c
-+++ b/i3bar/src/child.c
-@@ -72,6 +72,7 @@ static void clear_statusline(struct statusline_head *head, bool free_resources)
- I3STRING_FREE(first->full_text);
- I3STRING_FREE(first->short_text);
- FREE(first->color);
-+ FREE(first->icon);
- FREE(first->name);
- FREE(first->instance);
- FREE(first->min_width_str);
-@@ -209,6 +210,9 @@ static int stdin_string(void *context, const unsigned char *val, size_t len) {
- ctx->block.is_markup = (len == strlen("pango") && !strncasecmp((const char *)val, "pango", strlen("pango")));
- return 1;
- }
-+ if (strcasecmp(ctx->last_map_key, "icon") == 0) {
-+ sasprintf(&(ctx->block.icon), "%.*s", len, val);
-+ }
- if (strcasecmp(ctx->last_map_key, "align") == 0) {
- if (len == strlen("center") && !strncmp((const char *)val, "center", strlen("center"))) {
- ctx->block.align = ALIGN_CENTER;
-@@ -304,6 +308,7 @@ static int stdin_end_array(void *context) {
- DLOG("full_text = %s\n", i3string_as_utf8(current->full_text));
- DLOG("short_text = %s\n", (current->short_text == NULL ? NULL : i3string_as_utf8(current->short_text)));
- DLOG("color = %s\n", current->color);
-+ DLOG("icon = %s\n",current->icon);
- }
- DLOG("end of dump\n");
- return 1;
-diff --git a/i3bar/src/xbm.c b/i3bar/src/xbm.c
-new file mode 100644
-index 0000000..b6781e1
---- /dev/null
-+++ b/i3bar/src/xbm.c
-@@ -0,0 +1,238 @@
-+/*
-+ * vim:ts=4:sw=4:expandtab
-+ *
-+ * i3bar - an xcb-based status- and ws-bar for i3
-+ * © 2010-2011 Axel Wagner and contributors (see also: LICENSE)
-+ *
-+ * xbm.c: Parsing/Loading xbm data
-+ *
-+ * set_format from:
-+ * http://vincentsanders.blogspot.de/2010/04/xcb-programming-is-hard.html
-+ */
-+
-+#include <string.h>
-+
-+#include <xcb/xcb.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <sys/types.h>
-+#include <unistd.h>
-+#include <errno.h>
-+#include <string.h>
-+
-+#include "common.h"
-+
-+static xcb_format_t* format = NULL;
-+
-+void set_format(xcb_connection_t * c, uint8_t depth, uint8_t bpp) {
-+ const xcb_setup_t *setup = xcb_get_setup(c);
-+ xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
-+ xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
-+ for(; fmt != fmtend; ++fmt)
-+ if((fmt->depth == depth) && (fmt->bits_per_pixel == bpp))
-+ format = fmt;
-+}
-+
-+/* With pango we need to set colors ourselves, since the pango
-+ * patch only sets font color */
-+void set_icon_color(xcb_connection_t *c, xcb_gcontext_t gc,
-+ uint32_t foreground, uint32_t background) {
-+ uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
-+ uint32_t values[] = {foreground, background };
-+ xcb_change_gc(c, gc, mask, values);
-+}
-+
-+static int
-+parse_xbm(char* file, struct raw_xbm* data) {
-+ FILE *f;
-+ char *str;
-+ int i,p,r,lim;
-+ char *c;
-+ uint8_t *d;
-+
-+ int in_array = 0;
-+
-+ data->w = data->h = -1;
-+
-+ f = fopen(file,"r");
-+ if (!f) {
-+ ELOG("Could not open xbm file: %s",file);
-+ return 1;
-+ }
-+
-+ str=malloc(BUFSZ);
-+ if (!str) {
-+ ELOG("Could not malloc buffer for xbm parsing");
-+ fclose(f);
-+ return 1;
-+ }
-+
-+ while (fscanf(f," #define %s %d",str,&i) == 2) {
-+ if (strstr(str,"width") != NULL)
-+ data->w = i;
-+ else if (strstr(str,"height") != NULL)
-+ data->h = i;
-+ }
-+
-+ if (data->w <= 0 || data->h <= 0) {
-+ ELOG("Could not find height and/or width in xbm: %s\n",file);
-+ fclose(f);
-+ free(str);
-+ return 1;
-+ }
-+
-+ d = malloc(data->w*data->h);
-+ p = 0;
-+
-+ r = fread(str,1,BUFSZ,f);
-+ lim = r;
-+ while(r>0) {
-+ if(in_array) {
-+ while(c < (str+lim)) {
-+ char* t = c;
-+ while (*t && t!=(str+lim-1) && *t!=',' && *t!='}') t++;
-+ if (*t && (*t==',' || *t=='}'))
-+ d[p++] = strtol(c,NULL,16);
-+ else
-+ break;
-+ c=t+1;
-+ }
-+ } else {
-+ c = str;
-+ while (*c && c!=(str+lim) && *c!='{')
-+ c++;
-+ if (*c && c!=(str+lim) && *c=='{') {
-+ in_array=1;
-+ c++;
-+ if (c<(str+lim)) continue;
-+ }
-+ }
-+
-+ i = (str+lim)-c;
-+ if (i > 0) memcpy(str,c,i);
-+
-+ r = fread(str+i,1,BUFSZ-i,f);
-+ c=str;
-+ lim = r+i;
-+ }
-+
-+ fclose(f);
-+ free(str);
-+
-+ /* will free if p==0, so we only have malloced mem
-+ * when p!=0 */
-+ d = realloc(d,p);
-+
-+ data->dlen = p;
-+ data->data = d;
-+ return p==0;
-+}
-+
-+static xcb_image_t *
-+create_icon_image(struct raw_xbm *xbm) {
-+ int i,rowsize,done,di;
-+ unsigned char *imgdata;
-+ if (format == NULL) return NULL;
-+
-+ imgdata = (unsigned char *)calloc(xbm->w,xbm->h);
-+
-+ rowsize = format->scanline_pad;
-+ while(rowsize < xbm->w) rowsize+=format->scanline_pad;
-+
-+ for(done=0,di=0,i=0;i<xbm->dlen;i++) {
-+ imgdata[di] = xbm->data[i];
-+ di++;
-+ done+=8;
-+ if (done >= xbm->w) {
-+ // pad out to rowsize
-+ while (done < rowsize) {
-+ di++;
-+ done+=8;
-+ }
-+ done=0;
-+ }
-+ }
-+
-+ return xcb_image_create(xbm->w,
-+ xbm->h,
-+ XCB_IMAGE_FORMAT_XY_BITMAP,
-+ format->scanline_pad,
-+ format->depth,
-+ format->bits_per_pixel,
-+ 0,
-+ XCB_IMAGE_ORDER_LSB_FIRST,
-+ XCB_IMAGE_ORDER_LSB_FIRST,
-+ imgdata,
-+ xbm->w*xbm->h,
-+ imgdata);
-+}
-+
-+xcb_image_t* get_icon(char* path) {
-+ xcb_image_t* ret;
-+ struct raw_xbm rxbm;
-+
-+ ret = xbm_get_cached_icon(path);
-+ if (ret) return ret;
-+
-+ DLOG("Loading xbm: %s\n",path);
-+
-+ rxbm.data = NULL;
-+ if (parse_xbm(path,&rxbm)) {
-+ ELOG("Cannot parse xbm: %s\n",path);
-+ return NULL;
-+ }
-+ ret = create_icon_image(&rxbm);
-+ xbm_cache_icon(path,ret);
-+ free(rxbm.data);
-+ return ret;
-+}
-+
-+/* Below we implement a cache for parsed xbm icons.
-+ *
-+ * If an icon is used in a draw of the bar, it sticks around until the
-+ * next draw, otherwise we throw it away at the end of a update. The
-+ * idea being that most icons are fairly static, or change rarely
-+ * (like when a battery threshold is reached). Therefore, we are very
-+ * aggresive about throwing things out of the cache.
-+ */
-+
-+static SLIST_HEAD(xbm_cache_head, Cached_Xbm) xbm_cache;
-+
-+void xbm_clear_cache_used() {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ cxbm->used = 0;
-+ }
-+}
-+
-+xcb_image_t* xbm_get_cached_icon(char* path) {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ if (!strcmp(path,cxbm->path)) {
-+ cxbm->used = 1;
-+ return cxbm->icon;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+void xbm_cache_icon(char* path, xcb_image_t* icon) {
-+ struct Cached_Xbm *cxbm = smalloc(sizeof(struct Cached_Xbm));
-+ cxbm->used = 1;
-+ cxbm->path = strdup(path);
-+ cxbm->icon = icon;
-+ SLIST_INSERT_HEAD(&xbm_cache,cxbm,xbm_cache);
-+}
-+
-+void xbm_free_unused_icons() {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ if (!cxbm->used) {
-+ SLIST_REMOVE(&xbm_cache, cxbm, Cached_Xbm, xbm_cache);
-+ free(cxbm->path);
-+ xcb_image_destroy(cxbm->icon);
-+ free(cxbm);
-+ }
-+ }
-+}
-+
-diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c
-index f90bbce..9796a6d 100644
---- a/i3bar/src/xcb.c
-+++ b/i3bar/src/xcb.c
-@@ -211,6 +211,14 @@ void refresh_statusline(bool use_short_text) {
-
- block->width = predict_text_width(block->full_text);
-
-+ if (block->icon) {
-+ block->icon_image = get_icon(block->icon);
-+ if (!block->icon_image)
-+ ELOG("Could not load icon: %s\n",block->icon);
-+ else
-+ statusline_width += block->icon_image->width+1;
-+ }
-+
- /* Compute offset and append for text aligment in min_width. */
- if (block->min_width <= block->width) {
- block->x_offset = 0;
-@@ -275,6 +283,15 @@ void refresh_statusline(bool use_short_text) {
- }
-
- set_font_colors(statusline_ctx, fg_color, colors.bar_bg);
-+
-+ if (block->icon_image) {
-+ int h = (font.height-block->icon_image->height)/2;
-+ set_icon_color(xcb_connection, statusline_ctx, fg_color, colors.bar_bg);
-+ xcb_image_put(xcb_connection, statusline_pm, statusline_ctx, block->icon_image, x, h, 0);
-+ set_icon_color(xcb_connection, statusline_ctx, get_colorpixel("#666666"), colors.bar_bg);
-+ x += block->icon_image->width+1;
-+ }
-+
- draw_text(block->full_text, statusline_pm, statusline_ctx, x + block->x_offset, logical_px(ws_voff_px), block->width);
- x += block->width + block->sep_block_width + block->x_offset + block->x_append;
-
-@@ -1161,6 +1178,9 @@ char *init_xcb_early() {
- /* Now we get the atoms and save them in a nice data structure */
- get_atoms();
-
-+ /* Set the format for icons */
-+ set_format(xcb_connection,1,1);
-+
- char *path = root_atom_contents("I3_SOCKET_PATH", xcb_connection, screen);
-
- if (xcb_request_failed(sl_pm_cookie, "Could not allocate statusline buffer") ||
-@@ -1807,6 +1827,7 @@ void draw_bars(bool unhide) {
- /* Is the currently-rendered statusline using short_text items? */
- bool rendered_statusline_is_short = false;
-
-+ xbm_clear_cache_used();
- refresh_statusline(false);
-
- i3_output *outputs_walk;
-@@ -1990,6 +2011,8 @@ void draw_bars(bool unhide) {
- hide_bars();
- }
-
-+ xbm_free_unused_icons();
-+
- redraw_bars();
- }
-
diff --git a/x11-wm/i3-4.12/i3bar-xbm-icons.patch b/x11-wm/i3-4.12/i3bar-xbm-icons.patch
deleted file mode 100644
index 4b8d706..0000000
--- a/x11-wm/i3-4.12/i3bar-xbm-icons.patch
+++ /dev/null
@@ -1,501 +0,0 @@
-From 9dccd2ed48aff688e19cbce5f2b548b0b47ee526 Mon Sep 17 00:00:00 2001
-From: Artem Shinkarov <artyom.shinkaroff@gmail.com>
-Date: Tue, 28 Apr 2015 14:25:01 +0100
-Subject: [PATCH 1/2] Supporting *.xbm icons in i3bar.
-
-Very often in order to display non-default information in the status bar
-it comes handy to use icons near the text for aesthetic reasons and for
-faster navigation. XBM bitmaps is a very simple format to store pixel
-maps, and this patch allows to specify in the i3bar block two additional
-fields: icon, and icon_color. Icon field contains a path to the *.xbm
-file, and the icon_color -- colour to use when drawing the icon.
-
-XBM file parsing is written by hands, as Xlib implementation is not
-that easy to integrate in the xcb environment.
-
-People who contributed:
-
- * Artem Shinkarov
- Original patch.
-
- * woho (https://github.com/woho)
- Fixed icon coloring problem on Arch Linux.
-
- * soulofmachines (https://github.com/soulofmachines)
- Fixed click event, making sure it considers the icon if present.
-
- * btolsch (https://github.com/btolsch)
- Fixed an error when the xcb_image was created height and width
- were specified in the wrong order:
- https://github.com/ashinkarov/i3-extras/pull/29
----
- common.mk | 2 +
- i3bar/include/common.h | 4 +
- i3bar/include/xbm_image.h | 14 +++
- i3bar/src/child.c | 11 ++
- i3bar/src/xbm_image.c | 278 ++++++++++++++++++++++++++++++++++++++++++++++
- i3bar/src/xcb.c | 46 +++++++-
- 6 files changed, 353 insertions(+), 2 deletions(-)
- create mode 100644 i3bar/include/xbm_image.h
- create mode 100644 i3bar/src/xbm_image.c
-
-diff --git a/common.mk b/common.mk
-index 4fe8f2b..bef7877 100644
---- a/common.mk
-+++ b/common.mk
-@@ -89,8 +89,10 @@ ldflags_for_lib = $(shell $(PKG_CONFIG) --exists 2>/dev/null $(1) && $(PKG_CONFI
- # XCB common stuff
- XCB_CFLAGS := $(call cflags_for_lib, xcb)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-event)
-+XCB_CFLAGS += $(call cflags_for_lib, xcb-image)
- XCB_LIBS := $(call ldflags_for_lib, xcb,xcb)
- XCB_LIBS += $(call ldflags_for_lib, xcb-event,xcb-event)
-+XCB_LIBS += $(call ldflags_for_lib, xcb-image,xcb-image)
- ifeq ($(shell $(PKG_CONFIG) --exists xcb-util 2>/dev/null || echo 1),1)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-atom)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-aux)
-diff --git a/i3bar/include/common.h b/i3bar/include/common.h
-index 0d46ab6..9e47dae 100644
---- a/i3bar/include/common.h
-+++ b/i3bar/include/common.h
-@@ -12,6 +12,7 @@
- #include <xcb/xproto.h>
- #include "libi3.h"
- #include "queue.h"
-+#include "xbm_image.h"
-
- typedef struct rect_t rect;
-
-@@ -57,6 +58,9 @@ struct status_block {
-
- blockalign_t align;
-
-+ struct xbm_image *icon;
-+ char *icon_color;
-+
- bool urgent;
- bool no_separator;
- bool pango_markup;
-diff --git a/i3bar/include/xbm_image.h b/i3bar/include/xbm_image.h
-new file mode 100644
-index 0000000..3c01c84
---- /dev/null
-+++ b/i3bar/include/xbm_image.h
-@@ -0,0 +1,14 @@
-+#ifndef __XBM_IMAGE_H__
-+#define __XBM_IMAGE_H__
-+
-+struct xbm_image {
-+ int width, height;
-+ char * id;
-+ char * data;
-+};
-+
-+
-+struct xbm_image * xbm_from_file (char *);
-+void xbm_free (struct xbm_image *);
-+
-+#endif /* __XBM_IMAGE_H__ */
-diff --git a/i3bar/src/child.c b/i3bar/src/child.c
-index 3570dde..991e920 100644
---- a/i3bar/src/child.c
-+++ b/i3bar/src/child.c
-@@ -77,6 +77,8 @@ static void clear_statusline(struct statusline_head *head, bool free_resources)
- FREE(first->min_width_str);
- FREE(first->background);
- FREE(first->border);
-+ FREE(first->icon_color);
-+ xbm_free (first->icon);
- }
-
- TAILQ_REMOVE(head, first, blocks);
-@@ -219,6 +221,15 @@ static int stdin_string(void *context, const unsigned char *val, size_t len) {
- ctx->block.pango_markup = (len == strlen("pango") && !strncasecmp((const char *)val, "pango", strlen("pango")));
- return 1;
- }
-+ if (strcasecmp(ctx->last_map_key, "icon") == 0) {
-+ char * s;
-+ sasprintf(&s, "%.*s", len, val);
-+ ctx->block.icon = xbm_from_file(s);
-+ FREE(s);
-+ }
-+ if (strcasecmp(ctx->last_map_key, "icon_color") == 0) {
-+ sasprintf(&(ctx->block.icon_color), "%.*s", len, val);
-+ }
- if (strcasecmp(ctx->last_map_key, "align") == 0) {
- if (len == strlen("center") && !strncmp((const char *)val, "center", strlen("center"))) {
- ctx->block.align = ALIGN_CENTER;
-diff --git a/i3bar/src/xbm_image.c b/i3bar/src/xbm_image.c
-new file mode 100644
-index 0000000..ea99ffa
---- /dev/null
-+++ b/i3bar/src/xbm_image.c
-@@ -0,0 +1,278 @@
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <ctype.h>
-+#include <stdbool.h>
-+
-+#include "xbm_image.h"
-+
-+#if FILENAME_CHECKING
-+/* Assume that file is called xxx.xbm, get xxx out of the filename
-+ for furhter validation during parsing. */
-+static char *
-+validate_fname (char * fname)
-+{
-+ char * dot = strrchr (fname, '.');
-+ char * slash = strrchr (fname, '/');
-+ char * ret = NULL;
-+ unsigned sz = 0;
-+
-+ if (NULL == dot)
-+ return NULL;
-+
-+ if (0 != strncmp (dot, ".xbm", 4))
-+ return NULL;
-+
-+ if (slash)
-+ fname = slash + 1;
-+
-+ sz = dot - fname;
-+ ret = malloc (sz + 1);
-+ strncpy (ret, fname, sz);
-+ ret[sz] = 0;
-+ return ret;
-+}
-+#endif
-+
-+static char *
-+read_id (FILE * f)
-+{
-+ unsigned sz = 2, ptr = 0;
-+ char * data = malloc (sz);
-+ int c;
-+
-+ c = fgetc (f);
-+ if (isalpha (c) || c == '_')
-+ data[ptr++] = c;
-+ else
-+ goto out;
-+
-+ while (true) {
-+ c = fgetc (f);
-+ if (ptr == sz - 1)
-+ data = realloc (data, sz *= 2);
-+
-+ if (isalnum (c) || c == '_')
-+ data[ptr++] = c;
-+ else {
-+ ungetc (c, f);
-+ break;
-+ }
-+ }
-+
-+ data[ptr] = '\0';
-+ return data;
-+
-+out:
-+ if (data)
-+ free (data);
-+
-+ return NULL;
-+}
-+
-+
-+static bool
-+read_string (FILE * f, const char * s)
-+{
-+ while (*s != '\0') {
-+ int c = fgetc (f);
-+ if (c == EOF || c != *s) {
-+ ungetc (c, f);
-+ return false;
-+ }
-+ s++;
-+ }
-+
-+ return true;
-+}
-+
-+static bool
-+skip_spaces (FILE * f)
-+{
-+ int c;
-+ while (isspace (c = fgetc (f)) && c != EOF)
-+ ;
-+
-+ ungetc (c, f);
-+ return true;
-+}
-+
-+static inline bool
-+string_ends_with (const char * s, const char * postfix)
-+{
-+ return strlen (s) > strlen (postfix)
-+ && strncmp (s + strlen (s) - strlen (postfix),
-+ postfix, strlen (postfix)) == 0;
-+}
-+
-+#define READ_WORD_EAT_SPACES(file, word) \
-+do { \
-+ if (!read_string (file, word)) \
-+ return false; \
-+ skip_spaces (file); \
-+} while (0)
-+
-+
-+static bool
-+read_define (FILE * f, struct xbm_image * img)
-+{
-+ unsigned sz;
-+ char * wh;
-+
-+ READ_WORD_EAT_SPACES (f, "define");
-+
-+ /* read the <id>_width variable, and save <id> for
-+ later validation in the img. */
-+ if (NULL == (wh = read_id (f)))
-+ return false;
-+
-+ if (string_ends_with (wh, "_width")) {
-+ if (!img->id) {
-+ unsigned idsz = strlen (wh) - strlen ("_width");
-+ img->id = malloc (idsz+1);
-+ strncpy (img->id, wh, idsz);
-+ img->id[idsz] = '\0';
-+ } else if (0 != strncmp (img->id, wh, strlen (img->id))) {
-+ free (wh);
-+ return false;
-+ }
-+
-+ free (wh);
-+ skip_spaces (f);
-+ if (fscanf (f, "%u", &sz) < 1)
-+ return false;
-+
-+ img->width = sz;
-+ } else if (string_ends_with (wh, "_height")) {
-+ if (!img->id) {
-+ unsigned idsz = strlen (wh) - strlen ("_height");
-+ img->id = malloc (idsz+1);
-+ strncpy (img->id, wh, idsz);
-+ img->id[idsz] = '\0';
-+ } else if (0 != strncmp (img->id, wh, strlen (img->id))) {
-+ free (wh);
-+ return false;
-+ }
-+
-+ free (wh);
-+ skip_spaces (f);
-+ if (fscanf (f, "%u", &sz) < 1)
-+ return false;
-+
-+ img->height = sz;
-+ } else
-+ return false;
-+
-+ return true;
-+}
-+
-+static bool
-+read_data (FILE * f, struct xbm_image * img)
-+{
-+ int sz, i;
-+ char * data;
-+
-+ /* size in bytes */
-+ sz = (img->width / 8 + !!(img->width % 8)) * img->height;
-+
-+ data = malloc (sz);
-+
-+ READ_WORD_EAT_SPACES (f, "tatic");
-+ READ_WORD_EAT_SPACES (f, "unsigned");
-+ READ_WORD_EAT_SPACES (f, "char");
-+ READ_WORD_EAT_SPACES (f, img->id);
-+ READ_WORD_EAT_SPACES (f, "_bits[]");
-+ READ_WORD_EAT_SPACES (f, "=");
-+ READ_WORD_EAT_SPACES (f, "{");
-+
-+ for (i = 0; i < sz; i++) {
-+ unsigned value;
-+ if (fscanf (f, "%x", &value) < 1 || value > 255)
-+ return false;
-+
-+ data[i] = (char)value;
-+ skip_spaces (f);
-+ if (i != sz - 1)
-+ READ_WORD_EAT_SPACES (f, ",");
-+ }
-+
-+ READ_WORD_EAT_SPACES (f, "}");
-+ READ_WORD_EAT_SPACES (f, ";");
-+ img->data = data;
-+ return true;
-+}
-+
-+
-+struct xbm_image *
-+xbm_from_file (char * fname)
-+{
-+ struct xbm_image * img = NULL;
-+ FILE * f = NULL;
-+ int c;
-+
-+ if (!(f = fopen (fname, "r")))
-+ goto out;
-+
-+ img = malloc (sizeof (struct xbm_image));
-+ img->id = NULL;
-+ img->width = -1;
-+ img->height = -1;
-+
-+ do {
-+ c = fgetc (f);
-+ if (c == '#') {
-+ if (!read_define (f, img))
-+ goto out;
-+ } else if (c == 's') {
-+ if (img->width == -1 || img->height == -1 || !img->id
-+ || !read_data (f, img))
-+ goto out;
-+ } else if (isspace (c) || c == EOF)
-+ ;
-+ else
-+ goto out;
-+ } while (c != EOF);
-+
-+ fclose (f);
-+ return img;
-+
-+out:
-+ if (f)
-+ fclose (f);
-+
-+ return NULL;
-+}
-+
-+void
-+xbm_free (struct xbm_image * img)
-+{
-+ if (!img)
-+ return;
-+
-+ if (img->id)
-+ free (img->id);
-+ if (img->data)
-+ free (img->data);
-+
-+ free (img);
-+}
-+
-+#ifdef TESTING
-+int
-+main (int argc, char *argv[])
-+{
-+ struct xbm_image * img;
-+ int i;
-+
-+ img = xbm_from_file (argv[1]);
-+
-+ if (img != NULL) {
-+ for (i = 0; i < (img->width /8 + !!(img->width % 8)) * img->height; i++)
-+ printf ("%x, ", (unsigned char)img->data[i]);
-+
-+ xbm_free (img);
-+ }
-+
-+ return EXIT_SUCCESS;
-+}
-+#endif
-diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c
-index 496035c..c9a4573 100644
---- a/i3bar/src/xcb.c
-+++ b/i3bar/src/xcb.c
-@@ -12,6 +12,7 @@
- #include <xcb/xproto.h>
- #include <xcb/xcb_aux.h>
- #include <xcb/xcb_cursor.h>
-+#include <xcb/xcb_image.h>
-
- #ifdef XCB_COMPAT
- #include "xcb_compat.h"
-@@ -209,7 +210,7 @@ uint32_t predict_statusline_length(bool use_short_text) {
- render = &block->short_render;
- }
-
-- if (i3string_get_num_bytes(text) == 0)
-+ if (i3string_get_num_bytes(text) == 0 && block->icon == NULL)
- continue;
-
- render->width = predict_text_width(text);
-@@ -241,6 +242,10 @@ uint32_t predict_statusline_length(bool use_short_text) {
- /* If this is not the last block, add some pixels for a separator. */
- if (TAILQ_NEXT(block, blocks) != NULL)
- width += block->sep_block_width;
-+
-+ /* Add some space between the text and the icon. */
-+ if (block->icon)
-+ width += block->icon->width + 5;
- }
-
- return width;
-@@ -272,9 +277,42 @@ void draw_statusline(i3_output *output, uint32_t clip_left, bool use_focus_color
- render = &block->short_render;
- }
-
-- if (i3string_get_num_bytes(text) == 0)
-+ if (i3string_get_num_bytes(block->full_text) == 0 && block->icon == NULL)
- continue;
-
-+ if (block->icon != NULL) {
-+ xcb_image_t * img;
-+
-+ img = xcb_image_create_native (conn, block->icon->width,
-+ block->icon->height,
-+ XCB_IMAGE_FORMAT_XY_BITMAP,
-+ 1, NULL, ~0, NULL);
-+
-+ img->data = malloc (img->size);
-+ memset (img->data, 0, img->size);
-+
-+ for (int i = 0; i < block->icon->height; i++)
-+ for (int j = 0; j < block->icon->width; j++) {
-+ unsigned pos = (img->width /8 + !!(img->width % 8))*i + j/8;
-+ bool p = !!(block->icon->data[pos] & (1 << (j%8)));
-+ xcb_image_put_pixel (img, j, i, p);
-+ }
-+
-+ uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
-+ if (block->icon_color) {
-+ uint32_t values[] = { get_colorpixel(block->icon_color), colors.bar_bg.colorpixel };
-+ xcb_change_gc(xcb_connection, output->statusline_buffer.gc, mask, values);
-+ } else {
-+ uint32_t values[] = { colors.bar_fg.colorpixel, colors.bar_bg.colorpixel };
-+ xcb_change_gc(xcb_connection, output->statusline_buffer.gc, mask, values);
-+ }
-+
-+ xcb_image_put (conn, output->statusline_buffer.id, output->statusline_buffer.gc,
-+ img, x, 3 + (font.height - block->icon->height)/2, 0);
-+ xcb_image_destroy (img);
-+ x += block->icon->width + 5;
-+ }
-+
- color_t fg_color;
- if (block->urgent) {
- fg_color = colors.urgent_ws_fg;
-@@ -508,6 +546,10 @@ void handle_button(xcb_button_press_event_t *event) {
- last_block_x = block_x;
- block_x += render->width + render->x_offset + render->x_append + get_sep_offset(block) + sep_offset_remainder;
-
-+ /* Add icon width */
-+ if (block->icon)
-+ block_x += block->icon->width + 5;
-+
- if (statusline_x <= block_x && statusline_x >= last_block_x) {
- send_block_clicked(event->detail, block->name, block->instance, event->root_x, event->root_y);
- return;
---
-2.7.4
-
diff --git a/x11-wm/i3-4.6/i3bar-4.6-icons.patch b/x11-wm/i3-4.6/i3bar-4.6-icons.patch
deleted file mode 100644
index dda62d9..0000000
--- a/x11-wm/i3-4.6/i3bar-4.6-icons.patch
+++ /dev/null
@@ -1,440 +0,0 @@
-diff --git a/common.mk b/common.mk
-index de5c7e9..eff3468 100644
---- a/common.mk
-+++ b/common.mk
-@@ -83,6 +83,7 @@ XCB_CFLAGS := $(call cflags_for_lib, xcb)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-event)
- XCB_LIBS := $(call ldflags_for_lib, xcb,xcb)
- XCB_LIBS += $(call ldflags_for_lib, xcb-event,xcb-event)
-+XCB_LIBS += $(call ldflags_for_lib, xcb-image,xcb-image)
- ifeq ($(shell pkg-config --exists xcb-util 2>/dev/null || echo 1),1)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-atom)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-aux)
-diff --git a/i3bar/include/common.h b/i3bar/include/common.h
-index cb55e0d..a243fd0 100644
---- a/i3bar/include/common.h
-+++ b/i3bar/include/common.h
-@@ -11,6 +11,7 @@
- #include <stdbool.h>
- #include <xcb/xcb.h>
- #include <xcb/xproto.h>
-+#include <xcb/xcb_image.h>
- #include "libi3.h"
- #include "queue.h"
-
-@@ -39,6 +40,7 @@ struct status_block {
- i3String *full_text;
-
- char *color;
-+ char *icon;
- uint32_t min_width;
- blockalign_t align;
-
-@@ -57,6 +59,7 @@ struct status_block {
- /* Optional */
- char *name;
- char *instance;
-+ xcb_image_t *icon_image;
-
- TAILQ_ENTRY(status_block) blocks;
- };
-@@ -70,6 +73,7 @@ TAILQ_HEAD(statusline_head, status_block) statusline_head;
- #include "workspaces.h"
- #include "mode.h"
- #include "trayclients.h"
-+#include "xbm.h"
- #include "xcb.h"
- #include "config.h"
- #include "libi3.h"
-diff --git a/i3bar/include/xbm.h b/i3bar/include/xbm.h
-new file mode 100644
-index 0000000..f3cc3d5
---- /dev/null
-+++ b/i3bar/include/xbm.h
-@@ -0,0 +1,47 @@
-+/*
-+ * vim:ts=4:sw=4:expandtab
-+ *
-+ * i3bar - an xcb-based status- and ws-bar for i3
-+ * © 2010-2011 Axel Wagner and contributors (see also: LICENSE)
-+ *
-+ * xbm.c: Parsing/Loading xbm data
-+ *
-+ */
-+#ifndef XBM_H_
-+#define XBM_H_
-+
-+#include "queue.h"
-+
-+#define BUFSZ 512
-+
-+struct raw_xbm {
-+ uint32_t w,h;
-+ uint32_t dlen;
-+ uint8_t *data;
-+};
-+
-+struct Cached_Xbm {
-+ char *path;
-+ xcb_image_t *icon;
-+ int used;
-+ SLIST_ENTRY(Cached_Xbm) xbm_cache;
-+};
-+
-+/* Set the format information for loaded icons */
-+void set_format(xcb_connection_t * c, uint8_t depth, uint8_t bpp);
-+
-+/* Set xcb context color for icon, needed with pango patch */
-+void set_icon_color(xcb_connection_t *c, xcb_gcontext_t gc,
-+ uint32_t foreground, uint32_t background);
-+
-+/* get the xcb image for the given icon path */
-+xcb_image_t* get_icon(char* path);
-+
-+/* cache functions */
-+void xbm_clear_cache_used();
-+xcb_image_t* xbm_get_cached_icon(char* path);
-+void xbm_cache_icon(char* path, xcb_image_t* icon);
-+void xbm_free_unused_icons();
-+
-+
-+#endif
-diff --git a/i3bar/src/child.c b/i3bar/src/child.c
-index 4e5e49c..121e6e8 100644
---- a/i3bar/src/child.c
-+++ b/i3bar/src/child.c
-@@ -93,6 +93,7 @@ static int stdin_start_array(void *context) {
- FREE(first->color);
- FREE(first->name);
- FREE(first->instance);
-+ FREE(first->icon);
- TAILQ_REMOVE(&statusline_head, first, blocks);
- free(first);
- }
-@@ -147,6 +148,9 @@ static int stdin_string(void *context, const unsigned char *val, unsigned int le
- if (strcasecmp(ctx->last_map_key, "color") == 0) {
- sasprintf(&(ctx->block.color), "%.*s", len, val);
- }
-+ if (strcasecmp(ctx->last_map_key, "icon") == 0) {
-+ sasprintf(&(ctx->block.icon), "%.*s", len, val);
-+ }
- if (strcasecmp(ctx->last_map_key, "align") == 0) {
- if (len == strlen("left") && !strncmp((const char*)val, "left", strlen("left"))) {
- ctx->block.align = ALIGN_LEFT;
-@@ -210,6 +214,7 @@ static int stdin_end_array(void *context) {
- TAILQ_FOREACH(current, &statusline_head, blocks) {
- DLOG("full_text = %s\n", i3string_as_utf8(current->full_text));
- DLOG("color = %s\n", current->color);
-+ DLOG("icon = %s\n",current->icon);
- }
- DLOG("end of dump\n");
- return 1;
-diff --git a/i3bar/src/xbm.c b/i3bar/src/xbm.c
-new file mode 100644
-index 0000000..af7d18c
---- /dev/null
-+++ b/i3bar/src/xbm.c
-@@ -0,0 +1,239 @@
-+/*
-+ * vim:ts=4:sw=4:expandtab
-+ *
-+ * i3bar - an xcb-based status- and ws-bar for i3
-+ * © 2010-2011 Axel Wagner and contributors (see also: LICENSE)
-+ *
-+ * xbm.c: Parsing/Loading xbm data
-+ *
-+ * set_format from:
-+ * http://vincentsanders.blogspot.de/2010/04/xcb-programming-is-hard.html
-+ */
-+
-+#include <string.h>
-+
-+#include <xcb/xcb.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <sys/types.h>
-+#include <unistd.h>
-+#include <errno.h>
-+#include <string.h>
-+
-+#include "common.h"
-+
-+static xcb_format_t* format = NULL;
-+
-+void set_format(xcb_connection_t * c, uint8_t depth, uint8_t bpp) {
-+ const xcb_setup_t *setup = xcb_get_setup(c);
-+ xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
-+ xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
-+ for(; fmt != fmtend; ++fmt)
-+ if((fmt->depth == depth) && (fmt->bits_per_pixel == bpp))
-+ format = fmt;
-+}
-+
-+/* With pango we need to set colors ourselves, since the pango
-+ * patch only sets font color */
-+void set_icon_color(xcb_connection_t *c, xcb_gcontext_t gc,
-+ uint32_t foreground, uint32_t background) {
-+ uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
-+ uint32_t values[] = {foreground, background };
-+ xcb_change_gc(c, gc, mask, values);
-+}
-+
-+static int
-+parse_xbm(char* file, struct raw_xbm* data) {
-+ FILE *f;
-+ char *str;
-+ int i,p,r,lim;
-+ char *c;
-+ uint8_t *d;
-+
-+ int in_array = 0;
-+
-+ data->w = data->h = -1;
-+
-+ f = fopen(file,"r");
-+ if (!f) {
-+ ELOG("Could not open xbm file: %s",file);
-+ return 1;
-+ }
-+
-+ str=malloc(BUFSZ);
-+ if (!str) {
-+ ELOG("Could not malloc buffer for xbm parsing");
-+ fclose(f);
-+ return 1;
-+ }
-+
-+ while (fscanf(f," #define %s %d",str,&i) == 2) {
-+ if (strstr(str,"width") != NULL)
-+ data->w = i;
-+ else if (strstr(str,"height") != NULL)
-+ data->h = i;
-+ }
-+
-+ if (data->w <= 0 || data->h <= 0) {
-+ ELOG("Could not find height and/or width in xbm: %s\n",file);
-+ fclose(f);
-+ free(str);
-+ return 1;
-+ }
-+
-+ d = malloc(data->w*data->h);
-+ p = 0;
-+
-+ r = fread(str,1,BUFSZ,f);
-+ lim = r;
-+ while(r>0) {
-+ if(in_array) {
-+ while(c < (str+lim)) {
-+ char* t = c;
-+ while (*t && t!=(str+lim-1) && *t!=',' && *t!='}') t++;
-+ if (*t && (*t==',' || *t=='}'))
-+ d[p++] = strtol(c,NULL,16);
-+ else
-+ break;
-+ c=t+1;
-+ }
-+ } else {
-+ c = str;
-+ while (*c && c!=(str+lim) && *c!='{')
-+ c++;
-+ if (*c && c!=(str+lim) && *c=='{') {
-+ in_array=1;
-+ c++;
-+ if (c<(str+lim)) continue;
-+ }
-+ }
-+
-+ i = (str+lim)-c;
-+ if (i > 0) memcpy(str,c,i);
-+
-+ r = fread(str+i,1,BUFSZ-i,f);
-+ c=str;
-+ lim = r+i;
-+ }
-+
-+ fclose(f);
-+ free(str);
-+
-+ /* will free if p==0, so we only have malloced mem
-+ * when p!=0 */
-+ d = realloc(d,p);
-+
-+ data->dlen = p;
-+ data->data = d;
-+ return p==0;
-+}
-+
-+static xcb_image_t *
-+create_icon_image(struct raw_xbm *xbm) {
-+ int i,rowsize,done,di;
-+ unsigned char *imgdata;
-+ if (format == NULL) return NULL;
-+
-+ imgdata = (unsigned char *)malloc(xbm->w*xbm->h);
-+ memset(imgdata,0,sizeof(imgdata));
-+
-+ rowsize = format->scanline_pad;
-+ while(rowsize < xbm->w) rowsize+=format->scanline_pad;
-+
-+ for(done=0,di=0,i=0;i<xbm->dlen;i++) {
-+ imgdata[di] = xbm->data[i];
-+ di++;
-+ done+=8;
-+ if (done >= xbm->w) {
-+ // pad out to rowsize
-+ while (done < rowsize) {
-+ di++;
-+ done+=8;
-+ }
-+ done=0;
-+ }
-+ }
-+
-+ return xcb_image_create(xbm->w,
-+ xbm->h,
-+ XCB_IMAGE_FORMAT_XY_BITMAP,
-+ format->scanline_pad,
-+ format->depth,
-+ format->bits_per_pixel,
-+ 0,
-+ XCB_IMAGE_ORDER_LSB_FIRST,
-+ XCB_IMAGE_ORDER_LSB_FIRST,
-+ imgdata,
-+ xbm->w*xbm->h,
-+ imgdata);
-+}
-+
-+xcb_image_t* get_icon(char* path) {
-+ xcb_image_t* ret;
-+ struct raw_xbm rxbm;
-+
-+ ret = xbm_get_cached_icon(path);
-+ if (ret) return ret;
-+
-+ DLOG("Loading xbm: %s\n",path);
-+
-+ rxbm.data = NULL;
-+ if (parse_xbm(path,&rxbm)) {
-+ ELOG("Cannot parse xbm: %s\n",path);
-+ return NULL;
-+ }
-+ ret = create_icon_image(&rxbm);
-+ xbm_cache_icon(path,ret);
-+ free(rxbm.data);
-+ return ret;
-+}
-+
-+/* Below we implement a cache for parsed xbm icons.
-+ *
-+ * If an icon is used in a draw of the bar, it sticks around until the
-+ * next draw, otherwise we throw it away at the end of a update. The
-+ * idea being that most icons are fairly static, or change rarely
-+ * (like when a battery threshold is reached). Therefore, we are very
-+ * aggresive about throwing things out of the cache.
-+ */
-+
-+static SLIST_HEAD(xbm_cache_head, Cached_Xbm) xbm_cache;
-+
-+void xbm_clear_cache_used() {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ cxbm->used = 0;
-+ }
-+}
-+
-+xcb_image_t* xbm_get_cached_icon(char* path) {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ if (!strcmp(path,cxbm->path)) {
-+ cxbm->used = 1;
-+ return cxbm->icon;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+void xbm_cache_icon(char* path, xcb_image_t* icon) {
-+ struct Cached_Xbm *cxbm = smalloc(sizeof(struct Cached_Xbm));
-+ cxbm->used = 1;
-+ cxbm->path = strdup(path);
-+ cxbm->icon = icon;
-+ SLIST_INSERT_HEAD(&xbm_cache,cxbm,xbm_cache);
-+}
-+
-+void xbm_free_unused_icons() {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ if (!cxbm->used) {
-+ SLIST_REMOVE(&xbm_cache, cxbm, Cached_Xbm, xbm_cache);
-+ free(cxbm->path);
-+ xcb_image_destroy(cxbm->icon);
-+ free(cxbm);
-+ }
-+ }
-+}
-+
-diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c
-index 15c68a0..f59aefe 100644
---- a/i3bar/src/xcb.c
-+++ b/i3bar/src/xcb.c
-@@ -131,6 +131,14 @@ void refresh_statusline(void) {
-
- block->width = predict_text_width(block->full_text);
-
-+ if (block->icon) {
-+ block->icon_image = get_icon(block->icon);
-+ if (!block->icon_image)
-+ ELOG("Could not load icon: %s\n",block->icon);
-+ else
-+ statusline_width += block->icon_image->width+1;
-+ }
-+
- /* Compute offset and append for text aligment in min_width. */
- if (block->min_width <= block->width) {
- block->x_offset = 0;
-@@ -176,6 +184,18 @@ void refresh_statusline(void) {
-
- uint32_t colorpixel = (block->color ? get_colorpixel(block->color) : colors.bar_fg);
- set_font_colors(statusline_ctx, colorpixel, colors.bar_bg);
-+
-+ if (block->icon_image) {
-+ int h = (font.height-block->icon_image->height)/2;
-+ set_icon_color(xcb_connection,statusline_ctx,
-+ colorpixel,colors.bar_bg);
-+ xcb_image_put(xcb_connection,statusline_pm,statusline_ctx,
-+ block->icon_image,x,h,0);
-+ set_icon_color(xcb_connection,statusline_ctx,
-+ get_colorpixel("#666666"),colors.bar_bg);
-+ x+=block->icon_image->width+1;
-+ }
-+
- draw_text(block->full_text, statusline_pm, statusline_ctx, x + block->x_offset, 1, block->width);
- x += block->width + block->x_offset + block->x_append;
-
-@@ -977,6 +997,8 @@ char *init_xcb_early() {
- }
- }
-
-+ /* Set the format for icons */
-+ set_format(xcb_connection,1,1);
-
- if (xcb_request_failed(sl_pm_cookie, "Could not allocate statusline-buffer") ||
- xcb_request_failed(clear_ctx_cookie, "Could not allocate statusline-buffer-clearcontext") ||
-@@ -1610,6 +1632,7 @@ void draw_bars(bool unhide) {
- DLOG("Drawing Bars...\n");
- int i = 0;
-
-+ xbm_clear_cache_used();
- refresh_statusline();
-
- static char *last_urgent_ws = NULL;
-@@ -1780,6 +1803,8 @@ void draw_bars(bool unhide) {
- hide_bars();
- }
-
-+ xbm_free_unused_icons();
-+
- redraw_bars();
- }
-
diff --git a/x11-wm/i3-4.7.2 b/x11-wm/i3-4.7.2
deleted file mode 120000
index 46c2230..0000000
--- a/x11-wm/i3-4.7.2
+++ /dev/null
@@ -1 +0,0 @@
-i3-4.7 \ No newline at end of file
diff --git a/x11-wm/i3-4.7/i3bar-4.6-icons.patch b/x11-wm/i3-4.7/i3bar-4.6-icons.patch
deleted file mode 100644
index dda62d9..0000000
--- a/x11-wm/i3-4.7/i3bar-4.6-icons.patch
+++ /dev/null
@@ -1,440 +0,0 @@
-diff --git a/common.mk b/common.mk
-index de5c7e9..eff3468 100644
---- a/common.mk
-+++ b/common.mk
-@@ -83,6 +83,7 @@ XCB_CFLAGS := $(call cflags_for_lib, xcb)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-event)
- XCB_LIBS := $(call ldflags_for_lib, xcb,xcb)
- XCB_LIBS += $(call ldflags_for_lib, xcb-event,xcb-event)
-+XCB_LIBS += $(call ldflags_for_lib, xcb-image,xcb-image)
- ifeq ($(shell pkg-config --exists xcb-util 2>/dev/null || echo 1),1)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-atom)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-aux)
-diff --git a/i3bar/include/common.h b/i3bar/include/common.h
-index cb55e0d..a243fd0 100644
---- a/i3bar/include/common.h
-+++ b/i3bar/include/common.h
-@@ -11,6 +11,7 @@
- #include <stdbool.h>
- #include <xcb/xcb.h>
- #include <xcb/xproto.h>
-+#include <xcb/xcb_image.h>
- #include "libi3.h"
- #include "queue.h"
-
-@@ -39,6 +40,7 @@ struct status_block {
- i3String *full_text;
-
- char *color;
-+ char *icon;
- uint32_t min_width;
- blockalign_t align;
-
-@@ -57,6 +59,7 @@ struct status_block {
- /* Optional */
- char *name;
- char *instance;
-+ xcb_image_t *icon_image;
-
- TAILQ_ENTRY(status_block) blocks;
- };
-@@ -70,6 +73,7 @@ TAILQ_HEAD(statusline_head, status_block) statusline_head;
- #include "workspaces.h"
- #include "mode.h"
- #include "trayclients.h"
-+#include "xbm.h"
- #include "xcb.h"
- #include "config.h"
- #include "libi3.h"
-diff --git a/i3bar/include/xbm.h b/i3bar/include/xbm.h
-new file mode 100644
-index 0000000..f3cc3d5
---- /dev/null
-+++ b/i3bar/include/xbm.h
-@@ -0,0 +1,47 @@
-+/*
-+ * vim:ts=4:sw=4:expandtab
-+ *
-+ * i3bar - an xcb-based status- and ws-bar for i3
-+ * © 2010-2011 Axel Wagner and contributors (see also: LICENSE)
-+ *
-+ * xbm.c: Parsing/Loading xbm data
-+ *
-+ */
-+#ifndef XBM_H_
-+#define XBM_H_
-+
-+#include "queue.h"
-+
-+#define BUFSZ 512
-+
-+struct raw_xbm {
-+ uint32_t w,h;
-+ uint32_t dlen;
-+ uint8_t *data;
-+};
-+
-+struct Cached_Xbm {
-+ char *path;
-+ xcb_image_t *icon;
-+ int used;
-+ SLIST_ENTRY(Cached_Xbm) xbm_cache;
-+};
-+
-+/* Set the format information for loaded icons */
-+void set_format(xcb_connection_t * c, uint8_t depth, uint8_t bpp);
-+
-+/* Set xcb context color for icon, needed with pango patch */
-+void set_icon_color(xcb_connection_t *c, xcb_gcontext_t gc,
-+ uint32_t foreground, uint32_t background);
-+
-+/* get the xcb image for the given icon path */
-+xcb_image_t* get_icon(char* path);
-+
-+/* cache functions */
-+void xbm_clear_cache_used();
-+xcb_image_t* xbm_get_cached_icon(char* path);
-+void xbm_cache_icon(char* path, xcb_image_t* icon);
-+void xbm_free_unused_icons();
-+
-+
-+#endif
-diff --git a/i3bar/src/child.c b/i3bar/src/child.c
-index 4e5e49c..121e6e8 100644
---- a/i3bar/src/child.c
-+++ b/i3bar/src/child.c
-@@ -93,6 +93,7 @@ static int stdin_start_array(void *context) {
- FREE(first->color);
- FREE(first->name);
- FREE(first->instance);
-+ FREE(first->icon);
- TAILQ_REMOVE(&statusline_head, first, blocks);
- free(first);
- }
-@@ -147,6 +148,9 @@ static int stdin_string(void *context, const unsigned char *val, unsigned int le
- if (strcasecmp(ctx->last_map_key, "color") == 0) {
- sasprintf(&(ctx->block.color), "%.*s", len, val);
- }
-+ if (strcasecmp(ctx->last_map_key, "icon") == 0) {
-+ sasprintf(&(ctx->block.icon), "%.*s", len, val);
-+ }
- if (strcasecmp(ctx->last_map_key, "align") == 0) {
- if (len == strlen("left") && !strncmp((const char*)val, "left", strlen("left"))) {
- ctx->block.align = ALIGN_LEFT;
-@@ -210,6 +214,7 @@ static int stdin_end_array(void *context) {
- TAILQ_FOREACH(current, &statusline_head, blocks) {
- DLOG("full_text = %s\n", i3string_as_utf8(current->full_text));
- DLOG("color = %s\n", current->color);
-+ DLOG("icon = %s\n",current->icon);
- }
- DLOG("end of dump\n");
- return 1;
-diff --git a/i3bar/src/xbm.c b/i3bar/src/xbm.c
-new file mode 100644
-index 0000000..af7d18c
---- /dev/null
-+++ b/i3bar/src/xbm.c
-@@ -0,0 +1,239 @@
-+/*
-+ * vim:ts=4:sw=4:expandtab
-+ *
-+ * i3bar - an xcb-based status- and ws-bar for i3
-+ * © 2010-2011 Axel Wagner and contributors (see also: LICENSE)
-+ *
-+ * xbm.c: Parsing/Loading xbm data
-+ *
-+ * set_format from:
-+ * http://vincentsanders.blogspot.de/2010/04/xcb-programming-is-hard.html
-+ */
-+
-+#include <string.h>
-+
-+#include <xcb/xcb.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <sys/types.h>
-+#include <unistd.h>
-+#include <errno.h>
-+#include <string.h>
-+
-+#include "common.h"
-+
-+static xcb_format_t* format = NULL;
-+
-+void set_format(xcb_connection_t * c, uint8_t depth, uint8_t bpp) {
-+ const xcb_setup_t *setup = xcb_get_setup(c);
-+ xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
-+ xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
-+ for(; fmt != fmtend; ++fmt)
-+ if((fmt->depth == depth) && (fmt->bits_per_pixel == bpp))
-+ format = fmt;
-+}
-+
-+/* With pango we need to set colors ourselves, since the pango
-+ * patch only sets font color */
-+void set_icon_color(xcb_connection_t *c, xcb_gcontext_t gc,
-+ uint32_t foreground, uint32_t background) {
-+ uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
-+ uint32_t values[] = {foreground, background };
-+ xcb_change_gc(c, gc, mask, values);
-+}
-+
-+static int
-+parse_xbm(char* file, struct raw_xbm* data) {
-+ FILE *f;
-+ char *str;
-+ int i,p,r,lim;
-+ char *c;
-+ uint8_t *d;
-+
-+ int in_array = 0;
-+
-+ data->w = data->h = -1;
-+
-+ f = fopen(file,"r");
-+ if (!f) {
-+ ELOG("Could not open xbm file: %s",file);
-+ return 1;
-+ }
-+
-+ str=malloc(BUFSZ);
-+ if (!str) {
-+ ELOG("Could not malloc buffer for xbm parsing");
-+ fclose(f);
-+ return 1;
-+ }
-+
-+ while (fscanf(f," #define %s %d",str,&i) == 2) {
-+ if (strstr(str,"width") != NULL)
-+ data->w = i;
-+ else if (strstr(str,"height") != NULL)
-+ data->h = i;
-+ }
-+
-+ if (data->w <= 0 || data->h <= 0) {
-+ ELOG("Could not find height and/or width in xbm: %s\n",file);
-+ fclose(f);
-+ free(str);
-+ return 1;
-+ }
-+
-+ d = malloc(data->w*data->h);
-+ p = 0;
-+
-+ r = fread(str,1,BUFSZ,f);
-+ lim = r;
-+ while(r>0) {
-+ if(in_array) {
-+ while(c < (str+lim)) {
-+ char* t = c;
-+ while (*t && t!=(str+lim-1) && *t!=',' && *t!='}') t++;
-+ if (*t && (*t==',' || *t=='}'))
-+ d[p++] = strtol(c,NULL,16);
-+ else
-+ break;
-+ c=t+1;
-+ }
-+ } else {
-+ c = str;
-+ while (*c && c!=(str+lim) && *c!='{')
-+ c++;
-+ if (*c && c!=(str+lim) && *c=='{') {
-+ in_array=1;
-+ c++;
-+ if (c<(str+lim)) continue;
-+ }
-+ }
-+
-+ i = (str+lim)-c;
-+ if (i > 0) memcpy(str,c,i);
-+
-+ r = fread(str+i,1,BUFSZ-i,f);
-+ c=str;
-+ lim = r+i;
-+ }
-+
-+ fclose(f);
-+ free(str);
-+
-+ /* will free if p==0, so we only have malloced mem
-+ * when p!=0 */
-+ d = realloc(d,p);
-+
-+ data->dlen = p;
-+ data->data = d;
-+ return p==0;
-+}
-+
-+static xcb_image_t *
-+create_icon_image(struct raw_xbm *xbm) {
-+ int i,rowsize,done,di;
-+ unsigned char *imgdata;
-+ if (format == NULL) return NULL;
-+
-+ imgdata = (unsigned char *)malloc(xbm->w*xbm->h);
-+ memset(imgdata,0,sizeof(imgdata));
-+
-+ rowsize = format->scanline_pad;
-+ while(rowsize < xbm->w) rowsize+=format->scanline_pad;
-+
-+ for(done=0,di=0,i=0;i<xbm->dlen;i++) {
-+ imgdata[di] = xbm->data[i];
-+ di++;
-+ done+=8;
-+ if (done >= xbm->w) {
-+ // pad out to rowsize
-+ while (done < rowsize) {
-+ di++;
-+ done+=8;
-+ }
-+ done=0;
-+ }
-+ }
-+
-+ return xcb_image_create(xbm->w,
-+ xbm->h,
-+ XCB_IMAGE_FORMAT_XY_BITMAP,
-+ format->scanline_pad,
-+ format->depth,
-+ format->bits_per_pixel,
-+ 0,
-+ XCB_IMAGE_ORDER_LSB_FIRST,
-+ XCB_IMAGE_ORDER_LSB_FIRST,
-+ imgdata,
-+ xbm->w*xbm->h,
-+ imgdata);
-+}
-+
-+xcb_image_t* get_icon(char* path) {
-+ xcb_image_t* ret;
-+ struct raw_xbm rxbm;
-+
-+ ret = xbm_get_cached_icon(path);
-+ if (ret) return ret;
-+
-+ DLOG("Loading xbm: %s\n",path);
-+
-+ rxbm.data = NULL;
-+ if (parse_xbm(path,&rxbm)) {
-+ ELOG("Cannot parse xbm: %s\n",path);
-+ return NULL;
-+ }
-+ ret = create_icon_image(&rxbm);
-+ xbm_cache_icon(path,ret);
-+ free(rxbm.data);
-+ return ret;
-+}
-+
-+/* Below we implement a cache for parsed xbm icons.
-+ *
-+ * If an icon is used in a draw of the bar, it sticks around until the
-+ * next draw, otherwise we throw it away at the end of a update. The
-+ * idea being that most icons are fairly static, or change rarely
-+ * (like when a battery threshold is reached). Therefore, we are very
-+ * aggresive about throwing things out of the cache.
-+ */
-+
-+static SLIST_HEAD(xbm_cache_head, Cached_Xbm) xbm_cache;
-+
-+void xbm_clear_cache_used() {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ cxbm->used = 0;
-+ }
-+}
-+
-+xcb_image_t* xbm_get_cached_icon(char* path) {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ if (!strcmp(path,cxbm->path)) {
-+ cxbm->used = 1;
-+ return cxbm->icon;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+void xbm_cache_icon(char* path, xcb_image_t* icon) {
-+ struct Cached_Xbm *cxbm = smalloc(sizeof(struct Cached_Xbm));
-+ cxbm->used = 1;
-+ cxbm->path = strdup(path);
-+ cxbm->icon = icon;
-+ SLIST_INSERT_HEAD(&xbm_cache,cxbm,xbm_cache);
-+}
-+
-+void xbm_free_unused_icons() {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ if (!cxbm->used) {
-+ SLIST_REMOVE(&xbm_cache, cxbm, Cached_Xbm, xbm_cache);
-+ free(cxbm->path);
-+ xcb_image_destroy(cxbm->icon);
-+ free(cxbm);
-+ }
-+ }
-+}
-+
-diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c
-index 15c68a0..f59aefe 100644
---- a/i3bar/src/xcb.c
-+++ b/i3bar/src/xcb.c
-@@ -131,6 +131,14 @@ void refresh_statusline(void) {
-
- block->width = predict_text_width(block->full_text);
-
-+ if (block->icon) {
-+ block->icon_image = get_icon(block->icon);
-+ if (!block->icon_image)
-+ ELOG("Could not load icon: %s\n",block->icon);
-+ else
-+ statusline_width += block->icon_image->width+1;
-+ }
-+
- /* Compute offset and append for text aligment in min_width. */
- if (block->min_width <= block->width) {
- block->x_offset = 0;
-@@ -176,6 +184,18 @@ void refresh_statusline(void) {
-
- uint32_t colorpixel = (block->color ? get_colorpixel(block->color) : colors.bar_fg);
- set_font_colors(statusline_ctx, colorpixel, colors.bar_bg);
-+
-+ if (block->icon_image) {
-+ int h = (font.height-block->icon_image->height)/2;
-+ set_icon_color(xcb_connection,statusline_ctx,
-+ colorpixel,colors.bar_bg);
-+ xcb_image_put(xcb_connection,statusline_pm,statusline_ctx,
-+ block->icon_image,x,h,0);
-+ set_icon_color(xcb_connection,statusline_ctx,
-+ get_colorpixel("#666666"),colors.bar_bg);
-+ x+=block->icon_image->width+1;
-+ }
-+
- draw_text(block->full_text, statusline_pm, statusline_ctx, x + block->x_offset, 1, block->width);
- x += block->width + block->x_offset + block->x_append;
-
-@@ -977,6 +997,8 @@ char *init_xcb_early() {
- }
- }
-
-+ /* Set the format for icons */
-+ set_format(xcb_connection,1,1);
-
- if (xcb_request_failed(sl_pm_cookie, "Could not allocate statusline-buffer") ||
- xcb_request_failed(clear_ctx_cookie, "Could not allocate statusline-buffer-clearcontext") ||
-@@ -1610,6 +1632,7 @@ void draw_bars(bool unhide) {
- DLOG("Drawing Bars...\n");
- int i = 0;
-
-+ xbm_clear_cache_used();
- refresh_statusline();
-
- static char *last_urgent_ws = NULL;
-@@ -1780,6 +1803,8 @@ void draw_bars(bool unhide) {
- hide_bars();
- }
-
-+ xbm_free_unused_icons();
-+
- redraw_bars();
- }
-
diff --git a/x11-wm/i3-4.8/i3bar-icons.patch b/x11-wm/i3-4.8/i3bar-icons.patch
deleted file mode 100644
index ebf1abe..0000000
--- a/x11-wm/i3-4.8/i3bar-icons.patch
+++ /dev/null
@@ -1,441 +0,0 @@
-diff --git a/common.mk b/common.mk
-index b086bc8..a7b263c 100644
---- a/common.mk
-+++ b/common.mk
-@@ -82,6 +82,7 @@ XCB_CFLAGS := $(call cflags_for_lib, xcb)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-event)
- XCB_LIBS := $(call ldflags_for_lib, xcb,xcb)
- XCB_LIBS += $(call ldflags_for_lib, xcb-event,xcb-event)
-+XCB_LIBS += $(call ldflags_for_lib, xcb-image,xcb-image)
- ifeq ($(shell pkg-config --exists xcb-util 2>/dev/null || echo 1),1)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-atom)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-aux)
-diff --git a/i3bar/include/common.h b/i3bar/include/common.h
-index d63780d..b0b0394 100644
---- a/i3bar/include/common.h
-+++ b/i3bar/include/common.h
-@@ -10,6 +10,7 @@
- #include <stdbool.h>
- #include <xcb/xcb.h>
- #include <xcb/xproto.h>
-+#include <xcb/xcb_image.h>
- #include "libi3.h"
- #include "queue.h"
-
-@@ -38,6 +39,7 @@ struct status_block {
- i3String *full_text;
-
- char *color;
-+ char *icon;
- uint32_t min_width;
- blockalign_t align;
-
-@@ -56,6 +58,7 @@ struct status_block {
- /* Optional */
- char *name;
- char *instance;
-+ xcb_image_t *icon_image;
-
- TAILQ_ENTRY(status_block) blocks;
- };
-@@ -69,6 +72,7 @@ TAILQ_HEAD(statusline_head, status_block) statusline_head;
- #include "workspaces.h"
- #include "mode.h"
- #include "trayclients.h"
-+#include "xbm.h"
- #include "xcb.h"
- #include "config.h"
- #include "libi3.h"
-diff --git a/i3bar/include/xbm.h b/i3bar/include/xbm.h
-new file mode 100644
-index 0000000..f3cc3d5
---- /dev/null
-+++ b/i3bar/include/xbm.h
-@@ -0,0 +1,47 @@
-+/*
-+ * vim:ts=4:sw=4:expandtab
-+ *
-+ * i3bar - an xcb-based status- and ws-bar for i3
-+ * © 2010-2011 Axel Wagner and contributors (see also: LICENSE)
-+ *
-+ * xbm.c: Parsing/Loading xbm data
-+ *
-+ */
-+#ifndef XBM_H_
-+#define XBM_H_
-+
-+#include "queue.h"
-+
-+#define BUFSZ 512
-+
-+struct raw_xbm {
-+ uint32_t w,h;
-+ uint32_t dlen;
-+ uint8_t *data;
-+};
-+
-+struct Cached_Xbm {
-+ char *path;
-+ xcb_image_t *icon;
-+ int used;
-+ SLIST_ENTRY(Cached_Xbm) xbm_cache;
-+};
-+
-+/* Set the format information for loaded icons */
-+void set_format(xcb_connection_t * c, uint8_t depth, uint8_t bpp);
-+
-+/* Set xcb context color for icon, needed with pango patch */
-+void set_icon_color(xcb_connection_t *c, xcb_gcontext_t gc,
-+ uint32_t foreground, uint32_t background);
-+
-+/* get the xcb image for the given icon path */
-+xcb_image_t* get_icon(char* path);
-+
-+/* cache functions */
-+void xbm_clear_cache_used();
-+xcb_image_t* xbm_get_cached_icon(char* path);
-+void xbm_cache_icon(char* path, xcb_image_t* icon);
-+void xbm_free_unused_icons();
-+
-+
-+#endif
-diff --git a/i3bar/src/xbm.c b/i3bar/src/xbm.c
-new file mode 100644
-index 0000000..af7d18c
---- /dev/null
-+++ b/i3bar/src/xbm.c
-@@ -0,0 +1,239 @@
-+/*
-+ * vim:ts=4:sw=4:expandtab
-+ *
-+ * i3bar - an xcb-based status- and ws-bar for i3
-+ * © 2010-2011 Axel Wagner and contributors (see also: LICENSE)
-+ *
-+ * xbm.c: Parsing/Loading xbm data
-+ *
-+ * set_format from:
-+ * http://vincentsanders.blogspot.de/2010/04/xcb-programming-is-hard.html
-+ */
-+
-+#include <string.h>
-+
-+#include <xcb/xcb.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <sys/types.h>
-+#include <unistd.h>
-+#include <errno.h>
-+#include <string.h>
-+
-+#include "common.h"
-+
-+static xcb_format_t* format = NULL;
-+
-+void set_format(xcb_connection_t * c, uint8_t depth, uint8_t bpp) {
-+ const xcb_setup_t *setup = xcb_get_setup(c);
-+ xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
-+ xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
-+ for(; fmt != fmtend; ++fmt)
-+ if((fmt->depth == depth) && (fmt->bits_per_pixel == bpp))
-+ format = fmt;
-+}
-+
-+/* With pango we need to set colors ourselves, since the pango
-+ * patch only sets font color */
-+void set_icon_color(xcb_connection_t *c, xcb_gcontext_t gc,
-+ uint32_t foreground, uint32_t background) {
-+ uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
-+ uint32_t values[] = {foreground, background };
-+ xcb_change_gc(c, gc, mask, values);
-+}
-+
-+static int
-+parse_xbm(char* file, struct raw_xbm* data) {
-+ FILE *f;
-+ char *str;
-+ int i,p,r,lim;
-+ char *c;
-+ uint8_t *d;
-+
-+ int in_array = 0;
-+
-+ data->w = data->h = -1;
-+
-+ f = fopen(file,"r");
-+ if (!f) {
-+ ELOG("Could not open xbm file: %s",file);
-+ return 1;
-+ }
-+
-+ str=malloc(BUFSZ);
-+ if (!str) {
-+ ELOG("Could not malloc buffer for xbm parsing");
-+ fclose(f);
-+ return 1;
-+ }
-+
-+ while (fscanf(f," #define %s %d",str,&i) == 2) {
-+ if (strstr(str,"width") != NULL)
-+ data->w = i;
-+ else if (strstr(str,"height") != NULL)
-+ data->h = i;
-+ }
-+
-+ if (data->w <= 0 || data->h <= 0) {
-+ ELOG("Could not find height and/or width in xbm: %s\n",file);
-+ fclose(f);
-+ free(str);
-+ return 1;
-+ }
-+
-+ d = malloc(data->w*data->h);
-+ p = 0;
-+
-+ r = fread(str,1,BUFSZ,f);
-+ lim = r;
-+ while(r>0) {
-+ if(in_array) {
-+ while(c < (str+lim)) {
-+ char* t = c;
-+ while (*t && t!=(str+lim-1) && *t!=',' && *t!='}') t++;
-+ if (*t && (*t==',' || *t=='}'))
-+ d[p++] = strtol(c,NULL,16);
-+ else
-+ break;
-+ c=t+1;
-+ }
-+ } else {
-+ c = str;
-+ while (*c && c!=(str+lim) && *c!='{')
-+ c++;
-+ if (*c && c!=(str+lim) && *c=='{') {
-+ in_array=1;
-+ c++;
-+ if (c<(str+lim)) continue;
-+ }
-+ }
-+
-+ i = (str+lim)-c;
-+ if (i > 0) memcpy(str,c,i);
-+
-+ r = fread(str+i,1,BUFSZ-i,f);
-+ c=str;
-+ lim = r+i;
-+ }
-+
-+ fclose(f);
-+ free(str);
-+
-+ /* will free if p==0, so we only have malloced mem
-+ * when p!=0 */
-+ d = realloc(d,p);
-+
-+ data->dlen = p;
-+ data->data = d;
-+ return p==0;
-+}
-+
-+static xcb_image_t *
-+create_icon_image(struct raw_xbm *xbm) {
-+ int i,rowsize,done,di;
-+ unsigned char *imgdata;
-+ if (format == NULL) return NULL;
-+
-+ imgdata = (unsigned char *)malloc(xbm->w*xbm->h);
-+ memset(imgdata,0,sizeof(imgdata));
-+
-+ rowsize = format->scanline_pad;
-+ while(rowsize < xbm->w) rowsize+=format->scanline_pad;
-+
-+ for(done=0,di=0,i=0;i<xbm->dlen;i++) {
-+ imgdata[di] = xbm->data[i];
-+ di++;
-+ done+=8;
-+ if (done >= xbm->w) {
-+ // pad out to rowsize
-+ while (done < rowsize) {
-+ di++;
-+ done+=8;
-+ }
-+ done=0;
-+ }
-+ }
-+
-+ return xcb_image_create(xbm->w,
-+ xbm->h,
-+ XCB_IMAGE_FORMAT_XY_BITMAP,
-+ format->scanline_pad,
-+ format->depth,
-+ format->bits_per_pixel,
-+ 0,
-+ XCB_IMAGE_ORDER_LSB_FIRST,
-+ XCB_IMAGE_ORDER_LSB_FIRST,
-+ imgdata,
-+ xbm->w*xbm->h,
-+ imgdata);
-+}
-+
-+xcb_image_t* get_icon(char* path) {
-+ xcb_image_t* ret;
-+ struct raw_xbm rxbm;
-+
-+ ret = xbm_get_cached_icon(path);
-+ if (ret) return ret;
-+
-+ DLOG("Loading xbm: %s\n",path);
-+
-+ rxbm.data = NULL;
-+ if (parse_xbm(path,&rxbm)) {
-+ ELOG("Cannot parse xbm: %s\n",path);
-+ return NULL;
-+ }
-+ ret = create_icon_image(&rxbm);
-+ xbm_cache_icon(path,ret);
-+ free(rxbm.data);
-+ return ret;
-+}
-+
-+/* Below we implement a cache for parsed xbm icons.
-+ *
-+ * If an icon is used in a draw of the bar, it sticks around until the
-+ * next draw, otherwise we throw it away at the end of a update. The
-+ * idea being that most icons are fairly static, or change rarely
-+ * (like when a battery threshold is reached). Therefore, we are very
-+ * aggresive about throwing things out of the cache.
-+ */
-+
-+static SLIST_HEAD(xbm_cache_head, Cached_Xbm) xbm_cache;
-+
-+void xbm_clear_cache_used() {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ cxbm->used = 0;
-+ }
-+}
-+
-+xcb_image_t* xbm_get_cached_icon(char* path) {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ if (!strcmp(path,cxbm->path)) {
-+ cxbm->used = 1;
-+ return cxbm->icon;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+void xbm_cache_icon(char* path, xcb_image_t* icon) {
-+ struct Cached_Xbm *cxbm = smalloc(sizeof(struct Cached_Xbm));
-+ cxbm->used = 1;
-+ cxbm->path = strdup(path);
-+ cxbm->icon = icon;
-+ SLIST_INSERT_HEAD(&xbm_cache,cxbm,xbm_cache);
-+}
-+
-+void xbm_free_unused_icons() {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ if (!cxbm->used) {
-+ SLIST_REMOVE(&xbm_cache, cxbm, Cached_Xbm, xbm_cache);
-+ free(cxbm->path);
-+ xcb_image_destroy(cxbm->icon);
-+ free(cxbm);
-+ }
-+ }
-+}
-+
-diff --git a/i3bar/src/child.c b/i3bar/src/child.c
-index 5867ce4..0e618bf 100644
---- a/i3bar/src/child.c
-+++ b/i3bar/src/child.c
-@@ -141,6 +141,7 @@ static int stdin_start_array(void *context) {
- FREE(first->color);
- FREE(first->name);
- FREE(first->instance);
-+ FREE(first->icon);
- TAILQ_REMOVE(&statusline_head, first, blocks);
- free(first);
- }
-@@ -187,6 +188,9 @@ static int stdin_string(void *context, const unsigned char *val, size_t len) {
- if (strcasecmp(ctx->last_map_key, "color") == 0) {
- sasprintf(&(ctx->block.color), "%.*s", len, val);
- }
-+ if (strcasecmp(ctx->last_map_key, "icon") == 0) {
-+ sasprintf(&(ctx->block.icon), "%.*s", len, val);
-+ }
- if (strcasecmp(ctx->last_map_key, "align") == 0) {
- if (len == strlen("left") && !strncmp((const char *)val, "left", strlen("left"))) {
- ctx->block.align = ALIGN_LEFT;
-@@ -246,6 +250,7 @@ static int stdin_end_array(void *context) {
- TAILQ_FOREACH (current, &statusline_head, blocks) {
- DLOG("full_text = %s\n", i3string_as_utf8(current->full_text));
- DLOG("color = %s\n", current->color);
-+ DLOG("icon = %s\n",current->icon);
- }
- DLOG("end of dump\n");
- return 1;
-diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c
-index a29f909..28f2b23 100644
---- a/i3bar/src/xcb.c
-+++ b/i3bar/src/xcb.c
-@@ -134,6 +134,14 @@ void refresh_statusline(void) {
-
- block->width = predict_text_width(block->full_text);
-
-+ if (block->icon) {
-+ block->icon_image = get_icon(block->icon);
-+ if (!block->icon_image)
-+ ELOG("Could not load icon: %s\n",block->icon);
-+ else
-+ statusline_width += block->icon_image->width+1;
-+ }
-+
- /* Compute offset and append for text aligment in min_width. */
- if (block->min_width <= block->width) {
- block->x_offset = 0;
-@@ -179,6 +187,18 @@ void refresh_statusline(void) {
-
- uint32_t colorpixel = (block->color ? get_colorpixel(block->color) : colors.bar_fg);
- set_font_colors(statusline_ctx, colorpixel, colors.bar_bg);
-+
-+ if (block->icon_image) {
-+ int h = (font.height-block->icon_image->height)/2;
-+ set_icon_color(xcb_connection,statusline_ctx,
-+ colorpixel,colors.bar_bg);
-+ xcb_image_put(xcb_connection,statusline_pm,statusline_ctx,
-+ block->icon_image,x,h,0);
-+ set_icon_color(xcb_connection,statusline_ctx,
-+ get_colorpixel("#666666"),colors.bar_bg);
-+ x+=block->icon_image->width+1;
-+ }
-+
- draw_text(block->full_text, statusline_pm, statusline_ctx, x + block->x_offset, 1, block->width);
- x += block->width + block->x_offset + block->x_append;
-
-@@ -1035,6 +1055,9 @@ char *init_xcb_early() {
- /* Now we get the atoms and save them in a nice data structure */
- get_atoms();
-
-+ /* Set the format for icons */
-+ set_format(xcb_connection,1,1);
-+
- char *path = root_atom_contents("I3_SOCKET_PATH", xcb_connection, screen);
-
- if (xcb_request_failed(sl_pm_cookie, "Could not allocate statusline-buffer") ||
-@@ -1682,6 +1705,7 @@ void draw_bars(bool unhide) {
- DLOG("Drawing Bars...\n");
- int i = 0;
-
-+ xbm_clear_cache_used();
- refresh_statusline();
-
- i3_output *outputs_walk;
-@@ -1844,6 +1868,8 @@ void draw_bars(bool unhide) {
- hide_bars();
- }
-
-+ xbm_free_unused_icons();
-+
- redraw_bars();
- }
-
diff --git a/x11-wm/i3-4.8/move.patch b/x11-wm/i3-4.8/move.patch
deleted file mode 100644
index c65bd8a..0000000
--- a/x11-wm/i3-4.8/move.patch
+++ /dev/null
@@ -1,152 +0,0 @@
-From c2b6b06da7db49bd3ecd6fa1561ef2b407ff64a3 Mon Sep 17 00:00:00 2001
-From: Tony Crisci <tony@dubstepdish.com>
-Date: Thu, 19 Jun 2014 12:09:31 +0000
-Subject: Make command `move [direction]` work with criteria
-
-A container selected with criteria should be moved with the `move
-[direction]` command, instead of this command always acting on the
-focused container.
----
-diff --git a/include/move.h b/include/move.h
-index 5c8a7d2..939665e 100644
---- a/include/move.h
-+++ b/include/move.h
-@@ -10,8 +10,8 @@
- #pragma once
-
- /**
-- * Moves the current container in the given direction (TOK_LEFT, TOK_RIGHT,
-+ * Moves the given container in the given direction (TOK_LEFT, TOK_RIGHT,
- * TOK_UP, TOK_DOWN from cmdparse.l)
- *
- */
--void tree_move(int direction);
-+void tree_move(Con *con, int direction);
-diff --git a/src/commands.c b/src/commands.c
-index a60dde6..baf1989 100644
---- a/src/commands.c
-+++ b/src/commands.c
-@@ -1545,26 +1545,36 @@ void cmd_move_direction(I3_CMD, char *direction, char *move_px) {
- // TODO: We could either handle this in the parser itself as a separate token (and make the stack typed) or we need a better way to convert a string to a number with error checking
- int px = atoi(move_px);
-
-- /* TODO: make 'move' work with criteria. */
-- DLOG("moving in direction %s, px %s\n", direction, move_px);
-- if (con_is_floating(focused)) {
-- DLOG("floating move with %d pixels\n", px);
-- Rect newrect = focused->parent->rect;
-- if (strcmp(direction, "left") == 0) {
-- newrect.x -= px;
-- } else if (strcmp(direction, "right") == 0) {
-- newrect.x += px;
-- } else if (strcmp(direction, "up") == 0) {
-- newrect.y -= px;
-- } else if (strcmp(direction, "down") == 0) {
-- newrect.y += px;
-+ owindow *current;
-+ HANDLE_EMPTY_MATCH;
-+
-+ Con *initially_focused = focused;
-+
-+ TAILQ_FOREACH (current, &owindows, owindows) {
-+ DLOG("moving in direction %s, px %s\n", direction, move_px);
-+ if (con_is_floating(current->con)) {
-+ DLOG("floating move with %d pixels\n", px);
-+ Rect newrect = current->con->parent->rect;
-+ if (strcmp(direction, "left") == 0) {
-+ newrect.x -= px;
-+ } else if (strcmp(direction, "right") == 0) {
-+ newrect.x += px;
-+ } else if (strcmp(direction, "up") == 0) {
-+ newrect.y -= px;
-+ } else if (strcmp(direction, "down") == 0) {
-+ newrect.y += px;
-+ }
-+ floating_reposition(current->con->parent, newrect);
-+ } else {
-+ tree_move(current->con, (strcmp(direction, "right") == 0 ? D_RIGHT : (strcmp(direction, "left") == 0 ? D_LEFT : (strcmp(direction, "up") == 0 ? D_UP : D_DOWN))));
-+ cmd_output->needs_tree_render = true;
- }
-- floating_reposition(focused->parent, newrect);
-- } else {
-- tree_move((strcmp(direction, "right") == 0 ? D_RIGHT : (strcmp(direction, "left") == 0 ? D_LEFT : (strcmp(direction, "up") == 0 ? D_UP : D_DOWN))));
-- cmd_output->needs_tree_render = true;
- }
-
-+ /* the move command should not disturb focus */
-+ if (focused != initially_focused)
-+ con_focus(initially_focused);
-+
- // XXX: default reply for now, make this a better reply
- ysuccess(true);
- }
-diff --git a/src/move.c b/src/move.c
-index 44045f2..9c0f310 100644
---- a/src/move.c
-+++ b/src/move.c
-@@ -132,18 +132,17 @@ static void move_to_output_directed(Con *con, direction_t direction) {
- }
-
- /*
-- * Moves the current container in the given direction (D_LEFT, D_RIGHT,
-+ * Moves the given container in the given direction (D_LEFT, D_RIGHT,
- * D_UP, D_DOWN).
- *
- */
--void tree_move(int direction) {
-+void tree_move(Con *con, int direction) {
- position_t position;
- Con *target;
-
- DLOG("Moving in direction %d\n", direction);
-
- /* 1: get the first parent with the same orientation */
-- Con *con = focused;
-
- if (con->type == CT_WORKSPACE) {
- DLOG("Not moving workspace\n");
-diff --git a/testcases/t/232-cmd-move-criteria.t b/testcases/t/232-cmd-move-criteria.t
-new file mode 100644
-index 0000000..22a2eb4
---- a/dev/null
-+++ b/testcases/t/232-cmd-move-criteria.t
-@@ -0,0 +1,37 @@
-+#!perl
-+# vim:ts=4:sw=4:expandtab
-+#
-+# Please read the following documents before working on tests:
-+# • http://build.i3wm.org/docs/testsuite.html
-+# (or docs/testsuite)
-+#
-+# • http://build.i3wm.org/docs/lib-i3test.html
-+# (alternatively: perldoc ./testcases/lib/i3test.pm)
-+#
-+# • http://build.i3wm.org/docs/ipc.html
-+# (or docs/ipc)
-+#
-+# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
-+# (unless you are already familiar with Perl)
-+#
-+# Test that the `move [direction]` command works with criteria
-+# Bug still in: 4.8-16-g6888a1f
-+use i3test;
-+
-+my $ws = fresh_workspace;
-+
-+my $win1 = open_window;
-+my $win2 = open_window;
-+my $win3 = open_window;
-+
-+# move win1 from the left to the right
-+cmd '[id="' . $win1->{id} . '"] move right';
-+
-+# now they should be switched, with win2 still being focused
-+my $ws_con = get_ws($ws);
-+
-+# win2 should be on the left
-+is($ws_con->{nodes}[0]->{window}, $win2->{id}, 'the `move [direction]` command should work with criteria');
-+is($x->input_focus, $win3->{id}, 'it should not disturb focus');
-+
-+done_testing;
---
-cgit v0.9.0.3
diff --git a/x11-wm/i3-4.9.1/i3bar-icons.patch b/x11-wm/i3-4.9.1/i3bar-icons.patch
deleted file mode 100644
index d3d672f..0000000
--- a/x11-wm/i3-4.9.1/i3bar-icons.patch
+++ /dev/null
@@ -1,437 +0,0 @@
-diff --git a/common.mk b/common.mk
-index b9e15a2..5c9bdf9 100644
---- a/common.mk
-+++ b/common.mk
-@@ -82,6 +82,7 @@ XCB_CFLAGS := $(call cflags_for_lib, xcb)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-event)
- XCB_LIBS := $(call ldflags_for_lib, xcb,xcb)
- XCB_LIBS += $(call ldflags_for_lib, xcb-event,xcb-event)
-+XCB_LIBS += $(call ldflags_for_lib, xcb-image,xcb-image)
- ifeq ($(shell pkg-config --exists xcb-util 2>/dev/null || echo 1),1)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-atom)
- XCB_CFLAGS += $(call cflags_for_lib, xcb-aux)
-diff --git a/i3bar/include/common.h b/i3bar/include/common.h
-index e8b6be0..3f28624 100644
---- a/i3bar/include/common.h
-+++ b/i3bar/include/common.h
-@@ -10,6 +10,7 @@
- #include <stdbool.h>
- #include <xcb/xcb.h>
- #include <xcb/xproto.h>
-+#include <xcb/xcb_image.h>
- #include "libi3.h"
- #include "queue.h"
-
-@@ -39,6 +40,7 @@ struct status_block {
- i3String *full_text;
-
- char *color;
-+ char *icon;
- uint32_t min_width;
- blockalign_t align;
-
-@@ -57,6 +59,7 @@ struct status_block {
- /* Optional */
- char *name;
- char *instance;
-+ xcb_image_t *icon_image;
-
- TAILQ_ENTRY(status_block) blocks;
- };
-@@ -70,6 +73,7 @@ TAILQ_HEAD(statusline_head, status_block) statusline_head;
- #include "workspaces.h"
- #include "mode.h"
- #include "trayclients.h"
-+#include "xbm.h"
- #include "xcb.h"
- #include "config.h"
- #include "libi3.h"
-diff --git a/i3bar/include/xbm.h b/i3bar/include/xbm.h
-new file mode 100644
-index 0000000..f3cc3d5
---- /dev/null
-+++ b/i3bar/include/xbm.h
-@@ -0,0 +1,47 @@
-+/*
-+ * vim:ts=4:sw=4:expandtab
-+ *
-+ * i3bar - an xcb-based status- and ws-bar for i3
-+ * © 2010-2011 Axel Wagner and contributors (see also: LICENSE)
-+ *
-+ * xbm.c: Parsing/Loading xbm data
-+ *
-+ */
-+#ifndef XBM_H_
-+#define XBM_H_
-+
-+#include "queue.h"
-+
-+#define BUFSZ 512
-+
-+struct raw_xbm {
-+ uint32_t w,h;
-+ uint32_t dlen;
-+ uint8_t *data;
-+};
-+
-+struct Cached_Xbm {
-+ char *path;
-+ xcb_image_t *icon;
-+ int used;
-+ SLIST_ENTRY(Cached_Xbm) xbm_cache;
-+};
-+
-+/* Set the format information for loaded icons */
-+void set_format(xcb_connection_t * c, uint8_t depth, uint8_t bpp);
-+
-+/* Set xcb context color for icon, needed with pango patch */
-+void set_icon_color(xcb_connection_t *c, xcb_gcontext_t gc,
-+ uint32_t foreground, uint32_t background);
-+
-+/* get the xcb image for the given icon path */
-+xcb_image_t* get_icon(char* path);
-+
-+/* cache functions */
-+void xbm_clear_cache_used();
-+xcb_image_t* xbm_get_cached_icon(char* path);
-+void xbm_cache_icon(char* path, xcb_image_t* icon);
-+void xbm_free_unused_icons();
-+
-+
-+#endif
-diff --git a/i3bar/src/child.c b/i3bar/src/child.c
-index 2f7dd76..db53659 100644
---- a/i3bar/src/child.c
-+++ b/i3bar/src/child.c
-@@ -141,6 +141,7 @@ static int stdin_start_array(void *context) {
- FREE(first->color);
- FREE(first->name);
- FREE(first->instance);
-+ FREE(first->icon);
- TAILQ_REMOVE(&statusline_head, first, blocks);
- free(first);
- }
-@@ -187,6 +188,9 @@ static int stdin_string(void *context, const unsigned char *val, size_t len) {
- if (strcasecmp(ctx->last_map_key, "color") == 0) {
- sasprintf(&(ctx->block.color), "%.*s", len, val);
- }
-+ if (strcasecmp(ctx->last_map_key, "icon") == 0) {
-+ sasprintf(&(ctx->block.icon), "%.*s", len, val);
-+ }
- if (strcasecmp(ctx->last_map_key, "align") == 0) {
- if (len == strlen("center") && !strncmp((const char *)val, "center", strlen("center"))) {
- ctx->block.align = ALIGN_CENTER;
-@@ -246,6 +250,7 @@ static int stdin_end_array(void *context) {
- TAILQ_FOREACH(current, &statusline_head, blocks) {
- DLOG("full_text = %s\n", i3string_as_utf8(current->full_text));
- DLOG("color = %s\n", current->color);
-+ DLOG("icon = %s\n",current->icon);
- }
- DLOG("end of dump\n");
- return 1;
-diff --git a/i3bar/src/xbm.c b/i3bar/src/xbm.c
-new file mode 100644
-index 0000000..b6781e1
---- /dev/null
-+++ b/i3bar/src/xbm.c
-@@ -0,0 +1,238 @@
-+/*
-+ * vim:ts=4:sw=4:expandtab
-+ *
-+ * i3bar - an xcb-based status- and ws-bar for i3
-+ * © 2010-2011 Axel Wagner and contributors (see also: LICENSE)
-+ *
-+ * xbm.c: Parsing/Loading xbm data
-+ *
-+ * set_format from:
-+ * http://vincentsanders.blogspot.de/2010/04/xcb-programming-is-hard.html
-+ */
-+
-+#include <string.h>
-+
-+#include <xcb/xcb.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <sys/types.h>
-+#include <unistd.h>
-+#include <errno.h>
-+#include <string.h>
-+
-+#include "common.h"
-+
-+static xcb_format_t* format = NULL;
-+
-+void set_format(xcb_connection_t * c, uint8_t depth, uint8_t bpp) {
-+ const xcb_setup_t *setup = xcb_get_setup(c);
-+ xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
-+ xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
-+ for(; fmt != fmtend; ++fmt)
-+ if((fmt->depth == depth) && (fmt->bits_per_pixel == bpp))
-+ format = fmt;
-+}
-+
-+/* With pango we need to set colors ourselves, since the pango
-+ * patch only sets font color */
-+void set_icon_color(xcb_connection_t *c, xcb_gcontext_t gc,
-+ uint32_t foreground, uint32_t background) {
-+ uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
-+ uint32_t values[] = {foreground, background };
-+ xcb_change_gc(c, gc, mask, values);
-+}
-+
-+static int
-+parse_xbm(char* file, struct raw_xbm* data) {
-+ FILE *f;
-+ char *str;
-+ int i,p,r,lim;
-+ char *c;
-+ uint8_t *d;
-+
-+ int in_array = 0;
-+
-+ data->w = data->h = -1;
-+
-+ f = fopen(file,"r");
-+ if (!f) {
-+ ELOG("Could not open xbm file: %s",file);
-+ return 1;
-+ }
-+
-+ str=malloc(BUFSZ);
-+ if (!str) {
-+ ELOG("Could not malloc buffer for xbm parsing");
-+ fclose(f);
-+ return 1;
-+ }
-+
-+ while (fscanf(f," #define %s %d",str,&i) == 2) {
-+ if (strstr(str,"width") != NULL)
-+ data->w = i;
-+ else if (strstr(str,"height") != NULL)
-+ data->h = i;
-+ }
-+
-+ if (data->w <= 0 || data->h <= 0) {
-+ ELOG("Could not find height and/or width in xbm: %s\n",file);
-+ fclose(f);
-+ free(str);
-+ return 1;
-+ }
-+
-+ d = malloc(data->w*data->h);
-+ p = 0;
-+
-+ r = fread(str,1,BUFSZ,f);
-+ lim = r;
-+ while(r>0) {
-+ if(in_array) {
-+ while(c < (str+lim)) {
-+ char* t = c;
-+ while (*t && t!=(str+lim-1) && *t!=',' && *t!='}') t++;
-+ if (*t && (*t==',' || *t=='}'))
-+ d[p++] = strtol(c,NULL,16);
-+ else
-+ break;
-+ c=t+1;
-+ }
-+ } else {
-+ c = str;
-+ while (*c && c!=(str+lim) && *c!='{')
-+ c++;
-+ if (*c && c!=(str+lim) && *c=='{') {
-+ in_array=1;
-+ c++;
-+ if (c<(str+lim)) continue;
-+ }
-+ }
-+
-+ i = (str+lim)-c;
-+ if (i > 0) memcpy(str,c,i);
-+
-+ r = fread(str+i,1,BUFSZ-i,f);
-+ c=str;
-+ lim = r+i;
-+ }
-+
-+ fclose(f);
-+ free(str);
-+
-+ /* will free if p==0, so we only have malloced mem
-+ * when p!=0 */
-+ d = realloc(d,p);
-+
-+ data->dlen = p;
-+ data->data = d;
-+ return p==0;
-+}
-+
-+static xcb_image_t *
-+create_icon_image(struct raw_xbm *xbm) {
-+ int i,rowsize,done,di;
-+ unsigned char *imgdata;
-+ if (format == NULL) return NULL;
-+
-+ imgdata = (unsigned char *)calloc(xbm->w,xbm->h);
-+
-+ rowsize = format->scanline_pad;
-+ while(rowsize < xbm->w) rowsize+=format->scanline_pad;
-+
-+ for(done=0,di=0,i=0;i<xbm->dlen;i++) {
-+ imgdata[di] = xbm->data[i];
-+ di++;
-+ done+=8;
-+ if (done >= xbm->w) {
-+ // pad out to rowsize
-+ while (done < rowsize) {
-+ di++;
-+ done+=8;
-+ }
-+ done=0;
-+ }
-+ }
-+
-+ return xcb_image_create(xbm->w,
-+ xbm->h,
-+ XCB_IMAGE_FORMAT_XY_BITMAP,
-+ format->scanline_pad,
-+ format->depth,
-+ format->bits_per_pixel,
-+ 0,
-+ XCB_IMAGE_ORDER_LSB_FIRST,
-+ XCB_IMAGE_ORDER_LSB_FIRST,
-+ imgdata,
-+ xbm->w*xbm->h,
-+ imgdata);
-+}
-+
-+xcb_image_t* get_icon(char* path) {
-+ xcb_image_t* ret;
-+ struct raw_xbm rxbm;
-+
-+ ret = xbm_get_cached_icon(path);
-+ if (ret) return ret;
-+
-+ DLOG("Loading xbm: %s\n",path);
-+
-+ rxbm.data = NULL;
-+ if (parse_xbm(path,&rxbm)) {
-+ ELOG("Cannot parse xbm: %s\n",path);
-+ return NULL;
-+ }
-+ ret = create_icon_image(&rxbm);
-+ xbm_cache_icon(path,ret);
-+ free(rxbm.data);
-+ return ret;
-+}
-+
-+/* Below we implement a cache for parsed xbm icons.
-+ *
-+ * If an icon is used in a draw of the bar, it sticks around until the
-+ * next draw, otherwise we throw it away at the end of a update. The
-+ * idea being that most icons are fairly static, or change rarely
-+ * (like when a battery threshold is reached). Therefore, we are very
-+ * aggresive about throwing things out of the cache.
-+ */
-+
-+static SLIST_HEAD(xbm_cache_head, Cached_Xbm) xbm_cache;
-+
-+void xbm_clear_cache_used() {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ cxbm->used = 0;
-+ }
-+}
-+
-+xcb_image_t* xbm_get_cached_icon(char* path) {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ if (!strcmp(path,cxbm->path)) {
-+ cxbm->used = 1;
-+ return cxbm->icon;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+void xbm_cache_icon(char* path, xcb_image_t* icon) {
-+ struct Cached_Xbm *cxbm = smalloc(sizeof(struct Cached_Xbm));
-+ cxbm->used = 1;
-+ cxbm->path = strdup(path);
-+ cxbm->icon = icon;
-+ SLIST_INSERT_HEAD(&xbm_cache,cxbm,xbm_cache);
-+}
-+
-+void xbm_free_unused_icons() {
-+ struct Cached_Xbm* cxbm;
-+ SLIST_FOREACH(cxbm,&xbm_cache,xbm_cache) {
-+ if (!cxbm->used) {
-+ SLIST_REMOVE(&xbm_cache, cxbm, Cached_Xbm, xbm_cache);
-+ free(cxbm->path);
-+ xcb_image_destroy(cxbm->icon);
-+ free(cxbm);
-+ }
-+ }
-+}
-+
-diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c
-index 3a1b8cb..04be889 100644
---- a/i3bar/src/xcb.c
-+++ b/i3bar/src/xcb.c
-@@ -140,6 +140,14 @@ void refresh_statusline(void) {
-
- block->width = predict_text_width(block->full_text);
-
-+ if (block->icon) {
-+ block->icon_image = get_icon(block->icon);
-+ if (!block->icon_image)
-+ ELOG("Could not load icon: %s\n",block->icon);
-+ else
-+ statusline_width += block->icon_image->width+1;
-+ }
-+
- /* Compute offset and append for text aligment in min_width. */
- if (block->min_width <= block->width) {
- block->x_offset = 0;
-@@ -204,6 +212,15 @@ void refresh_statusline(void) {
- }
-
- set_font_colors(statusline_ctx, fg_color, colors.bar_bg);
-+
-+ if (block->icon_image) {
-+ int h = (font.height-block->icon_image->height)/2;
-+ set_icon_color(xcb_connection, statusline_ctx, fg_color, colors.bar_bg);
-+ xcb_image_put(xcb_connection, statusline_pm, statusline_ctx, block->icon_image, x, h, 0);
-+ set_icon_color(xcb_connection, statusline_ctx, get_colorpixel("#666666"), colors.bar_bg);
-+ x += block->icon_image->width+1;
-+ }
-+
- draw_text(block->full_text, statusline_pm, statusline_ctx, x + block->x_offset, 3, block->width);
- x += block->width + block->sep_block_width + block->x_offset + block->x_append;
-
-@@ -1107,6 +1124,9 @@ char *init_xcb_early() {
- /* Now we get the atoms and save them in a nice data structure */
- get_atoms();
-
-+ /* Set the format for icons */
-+ set_format(xcb_connection,1,1);
-+
- char *path = root_atom_contents("I3_SOCKET_PATH", xcb_connection, screen);
-
- if (xcb_request_failed(sl_pm_cookie, "Could not allocate statusline-buffer") ||
-@@ -1739,6 +1759,7 @@ void draw_bars(bool unhide) {
- DLOG("Drawing Bars...\n");
- int i = 0;
-
-+ xbm_clear_cache_used();
- refresh_statusline();
-
- i3_output *outputs_walk;
-@@ -1901,6 +1922,8 @@ void draw_bars(bool unhide) {
- hide_bars();
- }
-
-+ xbm_free_unused_icons();
-+
- redraw_bars();
- }
-