Mail Archives: djgpp-workers/2001/07/25/13:11:10
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 -