From 27c06ee7878c347d5237ed099a15d453ac36ac83 Mon Sep 17 00:00:00 2001 From: Sam Hoffman Date: Thu, 1 Jan 2026 13:47:02 -0500 Subject: [PATCH] remove diff files --- st | Bin 108600 -> 0 bytes st-bold-is-not-bright-20190127-3be4cf1.diff | 27 - st-scrollback-ringbuffer-0.9.2.diff | 730 ------- st.o | Bin 83304 -> 0 bytes x.c.orig | 2108 ------------------- x.o | Bin 75920 -> 0 bytes 6 files changed, 2865 deletions(-) delete mode 100755 st delete mode 100644 st-bold-is-not-bright-20190127-3be4cf1.diff delete mode 100644 st-scrollback-ringbuffer-0.9.2.diff delete mode 100644 st.o delete mode 100644 x.c.orig delete mode 100644 x.o diff --git a/st b/st deleted file mode 100755 index cda195825ba929bab65b29d40654386561579141..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108600 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 -Date: Sun, 27 Jan 2019 13:31:28 +0800 -Subject: [PATCH] Show bold not as bright - ---- - x.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/x.c b/x.c -index 0422421..904e1dc 100644 ---- a/x.c -+++ b/x.c -@@ -1296,10 +1296,6 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i - bg = &dc.col[base.bg]; - } - -- /* Change basic system colors [0-7] to bright system colors [8-15] */ -- if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7)) -- fg = &dc.col[base.fg + 8]; -- - if (IS_SET(MODE_REVERSE)) { - if (fg == &dc.col[defaultfg]) { - fg = &dc.col[defaultbg]; --- -2.20.1 - diff --git a/st-scrollback-ringbuffer-0.9.2.diff b/st-scrollback-ringbuffer-0.9.2.diff deleted file mode 100644 index a6f2973..0000000 --- a/st-scrollback-ringbuffer-0.9.2.diff +++ /dev/null @@ -1,730 +0,0 @@ -commit 0663bdf11a409961da5b1120741a69814da8ce65 -Author: Timo Röhling -Date: Tue Nov 23 19:45:33 2021 +0100 - - Terminal scrollback with ring buffer - - This patch adds a ring buffer for scrollback to the terminal. The - advantage of using a ring buffer is that the common case, scrolling with - no static screen content, can be achieved very efficiently by - incrementing and decrementing the starting line (modulo buffer size). - - The scrollback buffer is limited to HISTSIZE lines in order to bound - memory usage. As the lines are allocated on demand, it is possible to - implement unlimited scrollback with few changes. If the terminal is - reset, the scroll back buffer is reset, too. - -diff --git a/config.def.h b/config.def.h -index 2cd740a..8b25d40 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -201,6 +201,8 @@ static Shortcut shortcuts[] = { - { TERMMOD, XK_Y, selpaste, {.i = 0} }, - { ShiftMask, XK_Insert, selpaste, {.i = 0} }, - { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, -+ { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} }, -+ { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} }, - }; - - /* -diff --git a/st.c b/st.c -index b9f66e7..d9b163e 100644 ---- a/st.c -+++ b/st.c -@@ -43,6 +43,10 @@ - #define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) - #define ISDELIM(u) (u && wcschr(worddelimiters, u)) - -+#define TSCREEN term.screen[IS_SET(MODE_ALTSCREEN)] -+#define TLINEOFFSET(y) (((y) + TSCREEN.cur - TSCREEN.off + TSCREEN.size) % TSCREEN.size) -+#define TLINE(y) (TSCREEN.buffer[TLINEOFFSET(y)]) -+ - enum term_mode { - MODE_WRAP = 1 << 0, - MODE_INSERT = 1 << 1, -@@ -109,12 +113,21 @@ typedef struct { - int alt; - } Selection; - -+/* Screen lines */ -+typedef struct { -+ Line* buffer; /* ring buffer */ -+ int size; /* size of buffer */ -+ int cur; /* start of active screen */ -+ int off; /* scrollback line offset */ -+ TCursor sc; /* saved cursor */ -+} LineBuffer; -+ - /* Internal representation of the screen */ - typedef struct { - int row; /* nb row */ - int col; /* nb col */ -- Line *line; /* screen */ -- Line *alt; /* alternate screen */ -+ LineBuffer screen[2]; /* screen and alternate screen */ -+ int linelen; /* allocated line length */ - int *dirty; /* dirtyness of lines */ - TCursor c; /* cursor */ - int ocx; /* old cursor col */ -@@ -203,6 +216,8 @@ static void tdeftran(char); - static void tstrsequence(uchar); - - static void drawregion(int, int, int, int); -+static void clearline(Line, Glyph, int, int); -+static Line ensureline(Line); - - static void selnormalize(void); - static void selscroll(int, int); -@@ -408,11 +423,12 @@ int - tlinelen(int y) - { - int i = term.col; -+ Line line = TLINE(y); - -- if (term.line[y][i - 1].mode & ATTR_WRAP) -+ if (line[i - 1].mode & ATTR_WRAP) - return i; - -- while (i > 0 && term.line[y][i - 1].u == ' ') -+ while (i > 0 && line[i - 1].u == ' ') - --i; - - return i; -@@ -521,7 +537,7 @@ selsnap(int *x, int *y, int direction) - * Snap around if the word wraps around at the end or - * beginning of a line. - */ -- prevgp = &term.line[*y][*x]; -+ prevgp = &TLINE(*y)[*x]; - prevdelim = ISDELIM(prevgp->u); - for (;;) { - newx = *x + direction; -@@ -536,14 +552,14 @@ selsnap(int *x, int *y, int direction) - yt = *y, xt = *x; - else - yt = newy, xt = newx; -- if (!(term.line[yt][xt].mode & ATTR_WRAP)) -+ if (!(TLINE(yt)[xt].mode & ATTR_WRAP)) - break; - } - - if (newx >= tlinelen(newy)) - break; - -- gp = &term.line[newy][newx]; -+ gp = &TLINE(newy)[newx]; - delim = ISDELIM(gp->u); - if (!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim - || (delim && gp->u != prevgp->u))) -@@ -564,14 +580,14 @@ selsnap(int *x, int *y, int direction) - *x = (direction < 0) ? 0 : term.col - 1; - if (direction < 0) { - for (; *y > 0; *y += direction) { -- if (!(term.line[*y-1][term.col-1].mode -+ if (!(TLINE(*y-1)[term.col-1].mode - & ATTR_WRAP)) { - break; - } - } - } else if (direction > 0) { - for (; *y < term.row-1; *y += direction) { -- if (!(term.line[*y][term.col-1].mode -+ if (!(TLINE(*y)[term.col-1].mode - & ATTR_WRAP)) { - break; - } -@@ -602,13 +618,13 @@ getsel(void) - } - - if (sel.type == SEL_RECTANGULAR) { -- gp = &term.line[y][sel.nb.x]; -+ gp = &TLINE(y)[sel.nb.x]; - lastx = sel.ne.x; - } else { -- gp = &term.line[y][sel.nb.y == y ? sel.nb.x : 0]; -+ gp = &TLINE(y)[sel.nb.y == y ? sel.nb.x : 0]; - lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1; - } -- last = &term.line[y][MIN(lastx, linelen-1)]; -+ last = &TLINE(y)[MIN(lastx, linelen-1)]; - while (last >= gp && last->u == ' ') - --last; - -@@ -949,12 +965,15 @@ int - tattrset(int attr) - { - int i, j; -+ int y = TLINEOFFSET(0); - - for (i = 0; i < term.row-1; i++) { -+ Line line = TSCREEN.buffer[y]; - for (j = 0; j < term.col-1; j++) { -- if (term.line[i][j].mode & attr) -+ if (line[j].mode & attr) - return 1; - } -+ y = (y+1) % TSCREEN.size; - } - - return 0; -@@ -976,14 +995,17 @@ void - tsetdirtattr(int attr) - { - int i, j; -+ int y = TLINEOFFSET(0); - - for (i = 0; i < term.row-1; i++) { -+ Line line = TSCREEN.buffer[y]; - for (j = 0; j < term.col-1; j++) { -- if (term.line[i][j].mode & attr) { -+ if (line[j].mode & attr) { - tsetdirt(i, i); - break; - } - } -+ y = (y+1) % TSCREEN.size; - } - } - -@@ -996,27 +1018,19 @@ tfulldirt(void) - void - tcursor(int mode) - { -- static TCursor c[2]; -- int alt = IS_SET(MODE_ALTSCREEN); -- - if (mode == CURSOR_SAVE) { -- c[alt] = term.c; -+ TSCREEN.sc = term.c; - } else if (mode == CURSOR_LOAD) { -- term.c = c[alt]; -- tmoveto(c[alt].x, c[alt].y); -+ term.c = TSCREEN.sc; -+ tmoveto(term.c.x, term.c.y); - } - } - - void - treset(void) - { -- uint i; -- -- term.c = (TCursor){{ -- .mode = ATTR_NULL, -- .fg = defaultfg, -- .bg = defaultbg -- }, .x = 0, .y = 0, .state = CURSOR_DEFAULT}; -+ int i, j; -+ Glyph g = (Glyph){ .fg = defaultfg, .bg = defaultbg}; - - memset(term.tabs, 0, term.col * sizeof(*term.tabs)); - for (i = tabspaces; i < term.col; i += tabspaces) -@@ -1028,17 +1042,37 @@ treset(void) - term.charset = 0; - - for (i = 0; i < 2; i++) { -- tmoveto(0, 0); -- tcursor(CURSOR_SAVE); -- tclearregion(0, 0, term.col-1, term.row-1); -- tswapscreen(); -+ term.screen[i].sc = (TCursor){{ -+ .fg = defaultfg, -+ .bg = defaultbg -+ }}; -+ term.screen[i].cur = 0; -+ term.screen[i].off = 0; -+ for (j = 0; j < term.row; ++j) { -+ if (term.col != term.linelen) -+ term.screen[i].buffer[j] = xrealloc(term.screen[i].buffer[j], term.col * sizeof(Glyph)); -+ clearline(term.screen[i].buffer[j], g, 0, term.col); -+ } -+ for (j = term.row; j < term.screen[i].size; ++j) { -+ free(term.screen[i].buffer[j]); -+ term.screen[i].buffer[j] = NULL; -+ } - } -+ tcursor(CURSOR_LOAD); -+ term.linelen = term.col; -+ tfulldirt(); - } - - void - tnew(int col, int row) - { -- term = (Term){ .c = { .attr = { .fg = defaultfg, .bg = defaultbg } } }; -+ int i; -+ term = (Term){}; -+ term.screen[0].buffer = xmalloc(HISTSIZE * sizeof(Line)); -+ term.screen[0].size = HISTSIZE; -+ term.screen[1].buffer = NULL; -+ for (i = 0; i < HISTSIZE; ++i) term.screen[0].buffer[i] = NULL; -+ - tresize(col, row); - treset(); - } -@@ -1046,14 +1080,42 @@ tnew(int col, int row) - void - tswapscreen(void) - { -- Line *tmp = term.line; -- -- term.line = term.alt; -- term.alt = tmp; - term.mode ^= MODE_ALTSCREEN; - tfulldirt(); - } - -+void -+kscrollup(const Arg *a) -+{ -+ int n = a->i; -+ -+ if (IS_SET(MODE_ALTSCREEN)) -+ return; -+ -+ if (n < 0) n = (-n) * term.row; -+ if (n > TSCREEN.size - term.row - TSCREEN.off) n = TSCREEN.size - term.row - TSCREEN.off; -+ while (!TLINE(-n)) --n; -+ TSCREEN.off += n; -+ selscroll(0, n); -+ tfulldirt(); -+} -+ -+void -+kscrolldown(const Arg *a) -+{ -+ -+ int n = a->i; -+ -+ if (IS_SET(MODE_ALTSCREEN)) -+ return; -+ -+ if (n < 0) n = (-n) * term.row; -+ if (n > TSCREEN.off) n = TSCREEN.off; -+ TSCREEN.off -= n; -+ selscroll(0, -n); -+ tfulldirt(); -+} -+ - void - tscrolldown(int orig, int n) - { -@@ -1062,15 +1124,29 @@ tscrolldown(int orig, int n) - - LIMIT(n, 0, term.bot-orig+1); - -- tsetdirt(orig, term.bot-n); -- tclearregion(0, term.bot-n+1, term.col-1, term.bot); -+ /* Ensure that lines are allocated */ -+ for (i = -n; i < 0; i++) { -+ TLINE(i) = ensureline(TLINE(i)); -+ } - -- for (i = term.bot; i >= orig+n; i--) { -- temp = term.line[i]; -- term.line[i] = term.line[i-n]; -- term.line[i-n] = temp; -+ /* Shift non-scrolling areas in ring buffer */ -+ for (i = term.bot+1; i < term.row; i++) { -+ temp = TLINE(i); -+ TLINE(i) = TLINE(i-n); -+ TLINE(i-n) = temp; -+ } -+ for (i = 0; i < orig; i++) { -+ temp = TLINE(i); -+ TLINE(i) = TLINE(i-n); -+ TLINE(i-n) = temp; - } - -+ /* Scroll buffer */ -+ TSCREEN.cur = (TSCREEN.cur + TSCREEN.size - n) % TSCREEN.size; -+ /* Clear lines that have entered the view */ -+ tclearregion(0, orig, term.linelen-1, orig+n-1); -+ /* Redraw portion of the screen that has scrolled */ -+ tsetdirt(orig+n-1, term.bot); - selscroll(orig, n); - } - -@@ -1082,15 +1158,29 @@ tscrollup(int orig, int n) - - LIMIT(n, 0, term.bot-orig+1); - -- tclearregion(0, orig, term.col-1, orig+n-1); -- tsetdirt(orig+n, term.bot); -+ /* Ensure that lines are allocated */ -+ for (i = term.row; i < term.row + n; i++) { -+ TLINE(i) = ensureline(TLINE(i)); -+ } - -- for (i = orig; i <= term.bot-n; i++) { -- temp = term.line[i]; -- term.line[i] = term.line[i+n]; -- term.line[i+n] = temp; -+ /* Shift non-scrolling areas in ring buffer */ -+ for (i = orig-1; i >= 0; i--) { -+ temp = TLINE(i); -+ TLINE(i) = TLINE(i+n); -+ TLINE(i+n) = temp; -+ } -+ for (i = term.row-1; i >term.bot; i--) { -+ temp = TLINE(i); -+ TLINE(i) = TLINE(i+n); -+ TLINE(i+n) = temp; - } - -+ /* Scroll buffer */ -+ TSCREEN.cur = (TSCREEN.cur + n) % TSCREEN.size; -+ /* Clear lines that have entered the view */ -+ tclearregion(0, term.bot-n+1, term.linelen-1, term.bot); -+ /* Redraw portion of the screen that has scrolled */ -+ tsetdirt(orig, term.bot-n+1); - selscroll(orig, -n); - } - -@@ -1194,6 +1284,7 @@ tsetchar(Rune u, const Glyph *attr, int x, int y) - "⎻", "─", "⎼", "⎽", "├", "┤", "┴", "┬", /* p - w */ - "│", "≤", "≥", "π", "≠", "£", "·", /* x - ~ */ - }; -+ Line line = TLINE(y); - - /* - * The table is proudly stolen from rxvt. -@@ -1202,25 +1293,25 @@ tsetchar(Rune u, const Glyph *attr, int x, int y) - BETWEEN(u, 0x41, 0x7e) && vt100_0[u - 0x41]) - utf8decode(vt100_0[u - 0x41], &u, UTF_SIZ); - -- if (term.line[y][x].mode & ATTR_WIDE) { -+ if (line[x].mode & ATTR_WIDE) { - if (x+1 < term.col) { -- term.line[y][x+1].u = ' '; -- term.line[y][x+1].mode &= ~ATTR_WDUMMY; -+ line[x+1].u = ' '; -+ line[x+1].mode &= ~ATTR_WDUMMY; - } -- } else if (term.line[y][x].mode & ATTR_WDUMMY) { -- term.line[y][x-1].u = ' '; -- term.line[y][x-1].mode &= ~ATTR_WIDE; -+ } else if (line[x].mode & ATTR_WDUMMY) { -+ line[x-1].u = ' '; -+ line[x-1].mode &= ~ATTR_WIDE; - } - - term.dirty[y] = 1; -- term.line[y][x] = *attr; -- term.line[y][x].u = u; -+ line[x] = *attr; -+ line[x].u = u; - } - - void - tclearregion(int x1, int y1, int x2, int y2) - { -- int x, y, temp; -+ int x, y, L, S, temp; - Glyph *gp; - - if (x1 > x2) -@@ -1228,15 +1319,16 @@ tclearregion(int x1, int y1, int x2, int y2) - if (y1 > y2) - temp = y1, y1 = y2, y2 = temp; - -- LIMIT(x1, 0, term.col-1); -- LIMIT(x2, 0, term.col-1); -+ LIMIT(x1, 0, term.linelen-1); -+ LIMIT(x2, 0, term.linelen-1); - LIMIT(y1, 0, term.row-1); - LIMIT(y2, 0, term.row-1); - -+ L = TLINEOFFSET(y1); - for (y = y1; y <= y2; y++) { - term.dirty[y] = 1; - for (x = x1; x <= x2; x++) { -- gp = &term.line[y][x]; -+ gp = &TSCREEN.buffer[L][x]; - if (selected(x, y)) - selclear(); - gp->fg = term.c.attr.fg; -@@ -1244,6 +1336,7 @@ tclearregion(int x1, int y1, int x2, int y2) - gp->mode = 0; - gp->u = ' '; - } -+ L = (L + 1) % TSCREEN.size; - } - } - -@@ -1258,7 +1351,7 @@ tdeletechar(int n) - dst = term.c.x; - src = term.c.x + n; - size = term.col - src; -- line = term.line[term.c.y]; -+ line = TLINE(term.c.y); - - memmove(&line[dst], &line[src], size * sizeof(Glyph)); - tclearregion(term.col-n, term.c.y, term.col-1, term.c.y); -@@ -1275,7 +1368,7 @@ tinsertblank(int n) - dst = term.c.x + n; - src = term.c.x; - size = term.col - dst; -- line = term.line[term.c.y]; -+ line = TLINE(term.c.y); - - memmove(&line[dst], &line[src], size * sizeof(Glyph)); - tclearregion(src, term.c.y, dst - 1, term.c.y); -@@ -2079,7 +2172,7 @@ tdumpline(int n) - char buf[UTF_SIZ]; - const Glyph *bp, *end; - -- bp = &term.line[n][0]; -+ bp = &TLINE(n)[0]; - end = &bp[MIN(tlinelen(n), term.col) - 1]; - if (bp != end || bp->u != ' ') { - for ( ; bp <= end; ++bp) -@@ -2466,11 +2559,11 @@ check_control_code: - if (selected(term.c.x, term.c.y)) - selclear(); - -- gp = &term.line[term.c.y][term.c.x]; -+ gp = &TLINE(term.c.y)[term.c.x]; - if (IS_SET(MODE_WRAP) && (term.c.state & CURSOR_WRAPNEXT)) { - gp->mode |= ATTR_WRAP; - tnewline(1); -- gp = &term.line[term.c.y][term.c.x]; -+ gp = &TLINE(term.c.y)[term.c.x]; - } - - if (IS_SET(MODE_INSERT) && term.c.x+width < term.col) { -@@ -2483,7 +2576,7 @@ check_control_code: - tnewline(1); - else - tmoveto(term.col - width, term.c.y); -- gp = &term.line[term.c.y][term.c.x]; -+ gp = &TLINE(term.c.y)[term.c.x]; - } - - tsetchar(u, &term.c.attr, term.c.x, term.c.y); -@@ -2514,6 +2607,11 @@ twrite(const char *buf, int buflen, int show_ctrl) - Rune u; - int n; - -+ if (TSCREEN.off) { -+ TSCREEN.off = 0; -+ tfulldirt(); -+ } -+ - for (n = 0; n < buflen; n += charsize) { - if (IS_SET(MODE_UTF8)) { - /* process a complete utf8 char */ -@@ -2540,56 +2638,85 @@ twrite(const char *buf, int buflen, int show_ctrl) - } - - void --tresize(int col, int row) -+clearline(Line line, Glyph g, int x, int xend) - { - int i; -+ g.mode = 0; -+ g.u = ' '; -+ for (i = x; i < xend; ++i) { -+ line[i] = g; -+ } -+} -+ -+Line -+ensureline(Line line) -+{ -+ if (!line) { -+ line = xmalloc(term.linelen * sizeof(Glyph)); -+ } -+ return line; -+} -+ -+void -+tresize(int col, int row) -+{ -+ int i, j; - int minrow = MIN(row, term.row); - int mincol = MIN(col, term.col); -+ int linelen = MAX(col, term.linelen); - int *bp; -- TCursor c; - -- if (col < 1 || row < 1) { -+ if (col < 1 || row < 1 || row > HISTSIZE) { - fprintf(stderr, - "tresize: error resizing to %dx%d\n", col, row); - return; - } - -- /* -- * 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 <= term.c.y - row; i++) { -- free(term.line[i]); -- free(term.alt[i]); -+ /* Shift buffer to keep the cursor where we expect it */ -+ if (row <= term.c.y) { -+ term.screen[0].cur = (term.screen[0].cur - row + term.c.y + 1) % term.screen[0].size; -+ } -+ -+ /* Resize and clear line buffers as needed */ -+ if (linelen > term.linelen) { -+ for (i = 0; i < term.screen[0].size; ++i) { -+ if (term.screen[0].buffer[i]) { -+ term.screen[0].buffer[i] = xrealloc(term.screen[0].buffer[i], linelen * sizeof(Glyph)); -+ clearline(term.screen[0].buffer[i], term.c.attr, term.linelen, linelen); -+ } -+ } -+ for (i = 0; i < minrow; ++i) { -+ term.screen[1].buffer[i] = xrealloc(term.screen[1].buffer[i], linelen * sizeof(Glyph)); -+ clearline(term.screen[1].buffer[i], term.c.attr, term.linelen, linelen); -+ } - } -- /* ensure that both src and dst are not NULL */ -- if (i > 0) { -- memmove(term.line, term.line + i, row * sizeof(Line)); -- memmove(term.alt, term.alt + i, row * sizeof(Line)); -+ /* Allocate all visible lines for regular line buffer */ -+ for (j = term.screen[0].cur, i = 0; i < row; ++i, j = (j + 1) % term.screen[0].size) -+ { -+ if (!term.screen[0].buffer[j]) { -+ term.screen[0].buffer[j] = xmalloc(linelen * sizeof(Glyph)); -+ } -+ if (i >= term.row) { -+ clearline(term.screen[0].buffer[j], term.c.attr, 0, linelen); -+ } - } -- for (i += row; i < term.row; i++) { -- free(term.line[i]); -- free(term.alt[i]); -+ /* Resize alt screen */ -+ term.screen[1].cur = 0; -+ term.screen[1].size = row; -+ for (i = row; i < term.row; ++i) { -+ free(term.screen[1].buffer[i]); -+ } -+ term.screen[1].buffer = xrealloc(term.screen[1].buffer, row * sizeof(Line)); -+ for (i = term.row; i < row; ++i) { -+ term.screen[1].buffer[i] = xmalloc(linelen * sizeof(Glyph)); -+ clearline(term.screen[1].buffer[i], term.c.attr, 0, linelen); - } - - /* resize to new height */ -- term.line = xrealloc(term.line, row * sizeof(Line)); -- term.alt = xrealloc(term.alt, row * sizeof(Line)); - term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty)); - term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs)); - -- /* resize each row to new width, zero-pad if needed */ -- for (i = 0; i < minrow; i++) { -- term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph)); -- term.alt[i] = xrealloc(term.alt[i], col * sizeof(Glyph)); -- } -- -- /* allocate any new rows */ -- for (/* i = minrow */; i < row; i++) { -- term.line[i] = xmalloc(col * sizeof(Glyph)); -- term.alt[i] = xmalloc(col * sizeof(Glyph)); -- } -+ /* fix tabstops */ - if (col > term.col) { - bp = term.tabs + term.col; - -@@ -2599,26 +2726,16 @@ tresize(int col, int row) - for (bp += tabspaces; bp < term.tabs + col; bp += tabspaces) - *bp = 1; - } -+ - /* update terminal size */ - term.col = col; - term.row = row; -+ term.linelen = linelen; - /* reset scrolling region */ - tsetscroll(0, row-1); - /* make use of the LIMIT in tmoveto */ - tmoveto(term.c.x, term.c.y); -- /* Clearing both screens (it makes dirty all lines) */ -- c = term.c; -- for (i = 0; i < 2; i++) { -- if (mincol < col && 0 < minrow) { -- tclearregion(mincol, 0, col - 1, minrow - 1); -- } -- if (0 < col && minrow < row) { -- tclearregion(0, minrow, col - 1, row - 1); -- } -- tswapscreen(); -- tcursor(CURSOR_LOAD); -- } -- term.c = c; -+ tfulldirt(); - } - - void -@@ -2630,14 +2747,15 @@ resettitle(void) - void - drawregion(int x1, int y1, int x2, int y2) - { -- int y; -+ int y, L; - -+ L = TLINEOFFSET(y1); - for (y = y1; y < y2; y++) { -- if (!term.dirty[y]) -- continue; -- -- term.dirty[y] = 0; -- xdrawline(term.line[y], x1, y, x2); -+ if (term.dirty[y]) { -+ term.dirty[y] = 0; -+ xdrawline(TSCREEN.buffer[L], x1, y, x2); -+ } -+ L = (L + 1) % TSCREEN.size; - } - } - -@@ -2652,14 +2770,15 @@ draw(void) - /* adjust cursor position */ - LIMIT(term.ocx, 0, term.col-1); - LIMIT(term.ocy, 0, term.row-1); -- if (term.line[term.ocy][term.ocx].mode & ATTR_WDUMMY) -+ if (TLINE(term.ocy)[term.ocx].mode & ATTR_WDUMMY) - term.ocx--; -- if (term.line[term.c.y][cx].mode & ATTR_WDUMMY) -+ if (TLINE(term.c.y)[cx].mode & ATTR_WDUMMY) - cx--; - - drawregion(0, 0, term.col, term.row); -- xdrawcursor(cx, term.c.y, term.line[term.c.y][cx], -- term.ocx, term.ocy, term.line[term.ocy][term.ocx]); -+ if (TSCREEN.off == 0) -+ xdrawcursor(cx, term.c.y, TLINE(term.c.y)[cx], -+ term.ocx, term.ocy, TLINE(term.ocy)[term.ocx]); - term.ocx = cx; - term.ocy = term.c.y; - xfinishdraw(); -diff --git a/st.h b/st.h -index fd3b0d8..3cea73b 100644 ---- a/st.h -+++ b/st.h -@@ -19,6 +19,7 @@ - - #define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b)) - #define IS_TRUECOL(x) (1 << 24 & (x)) -+#define HISTSIZE 2000 - - enum glyph_attribute { - ATTR_NULL = 0, -diff --git a/x.c b/x.c -index bd23686..25785a6 100644 ---- a/x.c -+++ b/x.c -@@ -59,6 +59,8 @@ static void zoom(const Arg *); - static void zoomabs(const Arg *); - static void zoomreset(const Arg *); - static void ttysend(const Arg *); -+void kscrollup(const Arg *); -+void kscrolldown(const Arg *); - - /* config.h for applying patches and the configuration. */ - #include "config.h" diff --git a/st.o b/st.o deleted file mode 100644 index a6cb30901d5d4f48c0035247f6cc2d0d89e0c1a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83304 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 diff --git a/x.c.orig b/x.c.orig deleted file mode 100644 index d73152b..0000000 --- a/x.c.orig +++ /dev/null @@ -1,2108 +0,0 @@ -/* See LICENSE for license details. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -char *argv0; -#include "arg.h" -#include "st.h" -#include "win.h" - -/* types used in config.h */ -typedef struct { - uint mod; - KeySym keysym; - void (*func)(const Arg *); - const Arg arg; -} Shortcut; - -typedef struct { - uint mod; - uint button; - void (*func)(const Arg *); - const Arg arg; - uint release; -} MouseShortcut; - -typedef struct { - KeySym k; - uint mask; - char *s; - /* three-valued logic variables: 0 indifferent, 1 on, -1 off */ - signed char appkey; /* application keypad */ - signed char appcursor; /* application cursor */ -} Key; - -/* X modifiers */ -#define XK_ANY_MOD UINT_MAX -#define XK_NO_MOD 0 -#define XK_SWITCH_MOD (1<<13|1<<14) - -/* function definitions used in config.h */ -static void clipcopy(const Arg *); -static void clippaste(const Arg *); -static void numlock(const Arg *); -static void selpaste(const Arg *); -static void zoom(const Arg *); -static void zoomabs(const Arg *); -static void zoomreset(const Arg *); -static void ttysend(const Arg *); - -/* config.h for applying patches and the configuration. */ -#include "config.h" - -/* XEMBED messages */ -#define XEMBED_FOCUS_IN 4 -#define XEMBED_FOCUS_OUT 5 - -/* macros */ -#define IS_SET(flag) ((win.mode & (flag)) != 0) -#define TRUERED(x) (((x) & 0xff0000) >> 8) -#define TRUEGREEN(x) (((x) & 0xff00)) -#define TRUEBLUE(x) (((x) & 0xff) << 8) - -typedef XftDraw *Draw; -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; - Window win; - Drawable buf; - GlyphFontSpec *specbuf; /* font spec buffer used for rendering */ - Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid; - struct { - XIM xim; - XIC xic; - XPoint spot; - XVaNestedList spotlist; - } ime; - Draw draw; - Visual *vis; - XSetWindowAttributes attrs; - int scr; - int isfixed; /* is fixed geometry? */ - int l, t; /* left and top offset */ - int gm; /* geometry mask */ -} XWindow; - -typedef struct { - Atom xtarget; - char *primary, *clipboard; - struct timespec tclick1; - struct timespec tclick2; -} XSelection; - -/* Font structure */ -#define Font Font_ -typedef struct { - int height; - int width; - int ascent; - int descent; - int badslant; - int badweight; - short lbearing; - short rbearing; - XftFont *match; - FcFontSet *set; - FcPattern *pattern; -} Font; - -/* Drawing Context */ -typedef struct { - Color *col; - size_t collen; - Font font, bfont, ifont, ibfont; - GC gc; -} DC; - -static inline ushort sixd_to_16bit(int); -static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int); -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 int ximopen(Display *); -static void ximinstantiate(Display *, XPointer, XPointer); -static void ximdestroy(XIM, XPointer, XPointer); -static int xicdestroy(XIC, XPointer, XPointer); -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(const char *, double); -static void xunloadfont(Font *); -static void xunloadfonts(void); -static void xsetenv(void); -static void xseturgency(int); -static int evcol(XEvent *); -static int evrow(XEvent *); - -static void expose(XEvent *); -static void visibility(XEvent *); -static void unmap(XEvent *); -static void kpress(XEvent *); -static void cmessage(XEvent *); -static void resize(XEvent *); -static void focus(XEvent *); -static uint buttonmask(uint); -static int mouseaction(XEvent *, uint); -static void brelease(XEvent *); -static void bpress(XEvent *); -static void bmotion(XEvent *); -static void propnotify(XEvent *); -static void selnotify(XEvent *); -static void selclear_(XEvent *); -static void selrequest(XEvent *); -static void setsel(char *, Time); -static void mousesel(XEvent *, int); -static void mousereport(XEvent *); -static char *kmap(KeySym, uint); -static int match(uint, uint); - -static void run(void); -static void usage(void); - -static void (*handler[LASTEvent])(XEvent *) = { - [KeyPress] = kpress, - [ClientMessage] = cmessage, - [ConfigureNotify] = resize, - [VisibilityNotify] = visibility, - [UnmapNotify] = unmap, - [Expose] = expose, - [FocusIn] = focus, - [FocusOut] = focus, - [MotionNotify] = bmotion, - [ButtonPress] = bpress, - [ButtonRelease] = brelease, -/* - * Uncomment if you want the selection to disappear when you select something - * different in another window. - */ -/* [SelectionClear] = selclear_, */ - [SelectionNotify] = selnotify, -/* - * PropertyNotify is only turned on when there is some INCR transfer happening - * for the selection retrieval. - */ - [PropertyNotify] = propnotify, - [SelectionRequest] = selrequest, -}; - -/* Globals */ -static DC dc; -static XWindow xw; -static XSelection xsel; -static TermWindow win; - -/* Font Ring Cache */ -enum { - FRC_NORMAL, - FRC_ITALIC, - FRC_BOLD, - FRC_ITALICBOLD -}; - -typedef struct { - XftFont *font; - int flags; - Rune unicodep; -} Fontcache; - -/* Fontcache is an array now. A new font will be appended to the array. */ -static Fontcache *frc = NULL; -static int frclen = 0; -static int frccap = 0; -static char *usedfont = NULL; -static double usedfontsize = 0; -static double defaultfontsize = 0; - -static char *opt_class = NULL; -static char **opt_cmd = NULL; -static char *opt_embed = NULL; -static char *opt_font = NULL; -static char *opt_io = NULL; -static char *opt_line = NULL; -static char *opt_name = NULL; -static char *opt_title = NULL; - -static uint buttons; /* bit field of pressed buttons */ - -void -clipcopy(const Arg *dummy) -{ - Atom clipboard; - - free(xsel.clipboard); - xsel.clipboard = NULL; - - if (xsel.primary != NULL) { - xsel.clipboard = xstrdup(xsel.primary); - clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime); - } -} - -void -clippaste(const Arg *dummy) -{ - Atom clipboard; - - clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - XConvertSelection(xw.dpy, clipboard, xsel.xtarget, clipboard, - xw.win, CurrentTime); -} - -void -selpaste(const Arg *dummy) -{ - XConvertSelection(xw.dpy, XA_PRIMARY, xsel.xtarget, XA_PRIMARY, - xw.win, CurrentTime); -} - -void -numlock(const Arg *dummy) -{ - win.mode ^= MODE_NUMLOCK; -} - -void -zoom(const Arg *arg) -{ - Arg larg; - - larg.f = usedfontsize + arg->f; - zoomabs(&larg); -} - -void -zoomabs(const Arg *arg) -{ - xunloadfonts(); - xloadfonts(usedfont, arg->f); - cresize(0, 0); - redraw(); - xhints(); -} - -void -zoomreset(const Arg *arg) -{ - Arg larg; - - if (defaultfontsize > 0) { - larg.f = defaultfontsize; - zoomabs(&larg); - } -} - -void -ttysend(const Arg *arg) -{ - ttywrite(arg->s, strlen(arg->s), 1); -} - -int -evcol(XEvent *e) -{ - int x = e->xbutton.x - borderpx; - LIMIT(x, 0, win.tw - 1); - return x / win.cw; -} - -int -evrow(XEvent *e) -{ - int y = e->xbutton.y - borderpx; - LIMIT(y, 0, win.th - 1); - return y / win.ch; -} - -void -mousesel(XEvent *e, int done) -{ - int type, seltype = SEL_REGULAR; - uint state = e->xbutton.state & ~(Button1Mask | forcemousemod); - - for (type = 1; type < LEN(selmasks); ++type) { - if (match(selmasks[type], state)) { - seltype = type; - break; - } - } - selextend(evcol(e), evrow(e), seltype, done); - if (done) - setsel(getsel(), e->xbutton.time); -} - -void -mousereport(XEvent *e) -{ - int len, btn, code; - int x = evcol(e), y = evrow(e); - int state = e->xbutton.state; - char buf[40]; - static int ox, oy; - - if (e->type == MotionNotify) { - if (x == ox && y == oy) - return; - if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY)) - return; - /* MODE_MOUSEMOTION: no reporting if no button is pressed */ - if (IS_SET(MODE_MOUSEMOTION) && buttons == 0) - return; - /* Set btn to lowest-numbered pressed button, or 12 if no - * buttons are pressed. */ - for (btn = 1; btn <= 11 && !(buttons & (1<<(btn-1))); btn++) - ; - code = 32; - } else { - btn = e->xbutton.button; - /* Only buttons 1 through 11 can be encoded */ - if (btn < 1 || btn > 11) - return; - if (e->type == ButtonRelease) { - /* MODE_MOUSEX10: no button release reporting */ - if (IS_SET(MODE_MOUSEX10)) - return; - /* Don't send release events for the scroll wheel */ - if (btn == 4 || btn == 5) - return; - } - code = 0; - } - - ox = x; - oy = y; - - /* Encode btn into code. If no button is pressed for a motion event in - * MODE_MOUSEMANY, then encode it as a release. */ - if ((!IS_SET(MODE_MOUSESGR) && e->type == ButtonRelease) || btn == 12) - code += 3; - else if (btn >= 8) - code += 128 + btn - 8; - else if (btn >= 4) - code += 64 + btn - 4; - else - code += btn - 1; - - if (!IS_SET(MODE_MOUSEX10)) { - code += ((state & ShiftMask ) ? 4 : 0) - + ((state & Mod1Mask ) ? 8 : 0) /* meta key: alt */ - + ((state & ControlMask) ? 16 : 0); - } - - if (IS_SET(MODE_MOUSESGR)) { - len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c", - code, x+1, y+1, - e->type == ButtonRelease ? 'm' : 'M'); - } else if (x < 223 && y < 223) { - len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", - 32+code, 32+x+1, 32+y+1); - } else { - return; - } - - ttywrite(buf, len, 0); -} - -uint -buttonmask(uint button) -{ - return button == Button1 ? Button1Mask - : button == Button2 ? Button2Mask - : button == Button3 ? Button3Mask - : button == Button4 ? Button4Mask - : button == Button5 ? Button5Mask - : 0; -} - -int -mouseaction(XEvent *e, uint release) -{ - MouseShortcut *ms; - - /* ignore Buttonmask for Button - it's set on release */ - uint state = e->xbutton.state & ~buttonmask(e->xbutton.button); - - for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { - if (ms->release == release && - ms->button == e->xbutton.button && - (match(ms->mod, state) || /* exact or forced */ - match(ms->mod, state & ~forcemousemod))) { - ms->func(&(ms->arg)); - return 1; - } - } - - return 0; -} - -void -bpress(XEvent *e) -{ - int btn = e->xbutton.button; - struct timespec now; - int snap; - - if (1 <= btn && btn <= 11) - buttons |= 1 << (btn-1); - - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { - mousereport(e); - return; - } - - if (mouseaction(e, 0)) - return; - - if (btn == Button1) { - /* - * If the user clicks below predefined timeouts specific - * snapping behaviour is exposed. - */ - clock_gettime(CLOCK_MONOTONIC, &now); - if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) { - snap = SNAP_LINE; - } else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) { - snap = SNAP_WORD; - } else { - snap = 0; - } - xsel.tclick2 = xsel.tclick1; - xsel.tclick1 = now; - - selstart(evcol(e), evrow(e), snap); - } -} - -void -propnotify(XEvent *e) -{ - XPropertyEvent *xpev; - Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - - xpev = &e->xproperty; - if (xpev->state == PropertyNewValue && - (xpev->atom == XA_PRIMARY || - xpev->atom == clipboard)) { - selnotify(e); - } -} - -void -selnotify(XEvent *e) -{ - ulong nitems, ofs, rem; - int format; - uchar *data, *last, *repl; - Atom type, incratom, property = None; - - incratom = XInternAtom(xw.dpy, "INCR", 0); - - ofs = 0; - if (e->type == SelectionNotify) - property = e->xselection.property; - else if (e->type == PropertyNotify) - property = e->xproperty.atom; - - if (property == None) - return; - - do { - if (XGetWindowProperty(xw.dpy, xw.win, property, ofs, - BUFSIZ/4, False, AnyPropertyType, - &type, &format, &nitems, &rem, - &data)) { - fprintf(stderr, "Clipboard allocation failed\n"); - return; - } - - if (e->type == PropertyNotify && nitems == 0 && rem == 0) { - /* - * If there is some PropertyNotify with no data, then - * this is the signal of the selection owner that all - * data has been transferred. We won't need to receive - * PropertyNotify events anymore. - */ - MODBIT(xw.attrs.event_mask, 0, PropertyChangeMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, - &xw.attrs); - } - - if (type == incratom) { - /* - * Activate the PropertyNotify events so we receive - * when the selection owner does send us the next - * chunk of data. - */ - MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, - &xw.attrs); - - /* - * Deleting the property is the transfer start signal. - */ - XDeleteProperty(xw.dpy, xw.win, (int)property); - continue; - } - - /* - * As seen in getsel: - * Line endings are inconsistent in the terminal and GUI world - * copy and pasting. When receiving some selection data, - * replace all '\n' with '\r'. - * FIXME: Fix the computer world. - */ - repl = data; - last = data + nitems * format / 8; - while ((repl = memchr(repl, '\n', last - repl))) { - *repl++ = '\r'; - } - - if (IS_SET(MODE_BRCKTPASTE) && ofs == 0) - ttywrite("\033[200~", 6, 0); - ttywrite((char *)data, nitems * format / 8, 1); - if (IS_SET(MODE_BRCKTPASTE) && rem == 0) - ttywrite("\033[201~", 6, 0); - XFree(data); - /* number of 32-bit chunks returned */ - ofs += nitems * format / 32; - } while (rem > 0); - - /* - * Deleting the property again tells the selection owner to send the - * next data chunk in the property. - */ - XDeleteProperty(xw.dpy, xw.win, (int)property); -} - -void -xclipcopy(void) -{ - clipcopy(NULL); -} - -void -selclear_(XEvent *e) -{ - selclear(); -} - -void -selrequest(XEvent *e) -{ - XSelectionRequestEvent *xsre; - XSelectionEvent xev; - Atom xa_targets, string, clipboard; - char *seltext; - - xsre = (XSelectionRequestEvent *) e; - xev.type = SelectionNotify; - xev.requestor = xsre->requestor; - xev.selection = xsre->selection; - xev.target = xsre->target; - xev.time = xsre->time; - if (xsre->property == None) - xsre->property = xsre->target; - - /* reject */ - xev.property = None; - - xa_targets = XInternAtom(xw.dpy, "TARGETS", 0); - if (xsre->target == xa_targets) { - /* respond with the supported type */ - string = xsel.xtarget; - XChangeProperty(xsre->display, xsre->requestor, xsre->property, - XA_ATOM, 32, PropModeReplace, - (uchar *) &string, 1); - xev.property = xsre->property; - } else if (xsre->target == xsel.xtarget || xsre->target == XA_STRING) { - /* - * xith XA_STRING non ascii characters may be incorrect in the - * requestor. It is not our problem, use utf8. - */ - clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - if (xsre->selection == XA_PRIMARY) { - seltext = xsel.primary; - } else if (xsre->selection == clipboard) { - seltext = xsel.clipboard; - } else { - fprintf(stderr, - "Unhandled clipboard selection 0x%lx\n", - xsre->selection); - return; - } - if (seltext != NULL) { - XChangeProperty(xsre->display, xsre->requestor, - xsre->property, xsre->target, - 8, PropModeReplace, - (uchar *)seltext, strlen(seltext)); - xev.property = xsre->property; - } - } - - /* all done, send a notification to the listener */ - if (!XSendEvent(xsre->display, xsre->requestor, 1, 0, (XEvent *) &xev)) - fprintf(stderr, "Error sending SelectionNotify event\n"); -} - -void -setsel(char *str, Time t) -{ - if (!str) - return; - - free(xsel.primary); - xsel.primary = str; - - XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t); - if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) - selclear(); -} - -void -xsetsel(char *str) -{ - setsel(str, CurrentTime); -} - -void -brelease(XEvent *e) -{ - int btn = e->xbutton.button; - - if (1 <= btn && btn <= 11) - buttons &= ~(1 << (btn-1)); - - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { - mousereport(e); - return; - } - - if (mouseaction(e, 1)) - return; - if (btn == Button1) - mousesel(e, 1); -} - -void -bmotion(XEvent *e) -{ - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { - mousereport(e); - return; - } - - mousesel(e, 0); -} - -void -cresize(int width, int height) -{ - int col, row; - - if (width != 0) - win.w = width; - if (height != 0) - win.h = height; - - col = (win.w - 2 * borderpx) / win.cw; - row = (win.h - 2 * borderpx) / win.ch; - col = MAX(1, col); - row = MAX(1, row); - - tresize(col, row); - xresize(col, row); - ttyresize(win.tw, win.th); -} - -void -xresize(int col, int row) -{ - win.tw = col * win.cw; - win.th = row * win.ch; - - XFreePixmap(xw.dpy, xw.buf); - xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, - DefaultDepth(xw.dpy, xw.scr)); - XftDrawChange(xw.draw, xw.buf); - xclear(0, 0, win.w, win.h); - - /* resize to new width */ - xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec)); -} - -ushort -sixd_to_16bit(int x) -{ - return x == 0 ? 0 : 0x3737 + 0x2828 * x; -} - -int -xloadcolor(int i, const char *name, Color *ncolor) -{ - XRenderColor color = { .alpha = 0xffff }; - - if (!name) { - if (BETWEEN(i, 16, 255)) { /* 256 color */ - if (i < 6*6*6+16) { /* same colors as xterm */ - color.red = sixd_to_16bit( ((i-16)/36)%6 ); - color.green = sixd_to_16bit( ((i-16)/6) %6 ); - color.blue = sixd_to_16bit( ((i-16)/1) %6 ); - } else { /* greyscale */ - color.red = 0x0808 + 0x0a0a * (i - (6*6*6+16)); - color.green = color.blue = color.red; - } - return XftColorAllocValue(xw.dpy, xw.vis, - xw.cmap, &color, ncolor); - } else - name = colorname[i]; - } - - return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor); -} - -void -xloadcols(void) -{ - int i; - static int loaded; - Color *cp; - - if (loaded) { - for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp) - XftColorFree(xw.dpy, xw.vis, xw.cmap, cp); - } else { - dc.collen = MAX(LEN(colorname), 256); - dc.col = xmalloc(dc.collen * sizeof(Color)); - } - - for (i = 0; i < dc.collen; i++) - if (!xloadcolor(i, NULL, &dc.col[i])) { - if (colorname[i]) - die("could not allocate color '%s'\n", colorname[i]); - else - die("could not allocate color %d\n", i); - } - loaded = 1; -} - -int -xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b) -{ - if (!BETWEEN(x, 0, dc.collen - 1)) - return 1; - - *r = dc.col[x].color.red >> 8; - *g = dc.col[x].color.green >> 8; - *b = dc.col[x].color.blue >> 8; - - return 0; -} - -int -xsetcolorname(int x, const char *name) -{ - Color ncolor; - - if (!BETWEEN(x, 0, dc.collen - 1)) - return 1; - - if (!xloadcolor(x, name, &ncolor)) - return 1; - - XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]); - dc.col[x] = ncolor; - - return 0; -} - -/* - * Absolute coordinates. - */ -void -xclear(int x1, int y1, int x2, int y2) -{ - XftDrawRect(xw.draw, - &dc.col[IS_SET(MODE_REVERSE)? defaultfg : defaultbg], - x1, y1, x2-x1, y2-y1); -} - -void -xhints(void) -{ - XClassHint class = {opt_name ? opt_name : termname, - opt_class ? opt_class : termname}; - XWMHints wm = {.flags = InputHint, .input = 1}; - XSizeHints *sizeh; - - sizeh = XAllocSizeHints(); - - sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; - sizeh->height = win.h; - sizeh->width = win.w; - sizeh->height_inc = win.ch; - sizeh->width_inc = win.cw; - sizeh->base_height = 2 * borderpx; - sizeh->base_width = 2 * borderpx; - sizeh->min_height = win.ch + 2 * borderpx; - sizeh->min_width = win.cw + 2 * borderpx; - if (xw.isfixed) { - sizeh->flags |= PMaxSize; - sizeh->min_width = sizeh->max_width = win.w; - sizeh->min_height = sizeh->max_height = win.h; - } - if (xw.gm & (XValue|YValue)) { - sizeh->flags |= USPosition | PWinGravity; - sizeh->x = xw.l; - sizeh->y = xw.t; - sizeh->win_gravity = xgeommasktogravity(xw.gm); - } - - XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm, - &class); - XFree(sizeh); -} - -int -xgeommasktogravity(int mask) -{ - switch (mask & (XNegative|YNegative)) { - case 0: - return NorthWestGravity; - case XNegative: - return NorthEastGravity; - case YNegative: - return SouthWestGravity; - } - - return SouthEastGravity; -} - -int -xloadfont(Font *f, FcPattern *pattern) -{ - FcPattern *configured; - FcPattern *match; - FcResult result; - XGlyphInfo extents; - int wantattr, haveattr; - - /* - * Manually configure instead of calling XftMatchFont - * so that we can use the configured pattern for - * "missing glyph" lookups. - */ - configured = FcPatternDuplicate(pattern); - if (!configured) - return 1; - - FcConfigSubstitute(NULL, configured, FcMatchPattern); - XftDefaultSubstitute(xw.dpy, xw.scr, configured); - - match = FcFontMatch(NULL, configured, &result); - if (!match) { - FcPatternDestroy(configured); - return 1; - } - - if (!(f->match = XftFontOpenPattern(xw.dpy, match))) { - FcPatternDestroy(configured); - FcPatternDestroy(match); - return 1; - } - - if ((XftPatternGetInteger(pattern, "slant", 0, &wantattr) == - XftResultMatch)) { - /* - * Check if xft was unable to find a font with the appropriate - * slant but gave us one anyway. Try to mitigate. - */ - if ((XftPatternGetInteger(f->match->pattern, "slant", 0, - &haveattr) != XftResultMatch) || haveattr < wantattr) { - f->badslant = 1; - fputs("font slant does not match\n", stderr); - } - } - - if ((XftPatternGetInteger(pattern, "weight", 0, &wantattr) == - XftResultMatch)) { - if ((XftPatternGetInteger(f->match->pattern, "weight", 0, - &haveattr) != XftResultMatch) || haveattr != wantattr) { - f->badweight = 1; - fputs("font weight does not match\n", stderr); - } - } - - XftTextExtentsUtf8(xw.dpy, f->match, - (const FcChar8 *) ascii_printable, - strlen(ascii_printable), &extents); - - f->set = NULL; - f->pattern = configured; - - f->ascent = f->match->ascent; - f->descent = f->match->descent; - f->lbearing = 0; - f->rbearing = f->match->max_advance_width; - - f->height = f->ascent + f->descent; - f->width = DIVCEIL(extents.xOff, strlen(ascii_printable)); - - return 0; -} - -void -xloadfonts(const char *fontstr, double fontsize) -{ - FcPattern *pattern; - double fontval; - - if (fontstr[0] == '-') - pattern = XftXlfdParse(fontstr, False, False); - else - pattern = FcNameParse((const FcChar8 *)fontstr); - - if (!pattern) - die("can't open font %s\n", fontstr); - - if (fontsize > 1) { - FcPatternDel(pattern, FC_PIXEL_SIZE); - FcPatternDel(pattern, FC_SIZE); - FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)fontsize); - usedfontsize = fontsize; - } else { - if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) == - FcResultMatch) { - usedfontsize = fontval; - } else if (FcPatternGetDouble(pattern, FC_SIZE, 0, &fontval) == - FcResultMatch) { - usedfontsize = -1; - } else { - /* - * Default font size is 12, if none given. This is to - * have a known usedfontsize value. - */ - FcPatternAddDouble(pattern, FC_PIXEL_SIZE, 12); - usedfontsize = 12; - } - defaultfontsize = usedfontsize; - } - - if (xloadfont(&dc.font, pattern)) - die("can't open font %s\n", fontstr); - - if (usedfontsize < 0) { - FcPatternGetDouble(dc.font.match->pattern, - FC_PIXEL_SIZE, 0, &fontval); - usedfontsize = fontval; - if (fontsize == 0) - defaultfontsize = fontval; - } - - /* Setting character width and height. */ - win.cw = ceilf(dc.font.width * cwscale); - win.ch = ceilf(dc.font.height * chscale); - - FcPatternDel(pattern, FC_SLANT); - FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); - if (xloadfont(&dc.ifont, pattern)) - die("can't open font %s\n", fontstr); - - FcPatternDel(pattern, FC_WEIGHT); - FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); - if (xloadfont(&dc.ibfont, pattern)) - die("can't open font %s\n", fontstr); - - FcPatternDel(pattern, FC_SLANT); - FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); - if (xloadfont(&dc.bfont, pattern)) - die("can't open font %s\n", fontstr); - - FcPatternDestroy(pattern); -} - -void -xunloadfont(Font *f) -{ - XftFontClose(xw.dpy, f->match); - FcPatternDestroy(f->pattern); - if (f->set) - FcFontSetDestroy(f->set); -} - -void -xunloadfonts(void) -{ - /* Free the loaded fonts in the font cache. */ - while (frclen > 0) - XftFontClose(xw.dpy, frc[--frclen].font); - - xunloadfont(&dc.font); - xunloadfont(&dc.bfont); - xunloadfont(&dc.ifont); - xunloadfont(&dc.ibfont); -} - -int -ximopen(Display *dpy) -{ - XIMCallback imdestroy = { .client_data = NULL, .callback = ximdestroy }; - XICCallback icdestroy = { .client_data = NULL, .callback = xicdestroy }; - - xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL); - if (xw.ime.xim == NULL) - return 0; - - if (XSetIMValues(xw.ime.xim, XNDestroyCallback, &imdestroy, NULL)) - fprintf(stderr, "XSetIMValues: " - "Could not set XNDestroyCallback.\n"); - - xw.ime.spotlist = XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot, - NULL); - - if (xw.ime.xic == NULL) { - xw.ime.xic = XCreateIC(xw.ime.xim, XNInputStyle, - XIMPreeditNothing | XIMStatusNothing, - XNClientWindow, xw.win, - XNDestroyCallback, &icdestroy, - NULL); - } - if (xw.ime.xic == NULL) - fprintf(stderr, "XCreateIC: Could not create input context.\n"); - - return 1; -} - -void -ximinstantiate(Display *dpy, XPointer client, XPointer call) -{ - if (ximopen(dpy)) - XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, - ximinstantiate, NULL); -} - -void -ximdestroy(XIM xim, XPointer client, XPointer call) -{ - xw.ime.xim = NULL; - XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, - ximinstantiate, NULL); - XFree(xw.ime.spotlist); -} - -int -xicdestroy(XIC xim, XPointer client, XPointer call) -{ - xw.ime.xic = NULL; - return 1; -} - -void -xinit(int cols, int rows) -{ - XGCValues gcvalues; - Cursor cursor; - Window parent, root; - pid_t thispid = getpid(); - XColor xmousefg, xmousebg; - - if (!(xw.dpy = XOpenDisplay(NULL))) - die("can't open display\n"); - xw.scr = XDefaultScreen(xw.dpy); - xw.vis = XDefaultVisual(xw.dpy, xw.scr); - - /* font */ - if (!FcInit()) - die("could not init fontconfig.\n"); - - usedfont = (opt_font == NULL)? font : opt_font; - xloadfonts(usedfont, 0); - - /* colors */ - xw.cmap = XDefaultColormap(xw.dpy, xw.scr); - xloadcols(); - - /* adjust fixed window geometry */ - 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) - xw.t += DisplayHeight(xw.dpy, xw.scr) - win.h - 2; - - /* Events */ - xw.attrs.background_pixel = dc.col[defaultbg].pixel; - xw.attrs.border_pixel = dc.col[defaultbg].pixel; - xw.attrs.bit_gravity = NorthWestGravity; - xw.attrs.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask - | ExposureMask | VisibilityChangeMask | StructureNotifyMask - | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; - xw.attrs.colormap = xw.cmap; - - root = XRootWindow(xw.dpy, xw.scr); - if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) - parent = root; - xw.win = XCreateWindow(xw.dpy, root, xw.l, xw.t, - win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, - xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity - | CWEventMask | CWColormap, &xw.attrs); - if (parent != root) - XReparentWindow(xw.dpy, xw.win, parent, xw.l, xw.t); - - memset(&gcvalues, 0, sizeof(gcvalues)); - gcvalues.graphics_exposures = False; - dc.gc = XCreateGC(xw.dpy, xw.win, GCGraphicsExposures, - &gcvalues); - xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, - DefaultDepth(xw.dpy, xw.scr)); - XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); - XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); - - /* font spec buffer */ - xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec)); - - /* Xft rendering context */ - xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); - - /* input methods */ - if (!ximopen(xw.dpy)) { - XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, - ximinstantiate, NULL); - } - - /* white cursor, black outline */ - cursor = XCreateFontCursor(xw.dpy, mouseshape); - XDefineCursor(xw.dpy, xw.win, cursor); - - if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) { - xmousefg.red = 0xffff; - xmousefg.green = 0xffff; - xmousefg.blue = 0xffff; - } - - if (XParseColor(xw.dpy, xw.cmap, colorname[mousebg], &xmousebg) == 0) { - xmousebg.red = 0x0000; - xmousebg.green = 0x0000; - xmousebg.blue = 0x0000; - } - - XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg); - - xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); - xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); - xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False); - xw.netwmiconname = XInternAtom(xw.dpy, "_NET_WM_ICON_NAME", False); - XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1); - - xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False); - XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32, - PropModeReplace, (uchar *)&thispid, 1); - - win.mode = MODE_NUMLOCK; - resettitle(); - xhints(); - XMapWindow(xw.dpy, xw.win); - XSync(xw.dpy, False); - - clock_gettime(CLOCK_MONOTONIC, &xsel.tclick1); - clock_gettime(CLOCK_MONOTONIC, &xsel.tclick2); - xsel.primary = NULL; - xsel.clipboard = NULL; - xsel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0); - if (xsel.xtarget == None) - xsel.xtarget = XA_STRING; -} - -int -xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) -{ - float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp; - ushort mode, prevmode = USHRT_MAX; - Font *font = &dc.font; - int frcflags = FRC_NORMAL; - float runewidth = win.cw; - Rune rune; - FT_UInt glyphidx; - FcResult fcres; - FcPattern *fcpattern, *fontpattern; - FcFontSet *fcsets[] = { NULL }; - FcCharSet *fccharset; - int i, f, numspecs = 0; - - for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) { - /* Fetch rune and mode for current glyph. */ - rune = glyphs[i].u; - mode = glyphs[i].mode; - - /* Skip dummy wide-character spacing. */ - if (mode == ATTR_WDUMMY) - continue; - - /* Determine font for glyph if different from previous glyph. */ - if (prevmode != mode) { - prevmode = mode; - font = &dc.font; - frcflags = FRC_NORMAL; - runewidth = win.cw * ((mode & ATTR_WIDE) ? 2.0f : 1.0f); - if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) { - font = &dc.ibfont; - frcflags = FRC_ITALICBOLD; - } else if (mode & ATTR_ITALIC) { - font = &dc.ifont; - frcflags = FRC_ITALIC; - } else if (mode & ATTR_BOLD) { - font = &dc.bfont; - frcflags = FRC_BOLD; - } - yp = winy + font->ascent; - } - - /* Lookup character index with default font. */ - glyphidx = XftCharIndex(xw.dpy, font->match, rune); - if (glyphidx) { - specs[numspecs].font = font->match; - specs[numspecs].glyph = glyphidx; - specs[numspecs].x = (short)xp; - specs[numspecs].y = (short)yp; - xp += runewidth; - numspecs++; - continue; - } - - /* Fallback on font cache, search the font cache for match. */ - for (f = 0; f < frclen; f++) { - glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune); - /* Everything correct. */ - if (glyphidx && frc[f].flags == frcflags) - break; - /* We got a default font for a not found glyph. */ - if (!glyphidx && frc[f].flags == frcflags - && frc[f].unicodep == rune) { - break; - } - } - - /* Nothing was found. Use fontconfig to find matching font. */ - if (f >= frclen) { - if (!font->set) - font->set = FcFontSort(0, font->pattern, - 1, 0, &fcres); - fcsets[0] = font->set; - - /* - * Nothing was found in the cache. Now use - * some dozen of Fontconfig calls to get the - * font for one single character. - * - * Xft and fontconfig are design failures. - */ - fcpattern = FcPatternDuplicate(font->pattern); - fccharset = FcCharSetCreate(); - - FcCharSetAddChar(fccharset, rune); - FcPatternAddCharSet(fcpattern, FC_CHARSET, - fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, 1); - - FcConfigSubstitute(0, fcpattern, - FcMatchPattern); - FcDefaultSubstitute(fcpattern); - - fontpattern = FcFontSetMatch(0, fcsets, 1, - fcpattern, &fcres); - - /* Allocate memory for the new cache entry. */ - if (frclen >= frccap) { - frccap += 16; - frc = xrealloc(frc, frccap * sizeof(Fontcache)); - } - - frc[frclen].font = XftFontOpenPattern(xw.dpy, - fontpattern); - if (!frc[frclen].font) - die("XftFontOpenPattern failed seeking fallback font: %s\n", - strerror(errno)); - frc[frclen].flags = frcflags; - frc[frclen].unicodep = rune; - - glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, rune); - - f = frclen; - frclen++; - - FcPatternDestroy(fcpattern); - FcCharSetDestroy(fccharset); - } - - specs[numspecs].font = frc[f].font; - specs[numspecs].glyph = glyphidx; - specs[numspecs].x = (short)xp; - specs[numspecs].y = (short)yp; - xp += runewidth; - numspecs++; - } - - return numspecs; -} - -void -xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) -{ - int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); - int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, - width = charlen * win.cw; - Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; - XRenderColor colfg, colbg; - XRectangle r; - - /* Fallback on color display for attributes not supported by the font */ - if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) { - if (dc.ibfont.badslant || dc.ibfont.badweight) - base.fg = defaultattr; - } else if ((base.mode & ATTR_ITALIC && dc.ifont.badslant) || - (base.mode & ATTR_BOLD && dc.bfont.badweight)) { - base.fg = defaultattr; - } - - if (IS_TRUECOL(base.fg)) { - colfg.alpha = 0xffff; - colfg.red = TRUERED(base.fg); - colfg.green = TRUEGREEN(base.fg); - colfg.blue = TRUEBLUE(base.fg); - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &truefg); - fg = &truefg; - } else { - fg = &dc.col[base.fg]; - } - - if (IS_TRUECOL(base.bg)) { - colbg.alpha = 0xffff; - colbg.green = TRUEGREEN(base.bg); - colbg.red = TRUERED(base.bg); - colbg.blue = TRUEBLUE(base.bg); - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &truebg); - bg = &truebg; - } else { - bg = &dc.col[base.bg]; - } - - /* Change basic system colors [0-7] to bright system colors [8-15] */ - if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7)) - fg = &dc.col[base.fg + 8]; - - if (IS_SET(MODE_REVERSE)) { - if (fg == &dc.col[defaultfg]) { - fg = &dc.col[defaultbg]; - } else { - colfg.red = ~fg->color.red; - colfg.green = ~fg->color.green; - colfg.blue = ~fg->color.blue; - colfg.alpha = fg->color.alpha; - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, - &revfg); - fg = &revfg; - } - - if (bg == &dc.col[defaultbg]) { - bg = &dc.col[defaultfg]; - } else { - colbg.red = ~bg->color.red; - colbg.green = ~bg->color.green; - colbg.blue = ~bg->color.blue; - colbg.alpha = bg->color.alpha; - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, - &revbg); - bg = &revbg; - } - } - - if ((base.mode & ATTR_BOLD_FAINT) == ATTR_FAINT) { - colfg.red = fg->color.red / 2; - colfg.green = fg->color.green / 2; - colfg.blue = fg->color.blue / 2; - colfg.alpha = fg->color.alpha; - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &revfg); - fg = &revfg; - } - - if (base.mode & ATTR_REVERSE) { - temp = fg; - fg = bg; - bg = temp; - } - - if (base.mode & ATTR_BLINK && win.mode & MODE_BLINK) - fg = bg; - - if (base.mode & ATTR_INVISIBLE) - fg = bg; - - /* Intelligent cleaning up of the borders. */ - if (x == 0) { - xclear(0, (y == 0)? 0 : winy, borderpx, - winy + win.ch + - ((winy + win.ch >= borderpx + win.th)? win.h : 0)); - } - if (winx + width >= borderpx + win.tw) { - xclear(winx + width, (y == 0)? 0 : winy, win.w, - ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); - } - if (y == 0) - xclear(winx, 0, winx + width, borderpx); - 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. */ - XftDrawRect(xw.draw, bg, winx, winy, width, win.ch); - - /* Set the clip region because Xft is sometimes dirty. */ - r.x = 0; - r.y = 0; - r.height = win.ch; - r.width = width; - XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1); - - /* Render the glyphs. */ - XftDrawGlyphFontSpec(xw.draw, fg, specs, len); - - /* Render underline and strikethrough. */ - if (base.mode & ATTR_UNDERLINE) { - XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale + 1, - width, 1); - } - - if (base.mode & ATTR_STRUCK) { - XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent * chscale / 3, - width, 1); - } - - /* Reset clip to none. */ - XftDrawSetClip(xw.draw, 0); -} - -void -xdrawglyph(Glyph g, int x, int y) -{ - int numspecs; - XftGlyphFontSpec spec; - - numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); - xdrawglyphfontspecs(&spec, g, numspecs, x, y); -} - -void -xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) -{ - Color drawcol; - - /* remove the old cursor */ - if (selected(ox, oy)) - og.mode ^= ATTR_REVERSE; - xdrawglyph(og, ox, oy); - - if (IS_SET(MODE_HIDE)) - return; - - /* - * Select the right color for the right mode. - */ - g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE; - - if (IS_SET(MODE_REVERSE)) { - g.mode |= ATTR_REVERSE; - g.bg = defaultfg; - if (selected(cx, cy)) { - drawcol = dc.col[defaultcs]; - g.fg = defaultrcs; - } else { - drawcol = dc.col[defaultrcs]; - g.fg = defaultcs; - } - } else { - if (selected(cx, cy)) { - g.fg = defaultfg; - g.bg = defaultrcs; - } else { - g.fg = defaultbg; - g.bg = defaultcs; - } - drawcol = dc.col[g.bg]; - } - - /* draw the new one */ - if (IS_SET(MODE_FOCUSED)) { - switch (win.cursor) { - case 7: /* st extension */ - g.u = 0x2603; /* snowman (U+2603) */ - /* FALLTHROUGH */ - case 0: /* Blinking Block */ - case 1: /* Blinking Block (Default) */ - case 2: /* Steady Block */ - xdrawglyph(g, cx, cy); - break; - case 3: /* Blinking Underline */ - case 4: /* Steady Underline */ - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + (cy + 1) * win.ch - \ - cursorthickness, - win.cw, cursorthickness); - break; - case 5: /* Blinking bar */ - case 6: /* Steady bar */ - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, - cursorthickness, win.ch); - break; - } - } else { - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, - win.cw - 1, 1); - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, - 1, win.ch - 1); - XftDrawRect(xw.draw, &drawcol, - borderpx + (cx + 1) * win.cw - 1, - borderpx + cy * win.ch, - 1, win.ch - 1); - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + (cy + 1) * win.ch - 1, - win.cw, 1); - } -} - -void -xsetenv(void) -{ - char buf[sizeof(long) * 8 + 1]; - - snprintf(buf, sizeof(buf), "%lu", xw.win); - setenv("WINDOWID", buf, 1); -} - -void -xseticontitle(char *p) -{ - XTextProperty prop; - DEFAULT(p, opt_title); - - if (p[0] == '\0') - p = opt_title; - - if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, - &prop) != Success) - return; - XSetWMIconName(xw.dpy, xw.win, &prop); - XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmiconname); - XFree(prop.value); -} - -void -xsettitle(char *p) -{ - XTextProperty prop; - DEFAULT(p, opt_title); - - if (p[0] == '\0') - p = opt_title; - - if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, - &prop) != Success) - return; - XSetWMName(xw.dpy, xw.win, &prop); - XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname); - XFree(prop.value); -} - -int -xstartdraw(void) -{ - return IS_SET(MODE_VISIBLE); -} - -void -xdrawline(Line line, int x1, int y1, int x2) -{ - int i, x, ox, numspecs; - Glyph base, new; - XftGlyphFontSpec *specs = xw.specbuf; - - numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1); - i = ox = 0; - for (x = x1; x < x2 && i < numspecs; x++) { - new = line[x]; - if (new.mode == ATTR_WDUMMY) - continue; - if (selected(x, y1)) - new.mode ^= ATTR_REVERSE; - if (i > 0 && ATTRCMP(base, new)) { - xdrawglyphfontspecs(specs, base, i, ox, y1); - specs += i; - numspecs -= i; - i = 0; - } - if (i == 0) { - ox = x; - base = new; - } - i++; - } - if (i > 0) - xdrawglyphfontspecs(specs, base, i, ox, y1); -} - -void -xfinishdraw(void) -{ - XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, - win.h, 0, 0); - XSetForeground(xw.dpy, dc.gc, - dc.col[IS_SET(MODE_REVERSE)? - defaultfg : defaultbg].pixel); -} - -void -xximspot(int x, int y) -{ - if (xw.ime.xic == NULL) - return; - - xw.ime.spot.x = borderpx + x * win.cw; - xw.ime.spot.y = borderpx + (y + 1) * win.ch; - - XSetICValues(xw.ime.xic, XNPreeditAttributes, xw.ime.spotlist, NULL); -} - -void -expose(XEvent *ev) -{ - redraw(); -} - -void -visibility(XEvent *ev) -{ - XVisibilityEvent *e = &ev->xvisibility; - - MODBIT(win.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE); -} - -void -unmap(XEvent *ev) -{ - win.mode &= ~MODE_VISIBLE; -} - -void -xsetpointermotion(int set) -{ - MODBIT(xw.attrs.event_mask, set, PointerMotionMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); -} - -void -xsetmode(int set, unsigned int flags) -{ - int mode = win.mode; - MODBIT(win.mode, set, flags); - if ((win.mode & MODE_REVERSE) != (mode & MODE_REVERSE)) - redraw(); -} - -int -xsetcursor(int cursor) -{ - if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */ - return 1; - win.cursor = cursor; - return 0; -} - -void -xseturgency(int add) -{ - XWMHints *h = XGetWMHints(xw.dpy, xw.win); - - MODBIT(h->flags, add, XUrgencyHint); - XSetWMHints(xw.dpy, xw.win, h); - XFree(h); -} - -void -xbell(void) -{ - if (!(IS_SET(MODE_FOCUSED))) - xseturgency(1); - if (bellvolume) - XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); -} - -void -focus(XEvent *ev) -{ - XFocusChangeEvent *e = &ev->xfocus; - - if (e->mode == NotifyGrab) - return; - - if (ev->type == FocusIn) { - if (xw.ime.xic) - XSetICFocus(xw.ime.xic); - win.mode |= MODE_FOCUSED; - xseturgency(0); - if (IS_SET(MODE_FOCUS)) - ttywrite("\033[I", 3, 0); - } else { - if (xw.ime.xic) - XUnsetICFocus(xw.ime.xic); - win.mode &= ~MODE_FOCUSED; - if (IS_SET(MODE_FOCUS)) - ttywrite("\033[O", 3, 0); - } -} - -int -match(uint mask, uint state) -{ - return mask == XK_ANY_MOD || mask == (state & ~ignoremod); -} - -char* -kmap(KeySym k, uint state) -{ - Key *kp; - int i; - - /* Check for mapped keys out of X11 function keys. */ - for (i = 0; i < LEN(mappedkeys); i++) { - if (mappedkeys[i] == k) - break; - } - if (i == LEN(mappedkeys)) { - if ((k & 0xFFFF) < 0xFD00) - return NULL; - } - - for (kp = key; kp < key + LEN(key); kp++) { - if (kp->k != k) - continue; - - if (!match(kp->mask, state)) - continue; - - if (IS_SET(MODE_APPKEYPAD) ? kp->appkey < 0 : kp->appkey > 0) - continue; - if (IS_SET(MODE_NUMLOCK) && kp->appkey == 2) - continue; - - if (IS_SET(MODE_APPCURSOR) ? kp->appcursor < 0 : kp->appcursor > 0) - continue; - - return kp->s; - } - - return NULL; -} - -void -kpress(XEvent *ev) -{ - XKeyEvent *e = &ev->xkey; - KeySym ksym = NoSymbol; - char buf[64], *customkey; - int len; - Rune c; - Status status; - Shortcut *bp; - - if (IS_SET(MODE_KBDLOCK)) - return; - - if (xw.ime.xic) { - len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status); - if (status == XBufferOverflow) - return; - } else { - len = XLookupString(e, buf, sizeof buf, &ksym, NULL); - } - /* 1. shortcuts */ - for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { - if (ksym == bp->keysym && match(bp->mod, e->state)) { - bp->func(&(bp->arg)); - return; - } - } - - /* 2. custom keys from config.h */ - if ((customkey = kmap(ksym, e->state))) { - ttywrite(customkey, strlen(customkey), 1); - return; - } - - /* 3. composed string from input method */ - if (len == 0) - return; - if (len == 1 && e->state & Mod1Mask) { - if (IS_SET(MODE_8BIT)) { - if (*buf < 0177) { - c = *buf | 0x80; - len = utf8encode(c, buf); - } - } else { - buf[1] = buf[0]; - buf[0] = '\033'; - len = 2; - } - } - ttywrite(buf, len, 1); -} - -void -cmessage(XEvent *e) -{ - /* - * See xembed specs - * http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html - */ - if (e->xclient.message_type == xw.xembed && e->xclient.format == 32) { - if (e->xclient.data.l[1] == XEMBED_FOCUS_IN) { - win.mode |= MODE_FOCUSED; - xseturgency(0); - } else if (e->xclient.data.l[1] == XEMBED_FOCUS_OUT) { - win.mode &= ~MODE_FOCUSED; - } - } else if (e->xclient.data.l[0] == xw.wmdeletewin) { - ttyhangup(); - exit(0); - } -} - -void -resize(XEvent *e) -{ - if (e->xconfigure.width == win.w && e->xconfigure.height == win.h) - return; - - cresize(e->xconfigure.width, e->xconfigure.height); -} - -void -run(void) -{ - XEvent ev; - int w = win.w, h = win.h; - fd_set rfd; - int xfd = XConnectionNumber(xw.dpy), ttyfd, xev, drawing; - struct timespec seltv, *tv, now, lastblink, trigger; - double timeout; - - /* Waiting for window mapping */ - do { - XNextEvent(xw.dpy, &ev); - /* - * This XFilterEvent call is required because of XOpenIM. It - * does filter out the key event and some client message for - * the input method too. - */ - if (XFilterEvent(&ev, None)) - continue; - if (ev.type == ConfigureNotify) { - w = ev.xconfigure.width; - h = ev.xconfigure.height; - } - } while (ev.type != MapNotify); - - ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd); - cresize(w, h); - - for (timeout = -1, drawing = 0, lastblink = (struct timespec){0};;) { - FD_ZERO(&rfd); - FD_SET(ttyfd, &rfd); - FD_SET(xfd, &rfd); - - if (XPending(xw.dpy)) - timeout = 0; /* existing events might not set xfd */ - - seltv.tv_sec = timeout / 1E3; - seltv.tv_nsec = 1E6 * (timeout - 1E3 * seltv.tv_sec); - tv = timeout >= 0 ? &seltv : NULL; - - if (pselect(MAX(xfd, ttyfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) { - if (errno == EINTR) - continue; - die("select failed: %s\n", strerror(errno)); - } - clock_gettime(CLOCK_MONOTONIC, &now); - - if (FD_ISSET(ttyfd, &rfd)) - ttyread(); - - xev = 0; - while (XPending(xw.dpy)) { - xev = 1; - XNextEvent(xw.dpy, &ev); - if (XFilterEvent(&ev, None)) - continue; - if (handler[ev.type]) - (handler[ev.type])(&ev); - } - - /* - * To reduce flicker and tearing, when new content or event - * triggers drawing, we first wait a bit to ensure we got - * everything, and if nothing new arrives - we draw. - * We start with trying to wait minlatency ms. If more content - * arrives sooner, we retry with shorter and shorter periods, - * and eventually draw even without idle after maxlatency ms. - * Typically this results in low latency while interacting, - * maximum latency intervals during `cat huge.txt`, and perfect - * sync with periodic updates from animations/key-repeats/etc. - */ - if (FD_ISSET(ttyfd, &rfd) || xev) { - if (!drawing) { - trigger = now; - drawing = 1; - } - timeout = (maxlatency - TIMEDIFF(now, trigger)) \ - / maxlatency * minlatency; - if (timeout > 0) - continue; /* we have time, try to find idle */ - } - - /* idle detected or maxlatency exhausted -> draw */ - timeout = -1; - if (blinktimeout && tattrset(ATTR_BLINK)) { - timeout = blinktimeout - TIMEDIFF(now, lastblink); - if (timeout <= 0) { - if (-timeout > blinktimeout) /* start visible */ - win.mode |= MODE_BLINK; - win.mode ^= MODE_BLINK; - tsetdirtattr(ATTR_BLINK); - lastblink = now; - timeout = blinktimeout; - } - } - - draw(); - XFlush(xw.dpy); - drawing = 0; - } -} - -void -usage(void) -{ - die("usage: %s [-aiv] [-c class] [-f font] [-g geometry]" - " [-n name] [-o file]\n" - " [-T title] [-t title] [-w windowid]" - " [[-e] command [args ...]]\n" - " %s [-aiv] [-c class] [-f font] [-g geometry]" - " [-n name] [-o file]\n" - " [-T title] [-t title] [-w windowid] -l line" - " [stty_args ...]\n", argv0, argv0); -} - -int -main(int argc, char *argv[]) -{ - xw.l = xw.t = 0; - xw.isfixed = False; - xsetcursor(cursorshape); - - ARGBEGIN { - case 'a': - allowaltscreen = 0; - break; - case 'c': - opt_class = EARGF(usage()); - break; - case 'e': - if (argc > 0) - --argc, ++argv; - goto run; - case 'f': - opt_font = EARGF(usage()); - break; - case 'g': - xw.gm = XParseGeometry(EARGF(usage()), - &xw.l, &xw.t, &cols, &rows); - break; - case 'i': - xw.isfixed = 1; - break; - case 'o': - opt_io = EARGF(usage()); - break; - case 'l': - opt_line = EARGF(usage()); - break; - case 'n': - opt_name = EARGF(usage()); - break; - case 't': - case 'T': - opt_title = EARGF(usage()); - break; - case 'w': - opt_embed = EARGF(usage()); - break; - case 'v': - die("%s " VERSION "\n", argv0); - break; - default: - usage(); - } ARGEND; - -run: - if (argc > 0) /* eat all remaining arguments */ - opt_cmd = argv; - - if (!opt_title) - opt_title = (opt_line || !opt_cmd) ? "st" : opt_cmd[0]; - - setlocale(LC_CTYPE, ""); - XSetLocaleModifiers(""); - cols = MAX(cols, 1); - rows = MAX(rows, 1); - tnew(cols, rows); - xinit(cols, rows); - xsetenv(); - selinit(); - run(); - - return 0; -} diff --git a/x.o b/x.o deleted file mode 100644 index f38864117201f59e42087d8b3977474df6a0ed82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 75920 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