X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=st.c;h=79746297e62f71f0061aefc06428d7df0a33a20d;hb=8c3757986a41ff8fa95b175be40f67d67d7e27b1;hp=f7f9de8769e593365dd4ac2b458a729bb5b0db9d;hpb=9d82bdd94708fa2daabc0b53f8b71bca2a3c6f0a;p=st.git diff --git a/st.c b/st.c index f7f9de8..7974629 100644 --- a/st.c +++ b/st.c @@ -104,6 +104,7 @@ typedef struct { /* Purely graphic info */ typedef struct { Display* dis; + Colormap cmap; Window win; Pixmap buf; int scr; @@ -677,7 +678,8 @@ tsetattr(int *attr, int l) { else if(BETWEEN(attr[i], 100, 107)) term.c.attr.fg = attr[i] - 100 + 8; else - fprintf(stderr, "erresc: gfx attr %d unknown\n", attr[i]); + fprintf(stderr, "erresc: gfx attr %d unknown\n", attr[i]), csidump(); + break; } } @@ -795,6 +797,8 @@ csihandle(void) { case 1: term.mode &= ~MODE_APPKEYPAD; break; + case 5: /* TODO: DECSCNM -- Remove reverse video */ + break; case 7: term.mode &= ~MODE_WRAP; break; @@ -850,11 +854,16 @@ csihandle(void) { case 1: term.mode |= MODE_APPKEYPAD; break; + case 5: /* DECSCNM -- Reverve video */ + /* TODO: set REVERSE on the whole screen (f) */ + break; case 7: term.mode |= MODE_WRAP; break; case 12: /* att610 -- Start blinking cursor (IGNORED) */ - break; + /* fallthrough for xterm cvvis = CSI [ ? 12 ; 25 h */ + if(escseq.narg > 1 && escseq.arg[1] != 25) + break; case 25: term.c.state &= ~CURSOR_HIDE; break; @@ -1060,12 +1069,25 @@ tresize(int col, int row) { int i; int minrow = MIN(row, term.row); int mincol = MIN(col, term.col); + int slide = term.c.y - row + 1; if(col < 1 || row < 1) return; - /* free uneeded rows */ - for(i = row; i < term.row; i++) { + /* free unneeded rows */ + i = 0; + if(slide > 0) { + /* slide screen to keep cursor where we expect it - + * tscrollup would work here, but we can optimize to + * memmove because we're freeing the earlier lines */ + for(/* i = 0 */; i < slide; i++) { + free(term.line[i]); + free(term.alt[i]); + } + memmove(term.line, term.line + slide, row * sizeof(Line)); + memmove(term.alt, term.alt + slide, row * sizeof(Line)); + } + for(i += row; i < term.row; i++) { free(term.line[i]); free(term.alt[i]); } @@ -1100,11 +1122,10 @@ void xloadcols(void) { int i, r, g, b; XColor color; - Colormap cmap = DefaultColormap(xw.dis, xw.scr); unsigned long white = WhitePixel(xw.dis, xw.scr); for(i = 0; i < 16; i++) { - if (!XAllocNamedColor(xw.dis, cmap, colorname[i], &color, &color)) { + if (!XAllocNamedColor(xw.dis, xw.cmap, colorname[i], &color, &color)) { dc.col[i] = white; fprintf(stderr, "Could not allocate color '%s'\n", colorname[i]); } else @@ -1118,7 +1139,7 @@ xloadcols(void) { color.red = r == 0 ? 0 : 0x3737 + 0x2828 * r; color.green = g == 0 ? 0 : 0x3737 + 0x2828 * g; color.blue = b == 0 ? 0 : 0x3737 + 0x2828 * b; - if (!XAllocColor(xw.dis, cmap, &color)) { + if (!XAllocColor(xw.dis, xw.cmap, &color)) { dc.col[i] = white; fprintf(stderr, "Could not allocate color %d\n", i); } else @@ -1128,7 +1149,7 @@ xloadcols(void) { for(r = 0; r < 24; r++, i++) { color.red = color.green = color.blue = 0x0808 + 0x0a0a * r; - if (!XAllocColor(xw.dis, cmap, &color)) { + if (!XAllocColor(xw.dis, xw.cmap, &color)) { dc.col[i] = white; fprintf(stderr, "Could not allocate color %d\n", i); } else @@ -1163,6 +1184,8 @@ xhints(void) void xinit(void) { + XSetWindowAttributes attrs; + if(!(xw.dis = XOpenDisplay(NULL))) die("Can't open display\n"); xw.scr = XDefaultScreen(xw.dis); @@ -1176,25 +1199,32 @@ xinit(void) { xw.ch = dc.font->ascent + dc.font->descent; /* colors */ + xw.cmap = XDefaultColormap(xw.dis, xw.scr); xloadcols(); - /* windows */ - xw.bufh = term.row * xw.ch; - xw.bufw = term.col * xw.cw; + /* window - default size */ + xw.bufh = 24 * xw.ch; + xw.bufw = 80 * xw.cw; xw.h = xw.bufh + 2*BORDER; xw.w = xw.bufw + 2*BORDER; - xw.win = XCreateSimpleWindow(xw.dis, XRootWindow(xw.dis, xw.scr), 0, 0, - xw.w, xw.h, 0, - dc.col[DefaultBG], - dc.col[DefaultBG]); + + attrs.background_pixel = dc.col[DefaultBG]; + attrs.border_pixel = dc.col[DefaultBG]; + attrs.bit_gravity = NorthWestGravity; + attrs.event_mask = ExposureMask | KeyPressMask + | StructureNotifyMask | FocusChangeMask | PointerMotionMask + | ButtonPressMask | ButtonReleaseMask; + attrs.colormap = xw.cmap; + + xw.win = XCreateWindow(xw.dis, XRootWindow(xw.dis, xw.scr), 0, 0, + xw.w, xw.h, 0, XDefaultDepth(xw.dis, xw.scr), InputOutput, + XDefaultVisual(xw.dis, xw.scr), + CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask + | CWColormap, + &attrs); xw.buf = XCreatePixmap(xw.dis, xw.win, xw.bufw, xw.bufh, XDefaultDepth(xw.dis, xw.scr)); /* gc */ dc.gc = XCreateGC(xw.dis, xw.win, 0, NULL); - - /* event mask */ - XSelectInput(xw.dis, xw.win, ExposureMask | KeyPressMask - | StructureNotifyMask | FocusChangeMask | PointerMotionMask - | ButtonPressMask | ButtonReleaseMask); XMapWindow(xw.dis, xw.win); xhints(); @@ -1217,8 +1247,13 @@ xdraws(char *s, Glyph base, int x, int y, int len) { XSetForeground(xw.dis, dc.gc, xfg); if(base.mode & ATTR_GFX) - for(i = 0; i < len; i++) - s[i] = gfx[(int)s[i]]; + for(i = 0; i < len; i++) { + char c = gfx[(unsigned int)s[i] % 256]; + if(c) + s[i] = c; + else if(s[i] > 0x5f) + s[i] -= 0x5f; + } XSetFont(xw.dis, dc.gc, base.mode & ATTR_BOLD ? dc.bfont->fid : dc.font->fid); XDrawImageString(xw.dis, xw.buf, dc.gc, winx, winy, s, len); @@ -1406,7 +1441,6 @@ resize(XEvent *e) { xw.bufw = MAX(1, xw.bufw); XFreePixmap(xw.dis, xw.buf); xw.buf = XCreatePixmap(xw.dis, xw.win, xw.bufw, xw.bufh, XDefaultDepth(xw.dis, xw.scr)); - draw(SCREEN_REDRAW); } void