X-Git-Url: https://git.draconx.ca/gitweb/rrace.git/blobdiff_plain/85522c518d168600f1a3038aebfdd87bc9b62c3d..f0704cba12e437bbe72744281af71ec19951db46:/t/ewmhicon.c diff --git a/t/ewmhicon.c b/t/ewmhicon.c index 2ce721c..755cf5d 100644 --- a/t/ewmhicon.c +++ b/t/ewmhicon.c @@ -23,10 +23,14 @@ #include #include #include +#include +#include #include #include #include "ewmhicon.h" +#include "icon.h" +#include "colour.h" #include "help.h" static const char *progname = "ewmhicon"; @@ -38,23 +42,30 @@ static const struct option lopts[] = { { 0 } }; +#define PASTE(a, b) a ## b +#define INDIR(a) a + #define S8TO16(x) ((x) * 0xfffful / 0xff) -#define RGB8(r, g, b) { \ - 0xff000000|(r ## ul)<<16|(g ## ul)<<8|(b ## ul), \ + +#define RGB8_(r, g, b) { \ + 0xff000000 | (r << 16) | (g << 8) | b, \ S8TO16(r), S8TO16(g), S8TO16(b) } +#define RGB8(r, g, b) RGB8_(0x ## r ## ul, 0x ## g ## ul, 0x ## b ## ul) + +#define COLOURTAB(n) { \ + INDIR(RGB8 PASTE(COLOUR ## n, _PRIMARY_RGB_)), \ + INDIR(RGB8 PASTE(COLOUR ## n, _DARK_RGB_)), \ + INDIR(RGB8 PASTE(COLOUR ## n, _LIGHT_RGB_)) } + static const XColor colours[7][3] = { { { 0xffff0000, 0xffff }, { 0xff00ff00, 0, 0xffff }, { 0xff0000ff, 0, 0, 0xffff } }, - { RGB8(0x8d,0x2e,0x28), RGB8(0x6a,0x1b,0x17), RGB8(0xa1,0x48,0x42) }, - { RGB8(0xb4,0x6e,0x28), RGB8(0x92,0x4a,0x16), RGB8(0xc7,0x90,0x4f) }, - { RGB8(0xd8,0xb7,0x40), RGB8(0xc5,0x9f,0x39), RGB8(0xe2,0xc6,0x5d) }, - { RGB8(0x28,0x64,0x28), RGB8(0x19,0x47,0x19), RGB8(0x4e,0x87,0x4e) }, - { RGB8(0x00,0x34,0x71), RGB8(0x00,0x1f,0x4f), RGB8(0x00,0x52,0x8b) }, - { RGB8(0xdc,0xdc,0xdc), RGB8(0xc0,0xc0,0xc0), RGB8(0xea,0xea,0xea) } + COLOURTAB(0), COLOURTAB(1), COLOURTAB(2), + COLOURTAB(3), COLOURTAB(4), COLOURTAB(5) }; static void print_usage(FILE *f) @@ -89,51 +100,12 @@ static void print_version(void) puts("There is NO WARRANTY, to the extent permitted by law."); } -static const char sizes[][6] = { - "16x16", "24x24", "32x32", "48x48" -}; - -static int to_size_enum(const char *arg) -{ - char buf[8]; - unsigned i; - - if (!strchr(arg, 'x')) { - sprintf(buf, "%.3sx%.3s", arg, arg); - arg = buf; - } - - for (i = 0; i < sizeof sizes / sizeof sizes[0]; i++) { - if (!strcmp(arg, sizes[i])) - return i; - } - - return -1; -} - -static void gen_icon(int size, const char *colourseq) +static void +print_xpm(const char *colourseq, unsigned long size, unsigned long *icon_buf) { - void (*tilefunc)(unsigned long *, const XColor *, int, int); - static unsigned long icon_buf[48*48]; const char colourchars[21] = ".%+"",Rr""-Oo""'Yy"":Gg"";Bb"" Ww"; - unsigned i, j, x, y, w, h, n; - - switch (size) { - case ICON_16x16: tilefunc = ewmh_tile16; w = h = 16; break; - case ICON_24x24: tilefunc = ewmh_tile24; w = h = 24; break; - case ICON_32x32: tilefunc = ewmh_tile32; w = h = 32; break; - case ICON_48x48: tilefunc = ewmh_tile48; w = h = 48; break; - default: assert(0); - } - - for (i = 0; i < 9; i++) { - const XColor *c; - - assert(colourseq[i] >= '0' && colourseq[i] <= '6'); - c = colours[colourseq[i]-'0']; - - tilefunc(icon_buf, c, i%3, i/3); - } + unsigned w = size & 0xffff, h = (size >> 16) & 0xffff; + unsigned x, y, i, j, n; n = 7; for (i = 0; i < 7; i++) @@ -172,7 +144,7 @@ static void gen_icon(int size, const char *colourseq) printf("};\n"); } -int decode_colourseq(char *out, const char *arg) +static int decode_colourseq(char *out, const char *arg) { int i; @@ -201,10 +173,94 @@ err: return 0; } +/* Convert the user sequence into a list of colour index specifiers */ +static unsigned long *expand_seq(unsigned long *out, const char *seq) +{ + int i; + + for (i = 0; i < 9; i++) { + out[i] = 0x30303 * (seq[i]-'0') + 0x20100; + } + + return out; +} + +static unsigned long decode_size(char *size_spec) +{ + unsigned long w, h; + char c = 0; + size_t n; + + n = strspn(size_spec, "0123456789"); + switch (size_spec[n]) { + default: + goto err_invalid; + case 0: case 'x': case 'X': + c = size_spec[n]; + size_spec[n] = 0; + } + + w = strtoul(size_spec, NULL, 10); + size_spec[n] = c; + if (w > 0xffff) + goto err_range; + + if (!c) { + h = w; + } else { + n = strspn(size_spec += n+1, "0123456789"); + if (size_spec[n]) + goto err_invalid; + + h = strtoul(size_spec, NULL, 10); + if (h > 0xffff) + goto err_range; + } + + return (h << 16) | w; +err_range: + fprintf(stderr, "%s: %s: %s\n", progname, size_spec, strerror(ERANGE)); + return 0; +err_invalid: + fprintf(stderr, "%s: %s: %s\n", progname, size_spec, + "invalid size specification"); + return 0; +} + +static unsigned long *find_icon(unsigned long size, unsigned long *ewmhicon) +{ + unsigned long w = size & 0xffff, h = (size >> 16) & 0xffff; + unsigned long i; + + if (!size) + return NULL; + + for (i = 0; i < EWMH_ICON_NELEM-2;) { + unsigned long icon_w = ewmhicon[i]; + unsigned long icon_h = ewmhicon[i+1]; + + if (w == icon_w && h == icon_h) { + i += 2; + break; + } + + assert(icon_w < ULONG_MAX / icon_h); + assert(i < ULONG_MAX - icon_w*icon_h); + i += 2 + icon_w*icon_h; + } + + if (i < EWMH_ICON_NELEM) + return &ewmhicon[i]; + + fprintf(stderr, "%s: error: no %lux%lu icon found\n", progname, w, h); + return NULL; +} + int main(int argc, char **argv) { - char colourseq[9] = "000000000"; - int opt, size; + unsigned long *ewmhicon, *icon, size, buf[9]; + char colourseq[10] = "000000000"; + int opt; if (argc > 0) progname = argv[0]; @@ -233,13 +289,22 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - size = to_size_enum(argv[optind]); - if (size < 0) { - printf("%s: error: invalid size %s\n", progname, argv[optind]); - print_usage(stderr); + size = decode_size(argv[optind]); + if (!size) + return EXIT_FAILURE; + + ewmhicon = ewmh_icon_generate(expand_seq(buf, colourseq), colours[0]); + if (!ewmhicon) { + fprintf(stderr, "%s: failed to allocate memory\n", progname); return EXIT_FAILURE; } - gen_icon(size, colourseq); + icon = find_icon(size, ewmhicon); + if (!icon) + return EXIT_FAILURE; + + print_xpm(colourseq, size, icon); + + free(ewmhicon); return 0; }