From: "Mark E." To: djgpp-workers AT delorie DOT com Date: Sun, 10 Jun 2001 17:01:29 -0400 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: Re: old archived termios submission Message-ID: <3B23A7E9.663.2BC22F@localhost> In-reply-to: <200106101443.KAA11964@envy.delorie.com> References: <3B22C210 DOT 12214 DOT 6077D1 AT localhost> (snowball3 AT bigfoot DOT com) X-mailer: Pegasus Mail for Win32 (v3.12c) Reply-To: djgpp-workers AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp-workers AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk > Yes, I think it does. > > Perhaps someone could re-review the code and get it into cvs? With the OK, I downloaded the article and ran it through a base64 decoder, then unziped its contents to get at the creamy nuget center errrrr get at the patch. The enhanced keyboard support looks very much like that in Bash's version of tminit.c. For one, it has the second queue that I don't care for. The patch is pasted below so nobody else has to go to the same trouble: *** include/libc/ttyprvt.h-orig Sun Sep 15 15:56:30 1996 --- include/libc/ttyprvt.h Sat Dec 28 13:48:16 1996 *************** *** 127,132 **** --- 127,135 ---- /* functions */ void __libc_termios_init (void); + int __libc_termios_disable_function_and_arrow_keys (void); + int __libc_termios_enable_function_and_arrow_keys (void); + void __libc_termios_check_signals (void); #endif /* !_POSIX_SOURCE */ #endif /* !__STRICT_ANSI__ */ *** src/libc/posix/termios/tminit.txh-orig Sun Sep 15 16:02:18 1996 --- src/libc/posix/termios/tminit.txh Mon Dec 30 21:39:42 1996 *************** *** 1,3 **** --- 1,4 ---- + @c ---------------------------------------------------------------------- @node __libc_termios_init, termios @subheading Syntax *************** *** 14,17 **** --- 15,59 ---- the emulation is resolved by only internal(static) parameters. Note that this function is called by tcXXX function automatically. + @c ---------------------------------------------------------------------- + @node __libc_termios_disable_function_and_arrow_keys, termios + @subheading Syntax + + @example + #include + + int __libc_termios_disable_function_and_arrow_keys (void); + @end example + + @subheading Description + + This function disables function keys and arrow keys translation in + the termios emulation. (by default) + @xref{__libc_termios_enable_function_and_arrow_keys}. + + @subheading Return Value + + Returns nonzero if the translation had been enabled before this call, + zero if they were already disabled. + + @c ---------------------------------------------------------------------- + @node __libc_termios_enable_function_and_arrow_keys, termios + @subheading Syntax + + @example + #include + + int __libc_termios_enable_function_and_arrow_keys (void); + @end example + + @subheading Description + + This function enables function keys and arrow keys translation in + the termios emulation. + @xref{__libc_termios_enable_function_and_arrow_keys}. + + @subheading Return Value + + Returns nonzero if the translation was already enabled, zero if they + had been disabled before this call. *** src/libc/posix/termios/tcsetatr.c-orig Sun Sep 15 16:02:22 1996 --- src/libc/posix/termios/tcsetatr.c Mon Dec 30 20:48:32 1996 *************** *** 48,59 **** case TCSANOW: case TCSAFLUSH: case TCSADRAIN: /* enable or disable ^C */ if ((__libc_tty_p->t_lflag & ISIG) && ! (termiosp->c_iflag & IGNBRK) && (termiosp->c_iflag & BRKINT) && (termiosp->c_cc[VINTR] == 0x03)) ! __djgpp_set_ctrl_c (1); else __djgpp_set_ctrl_c (0); /* copy the structure */ __libc_tty_p->t_termios = *termiosp; --- 48,61 ---- case TCSANOW: case TCSAFLUSH: case TCSADRAIN: + #if 0 /* enable or disable ^C */ if ((__libc_tty_p->t_lflag & ISIG) && ! (termiosp->c_iflag & IGNBRK) && (termiosp->c_iflag & BRKINT) && (termiosp->c_cc[VINTR] == 0x03)) ! __djgpp_set_ctrl_c (0); /* want to enable but... */ else __djgpp_set_ctrl_c (0); + #endif /* copy the structure */ __libc_tty_p->t_termios = *termiosp; *** src/libc/posix/termios/tminit.c-orig Sun Sep 15 16:02:18 1996 --- src/libc/posix/termios/tminit.c Mon Dec 30 21:23:50 1996 *************** *** 5,10 **** --- 5,11 ---- */ #include + #include #include #include #include *************** *** 15,20 **** --- 16,23 ---- #include #include #include + #include + #include #include #include #include *************** *** 30,35 **** --- 33,59 ---- #define CPMEOF 0x1a /* Ctrl+Z */ + #define _REG_STATUS_CF 0x01 + #define _REG_STATUS_ZF 0x40 + #define _KEY_INS 0x80 + #define _KEY_CAPS 0x40 + #define _KEY_NUM 0x20 + #define _KEY_SCRL 0x10 + #define _KEY_ALT 0x08 + #define _KEY_CTRL 0x04 + #define _KEY_LSFT 0x02 + #define _KEY_RSFT 0x01 + #define _KEYE_SYSRQ 0x80 + #define _KEYE_CAPS 0x40 + #define _KEYE_NUM 0x20 + #define _KEYE_SCRL 0x10 + #define _KEYE_RALT 0x08 + #define _KEYE_RCTRL 0x04 + #define _KEYE_LALT 0x02 + #define _KEYE_LCTRL 0x01 + + #define CHECKBYTES 32 + /* tty buffers */ unsigned char __libc_tty_queue_buffer[_TTY_QUEUE_SIZE]; struct tty __libc_tty_internal = TTYDEFAULT; *************** *** 39,52 **** --- 63,85 ---- /* global only in the termios functions */ int __libc_termios_hook_common_count = -1; + /* static variables */ + static int __libc_use_function_and_arrow_keys = 0; + static int __libc_has_enhanced_keyboard = 0; + static int __libc_has_extended_keystroke = 0; + static unsigned char __libc_extended_keystroke[16] = { 0, }; + static ssize_t __libc_termios_check_bytes = CHECKBYTES; + /* static functions */ static void __libc_termios_fflushall (void); + static void __libc_termios_init_direct_functions (void); static ssize_t __libc_termios_read (int handle, void *buffer, size_t count, ssize_t *rv); static ssize_t __libc_termios_read_cooked_tty (int handle, void *buffer, size_t count); static ssize_t __libc_termios_read_raw_tty (int handle, void *buffer, size_t count); static ssize_t __libc_termios_write (int handle, const void *buffer, size_t count, ssize_t *rv); static ssize_t __libc_termios_write_cooked_tty (int handle, const void *buffer, size_t count); static ssize_t __libc_termios_write_raw_tty (int handle, const void *buffer, size_t count); + static int __libc_termios_fsext (__FSEXT_Fnumber n, int *rv, va_list ap); static void __libc_termios_echo_ctrl (unsigned char ch); static void __libc_termios_maybe_echo_ctrl (unsigned char ch); static void __libc_termios_maybe_echo (unsigned char ch); *************** *** 58,71 **** static void __libc_termios_clear_queue (void); static int __libc_termios_get_queue (void); static int __libc_termios_put_queue (unsigned char ch); static void __libc_termios_fill_queue (void); /* direct I/O functions */ ! static inline int __direct_keysense (void); ! static inline unsigned char __direct_keyinput (void); ! static inline int __direct_ctrlsense (void); ! static inline void __direct_output (unsigned char ch); ! static inline void __direct_outputs (const unsigned char *s); /******************************************************************************/ /* initialize function ********************************************************/ --- 91,123 ---- static void __libc_termios_clear_queue (void); static int __libc_termios_get_queue (void); static int __libc_termios_put_queue (unsigned char ch); + static void __libc_termios_raise_signal (unsigned char ch, int sig); static void __libc_termios_fill_queue (void); /* direct I/O functions */ ! static void __direct_add_keystroke (int c); ! static void __direct_add_keystrokes (char *s); ! static void __direct_check_extened_keystroke_at (int scan); ! /* AT keyboard */ ! static int __direct_keysense_at (void); ! static unsigned char __direct_keyinput_at (void); ! static int __direct_ctrlsense_at (void); ! /* AT enhanced keyboard */ ! static int __direct_keysense_ate (void); ! static unsigned char __direct_keyinput_ate (void); ! static int __direct_ctrlsense_ate (void); ! /* Output functions */ ! static void __direct_output_tab_at (void); ! static void __direct_output_at (unsigned char ch); ! static void __direct_outputns_at (int n, const unsigned char *s); ! static void __direct_outputs_at (const unsigned char *s); ! /* function pointers */ ! static int (*__direct_keysense) (void) = __direct_keysense_at; ! static unsigned char (*__direct_keyinput) (void) = __direct_keyinput_at; ! static int (*__direct_ctrlsense) (void) = __direct_ctrlsense_at; ! static void (*__direct_output) (unsigned char ch) = __direct_output_at; ! static void (*__direct_outputns) (int n, const unsigned char *s) = __direct_outputns_at; ! static void (*__direct_outputs) (const unsigned char *s) = __direct_outputs_at; /******************************************************************************/ /* initialize function ********************************************************/ *************** *** 80,85 **** --- 132,162 ---- #endif } + static void + __libc_termios_init_direct_functions (void) + { + __libc_has_enhanced_keyboard = 0; + __libc_has_extended_keystroke = 0; + + if (_farpeekb (_dos_ds, 0x496) & 0x10) + __libc_has_enhanced_keyboard = 1; + + if (__libc_has_enhanced_keyboard) + { + __direct_keysense = __direct_keysense_ate; + __direct_keyinput = __direct_keyinput_ate; + __direct_ctrlsense = __direct_ctrlsense_ate; + } + else + { + __direct_keysense = __direct_keysense_at; + __direct_keyinput = __direct_keyinput_at; + __direct_ctrlsense = __direct_ctrlsense_at; + } + __direct_output = __direct_output_at; + __direct_outputs = __direct_outputs_at; + } + void __libc_termios_init (void) { *************** *** 90,114 **** /* flush all buffered streams */ __libc_termios_fflushall (); /* set special hooks */ __libc_read_termios_hook = __libc_termios_read; __libc_write_termios_hook = __libc_termios_write; /* import parameters */ /* __libc_tty_p = ...; */ } } /******************************************************************************/ ! /* direct I/O function (inlined) **********************************************/ ! #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) --- 167,324 ---- /* flush all buffered streams */ __libc_termios_fflushall (); + /* check enhanced keyboard, etc */ + __libc_termios_init_direct_functions (); + /* set special hooks */ __libc_read_termios_hook = __libc_termios_read; __libc_write_termios_hook = __libc_termios_write; /* import parameters */ /* __libc_tty_p = ...; */ + + /* fsext */ + (void) __FSEXT_set_function (0, __libc_termios_fsext); + (void) __FSEXT_set_function (1, __libc_termios_fsext); + (void) __FSEXT_set_function (2, __libc_termios_fsext); + __libc_termios_check_bytes = CHECKBYTES; } } + int + __libc_termios_disable_function_and_arrow_keys (void) + { + int old_value; + + old_value = __libc_use_function_and_arrow_keys; + __libc_use_function_and_arrow_keys = 0; + + return old_value; + } + + int + __libc_termios_enable_function_and_arrow_keys (void) + { + int old_value; + + old_value = __libc_use_function_and_arrow_keys; + __libc_use_function_and_arrow_keys = 1; + + return old_value; + } + /******************************************************************************/ ! /* direct I/O function ********************************************************/ ! /* function key trans function */ ! static void ! __direct_add_keystroke (int c) ! { ! if (__libc_has_extended_keystroke + 1 > sizeof (__libc_extended_keystroke)) ! return; ! ! __libc_extended_keystroke[__libc_has_extended_keystroke++] = (unsigned char) c; ! } ! ! static void ! __direct_add_keystrokes (char *s) ! { ! int len; ! ! len = strlen (s); ! if (__libc_has_extended_keystroke + len > sizeof (__libc_extended_keystroke)) ! return; ! ! while (--len >= 0) ! __libc_extended_keystroke[__libc_has_extended_keystroke++] = (unsigned char) s[len]; ! } ! ! #define _NDUMMY (0xffU) ! #define _N(c) (0x00U|(c)) /* no shift */ ! #define _S(c) (0x40U|(c)) /* w/shift */ ! #define _C(c) (0x80U|(c)) /* w/ctrl */ ! #define _A(c) (0xc0U|(c)) /* w/alt */ ! #define _TRANS_NOSHIFT "\x1b[0" ! #define _TRANS_SHIFT "\x1b[1" ! #define _TRANS_CTRL "\x1b[2" ! #define _TRANS_ALT "\x1b[3" ! ! static unsigned char trans_alphabet_chars[64] = ! "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456ABCDEFGHIJKLMNOPQRSTUVWXYZ123456"; ! ! static unsigned char trans_mapping_chras_at[] = ! { ! /* 000-037: A-Z, 040-077: XA-XZ */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 00-07 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 08-0F */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 10-17 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 18-1F */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 20-27 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 28-2F */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 30-37 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _N(040), _N(041), _N(042), _N(043), _N(044), /* 38-3F */ ! _N(045), _N(046), _N(047), _N(050), _N(051), _NDUMMY, _NDUMMY, _N(006), /* 40-47 */ ! _N(000), _N(010), _NDUMMY, _N(001), _NDUMMY, _N(002), _NDUMMY, _N(007), /* 48-4F */ ! _N(003), _N(011), _N(004), _N(005), _S(040), _S(041), _S(042), _S(043), /* 50-57 */ ! _S(044), _S(045), _S(046), _S(047), _S(050), _S(051), _C(040), _C(041), /* 58-5F */ ! _C(042), _C(043), _C(044), _C(045), _C(046), _C(047), _C(050), _C(051), /* 60-67 */ ! _A(040), _A(041), _A(042), _A(043), _A(044), _A(045), _A(046), _A(047), /* 68-6F */ ! _A(050), _A(051), _NDUMMY, _C(001), _C(002), _C(007), _C(011), _C(006), /* 70-77 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 78-7F */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _C(010), _N(052), _N(053), _S(052), /* 80-87 */ ! _S(053), _C(052), _C(053), _A(052), _A(053), _C(000), _NDUMMY, _NDUMMY, /* 88-8F */ ! _NDUMMY, _C(003), _C(004), _C(005), _NDUMMY, _NDUMMY, _NDUMMY, _A(006), /* 90-97 */ ! _A(000), _A(010), _NDUMMY, _A(001), _NDUMMY, _A(002), _NDUMMY, _A(007), /* 98-9F */ ! _A(003), _A(011), _A(004), _A(005), _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* A0-A7 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* A8-AF */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* B0-B7 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* B8-BF */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* C0-C7 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* C8-CF */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* D0-D7 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* D8-DF */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* E0-E7 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* E8-EF */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* F0-F7 */ ! _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* F8-FF */ ! }; ! ! static void ! __direct_check_extened_keystroke_at (int scan) ! { ! int c, shift; ! ! if (!__libc_use_function_and_arrow_keys || scan < 0 || scan > 0xff) ! return; ! ! c = (int) trans_mapping_chras_at[scan]; ! if (c == (int) _NDUMMY) ! return; ! ! shift = c & 0xc0; ! c &= ~0xc0; ! __direct_add_keystroke (trans_alphabet_chars[c]); ! if (c >= 040) ! __direct_add_keystroke ('X'); ! if (shift == 0x00) ! __direct_add_keystrokes (_TRANS_NOSHIFT); ! else if (shift == 0x40) ! __direct_add_keystrokes (_TRANS_SHIFT); ! else if (shift == 0x80) ! __direct_add_keystrokes (_TRANS_CTRL); ! else if (shift == 0xc0) ! __direct_add_keystrokes (_TRANS_ALT); ! } ! /* Input form AT keyboard */ ! static int ! __direct_keysense_at (void) { __dpmi_regs r; + if (__libc_has_extended_keystroke) + return 1; + r.h.ah = 0x01; __dpmi_int (0x16, &r); if (r.x.flags & _REG_STATUS_ZF) *************** *** 117,147 **** return 1; } ! static inline unsigned char ! __direct_keyinput (void) { __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 ! #define _KEY_SCRL 0x10 ! #define _KEY_ALT 0x08 ! #define _KEY_CTRL 0x04 ! #define _KEY_LSFT 0x02 ! #define _KEY_RSFT 0x01 ! static inline int ! __direct_ctrlsense (void) { __dpmi_regs r; r.h.ah = 0x02; __dpmi_int (0x16, &r); if (r.h.al & _KEY_CTRL) --- 327,360 ---- return 1; } ! static unsigned char ! __direct_keyinput_at (void) { __dpmi_regs r; + if (__libc_has_extended_keystroke) + return __libc_extended_keystroke[--__libc_has_extended_keystroke]; + r.h.ah = 0x00; __dpmi_int (0x16, &r); + if (r.h.al != 0x00) + return r.h.al; ! __direct_check_extened_keystroke_at (r.h.ah); ! if (__libc_has_extended_keystroke) ! return __libc_extended_keystroke[--__libc_has_extended_keystroke]; ! return 0; ! } ! static int ! __direct_ctrlsense_at (void) { __dpmi_regs r; + if (__libc_has_extended_keystroke) + return 0; + r.h.ah = 0x02; __dpmi_int (0x16, &r); if (r.h.al & _KEY_CTRL) *************** *** 150,172 **** return 0; } ! static inline void ! __direct_output (unsigned char ch) { __dpmi_regs r; ! if (ch == 0xff) return; r.h.al = ch; __dpmi_int (0x29, &r); } ! static inline void ! __direct_outputs (const unsigned char *s) { while (*s) ! __direct_output (*s++); } /******************************************************************************/ --- 363,516 ---- return 0; } ! /* Input from AT enhanced keyboard */ ! static int ! __direct_keysense_ate (void) ! { ! __dpmi_regs r; ! ! if (__libc_has_extended_keystroke) ! return 1; ! ! r.h.ah = 0x11; ! __dpmi_int (0x16, &r); ! if (r.x.flags & _REG_STATUS_ZF) ! return 0; ! ! return 1; ! } ! ! static unsigned char ! __direct_keyinput_ate (void) ! { ! __dpmi_regs r; ! ! if (__libc_has_extended_keystroke) ! return __libc_extended_keystroke[--__libc_has_extended_keystroke]; ! ! r.h.ah = 0x10; ! __dpmi_int (0x16, &r); ! if (r.h.al != 0x00 && (r.h.al < 0xe0U ! || (r.h.al != 0xe0 && r.h.al != 0xf0))) ! return r.h.al; ! ! __direct_check_extened_keystroke_at (r.h.ah); ! if (__libc_has_extended_keystroke) ! return __libc_extended_keystroke[--__libc_has_extended_keystroke]; ! ! return 0; ! } ! ! static int ! __direct_ctrlsense_ate (void) ! { ! __dpmi_regs r; ! ! if (__libc_has_extended_keystroke) ! return 0; ! ! r.h.ah = 0x12; ! __dpmi_int (0x16, &r); ! if (r.h.al & _KEY_CTRL) /* either CTRL */ ! return 1; ! ! return 0; ! } ! ! /* output to Screen */ ! static void ! __direct_output_tab_at (void) ! { ! __dpmi_regs r; ! int page, col; ! int x, y; ! ! page = _farpeekb (_dos_ds, 0x462); ! col = _farpeekw (_dos_ds, 0x44a); ! ! r.h.ah = 3; ! r.h.bh = page; ! __dpmi_int (0x10, &r); ! x = r.h.dl; ! y = r.h.dh; ! ! x += 8; ! x &= ~7; ! if (x > col) ! { ! #if 1 ! r.h.al = '\r'; ! __dpmi_int (0x29, &r); ! r.h.al = '\n'; ! __dpmi_int (0x29, &r); ! #else ! (void) putch ('\r'); ! (void) putch ('\n'); ! #endif ! } ! else ! { ! r.h.ah = 2; ! r.h.bh = page; ! r.h.dl = x; ! r.h.dh = y; ! __dpmi_int (0x10, &r); ! } ! } ! ! static void ! __direct_output_at (unsigned char ch) { + #if 1 __dpmi_regs r; + #endif ! if (ch == 0x09) ! { ! __direct_output_tab_at (); ! return; ! } ! else if (ch == 0xff) return; + #if 1 r.h.al = ch; __dpmi_int (0x29, &r); + #else + (void) putch (ch); + #endif } ! static void ! __direct_outputns_at (int n, const unsigned char *s) ! { ! #if 1 ! __dpmi_regs r; ! #endif ! unsigned char ch; ! ! while (--n >= 0) ! { ! ch = *s++; ! if (ch == 0x09) ! __direct_output_tab_at (); ! else if (ch != 0xff) ! { ! #if 1 ! r.h.al = ch; ! __dpmi_int (0x29, &r); ! #else ! (void) putch (ch); ! #endif ! } ! } ! } ! ! static void ! __direct_outputs_at (const unsigned char *s) { while (*s) ! __direct_output_at (*s++); } /******************************************************************************/ *************** *** 490,495 **** --- 834,846 ---- } } + __libc_termios_check_bytes -= bytes; + if (__libc_termios_check_bytes <= 0) + { + __libc_termios_check_bytes = CHECKBYTES; + __libc_termios_check_signals (); + } + /* result of write() */ *rv = bytes; return 1; *************** *** 505,528 **** { const unsigned char *rp; unsigned char ch; ! ssize_t n; rp = buffer; n = count; ! while (--n >= 0) { ! /* get character */ ! ch = *rp++; ! /* NOTE: multibyte character don't contain control character */ ! /* map NL to CRNL */ ! if (ch == '\n' && (__libc_tty_p->t_oflag & ONLCR)) ! __direct_output ('\r'); ! /* map CR to NL */ ! else if (ch == '\r' && (__libc_tty_p->t_oflag & OCRNL)) ! ch = '\n'; ! __direct_output (ch); } /* don't count CR */ --- 856,892 ---- { const unsigned char *rp; unsigned char ch; ! ssize_t n, nn; rp = buffer; n = count; ! while (n > 0) { ! nn = (n < __libc_termios_check_bytes) ? n : __libc_termios_check_bytes; ! n -= nn; ! __libc_termios_check_bytes -= nn; ! while (--nn >= 0) ! { ! /* get character */ ! ch = *rp++; ! ! /* NOTE: multibyte character don't contain control character */ ! /* map NL to CRNL */ ! if (ch == '\n' && (__libc_tty_p->t_oflag & ONLCR)) ! __direct_output ('\r'); ! /* map CR to NL */ ! else if (ch == '\r' && (__libc_tty_p->t_oflag & OCRNL)) ! ch = '\n'; ! __direct_output (ch); ! } ! ! if (__libc_termios_check_bytes <= 0) ! { ! __libc_termios_check_bytes = CHECKBYTES; ! __libc_termios_check_signals (); ! } } /* don't count CR */ *************** *** 545,557 **** rp = buffer; n = count; ! while (--n >= 0) ! __direct_output (*rp++); return count; } /******************************************************************************/ /* echo routines **************************************************************/ static void --- 909,1012 ---- rp = buffer; n = count; ! while (n > 0) ! { ! if (n < __libc_termios_check_bytes) ! { ! __libc_termios_check_bytes -= n; ! __direct_outputns (n, rp); ! rp += n; ! break; ! } ! else ! { ! n -= __libc_termios_check_bytes; ! __direct_outputns (__libc_termios_check_bytes, rp); ! rp += __libc_termios_check_bytes; ! __libc_termios_check_bytes = CHECKBYTES; ! __libc_termios_check_signals (); ! } ! } return count; } /***************************************************************************** */ + /* special fsext function *****************************************************/ + + static int + __libc_termios_fsext (__FSEXT_Fnumber n, int *rv, va_list ap) + { + short devmod; + ssize_t bytes; + int handle; + + handle = va_arg (ap, int); + devmod = _get_dev_info (handle); + if (devmod == -1) + return 0; + if (!(devmod & _DEV_CDEV) || !(devmod & (_DEV_STDIN|_DEV_STDOUT))) + return 0; + + /* console only... */ + switch (n) + { + #if 0 + case __FSEXT_read: + { + void *buffer; + size_t count; + + buffer = va_arg (ap, void *); + count = va_arg (ap, size_t); + if (devmod & _DEV_RAW) + bytes = __libc_termios_read_raw_tty (handle, buffer, count); + else + bytes = __libc_termios_read_cooked_tty (handle, buffer, count); + + /* result of read */ + *rv = bytes; + return 1; + } + case __FSEXT_write: + { + const void *buffer; + size_t count; + + buffer = va_arg (ap, const void *); + count = va_arg (ap, size_t); + if (devmod & _DEV_RAW) + bytes = __libc_termios_write_raw_tty (handle, buffer, count); + else + bytes = __libc_termios_write_cooked_tty (handle, buffer, count); + + /* result of write */ + *rv = bytes; + return 1; + } + #else + case __FSEXT_write: + { + size_t count; + const void *buffer; + + buffer = va_arg (ap, const void *); + count = va_arg (ap, size_t); + bytes = __libc_termios_write_raw_tty (handle, buffer, count); + + /* result of write */ + *rv = bytes; + return 1; + } + #endif + default: + break; + } + + return 0; + } + + /***************************************************************************** */ /* echo routines **************************************************************/ static void *************** *** 845,850 **** --- 1300,1320 ---- } static void + __libc_termios_raise_signal (unsigned char ch, int sig) + { + #if 0 + struct sigaction oldact; + + if (sigaction (sig, NULL, &oldact) == 0) + if (oldact.sa_handler == SIG_DFL) + __libc_termios_maybe_echo_ctrl (ch); + #else + __libc_termios_maybe_echo_ctrl (ch); + #endif + kill (getpid(), sig); + } + + static void __libc_termios_fill_queue (void) { unsigned char ch; *************** *** 854,865 **** /* exhaust inputs ? */ if (! __direct_keysense ()) { if (__libc_tty_p->t_lflag & ICANON) ! { ! /* wait for NL or EOT */ ! __dpmi_yield (); ! continue; ! } return; } --- 1324,1333 ---- /* exhaust inputs ? */ if (! __direct_keysense ()) { + __dpmi_yield (); + /* wait for NL or EOT ? */ if (__libc_tty_p->t_lflag & ICANON) ! continue; return; } *************** *** 880,887 **** { if (__libc_tty_p->t_iflag & BRKINT) { ! __libc_termios_maybe_echo_ctrl (ch); ! kill (getpid (), SIGINT); continue; } else --- 1348,1354 ---- { if (__libc_tty_p->t_iflag & BRKINT) { ! __libc_termios_raise_signal (ch, SIGINT); continue; } else *************** *** 892,906 **** } else if (_CC_EQU (VQUIT, ch)) { ! __libc_termios_maybe_echo_ctrl (ch); ! kill (getpid(), SIGQUIT); continue; } else if (_CC_EQU (VSUSP, ch)) { - __libc_termios_maybe_echo_ctrl (ch); #ifdef SIGTSTP ! kill (getpid(), SIGTSTP); #else /* djgpp don't have ... */ { char oldcwd[PATH_MAX]; --- 1359,1371 ---- } else if (_CC_EQU (VQUIT, ch)) { ! __libc_termios_raise_signal (ch, SIGQUIT); continue; } else if (_CC_EQU (VSUSP, ch)) { #ifdef SIGTSTP ! __libc_termios_raise_signal (ch, SIGTSTP); #else /* djgpp don't have ... */ { char oldcwd[PATH_MAX]; *************** *** 1002,1005 **** --- 1467,1513 ---- } /***************************************************************************** */ + /* software signal checker ****************************************************/ + + void + __libc_termios_check_signals (void) + { + unsigned char ch; + + if (! __direct_keysense ()) + return; + + /* software signals */ + if (__libc_tty_p->t_lflag & ISIG) + { + ch = __direct_keyinput (); + if (! (__libc_tty_p->t_iflag & IGNBRK) && _CC_EQU (VINTR, ch)) + { + if (__libc_tty_p->t_iflag & BRKINT) + { + __libc_termios_raise_signal (ch, SIGINT); + return; + } + } + else if (_CC_EQU (VQUIT, ch)) + { + __libc_termios_raise_signal (ch, SIGQUIT); + return; + } + + /* for compatiblity */ + if (ch == 0x13 && !(__libc_tty_p->t_iflag & IXOFF)) + { + /* CTRL+S */ + while (! __direct_keysense ()) + __dpmi_yield (); + ch = __direct_keyinput (); + return; + } + /* push back */ + __direct_add_keystroke ((int) ch); + } + } + + /***************************************************************************** */