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.
This commit is contained in:
Michael Stapelberg 2009-06-01 15:14:45 +02:00
parent 1fcad44f66
commit 2a67630aa6
5 changed files with 53 additions and 70 deletions

View File

@ -19,9 +19,9 @@ typedef struct Config Config;
extern Config config; extern Config config;
struct Colortriple { struct Colortriple {
char border[8]; uint32_t border;
char background[8]; uint32_t background;
char text[8]; uint32_t text;
}; };
struct Config { struct Config {
@ -47,6 +47,6 @@ struct Config {
* configuration file. * configuration file.
* *
*/ */
void load_configuration(const char *override_configfile); void load_configuration(xcb_connection_t *conn, const char *override_configfile);
#endif #endif

View File

@ -17,6 +17,7 @@
#include "i3.h" #include "i3.h"
#include "util.h" #include "util.h"
#include "config.h" #include "config.h"
#include "xcb.h"
Config config; Config config;
@ -41,7 +42,7 @@ static char *glob_path(const char *path) {
* configuration file. * configuration file.
* *
*/ */
void load_configuration(const char *override_configpath) { void load_configuration(xcb_connection_t *conn, const char *override_configpath) {
#define OPTION_STRING(name) \ #define OPTION_STRING(name) \
if (strcasecmp(key, #name) == 0) { \ if (strcasecmp(key, #name) == 0) { \
config.name = sstrdup(value); \ config.name = sstrdup(value); \
@ -54,16 +55,20 @@ void load_configuration(const char *override_configpath) {
#define OPTION_COLORTRIPLE(opt, name) \ #define OPTION_COLORTRIPLE(opt, name) \
if (strcasecmp(key, opt) == 0) { \ if (strcasecmp(key, opt) == 0) { \
struct Colortriple buffer; \ char border[8], background[8], text[8]; \
memset(&buffer, 0, sizeof(struct Colortriple)); \ memset(border, 0, sizeof(border)); \
buffer.border[0] = buffer.background[0] = buffer.text[0] = '#'; \ 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]", \ 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 || \ border + 1, background + 1, text + 1) != 3 || \
strlen(buffer.border) != 7 || \ strlen(border) != 7 || \
strlen(buffer.background) != 7 || \ strlen(background) != 7 || \
strlen(buffer.text) != 7) \ strlen(text) != 7) \
die("invalid color code line: %s\n", value); \ 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; \ continue; \
} }
@ -71,25 +76,25 @@ void load_configuration(const char *override_configpath) {
memset(&config, 0, sizeof(config)); memset(&config, 0, sizeof(config));
/* Initialize default colors */ /* Initialize default colors */
strcpy(config.client.focused.border, "#4c7899"); config.client.focused.border = get_colorpixel(conn, "#4c7899");
strcpy(config.client.focused.background, "#285577"); config.client.focused.background = get_colorpixel(conn, "#285577");
strcpy(config.client.focused.text, "#ffffff"); config.client.focused.text = get_colorpixel(conn, "#ffffff");
strcpy(config.client.focused_inactive.border, "#4c7899"); config.client.focused_inactive.border = get_colorpixel(conn, "#4c7899");
strcpy(config.client.focused_inactive.background, "#555555"); config.client.focused_inactive.background = get_colorpixel(conn, "#555555");
strcpy(config.client.focused_inactive.text, "#ffffff"); config.client.focused_inactive.text = get_colorpixel(conn, "#ffffff");
strcpy(config.client.unfocused.border, "#333333"); config.client.unfocused.border = get_colorpixel(conn, "#333333");
strcpy(config.client.unfocused.background, "#222222"); config.client.unfocused.background = get_colorpixel(conn, "#222222");
strcpy(config.client.unfocused.text, "#888888"); config.client.unfocused.text = get_colorpixel(conn, "#888888");
strcpy(config.bar.focused.border, "#4c7899"); config.bar.focused.border = get_colorpixel(conn, "#4c7899");
strcpy(config.bar.focused.background, "#285577"); config.bar.focused.background = get_colorpixel(conn, "#285577");
strcpy(config.bar.focused.text, "#ffffff"); config.bar.focused.text = get_colorpixel(conn, "#ffffff");
strcpy(config.bar.unfocused.border, "#333333"); config.bar.unfocused.border = get_colorpixel(conn, "#333333");
strcpy(config.bar.unfocused.background, "#222222"); config.bar.unfocused.background = get_colorpixel(conn, "#222222");
strcpy(config.bar.unfocused.text, "#888888"); config.bar.unfocused.text = get_colorpixel(conn, "#888888");
FILE *handle; FILE *handle;
if (override_configpath != NULL) { if (override_configpath != NULL) {

View File

@ -793,9 +793,9 @@ int handle_expose_event(void *data, xcb_connection_t *conn, xcb_expose_event_t *
uint32_t background_color; uint32_t background_color;
/* Distinguish if the window is currently focused… */ /* Distinguish if the window is currently focused… */
if (CUR_CELL->currently_focused == client) 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 */ /* …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 */ /* Set foreground color to current focused color, line width to 2 */
uint32_t values[] = {background_color, 2}; uint32_t values[] = {background_color, 2};

View File

@ -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) { 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); i3Font *font = load_font(conn, config.font);
int decoration_height = font->height + 2 + 2; int decoration_height = font->height + 2 + 2;
uint32_t background_color, struct Colortriple *color;
text_color,
border_color;
/* Clients without a container (docks) wont get decorated */ /* Clients without a container (docks) wont get decorated */
if (client->dock) 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) { if (client->floating >= FLOATING_AUTO_ON || client->container->currently_focused == client) {
/* Distinguish if the window is currently focused… */ /* Distinguish if the window is currently focused… */
if (client->floating >= FLOATING_AUTO_ON || CUR_CELL->currently_focused == client) 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 */ /* …or if it is the focused window in a not focused container */
else background_color = get_colorpixel(conn, config.client.focused_inactive.background); else color = &(config.client.focused_inactive);
} else color = &(config.client.unfocused);
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);
}
/* Our plan is the following: /* 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 two lines in a lighter color
- Draw the windows title - Draw the windows title
*/ */
/* Draw a rectangle in background color around the window */ /* 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 */ /* In stacking mode, we only render the rect for this specific decoration */
if (client->container != NULL && client->container->mode == MODE_STACK) { 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 */ /* Draw the lines */
xcb_draw_line(conn, drawable, gc, border_color, 0, offset, client->rect.width, offset); xcb_draw_line(conn, drawable, gc, color->border, 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, 2, offset + font->height + 3,
client->rect.width - 4, offset + font->height + 3); client->rect.width - 4, offset + font->height + 3);
/* If the client has a title, we draw it */ /* If the client has a title, we draw it */
if (client->name != NULL) { if (client->name != NULL) {
/* Draw the font */ /* Draw the font */
uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_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); xcb_change_gc(conn, gc, mask, values);
/* name_len == -1 means this is a legacy application which does not specify _NET_WM_NAME, /* 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); i3Font *font = load_font(conn, config.font);
i3Screen *screen = r_ws->screen; i3Screen *screen = r_ws->screen;
enum { SET_NORMAL = 0, SET_FOCUSED = 1 }; enum { SET_NORMAL = 0, SET_FOCUSED = 1 };
uint32_t background_color[2],
text_color[2],
border_color[2],
black;
char label[3]; 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 */ /* 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_rectangle_t rect = {0, 0, width, height};
xcb_poly_fill_rectangle(conn, screen->bar, screen->bargc, 1, &rect); 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) if (workspaces[c].screen != screen)
continue; 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); 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); drawn * height + 1, 2, height - 4, height - 4);
snprintf(label, sizeof(label), "%d", c+1); 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_FOREGROUND, color->text);
xcb_change_gc_single(conn, screen->bargc, XCB_GC_BACKGROUND, background_color[set]); 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 */, xcb_image_text_8(conn, strlen(label), screen->bar, screen->bargc, drawn * height + 5 /* X */,
font->height + 1 /* Y = baseline of font */, label); font->height + 1 /* Y = baseline of font */, label);
drawn++; drawn++;

View File

@ -112,10 +112,10 @@ int main(int argc, char *argv[], char *env[]) {
memset(&evenths, 0, sizeof(xcb_event_handlers_t)); memset(&evenths, 0, sizeof(xcb_event_handlers_t));
memset(&prophs, 0, sizeof(xcb_property_handlers_t)); memset(&prophs, 0, sizeof(xcb_property_handlers_t));
load_configuration(override_configpath);
conn = xcb_connect(NULL, &screens); conn = xcb_connect(NULL, &screens);
load_configuration(conn, override_configpath);
/* Place requests for the atoms we need as soon as possible */ /* 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); #define REQUEST_ATOM(name) atom_cookies[name] = xcb_intern_atom(conn, 0, strlen(#name), #name);