1
diff -ruN newt-0.51.6-old/entry.c newt-0.51.6/entry.c
2
--- newt-0.51.6-old/entry.c 2003-02-05 07:11:35.000000000 +0000
3
+++ newt-0.51.6/entry.c 2004-04-25 19:43:57.000000000 +0100
8
- if ((key >= 0x20 && key <= 0x7e) || (key >= 0xa0 && key <= 0xff)) {
9
+ if ((key >= 0x20 && key <= 0x7e) || (key >= 0x80 && key <= 0xff)) {
10
if (!(en->flags & NEWT_FLAG_SCROLL) && en->bufUsed >= co->width) {
13
diff -ruN newt-0.51.6-old/newt.c newt-0.51.6/newt.c
14
--- newt-0.51.6-old/newt.c 2004-04-25 18:02:53.000000000 +0100
15
+++ newt-0.51.6/newt.c 2004-04-25 19:43:57.000000000 +0100
19
static const struct keymap keymap[] = {
20
- { "\033OA", NEWT_KEY_UP, "kh" },
21
- { "\033[A", NEWT_KEY_UP, "ku" },
22
+ { "\033OA", NEWT_KEY_UP, "ku" },
23
+ { "\020", NEWT_KEY_UP, NULL }, /* emacs ^P */
24
{ "\033OB", NEWT_KEY_DOWN, "kd" },
25
- { "\033[B", NEWT_KEY_DOWN, "kd" },
26
- { "\033[C", NEWT_KEY_RIGHT, "kr" },
27
+ { "\016", NEWT_KEY_DOWN, NULL }, /* emacs ^N */
28
{ "\033OC", NEWT_KEY_RIGHT, "kr" },
29
- { "\033[D", NEWT_KEY_LEFT, "kl" },
30
+ { "\006", NEWT_KEY_RIGHT, NULL }, /* emacs ^F */
31
{ "\033OD", NEWT_KEY_LEFT, "kl" },
32
- { "\033[H", NEWT_KEY_HOME, "kh" },
33
- { "\033[1~", NEWT_KEY_HOME, "kh" },
34
+ { "\002", NEWT_KEY_LEFT, NULL }, /* emacs ^B */
35
+ { "\033OH", NEWT_KEY_HOME, "kh" },
36
+ { "\033[1~", NEWT_KEY_HOME, NULL },
37
+ { "\001", NEWT_KEY_HOME, NULL }, /* emacs ^A */
38
{ "\033Ow", NEWT_KEY_END, "kH" },
39
- { "\033[4~", NEWT_KEY_END, "kH" },
40
+ { "\033[4~", NEWT_KEY_END, "@7" },
41
+ { "\005", NEWT_KEY_END, NULL }, /* emacs ^E */
43
- { "\033[3~", NEWT_KEY_DELETE, "kl" },
44
- { "\033[2~", NEWT_KEY_INSERT, NULL },
46
- { "\033\t", NEWT_KEY_UNTAB, NULL },
48
- { "\033[5~", NEWT_KEY_PGUP, NULL },
49
- { "\033[6~", NEWT_KEY_PGDN, NULL },
50
- { "\033V", NEWT_KEY_PGUP, "kH" },
51
- { "\033v", NEWT_KEY_PGUP, "kH" },
52
+ { "\033[3~", NEWT_KEY_DELETE, "kD" },
53
+ { "\004", NEWT_KEY_DELETE, NULL }, /* emacs ^D */
54
+ { "\033[2~", NEWT_KEY_INSERT, "kI" },
56
+ { "\033\t", NEWT_KEY_UNTAB, "kB" },
58
+ { "\033[5~", NEWT_KEY_PGUP, "kP" },
59
+ { "\033[6~", NEWT_KEY_PGDN, "kN" },
60
+ { "\033V", NEWT_KEY_PGUP, NULL },
61
+ { "\033v", NEWT_KEY_PGUP, NULL },
62
+ { "\026", NEWT_KEY_PGDN, NULL },
64
{ "\033[[A", NEWT_KEY_F1, NULL },
65
{ "\033[[B", NEWT_KEY_F2, NULL },
67
{ "\033OR", NEWT_KEY_F3, NULL },
68
{ "\033OS", NEWT_KEY_F4, NULL },
70
- { "\033[11~", NEWT_KEY_F1, NULL },
71
- { "\033[12~", NEWT_KEY_F2, NULL },
72
- { "\033[13~", NEWT_KEY_F3, NULL },
73
- { "\033[14~", NEWT_KEY_F4, NULL },
74
- { "\033[15~", NEWT_KEY_F5, NULL },
75
- { "\033[17~", NEWT_KEY_F6, NULL },
76
- { "\033[18~", NEWT_KEY_F7, NULL },
77
- { "\033[19~", NEWT_KEY_F8, NULL },
78
- { "\033[20~", NEWT_KEY_F9, NULL },
79
- { "\033[21~", NEWT_KEY_F10, NULL },
80
- { "\033[23~", NEWT_KEY_F11, NULL },
81
- { "\033[24~", NEWT_KEY_F12, NULL },
82
- { "\033", NEWT_KEY_ESCAPE, NULL },
83
+ { "\033[11~", NEWT_KEY_F1, "k1" },
84
+ { "\033[12~", NEWT_KEY_F2, "k2" },
85
+ { "\033[13~", NEWT_KEY_F3, "k3" },
86
+ { "\033[14~", NEWT_KEY_F4, "k4" },
87
+ { "\033[15~", NEWT_KEY_F5, "k5" },
88
+ { "\033[17~", NEWT_KEY_F6, "k6" },
89
+ { "\033[18~", NEWT_KEY_F7, "k7" },
90
+ { "\033[19~", NEWT_KEY_F8, "k8" },
91
+ { "\033[20~", NEWT_KEY_F9, "k9" },
92
+ { "\033[21~", NEWT_KEY_F10, "k;" },
93
+ { "\033[23~", NEWT_KEY_F11, "F1" },
94
+ { "\033[24~", NEWT_KEY_F12, "F2" },
95
+ { "\033", NEWT_KEY_ESCAPE, "@2" },
96
+ { "\033", NEWT_KEY_ESCAPE, "@9" },
98
+ { "\177", NEWT_KEY_BKSPC, NULL },
99
+ { "\010", NEWT_KEY_BKSPC, NULL },
101
{ 0 }, /* LEAVE this one */
103
-static char keyPrefix = '\033';
104
+static void initKeymap();
106
static const char ident[] = // ident friendly
107
"$Version: Newt windowing library v" VERSION " $"
110
newtSetColors(newtDefaultColorPalette);
115
/*memset(&sa, 0, sizeof(sa));
116
sa.sa_handler = handleSigwinch;
117
@@ -360,10 +368,142 @@
118
colors.selListboxBg);
121
+/* Keymap handling - rewritten by Henning Makholm <henning@makholm.net>,
125
+struct kmap_trie_entry {
126
+ char c ; /* character got from terminal */
127
+ int code; /* newt key, or 0 if c does not make a complete sequence */
128
+ struct kmap_trie_entry *contseq; /* sub-trie for character following c */
129
+ struct kmap_trie_entry *next; /* try this if char received != c */
131
+/* Here are some static entries that will help in handling esc O foo and
132
+ esc [ foo as variants of each other: */
133
+static struct kmap_trie_entry
134
+ kmap_trie_escO = { 'O', 0, 0, 0 },
135
+ kmap_trie_escBrack = { '[', 0, 0, &kmap_trie_escO },
136
+ kmap_trie_root = { '\033', 0, &kmap_trie_escBrack, 0 };
137
+static int keyreader_buf_len = 10 ;
138
+static unsigned char default_keyreader_buf[10];
139
+static unsigned char *keyreader_buf = default_keyreader_buf;
141
+#if 0 /* for testing of the keymap manipulation code */
142
+static void dumpkeys_recursive(struct kmap_trie_entry *curr, int i, FILE *f) {
144
+ char seen[256]={0};
145
+ if( curr && i >= keyreader_buf_len ) {
146
+ fprintf(f,"ARGH! Too long sequence!\n") ;
149
+ for(;curr;curr=curr->next) {
150
+ keyreader_buf[i] = curr->c ;
151
+ ps = seen[(unsigned char)curr->c]++ ;
152
+ if( ps || curr->code || (!curr->code && !curr->contseq) ) {
153
+ for(j=0;j<=i;j++) {
154
+ if( keyreader_buf[j] > 32 && keyreader_buf[j]<127 &&
155
+ keyreader_buf[j] != '^' && keyreader_buf[j] != '\\' )
156
+ fprintf(f,"%c",keyreader_buf[j]);
157
+ else if( keyreader_buf[j] > 0 && keyreader_buf[j]<=32 )
158
+ fprintf(f,"^%c",keyreader_buf[j] + 0x40);
160
+ fprintf(f,"\\%03o",
161
+ (unsigned)(unsigned char)keyreader_buf[j]);
164
+ fprintf(f,": 0x%X\n",curr->code);
166
+ fprintf(f,": (just keymap)\n");
168
+ dumpkeys_recursive(curr->contseq,i+1,f);
171
+static void dump_keymap(void) {
172
+ FILE *f = fopen("newt.keydump","wt");
174
+ dumpkeys_recursive(&kmap_trie_root,0,f);
180
+/* newtBindKey may overwrite a binding that is there already */
181
+static void newtBindKey(char *keyseq, int meaning) {
182
+ struct kmap_trie_entry *root = &kmap_trie_root ;
183
+ struct kmap_trie_entry **curptr = &root ;
185
+ /* Try to make sure the common matching buffer is long enough. */
186
+ if( strlen(keyseq) > keyreader_buf_len ) {
187
+ int i = strlen(keyseq)+10;
188
+ unsigned char *newbuf = malloc(i);
190
+ if (keyreader_buf != default_keyreader_buf)
191
+ free(keyreader_buf);
192
+ keyreader_buf = newbuf;
193
+ keyreader_buf_len = i;
197
+ if (*keyseq == 0) return; /* binding the empty sequence is meaningless */
200
+ while ((*curptr) && (*curptr)->c != *keyseq)
201
+ curptr = &(*curptr)->next;
202
+ if ((*curptr)==0) {
203
+ struct kmap_trie_entry* fresh
204
+ = calloc(strlen(keyseq),sizeof(struct kmap_trie_entry));
205
+ if (fresh == 0) return; /* despair! */
207
+ while (keyseq[1]) {
208
+ fresh->contseq = fresh+1;
209
+ (fresh++)->c = *(keyseq++);
211
+ fresh->c = *keyseq;
212
+ fresh->code = meaning;
215
+ if (keyseq[1]==0) {
216
+ (*curptr)->code = meaning;
219
+ curptr = &(*curptr)->contseq;
225
+/* This function recursively inserts all entries in the "to" trie into
226
+ corresponding positions in the "from" trie, except positions that
227
+ are already defined in the "from" trie. */
228
+static void kmap_trie_fallback(struct kmap_trie_entry *to,
229
+ struct kmap_trie_entry **from) {
234
+ for (;to!=NULL;to=to->next) {
235
+ struct kmap_trie_entry **fromcopy = from ;
236
+ while ((*fromcopy) && (*fromcopy)->c != to->c)
237
+ fromcopy = &(*fromcopy)->next ;
239
+ if ((*fromcopy)->code == 0)
240
+ (*fromcopy)->code = to->code;
241
+ kmap_trie_fallback(to->contseq, &(*fromcopy)->contseq);
243
+ *fromcopy = malloc(sizeof(struct kmap_trie_entry));
246
+ (*fromcopy)->next = 0 ;
252
int newtGetKey(void) {
254
- char buf[10], * chptr = buf;
255
- const struct keymap * curr;
256
+ unsigned char *chptr = keyreader_buf, *lastmatch;
258
+ struct kmap_trie_entry *curr = &kmap_trie_root;
262
@@ -387,66 +527,35 @@
263
suspendCallback(suspendCallbackData);
264
} while (key == NEWT_KEY_SUSPEND);
269
- return NEWT_KEY_PGUP;
272
- return NEWT_KEY_PGDN;
274
- return NEWT_KEY_BKSPC;
276
- return NEWT_KEY_BKSPC;
279
- return NEWT_KEY_BKSPC;
282
- if (key != keyPrefix) return key;
285
- memset(buf, 0, sizeof(buf));
288
- while (SLang_input_pending(5)) {
290
- if (key == keyPrefix) {
291
- /* he hit unknown keys too many times -- start over */
292
- memset(buf, 0, sizeof(buf));
298
- /* this search should use bsearch(), but when we only look through
299
- a list of 20 (or so) keymappings, it's probably faster just to
300
- do a inline linear search */
302
- for (curr = keymap; curr->code; curr++) {
304
- if (!strcmp(curr->str, buf))
310
- for (curr = keymap; curr->code; curr++) {
312
- if (!strcmp(curr->str, buf))
317
- /* Looks like we were a bit overzealous in reading characters. Return
318
- just the first character, and put everything else back in the buffer
322
- while (chptr > buf)
323
- SLang_ungetkey(*chptr--);
326
+ /* Read more characters, matching against the trie as we go */
327
+ lastcode = *chptr = key;
328
+ lastmatch = chptr ;
330
+ while (curr->c != key) {
331
+ curr = curr->next ;
332
+ if (curr==NULL) goto break2levels;
335
+ lastcode = curr->code;
338
+ curr = curr->contseq;
339
+ if (curr==NULL) break;
341
+ if (SLang_input_pending(5) <= 0)
344
+ if (chptr==keyreader_buf+keyreader_buf_len-1) break;
345
+ *++chptr = key = getkey();
349
+ /* The last time the trie matched was at position lastmatch. Back
350
+ * up if we have read too many characters. */
351
+ while (chptr > lastmatch)
352
+ SLang_ungetkey(*chptr--);
358
@@ -664,26 +773,38 @@
359
SLsmg_fill_region(top, left, height, width, ' ');
363
-/* This doesn't seem to work quite right. I don't know why not, but when
364
- I rsh from an rxvt into a box and run this code, the machine returns
365
- console key's (\033[B) rather then xterm ones (\033OB). */
366
static void initKeymap(void) {
367
- struct keymap * curr;
368
+ const struct keymap * curr;
370
+ /* First bind built-in default bindings. They may be shadowed by
371
+ the termcap entries that get bound later. */
372
for (curr = keymap; curr->code; curr++) {
374
- curr->str = SLtt_tgetstr(curr->tc);
376
+ newtBindKey(curr->str,curr->code);
379
- /* Newt's keymap handling is a bit broken. It assumes that any extended
380
- keystrokes begin with ESC. If you're using a homebrek terminal you
381
- will probably need to fix this, or just yell at me and I'll be so
382
- ashamed of myself for doing it this way I'll fix it */
383
+ /* Then bind strings from termcap entries */
384
+ for (curr = keymap; curr->code; curr++) {
386
+ char *pc = SLtt_tgetstr(curr->tc);
388
+ newtBindKey(pc,curr->code);
393
- keyPrefix = 0x1b; /* ESC */
394
+ /* Finally, invent lowest-priority keybindings that correspond to
395
+ searching for esc-O-foo if esc-[-foo was not found and vice
396
+ versa. That is needed because of strong confusion among
397
+ different emulators of VTxxx terminals; some terminfo/termcap
398
+ descriptions are apparently written by people who were not
399
+ aware of the differences between "applicataion" and "terminal"
400
+ keypad modes. Or perhaps they were, but tried to make their
401
+ description work with a program that puts the keyboard in the
402
+ wrong emulation mode. In short, one needs this: */
403
+ kmap_trie_fallback(kmap_trie_escO.contseq, &kmap_trie_escBrack.contseq);
404
+ kmap_trie_fallback(kmap_trie_escBrack.contseq, &kmap_trie_escO.contseq);
409
* @brief Delay for a specified number of usecs