On Fri, Nov 23 2018, Joel Carnat <joel@carnat.net> wrote:
> Hi,
Hi,
> On a journey to find a statusbar for cwm, I found that x11/lemonbar
> didn't support XFT. I used sources from https://github.com/krypt-n/bar
> to compile on OpenBSD 6.4/amd64 and it seems to work. So far, it
> compiles, lemonbar starts and renders text using xft:Sans:size=11.
>
> Find the relevant patches attached.
Make sure you at least Cc the port maintainer. You should probably have
discussed this diff with Ingo first, it looks a bit intrusive.
> Regards,
> Jo
>
> --- Makefile.orig Fri Nov 23 00:26:08 2018
> +++ Makefile Fri Nov 23 00:35:00 2018
> @@ -1,4 +1,4 @@
> # This snippet has been shmelessly stol^Hborrowed from thestinger's repose Makefile
> -VERSION = 1.2
> +VERSION = 1.3
> GIT_DESC=$(shell test -d .git && git describe --always 2>/dev/null)
>
> @@ -8,6 +8,8 @@
>
> CC ?= gcc
> -CFLAGS += -Wall -std=c99 -DVERSION="\"$(VERSION)\""
> -LDFLAGS += -lxcb -lxcb-xinerama -lxcb-randr
> +CFLAGS += -Wall -std=c99 -DVERSION="\"$(VERSION)\"" \
> + -I/usr/X11R6/include/freetype2
> +LDFLAGS += -lxcb -lxcb-xinerama -lxcb-randr \
> + -lX11 -lX11-xcb -lXft -lfreetype -lz -lfontconfig
> CFDEBUG = -g3 -pedantic -Wall -Wunused-parameter -Wlong-long \
> -Wsign-conversion -Wconversion -Wimplicit-function-declaration
>
> --- lemonbar.c.orig Mon Nov 20 11:47:43 2017
> +++ lemonbar.c Fri Nov 23 00:30:26 2018
> @@ -2,4 +2,5 @@
> #define _POSIX_C_SOURCE 200809L
> #include <stdbool.h>
> +#include <stddef.h>
> #include <stdio.h>
> #include <stdlib.h>
> @@ -8,4 +9,5 @@
> #include <signal.h>
> #include <poll.h>
> +#include <fcntl.h>
> #include <getopt.h>
> #include <unistd.h>
> @@ -18,6 +20,9 @@
> #include <xcb/randr.h>
>
> -// Here be dragons
> +#include <X11/Xft/Xft.h>
> +#include <X11/Xlib-xcb.h>
>
> +// Here bet dragons
> +
> #define max(a,b) ((a) > (b) ? (a) : (b))
> #define min(a,b) ((a) < (b) ? (a) : (b))
> @@ -26,8 +31,13 @@
> typedef struct font_t {
> xcb_font_t ptr;
> + xcb_charinfo_t *width_lut;
> +
> + XftFont *xft_ft;
> +
> + int ascent;
> +
> int descent, height, width;
> uint16_t char_max;
> uint16_t char_min;
> - xcb_charinfo_t *width_lut;
> } font_t;
>
> @@ -69,9 +79,8 @@
> };
>
> -enum {
> - ALIGN_L = 0,
> - ALIGN_C,
> - ALIGN_R
> -};
> +enum { ALIGN_L = 0,
> + ALIGN_C,
> + ALIGN_R
> + };
>
> enum {
> @@ -84,13 +93,24 @@
> #define MAX_FONT_COUNT 5
>
> +static Display *dpy;
> static xcb_connection_t *c;
> +
> static xcb_screen_t *scr;
> +static int scr_nbr = 0;
> +
> static xcb_gcontext_t gc[GC_MAX];
> static xcb_visualid_t visual;
> +static Visual *visual_ptr;
> static xcb_colormap_t colormap;
> +
> +
> static monitor_t *monhead, *montail;
> static font_t *font_list[MAX_FONT_COUNT];
> static int font_count = 0;
> static int font_index = -1;
> +static int offsets_y[MAX_FONT_COUNT];
> +static int offset_y_count = 0;
> +static int offset_y_index = 0;
> +
> static uint32_t attrs = 0;
> static bool dock = false;
> @@ -102,4 +122,12 @@
> static area_stack_t area_stack;
>
> +static XftColor sel_fg;
> +static XftDraw *xft_draw;
> +
> +//char width lookuptable
> +#define MAX_WIDTHS (1 << 16)
> +static wchar_t xft_char[MAX_WIDTHS];
> +static char xft_width[MAX_WIDTHS];
> +
> void
> update_gc (void)
> @@ -108,4 +136,11 @@
> xcb_change_gc(c, gc[GC_CLEAR], XCB_GC_FOREGROUND, (const uint32_t []){ bgc.v });
> xcb_change_gc(c, gc[GC_ATTR], XCB_GC_FOREGROUND, (const uint32_t []){ ugc.v });
> + XftColorFree(dpy, visual_ptr, colormap , &sel_fg);
> + char color[] = "#ffffff";
> + uint32_t nfgc = fgc.v & 0x00ffffff;
> + snprintf(color, sizeof(color), "#%06X", nfgc);
> + if (!XftColorAllocName (dpy, visual_ptr, colormap, color, &sel_fg)) {
> + fprintf(stderr, "Couldn't allocate xft font color '%s'\n", color);
> + }
> }
>
> @@ -189,5 +224,35 @@
> }
>
> +
> int
> +xft_char_width_slot (uint16_t ch)
> +{
> + int slot = ch % MAX_WIDTHS;
> + while (xft_char[slot] != 0 && xft_char[slot] != ch)
> + {
> + slot = (slot + 1) % MAX_WIDTHS;
> + }
> + return slot;
> +}
> +
> +int xft_char_width (uint16_t ch, font_t *cur_font)
> +{
> + int slot = xft_char_width_slot(ch);
> + if (!xft_char[slot]) {
> + XGlyphInfo gi;
> + FT_UInt glyph = XftCharIndex (dpy, cur_font->xft_ft, (FcChar32) ch);
> + XftFontLoadGlyphs (dpy, cur_font->xft_ft, FcFalse, &glyph, 1);
> + XftGlyphExtents (dpy, cur_font->xft_ft, &glyph, 1, &gi);
> + XftFontUnloadGlyphs (dpy, cur_font->xft_ft, &glyph, 1);
> + xft_char[slot] = ch;
> + xft_width[slot] = gi.xOff;
> + return gi.xOff;
> + } else if (xft_char[slot] == ch)
> + return xft_width[slot];
> + else
> + return 0;
> +}
> +
> +int
> shift (monitor_t *mon, int x, int align, int ch_width)
> {
> @@ -208,6 +273,6 @@
> break;
> }
> -
> - // Draw the background first
> +
> + /* Draw the background first */
> fill_rect(mon->pixmap, gc[GC_CLEAR], x, 0, ch_width, bh);
> return x;
> @@ -234,17 +299,28 @@
> draw_char (monitor_t *mon, font_t *cur_font, int x, int align, uint16_t ch)
> {
> - int ch_width = (cur_font->width_lut) ?
> - cur_font->width_lut[ch - cur_font->char_min].character_width:
> - cur_font->width;
> + int ch_width;
>
> + if (cur_font->xft_ft) {
> + ch_width = xft_char_width(ch, cur_font);
> + } else {
> + ch_width = (cur_font->width_lut) ?
> + cur_font->width_lut[ch - cur_font->char_min].character_width:
> + cur_font->width;
> + }
> +
> x = shift(mon, x, align, ch_width);
>
> - // xcb accepts string in UCS-2 BE, so swap
> - ch = (ch >> 8) | (ch << 8);
> -
> - // The coordinates here are those of the baseline
> - xcb_poly_text_16_simple(c, mon->pixmap, gc[GC_DRAW],
> - x, bh / 2 + cur_font->height / 2 - cur_font->descent,
> + int y = bh / 2 + cur_font->height / 2- cur_font->descent + offsets_y[offset_y_index];
> + if (cur_font->xft_ft) {
> + XftDrawString16 (xft_draw, &sel_fg, cur_font->xft_ft, x,y, &ch, 1);
> + } else {
> + /* xcb accepts string in UCS-2 BE, so swap */
> + ch = (ch >> 8) | (ch << 8);
> +
> + // The coordinates here are those of the baseline
> + xcb_poly_text_16_simple(c, mon->pixmap, gc[GC_DRAW],
> + x, y,
> 1, &ch);
> + }
>
> draw_lines(mon, x, ch_width);
> @@ -337,7 +413,13 @@
>
> switch (modifier) {
> - case '+': attrs |= (1<<pos); break;
> - case '-': attrs &=~(1<<pos); break;
> - case '!': attrs ^= (1<<pos); break;
> + case '+':
> + attrs |= (1u<<pos);
> + break;
> + case '-':
> + attrs &=~(1u<<pos);
> + break;
> + case '!':
> + attrs ^= (1u<<pos);
> + break;
> }
> }
> @@ -460,4 +542,13 @@
> font_has_glyph (font_t *font, const uint16_t c)
> {
> + if (font->xft_ft) {
> + if (XftCharExists(dpy, font->xft_ft, (FcChar32) c)) {
> + return true;
> + } else {
> + return false;
> + }
> +
> + }
> +
> if (c < font->char_min || c > font->char_max)
> return false;
> @@ -469,21 +560,25 @@
> }
>
> -// returns NULL if character cannot be printed
> font_t *
> select_drawable_font (const uint16_t c)
> {
> // If the user has specified a font to use, try that first.
> - if (font_index != -1 && font_has_glyph(font_list[font_index - 1], c))
> + if (font_index != -1 && font_has_glyph(font_list[font_index - 1], c)) {
> + offset_y_index = font_index - 1;
> return font_list[font_index - 1];
> + }
>
> // If the end is reached without finding an appropriate font, return NULL.
> // If the font can draw the character, return it.
> for (int i = 0; i < font_count; i++) {
> - if (font_has_glyph(font_list[i], c))
> + if (font_has_glyph(font_list[i], c)) {
> + offset_y_index = i;
> return font_list[i];
> + }
> }
> return NULL;
> }
>
> +
> void
> parse (char *text)
> @@ -505,7 +600,12 @@
> fill_rect(m->pixmap, gc[GC_CLEAR], 0, 0, m->width, bh);
>
> + /* Create xft drawable */
> + if (!(xft_draw = XftDrawCreate (dpy, cur_mon->pixmap, visual_ptr , colormap))) {
> + fprintf(stderr, "Couldn't create xft drawable\n");
> + }
> +
> for (;;) {
> if (*p == '\0' || *p == '\n')
> - return;
> + break;
>
> if (p[0] == '%' && p[1] == '{' && (block_end = strchr(p++, '}'))) {
> @@ -561,4 +661,8 @@
> else
> { p++; continue; }
> + XftDrawDestroy (xft_draw);
> + if (!(xft_draw = XftDrawCreate (dpy, cur_mon->pixmap, visual_ptr , colormap ))) {
> + fprintf(stderr, "Couldn't create xft drawable\n");
> + }
>
> p++;
> @@ -603,8 +707,4 @@
> p++;
> } else { // utf-8 -> ucs-2
> - // Escaped % symbol, eat the first one
> - if (p[0] == '%' && p[1] == '%')
> - p++;
> -
> uint8_t *utf = (uint8_t *)p;
> uint16_t ucs;
> @@ -650,6 +750,8 @@
> continue;
>
> - xcb_change_gc(c, gc[GC_DRAW] , XCB_GC_FONT, (const uint32_t []){ cur_font->ptr });
> -
> + if(cur_font->ptr)
> + xcb_change_gc(c, gc[GC_DRAW] , XCB_GC_FONT, (const uint32_t []) {
> + cur_font->ptr
> + });
> int w = draw_char(cur_mon, cur_font, pos_x, align, ucs);
>
> @@ -658,4 +760,5 @@
> }
> }
> + XftDrawDestroy (xft_draw);
> }
>
> @@ -675,10 +778,4 @@
> font = xcb_generate_id(c);
>
> - cookie = xcb_open_font_checked(c, font, strlen(pattern), pattern);
> - if (xcb_request_check (c, cookie)) {
> - fprintf(stderr, "Could not load font \"%s\"\n", pattern);
> - return;
> - }
> -
> font_t *ret = calloc(1, sizeof(font_t));
>
> @@ -686,26 +783,53 @@
> return;
>
> - queryreq = xcb_query_font(c, font);
> - font_info = xcb_query_font_reply(c, queryreq, NULL);
> + cookie = xcb_open_font_checked(c, font, strlen(pattern), pattern);
> + if (!xcb_request_check (c, cookie)) {
> + queryreq = xcb_query_font(c, font);
> + font_info = xcb_query_font_reply(c, queryreq, NULL);
>
> - ret->ptr = font;
> - ret->descent = font_info->font_descent;
> - ret->height = font_info->font_ascent + font_info->font_descent;
> - ret->width = font_info->max_bounds.character_width;
> - ret->char_max = font_info->max_byte1 << 8 | font_info->max_char_or_byte2;
> - ret->char_min = font_info->min_byte1 << 8 | font_info->min_char_or_byte2;
> -
> - // Copy over the width lut as it's part of font_info
> - int lut_size = sizeof(xcb_charinfo_t) * xcb_query_font_char_infos_length(font_info);
> - if (lut_size) {
> - ret->width_lut = malloc(lut_size);
> - memcpy(ret->width_lut, xcb_query_font_char_infos(font_info), lut_size);
> + ret->xft_ft = NULL;
> + ret->ptr = font;
> + ret->descent = font_info->font_descent;
> + ret->height = font_info->font_ascent + font_info->font_descent;
> + ret->width = font_info->max_bounds.character_width;
> + ret->char_max = font_info->max_byte1 << 8 | font_info->max_char_or_byte2;
> + ret->char_min = font_info->min_byte1 << 8 | font_info->min_char_or_byte2;
> + // Copy over the width lut as it's part of font_info
> + int lut_size = sizeof(xcb_charinfo_t) * xcb_query_font_char_infos_length(font_info);
> + if (lut_size) {
> + ret->width_lut = malloc(lut_size);
> + memcpy(ret->width_lut, xcb_query_font_char_infos(font_info), lut_size);
> + }
> + free(font_info);
> + } else if ((ret->xft_ft = XftFontOpenName (dpy, scr_nbr, pattern))) {
> + ret->ptr = 0;
> + ret->ascent = ret->xft_ft->ascent;
> + ret->descent = ret->xft_ft->descent;
> + ret->height = ret->ascent + ret->descent;
> + } else {
> + fprintf(stderr, "Could not load font %s\n", pattern);
> + free(ret);
> + return;
> }
>
> - free(font_info);
> -
> font_list[font_count++] = ret;
> }
>
> +void add_y_offset(int offset) {
> + if (offset_y_count >= MAX_FONT_COUNT) {
> + fprintf(stderr, "Max offset count reached. Could not set offset \"%d\"\n", offset);
> + return;
> + }
> +
> + offsets_y[offset_y_count] = strtol(optarg, NULL, 10);
> + if (offset_y_count == 0) {
> + for (int i = 1; i < MAX_FONT_COUNT; ++i) {
> + offsets_y[i] = offsets_y[0];
> + }
> + }
> + ++offset_y_count;
> +}
> +
> +
> enum {
> NET_WM_WINDOW_TYPE,
> @@ -757,17 +881,20 @@
> strut[2] = bh;
> strut[8] = mon->x;
> - strut[9] = mon->x + mon->width - 1;
> + strut[9] = mon->x + mon->width;
> } else {
> strut[3] = bh;
> strut[10] = mon->x;
> - strut[11] = mon->x + mon->width - 1;
> + strut[11] = mon->x + mon->width;
> }
>
> xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, atom_list[NET_WM_WINDOW_TYPE], XCB_ATOM_ATOM, 32, 1, &atom_list[NET_WM_WINDOW_TYPE_DOCK]);
> xcb_change_property(c, XCB_PROP_MODE_APPEND, mon->window, atom_list[NET_WM_STATE], XCB_ATOM_ATOM, 32, 2, &atom_list[NET_WM_STATE_STICKY]);
> - xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, atom_list[NET_WM_DESKTOP], XCB_ATOM_CARDINAL, 32, 1, (const uint32_t []){ -1 } );
> + xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, atom_list[NET_WM_DESKTOP], XCB_ATOM_CARDINAL, 32, 1, (const uint32_t []) {
> + 0u - 1u
> + } );
> xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, atom_list[NET_WM_STRUT_PARTIAL], XCB_ATOM_CARDINAL, 32, 12, strut);
> xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, atom_list[NET_WM_STRUT], XCB_ATOM_CARDINAL, 32, 4, strut);
> xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, 3, "bar");
> + xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 8, 12, "lemonbar\0Bar");
> }
> }
> @@ -789,11 +916,12 @@
> ret->next = ret->prev = NULL;
> ret->window = xcb_generate_id(c);
> -
> int depth = (visual == scr->root_visual) ? XCB_COPY_FROM_PARENT : 32;
> xcb_create_window(c, depth, ret->window, scr->root,
> - ret->x, ret->y, width, bh, 0,
> - XCB_WINDOW_CLASS_INPUT_OUTPUT, visual,
> - XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP,
> - (const uint32_t []){ bgc.v, bgc.v, dock, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS, colormap });
> + ret->x, ret->y, width, bh, 0,
> + XCB_WINDOW_CLASS_INPUT_OUTPUT, visual,
> + XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP,
> + (const uint32_t []) {
> + bgc.v, bgc.v, dock, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS, colormap
> + });
>
> ret->pixmap = xcb_generate_id(c);
> @@ -854,5 +982,5 @@
> // Get height of screen from y_offset + height of lowest monitor
> if (h >= height)
> - height = h;
> + height = h;
> }
>
> @@ -877,8 +1005,8 @@
> if (rects[i].width > left) {
> monitor_t *mon = monitor_new(
> - rects[i].x + left,
> - rects[i].y,
> - min(width, rects[i].width - left),
> - rects[i].height);
> + rects[i].x + left,
> + rects[i].y,
> + min(width, rects[i].width - left),
> + rects[i].height);
>
> if (!mon)
> @@ -888,5 +1016,4 @@
>
> width -= rects[i].width - left;
> -
> // No need to check for other monitors
> if (width <= 0)
> @@ -909,5 +1036,5 @@
>
> rres_reply = xcb_randr_get_screen_resources_current_reply(c,
> - xcb_randr_get_screen_resources_current(c, scr->root), NULL);
> + xcb_randr_get_screen_resources_current(c, scr->root), NULL);
>
> if (!rres_reply) {
> @@ -943,5 +1070,5 @@
>
> ci_reply = xcb_randr_get_crtc_info_reply(c,
> - xcb_randr_get_crtc_info(c, oi_reply->crtc, XCB_CURRENT_TIME), NULL);
> + xcb_randr_get_crtc_info(c, oi_reply->crtc, XCB_CURRENT_TIME), NULL);
>
> free(oi_reply);
> @@ -973,5 +1100,5 @@
> if (i != j && rects[j].width) {
> if (rects[j].x >= rects[i].x && rects[j].x + rects[j].width <= rects[i].x + rects[i].width &&
> - rects[j].y >= rects[i].y && rects[j].y + rects[j].height <= rects[i].y + rects[i].height) {
> + rects[j].y >= rects[i].y && rects[j].y + rects[j].height <= rects[i].y + rects[i].height) {
> rects[j].width = 0;
> valid--;
> @@ -1004,5 +1131,5 @@
>
> xqs_reply = xcb_xinerama_query_screens_reply(c,
> - xcb_xinerama_query_screens_unchecked(c), NULL);
> + xcb_xinerama_query_screens_unchecked(c), NULL);
>
> iter = xcb_xinerama_query_screens_screen_info_iterator(xqs_reply);
> @@ -1029,20 +1156,19 @@
> get_visual (void)
> {
> - xcb_depth_iterator_t iter;
>
> - iter = xcb_screen_allowed_depths_iterator(scr);
> + XVisualInfo xv;
> + xv.depth = 32;
> + int result = 0;
> + XVisualInfo* result_ptr = NULL;
> + result_ptr = XGetVisualInfo(dpy, VisualDepthMask, &xv, &result);
>
> - // Try to find a RGBA visual
> - while (iter.rem) {
> - xcb_visualtype_t *vis = xcb_depth_visuals(iter.data);
> -
> - if (iter.data->depth == 32)
> - return vis->visual_id;
> -
> - xcb_depth_next(&iter);
> + if (result > 0) {
> + visual_ptr = result_ptr->visual;
> + return result_ptr->visualid;
> }
> -
> - // Fallback to the default one
> - return scr->root_visual;
> +
> + //Fallback
> + visual_ptr = DefaultVisual(dpy, scr_nbr);
> + return scr->root_visual;
> }
>
> @@ -1101,6 +1227,15 @@
> xconn (void)
> {
> - // Connect to X
> - c = xcb_connect (NULL, NULL);
> + if ((dpy = XOpenDisplay(0)) == NULL) {
> + fprintf (stderr, "Couldnt open display\n");
> + }
> +
> + if ((c = XGetXCBConnection(dpy)) == NULL) {
> + fprintf (stderr, "Couldnt connect to X\n");
> + exit (EXIT_FAILURE);
> + }
> +
> + XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
> +
> if (xcb_connection_has_error(c)) {
> fprintf(stderr, "Couldn't connect to X\n");
> @@ -1108,10 +1243,9 @@
> }
>
> - // Grab infos from the first screen
> + /* Grab infos from the first screen */
> scr = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
>
> - // Try to get a RGBA visual and build the colormap for that
> - visual = get_visual();
> -
> + /* Try to get a RGBA visual and build the colormap for that */
> + visual = get_visual();
> colormap = xcb_generate_id(c);
> xcb_create_colormap(c, XCB_COLORMAP_ALLOC_NONE, colormap, scr->root, visual);
> @@ -1119,5 +1253,5 @@
>
> void
> -init (char *wm_name)
> +init (char *wm_name, char *wm_instance)
> {
> // Try to load a default font
> @@ -1214,6 +1348,31 @@
> if (wm_name)
> xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8 ,strlen(wm_name), wm_name);
> +
> + // set the WM_CLASS atom instance to the executable name
> + if (wm_instance) {
> + char *wm_class;
> + int wm_class_offset, wm_class_len;
> +
> + // WM_CLASS is nullbyte seperated: wm_instance + "\0Bar\0"
> + wm_class_offset = strlen(wm_instance) + 1;
> + wm_class_len = wm_class_offset + 4;
> +
> + wm_class = calloc(1, wm_class_len + 1);
> + strcpy(wm_class, wm_instance);
> + strcpy(wm_class+wm_class_offset, "Bar");
> +
> + xcb_change_property(c, XCB_PROP_MODE_REPLACE, mon->window, XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 8, wm_class_len, wm_class);
> +
> + free(wm_class);
> + }
> }
>
> + char color[] = "#ffffff";
> + uint32_t nfgc = fgc.v & 0x00ffffff;
> + snprintf(color, sizeof(color), "#%06X", nfgc);
> +
> + if (!XftColorAllocName (dpy, visual_ptr, colormap, color, &sel_fg)) {
> + fprintf(stderr, "Couldn't allocate xft font color '%s'\n", color);
> + }
> xcb_flush(c);
> }
> @@ -1223,8 +1382,12 @@
> {
> free(area_stack.area);
> -
> - for (int i = 0; i < font_count; i++) {
> - xcb_close_font(c, font_list[i]->ptr);
> - free(font_list[i]->width_lut);
> + for (int i = 0; font_list[i]; i++) {
> + if (font_list[i]->xft_ft) {
> + XftFontClose (dpy, font_list[i]->xft_ft);
> + }
> + else {
> + xcb_close_font(c, font_list[i]->ptr);
> + free(font_list[i]->width_lut);
> + }
> free(font_list[i]);
> }
> @@ -1238,5 +1401,5 @@
> }
>
> - xcb_free_colormap(c, colormap);
> + XftColorFree(dpy, visual_ptr, colormap, &sel_fg);
>
> if (gc[GC_DRAW])
> @@ -1250,4 +1413,19 @@
> }
>
> +char*
> +strip_path(char *path)
> +{
> + char *slash;
> +
> + if (path == NULL || *path == '\0')
> + return strdup("lemonbar");
> +
> + slash = strrchr(path, '/');
> + if (slash != NULL)
> + return strndup(slash + 1, 31);
> +
> + return strndup(path, 31);
> +}
> +
> void
> sighandle (int signal)
> @@ -1257,4 +1435,5 @@
> }
>
> +
> int
> main (int argc, char **argv)
> @@ -1272,4 +1451,5 @@
> int ch, areas;
> char *wm_name;
> + char *instance_name;
>
> // Install the parachute!
> @@ -1281,4 +1461,5 @@
> dbgc = bgc = (rgba_t)0x00000000U;
> dfgc = fgc = (rgba_t)0xffffffffU;
> +
> dugc = ugc = fgc;
>
> @@ -1287,11 +1468,13 @@
> wm_name = NULL;
>
> + instance_name = strip_path(argv[0]);
> +
> // Connect to the Xserver and initialize scr
> xconn();
>
> - while ((ch = getopt(argc, argv, "hg:bdf:a:pu:B:F:U:n:")) != -1) {
> + while ((ch = getopt(argc, argv, "hg:bdf:a:pu:B:F:U:n:o:")) != -1) {
> switch (ch) {
> case 'h':
> - printf ("lemonbar version %s\n", VERSION);
> + printf ("lemonbar version %s patched with XFT support\n", VERSION);
> printf ("usage: %s [-h | -g | -b | -d | -f | -a | -p | -n | -u | -B | -F]\n"
> "\t-h Show this help\n"
> @@ -1305,5 +1488,6 @@
> "\t-u Set the underline/overline height in pixels\n"
> "\t-B Set background color in #AARRGGBB\n"
> - "\t-F Set foreground color in #AARRGGBB\n", argv[0]);
> + "\t-F Set foreground color in #AARRGGBB\n"
> + "\t-o Add a vertical offset to the text, it can be negative\n", argv[0]);
> exit (EXIT_SUCCESS);
> case 'g': (void)parse_geometry_string(optarg, geom_v); break;
> @@ -1314,4 +1498,5 @@
> case 'f': font_load(optarg); break;
> case 'u': bu = strtoul(optarg, NULL, 10); break;
> + case 'o': add_y_offset(strtol(optarg, NULL, 10)); break;
> case 'B': dbgc = bgc = parse_color(optarg, NULL, (rgba_t)0x00000000U); break;
> case 'F': dfgc = fgc = parse_color(optarg, NULL, (rgba_t)0xffffffffU); break;
> @@ -1343,10 +1528,15 @@
>
> // Do the heavy lifting
> - init(wm_name);
> + init(wm_name, instance_name);
> // The string is strdup'd when the command line arguments are parsed
> free(wm_name);
> + // The string is strdup'd when stripping argv[0]
> + free(instance_name);
> // Get the fd to Xserver
> pollin[1].fd = xcb_get_file_descriptor(c);
>
> + // Prevent fgets to block
> + fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
> +
> for (;;) {
> bool redraw = false;
> @@ -1362,7 +1552,7 @@
> }
> if (pollin[0].revents & POLLIN) { // New input, process it
> - if (fgets(input, sizeof(input), stdin) == NULL)
> - break; // EOF received
> -
> + input[0] = '\0';
> + while (fgets(input, sizeof(input), stdin) != NULL)
> + ; // Drain the buffer, the last line is actually used
> parse(input);
> redraw = true;
> @@ -1387,5 +1577,5 @@
> }
> }
> - break;
> + break;
> }
>
>
--
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE
No comments:
Post a Comment