Introduction
Introduction Statistics Contact Development Disclaimer Help
Greatly simplified keyboard handling. - sam - An updated version of the sam tex…
git clone git://vernunftzentrum.de/sam.git
Log
Files
Refs
LICENSE
---
commit d16e3252dccaf9fe42dcaccdb0f41ca955689acc
parent 35ebbbec7c409c8852a3f16fe2d401ab39fcef87
Author: Rob King <[email protected]>
Date: Thu, 11 Aug 2016 19:49:27 -0500
Greatly simplified keyboard handling.
Diffstat:
config.h | 3 ---
include/commands.h | 26 ++++++++++++++++++++++++++
include/libg.h | 8 ++------
libXg/gwin.c | 152 ++++++++++++++++++++-----------
libXg/xtbinit.c | 4 ++--
samterm/io.c | 8 +-------
samterm/main.c | 462 ++++++++++++++++++-------------
samterm/samterm.h | 1 -
8 files changed, 408 insertions(+), 256 deletions(-)
---
diff --git a/config.h b/config.h
@@ -19,9 +19,6 @@
#define CHARLEFT 0x13 /* Ctrl-S */
#define CHARRIGHT 0x04 /* Ctrl-D */
#define COMMANDKEY 0x0B /* Ctrl-K */
-#define SCROLLKEY 0x80 /* Scroll down. */
-#define UPKEY 0x81 /* Scroll up. */
-#define ESC 0x1B /* Escape */
/* The remote shell to use for remote connections. */
#define RXPATH "/usr/bin/ssh"
diff --git a/include/commands.h b/include/commands.h
@@ -0,0 +1,26 @@
+#ifndef _COMMANDS_H
+#define _COMMANDS_H
+
+enum{
+ Knone,
+ Kraw,
+ Kcomposed,
+ Kcommand
+};
+
+enum{
+ Cescape,
+ Cscrolldown,
+ Cscrollup,
+ Cjump,
+ Ccharright,
+ Ccharleft,
+ Clinedown,
+ Clineup,
+ Cdelword,
+ Cdelbol,
+ Cdel,
+ Cmax
+}; /* virtual command keystrokes */
+
+#endif
diff --git a/include/libg.h b/include/libg.h
@@ -13,6 +13,8 @@
#include <X11/Xft/Xft.h>
#undef Cursor
+#include <commands.h>
+
enum{ EMAXMSG = 128+8192 }; /* max event size */
/*
@@ -59,12 +61,6 @@ struct Mouse
unsigned long msec;
};
-enum{
- Kraw,
- Kcomposed,
- Kcommand
-};
-
struct Keystroke
{
int k;
diff --git a/libXg/gwin.c b/libXg/gwin.c
@@ -19,6 +19,8 @@ typedef char* caddr_t;
#endif
#include "GwinP.h"
+#include "../config.h"
+#include <commands.h>
/* Forward declarations */
static void Realize(Widget, XtValueMask *, XSetWindowAttributes *);
@@ -170,6 +172,7 @@ Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
static unsigned char compose[5];
static int composing = -2;
int composed = 0;
+ int kind = Kraw;
int c, minmod;
KeySym k, mk;
@@ -212,58 +215,78 @@ Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
}
if(k == NoSymbol)
return;
- if(k&0xFF00){
- switch(k){
- case XK_BackSpace:
- case XK_Tab:
- case XK_Escape:
- case XK_Delete:
- case XK_KP_0:
- case XK_KP_1:
- case XK_KP_2:
- case XK_KP_3:
- case XK_KP_4:
- case XK_KP_5:
- case XK_KP_6:
- case XK_KP_7:
- case XK_KP_8:
- case XK_KP_9:
- case XK_KP_Divide:
- case XK_KP_Multiply:
- case XK_KP_Subtract:
- case XK_KP_Add:
- case XK_KP_Decimal:
- k &= 0x7F;
- break;
- case XK_Linefeed:
- k = '\r';
- break;
- case XK_KP_Enter:
- case XK_Return:
- k = '\n';
- break;
- case XK_Left:
- case XK_Down:
- case XK_Right:
- case XK_Next:
- k = 0x80; /* VIEW -- "Scroll" */
- break;
- case XK_Up:
- case XK_Prior:
- k = 0x81; /* PREVIEW -- "Scroll back" */
- break;
- default:
- return; /* not ISO-1 or tty control */
- }
- }
+
+ if (k & 0xFF00){
+ switch(k){
+ case XK_Escape:
+ kind = Kcommand;
+ k = Cescape;
+ break;
+
+ case XK_BackSpace:
+ case XK_Delete:
+ kind = Kcommand;
+ k = Cdel;
+ break;
+
+ case XK_Tab:
+ case XK_KP_0:
+ case XK_KP_1:
+ case XK_KP_2:
+ case XK_KP_3:
+ case XK_KP_4:
+ case XK_KP_5:
+ case XK_KP_6:
+ case XK_KP_7:
+ case XK_KP_8:
+ case XK_KP_9:
+ case XK_KP_Divide:
+ case XK_KP_Multiply:
+ case XK_KP_Subtract:
+ case XK_KP_Add:
+ case XK_KP_Decimal:
+ k &= 0x7F;
+ break;
+
+ case XK_Linefeed:
+ k = '\r';
+ break;
+
+ case XK_KP_Enter:
+ case XK_Return:
+ k = '\n';
+ break;
+
+ case XK_Up:
+ case XK_Prior:
+ case XK_Left:
+ kind = Kcommand;
+ k = Cscrollup;
+ break;
+
+ case XK_Right:
+ case XK_Next:
+ case XK_Down:
+ kind = Kcommand;
+ k = Cscrolldown;
+ break;
+
+ default:
+ return; /* not ISO-1 or tty control */
+ }
+ }
+
/* Compensate for servers that call a minus a hyphen */
- if(k == XK_hyphen)
- k = XK_minus;
+ if (k == XK_hyphen)
+ k = XK_minus;
+
/* Do control mapping ourselves if translator doesn't */
- if((e->xkey.state&ControlMask) && !(md&ControlMask))
- k &= 0x9f;
- if(k == NoSymbol)
- return;
+ if ((e->xkey.state & ControlMask) && !(md & ControlMask))
+ k &= 0x9f;
+
+ if(k == NoSymbol)
+ return;
+
/* Check to see if we are in a composition sequence */
if (!((GwinWidget)w)->gwin.compose && (e->xkey.state & Mod1Mask)
&& composing == -2)
@@ -306,9 +329,36 @@ Keyaction(Widget w, XEvent *e, String *p, Cardinal *np)
if (composing >= -1)
return;
+ switch (c){
+ case LINEUP:
+ kind = Kcommand;
+ c = Clineup;
+ break;
+
+ case LINEDOWN:
+ kind = Kcommand;
+ c = Clinedown;
+ break;
+
+ case CHARLEFT:
+ kind = Kcommand;
+ c = Ccharleft;
+ break;
+
+ case CHARRIGHT:
+ kind = Kcommand;
+ c = Ccharright;
+ break;
+
+ case COMMANDKEY:
+ kind = Kcommand;
+ c = Cjump;
+ break;
+ }
+
f = ((GwinWidget)w)->gwin.gotchar;
if(f)
- (*f)(c, composed);
+ (*f)(c, kind);
}
static void
diff --git a/libXg/xtbinit.c b/libXg/xtbinit.c
@@ -273,7 +273,7 @@ reshaped(int minx, int miny, int maxx, int maxy)
}
static void
-gotchar(int c, int composed)
+gotchar(int c, int kind)
{
Ebuf *eb;
Keystroke k;
@@ -284,7 +284,7 @@ gotchar(int c, int composed)
if (eb == 0)
berror("eballoc can't malloc");
k.c = c;
- k.k = composed ? Kcomposed : Kraw;
+ k.k = kind;
memcpy(eb->buf, &k, sizeof(Keystroke));
esrc[Skeyboard].count++;
}
diff --git a/samterm/io.c b/samterm/io.c
@@ -156,7 +156,7 @@ kbdchar(void)
return k;
if(got & Ekeyboard){
k = keystroke;
- keystroke.c = -1;
+ memset(&keystroke, 0, sizeof(keystroke));
got &= ~Ekeyboard;
return k;
}
@@ -174,12 +174,6 @@ kbdchar(void)
return ekbd();
}
-int
-qpeekc(void)
-{
- return keystroke.c;
-}
-
void
ereshaped(Rectangle r)
{
diff --git a/samterm/main.c b/samterm/main.c
@@ -6,6 +6,7 @@
#include <unistd.h>
#include "flayer.h"
#include "samterm.h"
+#include <commands.h>
Text cmd;
Rune *scratch;
@@ -470,58 +471,259 @@ flushtyping(int clearesc)
XFlush(_dpy);
}
+long
+cmdscrolldown(Flayer *l, long a, Text *t)
+{
+ flushtyping(0);
+ center(l, l->origin + l->f.nchars + 1);
+ return a;
+}
+
+long
+cmdscrollup(Flayer *l, long a, Text *t)
+{
+ flushtyping(0);
+ outTsll(Torigin, t->tag, l->origin, l->f.maxlines + 1);
+ return a;
+}
+
+long
+cmdcharleft(Flayer *l, long a, Text *t)
+{
+ flsetselect(l, a, a);
+ flushtyping(0);
+ if (a > 0)
+ a--;
+ flsetselect(l, a, a);
+ center(l, a);
+
+ return a;
+}
+
+long
+cmdcharright(Flayer *l, long a, Text *t)
+{
+ flsetselect(l, a, a);
+ flushtyping(0);
+ if (a < t->rasp.nrunes)
+ a++;
+ flsetselect(l, a, a);
+ center(l, a);
+
+ return a;
+}
+
+long
+cmdlineup(Flayer *l, long a, Text *t)
+{
+ flsetselect(l, a, a);
+ flushtyping(1);
+ if (a > 0){
+ long n0, n1, count = 0;
+ while (a > 0 && raspc(&t->rasp, a - 1) != '\n'){
+ a--;
+ count++;
+ }
+ if (a > 0){
+ n1 = a;
+ a--;
+ while (a > 0 && raspc(&t->rasp, a - 1) != '\n')
+ a--;
+
+ n0 = a;
+ a = (n0 + count >= n1) ? n1 - 1 : n0 + count;
+ flsetselect(l, a, a);
+ center(l, a);
+ }
+ }
+
+ return a;
+}
+
+long
+cmdlinedown(Flayer *l, long a, Text *t)
+{
+ flsetselect(l, a, a);
+ flushtyping(1);
+ if (a < t->rasp.nrunes){
+ long p0, count = 0;
+
+ p0 = a;
+ while (a > 0 && raspc(&t->rasp, a - 1) != '\n'){
+ a--;
+ count++;
+ }
+
+ a = p0;
+ while (a < t->rasp.nrunes && raspc(&t->rasp, a) != '\n')
+ a++;
+
+ if (a < t->rasp.nrunes){
+ a++;
+ while (a < t->rasp.nrunes && count > 0 && raspc(&t->rasp, a) != '\…
+ a++;
+ count--;
+ }
+ if (a != p0){
+ flsetselect(l, a, a);
+ center(l, a);
+ }
+ }
+ }
+
+ return a;
+}
+
+long
+cmdjump(Flayer *l, long a, Text *u)
+{
+ Text *t = NULL;
+
+ if (which == &cmd.l[cmd.front] && flast)
+ current(flast);
+ else{
+ l = &cmd.l[cmd.front];
+ t = (Text *)l->user1;
+ flast = which;
+ current(l);
+ flushtyping(0);
+ flsetselect(l, t->rasp.nrunes, t->rasp.nrunes);
+ center(l, a);
+ }
+
+ return a;
+}
+
+long
+cmdescape(Flayer *l, long a, Text *t)
+{
+ if (typeesc >= 0){
+ l->p0 = typeesc;
+ l->p1 = a;
+ flushtyping(1);
+ }
+
+ for (l = t->l; l < &t->l[NL]; l++)
+ if (l->textfn)
+ flsetselect(l, l->p0, l->p1);
+
+ return a;
+}
+
+long
+cmddelword(Flayer *l, long a, Text *t)
+{
+ if (l->f.p0 > 0 && a > 0)
+ l->p0 = ctlw(&t->rasp, l->origin, a);
+
+ l->p1 = a;
+ if (l->p1 != l->p0){
+ if(typestart<=l->p0 && l->p1<=typeend){
+ t->lock++; /* to call hcut */
+ hcut(t->tag, l->p0, l->p1-l->p0);
+ /* hcheck is local because we know rasp is contiguous */
+ hcheck(t->tag);
+ }else{
+ flushtyping(0);
+ cut(t, t->front, 0, 1);
+ }
+ }
+
+ return a;
+}
+
+long
+cmddelbol(Flayer *l, long a, Text *t)
+{
+ if (l->f.p0 > 0 && a > 0)
+ l->p0 = ctlu(&t->rasp, l->origin, a);
+
+ l->p1 = a;
+ if (l->p1 != l->p0){
+ if(typestart<=l->p0 && l->p1<=typeend){
+ t->lock++; /* to call hcut */
+ hcut(t->tag, l->p0, l->p1-l->p0);
+ /* hcheck is local because we know rasp is contiguous */
+ hcheck(t->tag);
+ }else{
+ flushtyping(0);
+ cut(t, t->front, 0, 1);
+ }
+ }
+
+ return a;
+}
+
+long
+cmddel(Flayer *l, long a, Text *t)
+{
+ if (l->f.p0 > 0 && a > 0)
+ l->p0 = a - 1;
+
+ l->p1 = a;
+ if (l->p1 != l->p0){
+ if(typestart<=l->p0 && l->p1<=typeend){
+ t->lock++; /* to call hcut */
+ hcut(t->tag, l->p0, l->p1-l->p0);
+ /* hcheck is local because we know rasp is contiguous */
+ hcheck(t->tag);
+ }else{
+ flushtyping(0);
+ cut(t, t->front, 0, 1);
+ }
+ }
+
+ return a;
+}
+
+typedef long (*Commandfunc)(Flayer *, long, Text *);
+typedef struct CommandEntry CommandEntry;
+struct CommandEntry{
+ Commandfunc f;
+ int lock;
+};
+
+CommandEntry commands[Cmax] ={
+ [Cscrolldown] = {cmdscrolldown, 0},
+ [Cscrollup] = {cmdscrollup, 0},
+ [Ccharleft] = {cmdcharleft, 0},
+ [Ccharright] = {cmdcharright, 0},
+ [Clineup] = {cmdlineup, 0},
+ [Clinedown] = {cmdlinedown, 0},
+ [Cjump] = {cmdjump, 0},
+ [Cescape] = {cmdescape, 0},
+ [Cdelword] = {cmddelword, 1},
+ [Cdelbol] = {cmddelbol, 1},
+ [Cdel] = {cmddel, 1}
+};
+
void
type(Flayer *l, int res) /* what a bloody mess this is */
{
Text *t = (Text *)l->user1;
Rune buf[100];
- Keystroke k;
+ Keystroke k = {0};
Rune *p = buf;
- int c, backspacing, moving;
+ int backspacing, moving;
long a;
- int scrollkey, upkey, movekey;
-
- scrollkey = 0;
- upkey = 0;
- movekey = 0;
- if(res == RKeyboard) {
- int pc = qpeekc();
- scrollkey = pc==SCROLLKEY; /* ICK */
- upkey = pc == UPKEY;
- movekey = (pc == CHARLEFT || pc == CHARRIGHT || pc == LINEUP |…
- }
if(lock || t->lock){
kbdblock();
return;
}
+
a = l->p0;
- if(a!=l->p1 && !scrollkey && !upkey && !movekey){
+ if (a != l->p1 && k.k != Kcommand){
flushtyping(1);
cut(t, t->front, 1, 1);
return; /* it may now be locked */
}
- backspacing = 0;
- moving = 0;
- while(((k = kbdchar()), k.c) > 0){
- c = k.c;
- if(res == RKeyboard){
- if(c == UPKEY || c==SCROLLKEY || c==ESC || c==COMMANDK…
- break;
-
- /* ctrl-s, ctrl-e, ctrl-d, ctrl-x */
- if (c==CHARLEFT || c==CHARRIGHT || c==LINEUP || c==LIN…
- moving = 1;
- break;
- }
- /* backspace, ctrl-u, ctrl-w, del */
- if(c=='\b' || c==0x15 || c==0x17 || c==0x7F){
- backspacing = 1;
- break;
- }
- }
- if (expandtabs && c == '\t' && k.k != Kcomposed){
+ while (((k = kbdchar()), k.c) > 0) {
+ if (k.k == Kcommand)
+ break;
+
+ if (expandtabs && k.c == '\t' && k.k != Kcomposed){
int col = 0, nspaces = 8, off = a;
int i;
while (off > 0 && raspc(&t->rasp, off - 1) != '\n')
@@ -532,164 +734,52 @@ type(Flayer *l, int res) /* what a bloody mess th…
pushkbd(' ');
break;
}
- *p++ = c;
- if(c == '\n' || p >= buf+sizeof(buf)/sizeof(buf[0]))
+
+ *p++ = k.c;
+ if (k.c == '\n' || p >= buf + sizeof(buf) / sizeof(buf[0]))
break;
}
- if(p > buf){
- if(typestart < 0)
- typestart = a;
- if(typeesc < 0)
- typeesc = a;
- hgrow(t->tag, a, p-buf, 0);
- t->lock++; /* pretend we Trequest'ed for hdatarune*/
- hdatarune(t->tag, a, buf, p-buf);
- a += p-buf;
- l->p0 = a;
- l->p1 = a;
- typeend = a;
- if(c=='\n' || typeend-typestart>100)
- flushtyping(0);
- onethird(l, a);
- }
- if(c == SCROLLKEY){
- flushtyping(0);
- center(l, l->origin+l->f.nchars+1);
- } else if (c == UPKEY) {
- flushtyping(0);
- outTsll(Torigin, t->tag, l->origin, l->f.maxlines+1);
- /* backspacing immediately after outcmd(): sorry */
- } else if (moving){
- if (c == CHARLEFT){
- flsetselect(l, a, a);
- flushtyping(0);
- if (a > 0)
- a--;
- flsetselect(l, a, a);
- center(l, a);
- } else if (c == CHARRIGHT){
- flsetselect(l, a, a);
+
+ if (p > buf){
+ if (typestart < 0)
+ typestart = a;
+
+ if (typeesc < 0)
+ typeesc = a;
+
+ hgrow(t->tag, a, p-buf, 0);
+ t->lock++; /* pretend we Trequest'ed for hdatarune*/
+ hdatarune(t->tag, a, buf, p-buf);
+ a += p-buf;
+ l->p0 = a;
+ l->p1 = a;
+ typeend = a;
+ if (k.c == '\n' || typeend - typestart > 100)
flushtyping(0);
- if (a < t->rasp.nrunes)
- a++;
- flsetselect(l, a, a);
- center(l, a);
- } else if (c == LINEUP){
- flsetselect(l, a, a);
- flushtyping(1);
- if (a > 0){
- long n0, n1, count = 0;
- while (a > 0 && raspc(&t->rasp, a - 1) != '\n'){
- a--;
- count++;
- }
- if (a > 0){
- n1 = a;
- a--;
- while (a > 0 && raspc(&t->rasp, a - 1) != '\n')
- a--;
-
- n0 = a;
- a = (n0 + count >= n1) ? n1 - 1 : n0 + count;
- flsetselect(l, a, a);
- center(l, a);
- }
- }
- } else if (c == LINEDOWN){
- flsetselect(l, a, a);
- flushtyping(1);
- if (a < t->rasp.nrunes){
- long p0, count = 0;
-
- p0 = a;
- while (a > 0 && raspc(&t->rasp, a - 1) != '\n'){
- a--;
- count++;
- }
-
- a = p0;
- while (a < t->rasp.nrunes && raspc(&t->rasp, a) != '\n')
- a++;
-
- if (a < t->rasp.nrunes){
- a++;
- while (a < t->rasp.nrunes && count > 0 && raspc(&t->rasp, …
- a++;
- count--;
- }
- if (a != p0){
- flsetselect(l, a, a);
- center(l, a);
- }
- }
- }
+ onethird(l, a);
+ }
+
+ if (k.k == Kcommand){
+ CommandEntry *e = &commands[k.k];
+ if (e->lock == 0 || !lock)
+ a = e->f(l, a, t);
+ }
+
+ if (typeesc >= l->p0)
+ typeesc = l->p0;
+
+ if (typestart >= 0){
+ if(typestart >= l->p0)
+ typestart = l->p0;
+ typeend = l->p0;
+ if (typestart == typeend){
+ typestart = -1;
+ typeend = -1;
+ modified = 0;
}
- }else if(backspacing && !lock){
- if(l->f.p0>0 && a>0){
- switch(c){
- case '\b':
- case 0x7F: /* del */
- l->p0 = a-1;
- break;
- case 0x15: /* ctrl-u */
- l->p0 = ctlu(&t->rasp, l->origin, a);
- break;
- case 0x17: /* ctrl-w */
- l->p0 = ctlw(&t->rasp, l->origin, a);
- break;
- }
- l->p1 = a;
- if(l->p1 != l->p0){
- /* cut locally if possible */
- if(typestart<=l->p0 && l->p1<=typeend){
- t->lock++; /* to call hcut */
- hcut(t->tag, l->p0, l->p1-l->p0);
- /* hcheck is local because we know ras…
- hcheck(t->tag);
- }else{
- flushtyping(0);
- cut(t, t->front, 0, 1);
- }
- }
- if(typeesc >= l->p0)
- typeesc = l->p0;
- if(typestart >= 0){
- if(typestart >= l->p0)
- typestart = l->p0;
- typeend = l->p0;
- if(typestart == typeend){
- typestart = -1;
- typeend = -1;
- modified = 0;
- }
- }
- }
- }else if(c==COMMANDKEY){
- if(which == &cmd.l[cmd.front]){
- if (flast)
- current(flast);
- }else{
- l = &cmd.l[cmd.front];
- Text *t = (Text *)l->user1;
- flast = which;
- current(l);
- flushtyping(0);
- flsetselect(l, t->rasp.nrunes, t->rasp.nrunes);
- center(l, a);
- }
- }else{
- if(c==ESC && typeesc>=0){
- l->p0 = typeesc;
- l->p1 = a;
- flushtyping(1);
- }
- for(l=t->l; l<&t->l[NL]; l++)
- if(l->textfn)
- flsetselect(l, l->p0, l->p1);
- }
+ }
}
-
void
outcmd(void){
if(work)
diff --git a/samterm/samterm.h b/samterm/samterm.h
@@ -91,7 +91,6 @@ int waitforio(void);
int rcvchar(void);
int getch(void);
Keystroke kbdchar(void);
-int qpeekc(void);
void mouseexit(void);
void cut(Text*, int, int, int);
void paste(Text*, int);
You are viewing proxied material from vernunftzentrum.de. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.