diff --git a/cagebreak.c b/cagebreak.c index a9852e5..164b4ea 100644 --- a/cagebreak.c +++ b/cagebreak.c @@ -307,7 +307,18 @@ main(int argc, char *argv[]) { } server.nws = 1; - server.message_timeout = 2; + server.message_config.fg_color[0]=0.0; + server.message_config.fg_color[1]=0.0; + server.message_config.fg_color[2]=0.0; + server.message_config.fg_color[3]=1.0; + + server.message_config.bg_color[0]=0.9; + server.message_config.bg_color[1]=0.85; + server.message_config.bg_color[2]=0.85; + server.message_config.bg_color[3]=1.0; + + server.message_config.display_time = 2; + server.message_config.font=strdup("pango:Monospace 10"); event_loop = wl_display_get_event_loop(server.wl_display); sigint_source = diff --git a/keybinding.c b/keybinding.c index 624a09f..c192e41 100644 --- a/keybinding.c +++ b/keybinding.c @@ -75,6 +75,12 @@ keybinding_free(struct keybinding *keybinding, bool recursive) { free(keybinding->data.i_cfg->mapped_to_output); } free(keybinding->data.o_cfg); + break; + case KEYBINDING_CONFIGURE_MESSAGE: + if(keybinding->data.m_cfg->font!=NULL) { + free(keybinding->data.m_cfg->font); + } + break; default: break; } @@ -970,6 +976,29 @@ keybinding_configure_input(struct cg_server *server, cg_input_apply_config(cfg, server); } +void +keybinding_configure_message(struct cg_server *server, struct cg_message_config *config) { + if(config->font!=NULL) { + free(server->message_config.font); + server->message_config.font=strdup(config->font); + } + if(config->display_time!=-1) { + server->message_config.display_time=config->display_time; + } + if(config->bg_color[0]!=-1) { + server->message_config.bg_color[0]=config->bg_color[0]; + server->message_config.bg_color[1]=config->bg_color[1]; + server->message_config.bg_color[2]=config->bg_color[2]; + server->message_config.bg_color[3]=config->bg_color[3]; + } + if(config->fg_color[0]!=-1) { + server->message_config.fg_color[0]=config->fg_color[0]; + server->message_config.fg_color[1]=config->fg_color[1]; + server->message_config.fg_color[2]=config->fg_color[2]; + server->message_config.fg_color[3]=config->fg_color[3]; + } +} + void keybinding_configure_input_dev(struct cg_server *server, struct cg_input_config *cfg) {} @@ -1109,6 +1138,9 @@ run_action(enum keybinding_action action, struct cg_server *server, case KEYBINDING_CONFIGURE_OUTPUT: keybinding_configure_output(server, data.o_cfg); break; + case KEYBINDING_CONFIGURE_MESSAGE: + keybinding_configure_message(server, data.m_cfg); + break; case KEYBINDING_CONFIGURE_INPUT: keybinding_configure_input(server, data.i_cfg); break; diff --git a/keybinding.h b/keybinding.h index 88378a1..fd9eefc 100644 --- a/keybinding.h +++ b/keybinding.h @@ -25,6 +25,7 @@ enum keybinding_action { KEYBINDING_CYCLE_OUTPUT, // data.b is 0 if forward, 1 if reverse KEYBINDING_CONFIGURE_OUTPUT, // data.o_cfg is the desired output // configuration + KEYBINDING_CONFIGURE_MESSAGE, // data.m_cfg is the desired config KEYBINDING_CONFIGURE_INPUT, // data.i_cfg is the desired input // configuration KEYBINDING_QUIT, @@ -69,6 +70,7 @@ union keybinding_params { struct keybinding *kb; struct cg_output_config *o_cfg; struct cg_input_config *i_cfg; + struct cg_message_config *m_cfg; }; struct keybinding { diff --git a/message.c b/message.c index f05b175..291f6ef 100644 --- a/message.c +++ b/message.c @@ -35,7 +35,6 @@ struct wlr_texture * create_message_texture(const char *string, const struct cg_output *output) { const int WIDTH_PADDING = 8; const int HEIGHT_PADDING = 2; - const char *font = "pango:Monospace 10"; struct wlr_texture *texture; double scale = output->wlr_output->scale; @@ -60,7 +59,7 @@ create_message_texture(const char *string, const struct cg_output *output) { cairo_font_options_set_subpixel_order( fo, to_cairo_subpixel_order(output->wlr_output->subpixel)); cairo_set_font_options(c, fo); - get_text_size(c, font, &width, &height, NULL, scale, "%s", string); + get_text_size(c, output->server->message_config.font, &width, &height, NULL, scale, "%s", string); width += 2 * WIDTH_PADDING; height += 2 * HEIGHT_PADDING; cairo_surface_destroy(dummy_surface); @@ -72,16 +71,18 @@ create_message_texture(const char *string, const struct cg_output *output) { cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); cairo_set_font_options(cairo, fo); cairo_font_options_destroy(fo); - cairo_set_source_rgba(cairo, 0.9, 0.85, 0.85, 1.0); + float *bg_col=output->server->message_config.bg_color; + cairo_set_source_rgba(cairo, bg_col[0], bg_col[1], bg_col[2], bg_col[3]); cairo_paint(cairo); PangoContext *pango = pango_cairo_create_context(cairo); - cairo_set_source_rgba(cairo, 0, 0, 0, 1); + float *fg_col=output->server->message_config.fg_color; + cairo_set_source_rgba(cairo, fg_col[0], fg_col[1], fg_col[2], fg_col[3]); cairo_set_line_width(cairo, 2); cairo_rectangle(cairo, 0, 0, width, height); cairo_stroke(cairo); cairo_move_to(cairo, WIDTH_PADDING, HEIGHT_PADDING); - pango_printf(cairo, font, scale, "%s", string); + pango_printf(cairo, output->server->message_config.font, scale, "%s", string); cairo_surface_flush(surface); unsigned char *data = cairo_image_surface_get_data(surface); @@ -176,7 +177,7 @@ message_printf(struct cg_output *output, const char *fmt, ...) { message_set_output(output, buffer, box, CG_MESSAGE_TOP_RIGHT); free(buffer); - alarm(output->server->message_timeout); + alarm(output->server->message_config.display_time); } #if CG_HAS_FANALYZE #pragma GCC diagnostic pop @@ -195,7 +196,7 @@ message_printf_pos(struct cg_output *output, struct wlr_box *position, message_set_output(output, buffer, position, align); free(buffer); - alarm(output->server->message_timeout); + alarm(output->server->message_config.display_time); } void diff --git a/message.h b/message.h index 9a4e53e..b1081ab 100644 --- a/message.h +++ b/message.h @@ -16,6 +16,13 @@ enum cg_message_align { CG_MESSAGE_CENTER, }; +struct cg_message_config { + char *font; + int display_time; + float bg_color[4]; + float fg_color[4]; +}; + struct cg_message { struct wlr_box *position; struct wlr_texture *message; diff --git a/parse.c b/parse.c index 6164408..2a22e66 100644 --- a/parse.c +++ b/parse.c @@ -122,7 +122,7 @@ parse_input_config(char **saveptr, char **errstr) { char *ident = NULL; if(cfg == NULL) { *errstr = - log_error("Failed to allocate memory for output configuration"); + log_error("Failed to allocate memory for input configuration"); goto error; } @@ -340,6 +340,9 @@ parse_input_config(char **saveptr, char **errstr) { "Invalid option \"%s\" to setting \"tap_button_map\"", value); goto error; } + } else { + *errstr = log_error("Invalid option to command \"input\""); + goto error; } free(value); @@ -625,6 +628,68 @@ error: return NULL; } +struct cg_message_config *parse_message_config(char **saveptr, char **errstr) { + struct cg_message_config *cfg = calloc(1, sizeof(struct cg_message_config)); + if(cfg == NULL) { + *errstr = + log_error("Failed to allocate memory for message configuration"); + goto error; + } + + cfg->bg_color[0]=-1; + cfg->fg_color[0]=-1; + cfg->display_time=-1; + cfg->font=NULL; + + char *setting = strtok_r(NULL, " ", saveptr); + if(setting == NULL) { + *errstr = + log_error("Expected setting to be set for message configuration, got none"); + goto error; + } + + if(strcmp(setting, "font") == 0) { + cfg->font=strdup(*saveptr); + if(cfg->font == NULL) { + *errstr = log_error( "Unable to allocate memory for font descrition in command \"message\""); + goto error; + } + } else if(strcmp(setting, "display_time") == 0) { + cfg->display_time=parse_uint(saveptr, " "); + if(cfg->display_time<0) { + *errstr = log_error("Error parsing command \"configure_message display_time\", expected a non-negative integer"); + goto error; + } + } else if(strcmp(setting, "bg_color") == 0) { + for(int i = 0; i < 4; ++i) { + cfg->bg_color[i]=parse_float(saveptr, " "); + if(cfg->bg_color[i] == FLT_MIN) { + *errstr = + log_error("Error parsing command \"configure_message bg_color\", expected 4 float values separated by spaces"); + goto error; + } + } + } else if(strcmp(setting, "fg_color") == 0) { + for(int i = 0; i < 4; ++i) { + cfg->fg_color[i]=parse_float(saveptr, " "); + if(cfg->fg_color[i] == FLT_MIN) { + *errstr = + log_error("Error parsing command \"configure_message bg_color\", expected 4 float values separated by spaces"); + goto error; + } + } + } else { + *errstr = log_error("Invalid option to command \"configure_message\""); + goto error; + } + return cfg; + +error: + wlr_log(WLR_ERROR, "Message configuration must be of the form 'configure_message '"); + return NULL; + +} + int parse_command(struct cg_server *server, struct keybinding *keybinding, char *saveptr, char **errstr) { @@ -865,6 +930,12 @@ parse_command(struct cg_server *server, struct keybinding *keybinding, if(keybinding->data.i_cfg == NULL) { return -1; } + } else if(strcmp(action, "configure_message") == 0) { + keybinding->action = KEYBINDING_CONFIGURE_MESSAGE; + keybinding->data.m_cfg = parse_message_config(&saveptr, errstr); + if(keybinding->data.m_cfg == NULL) { + return -1; + } } else { *errstr = log_error("Error, unsupported action \"%s\".", action); return -1; diff --git a/server.h b/server.h index 54fbc17..22dfe32 100644 --- a/server.h +++ b/server.h @@ -3,6 +3,7 @@ #include "config.h" #include "ipc_server.h" +#include "message.h" #include #include @@ -43,6 +44,7 @@ struct cg_server { struct keybinding_list *keybindings; struct wl_list output_config; struct wl_list input_config; + struct cg_message_config message_config; enum wl_output_transform output_transform; @@ -51,7 +53,6 @@ struct cg_server { bool running; char **modes; uint16_t nws; - uint16_t message_timeout; float *bg_color; #ifdef DEBUG bool debug_damage_tracking;