From: "Mark E." To: djgpp-workers AT delorie DOT com Date: Wed, 25 Jul 2001 13:11:10 -0400 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT 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 #include #include + #include #include #include #include *************** *** 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)