#include #include #include #include #include #include #include #include #include #include "pipe.h" #include "bardata.h" Display* display; Window win; GC gc; XftFont* font = NULL; XftColor xft_fg_color; static int bar_width = 1000; static float width_ratio = 1; static int err_code = 1; void die(const char* fmt, ...) { va_list args; va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); putc('\n', stderr); exit(err_code); } void load_font(const char* font_name) { XftFont* new_font = XftFontOpenName(display, DefaultScreen(display), font_name); if (new_font == NULL) { fprintf(stderr, "cannot open font %s\n", font_name); return; } if (font != NULL) { XftFontClose(display, font); } font = new_font; } void init_x(void) { display = XOpenDisplay(NULL); if (display == NULL) { die("could not open X display"); } XSetWindowAttributes win_attr = { .override_redirect = 1, .background_pixel = 0x202020, .event_mask = ExposureMask | PropertyChangeMask, }; Screen* screen = DefaultScreenOfDisplay(display); bar_width = WidthOfScreen(screen); win = XCreateWindow( display, DefaultRootWindow(display), 0, 0, bar_width, bar_height, 0, CopyFromParent, InputOutput, CopyFromParent, CWOverrideRedirect | CWBackPixel | CWEventMask, &win_attr ); XClassHint class_hint; class_hint.res_name = "tsarbar"; class_hint.res_class = "Bar"; XSetClassHint(display, win, &class_hint); XMapWindow(display, win); load_font("monospace:size=10"); XftColorAllocName( display, DefaultVisual(display, DefaultScreen(display)), DefaultColormap(display, DefaultScreen(display)), "#FFFFFF", &xft_fg_color ); gc = XCreateGC(display, win, 0, NULL); XSetForeground(display, gc, 0xFFFFFF); XLowerWindow(display, win); XFlush(display); } void deinit_x(void) { XftFontClose(display, font); XUnmapWindow(display, win); XDestroyWindow(display, win); } void draw_text(const char* text, int x, int y) { XftDraw* xft_draw = XftDrawCreate( display, win, DefaultVisual(display, DefaultScreen(display)), DefaultColormap(display, DefaultScreen(display)) ); int dy = y + (bar_height - font->height) / 2 + font->ascent; XftDrawString8(xft_draw, &xft_fg_color, font, x, dy, (const FcChar8*)text, strlen(text)); XftDrawDestroy(xft_draw); } void draw_comp_set(float pos_ratio, comp_t **set, int size) { int width = 0; for (int i = 0; i < size; i++) { comp_t *comp = set[i]; width += font->max_advance_width * strlen(comp->data); } int x = (bar_width - width) * pos_ratio; x += padding * 2*(0.5 - pos_ratio); // Magic formula lol int y = (bar_height - font->height) / 2; for (int i = 0; i < size; i++) { comp_t *comp = set[i]; draw_text(comp->data, x, y); x += font->max_advance_width * strlen(comp->data); } } int main(void) { init_pipe(); init_x(); while (true) { XEvent ev; while (XPending(display)) XNextEvent(display, &ev); XClearWindow(display, win); XResizeWindow(display, win, bar_width, bar_height); draw_comp_set(0, comps_left, left_size); draw_comp_set(0.5, comps_center, center_size); draw_comp_set(1, comps_right, right_size); XFlush(display); await_change(); } deinit_x(); return 0; }