X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=st.c;h=504239ea6ac121ec512a4e738e72b916a828015e;hb=88d8293fb4ba150a5f19d58d133b5db93d9dcfa5;hp=ea0726cd267532ef878655868c75dbfc4d920e59;hpb=5683b1f80c5ac274adf98517ce2217b4d4896243;p=st.git diff --git a/st.c b/st.c index ea0726c..504239e 100644 --- a/st.c +++ b/st.c @@ -42,6 +42,7 @@ #define STR_ARG_SIZ ESC_ARG_SIZ /* macros */ +#define IS_SET(flag) ((term.mode & (flag)) != 0) #define NUMMAXLEN(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1) #define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177') #define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) @@ -51,6 +52,17 @@ /* constants */ #define ISO14755CMD "dmenu -w \"$WINDOWID\" -p codepoint: 0) { + if (*s == '\r') { + next = s + 1; + ttywriteraw("\r\n", 2); + } else { + next = memchr(s, '\r', n); + DEFAULT(next, s + n); + ttywriteraw(s, next - s); + } + n -= next - s; + s = next; + } +} + +void +ttywriteraw(const char *s, size_t n) { fd_set wfd, rfd; ssize_t r; @@ -793,14 +883,6 @@ write_error: die("write error on tty: %s\n", strerror(errno)); } -void -ttysend(char *s, size_t n) -{ - ttywrite(s, n); - if (IS_SET(MODE_ECHO)) - twrite(s, n, 1); -} - void ttyresize(int tw, int th) { @@ -909,8 +991,6 @@ tnew(int col, int row) { term = (Term){ .c = { .attr = { .fg = defaultfg, .bg = defaultbg } } }; tresize(col, row); - term.numlock = 1; - treset(); } @@ -1346,20 +1426,16 @@ tsetscroll(int t, int b) void tsetmode(int priv, int set, int *args, int narg) { - int *lim, mode; - int alt; + int alt, *lim; for (lim = args + narg; args < lim; ++args) { if (priv) { switch (*args) { case 1: /* DECCKM -- Cursor key */ - MODBIT(term.mode, set, MODE_APPCURSOR); + xsetmode(set, MODE_APPCURSOR); break; case 5: /* DECSCNM -- Reverse video */ - mode = term.mode; - MODBIT(term.mode, set, MODE_REVERSE); - if (mode != term.mode) - redraw(); + xsetmode(set, MODE_REVERSE); break; case 6: /* DECOM -- Origin */ MODBIT(term.c.state, set, CURSOR_ORIGIN); @@ -1379,36 +1455,36 @@ tsetmode(int priv, int set, int *args, int narg) case 12: /* att610 -- Start blinking cursor (IGNORED) */ break; case 25: /* DECTCEM -- Text Cursor Enable Mode */ - MODBIT(term.mode, !set, MODE_HIDE); + xsetmode(!set, MODE_HIDE); break; case 9: /* X10 mouse compatibility mode */ xsetpointermotion(0); - MODBIT(term.mode, 0, MODE_MOUSE); - MODBIT(term.mode, set, MODE_MOUSEX10); + xsetmode(0, MODE_MOUSE); + xsetmode(set, MODE_MOUSEX10); break; case 1000: /* 1000: report button press */ xsetpointermotion(0); - MODBIT(term.mode, 0, MODE_MOUSE); - MODBIT(term.mode, set, MODE_MOUSEBTN); + xsetmode(0, MODE_MOUSE); + xsetmode(set, MODE_MOUSEBTN); break; case 1002: /* 1002: report motion on button press */ xsetpointermotion(0); - MODBIT(term.mode, 0, MODE_MOUSE); - MODBIT(term.mode, set, MODE_MOUSEMOTION); + xsetmode(0, MODE_MOUSE); + xsetmode(set, MODE_MOUSEMOTION); break; case 1003: /* 1003: enable all mouse motions */ xsetpointermotion(set); - MODBIT(term.mode, 0, MODE_MOUSE); - MODBIT(term.mode, set, MODE_MOUSEMANY); + xsetmode(0, MODE_MOUSE); + xsetmode(set, MODE_MOUSEMANY); break; case 1004: /* 1004: send focus events to tty */ - MODBIT(term.mode, set, MODE_FOCUS); + xsetmode(set, MODE_FOCUS); break; case 1006: /* 1006: extended reporting mode */ - MODBIT(term.mode, set, MODE_MOUSESGR); + xsetmode(set, MODE_MOUSESGR); break; case 1034: - MODBIT(term.mode, set, MODE_8BIT); + xsetmode(set, MODE_8BIT); break; case 1049: /* swap screen & set/restore cursor as xterm */ if (!allowaltscreen) @@ -1433,7 +1509,7 @@ tsetmode(int priv, int set, int *args, int narg) tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); break; case 2004: /* 2004: bracketed paste mode */ - MODBIT(term.mode, set, MODE_BRCKTPASTE); + xsetmode(set, MODE_BRCKTPASTE); break; /* Not implemented mouse modes. See comments there. */ case 1001: /* mouse highlight mode; can hang the @@ -1454,8 +1530,8 @@ tsetmode(int priv, int set, int *args, int narg) switch (*args) { case 0: /* Error (IGNORED) */ break; - case 2: /* KAM -- keyboard action */ - MODBIT(term.mode, set, MODE_KBDLOCK); + case 2: + xsetmode(set, MODE_KBDLOCK); break; case 4: /* IRM -- Insertion-replacement */ MODBIT(term.mode, set, MODE_INSERT); @@ -1523,7 +1599,7 @@ csihandle(void) break; case 'c': /* DA -- Device Attributes */ if (csiescseq.arg[0] == 0) - ttywrite(vtiden, strlen(vtiden)); + ttywrite(vtiden, strlen(vtiden), 0); break; case 'C': /* CUF -- Cursor Forward */ case 'a': /* HPR -- Cursor Forward */ @@ -1651,7 +1727,7 @@ csihandle(void) if (csiescseq.arg[0] == 6) { len = snprintf(buf, sizeof(buf),"\033[%i;%iR", term.c.y+1, term.c.x+1); - ttywrite(buf, len); + ttywrite(buf, len, 0); } break; case 'r': /* DECSTBM -- Set Scrolling Region */ @@ -1869,7 +1945,7 @@ iso14755(const Arg *arg) (*e != '\n' && *e != '\0')) return; - ttysend(uc, utf8encode(utf32, uc)); + ttywrite(uc, utf8encode(utf32, uc), 1); } void @@ -2082,7 +2158,7 @@ tcontrolcode(uchar ascii) case 0x99: /* TODO: SGCI */ break; case 0x9a: /* DECID -- Identify Terminal */ - ttywrite(vtiden, strlen(vtiden)); + ttywrite(vtiden, strlen(vtiden), 0); break; case 0x9b: /* TODO: CSI */ case 0x9c: /* TODO: ST */ @@ -2154,7 +2230,7 @@ eschandle(uchar ascii) } break; case 'Z': /* DECID -- Identify Terminal */ - ttywrite(vtiden, strlen(vtiden)); + ttywrite(vtiden, strlen(vtiden), 0); break; case 'c': /* RIS -- Reset to inital state */ treset(); @@ -2162,10 +2238,10 @@ eschandle(uchar ascii) xloadcols(); break; case '=': /* DECPAM -- Application keypad */ - term.mode |= MODE_APPKEYPAD; + xsetmode(1, MODE_APPKEYPAD); break; case '>': /* DECPNM -- Normal keypad */ - term.mode &= ~MODE_APPKEYPAD; + xsetmode(0, MODE_APPKEYPAD); break; case '7': /* DECSC -- Save Cursor */ tcursor(CURSOR_SAVE); @@ -2453,14 +2529,31 @@ resettitle(void) } void -redraw(void) +drawregion(int x1, int y1, int x2, int y2) { - tfulldirt(); - draw(); + int y; + for (y = y1; y < y2; y++) { + if (!term.dirty[y]) + continue; + + term.dirty[y] = 0; + xdrawline(term.line[y], x1, y, x2); + } } void -numlock(const Arg *dummy) +draw(void) { - term.numlock ^= 1; + if (!xstartdraw()) + return; + drawregion(0, 0, term.col, term.row); + xdrawcursor(); + xfinishdraw(); +} + +void +redraw(void) +{ + tfulldirt(); + draw(); }