diff options
-rw-r--r-- | config.h | 2 | ||||
-rw-r--r-- | st.c | 64 |
2 files changed, 39 insertions, 27 deletions
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | #define FONT "fixed" | 4 | #define FONT "fixed" |
5 | #define BORDER 3 | 5 | #define BORDER 3 |
6 | #define LINESPACE 1 /* additional pixel between each line */ | 6 | #define LINESPACE 0 /* additional pixel between each line */ |
7 | 7 | ||
8 | /* Terminal colors */ | 8 | /* Terminal colors */ |
9 | static const char *colorname[] = { | 9 | static const char *colorname[] = { |
@@ -3,6 +3,7 @@ | |||
3 | #include <ctype.h> | 3 | #include <ctype.h> |
4 | #include <errno.h> | 4 | #include <errno.h> |
5 | #include <fcntl.h> | 5 | #include <fcntl.h> |
6 | #include <limits.h> | ||
6 | #include <locale.h> | 7 | #include <locale.h> |
7 | #include <stdarg.h> | 8 | #include <stdarg.h> |
8 | #include <stdio.h> | 9 | #include <stdio.h> |
@@ -24,6 +25,7 @@ | |||
24 | /* Arbitrary sizes */ | 25 | /* Arbitrary sizes */ |
25 | #define ESCSIZ 256 | 26 | #define ESCSIZ 256 |
26 | #define ESCARG 16 | 27 | #define ESCARG 16 |
28 | #define MAXDRAWBUF 1024 | ||
27 | 29 | ||
28 | #define SERRNO strerror(errno) | 30 | #define SERRNO strerror(errno) |
29 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) | 31 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) |
@@ -32,6 +34,7 @@ | |||
32 | #define DEFAULT(a, b) (a) = (a) ? (a) : (b) | 34 | #define DEFAULT(a, b) (a) = (a) ? (a) : (b) |
33 | #define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) | 35 | #define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) |
34 | #define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) | 36 | #define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) |
37 | #define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg) | ||
35 | 38 | ||
36 | /* Attribute, Cursor, Character state, Terminal mode, Screen draw mode */ | 39 | /* Attribute, Cursor, Character state, Terminal mode, Screen draw mode */ |
37 | enum { ATnone=0 , ATreverse=1 , ATunderline=2, ATbold=4 }; | 40 | enum { ATnone=0 , ATreverse=1 , ATunderline=2, ATbold=4 }; |
@@ -934,6 +937,23 @@ xinit(void) { | |||
934 | } | 937 | } |
935 | 938 | ||
936 | void | 939 | void |
940 | xdraws (char *s, Glyph base, int x, int y, int len) { | ||
941 | unsigned long xfg, xbg; | ||
942 | int winx = x*xw.cw, winy = y*xw.ch + dc.font->ascent, width = len*xw.cw; | ||
943 | if(base.mode & ATreverse) | ||
944 | xfg = dc.col[base.bg], xbg = dc.col[base.fg]; | ||
945 | else | ||
946 | xfg = dc.col[base.fg], xbg = dc.col[base.bg]; | ||
947 | |||
948 | XSetBackground(xw.dis, dc.gc, xbg); | ||
949 | XSetForeground(xw.dis, dc.gc, xfg); | ||
950 | XDrawImageString(xw.dis, xw.win, dc.gc, winx, winy, s, len); | ||
951 | |||
952 | if(base.mode & ATunderline) | ||
953 | XDrawLine(xw.dis, xw.win, dc.gc, winx, winy+1, winx+width-1, winy+1); | ||
954 | } | ||
955 | |||
956 | void | ||
937 | xdrawc(int x, int y, Glyph g) { | 957 | xdrawc(int x, int y, Glyph g) { |
938 | XRectangle r = { x * xw.cw, y * xw.ch, xw.cw, xw.ch }; | 958 | XRectangle r = { x * xw.cw, y * xw.ch, xw.cw, xw.ch }; |
939 | unsigned long xfg, xbg; | 959 | unsigned long xfg, xbg; |
@@ -944,18 +964,9 @@ xdrawc(int x, int y, Glyph g) { | |||
944 | else | 964 | else |
945 | xfg = dc.col[g.fg], xbg = dc.col[g.bg]; | 965 | xfg = dc.col[g.fg], xbg = dc.col[g.bg]; |
946 | /* background */ | 966 | /* background */ |
947 | XSetForeground(xw.dis, dc.gc, xbg); | 967 | XSetBackground(xw.dis, dc.gc, xbg); |
948 | XFillRectangles(xw.dis, xw.win, dc.gc, &r, 1); | ||
949 | /* string */ | ||
950 | XSetForeground(xw.dis, dc.gc, xfg); | 968 | XSetForeground(xw.dis, dc.gc, xfg); |
951 | XDrawString(xw.dis, xw.win, dc.gc, r.x, r.y+dc.font->ascent, &(g.c), 1); | 969 | XDrawImageString(xw.dis, xw.win, dc.gc, r.x, r.y+dc.font->ascent, &g.c, 1); |
952 | if(g.mode & ATbold) /* XXX: bold hack (draw again at x+1) */ | ||
953 | XDrawString(xw.dis, xw.win, dc.gc, r.x+1, r.y+dc.font->ascent, &(g.c), 1); | ||
954 | /* underline */ | ||
955 | if(g.mode & ATunderline) { | ||
956 | r.y += dc.font->ascent + 1; | ||
957 | XDrawLine(xw.dis, xw.win, dc.gc, r.x, r.y, r.x+r.width-1, r.y); | ||
958 | } | ||
959 | } | 970 | } |
960 | 971 | ||
961 | void | 972 | void |
@@ -983,25 +994,26 @@ xcursor(int mode) { | |||
983 | 994 | ||
984 | void | 995 | void |
985 | draw(int redraw_all) { | 996 | draw(int redraw_all) { |
986 | int x, y; | 997 | int i, x, y, ox; |
987 | int changed, set; | 998 | Glyph base, new; |
988 | 999 | char buf[MAXDRAWBUF]; | |
989 | if(redraw_all) | 1000 | |
990 | XClearWindow(xw.dis, xw.win); | ||
991 | |||
992 | /* XXX: drawing could be optimised */ | ||
993 | for(y = 0; y < term.row; y++) { | 1001 | for(y = 0; y < term.row; y++) { |
1002 | base = term.line[y][0]; | ||
1003 | i = ox = 0; | ||
994 | for(x = 0; x < term.col; x++) { | 1004 | for(x = 0; x < term.col; x++) { |
995 | changed = term.line[y][x].state & CRupdate; | 1005 | new = term.line[y][x]; |
996 | set = term.line[y][x].state & CRset; | 1006 | if(!ATTRCMP(base, new) && i < MAXDRAWBUF) |
997 | if(redraw_all || changed) { | 1007 | buf[i++] = new.c; |
998 | term.line[y][x].state &= ~CRupdate; | 1008 | else { |
999 | if(set) | 1009 | xdraws(buf, base, ox, y, i); |
1000 | xdrawc(x, y, term.line[y][x]); | 1010 | buf[0] = new.c; |
1001 | else | 1011 | i = 1; |
1002 | xclear(x, y, x, y); | 1012 | ox = x; |
1013 | base = new; | ||
1003 | } | 1014 | } |
1004 | } | 1015 | } |
1016 | xdraws(buf, base, ox, y, i); | ||
1005 | } | 1017 | } |
1006 | xcursor(CSdraw); | 1018 | xcursor(CSdraw); |
1007 | } | 1019 | } |