diff --git a/Makefile b/Makefile
index 24800a5..06abaae 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ endif
 
 CC	?= gcc
 CFLAGS += -Wall -std=c99 -Os -DVERSION="\"$(VERSION)\""
-LDFLAGS += -lxcb -lxcb-xinerama -lxcb-randr
+LDFLAGS += -lxcb -lxcb-xinerama -lxcb-randr -lxcb-image
 CFDEBUG = -g3 -pedantic -Wall -Wunused-parameter -Wlong-long \
           -Wsign-conversion -Wconversion -Wimplicit-function-declaration
 
diff --git a/lemonbar.c b/lemonbar.c
index 2198731..86d0116 100644
--- a/lemonbar.c
+++ b/lemonbar.c
@@ -13,6 +13,7 @@
 #include <xcb/xcbext.h>
 #include <xcb/xinerama.h>
 #include <xcb/randr.h>
+#include <xcb/xcb_image.h>
 
 // Here be dragons
 
@@ -60,6 +61,12 @@ typedef struct area_stack_t {
     area_t *area;
 } area_stack_t;
 
+typedef struct xbm_icon_t {
+    int width, height;
+    char *filename;
+    xcb_image_t* image;
+} xbm_icon_t;
+
 enum {
     ATTR_OVERL = (1<<0),
     ATTR_UNDERL = (1<<1),
@@ -98,6 +105,11 @@ static rgba_t fgc, bgc, ugc;
 static rgba_t dfgc, dbgc, dugc;
 static area_stack_t area_stack;
 
+#define ICON_CACHE_SIZE 256
+static int icon_count = 0;
+static int icon_index = 0;
+static xbm_icon_t* icon_cache[ICON_CACHE_SIZE];
+
 void
 update_gc (void)
 {
@@ -231,6 +243,134 @@ draw_char (monitor_t *mon, font_t *cur_font, int x, int align, uint16_t ch)
     return ch_width;
 }
 
+xbm_icon_t* load_xbm(char* filename) {
+    for (int i=0; i<icon_count; i++) {
+        if (strcmp(icon_cache[i]->filename, filename) == 0) {
+            return icon_cache[i];
+        }
+    }
+    FILE *f = NULL;
+    f = fopen(filename, "r");
+    if (!f)
+        return NULL;
+
+    int width = -1;
+    int height = -1;
+
+    char line[256];
+    char define_name[256];
+    int value;
+    while (fgets(line, sizeof(line), f)) {
+        if (line[0] == '\n') continue;
+        if (sscanf(line, "#define %s %d", define_name, &value) == 2) {
+            char *type = strrchr(define_name, '_');
+            if (type)
+                type++;
+            else
+                type = define_name;
+
+            if (strcmp(type, "width") == 0)
+                width = value;
+            if (strcmp(type, "height") == 0)
+                height = value;
+
+            continue;
+        }
+        if (width <= 0 || height <= 0) {
+            fclose(f);
+            return NULL;
+        }
+        if (
+            sscanf(line, "static const unsigned char %s = {", define_name) == 1||
+            sscanf(line, "static unsigned char %s = {", define_name) == 1||
+            sscanf(line, "static const char %s = {", define_name) == 1||
+            sscanf(line, "static char %s = {", define_name) == 1
+        ) {
+        } else {
+            fclose(f);
+            return NULL;
+        }
+
+        //const int n = (width/8 + (width%8) ? 1 : 0) * height;
+        xbm_icon_t *icon = calloc(1, sizeof(xbm_icon_t));
+        icon->width = width;
+        icon->height = height;
+        icon->filename = calloc(strlen(filename), sizeof(char));
+        if (icon->filename == NULL) {
+            exit(1);
+        }
+        strcpy(icon->filename, filename);
+
+        xcb_image_t *img = xcb_image_create_native(c, width, height, XCB_IMAGE_FORMAT_XY_BITMAP, 1, NULL, ~0, NULL);
+        img->data = calloc(1, img->size);
+        if (img->data == NULL) {
+            exit(1);
+        }
+
+        for (int y = 0; y < height; y ++) {
+            for (int x = 0; x < width; x+= 8) {
+                if (x != 0 || y != 0)
+                    fgetc(f);
+                int val;
+                if (fscanf(f, "%x", &val)) {
+
+                } else {
+                    xcb_image_destroy(img);
+                    free(icon);
+                    fclose(f);
+                    return NULL;
+                }
+                for (int x2 = x; x2 < width && x2 < x + 8; x2++) {
+                    bool pix = (val >> (x2%8)) & 1;
+                    xcb_image_put_pixel(img, x2, y, pix);
+                }
+            }
+        }
+        icon->image = img;
+
+        if (icon_count < ICON_CACHE_SIZE)
+            icon_count++;
+        icon_cache[icon_index] = icon;
+        icon_index++;
+        icon_index %= ICON_CACHE_SIZE;
+        fclose(f);
+        return icon;
+    }
+    // Instruction pointer modifiecd by cosmic rays
+    return NULL;
+}
+
+int
+draw_icon (monitor_t *mon, int x, int align, char *filename)
+{
+    xbm_icon_t *icon = load_xbm(filename);
+    if (icon == NULL)
+        return 0;
+    int icon_width = icon->width;
+
+
+    switch (align) {
+        case ALIGN_C:
+            xcb_copy_area(c, mon->pixmap, mon->pixmap, gc[GC_DRAW],
+                    mon->width / 2 - x / 2, 0,
+                    mon->width / 2 - (x + icon_width) / 2, 0,
+                    x, bh);
+            x = mon->width / 2 - (x + icon_width) / 2 + x;
+            break;
+        case ALIGN_R:
+            xcb_copy_area(c, mon->pixmap, mon->pixmap, gc[GC_DRAW],
+                    mon->width - x, 0,
+                    mon->width - x - icon_width, 0,
+                    x, bh);
+            x = mon->width - icon_width;
+            break;
+    }
+
+    fill_rect(mon->pixmap, gc[GC_CLEAR], x, by, icon->width, bh);
+    xcb_image_put(c, mon->pixmap, gc[GC_DRAW], icon->image, x, (bh-icon->height) / 2, 0);
+    return 0;
+}
+
 rgba_t
 parse_color (const char *str, char **end, const rgba_t def)
 {
@@ -509,6 +649,17 @@ parse (char *text)
                     case 'c': pos_x = 0; align = ALIGN_C; break;
                     case 'r': pos_x = 0; align = ALIGN_R; break;
 
+                    case 'I':
+                              if (block_end-p > 255)
+                                  break;
+                              char filename[256];
+                              strncpy(filename, p, block_end-p);
+                              int icon_width = draw_icon(cur_mon, pos_x, align, filename);
+                              pos_x += icon_width;
+                              area_shift(cur_mon->window, align, icon_width);
+
+                              break;
+
                     case 'A':
                               button = XCB_BUTTON_INDEX_1;
                               // The range is 1-5