diff options
author | ridiculousfish <corydoras@ridiculousfish.com> | 2011-12-26 19:11:54 -0800 |
---|---|---|
committer | ridiculousfish <corydoras@ridiculousfish.com> | 2011-12-26 19:11:54 -0800 |
commit | 3f16ace6784caab54fb054836ee93902e9701913 (patch) | |
tree | 6ae6170f86bd45ce7fd0dae4a4242bb8dc67c505 /input_common.cpp | |
parent | 834ea94eb97d37c65fcbf2fcc3b69303f6fb7e24 (diff) |
Initial C++ conversion
Diffstat (limited to 'input_common.cpp')
-rw-r--r-- | input_common.cpp | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/input_common.cpp b/input_common.cpp new file mode 100644 index 00000000..117b464d --- /dev/null +++ b/input_common.cpp @@ -0,0 +1,241 @@ +/** \file input_common.c + +Implementation file for the low level input library + +*/ +#include "config.h" + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <sys/time.h> +#include <sys/types.h> +#include <unistd.h> +#include <wchar.h> +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif + +#include "fallback.h" +#include "util.h" + +#include "common.h" +#include "wutil.h" +#include "input_common.h" +#include "env_universal.h" + +/** + Time in milliseconds to wait for another byte to be available for + reading after \\x1b is read before assuming that escape key was + pressed, and not an escape sequence. +*/ +#define WAIT_ON_ESCAPE 10 + +/** + Characters that have been read and returned by the sequence matching code +*/ +static wint_t lookahead_arr[1024]; + +/** + Number of entries in lookahead_arr +*/ +static int lookahead_count = 0; + +/** + Callback function for handling interrupts on reading +*/ +static int (*interrupt_handler)(); + +void input_common_init( int (*ih)() ) +{ + interrupt_handler = ih; +} + +void input_common_destroy() +{ + +} + +/** + Internal function used by input_common_readch to read one byte from fd 1. This function should only be called by + input_common_readch(). +*/ +static wint_t readb() +{ + unsigned char arr[1]; + int do_loop = 0; + + do + { + fd_set fd; + int fd_max=1; + int res; + + FD_ZERO( &fd ); + FD_SET( 0, &fd ); + if( env_universal_server.fd > 0 ) + { + FD_SET( env_universal_server.fd, &fd ); + fd_max = env_universal_server.fd+1; + } + + do_loop = 0; + + res = select( fd_max, &fd, 0, 0, 0 ); + if( res==-1 ) + { + switch( errno ) + { + case EINTR: + case EAGAIN: + { + if( interrupt_handler ) + { + int res = interrupt_handler(); + if( res ) + { + return res; + } + if( lookahead_count ) + { + return lookahead_arr[--lookahead_count]; + } + + } + + + do_loop = 1; + break; + } + default: + { + /* + The terminal has been closed. Save and exit. + */ + return R_EOF; + } + } + } + else + { + if( env_universal_server.fd > 0 ) + { + if( FD_ISSET( env_universal_server.fd, &fd ) ) + { + debug( 3, L"Wake up on universal variable event" ); + env_universal_read_all(); + do_loop = 1; + + if( lookahead_count ) + { + return lookahead_arr[--lookahead_count]; + } + } + } + if( FD_ISSET( 0, &fd ) ) + { + if( read_blocked( 0, arr, 1 ) != 1 ) + { + /* + The teminal has been closed. Save and exit. + */ + return R_EOF; + } + do_loop = 0; + } + } + } + while( do_loop ); + + return arr[0]; +} + + +wchar_t input_common_readch( int timed ) +{ + if( lookahead_count == 0 ) + { + if( timed ) + { + int count; + fd_set fds; + struct timeval tm= + { + 0, + 1000 * WAIT_ON_ESCAPE + } + ; + + FD_ZERO( &fds ); + FD_SET( 0, &fds ); + count = select(1, &fds, 0, 0, &tm); + + switch( count ) + { + case 0: + return WEOF; + + case -1: + return WEOF; + break; + default: + break; + + } + } + + wchar_t res; + static mbstate_t state; + + while(1) + { + wint_t b = readb(); + char bb; + + int sz; + + if( (b >= R_NULL) && (b < R_NULL + 1000) ) + return b; + + bb=b; + + sz = mbrtowc( &res, &bb, 1, &state ); + + switch( sz ) + { + case -1: + memset (&state, '\0', sizeof (state)); + debug( 2, L"Illegal input" ); + return R_NULL; + case -2: + break; + case 0: + return 0; + default: + + return res; + } + } + } + else + { + if( !timed ) + { + while( (lookahead_count >= 0) && (lookahead_arr[lookahead_count-1] == WEOF) ) + lookahead_count--; + if( lookahead_count == 0 ) + return input_common_readch(0); + } + + return lookahead_arr[--lookahead_count]; + } +} + + +void input_common_unreadch( wint_t ch ) +{ + lookahead_arr[lookahead_count++] = ch; +} + |