diff --git a/Makefile b/Makefile index dae7ba2..ddc40b2 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC ?= gcc STRIP ?= strip -CFLAGS ?= -fshort-wchar -Os +CFLAGS ?= --std=c99 -fshort-wchar -Os LDFLAGS += -lxcb CFDEBUG = -g3 -pedantic -Wall -Wunused-parameter -Wlong-long\ -Wsign-conversion -Wconversion -Wimplicit-function-declaration diff --git a/bar.c b/bar.c index 51bc7e5..0529376 100644 --- a/bar.c +++ b/bar.c @@ -18,14 +18,14 @@ static xcb_gcontext_t gc; static xcb_drawable_t canvas; static int font_height, font_width, font_descent; static int bar_width; -static const uint32_t pal[] = {COLOR0,COLOR1,COLOR2,COLOR3,COLOR4,COLOR5,COLOR6,COLOR7,COLOR8,COLOR9}; +static const unsigned pal[] = {COLOR0,COLOR1,COLOR2,COLOR3,COLOR4,COLOR5,COLOR6,COLOR7,COLOR8,COLOR9}; #define MIN(a,b) ((a > b ? b : a)) void fill_rect (int color, int x, int y, int width, int height) { - xcb_change_gc (c, gc, XCB_GC_FOREGROUND, (const uint32_t []){ pal[color] }); + xcb_change_gc (c, gc, XCB_GC_FOREGROUND, (const unsigned []){ pal[color] }); xcb_poly_fill_rectangle (c, canvas, gc, 1, (const xcb_rectangle_t []){ { x, y, width, height } }); } @@ -33,45 +33,62 @@ fill_rect (int color, int x, int y, int width, int height) size_t wcslen_ (wchar_t *s) { size_t len; + for (len = 0; *s; s++, len++); + return len; } int draw_string (int x, int align, int fgcol, int bgcol, int udcol, wchar_t *text) { - int done = 0; - int pos_x = x; - int len = MIN(bar_width / font_width, wcslen_ (text)); - int strw = len * font_width; + int chunk_len; + int chars_done; + int pos_x; + int str_lenght; + int str_width; + + pos_x = x; + chars_done = 0; - if (!strw) return 0; + str_lenght = MIN(bar_width / font_width, wcslen_ (text)); + str_width = str_lenght * font_width; + + if (str_width == 0) + return 0; switch (align) { case 1: xcb_copy_area (c, canvas, canvas, gc, bar_width / 2 - pos_x / 2, 0, - bar_width / 2 - (pos_x + strw) / 2, 0, pos_x, BAR_HEIGHT); - pos_x = bar_width / 2 - (pos_x + strw) / 2 + pos_x; + bar_width / 2 - (pos_x + str_width) / 2, 0, pos_x, BAR_HEIGHT); + pos_x = bar_width / 2 - (pos_x + str_width) / 2 + pos_x; break; case 2: xcb_copy_area (c, canvas, canvas, gc, bar_width - pos_x, 0, - bar_width - pos_x - strw, 0, pos_x, BAR_HEIGHT); - pos_x = bar_width - strw; + bar_width - pos_x - str_width, 0, pos_x, BAR_HEIGHT); + pos_x = bar_width - str_width; break; } + /* Draw the background first */ - fill_rect (bgcol, pos_x, 0, strw, BAR_HEIGHT); + fill_rect (bgcol, pos_x, 0, str_width, BAR_HEIGHT); + /* Draw the underline */ - if (BAR_UNDERLINE_HEIGHT) fill_rect (udcol, pos_x, BAR_HEIGHT-BAR_UNDERLINE_HEIGHT, strw, BAR_UNDERLINE_HEIGHT); + if (BAR_UNDERLINE_HEIGHT) + fill_rect (udcol, pos_x, BAR_HEIGHT-BAR_UNDERLINE_HEIGHT, str_width, BAR_UNDERLINE_HEIGHT); + /* Setup the colors */ - xcb_change_gc (c, gc, XCB_GC_FOREGROUND, (const uint32_t []){ pal[fgcol] }); - xcb_change_gc (c, gc, XCB_GC_BACKGROUND, (const uint32_t []){ pal[bgcol] }); + xcb_change_gc (c, gc, XCB_GC_FOREGROUND, (const unsigned []){ pal[fgcol] }); + xcb_change_gc (c, gc, XCB_GC_BACKGROUND, (const unsigned []){ pal[bgcol] }); + do { - xcb_image_text_16 (c, MIN(len - done, 255), canvas, gc, pos_x, /* String baseline coordinates */ - BAR_HEIGHT / 2 + font_height / 2 - font_descent, (xcb_char2b_t *)text + done); - done += MIN(len - done, 255); - pos_x = done * font_width; - } while (done < len); + chunk_len = MIN(str_lenght - chars_done, 255); + /* String baseline coordinates */ + xcb_image_text_16 (c, chunk_len, canvas, gc, pos_x, + BAR_HEIGHT / 2 + font_height / 2 - font_descent, (xcb_char2b_t *)text + chars_done); + chars_done += chunk_len; + pos_x = chars_done * font_width; + } while (chars_done < str_lenght); return pos_x; } @@ -92,18 +109,40 @@ parse (char *text) int udcol = 0; fill_rect (0, 0, 0, bar_width, BAR_HEIGHT); + for (;;) { if (*p == 0x0 || *p == 0xA || (*p == '\\' && p++ && *p != '\\' && strchr ("fbulcr", *p))) { pos_x += draw_string (pos_x, align, fgcol, bgcol, udcol, parsed_text); switch (*p++) { - case 0x0: return; /* EOL */ - case 0xA: return; /* NL */ - case 'f': if (*p == 'r') *p = '1'; if (isdigit (*p)) { fgcol = *p-'0'; } p++; break; - case 'b': if (*p == 'r') *p = '0'; if (isdigit (*p)) { bgcol = *p-'0'; } p++; break; - case 'u': if (*p == 'r') *p = '0'; if (isdigit (*p)) { udcol = *p-'0'; } p++; break; - case 'l': align = 0; pos_x = 0; break; - case 'c': align = 1; pos_x = 0; break; - case 'r': align = 2; pos_x = 0; break; + case 0x0: /* EOL */ + case 0xA: /* NL */ + return; + + case 'f': + if (*p == 'r') *p = '1'; + if (isdigit (*p)) fgcol = (*p++)-'0'; + break; + case 'b': + if (*p == 'r') *p = '0'; + if (isdigit (*p)) bgcol = (*p++)-'0'; + break; + case 'u': + if (*p == 'r') *p = '0'; + if (isdigit (*p)) udcol = (*p++)-'0'; + break; + + case 'l': + align = 0; + pos_x = 0; + break; + case 'c': + align = 1; + pos_x = 0; + break; + case 'r': + align = 2; + pos_x = 0; + break; } q = parsed_text; } else { /* utf-8 -> ucs-2 */ @@ -142,7 +181,7 @@ sighandle (int signal) } void -set_ewmh_props (void) +set_ewmh_atoms (void) { xcb_intern_atom_cookie_t cookies[4]; xcb_atom_t atoms[4]; @@ -162,11 +201,14 @@ set_ewmh_props (void) reply = xcb_intern_atom_reply (c, cookies[3], NULL); atoms[3] = reply->atom; free (reply); + /* Set the _NET_WM_WINDOW_TYPE_DOCK state */ xcb_change_property (c, XCB_PROP_MODE_REPLACE, win, atoms[0], XCB_ATOM_ATOM, 32, 1, &atoms[1]); + /* Show on every desktop */ xcb_change_property (c, XCB_PROP_MODE_REPLACE, win, atoms[2], XCB_ATOM_CARDINAL, 32, 1, - (const int []){ 0xffffffff } ); + (const unsigned []){ 0xffffffff } ); + /* Set the window geometry */ xcb_change_property (c, XCB_PROP_MODE_REPLACE, win, atoms[3], XCB_ATOM_CARDINAL, 32, 12, - (const int []) { 0, 0, BAR_HEIGHT, 0, 0, 0, 0, 0, bar_width, 0, 0} ); + (const unsigned []) { 0, 0, BAR_HEIGHT, 0, 0, 0, 0, 0, bar_width, 0, 0} ); } void @@ -197,20 +239,22 @@ init (void) font_height = font_info->font_ascent + font_info->font_descent; font_width = font_info->max_bounds.character_width; font_descent = font_info->font_descent; + free (font_info); /* Create the main window */ win = xcb_generate_id (c); - xcb_create_window (c, XCB_COPY_FROM_PARENT, win, root, 0, 0, bar_width, BAR_HEIGHT, - 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, scr->root_visual, XCB_CW_BACK_PIXEL | - XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, (const uint32_t []){ pal[0], 1, XCB_EVENT_MASK_EXPOSURE }); + xcb_create_window (c, XCB_COPY_FROM_PARENT, win, root, 0, 0, bar_width, BAR_HEIGHT, + 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, scr->root_visual, + XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, + (const unsigned []){ pal[0], 1, XCB_EVENT_MASK_EXPOSURE }); /* Set EWMH hints */ - set_ewmh_props (); + set_ewmh_atoms (); /* Create a temporary canvas */ canvas = xcb_generate_id (c); xcb_create_pixmap (c, scr->root_depth, canvas, root, bar_width, BAR_HEIGHT); /* Create the gc for drawing */ gc = xcb_generate_id (c); xcb_create_gc (c, gc, root, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT, - (const uint32_t []){ pal[1], pal[0], font }); + (const unsigned []){ pal[1], pal[0], font }); /* Get rid of the font */ xcb_close_font (c, font); /* Make the bar visible */