X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=st.c;h=db21901c158e063092b66bb7405a8638605c5987;hb=0df350cd0b64f83fbc2324bb2a1bc04b51e657e0;hp=14408c566a54369e7fde2d7a167930fb75b21803;hpb=ea782bfc5d34d712bc9391e498935d2d27f3116c;p=st.git diff --git a/st.c b/st.c index 14408c5..db21901 100644 --- a/st.c +++ b/st.c @@ -59,13 +59,12 @@ #define STR_ARG_SIZ 16 #define DRAW_BUF_SIZ 20*1024 #define UTF_SIZ 4 -#define XK_NO_MOD UINT_MAX -#define XK_ANY_MOD 0 +#define XK_ANY_MOD UINT_MAX +#define XK_NO_MOD 0 #define REDRAW_TIMEOUT (80*1000) /* 80 ms */ /* macros */ -#define CLEANMASK(mask) (mask & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) #define SERRNO strerror(errno) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) < (b) ? (b) : (a)) @@ -90,10 +89,6 @@ enum glyph_attribute { }; enum cursor_movement { - CURSOR_UP, - CURSOR_DOWN, - CURSOR_LEFT, - CURSOR_RIGHT, CURSOR_SAVE, CURSOR_LOAD }; @@ -329,6 +324,7 @@ static void tsetmode(bool, bool, int *, int); static void tfulldirt(void); static void techo(char *, int); +static inline bool match(uint, uint); static void ttynew(void); static void ttyread(void); static void ttyresize(void); @@ -2100,11 +2096,19 @@ tputc(char *c, int len) { sel.bx = -1; if(IS_SET(MODE_WRAP) && term.c.state & CURSOR_WRAPNEXT) tnewline(1); /* always go to first col */ + + if(IS_SET(MODE_INSERT) && term.c.x+1 < term.col) { + memmove(&term.line[term.c.y][term.c.x+1], + &term.line[term.c.y][term.c.x], + (term.col - term.c.x - 1) * sizeof(Glyph)); + } + tsetchar(c, &term.c.attr, term.c.x, term.c.y); - if(term.c.x+1 < term.col) + if(term.c.x+1 < term.col) { tmoveto(term.c.x+1, term.c.y); - else + } else { term.c.state |= CURSOR_WRAPNEXT; + } } int @@ -2688,32 +2692,60 @@ focus(XEvent *ev) { } } +inline bool +match(uint mask, uint state) { + if(mask == XK_NO_MOD && state) + return false; + if(mask != XK_ANY_MOD && mask != XK_NO_MOD && !state) + return false; + if((state & mask) != state) + return false; + return true; +} + char* kmap(KeySym k, uint state) { uint mask; Key *kp; + int i; + + /* Check for mapped keys out of X11 function keys. */ + for(i = 0; i < LEN(mappedkeys); i++) { + if(mappedkeys[i] == k) + break; + } + if(i == LEN(mappedkeys)) { + if((k & 0xFFFF) < 0xFF00) + return NULL; + } - state &= ~Mod2Mask; 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)) + + if(!match(mask, state)) continue; + if((kp->appkey < 0 && IS_SET(MODE_APPKEYPAD)) || - (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))) + (kp->appcursor > 0 && !IS_SET(MODE_APPCURSOR))) { continue; + } + if((kp->crlf < 0 && IS_SET(MODE_CRLF)) || - (kp->crlf > 0 && !IS_SET(MODE_CRLF))) + (kp->crlf > 0 && !IS_SET(MODE_CRLF))) { continue; + } return kp->s; } + return NULL; } @@ -2722,21 +2754,20 @@ kpress(XEvent *ev) { XKeyEvent *e = &ev->xkey; KeySym ksym; char xstr[31], buf[32], *customkey, *cp = buf; - int len, i; + int len; Status status; + Shortcut *bp; if (IS_SET(MODE_KBDLOCK)) return; len = XmbLookupString(xw.xic, e, xstr, sizeof(xstr), &ksym, &status); - + e->state &= ~Mod2Mask; /* 1. shortcuts */ - for(i = 0; i < LEN(shortcuts); i++) { - if((ksym == shortcuts[i].keysym) - && (CLEANMASK(shortcuts[i].mod) == \ - CLEANMASK(e->state)) - && shortcuts[i].func) { - shortcuts[i].func(&(shortcuts[i].arg)); + for(bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { + if(ksym == bp->keysym && match(bp->mod, e->state)) { + bp->func(&(bp->arg)); + return; } } @@ -2755,6 +2786,7 @@ kpress(XEvent *ev) { memcpy(cp, xstr, len); len = cp - buf + len; } + ttywrite(buf, len); if(IS_SET(MODE_ECHO)) techo(buf, len); @@ -2869,7 +2901,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; @@ -2924,6 +2956,7 @@ run: ttynew(); selinit(); run(); + return 0; }