aboutsummaryrefslogtreecommitdiffhomepage
path: root/input_common.c
diff options
context:
space:
mode:
authorGravatar axel <axel@liljencrantz.se>2005-09-20 23:26:39 +1000
committerGravatar axel <axel@liljencrantz.se>2005-09-20 23:26:39 +1000
commit149594f974350bb364a76c73b91b1d5ffddaa1fa (patch)
tree95650e9982d5fabe4bd805d94c5d700cbbc1ca7f /input_common.c
Initial revision
darcs-hash:20050920132639-ac50b-fa3b476891e1f5f67207cf4cc7bf623834cc5edc.gz
Diffstat (limited to 'input_common.c')
-rw-r--r--input_common.c220
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;
+}
+