# st

Unnamed repository; edit this file 'description' to name the repository.

| Log | Files | Refs | README | LICENSE

    commit 73177ba366e5363b8a6695882b52617a8909a925
    parent ace789a79fc44c1c3b629f5c0fb477c651d84a48
    Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
    Date:   Tue, 13 Nov 2012 20:04:26 +0100

    Add SRM sequence

    This sequence enable/disable the local echo.
    ---
     st.c |   76 ++++++++++++++++++++++++++++++++++++++++++++++++------------------
     1 file changed, 56 insertions(+), 20 deletions(-)
    Diffstat:
    Mst.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------

    1 file changed, 56 insertions(+), 20 deletions(-)
    diff --git a/st.c b/st.c
    @@ -110,17 +110,18 @@ enum glyph_state {
     };

     enum term_mode {
    -	MODE_WRAP	= 1,
    +	MODE_WRAP	 = 1,
     	MODE_INSERT      = 2,
     	MODE_APPKEYPAD   = 4,
     	MODE_ALTSCREEN   = 8,
    -	MODE_CRLF	= 16,
    +	MODE_CRLF	 = 16,
     	MODE_MOUSEBTN    = 32,
     	MODE_MOUSEMOTION = 64,
     	MODE_MOUSE       = 32|64,
     	MODE_REVERSE     = 128,
     	MODE_KBDLOCK     = 256,
    -	MODE_HIDE      = 512
    +	MODE_HIDE	 = 512,
    +	MODE_ECHO	 = 1024
     };

     enum escape_state {
    @@ -320,6 +321,7 @@ static void tswapscreen(void);
     static void tsetdirt(int, int);
     static void tsetmode(bool, bool, int *, int);
     static void tfulldirt(void);
    +static void techo(char *, int);

     static void ttynew(void);
     static void ttyread(void);
    @@ -1534,7 +1536,8 @@ tsetmode(bool priv, bool set, int *args, int narg) {
     			case 4:  /* IRM -- Insertion-replacement */
     				MODBIT(term.mode, set, MODE_INSERT);
     				break;
    -			case 12: /* XXX: SRM -- Send/Receive */
    +			case 12: /* SRM -- Send/Receive */
    +				MODBIT(term.mode, !set, MODE_ECHO);
     				break;
     			case 20: /* LNM -- Linefeed/new line */
     				MODBIT(term.mode, set, MODE_CRLF);
    @@ -1849,6 +1852,28 @@ tputtab(bool forward) {
     }

     void
    +techo(char *buf, int len) {
    +	for(; len > 0; buf++, len--) {
    +		char c = *buf;
    +
    +		if(c == '\033') {		/* escape */
    +			tputc("^", 1);
    +			tputc("[", 1);
    +		} else if (c < '\x20') {	/* control code */
    +			if(c != '\n' && c != '\r' && c != '\t') {
    +				c |= '\x40';
    +				tputc("^", 1);
    +			}
    +			tputc(&c, 1);
    +		} else {
    +			break;
    +		}
    +	}
    +	if (len)
    +		tputc(buf, len);
    +}
    +
    +void
     tputc(char *c, int len) {
     	uchar ascii = *c;
     	bool control = ascii < '\x20' || ascii == 0177;
    @@ -2679,7 +2704,7 @@ void
     kpress(XEvent *ev) {
     	XKeyEvent *e = &ev->xkey;
     	KeySym ksym;
    -	char buf[32], *customkey;
    +	char xstr[31], buf[32], *customkey, *cp = buf;
     	int len, meta, shift, i;
     	Status status;

    @@ -2688,7 +2713,7 @@ kpress(XEvent *ev) {

     	meta = e->state & Mod1Mask;
     	shift = e->state & ShiftMask;
    -	len = XmbLookupString(xw.xic, e, buf, sizeof(buf), &ksym, &status);
    +	len = XmbLookupString(xw.xic, e, xstr, sizeof(xstr), &ksym, &status);

     	/* 1. shortcuts */
     	for(i = 0; i < LEN(shortcuts); i++) {
    @@ -2702,7 +2727,8 @@ kpress(XEvent *ev) {

     	/* 2. custom keys from config.h */
     	if((customkey = kmap(ksym, e->state))) {
    -		ttywrite(customkey, strlen(customkey));
    +		len = strlen(customkey);
    +		memcpy(buf, customkey, len);
     	/* 2. hardcoded (overrides X lookup) */
     	} else {
     		switch(ksym) {
    @@ -2714,34 +2740,44 @@ kpress(XEvent *ev) {
     			sprintf(buf, "\033%c%c",
     				IS_SET(MODE_APPKEYPAD) ? 'O' : '[',
     				(shift ? "dacb":"DACB")[ksym - XK_Left]);
    -			ttywrite(buf, 3);
    +			len = 3;
     			break;
     		case XK_Insert:
    -			if(shift)
    +			if(shift) {
     				selpaste();
    +				return;
    +			}
    +			memcpy(buf, xstr, len);
     			break;
     		case XK_Return:
    +			len = 0;
     			if(meta)
    -				ttywrite("\033", 1);
    +				*cp++ = '\033', len++;

    -			if(IS_SET(MODE_CRLF)) {
    -				ttywrite("\r\n", 2);
    -			} else {
    -				ttywrite("\r", 1);
    -			}
    +			*cp++ = '\r', len++;
    +
    +			if(IS_SET(MODE_CRLF))
    +				*cp = '\n', len++;
     			break;
     			/* 3. X lookup  */
     		default:
    -			if(len > 0) {
    -				if(meta && len == 1)
    -					ttywrite("\033", 1);
    -				ttywrite(buf, len);
    -			}
    +			if(len == 0)
    +				return;
    +
    +			if (len == 1 && meta)
    +				*cp++ = '\033';
    +
    +			memcpy(cp, xstr, len);
    +			len = cp - buf + len;
     			break;
     		}
     	}
    +	ttywrite(buf, len);
    +	if(IS_SET(MODE_ECHO))
    +		techo(buf, len);
     }

    +
     void
     cmessage(XEvent *e) {
     	/* See xembed specs