slang-users mailing list

[2001 Date Index] [2001 Thread Index] [Other years]
[Thread Prev] [Thread Next]      [Date Prev] [Date Next]

Re: slcurses wgetch() behavior


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]