diff options
author | Alexander Sedov <alex0player@gmail.com> | 2013-02-19 21:39:13 +0400 |
---|---|---|
committer | Christoph Lohmann <20h@r-36.net> | 2013-02-19 19:12:42 +0100 |
commit | 800800a3bba020f1e71e821b31c1ad037aab64ee (patch) | |
tree | 46c65e37d20ea832d3ceb425f0f5fb7b1203e422 | |
parent | 3865e9eaaf4e1c7820b1f41ce9d0b1d7b109fb26 (diff) | |
download | st-patched-800800a3bba020f1e71e821b31c1ad037aab64ee.tar.bz2 st-patched-800800a3bba020f1e71e821b31c1ad037aab64ee.tar.xz st-patched-800800a3bba020f1e71e821b31c1ad037aab64ee.zip |
Added basic xterm-ish palette swap support.
Signed-off-by: Christoph Lohmann <20h@r-36.net>
-rw-r--r-- | st.c | 111 |
1 files changed, 93 insertions, 18 deletions
@@ -302,6 +302,7 @@ static void execsh(void); | |||
302 | static void sigchld(int); | 302 | static void sigchld(int); |
303 | static void run(void); | 303 | static void run(void); |
304 | 304 | ||
305 | static inline int parse_int(char *); | ||
305 | static void csidump(void); | 306 | static void csidump(void); |
306 | static void csihandle(void); | 307 | static void csihandle(void); |
307 | static void csiparse(void); | 308 | static void csiparse(void); |
@@ -348,6 +349,7 @@ static void xclear(int, int, int, int); | |||
348 | static void xdrawcursor(void); | 349 | static void xdrawcursor(void); |
349 | static void xinit(void); | 350 | static void xinit(void); |
350 | static void xloadcols(void); | 351 | static void xloadcols(void); |
352 | static int xsetcolorname(int, const char *); | ||
351 | static int xloadfont(Font *, FcPattern *); | 353 | static int xloadfont(Font *, FcPattern *); |
352 | static void xloadfonts(char *, int); | 354 | static void xloadfonts(char *, int); |
353 | static void xresettitle(void); | 355 | static void xresettitle(void); |
@@ -1855,34 +1857,58 @@ csireset(void) { | |||
1855 | memset(&csiescseq, 0, sizeof(csiescseq)); | 1857 | memset(&csiescseq, 0, sizeof(csiescseq)); |
1856 | } | 1858 | } |
1857 | 1859 | ||
1860 | inline int | ||
1861 | parse_int(char *s) { | ||
1862 | int x = 0; | ||
1863 | char c; | ||
1864 | while(isdigit(c = *s)) { | ||
1865 | if((INT_MAX - c + '0') / 10 >= x) { | ||
1866 | x = x * 10 + c - '0'; | ||
1867 | } else | ||
1868 | return -1; | ||
1869 | s++; | ||
1870 | } | ||
1871 | if(*s != '\0') | ||
1872 | return -1; | ||
1873 | return x; | ||
1874 | } | ||
1875 | |||
1858 | void | 1876 | void |
1859 | strhandle(void) { | 1877 | strhandle(void) { |
1860 | char *p; | 1878 | char *p = NULL; |
1879 | int i, j; | ||
1880 | int narg; | ||
1861 | 1881 | ||
1862 | /* | 1882 | /* |
1863 | * TODO: make this being useful in case of color palette change. | 1883 | * TODO: make this being useful in case of color palette change. |
1864 | */ | 1884 | */ |
1865 | strparse(); | 1885 | strparse(); |
1866 | 1886 | narg = strescseq.narg; | |
1867 | p = strescseq.buf; | ||
1868 | 1887 | ||
1869 | switch(strescseq.type) { | 1888 | switch(strescseq.type) { |
1870 | case ']': /* OSC -- Operating System Command */ | 1889 | case ']': /* OSC -- Operating System Command */ |
1871 | switch(p[0]) { | 1890 | switch(i = parse_int(strescseq.args[0])) { |
1872 | case '0': | 1891 | case 0: |
1873 | case '1': | 1892 | case 1: |
1874 | case '2': | 1893 | case 2: |
1875 | /* | 1894 | /* |
1876 | * TODO: Handle special chars in string, like umlauts. | 1895 | * TODO: Handle special chars in string, like umlauts. |
1877 | */ | 1896 | */ |
1878 | if(p[1] == ';') { | 1897 | if(narg > 1) |
1879 | XStoreName(xw.dpy, xw.win, strescseq.buf+2); | 1898 | XStoreName(xw.dpy, xw.win, strescseq.args[2]); |
1880 | } | ||
1881 | break; | ||
1882 | case ';': | ||
1883 | XStoreName(xw.dpy, xw.win, strescseq.buf+1); | ||
1884 | break; | 1899 | break; |
1885 | case '4': /* TODO: Set color (arg0) to "rgb:%hexr/$hexg/$hexb" (arg1) */ | 1900 | case 4: /* color set */ |
1901 | if(narg < 3) | ||
1902 | break; | ||
1903 | p = strescseq.args[2]; | ||
1904 | /* fall through */ | ||
1905 | case 104: /* color reset, here p = NULL */ | ||
1906 | j = (narg > 1) ? parse_int(strescseq.args[1]) : -1; | ||
1907 | if (!xsetcolorname(j, p)) | ||
1908 | fprintf(stderr, "erresc: invalid color %s\n", p); | ||
1909 | else { | ||
1910 | redraw(0); /* TODO if defaultbg color is changed, borders are dirty */ | ||
1911 | } | ||
1886 | break; | 1912 | break; |
1887 | default: | 1913 | default: |
1888 | fprintf(stderr, "erresc: unknown str "); | 1914 | fprintf(stderr, "erresc: unknown str "); |
@@ -1910,7 +1936,19 @@ strparse(void) { | |||
1910 | * TODO: Implement parsing like for CSI when required. | 1936 | * TODO: Implement parsing like for CSI when required. |
1911 | * Format: ESC type cmd ';' arg0 [';' argn] ESC \ | 1937 | * Format: ESC type cmd ';' arg0 [';' argn] ESC \ |
1912 | */ | 1938 | */ |
1913 | return; | 1939 | int narg = 0; |
1940 | char *start = strescseq.buf, *end = start + strescseq.len; | ||
1941 | strescseq.args[0] = start; | ||
1942 | while(start < end && narg < LEN(strescseq.args)) { | ||
1943 | start = memchr(start, ';', end - start); | ||
1944 | if(!start) | ||
1945 | break; | ||
1946 | *start++ = '\0'; | ||
1947 | if(start < end) { | ||
1948 | strescseq.args[++narg] = start; | ||
1949 | } | ||
1950 | } | ||
1951 | strescseq.narg = narg + 1; | ||
1914 | } | 1952 | } |
1915 | 1953 | ||
1916 | void | 1954 | void |
@@ -2325,6 +2363,11 @@ xresize(int col, int row) { | |||
2325 | XftDrawChange(xw.draw, xw.buf); | 2363 | XftDrawChange(xw.draw, xw.buf); |
2326 | } | 2364 | } |
2327 | 2365 | ||
2366 | static inline ushort | ||
2367 | sixd_to_16bit(int x) { | ||
2368 | return x == 0 ? 0 : 0x3737 + 0x2828 * x; | ||
2369 | } | ||
2370 | |||
2328 | void | 2371 | void |
2329 | xloadcols(void) { | 2372 | xloadcols(void) { |
2330 | int i, r, g, b; | 2373 | int i, r, g, b; |
@@ -2343,9 +2386,9 @@ xloadcols(void) { | |||
2343 | for(i = 16, r = 0; r < 6; r++) { | 2386 | for(i = 16, r = 0; r < 6; r++) { |
2344 | for(g = 0; g < 6; g++) { | 2387 | for(g = 0; g < 6; g++) { |
2345 | for(b = 0; b < 6; b++) { | 2388 | for(b = 0; b < 6; b++) { |
2346 | color.red = r == 0 ? 0 : 0x3737 + 0x2828 * r; | 2389 | color.red = sixd_to_16bit(r); |
2347 | color.green = g == 0 ? 0 : 0x3737 + 0x2828 * g; | 2390 | color.green = sixd_to_16bit(g); |
2348 | color.blue = b == 0 ? 0 : 0x3737 + 0x2828 * b; | 2391 | color.blue = sixd_to_16bit(b); |
2349 | if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &color, &dc.col[i])) { | 2392 | if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &color, &dc.col[i])) { |
2350 | die("Could not allocate color %d\n", i); | 2393 | die("Could not allocate color %d\n", i); |
2351 | } | 2394 | } |
@@ -2363,6 +2406,38 @@ xloadcols(void) { | |||
2363 | } | 2406 | } |
2364 | } | 2407 | } |
2365 | 2408 | ||
2409 | int | ||
2410 | xsetcolorname(int x, const char *name) { | ||
2411 | XRenderColor color = { .alpha = 0xffff }; | ||
2412 | Colour colour; | ||
2413 | if (x < 0 || x > LEN(colorname)) | ||
2414 | return -1; | ||
2415 | if(!name) { | ||
2416 | if(16 <= x && x < 16 + 216) { | ||
2417 | int r = (x - 16) / 36, g = ((x - 16) % 36) / 6, b = (x - 16) % 6; | ||
2418 | color.red = sixd_to_16bit(r); | ||
2419 | color.green = sixd_to_16bit(g); | ||
2420 | color.blue = sixd_to_16bit(b); | ||
2421 | if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &color, &colour)) | ||
2422 | return 0; /* something went wrong */ | ||
2423 | dc.col[x] = colour; | ||
2424 | return 1; | ||
2425 | } else if (16 + 216 <= x && x < 256) { | ||
2426 | color.red = color.green = color.blue = 0x0808 + 0x0a0a * (x - (16 + 216)); | ||
2427 | if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &color, &colour)) | ||
2428 | return 0; /* something went wrong */ | ||
2429 | dc.col[x] = colour; | ||
2430 | return 1; | ||
2431 | } else { | ||
2432 | name = colorname[x]; | ||
2433 | } | ||
2434 | } | ||
2435 | if(!XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, &colour)) | ||
2436 | return 0; | ||
2437 | dc.col[x] = colour; | ||
2438 | return 1; | ||
2439 | } | ||
2440 | |||
2366 | void | 2441 | void |
2367 | xtermclear(int col1, int row1, int col2, int row2) { | 2442 | xtermclear(int col1, int row1, int col2, int row2) { |
2368 | XftDrawRect(xw.draw, | 2443 | XftDrawRect(xw.draw, |