www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/07/23/20:13:24

From: "Mark E." <snowball3 AT bigfoot DOT com>
To: djgpp-workers AT delorie DOT com
Date: Mon, 23 Jul 2001 20:13:04 -0400
MIME-Version: 1.0
Subject: extended keys support
Message-ID: <3B5C8550.21789.243885@localhost>
X-mailer: Pegasus Mail for Win32 (v3.12c)
Reply-To: djgpp-workers AT delorie DOT com

I got to fiddline around and extended key  turned out to much easier task 
than I thought it was going to be. I haven't added all encodings because 
perhaps y'all will some different ones for the ones with the private 
encodings (the ones ending with ~ ). The cursor keys are from ecma-48, the 
insert, delete definitions are cribbed from cygwin, and the function keys 
encodings are partially based on cygwin.

*** /cvs/djgpp/src/libc/posix/termios/tminit.c	Fri Apr  6 13:17:30 2001
--- tminit.c	Mon Jul 23 20:02:34 2001
***************
*** 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 */
***************
*** 28,33 ****
--- 29,38 ----
  
  #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 ****
--- 42,53 ----
  /* 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 *enh_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 ****
--- 98,116 ----
        /* 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
--- 126,143 ----
  #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
--- 145,269 ----
  {
    __dpmi_regs r;
  
!   r.h.ah = ah_key_get;
    __dpmi_int (0x16, &r);
  
    return r.h.al;
  }
  
+ static const unsigned char *
+ ext_key_string_table[] =
+ {
+   "\e[[A",  /* 0x3B: F1 */
+   "\e[[B",  /* 0x3C: F2 */
+   "\e[[C",  /* 0x3D: F3 */
+   "\e[[D",  /* 0x3E: F4 */
+   "\e[[E",  /* 0x3F: F5 */
+   "\e[17",  /* 0x40: F6 */
+   "\e[18~", /* 0x41: F7 */
+   "\e[19~", /* 0x42: F8 */
+   "\e[20~", /* 0x43: F9 */
+   "\e[21~", /* 0x44: F10 */
+   0,        /* 0x45 */
+   0,        /* 0x46 */
+   "\e[1~",  /* 0x47: Home */
+   "\e[A",   /* 0x48: Up Arrow */
+   "\e[5~",  /* 0x49: Page Up */
+   0,        /* 0x4a */
+   "\e[D",   /* 0x4b: Left Arrow */
+   0,        /* 0x4c */
+   "\e[C",   /* 0x4d: Right Arrow */
+   0,        /* 0x4e */
+   "\e[4~",  /* 0x4f: End */
+   "\e[B",   /* 0x50: Down Arrow */
+   "\e[6~",  /* 0x51: Page Down */
+   "\e[2~",  /* 0x52: Insert */
+   "\e[3~",  /* 0x53: Delete */
+   "\e[25~", /* 0x54: Shift-F1 */
+   "\e[26~", /* 0x55: Shift-F2 */
+   "\e[27~", /* 0x56: Shift-F3 */
+   "\e[28~", /* 0x57: Shift-F4 */
+   "\e[29~", /* 0x58: Shift-F5 */
+   "\e[30~", /* 0x59: Shift-F6 */
+   "\e[31~", /* 0x5a: Shift-F7 */
+   "\e[32~", /* 0x5b: Shift-F8 */
+   "\e[33~", /* 0x5c: Shift-F9 */
+   "\e[34~", /* 0x5d: Shift-F10 */
+   "\e[37~", /* 0x5e: Ctrl-F1 */
+   "\e[37~", /* 0x5f: Ctrl-F2 */
+   0,        /* 0x60 */
+   0,        /* 0x61 */
+   0,        /* 0x62 */
+   0,        /* 0x63 */
+   0,        /* 0x64 */
+   0,        /* 0x65 */
+   0,        /* 0x66 */
+   0,        /* 0x67 */
+   0,        /* 0x68 */
+   0,        /* 0x69 */
+   0,        /* 0x6a */
+   0,        /* 0x6b */
+   0,        /* 0x6c */
+   0,        /* 0x6d */
+   0,        /* 0x6e */
+   0,        /* 0x6f */
+   0,        /* 0x70 */
+   0,        /* 0x71 */
+   0,        /* 0x72 */
+   0,        /* 0x73 */
+   0,        /* 0x74 */
+   0,        /* 0x75 */
+   0,        /* 0x76 */
+   0,        /* 0x77 */
+   0,        /* 0x78 */
+   0,        /* 0x79 */
+   0,        /* 0x7a */
+   0,        /* 0x7b */
+   0,        /* 0x7c */
+   0,        /* 0x7d */
+   0,        /* 0x7e */
+   0,        /* 0x7f */
+   0,        /* 0x80 */
+   0,        /* 0x81 */
+   0,        /* 0x82 */
+   0,        /* 0x83 */
+   0,        /* 0x84 */
+   "\e23~",  /* F11: 0x85 */
+   "\e24~",  /* F12: 0x86 */
+   0,        /* 0x87 */
+   0,        /* 0x88 */
+   "\e[35~", /* 0x89: Shift-F11 */
+   "\e[36~", /* 0x8a: Shift-F12 */
+   0,        /* 0x8a */
+   0,        /* 0x8b */
+   0,        /* 0x8c */
+   0,        /* 0x8d */
+   0,        /* 0x8e */
+   0,        /* 0x8f */
+ };
+ 
+ #define MIN_EXT_SCAN_CODE 0x3b
+ 
+ static const unsigned char *
+ get_extended_key_string(void)
+ {
+   __dpmi_regs r;
+   unsigned table_index;
+ 
+   r.h.ah = ah_key_get;
+   __dpmi_int (0x16, &r);
+ 
+   /* Shouldn't happen. But just in case.  */
+   if (r.h.ah < MIN_EXT_SCAN_CODE)
+     return NULL;
+ 
+   table_index = r.h.ah - MIN_EXT_SCAN_CODE;
+   if (table_index > (sizeof(ext_key_string_table) / sizeof(ext_key_string_table[0])))
+     return NULL;
+ 
+   return ext_key_string_table[table_index];
+ }
+ 
  #define _KEY_INS  0x80
  #define _KEY_CAPS 0x40
  #define _KEY_NUM  0x20
*************** __libc_termios_read_raw_tty (int handle,
*** 331,336 ****
--- 470,476 ----
    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);
--- 480,523 ----
      __libc_termios_clear_queue ();
  
    /* block until getting inputs */
!   while (enh_key_string == 0 && (sense = __direct_keysense()) == SENSE_NO_KEY)
      __dpmi_yield ();
  
    while (--n >= 0)
      {
        /* exhaust inputs ? */
!       if (enh_key_string == 0 && sense == SENSE_NO_KEY)
  	break;
  
!       if (enh_key_string)
!       {
!         ch = *enh_key_string;
!         ++enh_key_string;
!         if (*enh_key_string == '\0')
!           enh_key_string = 0;
!       }
!       else if (sense == SENSE_REG_KEY)
!       {
!         ch = __direct_keyinput();
! 
!         /* replace CTRL+SPACE with 0x00 */
!         if (ch == ' ' && __direct_ctrlsense ())
! 	  ch = '\0';
!       }
!       else
!       {
!         enh_key_string = get_extended_key_string();
!         if (enh_key_string == NULL)
!           continue;
!         ch = *enh_key_string;
!         ++enh_key_string;
!       }
  
        /* copy a character into buffer and echo */
        *wp++ = ch;
        __libc_termios_maybe_echo (ch);
+ 
+       sense = __direct_keysense();
      }
  
    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)
  	    {
--- 1023,1034 ----
  __libc_termios_fill_queue (void)
  {
    unsigned char ch;
+   int sense;
  
    while (1)
      {
        /* exhaust inputs ? */
!       if (enh_key_string == 0 && (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)
--- 1039,1068 ----
  	  return;
  	}
  
!       /* really get */
!       if (enh_key_string)
!       {
!         ch = *enh_key_string;
!         ++enh_key_string;
!         if (*enh_key_string == '\0')
!           enh_key_string = 0;
!       }
!       else  if (sense == SENSE_REG_KEY)
!       {
!         ch = __direct_keyinput();
! 
!         /* replace CTRL+SPACE with 0x00 */
!         if (ch == ' ' && __direct_ctrlsense())
! 	      ch = '\0';
!       }
!       else
!       {
!         enh_key_string = get_extended_key_string();
!         if (enh_key_string == NULL)
!           continue;
!         ch = *enh_key_string;
!         ++enh_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