delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/07/25/13:11:10

From: "Mark E." <snowball3 AT bigfoot DOT com>
To: djgpp-workers AT delorie DOT com
Date: Wed, 25 Jul 2001 13:11:10 -0400
MIME-Version: 1.0
Subject: termios extended key support
Message-ID: <3B5EC56E.16406.266C9C@localhost>
X-mailer: Pegasus Mail for Win32 (v3.12c)
Reply-To: djgpp-workers AT delorie DOT com

This is my patch to support extended keys in termios. Any problems with it?

Index: tminit.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/termios/tminit.c,v
retrieving revision 1.9
diff -c -p -r1.9 tminit.c
*** tminit.c	2001/03/31 10:33:42	1.9
--- tminit.c	2001/07/25 17:09:14
***************
*** 1,3 ****
--- 1,4 ----
+ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
***************
*** 10,15 ****
--- 11,17 ----
  #include <libc/stubs.h>
  #include <fcntl.h>
  #include <go32.h>
+ #include <pc.h>
  #include <io.h>
  #include <limits.h>
  #include <signal.h>
***************
*** 28,33 ****
--- 30,39 ----
  
  #define CPMEOF 0x1a /* Ctrl+Z */
  
+ #define SENSE_NO_KEY	0
+ #define SENSE_REG_KEY	1
+ #define SENSE_EXT_KEY	2
+ 
  /* tty buffers */
  unsigned char __libc_tty_queue_buffer[_TTY_QUEUE_SIZE];
  struct tty __libc_tty_internal = TTYDEFAULT;
*************** struct tty_editline __libc_tty_editline 
*** 37,42 ****
--- 43,55 ----
  /* global only in the termios functions */
  int __libc_termios_hook_common_count = -1;
  
+ /* static data */
+ static unsigned ah_key_sense;
+ static unsigned ah_key_get;
+ static unsigned ah_ctrl_sense;
+ 
+ static const unsigned char *ext_key_string;
+ 
  /* static functions */
  static void __libc_termios_fflushall (void);
  static ssize_t __libc_termios_read (int handle, void *buffer, size_t count, ssize_t *rv);
*************** __libc_termios_init (void)
*** 87,92 ****
--- 100,118 ----
        /* flush all buffered streams */
        __libc_termios_fflushall ();
  
+       if (_farpeekb (_dos_ds, 0x496) & 0x10)
+       {
+         ah_key_get = 0x10;
+         ah_key_sense = 0x11;
+         ah_ctrl_sense = 0x12;
+       }
+       else
+       {
+         ah_key_get = 0x00;
+         ah_key_sense = 0x01;
+         ah_ctrl_sense = 0x02;
+       }
+ 
        /* set special hooks */
        __libc_read_termios_hook = __libc_termios_read;
        __libc_write_termios_hook = __libc_termios_write;
*************** __libc_termios_init (void)
*** 102,117 ****
  #define _REG_STATUS_ZF 0x40
  
  static inline int
! __direct_keysense (void)
  {
    __dpmi_regs r;
  
!   r.h.ah = 0x01;
!   __dpmi_int (0x16, &r);
    if (r.x.flags & _REG_STATUS_ZF)
!     return 0;
  
!   return 1;
  }
  
  static inline unsigned char
--- 128,145 ----
  #define _REG_STATUS_ZF 0x40
  
  static inline int
! __direct_keysense(void)
  {
    __dpmi_regs r;
+   char is_ext_key;
  
!   r.h.ah = ah_key_sense;
!   __dpmi_int(0x16, &r);
    if (r.x.flags & _REG_STATUS_ZF)
!     return SENSE_NO_KEY;
  
!   is_ext_key = (r.h.al == 0x00 || r.h.al == 0xe0);
!   return is_ext_key ? SENSE_EXT_KEY : SENSE_REG_KEY;
  }
  
  static inline unsigned char
*************** __direct_keyinput (void)
*** 119,130 ****
  {
    __dpmi_regs r;
  
!   r.h.ah = 0x00;
    __dpmi_int (0x16, &r);
  
    return r.h.al;
  }
  
  #define _KEY_INS  0x80
  #define _KEY_CAPS 0x40
  #define _KEY_NUM  0x20
--- 147,171 ----
  {
    __dpmi_regs r;
  
!   r.h.ah = ah_key_get;
    __dpmi_int (0x16, &r);
  
    return r.h.al;
  }
  
+ /* Get an extended key and return its encoding.  */
+ static inline
+ const unsigned char *
+ set_ext_key_string(void)
+ {
+   __dpmi_regs r;
+ 
+   r.h.ah = ah_key_get;
+   __dpmi_int(0x16, &r);
+ 
+   return (ext_key_string = __get_extended_key_string((int)r.h.ah));
+ }
+ 
  #define _KEY_INS  0x80
  #define _KEY_CAPS 0x40
  #define _KEY_NUM  0x20
*************** __libc_termios_read_raw_tty (int handle,
*** 331,336 ****
--- 372,378 ----
    unsigned char *wp;
    unsigned char ch;
    ssize_t n;
+   int sense;
  
    n = count;
    wp = buffer;
*************** __libc_termios_read_raw_tty (int handle,
*** 340,364 ****
      __libc_termios_clear_queue ();
  
    /* block until getting inputs */
!   while (! __direct_keysense ())
      __dpmi_yield ();
  
!   while (--n >= 0)
      {
        /* exhaust inputs ? */
!       if (! __direct_keysense ())
  	break;
  
!       /* realy get */
!       ch = __direct_keyinput ();
! 
!       /* replace CTRL+SPACE with 0x00 */
!       if (ch == ' ' && __direct_ctrlsense ())
! 	ch = '\0';
  
        /* copy a character into buffer and echo */
        *wp++ = ch;
        __libc_termios_maybe_echo (ch);
      }
  
    return (ssize_t) (wp - (unsigned char *) buffer);
--- 382,434 ----
      __libc_termios_clear_queue ();
  
    /* block until getting inputs */
!   while (ext_key_string == NULL && __direct_keysense() == SENSE_NO_KEY)
      __dpmi_yield ();
  
!   while (n >= 0)
      {
        /* exhaust inputs ? */
!       if (ext_key_string == NULL
!           && (sense = __direct_keysense()) == SENSE_NO_KEY)
  	break;
  
!       if (ext_key_string)
!       {
!         ch = *ext_key_string;
!         ++ext_key_string;
!         if (*ext_key_string == '\0')
!           ext_key_string = NULL;
!       }
!       else if (sense == SENSE_REG_KEY)
!       {
!         ch = __direct_keyinput();
! 
!         /* replace CTRL+SPACE with 0x00 */
!         if (ch == ' ' && __direct_ctrlsense ())
! 	  ch = '\0';
!       }
!       else
!       {
!         if (set_ext_key_string() == NULL)
!         {
!           /* This extended key has no encoding.  If there are no keys
!              already stored in the buffer, wait for another key to ensure
!              at least one character is put into the buffer.  */
!           if (wp == (unsigned char *)buffer)
!           {
!             while (__direct_keysense() == SENSE_NO_KEY)
!               __dpmi_yield();
!           }
!            continue;
!         }
!         ch = *ext_key_string;
!         ++ext_key_string;
!       }
  
        /* copy a character into buffer and echo */
        *wp++ = ch;
        __libc_termios_maybe_echo (ch);
+       --n;
      }
  
    return (ssize_t) (wp - (unsigned char *) buffer);
*************** static void
*** 864,874 ****
  __libc_termios_fill_queue (void)
  {
    unsigned char ch;
  
    while (1)
      {
        /* exhaust inputs ? */
!       if (! __direct_keysense ())
  	{
  	  if (__libc_tty_p->t_lflag & ICANON)
  	    {
--- 934,946 ----
  __libc_termios_fill_queue (void)
  {
    unsigned char ch;
+   int sense;
  
    while (1)
      {
        /* exhaust inputs ? */
!       if (ext_key_string == NULL
!           && (sense = __direct_keysense()) == SENSE_NO_KEY)
  	{
  	  if (__libc_tty_p->t_lflag & ICANON)
  	    {
*************** __libc_termios_fill_queue (void)
*** 879,890 ****
  	  return;
  	}
  
!       /* realy get */
!       ch = __direct_keyinput ();
! 
!       /* replace CTRL+SPACE with 0x00 */
!       if (ch == ' ' && __direct_ctrlsense ())
! 	ch = '\0';
  
        /* input process if need */
        if (! (__libc_tty_p->t_status & _TS_LNCH) || ch != (unsigned char) _POSIX_VDISABLE)
--- 951,979 ----
  	  return;
  	}
  
!       /* really get */
!       if (ext_key_string)
!       {
!         ch = *ext_key_string;
!         ++ext_key_string;
!         if (*ext_key_string == '\0')
!           ext_key_string = NULL;
!       }
!       else  if (sense == SENSE_REG_KEY)
!       {
!         ch = __direct_keyinput();
! 
!         /* replace CTRL+SPACE with 0x00 */
!         if (ch == ' ' && __direct_ctrlsense())
! 	      ch = '\0';
!       }
!       else
!       {
!         if (set_ext_key_string() == NULL)
!           continue;
!         ch = *ext_key_string;
!         ++ext_key_string;
!       }
  
        /* input process if need */
        if (! (__libc_tty_p->t_status & _TS_LNCH) || ch != (unsigned char) 
_POSIX_VDISABLE)

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019