From: "Mark E." To: djgpp-workers AT delorie DOT com Date: Mon, 23 Jul 2001 20:13:04 -0400 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT 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)