bar: break out all XCB specific code to separate functions

This commit is contained in:
Daniel Eklöf 2019-01-29 20:09:07 +01:00
parent 8d1afd027b
commit f5aebc07ef

166
bar.c
View file

@ -64,7 +64,13 @@ struct private {
int width; int width;
int height_with_border; int height_with_border;
/* Resources */ /* Name of currently active cursor */
char *cursor_name;
cairo_t *cairo;
cairo_surface_t *cairo_surface;
/* Backend specifics */
xcb_connection_t *conn; xcb_connection_t *conn;
xcb_window_t win; xcb_window_t win;
@ -73,10 +79,6 @@ struct private {
xcb_gc_t gc; xcb_gc_t gc;
xcb_cursor_context_t *cursor_ctx; xcb_cursor_context_t *cursor_ctx;
xcb_cursor_t cursor; xcb_cursor_t cursor;
char *cursor_name;
cairo_t *cairo;
cairo_surface_t *cairo_surface;
}; };
/* /*
@ -114,6 +116,15 @@ calculate_widths(const struct private *b, int *left, int *center, int *right)
*right -= b->left_spacing + b->right_spacing; *right -= b->left_spacing + b->right_spacing;
} }
static void
backend_commit_surface(const struct bar *_bar)
{
const struct private *bar = _bar->private;
xcb_copy_area(bar->conn, bar->pixmap, bar->win, bar->gc,
0, 0, 0, 0, bar->width, bar->height_with_border);
xcb_flush(bar->conn);
}
static void static void
expose(const struct bar *_bar) expose(const struct bar *_bar)
{ {
@ -204,14 +215,12 @@ expose(const struct bar *_bar)
} }
cairo_surface_flush(bar->cairo_surface); cairo_surface_flush(bar->cairo_surface);
xcb_copy_area(bar->conn, bar->pixmap, bar->win, bar->gc, backend_commit_surface(_bar);
0, 0, 0, 0, bar->width, bar->height_with_border);
xcb_flush(bar->conn);
} }
static void static void
refresh(const struct bar *bar) backend_refresh(const struct bar *bar)
{ {
const struct private *b = bar->private; const struct private *b = bar->private;
@ -237,7 +246,13 @@ refresh(const struct bar *bar)
} }
static void static void
set_cursor(struct bar *bar, const char *cursor) refresh(const struct bar *bar)
{
backend_refresh(bar);
}
static void
backend_set_cursor(struct bar *bar, const char *cursor)
{ {
struct private *b = bar->private; struct private *b = bar->private;
@ -258,6 +273,12 @@ set_cursor(struct bar *bar, const char *cursor)
xcb_change_window_attributes(b->conn, b->win, XCB_CW_CURSOR, &b->cursor); xcb_change_window_attributes(b->conn, b->win, XCB_CW_CURSOR, &b->cursor);
} }
static void
set_cursor(struct bar *bar, const char *cursor)
{
backend_set_cursor(bar, cursor);
}
static void static void
on_mouse(struct bar *bar, enum mouse_event event, int x, int y) on_mouse(struct bar *bar, enum mouse_event event, int x, int y)
{ {
@ -266,7 +287,7 @@ on_mouse(struct bar *bar, enum mouse_event event, int x, int y)
if ((y < b->border.width || y >= (b->height_with_border - b->border.width)) || if ((y < b->border.width || y >= (b->height_with_border - b->border.width)) ||
(x < b->border.width || x >= (b->width - b->border.width))) (x < b->border.width || x >= (b->width - b->border.width)))
{ {
set_cursor(bar, "left_ptr"); backend_set_cursor(bar, "left_ptr");
return; return;
} }
@ -315,11 +336,11 @@ on_mouse(struct bar *bar, enum mouse_event event, int x, int y)
mx += e->width + b->right_spacing; mx += e->width + b->right_spacing;
} }
set_cursor(bar, "left_ptr"); backend_set_cursor(bar, "left_ptr");
} }
static int static bool
run(struct bar *_bar) backend_setup(struct bar *_bar)
{ {
struct private *bar = _bar->private; struct private *bar = _bar->private;
@ -331,7 +352,7 @@ run(struct bar *_bar)
if (xcb_connection_has_error(bar->conn) > 0) { if (xcb_connection_has_error(bar->conn) > 0) {
LOG_ERR("failed to connect to X"); LOG_ERR("failed to connect to X");
xcb_disconnect(bar->conn); xcb_disconnect(bar->conn);
return 1; return false;
} }
xcb_screen_t *screen = xcb_aux_get_screen(bar->conn, default_screen); xcb_screen_t *screen = xcb_aux_get_screen(bar->conn, default_screen);
@ -345,7 +366,7 @@ run(struct bar *_bar)
LOG_ERR("failed to get monitor list: %s", xcb_error(e)); LOG_ERR("failed to get monitor list: %s", xcb_error(e));
free(e); free(e);
/* TODO: cleanup (disconnect) */ /* TODO: cleanup (disconnect) */
return 1; return false;
} }
bar->height_with_border = bar->height + 2 * bar->border.width; bar->height_with_border = bar->height + 2 * bar->border.width;
@ -386,7 +407,7 @@ run(struct bar *_bar)
if (!found_monitor) { if (!found_monitor) {
LOG_ERR("no matching monitor"); LOG_ERR("no matching monitor");
/* TODO: cleanup */ /* TODO: cleanup */
return 1; return false;
} }
uint8_t depth = 0; uint8_t depth = 0;
@ -522,38 +543,16 @@ run(struct bar *_bar)
if (xcb_cursor_context_new(bar->conn, screen, &bar->cursor_ctx) < 0) if (xcb_cursor_context_new(bar->conn, screen, &bar->cursor_ctx) < 0)
LOG_WARN("failed to create XCB cursor context"); LOG_WARN("failed to create XCB cursor context");
else
set_cursor(_bar, "left_ptr");
xcb_flush(bar->conn); xcb_flush(bar->conn);
return true;
/* Start modules */
thrd_t thrd_left[bar->left.count];
thrd_t thrd_center[bar->center.count];
thrd_t thrd_right[bar->right.count];
for (size_t i = 0; i < bar->left.count; i++) {
struct module *mod = bar->left.mods[i];
mod->abort_fd = _bar->abort_fd;
thrd_create(&thrd_left[i], (int (*)(void *))bar->left.mods[i]->run, mod);
}
for (size_t i = 0; i < bar->center.count; i++) {
struct module *mod = bar->center.mods[i];
mod->abort_fd = _bar->abort_fd;
thrd_create(&thrd_center[i], (int (*)(void *))bar->center.mods[i]->run, mod);
}
for (size_t i = 0; i < bar->right.count; i++) {
struct module *mod = bar->right.mods[i];
mod->abort_fd = _bar->abort_fd;
thrd_create(&thrd_right[i], (int (*)(void *))bar->right.mods[i]->run, mod);
} }
LOG_DBG("all modules started"); static void
backend_loop(struct bar *_bar)
int fd = xcb_get_file_descriptor(bar->conn); {
struct private *bar = _bar->private;
const int fd = xcb_get_file_descriptor(bar->conn);
while (true) { while (true) {
struct pollfd fds[] = { struct pollfd fds[] = {
@ -620,6 +619,67 @@ run(struct bar *_bar)
xcb_flush(bar->conn); xcb_flush(bar->conn);
} }
} }
}
static void
backend_cleanup(struct bar *_bar)
{
struct private *bar = _bar->private;
if (bar->cursor_ctx != NULL) {
xcb_free_cursor(bar->conn, bar->cursor);
xcb_cursor_context_free(bar->cursor_ctx);
free(bar->cursor_name);
bar->cursor_name = NULL;
}
xcb_free_gc(bar->conn, bar->gc);
xcb_free_pixmap(bar->conn, bar->pixmap);
xcb_destroy_window(bar->conn, bar->win);
xcb_free_colormap(bar->conn, bar->colormap);
xcb_flush(bar->conn);
xcb_disconnect(bar->conn);
}
static int
run(struct bar *_bar)
{
struct private *bar = _bar->private;
if (!backend_setup(_bar))
return 1;
backend_set_cursor(_bar, "left_ptr");
/* Start modules */
thrd_t thrd_left[bar->left.count];
thrd_t thrd_center[bar->center.count];
thrd_t thrd_right[bar->right.count];
for (size_t i = 0; i < bar->left.count; i++) {
struct module *mod = bar->left.mods[i];
mod->abort_fd = _bar->abort_fd;
thrd_create(&thrd_left[i], (int (*)(void *))bar->left.mods[i]->run, mod);
}
for (size_t i = 0; i < bar->center.count; i++) {
struct module *mod = bar->center.mods[i];
mod->abort_fd = _bar->abort_fd;
thrd_create(&thrd_center[i], (int (*)(void *))bar->center.mods[i]->run, mod);
}
for (size_t i = 0; i < bar->right.count; i++) {
struct module *mod = bar->right.mods[i];
mod->abort_fd = _bar->abort_fd;
thrd_create(&thrd_right[i], (int (*)(void *))bar->right.mods[i]->run, mod);
}
LOG_DBG("all modules started");
backend_loop(_bar);
LOG_DBG("shutting down"); LOG_DBG("shutting down");
@ -678,21 +738,7 @@ run(struct bar *_bar)
cairo_surface_destroy(bar->cairo_surface); cairo_surface_destroy(bar->cairo_surface);
cairo_debug_reset_static_data(); cairo_debug_reset_static_data();
if (bar->cursor_ctx != NULL) { backend_cleanup(_bar);
xcb_free_cursor(bar->conn, bar->cursor);
xcb_cursor_context_free(bar->cursor_ctx);
free(bar->cursor_name);
bar->cursor_name = NULL;
}
xcb_free_gc(bar->conn, bar->gc);
xcb_free_pixmap(bar->conn, bar->pixmap);
xcb_destroy_window(bar->conn, bar->win);
xcb_free_colormap(bar->conn, bar->colormap);
xcb_flush(bar->conn);
xcb_disconnect(bar->conn);
LOG_DBG("bar exiting"); LOG_DBG("bar exiting");
return ret; return ret;