From 2a67630aa665fe184943943c197eddc60721764a Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 1 Jun 2009 15:14:45 +0200 Subject: [PATCH] Optimization: Get the colorpixels when loading configuration, make use of the new config struct Instead of building arrays of colorpixels we can simply use a pointer to a struct Colortriple. Furthermore, by getting the colorpixels when loading the configuration, we save a lot of function calls in the main code. --- include/config.h | 8 +++---- src/config.c | 53 ++++++++++++++++++++++++++--------------------- src/handlers.c | 4 ++-- src/layout.c | 54 ++++++++++++++---------------------------------- src/mainx.c | 4 ++-- 5 files changed, 53 insertions(+), 70 deletions(-) diff --git a/include/config.h b/include/config.h index b803c8cd..4ed73a3d 100644 --- a/include/config.h +++ b/include/config.h @@ -19,9 +19,9 @@ typedef struct Config Config; extern Config config; struct Colortriple { - char border[8]; - char background[8]; - char text[8]; + uint32_t border; + uint32_t background; + uint32_t text; }; struct Config { @@ -47,6 +47,6 @@ struct Config { * configuration file. * */ -void load_configuration(const char *override_configfile); +void load_configuration(xcb_connection_t *conn, const char *override_configfile); #endif diff --git a/src/config.c b/src/config.c index 8e8a80bd..3dec073d 100644 --- a/src/config.c +++ b/src/config.c @@ -17,6 +17,7 @@ #include "i3.h" #include "util.h" #include "config.h" +#include "xcb.h" Config config; @@ -41,7 +42,7 @@ static char *glob_path(const char *path) { * configuration file. * */ -void load_configuration(const char *override_configpath) { +void load_configuration(xcb_connection_t *conn, const char *override_configpath) { #define OPTION_STRING(name) \ if (strcasecmp(key, #name) == 0) { \ config.name = sstrdup(value); \ @@ -54,16 +55,20 @@ void load_configuration(const char *override_configpath) { #define OPTION_COLORTRIPLE(opt, name) \ if (strcasecmp(key, opt) == 0) { \ - struct Colortriple buffer; \ - memset(&buffer, 0, sizeof(struct Colortriple)); \ - buffer.border[0] = buffer.background[0] = buffer.text[0] = '#'; \ + char border[8], background[8], text[8]; \ + memset(border, 0, sizeof(border)); \ + memset(background, 0, sizeof(background)); \ + memset(text, 0, sizeof(text)); \ + border[0] = background[0] = text[0] = '#'; \ if (sscanf(value, "#%06[0-9a-fA-F] #%06[0-9a-fA-F] #%06[0-9a-fA-F]", \ - buffer.border + 1, buffer.background + 1, buffer.text + 1) != 3 || \ - strlen(buffer.border) != 7 || \ - strlen(buffer.background) != 7 || \ - strlen(buffer.text) != 7) \ + border + 1, background + 1, text + 1) != 3 || \ + strlen(border) != 7 || \ + strlen(background) != 7 || \ + strlen(text) != 7) \ die("invalid color code line: %s\n", value); \ - memcpy(&config.name, &buffer, sizeof(struct Colortriple)); \ + config.name.border = get_colorpixel(conn, border); \ + config.name.background = get_colorpixel(conn, background); \ + config.name.text = get_colorpixel(conn, text); \ continue; \ } @@ -71,25 +76,25 @@ void load_configuration(const char *override_configpath) { memset(&config, 0, sizeof(config)); /* Initialize default colors */ - strcpy(config.client.focused.border, "#4c7899"); - strcpy(config.client.focused.background, "#285577"); - strcpy(config.client.focused.text, "#ffffff"); + config.client.focused.border = get_colorpixel(conn, "#4c7899"); + config.client.focused.background = get_colorpixel(conn, "#285577"); + config.client.focused.text = get_colorpixel(conn, "#ffffff"); - strcpy(config.client.focused_inactive.border, "#4c7899"); - strcpy(config.client.focused_inactive.background, "#555555"); - strcpy(config.client.focused_inactive.text, "#ffffff"); + config.client.focused_inactive.border = get_colorpixel(conn, "#4c7899"); + config.client.focused_inactive.background = get_colorpixel(conn, "#555555"); + config.client.focused_inactive.text = get_colorpixel(conn, "#ffffff"); - strcpy(config.client.unfocused.border, "#333333"); - strcpy(config.client.unfocused.background, "#222222"); - strcpy(config.client.unfocused.text, "#888888"); + config.client.unfocused.border = get_colorpixel(conn, "#333333"); + config.client.unfocused.background = get_colorpixel(conn, "#222222"); + config.client.unfocused.text = get_colorpixel(conn, "#888888"); - strcpy(config.bar.focused.border, "#4c7899"); - strcpy(config.bar.focused.background, "#285577"); - strcpy(config.bar.focused.text, "#ffffff"); + config.bar.focused.border = get_colorpixel(conn, "#4c7899"); + config.bar.focused.background = get_colorpixel(conn, "#285577"); + config.bar.focused.text = get_colorpixel(conn, "#ffffff"); - strcpy(config.bar.unfocused.border, "#333333"); - strcpy(config.bar.unfocused.background, "#222222"); - strcpy(config.bar.unfocused.text, "#888888"); + config.bar.unfocused.border = get_colorpixel(conn, "#333333"); + config.bar.unfocused.background = get_colorpixel(conn, "#222222"); + config.bar.unfocused.text = get_colorpixel(conn, "#888888"); FILE *handle; if (override_configpath != NULL) { diff --git a/src/handlers.c b/src/handlers.c index cf15d1e4..cdc735e4 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -793,9 +793,9 @@ int handle_expose_event(void *data, xcb_connection_t *conn, xcb_expose_event_t * uint32_t background_color; /* Distinguish if the window is currently focused… */ if (CUR_CELL->currently_focused == client) - background_color = get_colorpixel(conn, config.client.focused.background); + background_color = config.client.focused.background; /* …or if it is the focused window in a not focused container */ - else background_color = get_colorpixel(conn, config.client.focused_inactive.background); + else background_color = config.client.focused_inactive.background; /* Set foreground color to current focused color, line width to 2 */ uint32_t values[] = {background_color, 2}; diff --git a/src/layout.c b/src/layout.c index 0903e2dd..ab6b7452 100644 --- a/src/layout.c +++ b/src/layout.c @@ -100,9 +100,7 @@ void redecorate_window(xcb_connection_t *conn, Client *client) { void decorate_window(xcb_connection_t *conn, Client *client, xcb_drawable_t drawable, xcb_gcontext_t gc, int offset) { i3Font *font = load_font(conn, config.font); int decoration_height = font->height + 2 + 2; - uint32_t background_color, - text_color, - border_color; + struct Colortriple *color; /* Clients without a container (docks) won’t get decorated */ if (client->dock) @@ -112,26 +110,19 @@ void decorate_window(xcb_connection_t *conn, Client *client, xcb_drawable_t draw if (client->floating >= FLOATING_AUTO_ON || client->container->currently_focused == client) { /* Distinguish if the window is currently focused… */ if (client->floating >= FLOATING_AUTO_ON || CUR_CELL->currently_focused == client) - background_color = get_colorpixel(conn, config.client.focused.background); + color = &(config.client.focused); /* …or if it is the focused window in a not focused container */ - else background_color = get_colorpixel(conn, config.client.focused_inactive.background); - - text_color = get_colorpixel(conn, config.client.focused.text); - border_color = get_colorpixel(conn, config.client.focused.border); - } else { - background_color = get_colorpixel(conn, config.client.unfocused.background); - text_color = get_colorpixel(conn, config.client.unfocused.text); - border_color = get_colorpixel(conn, config.client.unfocused.border); - } + else color = &(config.client.focused_inactive); + } else color = &(config.client.unfocused); /* Our plan is the following: - - Draw a rect around the whole client in background_color + - Draw a rect around the whole client in color->background - Draw two lines in a lighter color - Draw the window’s title */ /* Draw a rectangle in background color around the window */ - xcb_change_gc_single(conn, gc, XCB_GC_FOREGROUND, background_color); + xcb_change_gc_single(conn, gc, XCB_GC_FOREGROUND, color->background); /* In stacking mode, we only render the rect for this specific decoration */ if (client->container != NULL && client->container->mode == MODE_STACK) { @@ -153,15 +144,15 @@ void decorate_window(xcb_connection_t *conn, Client *client, xcb_drawable_t draw } /* Draw the lines */ - xcb_draw_line(conn, drawable, gc, border_color, 0, offset, client->rect.width, offset); - xcb_draw_line(conn, drawable, gc, border_color, 2, offset + font->height + 3, + xcb_draw_line(conn, drawable, gc, color->border, 0, offset, client->rect.width, offset); + xcb_draw_line(conn, drawable, gc, color->border, 2, offset + font->height + 3, client->rect.width - 4, offset + font->height + 3); /* If the client has a title, we draw it */ if (client->name != NULL) { /* Draw the font */ uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT; - uint32_t values[] = { text_color, background_color, font->id }; + uint32_t values[] = { color->text, color->background, font->id }; xcb_change_gc(conn, gc, mask, values); /* name_len == -1 means this is a legacy application which does not specify _NET_WM_NAME, @@ -401,24 +392,10 @@ static void render_internal_bar(xcb_connection_t *conn, Workspace *r_ws, int wid i3Font *font = load_font(conn, config.font); i3Screen *screen = r_ws->screen; enum { SET_NORMAL = 0, SET_FOCUSED = 1 }; - uint32_t background_color[2], - text_color[2], - border_color[2], - black; char label[3]; - black = get_colorpixel(conn, "#000000"); - - background_color[SET_NORMAL] = get_colorpixel(conn, config.bar.unfocused.background); - text_color[SET_NORMAL] = get_colorpixel(conn, config.bar.unfocused.text); - border_color[SET_NORMAL] = get_colorpixel(conn, config.bar.unfocused.border); - - background_color[SET_FOCUSED] = get_colorpixel(conn, config.bar.focused.background); - text_color[SET_FOCUSED] = get_colorpixel(conn, config.bar.focused.text); - border_color[SET_FOCUSED] = get_colorpixel(conn, config.bar.focused.border); - /* Fill the whole bar in black */ - xcb_change_gc_single(conn, screen->bargc, XCB_GC_FOREGROUND, black); + xcb_change_gc_single(conn, screen->bargc, XCB_GC_FOREGROUND, get_colorpixel(conn, "#000000")); xcb_rectangle_t rect = {0, 0, width, height}; xcb_poly_fill_rectangle(conn, screen->bar, screen->bargc, 1, &rect); @@ -430,16 +407,17 @@ static void render_internal_bar(xcb_connection_t *conn, Workspace *r_ws, int wid if (workspaces[c].screen != screen) continue; - int set = (screen->current_workspace == c ? SET_FOCUSED : SET_NORMAL); + struct Colortriple *color = (screen->current_workspace == c ? &(config.bar.focused) : + &(config.bar.unfocused)); - xcb_draw_rect(conn, screen->bar, screen->bargc, border_color[set], + xcb_draw_rect(conn, screen->bar, screen->bargc, color->border, drawn * height, 1, height - 2, height - 2); - xcb_draw_rect(conn, screen->bar, screen->bargc, background_color[set], + xcb_draw_rect(conn, screen->bar, screen->bargc, color->background, drawn * height + 1, 2, height - 4, height - 4); snprintf(label, sizeof(label), "%d", c+1); - xcb_change_gc_single(conn, screen->bargc, XCB_GC_FOREGROUND, text_color[set]); - xcb_change_gc_single(conn, screen->bargc, XCB_GC_BACKGROUND, background_color[set]); + xcb_change_gc_single(conn, screen->bargc, XCB_GC_FOREGROUND, color->text); + xcb_change_gc_single(conn, screen->bargc, XCB_GC_BACKGROUND, color->background); xcb_image_text_8(conn, strlen(label), screen->bar, screen->bargc, drawn * height + 5 /* X */, font->height + 1 /* Y = baseline of font */, label); drawn++; diff --git a/src/mainx.c b/src/mainx.c index 50db96d9..79a21e14 100644 --- a/src/mainx.c +++ b/src/mainx.c @@ -112,10 +112,10 @@ int main(int argc, char *argv[], char *env[]) { memset(&evenths, 0, sizeof(xcb_event_handlers_t)); memset(&prophs, 0, sizeof(xcb_property_handlers_t)); - load_configuration(override_configpath); - conn = xcb_connect(NULL, &screens); + load_configuration(conn, override_configpath); + /* Place requests for the atoms we need as soon as possible */ #define REQUEST_ATOM(name) atom_cookies[name] = xcb_intern_atom(conn, 0, strlen(#name), #name); -- 2.39.5