diff options
| -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, |
