diff options
-rw-r--r-- | st.c | 76 |
1 files changed, 56 insertions, 20 deletions
@@ -110,17 +110,18 @@ enum glyph_state { | |||
110 | }; | 110 | }; |
111 | 111 | ||
112 | enum term_mode { | 112 | enum term_mode { |
113 | MODE_WRAP = 1, | 113 | MODE_WRAP = 1, |
114 | MODE_INSERT = 2, | 114 | MODE_INSERT = 2, |
115 | MODE_APPKEYPAD = 4, | 115 | MODE_APPKEYPAD = 4, |
116 | MODE_ALTSCREEN = 8, | 116 | MODE_ALTSCREEN = 8, |
117 | MODE_CRLF = 16, | 117 | MODE_CRLF = 16, |
118 | MODE_MOUSEBTN = 32, | 118 | MODE_MOUSEBTN = 32, |
119 | MODE_MOUSEMOTION = 64, | 119 | MODE_MOUSEMOTION = 64, |
120 | MODE_MOUSE = 32|64, | 120 | MODE_MOUSE = 32|64, |
121 | MODE_REVERSE = 128, | 121 | MODE_REVERSE = 128, |
122 | MODE_KBDLOCK = 256, | 122 | MODE_KBDLOCK = 256, |
123 | MODE_HIDE = 512 | 123 | MODE_HIDE = 512, |
124 | MODE_ECHO = 1024 | ||
124 | }; | 125 | }; |
125 | 126 | ||
126 | enum escape_state { | 127 | enum escape_state { |
@@ -320,6 +321,7 @@ static void tswapscreen(void); | |||
320 | static void tsetdirt(int, int); | 321 | static void tsetdirt(int, int); |
321 | static void tsetmode(bool, bool, int *, int); | 322 | static void tsetmode(bool, bool, int *, int); |
322 | static void tfulldirt(void); | 323 | static void tfulldirt(void); |
324 | static void techo(char *, int); | ||
323 | 325 | ||
324 | static void ttynew(void); | 326 | static void ttynew(void); |
325 | static void ttyread(void); | 327 | static void ttyread(void); |
@@ -1534,7 +1536,8 @@ tsetmode(bool priv, bool set, int *args, int narg) { | |||
1534 | case 4: /* IRM -- Insertion-replacement */ | 1536 | case 4: /* IRM -- Insertion-replacement */ |
1535 | MODBIT(term.mode, set, MODE_INSERT); | 1537 | MODBIT(term.mode, set, MODE_INSERT); |
1536 | break; | 1538 | break; |
1537 | case 12: /* XXX: SRM -- Send/Receive */ | 1539 | case 12: /* SRM -- Send/Receive */ |
1540 | MODBIT(term.mode, !set, MODE_ECHO); | ||
1538 | break; | 1541 | break; |
1539 | case 20: /* LNM -- Linefeed/new line */ | 1542 | case 20: /* LNM -- Linefeed/new line */ |
1540 | MODBIT(term.mode, set, MODE_CRLF); | 1543 | MODBIT(term.mode, set, MODE_CRLF); |
@@ -1849,6 +1852,28 @@ tputtab(bool forward) { | |||
1849 | } | 1852 | } |
1850 | 1853 | ||
1851 | void | 1854 | void |
1855 | techo(char *buf, int len) { | ||
1856 | for(; len > 0; buf++, len--) { | ||
1857 | char c = *buf; | ||
1858 | |||
1859 | if(c == '\033') { /* escape */ | ||
1860 | tputc("^", 1); | ||
1861 | tputc("[", 1); | ||
1862 | } else if (c < '\x20') { /* control code */ | ||
1863 | if(c != '\n' && c != '\r' && c != '\t') { | ||
1864 | c |= '\x40'; | ||
1865 | tputc("^", 1); | ||
1866 | } | ||
1867 | tputc(&c, 1); | ||
1868 | } else { | ||
1869 | break; | ||
1870 | } | ||
1871 | } | ||
1872 | if (len) | ||
1873 | tputc(buf, len); | ||
1874 | } | ||
1875 | |||
1876 | void | ||
1852 | tputc(char *c, int len) { | 1877 | tputc(char *c, int len) { |
1853 | uchar ascii = *c; | 1878 | uchar ascii = *c; |
1854 | bool control = ascii < '\x20' || ascii == 0177; | 1879 | bool control = ascii < '\x20' || ascii == 0177; |
@@ -2679,7 +2704,7 @@ void | |||
2679 | kpress(XEvent *ev) { | 2704 | kpress(XEvent *ev) { |
2680 | XKeyEvent *e = &ev->xkey; | 2705 | XKeyEvent *e = &ev->xkey; |
2681 | KeySym ksym; | 2706 | KeySym ksym; |
2682 | char buf[32], *customkey; | 2707 | char xstr[31], buf[32], *customkey, *cp = buf; |
2683 | int len, meta, shift, i; | 2708 | int len, meta, shift, i; |
2684 | Status status; | 2709 | Status status; |
2685 | 2710 | ||
@@ -2688,7 +2713,7 @@ kpress(XEvent *ev) { | |||
2688 | 2713 | ||
2689 | meta = e->state & Mod1Mask; | 2714 | meta = e->state & Mod1Mask; |
2690 | shift = e->state & ShiftMask; | 2715 | shift = e->state & ShiftMask; |
2691 | len = XmbLookupString(xw.xic, e, buf, sizeof(buf), &ksym, &status); | 2716 | len = XmbLookupString(xw.xic, e, xstr, sizeof(xstr), &ksym, &status); |
2692 | 2717 | ||
2693 | /* 1. shortcuts */ | 2718 | /* 1. shortcuts */ |
2694 | for(i = 0; i < LEN(shortcuts); i++) { | 2719 | for(i = 0; i < LEN(shortcuts); i++) { |
@@ -2702,7 +2727,8 @@ kpress(XEvent *ev) { | |||
2702 | 2727 | ||
2703 | /* 2. custom keys from config.h */ | 2728 | /* 2. custom keys from config.h */ |
2704 | if((customkey = kmap(ksym, e->state))) { | 2729 | if((customkey = kmap(ksym, e->state))) { |
2705 | ttywrite(customkey, strlen(customkey)); | 2730 | len = strlen(customkey); |
2731 | memcpy(buf, customkey, len); | ||
2706 | /* 2. hardcoded (overrides X lookup) */ | 2732 | /* 2. hardcoded (overrides X lookup) */ |
2707 | } else { | 2733 | } else { |
2708 | switch(ksym) { | 2734 | switch(ksym) { |
@@ -2714,34 +2740,44 @@ kpress(XEvent *ev) { | |||
2714 | sprintf(buf, "\033%c%c", | 2740 | sprintf(buf, "\033%c%c", |
2715 | IS_SET(MODE_APPKEYPAD) ? 'O' : '[', | 2741 | IS_SET(MODE_APPKEYPAD) ? 'O' : '[', |
2716 | (shift ? "dacb":"DACB")[ksym - XK_Left]); | 2742 | (shift ? "dacb":"DACB")[ksym - XK_Left]); |
2717 | ttywrite(buf, 3); | 2743 | len = 3; |
2718 | break; | 2744 | break; |
2719 | case XK_Insert: | 2745 | case XK_Insert: |
2720 | if(shift) | 2746 | if(shift) { |
2721 | selpaste(); | 2747 | selpaste(); |
2748 | return; | ||
2749 | } | ||
2750 | memcpy(buf, xstr, len); | ||
2722 | break; | 2751 | break; |
2723 | case XK_Return: | 2752 | case XK_Return: |
2753 | len = 0; | ||
2724 | if(meta) | 2754 | if(meta) |
2725 | ttywrite("\033", 1); | 2755 | *cp++ = '\033', len++; |
2726 | 2756 | ||
2727 | if(IS_SET(MODE_CRLF)) { | 2757 | *cp++ = '\r', len++; |
2728 | ttywrite("\r\n", 2); | 2758 | |
2729 | } else { | 2759 | if(IS_SET(MODE_CRLF)) |
2730 | ttywrite("\r", 1); | 2760 | *cp = '\n', len++; |
2731 | } | ||
2732 | break; | 2761 | break; |
2733 | /* 3. X lookup */ | 2762 | /* 3. X lookup */ |
2734 | default: | 2763 | default: |
2735 | if(len > 0) { | 2764 | if(len == 0) |
2736 | if(meta && len == 1) | 2765 | return; |
2737 | ttywrite("\033", 1); | 2766 | |
2738 | ttywrite(buf, len); | 2767 | if (len == 1 && meta) |
2739 | } | 2768 | *cp++ = '\033'; |
2769 | |||
2770 | memcpy(cp, xstr, len); | ||
2771 | len = cp - buf + len; | ||
2740 | break; | 2772 | break; |
2741 | } | 2773 | } |
2742 | } | 2774 | } |
2775 | ttywrite(buf, len); | ||
2776 | if(IS_SET(MODE_ECHO)) | ||
2777 | techo(buf, len); | ||
2743 | } | 2778 | } |
2744 | 2779 | ||
2780 | |||
2745 | void | 2781 | void |
2746 | cmessage(XEvent *e) { | 2782 | cmessage(XEvent *e) { |
2747 | /* See xembed specs | 2783 | /* See xembed specs |