aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--st.c107
1 files changed, 45 insertions, 62 deletions
diff --git a/st.c b/st.c
index 2788746..f527858 100644
--- a/st.c
+++ b/st.c
@@ -383,20 +383,20 @@ static void tmoveato(int, int);
383static void tnew(int, int); 383static void tnew(int, int);
384static void tnewline(int); 384static void tnewline(int);
385static void tputtab(int); 385static void tputtab(int);
386static void tputc(char *, int); 386static void tputc(long);
387static void treset(void); 387static void treset(void);
388static void tresize(int, int); 388static void tresize(int, int);
389static void tscrollup(int, int); 389static void tscrollup(int, int);
390static void tscrolldown(int, int); 390static void tscrolldown(int, int);
391static void tsetattr(int *, int); 391static void tsetattr(int *, int);
392static void tsetchar(char *, Glyph *, int, int); 392static void tsetchar(long, Glyph *, int, int);
393static void tsetscroll(int, int); 393static void tsetscroll(int, int);
394static void tswapscreen(void); 394static void tswapscreen(void);
395static void tsetdirt(int, int); 395static void tsetdirt(int, int);
396static void tsetdirtattr(int); 396static void tsetdirtattr(int);
397static void tsetmode(bool, bool, int *, int); 397static void tsetmode(bool, bool, int *, int);
398static void tfulldirt(void); 398static void tfulldirt(void);
399static void techo(char *, int); 399static void techo(long);
400static void tcontrolcode(uchar ); 400static void tcontrolcode(uchar );
401static void tdectest(char ); 401static void tdectest(char );
402static int32_t tdefcolor(int *, int *, int); 402static int32_t tdefcolor(int *, int *, int);
@@ -1332,7 +1332,6 @@ ttyread(void) {
1332 static char buf[BUFSIZ]; 1332 static char buf[BUFSIZ];
1333 static int buflen = 0; 1333 static int buflen = 0;
1334 char *ptr; 1334 char *ptr;
1335 char s[UTF_SIZ];
1336 int charsize; /* size of utf8 char in bytes */ 1335 int charsize; /* size of utf8 char in bytes */
1337 long unicodep; 1336 long unicodep;
1338 int ret; 1337 int ret;
@@ -1345,8 +1344,7 @@ ttyread(void) {
1345 buflen += ret; 1344 buflen += ret;
1346 ptr = buf; 1345 ptr = buf;
1347 while((charsize = utf8decode(ptr, &unicodep, buflen))) { 1346 while((charsize = utf8decode(ptr, &unicodep, buflen))) {
1348 utf8encode(unicodep, s); 1347 tputc(unicodep);
1349 tputc(s, charsize);
1350 ptr += charsize; 1348 ptr += charsize;
1351 buflen -= charsize; 1349 buflen -= charsize;
1352 } 1350 }
@@ -1363,9 +1361,16 @@ ttywrite(const char *s, size_t n) {
1363 1361
1364void 1362void
1365ttysend(char *s, size_t n) { 1363ttysend(char *s, size_t n) {
1364 int len;
1365 long u;
1366
1366 ttywrite(s, n); 1367 ttywrite(s, n);
1367 if(IS_SET(MODE_ECHO)) 1368 if(IS_SET(MODE_ECHO))
1368 techo(s, n); 1369 while((len = utf8decode(s, &u, n)) > 0) {
1370 techo(u);
1371 n -= len;
1372 s += len;
1373 }
1369} 1374}
1370 1375
1371void 1376void
@@ -1614,7 +1619,7 @@ tmoveto(int x, int y) {
1614} 1619}
1615 1620
1616void 1621void
1617tsetchar(char *c, Glyph *attr, int x, int y) { 1622tsetchar(long u, Glyph *attr, int x, int y) {
1618 static char *vt100_0[62] = { /* 0x41 - 0x7e */ 1623 static char *vt100_0[62] = { /* 0x41 - 0x7e */
1619 "↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */ 1624 "↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */
1620 0, 0, 0, 0, 0, 0, 0, 0, /* H - O */ 1625 0, 0, 0, 0, 0, 0, 0, 0, /* H - O */
@@ -1629,11 +1634,9 @@ tsetchar(char *c, Glyph *attr, int x, int y) {
1629 /* 1634 /*
1630 * The table is proudly stolen from rxvt. 1635 * The table is proudly stolen from rxvt.
1631 */ 1636 */
1632 if(term.trantbl[term.charset] == CS_GRAPHIC0) { 1637 if(term.trantbl[term.charset] == CS_GRAPHIC0 &&
1633 if(BETWEEN(c[0], 0x41, 0x7e) && vt100_0[c[0] - 0x41]) { 1638 BETWEEN(u, 0x41, 0x7e) && vt100_0[u - 0x41])
1634 c = vt100_0[c[0] - 0x41]; 1639 utf8decode(vt100_0[u - 0x41], &u, UTF_SIZ);
1635 }
1636 }
1637 1640
1638 if(term.line[y][x].mode & ATTR_WIDE) { 1641 if(term.line[y][x].mode & ATTR_WIDE) {
1639 if(x+1 < term.col) { 1642 if(x+1 < term.col) {
@@ -1647,7 +1650,7 @@ tsetchar(char *c, Glyph *attr, int x, int y) {
1647 1650
1648 term.dirty[y] = 1; 1651 term.dirty[y] = 1;
1649 term.line[y][x] = *attr; 1652 term.line[y][x] = *attr;
1650 utf8decode(c, &term.line[y][x].u, UTF_SIZ); 1653 term.line[y][x].u = u;
1651} 1654}
1652 1655
1653void 1656void
@@ -2431,26 +2434,18 @@ tputtab(int n) {
2431} 2434}
2432 2435
2433void 2436void
2434techo(char *buf, int len) { 2437techo(long u) {
2435 for(; len > 0; buf++, len--) { 2438 if(ISCONTROL(u)) { /* control code */
2436 char c = *buf; 2439 if(u & 0x80) {
2437 2440 u &= 0x7f;
2438 if(ISCONTROL((uchar) c)) { /* control code */ 2441 tputc('^');
2439 if(c & 0x80) { 2442 tputc('[');
2440 c &= 0x7f; 2443 } else if(u != '\n' && u != '\r' && u != '\t') {
2441 tputc("^", 1); 2444 u ^= 0x40;
2442 tputc("[", 1); 2445 tputc('^');
2443 } else if(c != '\n' && c != '\r' && c != '\t') {
2444 c ^= 0x40;
2445 tputc("^", 1);
2446 }
2447 tputc(&c, 1);
2448 } else {
2449 break;
2450 } 2446 }
2451 } 2447 }
2452 if(len) 2448 tputc(u);
2453 tputc(buf, len);
2454} 2449}
2455 2450
2456void 2451void
@@ -2468,13 +2463,12 @@ tdeftran(char ascii) {
2468 2463
2469void 2464void
2470tdectest(char c) { 2465tdectest(char c) {
2471 static char E[UTF_SIZ] = "E";
2472 int x, y; 2466 int x, y;
2473 2467
2474 if(c == '8') { /* DEC screen alignment test. */ 2468 if(c == '8') { /* DEC screen alignment test. */
2475 for(x = 0; x < term.col; ++x) { 2469 for(x = 0; x < term.col; ++x) {
2476 for(y = 0; y < term.row; ++y) 2470 for(y = 0; y < term.row; ++y)
2477 tsetchar(E, &term.c.attr, x, y); 2471 tsetchar('E', &term.c.attr, x, y);
2478 } 2472 }
2479 } 2473 }
2480} 2474}
@@ -2502,8 +2496,6 @@ tstrsequence(uchar c) {
2502 2496
2503void 2497void
2504tcontrolcode(uchar ascii) { 2498tcontrolcode(uchar ascii) {
2505 static char question[UTF_SIZ] = "?";
2506
2507 switch(ascii) { 2499 switch(ascii) {
2508 case '\t': /* HT */ 2500 case '\t': /* HT */
2509 tputtab(1); 2501 tputtab(1);
@@ -2541,7 +2533,7 @@ tcontrolcode(uchar ascii) {
2541 term.charset = 1 - (ascii - '\016'); 2533 term.charset = 1 - (ascii - '\016');
2542 return; 2534 return;
2543 case '\032': /* SUB */ 2535 case '\032': /* SUB */
2544 tsetchar(question, &term.c.attr, term.c.x, term.c.y); 2536 tsetchar('?', &term.c.attr, term.c.x, term.c.y);
2545 case '\030': /* CAN */ 2537 case '\030': /* CAN */
2546 csireset(); 2538 csireset();
2547 break; 2539 break;
@@ -2665,28 +2657,21 @@ eschandle(uchar ascii) {
2665} 2657}
2666 2658
2667void 2659void
2668tputc(char *c, int len) { 2660tputc(long u) {
2669 uchar ascii; 2661 char c[UTF_SIZ];
2670 bool control; 2662 bool control;
2671 long unicodep; 2663 int width, len;
2672 int width;
2673 Glyph *gp; 2664 Glyph *gp;
2674 2665
2675 if(len == 1) { 2666 len = utf8encode(u, c);
2667 if((width = wcwidth(u)) == -1) {
2668 memcpy(c, "\357\277\275", 4); /* UTF_INVALID */
2676 width = 1; 2669 width = 1;
2677 unicodep = ascii = *c;
2678 } else {
2679 utf8decode(c, &unicodep, UTF_SIZ);
2680 if ((width = wcwidth(unicodep)) == -1) {
2681 c = "\357\277\275"; /* UTF_INVALID */
2682 width = 1;
2683 }
2684 ascii = unicodep;
2685 } 2670 }
2686 2671
2687 if(IS_SET(MODE_PRINT)) 2672 if(IS_SET(MODE_PRINT))
2688 tprinter(c, len); 2673 tprinter(c, len);
2689 control = ISCONTROL(unicodep); 2674 control = ISCONTROL(u);
2690 2675
2691 /* 2676 /*
2692 * STR sequence must be checked before anything else 2677 * STR sequence must be checked before anything else
@@ -2695,10 +2680,8 @@ tputc(char *c, int len) {
2695 * character. 2680 * character.
2696 */ 2681 */
2697 if(term.esc & ESC_STR) { 2682 if(term.esc & ESC_STR) {
2698 if(len == 1 && 2683 if(u == '\a' || u == 030 || u == 032 || u == 033 ||
2699 (ascii == '\a' || ascii == 030 || 2684 ISCONTROLC1(u)) {
2700 ascii == 032 || ascii == 033 ||
2701 ISCONTROLC1(unicodep))) {
2702 term.esc &= ~(ESC_START|ESC_STR); 2685 term.esc &= ~(ESC_START|ESC_STR);
2703 term.esc |= ESC_STR_END; 2686 term.esc |= ESC_STR_END;
2704 } else if(strescseq.len + len < sizeof(strescseq.buf) - 1) { 2687 } else if(strescseq.len + len < sizeof(strescseq.buf) - 1) {
@@ -2729,15 +2712,15 @@ tputc(char *c, int len) {
2729 * they must not cause conflicts with sequences. 2712 * they must not cause conflicts with sequences.
2730 */ 2713 */
2731 if(control) { 2714 if(control) {
2732 tcontrolcode(ascii); 2715 tcontrolcode(u);
2733 /* 2716 /*
2734 * control codes are not shown ever 2717 * control codes are not shown ever
2735 */ 2718 */
2736 return; 2719 return;
2737 } else if(term.esc & ESC_START) { 2720 } else if(term.esc & ESC_START) {
2738 if(term.esc & ESC_CSI) { 2721 if(term.esc & ESC_CSI) {
2739 csiescseq.buf[csiescseq.len++] = ascii; 2722 csiescseq.buf[csiescseq.len++] = u;
2740 if(BETWEEN(ascii, 0x40, 0x7E) 2723 if(BETWEEN(u, 0x40, 0x7E)
2741 || csiescseq.len >= \ 2724 || csiescseq.len >= \
2742 sizeof(csiescseq.buf)-1) { 2725 sizeof(csiescseq.buf)-1) {
2743 term.esc = 0; 2726 term.esc = 0;
@@ -2746,11 +2729,11 @@ tputc(char *c, int len) {
2746 } 2729 }
2747 return; 2730 return;
2748 } else if(term.esc & ESC_ALTCHARSET) { 2731 } else if(term.esc & ESC_ALTCHARSET) {
2749 tdeftran(ascii); 2732 tdeftran(u);
2750 } else if(term.esc & ESC_TEST) { 2733 } else if(term.esc & ESC_TEST) {
2751 tdectest(ascii); 2734 tdectest(u);
2752 } else { 2735 } else {
2753 if (!eschandle(ascii)) 2736 if (!eschandle(u))
2754 return; 2737 return;
2755 /* sequence already finished */ 2738 /* sequence already finished */
2756 } 2739 }
@@ -2779,7 +2762,7 @@ tputc(char *c, int len) {
2779 gp = &term.line[term.c.y][term.c.x]; 2762 gp = &term.line[term.c.y][term.c.x];
2780 } 2763 }
2781 2764
2782 tsetchar(c, &term.c.attr, term.c.x, term.c.y); 2765 tsetchar(u, &term.c.attr, term.c.x, term.c.y);
2783 2766
2784 if(width == 2) { 2767 if(width == 2) {
2785 gp->mode |= ATTR_WIDE; 2768 gp->mode |= ATTR_WIDE;