aboutsummaryrefslogtreecommitdiffhomepage
path: root/input_common.cpp
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2011-12-26 19:11:54 -0800
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2011-12-26 19:11:54 -0800
commit3f16ace6784caab54fb054836ee93902e9701913 (patch)
tree6ae6170f86bd45ce7fd0dae4a4242bb8dc67c505 /input_common.cpp
parent834ea94eb97d37c65fcbf2fcc3b69303f6fb7e24 (diff)
Initial C++ conversion
Diffstat (limited to 'input_common.cpp')
-rw-r--r--input_common.cpp241
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;
+}
+