X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=st.c;h=3ebf8c6947e69086dfb51541600d5320f8ce7466;hb=33201ac65f74e45b4fa60822ba9a538c3cfa9b25;hp=21cba9ef8e8e56e3ee90c8392e4efc73a9e4395f;hpb=bcb5d3adbe57ead05a829e5144c2ba1dc465865f;p=st.git diff --git a/st.c b/st.c index 21cba9e..3ebf8c6 100644 --- a/st.c +++ b/st.c @@ -108,6 +108,7 @@ typedef struct { static void execsh(char **); static void stty(char **); static void sigchld(int); +static void ttywriteraw(const char *, size_t); static void csidump(void); static void csihandle(void); @@ -167,11 +168,11 @@ static ssize_t xwrite(int, const char *, size_t); /* Globals */ Term term; -Selection sel; int cmdfd; pid_t pid; int oldbutton = 3; /* button event on startup: 3 = release */ +static Selection sel; static CSIEscape csiescseq; static STREscape strescseq; static int iofd = 1; @@ -402,9 +403,17 @@ selstart(int col, int row, int snap) } void -selextend(int col, int row, int type) +selextend(int col, int row, int type, int done) { int oldey, oldex, oldsby, oldsey, oldtype; + + if (!sel.mode) + return; + if (done && sel.mode == SEL_EMPTY) { + selclear(); + return; + } + oldey = sel.oe.y; oldex = sel.oe.x; oldsby = sel.nb.y; @@ -419,6 +428,8 @@ selextend(int col, int row, int type) if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type) tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey)); + + sel.mode = done ? SEL_IDLE : SEL_READY; } void @@ -774,7 +785,35 @@ ttyread(void) } void -ttywrite(const char *s, size_t n) +ttywrite(const char *s, size_t n, int may_echo) +{ + const char *next; + + if (may_echo && IS_SET(MODE_ECHO)) + twrite(s, n, 1); + + if (!IS_SET(MODE_CRLF)) { + ttywriteraw(s, n); + return; + } + + /* This is similar to how the kernel handles ONLCR for ttys */ + while (n > 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; @@ -830,14 +869,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) { @@ -1560,7 +1591,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 */ @@ -1688,7 +1719,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 */ @@ -1906,7 +1937,7 @@ iso14755(const Arg *arg) (*e != '\n' && *e != '\0')) return; - ttysend(uc, utf8encode(utf32, uc)); + ttywrite(uc, utf8encode(utf32, uc), 1); } void @@ -2119,7 +2150,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 */ @@ -2191,7 +2222,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();