bugGNU Screen - Bugs: bug #25574, [patch] DECKPM support

 
 

bug #25574: [patch] DECKPM support

Submitter:  Micah Cowan <micahcowan>
Submitted:  Fri 13 Feb 2009 05:22:25 AM UTC
   
 
Category:  Feature Request Severity:  3 - Normal
Priority:  * 5 - Normal Status:  Need Discussion
Privacy:  Public Assigned to:  None
Open/Closed:  Open Release:  None
Fixed Release:  None Planned Release:  Later
Work Required:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Tue 26 Jan 2016 10:46:03 AM UTC, comment #1: 

http://lists.gnu.org/archive/html/screen-devel/2009-02/msg00000.html

It looks like we forgot about this patch. I'm not sure... do we really need it? I'm going to look at code in details in the few next days.

Alexander Naumov <anaumov>
Group administrator
Fri 13 Feb 2009 05:22:25 AM UTC, original submission:  

From mailing list.

I'd like to move away from the explicit terminal-name checking, (I know we currently do it to detect, say, XT), but that may not be possible until we support terminfo properly, though, rather than termcap. I haven't had a chance to look this over closely.


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


Micah Cowan <micahcowan>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by anaumov (Posted a comment)
  • -email is unavailable- added by micahcowan (Submitted the item)
  • -email is unavailable- added by micahcowan (Brian Templeton, originator)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follows 1 latest change.

    Date Changed by Updated Field Previous Value => Replaced by
    2009-02-13 micahcowan Carbon-Copy- Added -email is unavailable-

    Back to the top

    Powered by Savane 3.13-b921.
    Corresponding source code