commit df29e05e70872729933cba8ce2f5038dcabb1b29 from: Omar Polo date: Wed Oct 17 13:49:36 2018 UTC Added padding, border size and border color to prompt and completions* commit - 37dbf9ce24169baeb00227fcb3aa075074a89e29 commit + df29e05e70872729933cba8ce2f5038dcabb1b29 blob - c84331472c5aac7a0572744e471fdb8f42cccfb9 blob + 1f38aba52acfe5caee0cb5019f478e77020c06e3 --- mymenu.c +++ mymenu.c @@ -39,7 +39,7 @@ # define default_fontname "fixed" #endif -#define ARGS "Aahmve:p:P:l:f:W:H:x:y:b:B:t:T:c:C:s:S:d:" +#define ARGS "Aahmve:p:P:l:f:W:H:x:y:b:B:t:T:c:C:s:S:d:G:g:I:i:J:j:" #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -78,7 +78,7 @@ enum state {LOOPING, OK_LOOP, OK, ERR}; * For the drawing-related function. The text to be rendere could be * the prompt, a completion or a highlighted completion */ -enum text_type {PROMPT, COMPL, COMPL_HIGH}; +enum obj_type {PROMPT, COMPL, COMPL_HIGH}; /* These are the possible action to be performed after user input. */ enum action { @@ -101,7 +101,9 @@ struct rendering { Window w; int width; int height; - int padding; + int p_padding[4]; + int c_padding[4]; + int ch_padding[4]; int x_zero; /* the "zero" on the x axis (may not be exactly 0 'cause the borders) */ int y_zero; /* like x_zero but for the y axis */ @@ -113,6 +115,9 @@ struct rendering { /* four border width */ int borders[4]; + int p_borders[4]; + int c_borders[4]; + int ch_borders[4]; short horizontal_layout; @@ -122,12 +127,17 @@ struct rendering { int ps1w; /* ps1 width */ int ps1h; /* ps1 height */ + int text_height; /* cache for the vertical layout */ + XIC xic; /* colors */ GC fgs[4]; GC bgs[4]; GC borders_bg[4]; + GC p_borders_bg[4]; + GC c_borders_bg[4]; + GC ch_borders_bg[4]; #ifdef USE_XFT XftFont *font; XftDraw *xftdraw; @@ -521,7 +531,7 @@ text_extents(char *str, int len, struct rendering *r, } void -draw_string(char *str, int len, int x, int y, struct rendering *r, enum text_type tt) +draw_string(char *str, int len, int x, int y, struct rendering *r, enum obj_type tt) { #ifdef USE_XFT XftColor xftcolor; @@ -561,58 +571,165 @@ strdupn(char *str) return dup; } -/* ,-----------------------------------------------------------------, */ -/* | 20 char text | completion | completion | completion | compl | */ -/* `-----------------------------------------------------------------' */ -void -draw_horizontally(struct rendering *r, char *text, struct completions *cs) +int +draw_v_box(struct rendering *r, int y, char *prefix, int prefix_width, enum obj_type t, char *text) { - size_t i; - int prompt_width, start_at; - int texty, textlen; + GC *border_color, bg; + int *padding, *borders; + int ret = 0, inner_width, inner_height, x; - prompt_width = 20; /* TODO: calculate the correct amount of char to show */ - - start_at = r->x_zero + text_extents("n", 1, r, NULL, NULL); - start_at *= prompt_width; - start_at += r->padding; - - texty = (inner_height(r) + r->ps1h + r->y_zero) / 2; + switch (t) { + case PROMPT: + border_color = r->p_borders_bg; + padding = r->p_padding; + borders = r->p_borders; + bg = r->bgs[0]; + break; + case COMPL: + border_color = r->c_borders_bg; + padding = r->c_padding; + borders = r->c_borders; + bg = r->bgs[1]; + break; + case COMPL_HIGH: + border_color = r->ch_borders_bg; + padding = r->ch_padding; + borders = r->ch_borders; + bg = r->bgs[2]; + break; + } - XFillRectangle(r->d, r->w, r->bgs[0], r->x_zero, r->y_zero, start_at, inner_height(r)); + ret = borders[0] + padding[0] + r->text_height + padding[2] + borders[2]; - textlen = strlen(text); - if (textlen > prompt_width) - text = text + textlen - prompt_width; + inner_width = inner_width(r) - borders[1] - borders[3]; + inner_height = padding[0] + r->text_height + padding[2]; - draw_string(r->ps1, r->ps1len, r->x_zero + r->padding, texty, r, PROMPT); - draw_string(text, MIN(textlen, prompt_width), r->x_zero + r->padding + r->ps1w, texty, r, PROMPT); + /* Border top */ + XFillRectangle(r->d, r->w, border_color[0], r->x_zero, y, r->width, borders[0]); - XFillRectangle(r->d, r->w, r->bgs[1], start_at, r->y_zero, r->width, inner_height(r)); + /* Border right */ + XFillRectangle(r->d, r->w, border_color[1], r->x_zero + inner_width(r) - borders[1] , y, borders[1], ret); + + /* Border bottom */ + XFillRectangle(r->d, r->w, border_color[2], r->x_zero, y + borders[0] + padding[0] + r->text_height + padding[2], r->width, borders[2]); - for (i = r->offset; i < cs->length; ++i) { - struct completion *c; - enum text_type tt; - GC h; - int len, text_width; + /* Border left */ + XFillRectangle(r->d, r->w, border_color[3], r->x_zero, y, borders[3], ret); - c = &cs->completions[i]; - tt = cs->selected == (ssize_t)i ? COMPL_HIGH : COMPL; - h = cs->selected == (ssize_t)i ? r->bgs[2] : r->bgs[1]; - len = strlen(c->completion); - text_width = text_extents(c->completion, len, r, NULL, NULL); + /* bg */ + x = r->x_zero + borders[3]; + y += borders[0]; + XFillRectangle(r->d, r->w, bg, x, y, inner_width, inner_height); - XFillRectangle(r->d, r->w, h, start_at, r->y_zero, text_width + r->padding*2, inner_height(r)); - draw_string(c->completion, len, start_at + r->padding, texty, r, tt); + /* content */ + y += padding[0] + r->text_height; + x += padding[3]; + if (prefix != NULL) { + draw_string(prefix, strlen(prefix), x, y, r, t); + x += prefix_width; + } + draw_string(text, strlen(text), x, y, r, t); - start_at += text_width + r->padding * 2; + return ret; +} - if (start_at > inner_width(r)) - break; /* don't draw completion out of the window */ +int +draw_h_box(struct rendering *r, int x, char *prefix, int prefix_width, enum obj_type t, char *text) +{ + GC *border_color, bg; + int *padding, *borders; + int ret = 0, inner_width, inner_height, y, text_width; + + switch (t) { + case PROMPT: + border_color = r->p_borders_bg; + padding = r->p_padding; + borders = r->p_borders; + bg = r->bgs[0]; + break; + case COMPL: + border_color = r->c_borders_bg; + padding = r->c_padding; + borders = r->c_borders; + bg = r->bgs[1]; + break; + case COMPL_HIGH: + border_color = r->ch_borders_bg; + padding = r->ch_padding; + borders = r->ch_borders; + bg = r->bgs[2]; + break; + } + + if (padding[0] < 0 || padding[2] < 0) + padding[0] = padding[2] = (inner_height(r) - borders[0] - borders[2] - r->text_height)/2; + + /* If they are still lesser than 0, set 'em to 0 */ + if (padding[0] < 0 || padding[2] < 0) + padding[0] = padding[2] = 0; + + /* Get the text width */ + text_extents(text, strlen(text), r, &text_width, NULL); + if (prefix != NULL) + text_width += prefix_width; + + ret = borders[3] + padding[3] + text_width + padding[1] + borders[1]; + + inner_width = padding[3] + text_width + padding[1]; + inner_height = inner_height(r) - borders[0] - borders[2]; + + /* Border top */ + XFillRectangle(r->d, r->w, border_color[0], x, r->y_zero, ret, borders[0]); + + /* Border right */ + XFillRectangle(r->d, r->w, border_color[1], x + borders[3] + inner_width, r->y_zero, borders[1], inner_height(r)); + + /* Border bottom */ + XFillRectangle(r->d, r->w, border_color[2], x, r->y_zero + inner_height(r) - borders[2], ret, borders[2]); + + /* Border left */ + XFillRectangle(r->d, r->w, border_color[3], x, r->y_zero, borders[3], inner_height(r)); + + /* bg */ + x += borders[3]; + y = r->y_zero + borders[0]; + XFillRectangle(r->d, r->w, bg, x, y, inner_width, inner_height); + + /* content */ + y += padding[0] + r->text_height; + x += padding[3]; + if (prefix != NULL) { + draw_string(prefix, strlen(prefix), x, y, r, t); + x += prefix_width; } + draw_string(text, strlen(text), x, y, r, t); + + return ret; } /* ,-----------------------------------------------------------------, */ +/* | 20 char text | completion | completion | completion | compl | */ +/* `-----------------------------------------------------------------' */ +void +draw_horizontally(struct rendering *r, char *text, struct completions *cs) +{ + size_t i; + int x = r->x_zero; + + /* Draw the prompt */ + x += draw_h_box(r, x, r->ps1, r->ps1w, PROMPT, text); + + for (i = r->offset; i < cs->length; ++i) { + enum obj_type t = cs->selected == (ssize_t)i ? COMPL_HIGH : COMPL; + + x += draw_h_box(r, x, NULL, 0, t, cs->completions[i].completion); + + if (x > inner_width(r)) + break; + } +} + +/* ,-----------------------------------------------------------------, */ /* | prompt | */ /* |-----------------------------------------------------------------| */ /* | completion | */ @@ -623,43 +740,27 @@ void draw_vertically(struct rendering *r, char *text, struct completions *cs) { size_t i; - int height, start_at; - - text_extents("fjpgl", 5, r, NULL, &height); - start_at = r->padding * 2 + height; + int y = r->y_zero; - XFillRectangle(r->d, r->w, r->bgs[1], r->x_zero, r->y_zero, r->width, r->height); - XFillRectangle(r->d, r->w, r->bgs[0], r->x_zero, r->y_zero, r->width, start_at); + y += draw_v_box(r, y, r->ps1, r->ps1w, PROMPT, text); - draw_string(r->ps1, r->ps1len, r->x_zero + r->padding, r->y_zero + height + r->padding, r, PROMPT); - draw_string(text, strlen(text), r->x_zero + r->padding + r->ps1w, r->y_zero + height + r->padding, r, PROMPT); - - start_at += r->y_zero; - for (i = r->offset; i < cs->length; ++i) { - struct completion *c; - enum text_type tt; - GC h; - int len; + enum obj_type t = cs->selected == (ssize_t)i ? COMPL_HIGH : COMPL; - c = &cs->completions[i]; - tt = cs->selected == (ssize_t)i ? COMPL_HIGH : COMPL; - h = cs->selected == (ssize_t)i ? r->bgs[2] : r->bgs[1]; - len = strlen(c->completion); + y += draw_v_box(r, y, NULL, 0, t, cs->completions[i].completion); - XFillRectangle(r->d, r->w, h, r->x_zero, start_at, inner_width(r), height + r->padding*2); - draw_string(c->completion, len, r->x_zero + r->padding, start_at + height + r->padding, r, tt); - - start_at += height + r->padding * 2; - - if (start_at > inner_height(r)) - break; /* don't draw completion out of the window */ + if (y > inner_height(r)) + break; } } void draw(struct rendering *r, char *text, struct completions *cs) { + /* Draw the background */ + XFillRectangle(r->d, r->w, r->bgs[1], r->x_zero, r->y_zero, inner_width(r), inner_height(r)); + + /* Draw the contents */ if (r->horizontal_layout) draw_horizontally(r, text, cs); else @@ -1310,10 +1411,12 @@ ps1extents(struct rendering *r) void usage(char *prgname) { - fprintf(stderr, "%s [-Aamvh] [-B colors] [-b borders] [-C color] [-c color]\n" - " [-d separator] [-e window] [-f font] [-H height] [-l layout]\n" - " [-P padding] [-p prompt] [-T color] [-t color] [-S color]\n" - " [-s color] [-W width] [-x coord] [-y coord]\n", prgname); + fprintf(stderr, + "%s [-Aahmv] [-B colors] [-b size] [-C color] [-c color]\n" + " [-d separator] [-e window] [-f font] [-G color] [-g size]\n" + " [-H height] [-I color] [-i size] [-J color] [-j size] [-l layout]\n" + " [-P padding] [-p prompt] [-S color] [-s color] [-T color]\n" + " [-t color] [-W width] [-x coord] [-y coord]\n", prgname); } int @@ -1327,7 +1430,7 @@ main(int argc, char **argv) Window parent_window; XrmDatabase xdb; unsigned long fgs[3], bgs[3]; /* prompt, compl, compl_highlighted */ - unsigned long borders_bg[4]; /* N E S W */ + unsigned long borders_bg[4], p_borders_bg[4], c_borders_bg[4], ch_borders_bg[4]; /* N E S W */ enum state status; int ch; int offset_x, offset_y, x, y; @@ -1413,11 +1516,18 @@ main(int argc, char **argv) /* default position on the screen */ x = y = 0; - /* default padding */ - r.padding = 10; + for (i = 0; i < 4; ++i) { + /* default paddings */ + r.p_padding[i] = 10; + r.c_padding[i] = 10; + r.ch_padding[i] = 10; - /* default borders */ - r.borders[0] = r.borders[1] = r.borders[2] = r.borders[3] = 0; + /* default borders */ + r.borders[i] = 0; + r.p_borders[i] = 0; + r.c_borders[i] = 0; + r.ch_borders[i] = 0; + } /* the prompt. We duplicate the string so later is easy to * free (in the case it's been overwritten by the user) */ @@ -1505,6 +1615,10 @@ main(int argc, char **argv) borders_bg[0] = borders_bg[1] = borders_bg[2] = borders_bg[3] = parse_color("#000", NULL); + p_borders_bg[0] = p_borders_bg[1] = p_borders_bg[2] = p_borders_bg[3] = parse_color("#000", NULL); + c_borders_bg[0] = c_borders_bg[1] = c_borders_bg[2] = c_borders_bg[3] = parse_color("#000", NULL); + ch_borders_bg[0] = ch_borders_bg[1] = ch_borders_bg[2] = ch_borders_bg[3] = parse_color("#000", NULL); + r.horizontal_layout = 1; /* Read the resources */ @@ -1537,6 +1651,36 @@ main(int argc, char **argv) fprintf(stderr, "no prompt defined, using \"%s\" as default\n", r.ps1); } + if (XrmGetResource(xdb, "MyMenu.prompt.border.size", "*", datatype, &value) == 1) { + char **sizes; + sizes = parse_csslike(value.addr); + if (sizes != NULL) + for (i = 0; i < 4; ++i) + r.p_borders[i] = parse_integer(sizes[i], 0); + else + fprintf(stderr, "error while parsing MyMenu.prompt.border.size"); + } + + if (XrmGetResource(xdb, "MyMenu.prompt.border.color", "*", datatype, &value) == 1) { + char **colors; + colors = parse_csslike(value.addr); + if (colors != NULL) + for (i = 0; i < 4; ++i) + p_borders_bg[i] = parse_color(colors[i], "#000"); + else + fprintf(stderr, "error while parsing MyMenu.prompt.border.color"); + } + + if (XrmGetResource(xdb, "MyMenu.prompt.padding", "*", datatype, &value) == 1) { + char **colors; + colors = parse_csslike(value.addr); + if (colors != NULL) + for (i = 0; i < 4; ++i) + r.p_padding[i] = parse_integer(colors[i], 0); + else + fprintf(stderr, "error while parsing MyMenu.prompt.padding"); + } + if (XrmGetResource(xdb, "MyMenu.width", "*", datatype, &value) == 1) r.width = parse_int_with_percentage(value.addr, r.width, d_width); else @@ -1549,32 +1693,19 @@ main(int argc, char **argv) if (XrmGetResource(xdb, "MyMenu.x", "*", datatype, &value) == 1) x = parse_int_with_pos(value.addr, x, d_width, r.width); - else - fprintf(stderr, "no x defined, using %d\n", x); if (XrmGetResource(xdb, "MyMenu.y", "*", datatype, &value) == 1) y = parse_int_with_pos(value.addr, y, d_height, r.height); - else - fprintf(stderr, "no y defined, using %d\n", y); - if (XrmGetResource(xdb, "MyMenu.padding", "*", datatype, &value) == 1) - r.padding = parse_integer(value.addr, r.padding); - else - fprintf(stderr, "no padding defined, using %d\n", r.padding); - if (XrmGetResource(xdb, "MyMenu.border.size", "*", datatype, &value) == 1) { char **borders; - borders = parse_csslike(value.addr); - if (borders != NULL) { - r.borders[0] = parse_integer(borders[0], 0); - r.borders[1] = parse_integer(borders[1], 0); - r.borders[2] = parse_integer(borders[2], 0); - r.borders[3] = parse_integer(borders[3], 0); - } else + if (borders != NULL) + for (i = 0; i < 4; ++i) + r.borders[i] = parse_int_with_percentage(borders[i], 0, (i % 2) == 0 ? r.height : r.width); + else fprintf(stderr, "error while parsing MyMenu.border.size\n"); - } else - fprintf(stderr, "no border defined, using 0.\n"); + } /* Prompt */ if (XrmGetResource(xdb, "MyMenu.prompt.foreground", "*", datatype, &value) == 1) @@ -1590,6 +1721,36 @@ main(int argc, char **argv) if (XrmGetResource(xdb, "MyMenu.completion.background", "*", datatype, &value) == 1) bgs[1] = parse_color(value.addr, "#000"); + if (XrmGetResource(xdb, "MyMenu.completion.padding", "*", datatype, &value) == 1) { + char **paddings; + paddings = parse_csslike(value.addr); + if (paddings != NULL) + for (i = 0; i < 4; ++i) + r.c_padding[i] = parse_integer(paddings[i], 0); + else + fprintf(stderr, "Error while parsing MyMenu.completion.padding"); + } + + if (XrmGetResource(xdb, "MyMenu.completion.border.size", "*", datatype, &value) == 1) { + char **sizes; + sizes = parse_csslike(value.addr); + if (sizes != NULL) + for (i = 0; i < 4; ++i) + r.c_borders[i] = parse_integer(sizes[i], 0); + else + fprintf(stderr, "Error while parsing MyMenu.completion.border.size"); + } + + if (XrmGetResource(xdb, "MyMenu.completion.border.color", "*", datatype, &value) == 1) { + char **sizes; + sizes = parse_csslike(value.addr); + if (sizes != NULL) + for (i = 0; i < 4; ++i) + c_borders_bg[i] = parse_color(sizes[i], "#000"); + else + fprintf(stderr, "Error while parsing MyMenu.completion.border.color"); + } + /* Completion Highlighted */ if (XrmGetResource(xdb, "MyMenu.completion_highlighted.foreground", "*", datatype, &value) == 1) fgs[2] = parse_color(value.addr, "#000"); @@ -1597,16 +1758,44 @@ main(int argc, char **argv) if (XrmGetResource(xdb, "MyMenu.completion_highlighted.background", "*", datatype, &value) == 1) bgs[2] = parse_color(value.addr, "#fff"); + if (XrmGetResource(xdb, "MyMenu.completion_highlighted.padding", "*", datatype, &value) == 1) { + char **paddings; + paddings = parse_csslike(value.addr); + if (paddings != NULL) + for (i = 0; i < 4; ++i) + r.ch_padding[i] = parse_integer(paddings[i], 0); + else + fprintf(stderr, "Error while parsing MyMenu.completion_highlighted.padding"); + } + + if (XrmGetResource(xdb, "MyMenu.completion_highlighted.border.size", "*", datatype, &value) == 1) { + char **sizes; + sizes = parse_csslike(value.addr); + if (sizes != NULL) + for (i = 0; i < 4; ++i) + r.ch_borders[i] = parse_integer(sizes[i], 0); + else + fprintf(stderr, "Error while parsing MyMenu.completion_highlighted.border.size"); + } + + if (XrmGetResource(xdb, "MyMenu.completion_highlighted.border.color", "*", datatype, &value) == 1) { + char **colors; + colors = parse_csslike(value.addr); + if (colors != NULL) + for (i = 0; i < 4; ++i) + ch_borders_bg[i] = parse_color(colors[i], "#000"); + else + fprintf(stderr, "Error while parsing MyMenu.completion_highlighted.border.color"); + } + /* Border */ if (XrmGetResource(xdb, "MyMenu.border.color", "*", datatype, &value) == 1) { char **colors; colors = parse_csslike(value.addr); - if (colors != NULL) { - borders_bg[0] = parse_color(colors[0], "#000"); - borders_bg[1] = parse_color(colors[1], "#000"); - borders_bg[2] = parse_color(colors[2], "#000"); - borders_bg[3] = parse_color(colors[3], "#000"); - } else + if (colors != NULL) + for (i = 0; i < 4; ++i) + borders_bg[i] = parse_color(colors[i], "#000"); + else fprintf(stderr, "error while parsing MyMenu.border.color\n"); } } @@ -1642,9 +1831,55 @@ main(int argc, char **argv) case 'y': y = parse_int_with_pos(optarg, y, d_height, r.height); break; - case 'P': - r.padding = parse_integer(optarg, r.padding); + case 'P': { + char **paddings; + if ((paddings = parse_csslike(optarg)) != NULL) + for (i = 0; i < 4; ++i) + r.p_padding[i] = parse_integer(paddings[i], 0); break; + } + case 'G': { + char **colors; + if ((colors = parse_csslike(optarg)) != NULL) + for (i = 0; i < 4; ++i) + p_borders_bg[i] = parse_color(colors[i], "#000"); + break; + } + case 'g': { + char **sizes; + if ((sizes = parse_csslike(optarg)) != NULL) + for (i = 0; i < 4; ++i) + r.p_borders[i] = parse_integer(sizes[i], 0); + break; + } + case 'I': { + char **colors; + if ((colors = parse_csslike(optarg)) != NULL) + for (i = 0; i < 4; ++i) + c_borders_bg[i] = parse_color(colors[i], "#000"); + break; + } + case 'i': { + char **sizes; + if ((sizes = parse_csslike(optarg)) != NULL) + for (i = 0; i < 4; ++i) + r.c_borders[i] = parse_integer(sizes[i], 0); + break; + } + case 'J': { + char **colors; + if ((colors = parse_csslike(optarg)) != NULL) + for (i = 0; i < 4; ++i) + ch_borders_bg[i] = parse_color(colors[i], "#000"); + break; + } + case 'j': { + char **sizes; + if ((sizes = parse_csslike(optarg)) != NULL) + for (i = 0; i < 4; ++i) + r.ch_borders[i] = parse_integer(sizes[i], 0); + break; + } case 'l': r.horizontal_layout = !strcmp(optarg, "horizontal"); break; @@ -1665,10 +1900,8 @@ main(int argc, char **argv) case 'b': { char **borders; if ((borders = parse_csslike(optarg)) != NULL) { - r.borders[0] = parse_integer(borders[0], 0); - r.borders[1] = parse_integer(borders[1], 0); - r.borders[2] = parse_integer(borders[2], 0); - r.borders[3] = parse_integer(borders[3], 0); + for (i = 0; i < 4; ++i) + r.borders[i] = parse_integer(borders[i], 0); } else fprintf(stderr, "Error parsing b option\n"); break; @@ -1676,10 +1909,8 @@ main(int argc, char **argv) case 'B': { char **colors; if ((colors = parse_csslike(optarg)) != NULL) { - borders_bg[0] = parse_color(colors[0], "#000"); - borders_bg[1] = parse_color(colors[1], "#000"); - borders_bg[2] = parse_color(colors[2], "#000"); - borders_bg[3] = parse_color(colors[3], "#000"); + for (i = 0; i < 4; ++i) + borders_bg[i] = parse_color(colors[i], "#000"); } else fprintf(stderr, "error while parsing B option\n"); break; @@ -1709,6 +1940,11 @@ main(int argc, char **argv) } } + if (r.height < 0 || r.width < 0 || x < 0 || y < 0) { + fprintf(stderr, "height, width, x or y are lesser than 0."); + status = ERR; + } + /* since only now we know if the first should be selected, * update the completion here */ update_completions(cs, text, lines, vlines, r.first_selected); @@ -1744,23 +1980,37 @@ main(int argc, char **argv) { XGCValues values; - r.fgs[0] = XCreateGC(r.d, r.w, 0, &values), - r.fgs[1] = XCreateGC(r.d, r.w, 0, &values), - r.fgs[2] = XCreateGC(r.d, r.w, 0, &values), - r.bgs[0] = XCreateGC(r.d, r.w, 0, &values), - r.bgs[1] = XCreateGC(r.d, r.w, 0, &values), - r.bgs[2] = XCreateGC(r.d, r.w, 0, &values), - r.borders_bg[0] = XCreateGC(r.d, r.w, 0, &values); - r.borders_bg[1] = XCreateGC(r.d, r.w, 0, &values); - r.borders_bg[2] = XCreateGC(r.d, r.w, 0, &values); - r.borders_bg[3] = XCreateGC(r.d, r.w, 0, &values); + for (i = 0; i < 3; ++i) { + r.fgs[i] = XCreateGC(r.d, r.w, 0, &values); + r.bgs[i] = XCreateGC(r.d, r.w, 0, &values); + } + + for (i = 0; i < 4; ++i) { + r.borders_bg[i] = XCreateGC(r.d, r.w, 0, &values); + r.p_borders_bg[i] = XCreateGC(r.d, r.w, 0, &values); + r.c_borders_bg[i] = XCreateGC(r.d, r.w, 0, &values); + r.ch_borders_bg[i] = XCreateGC(r.d, r.w, 0, &values); + } } + /* Load the colors in our GCs */ + for (i = 0; i < 3; ++i) { + XSetForeground(r.d, r.fgs[i], fgs[i]); + XSetForeground(r.d, r.bgs[i], bgs[i]); + } + + for (i = 0; i < 4; ++i) { + XSetForeground(r.d, r.borders_bg[i], borders_bg[i]); + XSetForeground(r.d, r.p_borders_bg[i], p_borders_bg[i]); + XSetForeground(r.d, r.c_borders_bg[i], c_borders_bg[i]); + XSetForeground(r.d, r.ch_borders_bg[i], ch_borders_bg[i]); + } + if (load_font(&r, fontname) == -1) status = ERR; #ifdef USE_XFT - r.xftdraw = XftDrawCreate(r.d, r.w, vinfo.visual, DefaultColormap(r.d, 0)); + r.xftdraw = XftDrawCreate(r.d, r.w, vinfo.visual, cmap); { rgba_t c; @@ -1792,18 +2042,6 @@ main(int argc, char **argv) } #endif - /* Load the colors in our GCs */ - XSetForeground(r.d, r.fgs[0], fgs[0]); - XSetForeground(r.d, r.bgs[0], bgs[0]); - XSetForeground(r.d, r.fgs[1], fgs[1]); - XSetForeground(r.d, r.bgs[1], bgs[1]); - XSetForeground(r.d, r.fgs[2], fgs[2]); - XSetForeground(r.d, r.bgs[2], bgs[2]); - XSetForeground(r.d, r.borders_bg[0], borders_bg[0]); - XSetForeground(r.d, r.borders_bg[1], borders_bg[1]); - XSetForeground(r.d, r.borders_bg[2], borders_bg[2]); - XSetForeground(r.d, r.borders_bg[3], borders_bg[3]); - /* compute prompt dimensions */ ps1extents(&r); @@ -1814,6 +2052,9 @@ main(int argc, char **argv) pledge("stdio", ""); #endif + /* Cache text height */ + text_extents("fyjpgl", 6, &r, NULL, &r.text_height); + /* Draw the window for the first time */ draw(&r, text, cs);