diff --git a/src/conio/ansi_cio.c b/src/conio/ansi_cio.c
index 2e8157e0da69a09b4e4208019b42055c841cfb27..85ad1dfe10605384bbd1445fa11a9d785df5c075 100644
--- a/src/conio/ansi_cio.c
+++ b/src/conio/ansi_cio.c
@@ -55,6 +55,10 @@
 #include "ansi_cio.h"
 
 int	CIOLIB_ANSI_TIMEOUT=500;
+int  (*ciolib_ansi_readbyte_cb)(void)=ansi_readbyte_cb;
+int  (*ciolib_ansi_writebyte_cb)(unsigned char ch)=ansi_writebyte_cb;
+int  (*ciolib_ansi_initio_cb)(void)=ansi_initio_cb;
+int  (*ciolib_ansi_writestr_cb)(unsigned char *str, size_t len)=ansi_writestr_cb;
 
 static sem_t	got_key;
 static sem_t	got_input;
@@ -70,7 +74,7 @@ static int doorway_enabled=0;
 
 const int 	ansi_colours[8]={0,4,2,6,1,5,3,7};
 static WORD		ansi_inch;
-static unsigned char		ansi_raw_inch;
+static int		ansi_raw_inch;
 static WORD	*ansivmem;
 static int		force_move=1;
 
@@ -210,8 +214,8 @@ static void ansi_sendch(char ch)
 		}
 	}
 	if(doorway_enabled && ch < ' ')
-		fwrite("",1,1,stdout);
-	fwrite(&ch,1,1,stdout);
+		ciolib_ansi_writebyte_cb(0);
+	ciolib_ansi_writebyte_cb((unsigned char)ch);
 	/* We sent a control char... better make the next movement explicit */
 	if(ch<' ' && ch > 0)
 		force_move=1;
@@ -222,7 +226,7 @@ static void ansi_sendstr(char *str,int len)
 	if(len==-1)
 		len=strlen(str);
 	if(len)
-		fwrite(str,len,1,stdout);
+		ciolib_ansi_writestr_cb((unsigned char *)str, (size_t)len);
 }
 
 static void ansi_gotoxy_abs(int x, int y)
@@ -775,8 +779,13 @@ static void ansi_keythread(void *params)
 		sem_wait(&need_key);
 		/* If you already have a key, don't get another */
 		sem_getvalue(&got_key,&sval);
-		if((!sval) && fread(&ansi_raw_inch,1,1,stdin)==1)
-			sem_post(&got_key);
+		if(!sval) {
+			ansi_raw_inch=ciolib_ansi_readbyte_cb();
+			if(ansi_raw_inch >= 0)
+				sem_post(&got_key);
+			else
+				SLEEP(1);
+		}
 		else
 			SLEEP(1);
 	}
@@ -858,18 +867,30 @@ void ansi_fixterm(void)
 #define ENABLE_AUTO_POSITION	0x0100
 #endif
 
-#if defined(__BORLANDC__)
-        #pragma argsused
-#endif
-int ansi_initciolib(long inmode)
+/*
+ * Returns -1 if no character read or -2 on abort
+ */
+int ansi_readbyte_cb(void)
 {
-	int i;
-	char *init="\033[s\033[99B\033[99B\033[99B_\033[99C\033[99C\033[99C_\033[6n\033[u\033[0m_\033[2J\033[H";
-	time_t start;
+	unsigned char ch;
 
-	ansi_textmode(1);
-	cio_textinfo.screenheight=24;
-	cio_textinfo.screenwidth=80;
+	if(fread(&ch,1,1,stdin)!=1)
+		return(-1);
+	return(ch);
+}
+
+int ansi_writebyte_cb(unsigned char ch)
+{
+	fwrite(&ch,1,1,stdout);
+}
+
+int ansi_writestr_cb(unsigned char *str, size_t len)
+{
+	fwrite(str,len,1,stdout);
+}
+
+int ansi_initio_cb(void)
+{
 #ifdef _WIN32
 	if(isatty(fileno(stdin))) {
 		if(!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0))
@@ -898,6 +919,21 @@ int ansi_initciolib(long inmode)
 		atexit(ansi_fixterm);
 	}
 #endif
+}
+
+#if defined(__BORLANDC__)
+        #pragma argsused
+#endif
+int ansi_initciolib(long inmode)
+{
+	int i;
+	char *init="\033[s\033[99B\033[99B\033[99B_\033[99C\033[99C\033[99C_\033[6n\033[u\033[0m_\033[2J\033[H";
+	time_t start;
+
+	ansi_textmode(1);
+	cio_textinfo.screenheight=24;
+	cio_textinfo.screenwidth=80;
+	ciolib_ansi_initio_cb();
 
 	sem_init(&got_key,0,0);
 	sem_init(&got_input,0,0);
diff --git a/src/conio/ansi_cio.h b/src/conio/ansi_cio.h
index efb2f5daf11947b51e941c8d20accb70b5d2c135..0b4ff8da906cabece4b8caec2f4fc0117b22db82 100644
--- a/src/conio/ansi_cio.h
+++ b/src/conio/ansi_cio.h
@@ -39,11 +39,21 @@
 #endif
 
 #include "ciolib.h"
-extern int	CIOLIB_ANSI_TIMEOUT;
 
 #ifdef __cplusplus
 extern "C" {
 #endif
+extern int	CIOLIB_ANSI_TIMEOUT;
+extern int  (*ciolib_ansi_readbyte_cb)(void);
+extern int  (*ciolib_ansi_writebyte_cb)(unsigned char ch);
+extern int  (*ciolib_ansi_initio_cb)(void);
+extern int  (*ciolib_ansi_writestr_cb)(unsigned char *str, size_t len);
+
+int ansi_readbyte_cb(void);
+int ansi_writebyte_cb(unsigned char ch);
+int ansi_initio_cb(void);
+int ansi_writestr_cb(unsigned char *str, size_t len);
+
 int ansi_puttext(int sx, int sy, int ex, int ey, void *fill);
 int ansi_gettext(int sx, int sy, int ex, int ey, void *fill);
 void ansi_textattr(int);