X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=st.c;h=932253c3953566b7892411be73603c9e4873d739;hb=16ccf344deccbae53865b6efbe9dc23ebdceccb7;hp=8b18607db7db882c456e1aac45cf0399627769da;hpb=ace789a79fc44c1c3b629f5c0fb477c651d84a48;p=st.git diff --git a/st.c b/st.c index 8b18607..932253c 100644 --- a/st.c +++ b/st.c @@ -110,17 +110,19 @@ 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, + MODE_APPCURSOR = 2048 }; enum escape_state { @@ -226,6 +228,10 @@ typedef struct { KeySym k; uint mask; char s[ESC_BUF_SIZ]; + /* three valued logic variables: 0 indifferent, 1 on, -1 off */ + signed char appkey; /* application keypad */ + signed char appcursor; /* application cursor */ + signed char crlf; /* crlf mode */ } Key; /* TODO: use better name for vars... */ @@ -259,6 +265,7 @@ typedef struct { /* function definitions used in config.h */ static void xzoom(const Arg *); +static void selpaste(const Arg *); /* Config.h for applying patches and the configuration. */ #include "config.h" @@ -320,6 +327,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); @@ -357,7 +365,6 @@ static void selrequest(XEvent *); static void selinit(void); static inline bool selected(int, int); static void selcopy(void); -static void selpaste(void); static void selscroll(int, int); static int utf8decode(char *, long *); @@ -747,7 +754,7 @@ selnotify(XEvent *e) { } void -selpaste(void) { +selpaste(const Arg *dummy) { XConvertSelection(xw.dpy, XA_PRIMARY, sel.xtarget, XA_PRIMARY, xw.win, CurrentTime); } @@ -818,7 +825,7 @@ brelease(XEvent *e) { } if(e->xbutton.button == Button2) { - selpaste(); + selpaste(NULL); } else if(e->xbutton.button == Button1) { sel.mode = 0; getbuttoninfo(e, NULL, &sel.ex, &sel.ey); @@ -1469,7 +1476,7 @@ tsetmode(bool priv, bool set, int *args, int narg) { switch(*args) { break; case 1: /* DECCKM -- Cursor key */ - MODBIT(term.mode, set, MODE_APPKEYPAD); + MODBIT(term.mode, set, MODE_APPCURSOR); break; case 5: /* DECSCNM -- Reverse video */ mode = term.mode; @@ -1534,7 +1541,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 +1857,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; @@ -2660,18 +2690,39 @@ focus(XEvent *ev) { char* kmap(KeySym k, uint state) { - int i; uint mask; + Key *kp; state &= ~Mod2Mask; - for(i = 0; i < LEN(key); i++) { - mask = key[i].mask; + for(kp = key; kp < key + LEN(key); kp++) { + mask = kp->mask; + + if(kp->k != k) + continue; + + if((state & mask) != mask && + (mask == XK_NO_MOD && state)) { + continue; + } + + if((kp->appkey < 0 && IS_SET(MODE_APPKEYPAD)) || + (kp->appkey > 0 && !IS_SET(MODE_APPKEYPAD))) { + continue; + } + + if((kp->appcursor < 0 && IS_SET(MODE_APPCURSOR)) || + (kp->appcursor > 0 && !IS_SET(MODE_APPCURSOR))) { + continue; + } - if(key[i].k == k && ((state & mask) == mask - || (mask == XK_NO_MOD && !state))) { - return (char*)key[i].s; + if((kp->crlf < 0 && IS_SET(MODE_CRLF)) || + (kp->crlf > 0 && !IS_SET(MODE_CRLF))) { + continue; } + + return kp->s; } + return NULL; } @@ -2679,16 +2730,14 @@ void kpress(XEvent *ev) { XKeyEvent *e = &ev->xkey; KeySym ksym; - char buf[32], *customkey; - int len, meta, shift, i; + char xstr[31], buf[32], *customkey, *cp = buf; + int len, i; Status status; if (IS_SET(MODE_KBDLOCK)) return; - 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,46 +2751,26 @@ 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) { - case XK_Up: - case XK_Down: - case XK_Left: - case XK_Right: - /* XXX: shift up/down doesn't work */ - sprintf(buf, "\033%c%c", - IS_SET(MODE_APPKEYPAD) ? 'O' : '[', - (shift ? "dacb":"DACB")[ksym - XK_Left]); - ttywrite(buf, 3); - break; - case XK_Insert: - if(shift) - selpaste(); - break; - case XK_Return: - if(meta) - ttywrite("\033", 1); + if(len == 0) + return; - if(IS_SET(MODE_CRLF)) { - ttywrite("\r\n", 2); - } else { - ttywrite("\r", 1); - } - break; - /* 3. X lookup */ - default: - if(len > 0) { - if(meta && len == 1) - ttywrite("\033", 1); - ttywrite(buf, len); - } - break; - } + if (len == 1 && e->state & Mod1Mask) + *cp++ = '\033'; + + memcpy(cp, xstr, len); + len = cp - buf + len; } + + ttywrite(buf, len); + if(IS_SET(MODE_ECHO)) + techo(buf, len); } + void cmessage(XEvent *e) { /* See xembed specs @@ -2850,7 +2879,7 @@ main(int argc, char *argv[]) { opt_class = argv[i]; break; case 'e': - /* eat every remaining arguments */ + /* eat all remaining arguments */ if(++i < argc) opt_cmd = &argv[i]; goto run; @@ -2905,6 +2934,7 @@ run: ttynew(); selinit(); run(); + return 0; }