[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[screen-devel] [patch] DECKPM support
From: |
Brian Templeton |
Subject: |
[screen-devel] [patch] DECKPM support |
Date: |
Tue, 10 Feb 2009 02:32:36 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/23.0.90 (gnu/linux) |
I've added support for Key Position Mode, which makes it possible to
effectively remap modifier and function keys on some DEC terminals.
>From ab7e813b84dcaf8d13479a662ba0014d25231143 Mon Sep 17 00:00:00 2001
From: Brian Templeton <address@hidden>
Date: Tue, 10 Feb 2009 01:33:58 -0500
Subject: [PATCH] Enable Key Position Mode on DEC VT420 terminals.
The key mapping (defined in kpm.c) uses a modified Dvorak layout and
maps the Lock key to Control.
---
src/Makefile.in | 4 +-
src/display.c | 34 ++++++++++
src/kpm.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/kpm.h | 4 +
4 files changed, 235 insertions(+), 2 deletions(-)
create mode 100644 src/kpm.c
create mode 100644 src/kpm.h
diff --git a/src/Makefile.in b/src/Makefile.in
index c551067..b37c408 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -61,12 +61,12 @@ CFILES= screen.c ansi.c fileio.c mark.c misc.c resize.c
socket.c \
search.c tty.c term.c window.c utmp.c loadav.c putenv.c help.c \
termcap.c input.c attacher.c pty.c process.c display.c comm.c \
kmapdef.c acls.c braille.c braille_tsi.c logfile.c layer.c \
- sched.c teln.c nethack.c encoding.c
+ sched.c teln.c nethack.c encoding.c kpm.c
OFILES= screen.o ansi.o fileio.o mark.o misc.o resize.o socket.o \
search.o tty.o term.o window.o utmp.o loadav.o putenv.o help.o \
termcap.o input.o attacher.o pty.o process.o display.o comm.o \
kmapdef.o acls.o braille.o braille_tsi.o logfile.o layer.o \
- sched.o teln.o nethack.o encoding.o
+ sched.o teln.o nethack.o encoding.o kpm.o
all: screen
diff --git a/src/display.c b/src/display.c
index ec13ec7..6489c62 100644
--- a/src/display.c
+++ b/src/display.c
@@ -29,6 +29,7 @@
#include <sys/types.h>
#include <signal.h>
#include <fcntl.h>
+#include <string.h>
#ifndef sun
# include <sys/ioctl.h>
#endif
@@ -37,6 +38,9 @@
#include "screen.h"
#include "extern.h"
#include "braille.h"
+#include "kpm.h"
+
+#define ENABLE_KPM_P (strncmp(D_termname, "vt420", 5) == 0)
static int CountChars __P((int));
static int DoAddChar __P((int));
@@ -1153,6 +1157,8 @@ int adapt;
{
ASSERT(display);
ASSERT(D_tcinited);
+ if (ENABLE_KPM_P)
+ kpm_on(D_userfd);
D_top = D_bot = -1;
AddCStr(D_TI);
AddCStr(D_IS);
@@ -1196,6 +1202,8 @@ FinitTerm()
#ifdef BLANKER_PRG
KillBlanker();
#endif
+ if (ENABLE_KPM_P)
+ kpm_off(D_userfd);
if (D_tcinited)
{
ResizeDisplay(D_defwidth, D_defheight);
@@ -4040,6 +4048,32 @@ char *data;
size -= 5;
}
}
+ if (ENABLE_KPM_P) {
+ char kbuf[IOSIZE];
+ int krc, ki, ksize = 0;
+ char kout[6];
+ for (ki = 0; ki < size; ki++) {
+ krc = kpm_decode(buf[ki]);
+ if (krc < 0) {
+ Msg(0, "KPM parsing failed");
+ return;
+ } else if (krc == 0) {
+ continue;
+ } else {
+ krc = kpm_map(kpm_state.pos, kpm_state.mod, kout);
+ if (krc >= 0) {
+ memcpy(kbuf+ksize, kout, krc);
+ ksize += krc;
+ }
+ }
+ }
+ if (ksize > 0) {
+ memcpy(buf, kbuf, ksize);
+ size = ksize;
+ } else {
+ return;
+ }
+ }
#ifdef ENCODINGS
if (D_encoding != (D_forecv ? D_forecv->c_layer->l_encoding : 0))
{
diff --git a/src/kpm.c b/src/kpm.c
new file mode 100644
index 0000000..c7e3950
--- /dev/null
+++ b/src/kpm.c
@@ -0,0 +1,195 @@
+#include <string.h>
+#include "kpm.h"
+
+enum {
+ M_SHIFT_L = 0x01,
+ M_SHIFT_R = 0x02,
+ M_LOCK = 0x04,
+ M_CTRL = 0x08,
+ M_ALT_L = 0x10,
+ M_ALT_R = 0x20,
+ M_COMPOSE_L = 0x40,
+ M_COMPOSE_R = 0x80
+};
+
+/*
+ * G99: F1
+ * G00..G03: F2..F5
+ * G05..G09: F6..F10
+ * G11..G14: F11..F14
+ * G16..G17: Help, Do
+ * G20..G23: F17..F20
+ * E16..E18: Find, Insert Here, Remove
+ * D16: Select, Prev, Next
+ * C17: Up
+ * B16..B18: Left, Down, Right
+ * E20..E23: PF1..PF4
+ * D20..D23: 7, 8, 9, minus
+ * C20..C23: 4, 5, 6, comma
+ * B20..B22: 1, 2, 3
+ * A20: 0
+ * A22..A23: period, Enter
+ */
+
+char* kpm_keys['H'][100] = {
+ ['A'] = { 0, 0, " " },
+ ['B'] = { "<>", ";:", "qQ", "jJ","kK", "xX",
+ "bB","mM","wW","vV","zZ" },
+ ['C'] = { 0, "aA", "oO", "eE", "uU", "iI",
+ "dD", "hH", "tT", "nN", "sS", "-_", "\\|", "\r\r" },
+ ['D'] = { "\t\t", "'\"", ",(", ".)", "pP", "yY",
+ "fF","gG","cC","rR", "lL", "/?", "=+" },
+ ['E'] = { "`~", "1!", "2@", "3#", "4$", "5%",
+ "6^", "7&", "8*", "9<", "0>", "[{", "]}", "\x7F\x7F" }
+};
+
+#define CSI "\x1B["
+#define SS3 "\x1BO"
+char* kpm_keys_x['H'][100] = {
+ ['A'] = { [20] = SS3 "p", SS3 "n", SS3 "M" },
+ ['B'] = { [16] = SS3 "D", SS3 "B", SS3 "C",
+ [20] = SS3 "q", SS3 "r", SS3 "s" },
+ ['C'] = { [17] = SS3 "A",
+ [20] = SS3 "t", SS3 "u", SS3 "v", SS3 "l" },
+ ['D'] = { [16] = CSI "4~", CSI "5~", CSI "6~",
+ [20] = SS3 "w", SS3 "x", SS3 "y", SS3 "m" },
+ ['E'] = { [16] = CSI "1~", CSI "2~", CSI "3~",
+ [20] = SS3 "P", SS3 "Q", SS3 "R", SS3 "S" },
+ ['G'] = { CSI "12~", CSI "13~", CSI "14~", CSI "15~", 0,
+ CSI "17~", CSI "18~", CSI "19~", CSI "20~", CSI "21~", 0,
+ CSI "23~", CSI "24~", CSI "25~", CSI "26~", 0,
+ CSI "28~", CSI "29~", 0, 0,
+ CSI "31~", CSI "32~", CSI "33~", CSI "34~",
+ [99] = CSI "11~" }
+};
+
+typedef struct {
+ int state;
+ char pos[3];
+ int mod;
+ char buf[5];
+ int n;
+} kpm_state_t;
+
+kpm_state_t kpm_state;
+
+int kpm_on(int fd)
+{
+ kpm_state.state = 0;
+ write(fd, "\x1B[?81h", 6);
+}
+
+int kpm_off(int fd)
+{
+ write(fd, "\x1B[?81l", 6);
+}
+
+int kpm_keys_lookup(char pos[3], char **k)
+{
+ char **r;
+ int d = 10 * ((int)pos[1] - 48) + ((int)pos[2] - 48);
+ r = kpm_keys[pos[0]];
+ if (!r)
+ goto ext;
+ *k = r[d];
+ if (!*k)
+ goto ext;
+ return 0;
+
+ ext:
+ r = kpm_keys_x[pos[0]];
+ if (!r)
+ return -1;
+ *k = r[d];
+ if (!*k)
+ return -1;
+ return 1;
+}
+
+#define CTRLP(m) ((m & M_CTRL) || (m & M_LOCK))
+#define SHIFTP(m) ((m & M_SHIFT_L) || (m & M_SHIFT_R))
+#define ALTP(m) ((m & M_ALT_L) || (m & M_ALT_R))
+#define UPPER_ALPHA_P(c) (('A' <= c) && (c <= 'Z'))
+int kpm_map(char pos[3], int mod, char *out)
+{
+ char *k, c;
+ int l;
+ switch (kpm_keys_lookup(pos, &k)) {
+ case -1:
+ return -1;
+ case 0:
+ if (CTRLP(mod) && UPPER_ALPHA_P(k[1]))
+ c = k[1]-'@';
+ else if (SHIFTP(mod))
+ c = k[1];
+ else
+ c = k[0];
+ if (ALTP(mod))
+ c |= 0x80;
+ out[0] = c;
+ return 1;
+ case 1:
+ l = strlen(k);
+ memcpy(out, k, l);
+ return l;
+ }
+}
+
+#define KPM_END(r, next) \
+ ({ kpm_state.state = next; return r; })
+#define KPM_NEED(x, next) \
+ ({if (c == x) { KPM_END(0, next); } else { return -1; } })
+
+int kpm_decode(char c)
+{
+ switch (kpm_state.state) {
+ case 0:
+ KPM_NEED('\x1B', 1);
+ case 1:
+ KPM_NEED('_', 2);
+ case 2:
+ KPM_NEED(':', 3);
+ case 3:
+ kpm_state.buf[0] = c;
+ kpm_state.n = 1;
+ KPM_END(0, 4);
+ case 4:
+ kpm_state.buf[kpm_state.n++] = c;
+ if (kpm_state.n == 5) {
+ kpm_state.pos[0] = kpm_state.buf[0];
+ kpm_state.pos[1] = kpm_state.buf[1];
+ kpm_state.pos[2] = kpm_state.buf[2];
+ kpm_state.mod = (16 * ((int)kpm_state.buf[3] - 48)
+ + ((int)kpm_state.buf[4] - 48));
+ KPM_END(1, 5);
+ } else {
+ KPM_END(0, 4);
+ }
+ case 5:
+ switch (c) {
+ case '\x1B':
+ KPM_END(0, 6);
+ case '.':
+ KPM_END(1, 5);
+ case '/':
+ kpm_state.n = 0;
+ KPM_END(0, 7);
+ default:
+ return -1;
+ }
+ case 6:
+ KPM_NEED('\\', 0);
+ case 7:
+ kpm_state.buf[kpm_state.n++] = c;
+ if (kpm_state.n == 3) {
+ kpm_state.pos[0] = kpm_state.buf[0];
+ kpm_state.pos[1] = kpm_state.buf[1];
+ kpm_state.pos[2] = kpm_state.buf[2];
+ KPM_END(1, 5);
+ } else {
+ KPM_END(0, 7);
+ }
+ default:
+ return -1;
+ }
+}
diff --git a/src/kpm.h b/src/kpm.h
new file mode 100644
index 0000000..61ae8ef
--- /dev/null
+++ b/src/kpm.h
@@ -0,0 +1,4 @@
+int kpm_on(int);
+int kpm_off(int);
+int kpm_map(char[3], int, char *);
+int kpm_decode(char);
--
1.5.6.5
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [screen-devel] [patch] DECKPM support,
Brian Templeton <=