From e43e6321e3504a7edf7b138e43af79a01b996609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Tue, 28 Apr 2015 14:17:12 +0200 Subject: i3-4.10.2 --- x11-wm/i3-4.10.2/i3bar-icons.patch | 437 +++++++++++++++++++++++++++++++++++++ 1 file changed, 437 insertions(+) create mode 100644 x11-wm/i3-4.10.2/i3bar-icons.patch diff --git a/x11-wm/i3-4.10.2/i3bar-icons.patch b/x11-wm/i3-4.10.2/i3bar-icons.patch new file mode 100644 index 0000000..e9cacb8 --- /dev/null +++ b/x11-wm/i3-4.10.2/i3bar-icons.patch @@ -0,0 +1,437 @@ +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 + #include + #include ++#include + #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 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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;idlen;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(); + } + -- cgit v1.2.3