diff options
| author | Steve Slaven <bpk@hoopajoo.net> | 2005-03-21 20:49:24 (GMT) | 
|---|---|---|
| committer | Steve Slaven <bpk@hoopajoo.net> | 2005-03-21 20:49:24 (GMT) | 
| commit | 22e6d965aa95a519d2b5672ee2c888785fc524ee (patch) | |
| tree | 13db9f59127a2b9169acfe7d10e707b2264e7133 /tty.c | |
| parent | abe994ae16b892106e0b36d7be5bfd7e1100075c (diff) | |
| download | powwow-22e6d965aa95a519d2b5672ee2c888785fc524ee.zip powwow-22e6d965aa95a519d2b5672ee2c888785fc524ee.tar.gz powwow-22e6d965aa95a519d2b5672ee2c888785fc524ee.tar.bz2 | |
Wide character (locale) support from Dain, changed output of the compiled
options line since there are more compile time options now
Diffstat (limited to 'tty.c')
| -rw-r--r-- | tty.c | 152 | 
1 files changed, 151 insertions, 1 deletions
| @@ -9,13 +9,22 @@   *  (at your option) any later version.   *   */ +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdarg.h>  #include <stdio.h>  #include <stdlib.h>  #include <string.h> -#include <time.h>  #include <sys/types.h> +#include <time.h>  #include <unistd.h> +#ifdef USE_LOCALE +#include <wchar.h> +#include <locale.h> +#endif +  #include "defines.h"  #include "main.h"  #include "edit.h" @@ -133,6 +142,9 @@ char *tty_modebold = modebold,       *tty_modeblink = modeblink,  int tty_read_fd = 0;  static int wrapglitch = 0; +#ifdef USE_LOCALE +FILE *tty_read_stream, *tty_write_stream; +#endif  #ifdef USE_SGTTY  static struct sgttyb ttybsave; @@ -289,6 +301,12 @@ void tty_sig_winch_bottomhalf __P0 (void)   */  void tty_bootstrap __P0 (void)  { +#ifdef USE_LOCALE +    tty_read_stream = stdin; +    tty_write_stream = stdout; +    fcntl(tty_read_fd, F_SETFL, O_NONBLOCK | fcntl(tty_read_fd, F_GETFL)); +#endif +  #ifndef USE_VT100      struct tc_init_node {  	char cap[4], *buf; @@ -772,3 +790,135 @@ void input_insert_follow_chars __P2 (char *,str, int,n)  	tty_gotoxy_opt(CURCOL(p), cl, CURCOL(pos), CURLINE(pos));  } +#ifdef USE_LOCALE +/* curses wide character support by Dain */ + +void tty_puts __P ((const char *s)) +{ +    while (*s) +	putwc((unsigned char)*s++, tty_write_stream); +} + +void tty_putc __P ((char c)) +{ +    putwc((unsigned char)c, tty_write_stream); +} + + +void tty_printf __P ((const char *format, ...)) +{ +    char buf[1024], *bufp = buf; +    va_list va; +    int res; + +    char *old_locale = strdup(setlocale(LC_ALL, NULL)); + +    setlocale(LC_ALL, "C"); + +    va_start(va, format); +    res = vsnprintf(buf, sizeof buf, format, va); +    va_end(va); + +    if (res >= sizeof buf) { +	bufp = alloca(res + 1); +	va_start(va, format); +	vsprintf(bufp, format, va); +	va_end(va); +    } + +    setlocale(LC_ALL, old_locale); +    free(old_locale); + +    tty_puts(bufp); +} + +static char tty_in_buf[MB_LEN_MAX + 1]; +static int tty_in_buf_used = 0; + +int tty_has_chars __P ((void)) +{ +    return !!tty_in_buf_used; +} + +int tty_read __P ((char *buf, size_t count)) +{ +    int result = 0; +    int converted; +    wchar_t wc; + +    if (count && tty_in_buf_used) { +	converted = mbtowc(&wc, tty_in_buf, tty_in_buf_used); +	if (converted >= 0) +	    goto another; +    } + +    while (count) { +	int should_read = sizeof tty_in_buf - tty_in_buf_used; +	int did_read = read(tty_read_fd, tty_in_buf + tty_in_buf_used, +			    should_read); + +	if (did_read < 0 && errno == EINTR) +	    continue; +	if (did_read <= 0) +	    break; + +	tty_in_buf_used += did_read; + +	converted = mbtowc(&wc, tty_in_buf, tty_in_buf_used); +	if (converted < 0) +	    break; + +    another: +	if (converted == 0) +	    converted = 1; + +	if (!(wc & ~0xff)) { +	    *buf++ = (unsigned char)wc; +	    --count; +	    ++result; +	} + +	tty_in_buf_used -= converted; +	memmove(tty_in_buf, tty_in_buf + converted, tty_in_buf_used); + +	if (count == 0) +	    break; + +	converted = mbtowc(&wc, tty_in_buf, tty_in_buf_used); +	if (converted >= 0 && tty_in_buf_used) +	    goto another; + +	if (did_read < should_read) +	    break; +    } + +    return result; +} + + +void tty_gets __P ((char *s, int size)) +{ +    wchar_t *ws = alloca(size * sizeof *ws); + +    if (!fgetws(ws, size, stdin)) +	return; + +    while (*ws) { +	if (!(*ws & ~0xff)) +	    *s++ = (unsigned char)*ws; +	++ws; +    } +} + +void tty_flush __P ((void)) +{ +    fflush(tty_write_stream); +} + +void tty_raw_write __P ((char *data, int len)) +{ +    tty_flush(); +    write(1, data, len); +} + +#endif /* USE_LOCALE */ | 
