Add xbm support
This commit is contained in:
parent
3020df1923
commit
fb19fe2e49
2
Makefile
2
Makefile
|
@ -8,7 +8,7 @@ endif
|
||||||
|
|
||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
CFLAGS += -Wall -std=c99 -Os -DVERSION="\"$(VERSION)\""
|
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 \
|
CFDEBUG = -g3 -pedantic -Wall -Wunused-parameter -Wlong-long \
|
||||||
-Wsign-conversion -Wconversion -Wimplicit-function-declaration
|
-Wsign-conversion -Wconversion -Wimplicit-function-declaration
|
||||||
|
|
||||||
|
|
151
lemonbar.c
151
lemonbar.c
|
@ -13,6 +13,7 @@
|
||||||
#include <xcb/xcbext.h>
|
#include <xcb/xcbext.h>
|
||||||
#include <xcb/xinerama.h>
|
#include <xcb/xinerama.h>
|
||||||
#include <xcb/randr.h>
|
#include <xcb/randr.h>
|
||||||
|
#include <xcb/xcb_image.h>
|
||||||
|
|
||||||
// Here be dragons
|
// Here be dragons
|
||||||
|
|
||||||
|
@ -60,6 +61,12 @@ typedef struct area_stack_t {
|
||||||
area_t *area;
|
area_t *area;
|
||||||
} area_stack_t;
|
} area_stack_t;
|
||||||
|
|
||||||
|
typedef struct xbm_icon_t {
|
||||||
|
int width, height;
|
||||||
|
char *filename;
|
||||||
|
xcb_image_t* image;
|
||||||
|
} xbm_icon_t;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ATTR_OVERL = (1<<0),
|
ATTR_OVERL = (1<<0),
|
||||||
ATTR_UNDERL = (1<<1),
|
ATTR_UNDERL = (1<<1),
|
||||||
|
@ -98,6 +105,11 @@ static rgba_t fgc, bgc, ugc;
|
||||||
static rgba_t dfgc, dbgc, dugc;
|
static rgba_t dfgc, dbgc, dugc;
|
||||||
static area_stack_t area_stack;
|
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
|
void
|
||||||
update_gc (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;
|
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
|
rgba_t
|
||||||
parse_color (const char *str, char **end, const rgba_t def)
|
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 'c': pos_x = 0; align = ALIGN_C; break;
|
||||||
case 'r': pos_x = 0; align = ALIGN_R; 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':
|
case 'A':
|
||||||
button = XCB_BUTTON_INDEX_1;
|
button = XCB_BUTTON_INDEX_1;
|
||||||
// The range is 1-5
|
// The range is 1-5
|
||||||
|
|
Loading…
Reference in New Issue
Block a user