#include #include #include #include #include "window.h" #include "layout.h" #include "util.h" #include "event.h" #include "config.h" #include "block.h" #ifdef RELEASE #define ANY_LOG_VALUE_BEFORE(level, module, func, message) \ "[%s%s%s] %s%s%s: %s [", any_log_colors[ANY_LOG_ALL + 2], func, any_log_colors[ANY_LOG_ALL], \ any_log_colors[level], any_log_level_strings[level], any_log_colors[ANY_LOG_ALL], message #define ANY_LOG_FORMAT_BEFORE(level, module, func) \ "[%s%s%s] %s%s%s: ", any_log_colors[ANY_LOG_ALL + 2], func, any_log_colors[ANY_LOG_ALL], \ any_log_colors[level], any_log_level_strings[level], any_log_colors[ANY_LOG_ALL] #define ANY_LOG_FUNC_COLOR "" #define ANY_LOG_NO_TRACE #endif #define ANY_LOG_VALUE_STRING(key, value) "%s=\"%s\"", key, value ? value : "(null)" #define ANY_LOG_IMPLEMENT #include "any_log.h" static sig_atomic_t running = true; static void signal_quit(int status) { running = false; } static cairo_surface_t *render_all(layout_t *layout, config_t *config, layout_info_t info) { cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, config->width, config->height); log_value_trace("Created cairo surface", "i:width", config->width, "i:height", config->height); cairo_t *cr = cairo_create(surface); cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); color_t color = config->background; cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a); cairo_paint(cr); layout_render(layout, cr); log_trace("Rendered layouts"); cairo_destroy(cr); return surface; } int main(int argc, char **argv) { setlocale(LC_CTYPE, ""); any_log_init(stdout, ANY_LOG_DEBUG); config_t config; config_init(&config); log_debug("Copied default config"); const char *config_path = "comet.conf"; FILE *config_file = fopen(config_path, "rb"); if (config_file != NULL) { log_info("Reading config '%s'", config_path); config_read(&config, config_file); } signal(SIGINT, signal_quit); signal(SIGTERM, signal_quit); display_t display; display_init(&display); window_t window; window_init(&window, &display, &config); int x_padding = 10; int y_padding = 8; log_debug("Loading font '%s'", config.font); PangoFontDescription *fontdesc = pango_font_description_from_string(config.font); layout_info_t info = { .fontdesc = fontdesc, .context = pango_cairo_create_context(window.cr), .x_offset = 0, .height = config.height, }; block_t *block = config_resolve(&config); log_debug("Starting bar"); window_resize(&window, config.width, config.height); window_move(&window, x_padding, y_padding); // TODO: Allow ondemand rendering struct timespec rate, start, end, diff; double freq = 1.0 / 60.0 + 0.5e-9; rate.tv_sec = (long)freq; rate.tv_nsec = (freq - rate.tv_sec) * 1000000000ul; while (running) { timespec_get(&start, TIME_UTC); block_update(block); layout_t layout; layout_init(&layout, block, info); event_dispatch(&display, &layout); cairo_surface_t *surface = render_all(&layout, &config, info); window_present(&window, surface); cairo_surface_destroy(surface); layout_free(&layout); timespec_get(&end, TIME_UTC); diff = timespec_diff(rate, timespec_diff(end, start)); nanosleep(&diff, NULL); } log_debug("Quitting bar"); g_object_unref(info.context); pango_font_description_free(fontdesc); window_close(&window); display_close(&display); config_free(&config); return 0; }