diff options
author | axel <axel@liljencrantz.se> | 2005-09-20 23:26:39 +1000 |
---|---|---|
committer | axel <axel@liljencrantz.se> | 2005-09-20 23:26:39 +1000 |
commit | 149594f974350bb364a76c73b91b1d5ffddaa1fa (patch) | |
tree | 95650e9982d5fabe4bd805d94c5d700cbbc1ca7f /input_common.c |
Initial revision
darcs-hash:20050920132639-ac50b-fa3b476891e1f5f67207cf4cc7bf623834cc5edc.gz
Diffstat (limited to 'input_common.c')
-rw-r--r-- | input_common.c | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/input_common.c b/input_common.c new file mode 100644 index 00000000..0f92a314 --- /dev/null +++ b/input_common.c @@ -0,0 +1,220 @@ +/** \file input_common.h + +Implementation file for the low level input library + +*/ +#include "config.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <wchar.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 \e 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[32]; + +/** + 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() +{ + 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: + { +// wperror( L"select" ); + if( interrupt_handler ) + { + int res = interrupt_handler(); + +/* debug( 0, + L"interrupt, %d is %ls", + res, + (res==R_NULL?L"good": L"Bad") ); +*/ + if( res ) + return res; + } + + do_loop = 1; + break; + } + default: + { + debug( 0, L"Error while reading input from keyboard, shutting down" ); + wperror(L"read"); + exit(1); + } + } + } + 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(); + return R_NULL; + } + } + if( FD_ISSET( 0, &fd ) ) + { + if( read_blocked( 0, arr, 1 ) == -1 ) + { + debug( 0, L"Error while reading input from keyboard, shutting down" ); + wperror(L"read"); + exit(1); + } + 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(); + int sz; + + if( b == R_NULL ) + return R_NULL; + + sz = mbrtowc( &res, &b, 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; +} + |