- Subject: Re: slcurses wgetch() behavior
- From: Glenn Maynard <g_slang@xxxxxxxx>
- Date: Fri, 12 Oct 2001 00:17:05 -0400
On Thu, Oct 11, 2001 at 04:07:28PM -0400, John E. Davis wrote:
> >slcurses getch() appears to eat unknwon escape sequences, returning ERR.
> >This breaks a lot of keys in mutt when compiled with slang. I'd
> >recommend emulating the ncurses behavior when going through the ncurses
> >interface.
>
> I am not sure what you mean by "when going through the ncurses
> interface". S-Lang does not depend upon ncurses nor does it use any
> of its functions. It simply replies upon the existence of the
> terminfo database.
I'm talking about slcurses; the ncurses-compatibility interface for
slang. Of course, I don't expect perfect emulation for the more obscure
behavior of ncurses, but this is a pretty notable difference.
Here's a patch. It's a mild hack, but straightforward: add a function
pointer to ungetkey; when it's set (only by slcurses), unknown key
sequences are stuffed back in the buffer and SLkp_getkey doesn't flush.
> As far as binding arbitraty key sequences to keys. this can be done
> using the SLkp_define_kesym function. It associates an arbitray
> keysym to a key sequence. Then SLkp_getkey will return the keysym
> when the key is pressed (getch is a wrapper around getch).
Well, I'm compiling mutt with slang, which uses the ncurses interface.
(Doing this to get sane UTF-8.) It expects getch() to return unknown
escape sequences literally. (Of course, nobody expects emulated APIs to
be perfect, but this is a fairly significant difference.)
No comment on $TERMCAP? It caused me quite a headache; since I assumed
slang behaved like ncurses and always used terminfo, I didn't even think
to check it. It's quite useless on terminfo systems ... (Of course,
the real problem was screen's fault, not slang's.)
--
Glenn Maynard
diff -ru slang-1.4.4/src/_slang.h slang-1.4.4~/src/_slang.h
--- slang-1.4.4/src/_slang.h Tue Feb 20 21:17:35 2001
+++ slang-1.4.4~/src/_slang.h Thu Oct 11 23:48:41 2001
@@ -452,6 +452,7 @@
extern void _SLcompile (_SLang_Token_Type *);
extern void (*_SLcompile_ptr)(_SLang_Token_Type *);
+extern int (*_SLang_key_type_ungetkey)(unsigned char);
/* *** TOKENS *** */
diff -ru slang-1.4.4/src/slcurses.c slang-1.4.4~/src/slcurses.c
--- slang-1.4.4/src/slcurses.c Fri Oct 12 00:03:52 2001
+++ slang-1.4.4~/src/slcurses.c Fri Oct 12 00:02:29 2001
@@ -119,7 +119,7 @@
{
if (w->use_keypad)
{
- int ch = SLang_getkey ();
+ int ch = SLang_getkey (), ret;
if (ch == '\033')
{
if (0 == SLang_input_pending (ESCDELAY / 100))
@@ -127,7 +127,13 @@
}
else if (ch == 0xFFFF) return ERR;
SLang_ungetkey (ch);
- return SLkp_getkey ();
+
+ /* return unknown escape codes as characters, not ERR */
+ _SLang_key_type_ungetkey = SLang_ungetkey;
+ ret = SLkp_getkey ();
+ _SLang_key_type_ungetkey = NULL;
+ if(ret == SL_KEY_ERR) return SLang_getkey();
+ return ret;
}
return SLang_getkey ();
}
diff -ru slang-1.4.4/src/slkeymap.c slang-1.4.4~/src/slkeymap.c
--- slang-1.4.4/src/slkeymap.c Tue Feb 20 21:17:37 2001
+++ slang-1.4.4~/src/slkeymap.c Thu Oct 11 23:55:36 2001
@@ -333,6 +333,8 @@
return 0;
}
+int (*_SLang_key_type_ungetkey)(unsigned char) = NULL;
+
SLang_Key_Type *SLang_do_key(SLKeyMap_List_Type *kml, int (*getkey)(void))
{
register SLang_Key_Type *key, *next, *kmax;
@@ -340,6 +342,8 @@
unsigned char input_ch;
register unsigned char chup, chlow;
unsigned char key_ch = 0;
+ static unsigned char *buf = NULL;
+ static int bufsiz = 0;
SLang_Last_Key_Char = (*getkey)();
SLang_Key_TimeOut_Flag = 0;
@@ -363,8 +367,10 @@
input_ch = UPPER_CASE_KEY(input_ch);
key = kml->keymap + input_ch;
- if (key->type == 0)
+ if (key->type == 0) {
+ if(_SLang_key_type_ungetkey) _SLang_key_type_ungetkey(input_ch);
return NULL;
+ }
}
/* It appears to be a prefix character in a key sequence. */
@@ -372,6 +378,16 @@
len = 1; /* already read one character */
key = key->next; /* Now we are in the key list */
kmax = NULL; /* set to end of list */
+ if(_SLang_key_type_ungetkey) {
+ if(len > bufsiz) {
+ char *bufp;
+ bufsiz = len;
+ bufp = SLrealloc(buf, bufsiz);
+ if(bufp == NULL) return NULL;
+ buf = bufp;
+ }
+ buf[len-1] = input_ch;
+ }
while (1)
{
@@ -387,6 +403,17 @@
input_ch = (unsigned char) SLang_Last_Key_Char;
+ if(_SLang_key_type_ungetkey) {
+ if(len > bufsiz) {
+ char *bufp;
+ bufsiz = len;
+ bufp = SLrealloc(buf, bufsiz);
+ if(bufp == NULL) return NULL;
+ buf = bufp;
+ }
+ buf[len-1] = input_ch;
+ }
+
chup = UPPER_CASE_KEY(input_ch); chlow = LOWER_CASE_KEY(input_ch);
while (key != kmax)
@@ -449,6 +476,12 @@
}
kmax = next;
}
+
+ if(_SLang_key_type_ungetkey) {
+ /* unget all but the first character and return the first */
+ while(len)
+ _SLang_key_type_ungetkey(buf[--len]);
+ }
return NULL;
}
diff -ru slang-1.4.4/src/slkeypad.c slang-1.4.4~/src/slkeypad.c
--- slang-1.4.4/src/slkeypad.c Tue Feb 20 21:17:37 2001
+++ slang-1.4.4~/src/slkeypad.c Thu Oct 11 23:58:44 2001
@@ -122,7 +122,9 @@
key = SLang_do_key (Keymap_List, (int (*)(void)) SLang_getkey);
if ((key == NULL) || (key->type != SLKEY_F_KEYSYM))
{
- SLang_flush_input ();
+ /* don't flush if SLang_do_key is in unget mode */
+ if(_SLang_key_type_ungetkey == NULL)
+ SLang_flush_input ();
return SL_KEY_ERR;
}
[2001 date index]
[2001 thread index]
[Thread Prev] [Thread Next]
[Date Prev] [Date Next]