X-Git-Url: https://git.xinqibao.xyz/st.git/blobdiff_plain/a5dc1b46976b2252f9d7bb68f126c4b0f351dd1a..e0215d53770a9b6bc6e5d7b9a603ecd34dbd7100:/x.c diff --git a/x.c b/x.c index d205ca7..f7b0528 100644 --- a/x.c +++ b/x.c @@ -75,6 +75,15 @@ typedef XftColor Color; typedef XftGlyphFontSpec GlyphFontSpec; /* Purely graphic info */ +typedef struct { + int tw, th; /* tty width and height */ + int w, h; /* window width and height */ + int ch; /* char height */ + int cw; /* char width */ + int mode; /* window state/mode flags */ + int cursor; /* cursor style */ +} TermWindow; + typedef struct { Display *dpy; Colormap cmap; @@ -130,9 +139,11 @@ static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int); static void xdrawglyph(Glyph, int, int); static void xclear(int, int, int, int); static int xgeommasktogravity(int); -static void xinit(void); +static void xinit(int, int); static void cresize(int, int); static void xresize(int, int); +static void xhints(void); +static int xloadcolor(int, const char *, Color *); static int xloadfont(Font *, FcPattern *); static void xloadfonts(char *, double); static void xunloadfont(Font *); @@ -227,6 +238,8 @@ static char *opt_line = NULL; static char *opt_name = NULL; static char *opt_title = NULL; +static int oldbutton = 3; /* button event on startup: 3 = release */ + void clipcopy(const Arg *dummy) { @@ -299,18 +312,16 @@ int x2col(int x) { x -= borderpx; - x /= win.cw; - - return LIMIT(x, 0, term.col-1); + LIMIT(x, 0, win.tw - 1); + return x / win.cw; } int y2row(int y) { y -= borderpx; - y /= win.ch; - - return LIMIT(y, 0, term.row-1); + LIMIT(y, 0, win.th - 1); + return y / win.ch; } void @@ -984,7 +995,7 @@ xunloadfonts(void) } void -xinit(void) +xinit(int cols, int rows) { XGCValues gcvalues; Cursor cursor; @@ -1009,8 +1020,8 @@ xinit(void) xloadcols(); /* adjust fixed window geometry */ - win.w = 2 * borderpx + term.col * win.cw; - win.h = 2 * borderpx + term.row * win.ch; + win.w = 2 * borderpx + cols * win.cw; + win.h = 2 * borderpx + rows * win.ch; if (xw.gm & XNegative) xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; if (xw.gm & YNegative) @@ -1042,7 +1053,7 @@ xinit(void) XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); /* font spec buffer */ - xw.specbuf = xmalloc(term.col * sizeof(GlyphFontSpec)); + xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec)); /* Xft rendering context */ xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); @@ -1337,15 +1348,16 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i /* Intelligent cleaning up of the borders. */ if (x == 0) { xclear(0, (y == 0)? 0 : winy, borderpx, - winy + win.ch + ((y >= term.row-1)? win.h : 0)); + winy + win.ch + + ((winy + win.ch >= borderpx + win.th)? win.h : 0)); } - if (x + charlen >= term.col) { + if (winx + width >= borderpx + win.tw) { xclear(winx + width, (y == 0)? 0 : winy, win.w, - ((y >= term.row-1)? win.h : (winy + win.ch))); + ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); } if (y == 0) xclear(winx, 0, winx + width, borderpx); - if (y == term.row-1) + if (winy + win.ch >= borderpx + win.th) xclear(winx, winy + win.ch, winx + width, win.h); /* Clean up the region we want to draw to. */ @@ -1429,8 +1441,8 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) /* draw the new one */ if (IS_SET(MODE_FOCUSED)) { switch (win.cursor) { - case 7: /* st extension: snowman */ - utf8decode("☃", &g.u, UTF_SIZ); + case 7: /* st extension: snowman (U+2603) */ + g.u = 0x2603; case 0: /* Blinking Block */ case 1: /* Blinking Block (Default) */ case 2: /* Steady Block */ @@ -1734,8 +1746,7 @@ cmessage(XEvent *e) win.mode &= ~MODE_FOCUSED; } } else if (e->xclient.data.l[0] == xw.wmdeletewin) { - /* Send SIGHUP to shell */ - kill(pid, SIGHUP); + ttyhangup(); exit(0); } } @@ -1756,6 +1767,7 @@ run(void) int w = win.w, h = win.h; fd_set rfd; int xfd = XConnectionNumber(xw.dpy), xev, blinkset = 0, dodraw = 0; + int ttyfd; struct timespec drawtimeout, *tv = NULL, now, last, lastblink; long deltatime; @@ -1775,7 +1787,7 @@ run(void) } } while (ev.type != MapNotify); - ttynew(opt_line, opt_io, opt_cmd); + ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd); cresize(w, h); clock_gettime(CLOCK_MONOTONIC, &last); @@ -1783,15 +1795,15 @@ run(void) for (xev = actionfps;;) { FD_ZERO(&rfd); - FD_SET(cmdfd, &rfd); + FD_SET(ttyfd, &rfd); FD_SET(xfd, &rfd); - if (pselect(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) { + if (pselect(MAX(xfd, ttyfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) { if (errno == EINTR) continue; die("select failed: %s\n", strerror(errno)); } - if (FD_ISSET(cmdfd, &rfd)) { + if (FD_ISSET(ttyfd, &rfd)) { ttyread(); if (blinktimeout) { blinkset = tattrset(ATTR_BLINK); @@ -1835,7 +1847,7 @@ run(void) if (xev && !FD_ISSET(xfd, &rfd)) xev--; - if (!FD_ISSET(cmdfd, &rfd) && !FD_ISSET(xfd, &rfd)) { + if (!FD_ISSET(ttyfd, &rfd) && !FD_ISSET(xfd, &rfd)) { if (blinkset) { if (TIMEDIFF(now, lastblink) \ > blinktimeout) { @@ -1930,8 +1942,10 @@ run: } setlocale(LC_CTYPE, ""); XSetLocaleModifiers(""); - tnew(MAX(cols, 1), MAX(rows, 1)); - xinit(); + cols = MAX(cols, 1); + rows = MAX(rows, 1); + tnew(cols, rows); + xinit(cols, rows); xsetenv(); selinit(); run();