diff options
| -rw-r--r-- | st.c | 119 |
1 files changed, 85 insertions, 34 deletions
| @@ -77,6 +77,13 @@ char *argv0; | |||
| 77 | #define IS_SET(flag) ((term.mode & (flag)) != 0) | 77 | #define IS_SET(flag) ((term.mode & (flag)) != 0) |
| 78 | #define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + (t1.tv_usec-t2.tv_usec)/1000) | 78 | #define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + (t1.tv_usec-t2.tv_usec)/1000) |
| 79 | 79 | ||
| 80 | #define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b)) | ||
| 81 | #define IS_TRUECOL(x) (1 << 24 & (x)) | ||
| 82 | #define TRUERED(x) (((x) & 0xff0000) >> 8) | ||
| 83 | #define TRUEGREEN(x) (((x) & 0xff00)) | ||
| 84 | #define TRUEBLUE(x) (((x) & 0xff) << 8) | ||
| 85 | |||
| 86 | |||
| 80 | #define VT102ID "\033[?6c" | 87 | #define VT102ID "\033[?6c" |
| 81 | 88 | ||
| 82 | enum glyph_attribute { | 89 | enum glyph_attribute { |
| @@ -158,8 +165,8 @@ typedef unsigned short ushort; | |||
| 158 | typedef struct { | 165 | typedef struct { |
| 159 | char c[UTF_SIZ]; /* character code */ | 166 | char c[UTF_SIZ]; /* character code */ |
| 160 | uchar mode; /* attribute flags */ | 167 | uchar mode; /* attribute flags */ |
| 161 | ushort fg; /* foreground */ | 168 | ulong fg; /* foreground */ |
| 162 | ushort bg; /* background */ | 169 | ulong bg; /* background */ |
| 163 | } Glyph; | 170 | } Glyph; |
| 164 | 171 | ||
| 165 | typedef Glyph *Line; | 172 | typedef Glyph *Line; |
| @@ -354,7 +361,7 @@ static void tsetdirtattr(int); | |||
| 354 | static void tsetmode(bool, bool, int *, int); | 361 | static void tsetmode(bool, bool, int *, int); |
| 355 | static void tfulldirt(void); | 362 | static void tfulldirt(void); |
| 356 | static void techo(char *, int); | 363 | static void techo(char *, int); |
| 357 | 364 | static ulong tdefcolor(int *, int *, int); | |
| 358 | static inline bool match(uint, uint); | 365 | static inline bool match(uint, uint); |
| 359 | static void ttynew(void); | 366 | static void ttynew(void); |
| 360 | static void ttyread(void); | 367 | static void ttyread(void); |
| @@ -1618,9 +1625,58 @@ tdeleteline(int n) { | |||
| 1618 | tscrollup(term.c.y, n); | 1625 | tscrollup(term.c.y, n); |
| 1619 | } | 1626 | } |
| 1620 | 1627 | ||
| 1628 | ulong | ||
| 1629 | tdefcolor(int *attr, int *npar, int l) { | ||
| 1630 | long idx = -1; | ||
| 1631 | uint r, g, b; | ||
| 1632 | |||
| 1633 | switch (attr[*npar + 1]) { | ||
| 1634 | case 2: /* direct colour in RGB space */ | ||
| 1635 | if (*npar + 4 >= l) { | ||
| 1636 | fprintf(stderr, | ||
| 1637 | "erresc(38): Incorrect number of parameters (%d)\n", | ||
| 1638 | *npar); | ||
| 1639 | break; | ||
| 1640 | } | ||
| 1641 | r = attr[*npar + 2]; | ||
| 1642 | g = attr[*npar + 3]; | ||
| 1643 | b = attr[*npar + 4]; | ||
| 1644 | *npar += 4; | ||
| 1645 | if(!BETWEEN(r, 0, 255) || !BETWEEN(g, 0, 255) || !BETWEEN(b, 0, 255)) | ||
| 1646 | fprintf(stderr, "erresc: bad rgb color (%d,%d,%d)\n", | ||
| 1647 | r, g, b); | ||
| 1648 | else | ||
| 1649 | idx = TRUECOLOR(r, g, b); | ||
| 1650 | break; | ||
| 1651 | case 5: /* indexed colour */ | ||
| 1652 | if (*npar + 2 >= l) { | ||
| 1653 | fprintf(stderr, | ||
| 1654 | "erresc(38): Incorrect number of parameters (%d)\n", | ||
| 1655 | *npar); | ||
| 1656 | break; | ||
| 1657 | } | ||
| 1658 | *npar += 2; | ||
| 1659 | if(!BETWEEN(attr[*npar], 0, 255)) | ||
| 1660 | fprintf(stderr, "erresc: bad fgcolor %d\n", attr[*npar]); | ||
| 1661 | else | ||
| 1662 | idx = attr[*npar]; | ||
| 1663 | break; | ||
| 1664 | case 0: /* implemented defined (only foreground) */ | ||
| 1665 | case 1: /* transparent */ | ||
| 1666 | case 3: /* direct colour in CMY space */ | ||
| 1667 | case 4: /* direct colour in CMYK space */ | ||
| 1668 | default: | ||
| 1669 | fprintf(stderr, | ||
| 1670 | "erresc(38): gfx attr %d unknown\n", attr[*npar]); | ||
| 1671 | } | ||
| 1672 | |||
| 1673 | return idx; | ||
| 1674 | } | ||
| 1675 | |||
| 1621 | void | 1676 | void |
| 1622 | tsetattr(int *attr, int l) { | 1677 | tsetattr(int *attr, int l) { |
| 1623 | int i; | 1678 | int i; |
| 1679 | ulong idx; | ||
| 1624 | 1680 | ||
| 1625 | for(i = 0; i < l; i++) { | 1681 | for(i = 0; i < l; i++) { |
| 1626 | switch(attr[i]) { | 1682 | switch(attr[i]) { |
| @@ -1665,39 +1721,15 @@ tsetattr(int *attr, int l) { | |||
| 1665 | term.c.attr.mode &= ~ATTR_REVERSE; | 1721 | term.c.attr.mode &= ~ATTR_REVERSE; |
| 1666 | break; | 1722 | break; |
| 1667 | case 38: | 1723 | case 38: |
| 1668 | if(i + 2 < l && attr[i + 1] == 5) { | 1724 | if ((idx = tdefcolor(attr, &i, l)) >= 0) |
| 1669 | i += 2; | 1725 | term.c.attr.fg = idx; |
| 1670 | if(BETWEEN(attr[i], 0, 255)) { | ||
| 1671 | term.c.attr.fg = attr[i]; | ||
| 1672 | } else { | ||
| 1673 | fprintf(stderr, | ||
| 1674 | "erresc: bad fgcolor %d\n", | ||
| 1675 | attr[i]); | ||
| 1676 | } | ||
| 1677 | } else { | ||
| 1678 | fprintf(stderr, | ||
| 1679 | "erresc(38): gfx attr %d unknown\n", | ||
| 1680 | attr[i]); | ||
| 1681 | } | ||
| 1682 | break; | 1726 | break; |
| 1683 | case 39: | 1727 | case 39: |
| 1684 | term.c.attr.fg = defaultfg; | 1728 | term.c.attr.fg = defaultfg; |
| 1685 | break; | 1729 | break; |
| 1686 | case 48: | 1730 | case 48: |
| 1687 | if(i + 2 < l && attr[i + 1] == 5) { | 1731 | if ((idx = tdefcolor(attr, &i, l)) >= 0) |
| 1688 | i += 2; | 1732 | term.c.attr.bg = idx; |
| 1689 | if(BETWEEN(attr[i], 0, 255)) { | ||
| 1690 | term.c.attr.bg = attr[i]; | ||
| 1691 | } else { | ||
| 1692 | fprintf(stderr, | ||
| 1693 | "erresc: bad bgcolor %d\n", | ||
| 1694 | attr[i]); | ||
| 1695 | } | ||
| 1696 | } else { | ||
| 1697 | fprintf(stderr, | ||
| 1698 | "erresc(48): gfx attr %d unknown\n", | ||
| 1699 | attr[i]); | ||
| 1700 | } | ||
| 1701 | break; | 1733 | break; |
| 1702 | case 49: | 1734 | case 49: |
| 1703 | term.c.attr.bg = defaultbg; | 1735 | term.c.attr.bg = defaultbg; |
| @@ -2916,7 +2948,7 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { | |||
| 2916 | FcPattern *fcpattern, *fontpattern; | 2948 | FcPattern *fcpattern, *fontpattern; |
| 2917 | FcFontSet *fcsets[] = { NULL }; | 2949 | FcFontSet *fcsets[] = { NULL }; |
| 2918 | FcCharSet *fccharset; | 2950 | FcCharSet *fccharset; |
| 2919 | Colour *fg, *bg, *temp, revfg, revbg; | 2951 | Colour *fg, *bg, *temp, revfg, revbg, truefg, truebg; |
| 2920 | XRenderColor colfg, colbg; | 2952 | XRenderColor colfg, colbg; |
| 2921 | Rectangle r; | 2953 | Rectangle r; |
| 2922 | 2954 | ||
| @@ -2936,8 +2968,27 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { | |||
| 2936 | if(base.fg == defaultfg) | 2968 | if(base.fg == defaultfg) |
| 2937 | base.fg = defaultunderline; | 2969 | base.fg = defaultunderline; |
| 2938 | } | 2970 | } |
| 2939 | fg = &dc.col[base.fg]; | 2971 | if(IS_TRUECOL(base.fg)) { |
| 2940 | bg = &dc.col[base.bg]; | 2972 | colfg.red = TRUERED(base.fg); |
| 2973 | colfg.green = TRUEGREEN(base.fg); | ||
| 2974 | colfg.blue = TRUEBLUE(base.fg); | ||
| 2975 | XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &truefg); | ||
| 2976 | fg = &truefg; | ||
| 2977 | } else { | ||
| 2978 | fg = &dc.col[base.fg]; | ||
| 2979 | } | ||
| 2980 | |||
| 2981 | if(IS_TRUECOL(base.bg)) { | ||
| 2982 | colbg.green = TRUEGREEN(base.bg); | ||
| 2983 | colbg.red = TRUERED(base.bg); | ||
| 2984 | colbg.blue = TRUEBLUE(base.bg); | ||
| 2985 | XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &truebg); | ||
| 2986 | bg = &truebg; | ||
| 2987 | } else { | ||
| 2988 | bg = &dc.col[base.bg]; | ||
| 2989 | } | ||
| 2990 | |||
| 2991 | |||
| 2941 | 2992 | ||
| 2942 | if(base.mode & ATTR_BOLD) { | 2993 | if(base.mode & ATTR_BOLD) { |
| 2943 | if(BETWEEN(base.fg, 0, 7)) { | 2994 | if(BETWEEN(base.fg, 0, 7)) { |
