diff --git a/src/conio/ansi_cio.c b/src/conio/ansi_cio.c
index 3b0fbdf103dd6b610babc40027a8eada1abf6dbf..09bcbaa86a337df7ee5a00ae6351ae5a6068cbcc 100644
--- a/src/conio/ansi_cio.c
+++ b/src/conio/ansi_cio.c
@@ -56,29 +56,24 @@
 
 int	CIOLIB_ANSI_TIMEOUT=500;
 
-sem_t	got_key;
-sem_t	got_input;
-sem_t	used_input;
-sem_t	goahead;
-sem_t	need_key;
+static sem_t	got_key;
+static sem_t	got_input;
+static sem_t	used_input;
+static sem_t	goahead;
+static sem_t	need_key;
 static BOOL	sent_ga=FALSE;
-WORD	ansi_curr_attr=0x07<<8;
+static int ansix=1;
+static int ansiy=1;
 
-int ansi_rows=-1;
-int ansi_cols=80;
-int ansi_got_row=0;
-int ansi_got_col=0;
-int ansi_esc_delay=25;
-int doorway_enabled=0;
+static int ansi_got_row=0;
+static int ansi_got_col=0;
+static int doorway_enabled=0;
 
-const int 	ansi_tabs[10]={9,17,25,33,41,49,57,65,73,80};
 const int 	ansi_colours[8]={0,4,2,6,1,5,3,7};
 static WORD		ansi_inch;
 static unsigned char		ansi_raw_inch;
-WORD	*ansivmem;
-int		ansi_row=0;
-int		ansi_col=0;
-int		force_move=1;
+static WORD	*ansivmem;
+static int		force_move=1;
 
 /* Control sequence table definitions. */
 typedef struct
@@ -108,7 +103,7 @@ typedef struct
 #define ANSI_KEY_INSERT	0x52<<8
 #define ANSI_KEY_DELETE	0x53<<8
 
-tODKeySequence ODaKeySequences[] =
+static tODKeySequence ODaKeySequences[] =
 {
    /* VT-52 control sequences. */
    {"\033A", ANSI_KEY_UP},
@@ -171,7 +166,7 @@ tODKeySequence ODaKeySequences[] =
 };
 
 #ifdef NEEDS_CFMAKERAW
-void
+static void
 cfmakeraw(struct termios *t)
 {
 	t->c_iflag &= ~(IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
@@ -184,19 +179,19 @@ cfmakeraw(struct termios *t)
 
 /* Do NOT call this to output to the last column of the last row. */
 /* ONLY call this for chars which will move the cursor */
-void ansi_sendch(char ch)
+static void ansi_sendch(char ch)
 {
 	if(!ch)
 		ch=' ';
-	ansi_col++;
-	if(ansi_col>=ansi_cols) {
+	ansix++;
+	if(ansix>cio_textinfo.screenwidth) {
 		/* Column 80 sux0rz */
 		force_move=1;
-		ansi_col=0;
-		ansi_row++;
-		if(ansi_row>=ansi_rows) {
-			ansi_col=ansi_cols-1;
-			ansi_row=ansi_rows-1;
+		ansix=1;
+		ansiy++;
+		if(ansiy>cio_textinfo.screenheight) {
+			ansix=cio_textinfo.screenwidth;
+			ansiy=cio_textinfo.screenheight;
 		}
 	}
 	if(doorway_enabled && ch < ' ')
@@ -207,13 +202,132 @@ void ansi_sendch(char ch)
 		force_move=1;
 }
 
-void ansi_sendstr(char *str,int len)
+static void ansi_sendstr(char *str,int len)
 {
 	if(len==-1)
 		len=strlen(str);
-	if(len) {
+	if(len)
 		fwrite(str,len,1,stdout);
+}
+
+static void ansi_gotoxy_abs(int x, int y)
+{
+	char str[16];
+
+	str[0]=0;
+	if(x < 1
+		|| x > cio_textinfo.screenwidth
+		|| y < 1
+		|| y > cio_textinfo.screenheight)
+		return;
+
+	/* ToDo optimizations: use tabs for horizontal movement to tabstops */
+
+	/* Movement forced... always send position code */
+	if(force_move) {
+		sprintf(str,"\033[%d;%dH",y,x);
+		ansi_sendstr(str,-1);
+		force_move=0;
+		ansiy=y;
+		ansix=x;
+		return;
+	}
+
+	/* Moving to col 1 (and not already there)... use \r */
+	if(x==1 && ansix>1) {
+		ansi_sendstr("\r",1);
+		ansix=1;
+	}
+
+	/* Do we even NEED to move? */
+	if(x==ansix && y==ansiy)
+		return;
+
+	/* If we're already on the correct column */
+	if(x==ansix) {
+		/* Do we need to move up? */
+		if(y<ansiy) {
+			if(y==ansiy-1)
+				/* Only up one */
+				strcpy(str,"\033[A");
+			else
+				sprintf(str,"\033[%dA",ansiy-y);
+			ansi_sendstr(str,-1);
+			ansiy=y;
+			return;
+		}
+
+		/* We must have to move down then. */
+		/* Only one, use a newline */
+		if(y-ansiy < 4)
+			ansi_sendstr("\n\n\n",y-ansiy);
+		else {
+			sprintf(str,"\033[%dB",y-ansiy);
+			ansi_sendstr(str,-1);
+		}
+		ansiy=y;
+		return;
+	}
+
+	/* Ok, we need to change the column then... is the row right though? */
+	if(y==ansiy) {
+		/* Do we need to move left then? */
+		if(x<ansix) {
+			if(x==ansix-1)
+				strcpy(str,"\033[D");
+			else
+				sprintf(str,"\033[%dD",ansix-x);
+			ansi_sendstr(str,-1);
+			ansix=x;
+			return;
+		}
+
+		/* Must need to move right then */
+#if 1
+		/* Check if we can use spaces */
+		if(x-ansix < 5) {
+			int i,j;
+			j=1;
+			/* If all the intervening cells are spaces with the current background, we're good */
+			for(i=0; i<x-ansix; i++) {
+				if((ansivmem[(ansiy-1)*cio_textinfo.screenwidth+ansix-1+i] & 0xff) != ' '/* && (ansivmem[(ansiy-1)*cio_textinfo.screenwidth+ansix-1+i]) & 0xff != 0*/) {
+					j=0;
+					break;
+				}
+				if((ansivmem[(y-1)*cio_textinfo.screenwidth+ansix-1+i] & 0x7000) != ((cio_textinfo.attribute<<8) & 0x7000)) {
+					j=0;
+					break;
+				}
+			}
+			if(j) {
+				ansi_sendstr("    ",x-ansix);
+				ansix=x;
+				return;
+			}
+		}
+#endif
+		if(x==ansix+1)
+			strcpy(str,"\033[C");
+		else
+			sprintf(str,"\033[%dC",x-ansix);
+		ansi_sendstr(str,-1);
+		ansix=x;
+		return;
 	}
+
+	/* Changing the row and the column... better use a fill movement then. */
+	sprintf(str,"\033[%d;%dH",y,x);
+	ansi_sendstr(str,-1);
+	ansiy=y;
+	ansix=x;
+	return;
+}
+
+void ansi_gotoxy(int x, int y)
+{
+	ansi_gotoxy_abs(x+cio_textinfo.winleft-1,y+cio_textinfo.wintop-1);
+	cio_textinfo.curx=x;
+	cio_textinfo.cury=y;
 }
 
 int ansi_puttext(int sx, int sy, int ex, int ey, void* buf)
@@ -242,6 +356,7 @@ int ansi_puttext(int sx, int sy, int ex, int ey, void* buf)
 		return(0);
 
 	/* Check if this actually does anything */
+	/* TODO: This assumes a little-endian system!  Ack! */
 	if(sx==1 && sy==1 && ex==ti.screenwidth && ey==ti.screenheight
 			&& memcmp(buf,ansivmem,ti.screenwidth*ti.screenheight*2)==0)
 		return(1);
@@ -270,8 +385,8 @@ int ansi_puttext(int sx, int sy, int ex, int ey, void* buf)
 		textattr(*(out+1));
 		/* Many terminals make ESC[2J home the cursor */
 		ansi_sendstr("\033[2J\033[1;1H",-1);
-		ansi_col=0;
-		ansi_row=0;
+		ansix=1;
+		ansiy=1;
 		memcpy(ansivmem,out,ti.screenwidth*ti.screenheight*2);
 		i=1;
 	}
@@ -280,12 +395,12 @@ int ansi_puttext(int sx, int sy, int ex, int ey, void* buf)
 	if((!i) && sx==1 && sy==1 && ex==ti.screenwidth && ey==ti.screenheight-1
 			&& memcmp(buf,ansivmem,ti.screenwidth*(ti.screenheight-1)*2)==0) {
 		/* We need to get to the bottom line... */
-		if(ansi_row < ti.screenheight-1) {
-			if(ansi_row > ti.screenheight-5) {
-				ansi_sendstr("\n\n\n\n\n",ti.screenheight-ansi_row-1);
+		if(ansiy < ti.screenheight) {
+			if(ansiy > ti.screenheight-4) {
+				ansi_sendstr("\n\n\n\n\n",ti.screenheight-ansiy-2);
 			}
 			else {
-				sprintf(str,"\033[%dB",ti.screenheight-ansi_row-1);
+				sprintf(str,"\033[%dB",ti.screenheight-ansiy-2);
 				ansi_sendstr(str,-1);
 			}
 		}
@@ -301,13 +416,13 @@ int ansi_puttext(int sx, int sy, int ex, int ey, void* buf)
 	if((!i) && sx==1 && sy==1 && ex==ti.screenwidth && ey==ti.screenheight
 			&& memcmp(buf,ansivmem+ti.screenwidth,ti.screenwidth*(ti.screenheight-1)*2)==0) {
 		/* We need to get to the bottom line... */
-		if(ansi_row < ti.screenheight-1) {
-			if(ansi_row > ti.screenheight-5) {
-				ansi_sendstr("\n\n\n\n\n",ti.screenheight-ansi_row-1);
+		if(ansiy < ti.screenheight) {
+			if(ansiy > ti.screenheight-4) {
+				ansi_sendstr("\n\n\n\n\n",ti.screenheight-ansiy-2);
 			}
 			else {
 				char str[6];
-				sprintf(str,"\033[%dB",ti.screenheight-ansi_row-1);
+				sprintf(str,"\033[%dB",ti.screenheight-ansiy-2);
 				ansi_sendstr(str,-1);
 			}
 		}
@@ -338,21 +453,21 @@ int ansi_puttext(int sx, int sy, int ex, int ey, void* buf)
 					if(out[(cx-x)*2+1] != out[cx*2+1])
 						break;
 					/* Finally, if this isn't what's on screen, increment i */
-					if((ansivmem[y*ansi_cols+cx] & 0xff) != 0 && (ansivmem[y*ansi_cols+cx] & 0xff) != ' ')
+					if((ansivmem[y*cio_textinfo.screenwidth+cx] & 0xff) != 0 && (ansivmem[y*cio_textinfo.screenwidth+cx] & 0xff) != ' ')
 						i++;
-					else if(ansivmem[y*ansi_cols+cx] >> 8 != out[(cx-x)*2+1])
+					else if(ansivmem[y*cio_textinfo.screenwidth+cx] >> 8 != out[(cx-x)*2+1])
 						i++;
 				}
 				if(cx==ti.screenwidth)
 					j=1;
 
 				if(j && i>3) {
-					ansi_gotoxy(x+1,y+1);
+					ansi_gotoxy_abs(x+1,y+1);
 					textattr(*(out+1));
 					ansi_sendstr("\033[K",-1);
 					for(cx=x; cx<ex; cx++) {
-						ansivmem[y*ansi_cols+cx]=*(out++);
-						ansivmem[y*ansi_cols+cx]|=(*(out++))<<8;
+						ansivmem[y*cio_textinfo.screenwidth+cx]=*(out++);
+						ansivmem[y*cio_textinfo.screenwidth+cx]|=(*(out++))<<8;
 					}
 					break;
 				}
@@ -362,11 +477,11 @@ int ansi_puttext(int sx, int sy, int ex, int ey, void* buf)
 				if(sch==0)
 					sch=' ';
 				sch |= (*(out++))<<8;
-				if(ansivmem[y*ansi_cols+x]==sch)
+				if(ansivmem[y*cio_textinfo.screenwidth+x]==sch)
 					continue;
-				ansivmem[y*ansi_cols+x]=sch;
-				ansi_gotoxy(x+1,y+1);
-				if(y>=ansi_rows-1 && x>=ansi_cols-1)
+				ansivmem[y*cio_textinfo.screenwidth+x]=sch;
+				ansi_gotoxy_abs(x+1,y+1);
+				if(y>=cio_textinfo.screenheight-1 && x>=cio_textinfo.screenwidth-1)
 					continue;
 				if(attrib!=sch>>8) {
 					textattr(sch>>8);
@@ -410,7 +525,7 @@ int ansi_gettext(int sx, int sy, int ex, int ey, void* buf)
 	out=fill;
 	for(y=sy-1;y<ey;y++) {
 		for(x=sx-1;x<ex;x++) {
-			sch=ansivmem[y*ansi_cols+x];
+			sch=ansivmem[y*cio_textinfo.screenwidth+x];
 			*(out++)=sch & 0xff;
 			*(out++)=sch >> 8;
 		}
@@ -428,7 +543,7 @@ void ansi_textattr(int attr)
 	int oa;
 
 	str[0]=0;
-	if(ansi_curr_attr==attr<<8)
+	if(cio_textinfo.attribute==attr)
 		return;
 
 	bl=attr&0x80;
@@ -436,13 +551,13 @@ void ansi_textattr(int attr)
 	fg=attr&0x07;
 	br=attr&0x08;
 
-	oa=ansi_curr_attr>>8;
+	oa=cio_textinfo.attribute;
 	obl=oa&0x80;
 	obg=(oa>>4)&0x7;
 	ofg=oa&0x07;
 	obr=oa&0x08;
 
-	ansi_curr_attr=attr<<8;
+	cio_textinfo.attribute=attr;
 
 	strcpy(str,"\033[");
 	if(obl!=bl) {
@@ -482,6 +597,7 @@ void ansi_textattr(int attr)
 		sprintf(str+strlen(str),"4%d;",ansi_colours[bg]);
 	str[strlen(str)-1]='m';
 	ansi_sendstr(str,-1);
+	cio_textinfo.attribute=attr;
 }
 
 #if defined(__BORLANDC__)
@@ -501,7 +617,7 @@ static void ansi_keyparse(void *par)
 
 	seq[0]=0;
 	for(;;) {
-		if(ansi_rows != -1)
+		if(ansi_got_row)
 			sem_wait(&goahead);
 		if(timedout || unknown) {
 			for(p=seq;*p;p++) {
@@ -579,8 +695,10 @@ static void ansi_keyparse(void *par)
 						if(strspn(seq,"\033[0123456789;R")==strlen(seq)) {
 							p=seq+2;
 							i=strtol(p,&p,10);
-							if(i>ansi_rows)
-								ansi_rows=i;
+							if(i>cio_textinfo.screenheight) {
+								cio_textinfo.screenheight=i;
+								ansi_got_row=i;
+							}
 						}
 						unknown=0;
 					}
@@ -656,219 +774,6 @@ int ansi_kbhit(void)
 	return(sval);
 }
 
-void ansi_delay(long msec)
-{
-	SLEEP(msec);
-}
-
-int ansi_wherey(void)
-{
-	return(ansi_row+1);
-}
-
-int ansi_wherex(void)
-{
-	return(ansi_col+1);
-}
-
-/* Put the character _c on the screen at the current cursor position. 
- * The special characters return, linefeed, bell, and backspace are handled
- * properly, as is line wrap and scrolling. The cursor position is updated. 
- */
-int ansi_putch(int ch)
-{
-	struct text_info ti;
-	int i;
-	unsigned char buf[2];
-
-	buf[0]=ch;
-	buf[1]=ansi_curr_attr>>8;
-
-	gettextinfo(&ti);
-	puttext_can_move=1;
-
-	switch(ch) {
-		case '\r':
-			gotoxy(1,wherey());
-			break;
-		case '\n':
-			if(wherey()==ti.winbottom-ti.wintop+1)
-				wscroll();
-			else
-				gotoxy(wherex(),wherey()+1);
-			break;
-		case '\b':
-			if(ansi_col>ti.winleft-1) {
-				buf[0]=' ';
-				gotoxy(wherex()-1,wherey());
-				puttext(ansi_col+1,ansi_row+1,ansi_col+1,ansi_row+1,buf);
-			}
-			break;
-		case 7:		/* Bell */
-			ansi_sendstr("\007",1);
-			break;
-		case '\t':
-			for(i=0;i<10;i++) {
-				if(ansi_tabs[i]>ansi_col+1) {
-					while(ansi_col+1<ansi_tabs[i]) {
-						putch(' ');
-					}
-					break;
-				}
-			}
-			if(i==10) {
-				putch('\r');
-				putch('\n');
-			}
-			break;
-		default:
-			if(wherey()==ti.winbottom-ti.wintop+1
-					&& wherex()==ti.winright-ti.winleft+1) {
-				gotoxy(1,wherey());
-				puttext(ansi_col+1,ansi_row+1,ansi_col+1,ansi_row+1,buf);
-				wscroll();
-			}
-			else {
-				if(wherex()==ti.winright-ti.winleft+1) {
-					gotoxy(1,ti.cury+1);
-					puttext(ansi_col+1,ansi_row+1,ansi_col+1,ansi_row+1,buf);
-				}
-				else {
-					puttext(ansi_col+1,ansi_row+1,ansi_col+1,ansi_row+1,buf);
-					gotoxy(ti.curx+1,ti.cury);
-				}
-			}
-			break;
-	}
-
-	puttext_can_move=0;
-	return(ch);
-}
-
-void ansi_gotoxy(int x, int y)
-{
-	char str[16];
-
-	str[0]=0;
-	if(x < 1
-		|| x > ansi_cols
-		|| y < 1
-		|| y > ansi_rows)
-		return;
-
-	/* ToDo optimizations: use tabs for horizontal movement to tabstops */
-
-	/* Movement forced... always send position code */
-	if(force_move) {
-		sprintf(str,"\033[%d;%dH",y,x);
-		ansi_sendstr(str,-1);
-		force_move=0;
-		ansi_row=y-1;
-		ansi_col=x-1;
-		return;
-	}
-
-	/* Moving to col 1 (and not already there)... use \r */
-	if(x==1 && ansi_col) {
-		ansi_sendstr("\r",1);
-		ansi_col=0;
-	}
-
-	/* Do we even NEED to move? */
-	if(x==ansi_col+1 && y==ansi_row+1)
-		return;
-
-	/* If we're already on the correct column */
-	if(x==ansi_col+1) {
-		/* Do we need to move up? */
-		if(y<ansi_row+1) {
-			if(y==ansi_row)
-				/* Only up one */
-				strcpy(str,"\033[A");
-			else
-				sprintf(str,"\033[%dA",ansi_row+1-y);
-			ansi_sendstr(str,-1);
-			ansi_row=y-1;
-			return;
-		}
-
-		/* We must have to move down then. */
-		/* Only one, use a newline */
-		if(y==ansi_row+2)
-			strcpy(str,"\n");
-		else
-			sprintf(str,"\033[%dB",y-ansi_row-1);
-		ansi_sendstr(str,-1);
-		ansi_row=y-1;
-		return;
-	}
-
-	/* Ok, we need to change the column then... is the row right though? */
-	if(y==ansi_row+1) {
-		/* Do we need to move left then? */
-		if(x<ansi_col+1) {
-			if(x==ansi_col)
-				strcpy(str,"\033[D");
-			else
-				sprintf(str,"\033[%dD",ansi_col+1-x);
-			ansi_sendstr(str,-1);
-			ansi_col=x-1;
-			return;
-		}
-
-		/* Must need to move right then */
-#if 1
-		/* Check if we can use spaces */
-		/* ansi_col... 0-based current position */
-		/* x... 1-based desired position */
-		if(x-ansi_col-1 < 5) {
-			int i,j;
-			j=1;
-			/* If all the intervening cells are spaces with the current background, we're good */
-			for(i=0; i<x-ansi_col-1; i++) {
-				if((ansivmem[y*ansi_cols+ansi_col+i] & 0xff) != ' ' && (ansivmem[y*ansi_cols+ansi_col+i]) & 0xff != 0) {
-					j=0;
-					break;
-				}
-				if((ansivmem[y*ansi_cols+ansi_col+i] & 0x7000) != (ansi_curr_attr & 0x7000)) {
-					j=0;
-					break;
-				}
-			}
-			if(j) {
-				ansi_sendstr("    ",x-ansi_col-1);
-				ansi_col=x-1;
-				return;
-			}
-		}
-#endif
-		if(x==ansi_col+2)
-			strcpy(str,"\033[C");
-		else
-			sprintf(str,"\033[%dC",x-ansi_col-1);
-		ansi_sendstr(str,-1);
-		ansi_col=x-1;
-		return;
-	}
-
-	/* Changing the row and the column... better use a fill movement then. */
-	sprintf(str,"\033[%d;%dH",y,x);
-	ansi_sendstr(str,-1);
-	ansi_row=y-1;
-	ansi_col=x-1;
-	return;
-}
-
-void ansi_gettextinfo(struct text_info *info)
-{
-	info->currmode=3;
-	info->screenheight=ansi_rows;
-	info->screenwidth=ansi_cols;
-	info->curx=ansi_wherex();
-	info->cury=ansi_wherey();
-	info->attribute=ansi_curr_attr>>8;
-}
-
 void ansi_setcursortype(int type)
 {
 	switch(type) {
@@ -895,19 +800,9 @@ int ansi_getch(void)
 	return(ch);
 }
 
-int ansi_getche(void)
-{
-	int ch;
-
-	ch=ansi_getch();
-	if(ch)
-		putch(ch);
-	return(ch);
-}
-
 int ansi_beep(void)
 {
-	putch(7);
+	ansi_sendstr("\7",1);
 	return(0);
 }
 
@@ -916,6 +811,18 @@ int ansi_beep(void)
 #endif
 void ansi_textmode(int mode)
 {
+	cio_textinfo.screenwidth=80;
+	cio_textinfo.winleft=1;
+	cio_textinfo.wintop=1;
+	cio_textinfo.winright=cio_textinfo.screenwidth;
+	cio_textinfo.winbottom=cio_textinfo.screenheight;
+	cio_textinfo.attribute=7;
+	cio_textinfo.normattr=7;
+	cio_textinfo.currmode=COLOR_MODE;
+	cio_textinfo.curx=1;
+	cio_textinfo.cury=1;
+	ansix=1;
+	ansiy=1;
 }
 
 #ifdef __unix__
@@ -941,6 +848,9 @@ int ansi_initciolib(long inmode)
 	char *init="\033[s\033[99B_\033[6n\033[u\033[0m_\033[2J\033[H";
 	time_t start;
 
+	ansi_textmode(1);
+	cio_textinfo.screenheight=24;
+	cio_textinfo.screenwidth=80;
 #ifdef _WIN32
 	if(isatty(fileno(stdin))) {
 		if(!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0))
@@ -979,12 +889,14 @@ int ansi_initciolib(long inmode)
 	ansi_sendstr(init,-1);
 	_beginthread(ansi_keythread,1024,NULL);
 	start=time(NULL);
-	while(time(NULL)-start < 5 && ansi_rows==-1)
+	while(time(NULL)-start < 5 && !ansi_got_row)
 		SLEEP(1);
-	if(ansi_rows==-1)
-		ansi_rows=24;
-	ansivmem=(WORD *)malloc(ansi_rows*ansi_cols*sizeof(WORD));
-	for(i=0;i<ansi_rows*ansi_cols;i++)
+	if(!ansi_got_row) {
+		cio_textinfo.screenheight=24;
+		ansi_got_row=24;
+	}
+	ansivmem=(WORD *)malloc(cio_textinfo.screenheight*cio_textinfo.screenwidth*sizeof(WORD));
+	for(i=0;i<cio_textinfo.screenheight*cio_textinfo.screenwidth;i++)
 		ansivmem[i]=0x0720;
 	/* drain all the semaphores */
 	sem_reset(&got_key);
diff --git a/src/conio/ciolib.c b/src/conio/ciolib.c
index a1bf0fdac628e5bd85a6f85a1aa0c3e362e9cd92..e61e06f351f47b398ab9917d92845f071a6ee0c0 100644
--- a/src/conio/ciolib.c
+++ b/src/conio/ciolib.c
@@ -44,6 +44,8 @@
 #endif
 
 #include <threadwrap.h>
+#include <genwrap.h>
+#include <xpbeep.h>
 
 #define CIOLIB_NO_MACROS
 #include "ciolib.h"
@@ -65,8 +67,9 @@
 
 CIOLIBEXPORT cioapi_t	cio_api;
 
+static const int tabs[10]={9,17,25,33,41,49,57,65,73,80};
 static int ungotch;
-static struct text_info cio_textinfo;
+struct text_info cio_textinfo;
 static int lastmode=3;
 CIOLIBEXPORT int _wscroll=1;
 CIOLIBEXPORT int directvideo=0;
@@ -119,17 +122,10 @@ int try_sdl_init(int mode)
 		cio_api.mouse=1;
 		cio_api.puttext=sdl_puttext;
 		cio_api.gettext=sdl_gettext;
-		cio_api.textattr=sdl_textattr;
 		cio_api.kbhit=sdl_kbhit;
-		cio_api.delay=sdl_delay;
-		cio_api.wherey=sdl_wherey;
-		cio_api.wherex=sdl_wherex;
-		cio_api.putch=sdl_putch;
 		cio_api.gotoxy=sdl_gotoxy;
-		cio_api.gettextinfo=sdl_gettextinfo;
 		cio_api.setcursortype=sdl_setcursortype;
 		cio_api.getch=sdl_getch;
-		cio_api.getche=sdl_getche;
 		cio_api.textmode=sdl_textmode;
 		cio_api.showmouse=sdl_showmouse;
 		cio_api.hidemouse=sdl_hidemouse;
@@ -162,25 +158,19 @@ int try_x_init(int mode)
 		cio_api.mouse=1;
 		cio_api.puttext=x_puttext;
 		cio_api.gettext=x_gettext;
-		cio_api.textattr=x_textattr;
-		cio_api.kbhit=x_kbhit;
-		cio_api.delay=x_delay;
-		cio_api.wherey=x_wherey;
-		cio_api.wherex=x_wherex;
-		cio_api.putch=x_putch;
 		cio_api.gotoxy=x_gotoxy;
-		cio_api.gettextinfo=x_gettextinfo;
 		cio_api.setcursortype=x_setcursortype;
+		cio_api.setfont=x_setfont;
+		cio_api.getfont=x_getfont;
+		cio_api.loadfont=x_loadfont;
+
+		cio_api.kbhit=x_kbhit;
 		cio_api.getch=x_getch;
-		cio_api.getche=x_getche;
 		cio_api.textmode=x_textmode;
 		cio_api.setname=x_setname;
 		cio_api.settitle=x_settitle;
 		cio_api.copytext=x_copytext;
 		cio_api.getcliptext=x_getcliptext;
-		cio_api.setfont=x_setfont;
-		cio_api.getfont=x_getfont;
-		cio_api.loadfont=x_loadfont;
 		cio_api.get_window_info=x_get_window_info;
 		return(1);
 	}
@@ -196,20 +186,15 @@ int try_curses_init(int mode)
 		cio_api.gettext=curs_gettext;
 		cio_api.textattr=curs_textattr;
 		cio_api.kbhit=curs_kbhit;
-		cio_api.delay=curs_delay;
-		cio_api.wherey=curs_wherey;
-		cio_api.wherex=curs_wherex;
-		cio_api.putch=curs_putch;
 		cio_api.gotoxy=curs_gotoxy;
-		cio_api.gettextinfo=curs_gettextinfo;
 		cio_api.setcursortype=curs_setcursortype;
 		cio_api.getch=curs_getch;
-		cio_api.getche=curs_getche;
 		cio_api.textmode=curs_textmode;
 		cio_api.showmouse=curs_showmouse;
 		cio_api.hidemouse=curs_hidemouse;
 		cio_api.suspend=curs_suspend;
 		cio_api.resume=curs_resume;
+		cio_api.beep=curs_beep;
 #if defined(NCURSES_VERSION_MAJOR) || defined (__NetBSD__)
 		cio_api.ESCDELAY=&ESCDELAY;
 #endif
@@ -228,15 +213,9 @@ int try_ansi_init(int mode)
 		cio_api.gettext=ansi_gettext;
 		cio_api.textattr=ansi_textattr;
 		cio_api.kbhit=ansi_kbhit;
-		cio_api.delay=ansi_delay;
-		cio_api.wherey=ansi_wherey;
-		cio_api.wherex=ansi_wherex;
-		cio_api.putch=ansi_putch;
 		cio_api.gotoxy=ansi_gotoxy;
-		cio_api.gettextinfo=ansi_gettextinfo;
 		cio_api.setcursortype=ansi_setcursortype;
 		cio_api.getch=ansi_getch;
-		cio_api.getche=ansi_getche;
 		cio_api.textmode=ansi_textmode;
 		cio_api.ESCDELAY=&CIOLIB_ANSI_TIMEOUT;
 		return(1);
@@ -256,17 +235,10 @@ int try_conio_init(int mode)
 		cio_api.mouse=1;
 		cio_api.puttext=win32_puttext;
 		cio_api.gettext=win32_gettext;
-		cio_api.textattr=win32_textattr;
 		cio_api.kbhit=win32_kbhit;
-		cio_api.delay=win32_delay;
-		cio_api.wherey=win32_wherey;
-		cio_api.wherex=win32_wherex;
-		cio_api.putch=win32_putch;
 		cio_api.gotoxy=win32_gotoxy;
-		cio_api.gettextinfo=win32_gettextinfo;
 		cio_api.setcursortype=win32_setcursortype;
 		cio_api.getch=win32_getch;
-		cio_api.getche=win32_getche;
 		cio_api.textmode=win32_textmode;
 		cio_api.showmouse=win32_showmouse;
 		cio_api.hidemouse=win32_hidemouse;
@@ -282,6 +254,7 @@ int try_conio_init(int mode)
 }
 #endif
 
+/* Optional */
 CIOLIBEXPORT void CIOLIBCALL suspendciolib(void)
 {
 	ciolib_clrscr();
@@ -353,7 +326,6 @@ CIOLIBEXPORT int CIOLIBCALL initciolib(int mode)
 	}
 
 	initialized=1;
-	ciolib_gettextinfo(&cio_textinfo);
 	cio_textinfo.winleft=1;
 	cio_textinfo.wintop=1;
 	cio_textinfo.winright=cio_textinfo.screenwidth;
@@ -372,6 +344,7 @@ CIOLIBEXPORT int CIOLIBCALL initciolib(int mode)
 	return(0);
 }
 
+/* **MUST** be implemented */
 CIOLIBEXPORT int CIOLIBCALL ciolib_kbhit(void)
 {
 	CIOLIB_INIT();
@@ -380,6 +353,7 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_kbhit(void)
 	return(cio_api.kbhit());
 }
 
+/* **MUST** be implemented */
 CIOLIBEXPORT int CIOLIBCALL ciolib_getch(void)
 {
 	int ch;
@@ -394,6 +368,7 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_getch(void)
 	return(cio_api.getch());
 }
 
+/* Optional */
 CIOLIBEXPORT int CIOLIBCALL ciolib_getche(void)
 {
 	int ch;
@@ -406,19 +381,35 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_getche(void)
 		ciolib_putch(ch);
 		return(ch);
 	}
-	return(cio_api.getche());
+	if(cio_api.getche())
+		return(cio_api.getche());
+	else {
+		while(1) {
+			ch=ciolib_getch();
+			if(ch) {
+				ciolib_putch(ch);
+				return(ch);
+			}
+			/* Eat extended chars */
+			ciolib_getch();
+		}
+	}
 }
 
+/* Optional */
 CIOLIBEXPORT int CIOLIBCALL ciolib_ungetch(int ch)
 {
 	CIOLIB_INIT();
-	
+
 	if(ungotch)
 		return(EOF);
+	if(cio_api.ungetch)
+		return(cio_api.ungetch(ch));
 	ungotch=ch;
 	return(ch);
 }
 
+/* Optional */
 CIOLIBEXPORT int CIOLIBCALL ciolib_movetext(int sx, int sy, int ex, int ey, int dx, int dy)
 {
 	int width;
@@ -442,6 +433,7 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_movetext(int sx, int sy, int ex, int ey, int
 	return(1);
 }
 
+/* Optional */
 CIOLIBEXPORT char * CIOLIBCALL ciolib_cgets(char *str)
 {
 	int	maxlen;
@@ -450,6 +442,9 @@ CIOLIBEXPORT char * CIOLIBCALL ciolib_cgets(char *str)
 
 	CIOLIB_INIT();
 
+	if(cio_api.cgets)
+		return(cio_api.cgets(str));
+
 	maxlen=*(unsigned char *)str;
 	while((ch=ciolib_getch())!='\n' && ch !='\r') {
 		switch(ch) {
@@ -519,6 +514,7 @@ int vsscanf( const char *buffer, const char *format, va_list arg_ptr )
 }
 #endif
 
+/* Optional... in fact, since it's varargs, you can't override it */
 CIOLIBEXPORT int CIOLIBCALL ciolib_cscanf (char *format , ...)
 {
 	char str[255];
@@ -526,7 +522,7 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_cscanf (char *format , ...)
 	int ret;
 
 	CIOLIB_INIT();
-	
+
 	str[0]=-1;
 	va_start(argptr,format);
 	ret=vsscanf(ciolib_cgets(str),format,argptr);
@@ -534,6 +530,7 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_cscanf (char *format , ...)
 	return(ret);
 }
 
+/* Optional */
 CIOLIBEXPORT char * CIOLIBCALL ciolib_getpass(const char *prompt)
 {
 	static char pass[9];
@@ -541,7 +538,10 @@ CIOLIBEXPORT char * CIOLIBCALL ciolib_getpass(const char *prompt)
 	int ch;
 
 	CIOLIB_INIT();
-	
+
+	if(cio_api.getpass)
+		return(cio_api.getpass(prompt));
+
 	ciolib_cputs((char *)prompt);
 	while((ch=ciolib_getch())!='\n') {
 		switch(ch) {
@@ -569,13 +569,18 @@ CIOLIBEXPORT char * CIOLIBCALL ciolib_getpass(const char *prompt)
 	return(pass);
 }
 
+/* TODO: Hackery here... must fix */
+/* Optional */
 CIOLIBEXPORT void CIOLIBCALL ciolib_gettextinfo(struct text_info *info)
 {
-	if(!initialized)
-		initciolib(CIOLIB_MODE_AUTO);
-	else {
+
+	CIOLIB_INIT()
+
+	if(cio_api.gettextinfo) {
 		cio_api.gettextinfo(&cio_textinfo);
+		return;
 	}
+	
 	if(info!=&cio_textinfo) {
 		info->winleft=cio_textinfo.winleft;        /* left window coordinate */
 		info->wintop=cio_textinfo.wintop;         /* top window coordinate */
@@ -592,10 +597,10 @@ CIOLIBEXPORT void CIOLIBCALL ciolib_gettextinfo(struct text_info *info)
 	}
 }
 
+/* Optional */
 CIOLIBEXPORT void CIOLIBCALL ciolib_wscroll(void)
 {
 	int os;
-	struct text_info ti;
 
 	CIOLIB_INIT();
 
@@ -603,75 +608,86 @@ CIOLIBEXPORT void CIOLIBCALL ciolib_wscroll(void)
 		cio_api.wscroll();
 		return;
 	}
-	ciolib_gettextinfo(&ti);
 	if(!_wscroll)
 		return;
-	ciolib_movetext(ti.winleft,ti.wintop+1,ti.winright,ti.winbottom,ti.winleft,ti.wintop);
-	ciolib_gotoxy(1,ti.winbottom-ti.wintop+1);
+	ciolib_movetext(cio_textinfo.winleft
+			,cio_textinfo.wintop+1
+			,cio_textinfo.winright
+			,cio_textinfo.winbottom
+			,cio_textinfo.winleft
+			,cio_textinfo.wintop);
+	ciolib_gotoxy(1,cio_textinfo.winbottom-cio_textinfo.wintop+1);
 	os=_wscroll;
 	_wscroll=0;
 	/* ciolib_cprintf("%*s",ti.winright-ti.winleft+1,""); */
 	ciolib_clreol();
 	_wscroll=os;
-	ciolib_gotoxy(ti.curx,ti.cury);
+	ciolib_gotoxy(cio_textinfo.curx,cio_textinfo.cury);
 }
 
+/* Optional */
 CIOLIBEXPORT int CIOLIBCALL ciolib_wherex(void)
 {
 	int x;
 
 	CIOLIB_INIT();
-	
-	x=cio_api.wherex();
-	x=x-cio_textinfo.winleft+1;
+
+	if(cio_api.wherex) {
+		/* TODO: This is old hackery... beware */
+		x=cio_api.wherex();
+		x=x-cio_textinfo.winleft+1;
+	}
+	else
+		x=cio_textinfo.curx;
 	return(x);
 }
 
+/* Optional */
 CIOLIBEXPORT int CIOLIBCALL ciolib_wherey(void)
 {
 	int y;
 
 	CIOLIB_INIT();
-	
-	y=cio_api.wherey();
-	y=y-cio_textinfo.wintop+1;
+
+	if(cio_api.wherey) {
+		/* TODO: This is old hackery... beware */
+		y=cio_api.wherey();
+		y=y-cio_textinfo.wintop+1;
+	}
+	else
+		y=cio_textinfo.cury;
 	return(y);
 }
 
+/* **MUST** be implemented */
 CIOLIBEXPORT void CIOLIBCALL ciolib_gotoxy(int x, int y)
 {
 	int nx;
 	int ny;
-	struct text_info ti;
 
 	CIOLIB_INIT();
-	
-	ciolib_gettextinfo(&ti);
+
 	if(		x < 1
-			|| x > ti.winright-ti.winleft+1
+			|| x > cio_textinfo.winright-cio_textinfo.winleft+1
 			|| y < 1
-			|| y > ti.winbottom-ti.wintop+1)
+			|| y > cio_textinfo.winbottom-cio_textinfo.wintop+1)
 		return;
-	nx=x+ti.winleft-1;
-	ny=y+ti.wintop-1;
-	cio_api.gotoxy(nx,ny);
+	cio_api.gotoxy(x,y);
 }
 
+/* **MUST** be implemented */
 CIOLIBEXPORT void CIOLIBCALL ciolib_textmode(int mode)
 {
 	CIOLIB_INIT();
-	
+
 	if(mode==-1) {
-		ciolib_gettextinfo(&cio_textinfo);
 		cio_api.textmode(lastmode);
 		lastmode=cio_textinfo.currmode;
 	}
 	else {
-		ciolib_gettextinfo(&cio_textinfo);
 		lastmode=cio_textinfo.currmode;
 		cio_api.textmode(mode);
 	}
-	ciolib_gettextinfo(&cio_textinfo);
 	cio_textinfo.winleft=1;
 	cio_textinfo.wintop=1;
 	cio_textinfo.winright=cio_textinfo.screenwidth;
@@ -687,11 +703,14 @@ CIOLIBEXPORT void CIOLIBCALL ciolib_textmode(int mode)
 	}
 }
 
+/* Optional */
 CIOLIBEXPORT void CIOLIBCALL ciolib_window(int sx, int sy, int ex, int ey)
 {
 	CIOLIB_INIT();
-	
-	ciolib_gettextinfo(&cio_textinfo);
+
+	if(cio_api.window)
+		cio_api.window(sx,sy,ex,ey);
+
 	if(		   sx < 1
 			|| sy < 1
 			|| ex < 1
@@ -710,6 +729,7 @@ CIOLIBEXPORT void CIOLIBCALL ciolib_window(int sx, int sy, int ex, int ey)
 	ciolib_gotoxy(1,1);
 }
 
+/* Optional */
 CIOLIBEXPORT void CIOLIBCALL ciolib_clreol(void)
 {
 	unsigned char *buf;
@@ -719,71 +739,89 @@ CIOLIBEXPORT void CIOLIBCALL ciolib_clreol(void)
 
 	CIOLIB_INIT();
 	
-	ciolib_gettextinfo(&ti);
+	if(cio_api.clreol) {
+		cio_api.clreol();
+		return;
+	}
 
-	width=ti.winright-ti.winleft+1-ti.curx+1;
+	width=cio_textinfo.winright-cio_textinfo.winleft+1-cio_textinfo.curx+1;
 	height=1;
 	buf=(unsigned char *)alloca(width*height*2);
 	for(i=0;i<width*height*2;) {
 		buf[i++]=' ';
-		buf[i++]=ti.attribute;
+		buf[i++]=cio_textinfo.attribute;
 	}
-	ciolib_puttext(ti.curx+ti.winleft-1,ti.cury+ti.wintop-1,ti.winright,ti.cury+ti.wintop-1,buf);
+	ciolib_puttext(
+			cio_textinfo.curx+cio_textinfo.winleft-1,
+			cio_textinfo.cury+cio_textinfo.wintop-1,
+			cio_textinfo.winright,
+			cio_textinfo.cury+cio_textinfo.wintop-1,
+			buf);
 }
 
+/* Optional */
 CIOLIBEXPORT void CIOLIBCALL ciolib_clrscr(void)
 {
 	unsigned char *buf;
 	int i;
 	int width,height;
-	struct text_info ti;
 	int old_ptcm=puttext_can_move;
 
 	CIOLIB_INIT();
+	if(cio_api.clrscr) {
+		cio_api.clrscr();
+		return;
+	}
 	
-	ciolib_gettextinfo(&ti);
-
-	width=ti.winright-ti.winleft+1;
-	height=ti.winbottom-ti.wintop+1;
+	width=cio_textinfo.winright-cio_textinfo.winleft+1;
+	height=cio_textinfo.winbottom-cio_textinfo.wintop+1;
 	buf=(unsigned char *)alloca(width*height*2);
 	for(i=0;i<width*height*2;) {
 		buf[i++]=' ';
-		buf[i++]=ti.attribute;
+		buf[i++]=cio_textinfo.attribute;
 	}
 	puttext_can_move=1;
-	ciolib_puttext(ti.winleft,ti.wintop,ti.winright,ti.winbottom,buf);
+	ciolib_puttext(cio_textinfo.winleft,cio_textinfo.wintop,cio_textinfo.winright,cio_textinfo.winbottom,buf);
 	ciolib_gotoxy(1,1);
-	puttext_can_move=old_ptcm;;
+	puttext_can_move=old_ptcm;
 }
 
+/* Optional */
 CIOLIBEXPORT void CIOLIBCALL ciolib_delline(void)
 {
-	struct text_info ti;
-
 	CIOLIB_INIT();
-	
-	ciolib_gettextinfo(&ti);
 
-	ciolib_movetext(ti.winleft,ti.cury+1,ti.winright,ti.winbottom,ti.winleft,ti.cury);
-	ciolib_gotoxy(1,ti.winbottom-ti.wintop+1);
+	if(cio_api.delline) {
+		cio_api.delline();
+		return;
+	}
+	ciolib_movetext(cio_textinfo.winleft
+			,cio_textinfo.cury+1
+			,cio_textinfo.winright
+			,cio_textinfo.winbottom
+			,cio_textinfo.winleft
+			,cio_textinfo.cury);
+	ciolib_gotoxy(1,cio_textinfo.winbottom-cio_textinfo.wintop+1);
 	ciolib_clreol();
-	ciolib_gotoxy(ti.curx,ti.cury);
+	ciolib_gotoxy(cio_textinfo.curx,cio_textinfo.cury);
 }
 
+/* Optional */
 CIOLIBEXPORT void CIOLIBCALL ciolib_insline(void)
 {
-	struct text_info ti;
-
 	CIOLIB_INIT();
-	
-	ciolib_gettextinfo(&ti);
 
-	ciolib_movetext(ti.winleft,ti.cury,ti.winright,ti.winbottom,ti.winleft,ti.cury+1);
-	ciolib_gotoxy(1,ti.cury);
+	if(cio_api.insline) {
+		cio_api.insline();
+		return;
+	}
+	ciolib_movetext(cio_textinfo.winleft,cio_textinfo.cury,cio_textinfo.winright,cio_textinfo.winbottom,cio_textinfo.winleft,cio_textinfo.cury+1);
+	ciolib_gotoxy(1,cio_textinfo.cury);
 	ciolib_clreol();
-	ciolib_gotoxy(ti.curx,ti.cury);
+	ciolib_gotoxy(cio_textinfo.curx,cio_textinfo.cury);
 }
 
+/* Not overridable due to varargs */
 CIOLIBEXPORT int CIOLIBCALL ciolib_cprintf(char *fmat, ...)
 {
     va_list argptr;
@@ -826,6 +864,7 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_cprintf(char *fmat, ...)
     return(ret);
 }
 
+/* Optional */
 CIOLIBEXPORT int CIOLIBCALL ciolib_cputs(char *str)
 {
 	int		pos;
@@ -834,6 +873,9 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_cputs(char *str)
 
 	CIOLIB_INIT();
 
+	if(cio_api.cputs)
+		return(cio_api.cputs(str));
+
 	olddmc=hold_update;
 	hold_update=1;
 	for(pos=0;str[pos];pos++)
@@ -848,14 +890,19 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_cputs(char *str)
 	return(ret);
 }
 
+/* Optional... and overriding is silly */
 CIOLIBEXPORT void CIOLIBCALL ciolib_textbackground(int colour)
 {
 	unsigned char attr;
 	unsigned char col;
 
 	CIOLIB_INIT();
-	
-	ciolib_gettextinfo(&cio_textinfo);
+
+	if(cio_api.textbackground) {
+		cio_api.textbackground(colour);
+		return;
+	}
+
 	attr=cio_textinfo.attribute;
 	attr&=143;
 	col=(colour & 0x07);
@@ -863,14 +910,19 @@ CIOLIBEXPORT void CIOLIBCALL ciolib_textbackground(int colour)
 	ciolib_textattr(attr);
 }
 
+/* Optional... and overriding is silly */
 CIOLIBEXPORT void CIOLIBCALL ciolib_textcolor(int colour)
 {
 	unsigned char attr;
 	unsigned char col;
 
 	CIOLIB_INIT();
-	
-	ciolib_gettextinfo(&cio_textinfo);
+
+	if(cio_api.textcolor) {
+		cio_api.textcolor(colour);
+		return;
+	}
+
 	attr=cio_textinfo.attribute;
 	attr&=240;
 	col=colour&0x0f;
@@ -878,37 +930,53 @@ CIOLIBEXPORT void CIOLIBCALL ciolib_textcolor(int colour)
 	ciolib_textattr(attr);
 }
 
+/* Optional... and overriding is silly */
 CIOLIBEXPORT void CIOLIBCALL ciolib_highvideo(void)
 {
 	int attr;
 
 	CIOLIB_INIT();
-	
-	ciolib_gettextinfo(&cio_textinfo);
+
+	if(cio_api.highvideo) {
+		cio_api.highvideo();
+		return;
+	}
+
 	attr=cio_textinfo.attribute;
 	attr |= 8;
 	ciolib_textattr(attr);
 }
 
+/* Optional... and overriding is silly */
 CIOLIBEXPORT void CIOLIBCALL ciolib_lowvideo(void)
 {
 	int attr;
 
 	CIOLIB_INIT();
-	
-	ciolib_gettextinfo(&cio_textinfo);
+
+	if(cio_api.lowvideo) {
+		cio_api.lowvideo();
+		return;
+	}
+
 	attr=cio_textinfo.attribute;
 	attr &= 0xf7;
 	ciolib_textattr(attr);
 }
 
+/* Optional... and overriding is silly */
 CIOLIBEXPORT void CIOLIBCALL ciolib_normvideo(void)
 {
 	CIOLIB_INIT();
 	
-	ciolib_textattr(0x07);
+	if(cio_api.normvideo) {
+		cio_api.normvideo();
+		return;
+	}
+	ciolib_textattr(cio_textinfo.normattr);
 }
 
+/* **MUST** be implemented */
 CIOLIBEXPORT int CIOLIBCALL ciolib_puttext(int a,int b,int c,int d,unsigned char *e)
 {
 	CIOLIB_INIT();
@@ -916,6 +984,7 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_puttext(int a,int b,int c,int d,unsigned char
 	return(cio_api.puttext(a,b,c,d,e));
 }
 
+/* **MUST** be implemented */
 CIOLIBEXPORT int CIOLIBCALL ciolib_gettext(int a,int b,int c,int d,unsigned char *e)
 {
 	CIOLIB_INIT();
@@ -923,30 +992,134 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_gettext(int a,int b,int c,int d,unsigned char
 	return(cio_api.gettext(a,b,c,d,e));
 }
 
+/* Optional */
 CIOLIBEXPORT void CIOLIBCALL ciolib_textattr(int a)
 {
 	CIOLIB_INIT();
-	
-	cio_api.textattr(a);
+
+	if(cio_api.textattr) {
+		cio_api.textattr(a);
+		return;
+	}
+
+	cio_textinfo.attribute=a;
 }
 
+/* Optional */
 CIOLIBEXPORT void CIOLIBCALL ciolib_delay(long a)
 {
 	CIOLIB_INIT();
-	
-	cio_api.delay(a);
+
+	if(cio_api.delay) {
+		cio_api.delay(a);
+		return;
+	}
+	SLEEP(a);
 }
 
+/* Optional */
 CIOLIBEXPORT int CIOLIBCALL ciolib_putch(int a)
 {
 	unsigned char a1=a;
+	unsigned char buf[2];
+	int i;
 	CIOLIB_INIT();
+	int old_puttext_can_move=puttext_can_move;
 
-	if(a1=='\n')
+	if(cio_api.putch)
 		return(cio_api.putch(a1));
-	return(cio_api.putch(a1));
+
+	puttext_can_move=1;
+
+	buf[0]=a1;
+	buf[1]=cio_textinfo.attribute;
+
+	switch(a1) {
+		case '\r':
+			ciolib_gotoxy(1,cio_textinfo.cury);
+			break;
+		case '\n':
+			if(cio_textinfo.cury==cio_textinfo.winbottom-cio_textinfo.wintop+1)
+				ciolib_wscroll();
+			else
+				ciolib_gotoxy(cio_textinfo.curx, cio_textinfo.cury+1);
+			break;
+		case '\b':
+			if(cio_textinfo.curx>1) {
+				ciolib_gotoxy(cio_textinfo.curx-1,cio_textinfo.cury);
+				buf[0]=' ';
+				ciolib_puttext(cio_textinfo.curx+cio_textinfo.winleft-1
+						,cio_textinfo.cury+cio_textinfo.wintop-1
+						,cio_textinfo.curx+cio_textinfo.winleft-1
+						,cio_textinfo.cury+cio_textinfo.wintop-1
+						,buf);
+			}
+			break;
+		case 7:		/* Bell */
+			ciolib_beep();
+			break;
+		case '\t':
+			for(i=0;i<10;i++) {
+				if(tabs[i]>cio_textinfo.curx) {
+					buf[0]=' ';
+					while(cio_textinfo.curx<tabs[i]) {
+						ciolib_puttext(cio_textinfo.curx+cio_textinfo.winleft-1
+								,cio_textinfo.cury+cio_textinfo.wintop-1
+								,cio_textinfo.curx+cio_textinfo.winleft-1
+								,cio_textinfo.cury+cio_textinfo.wintop-1
+								,buf);
+						ciolib_gotoxy(cio_textinfo.curx+1,cio_textinfo.cury);
+					}
+					break;
+				}
+			}
+			if(i==10) {
+				ciolib_gotoxy(1,cio_textinfo.cury);
+				if(cio_textinfo.cury==cio_textinfo.winbottom-cio_textinfo.wintop+1)
+					ciolib_wscroll();
+				else
+					ciolib_gotoxy(cio_textinfo.curx, cio_textinfo.cury+1);
+			}
+			break;
+		default:
+			if(cio_textinfo.cury==cio_textinfo.winbottom-cio_textinfo.wintop+1
+					&& cio_textinfo.curx==cio_textinfo.winright-cio_textinfo.winleft+1) {
+				ciolib_puttext(ciolib_wherex()+cio_textinfo.winleft-1
+						,ciolib_wherey()+cio_textinfo.wintop-1
+						,ciolib_wherex()+cio_textinfo.winleft-1
+						,ciolib_wherey()+cio_textinfo.wintop-1
+						,buf);
+				ciolib_wscroll();
+				ciolib_gotoxy(1, cio_textinfo.winbottom-cio_textinfo.wintop+1);
+			}
+			else {
+				if(cio_textinfo.curx==cio_textinfo.winright-cio_textinfo.winleft+1) {
+					ciolib_puttext(ciolib_wherex()+cio_textinfo.winleft-1
+							,ciolib_wherey()+cio_textinfo.wintop-1
+							,ciolib_wherex()+cio_textinfo.winleft-1
+							,ciolib_wherey()+cio_textinfo.wintop-1
+							,buf);
+					ciolib_gotoxy(1,cio_textinfo.cury+1);
+				}
+				else {
+					ciolib_puttext(ciolib_wherex()+cio_textinfo.winleft-1
+							,ciolib_wherey()+cio_textinfo.wintop-1
+							,ciolib_wherex()+cio_textinfo.winleft-1
+							,ciolib_wherey()+cio_textinfo.wintop-1
+							,buf);
+					ciolib_gotoxy(cio_textinfo.curx+1, cio_textinfo.cury);
+				}
+			}
+			break;
+	}
+
+	puttext_can_move=old_puttext_can_move;
+
+	return(a1);
+	
 }
 
+/* **MUST** be implemented */
 CIOLIBEXPORT void CIOLIBCALL ciolib_setcursortype(int a)
 {
 	CIOLIB_INIT();
@@ -954,6 +1127,7 @@ CIOLIBEXPORT void CIOLIBCALL ciolib_setcursortype(int a)
 	cio_api.setcursortype(a);
 }
 
+/* Optional */
 CIOLIBEXPORT int CIOLIBCALL ciolib_showmouse(void) {
 	CIOLIB_INIT();
 
@@ -962,6 +1136,7 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_showmouse(void) {
 	return(-1);
 }
 
+/* Optional */
 CIOLIBEXPORT int CIOLIBCALL ciolib_hidemouse(void) {
 	CIOLIB_INIT();
 
@@ -970,6 +1145,7 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_hidemouse(void) {
 	return(-1);
 }
 
+/* Optional */
 CIOLIBEXPORT void CIOLIBCALL ciolib_setname(const char *name) {
 	CIOLIB_INIT();
 
@@ -977,6 +1153,7 @@ CIOLIBEXPORT void CIOLIBCALL ciolib_setname(const char *name) {
 		cio_api.setname(name);
 }
 
+/* Optional */
 CIOLIBEXPORT void CIOLIBCALL ciolib_seticon(const void *icon, unsigned long size) {
 	CIOLIB_INIT();
 
@@ -984,6 +1161,7 @@ CIOLIBEXPORT void CIOLIBCALL ciolib_seticon(const void *icon, unsigned long size
 		cio_api.seticon(icon,size);
 }
 
+/* Optional */
 CIOLIBEXPORT void CIOLIBCALL ciolib_settitle(const char *title) {
 	CIOLIB_INIT();
 
@@ -991,6 +1169,7 @@ CIOLIBEXPORT void CIOLIBCALL ciolib_settitle(const char *title) {
 		cio_api.settitle(title);
 }
 
+/* Optional */
 CIOLIBEXPORT void CIOLIBCALL ciolib_copytext(const char *text, size_t buflen)
 {
 	CIOLIB_INIT();
@@ -999,6 +1178,7 @@ CIOLIBEXPORT void CIOLIBCALL ciolib_copytext(const char *text, size_t buflen)
 		cio_api.copytext(text,buflen);
 }
 
+/* Optional */
 CIOLIBEXPORT char * CIOLIBCALL ciolib_getcliptext(void)
 {
 	CIOLIB_INIT();
@@ -1009,6 +1189,7 @@ CIOLIBEXPORT char * CIOLIBCALL ciolib_getcliptext(void)
 		return(NULL);
 }
 
+/* Optional */
 CIOLIBEXPORT int CIOLIBCALL ciolib_setfont(int font, int force)
 {
 	CIOLIB_INIT();
@@ -1019,6 +1200,7 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_setfont(int font, int force)
 		return(-1);
 }
 
+/* Optional */
 CIOLIBEXPORT int CIOLIBCALL ciolib_getfont(void)
 {
 	CIOLIB_INIT();
@@ -1029,6 +1211,7 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_getfont(void)
 		return(-1);
 }
 
+/* Optional */
 CIOLIBEXPORT int CIOLIBCALL ciolib_loadfont(char *filename)
 {
 	CIOLIB_INIT();
@@ -1039,6 +1222,7 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_loadfont(char *filename)
 		return(-1);
 }
 
+/* Optional */
 CIOLIBEXPORT int CIOLIBCALL ciolib_get_window_info(int *width, int *height, int *xpos, int *ypos)
 {
 	CIOLIB_INIT();
@@ -1057,3 +1241,12 @@ CIOLIBEXPORT int CIOLIBCALL ciolib_get_window_info(int *width, int *height, int
 	}
 	return(-1);
 }
+
+/* Optional */
+CIOLIBEXPORT int ciolib_beep(void)
+{
+	if(cio_api.beep)
+		return(cio_api.beep());
+	BEEP(440,100);
+	return(0);
+}
diff --git a/src/conio/ciolib.h b/src/conio/ciolib.h
index 284c34c5b3f6762de120e42e473fc2ae23ad5a4a..9d4bd7fb9fb1d27d2368551b7ba82d090c0aa645 100644
--- a/src/conio/ciolib.h
+++ b/src/conio/ciolib.h
@@ -200,6 +200,8 @@ struct text_info {
 	unsigned char cury;           /* y-coordinate in current window */
 };
 
+extern struct text_info cio_textinfo;
+
 typedef struct {
 	int		mode;
 	int		mouse;
diff --git a/src/conio/console.c b/src/conio/console.c
index df3579f6afe451b9eee6b0b98ec7905d24a7e069..bf40528f970d6fda278c3d976835978a6b204ca2 100644
--- a/src/conio/console.c
+++ b/src/conio/console.c
@@ -1561,6 +1561,19 @@ init_mode(int mode)
 
 	CurrMode=mode;
 	console_new_mode=NO_NEW_MODE;
+
+	cio_textinfo.attribute=7;
+	cio_textinfo.normattr=7;
+	cio_textinfo.currmode=mode;
+	cio_textinfo.screenheight=DpyRows+1;
+	cio_textinfo.screenwidth=DpyCols;
+	cio_textinfo.curx=1;
+	cio_textinfo.cury=1;
+	cio_textinfo.winleft=1;
+	cio_textinfo.wintop=1;
+	cio_textinfo.winright=cio_textinfo.screenwidth;
+	cio_textinfo.winbottom=cio_textinfo.screenheight;
+
 	sem_post(&console_mode_changed);
     return(0);
 }
@@ -1794,6 +1807,7 @@ console_init()
 
 	_beginthread(video_async_event,1<<16,NULL);
 	_beginthread(mouse_event,1<<16,NULL);
+
 	return(0);
 }
 
diff --git a/src/conio/curs_cio.c b/src/conio/curs_cio.c
index d153bf1f47e797385143b31798605b1d8be015ca..ed0d2a06321a2c77aa4156f76c9302bc81ac6461 100644
--- a/src/conio/curs_cio.c
+++ b/src/conio/curs_cio.c
@@ -53,12 +53,11 @@
 #include "vidmodes.h"
 
 static unsigned char curs_nextgetch=0;
-const int curs_tabs[10]={9,17,25,33,41,49,57,65,73,80};
 
 static int lastattr=0;
 static long mode;
 
-short curses_color(short color)
+static short curses_color(short color)
 {
 	switch(color)
 	{
@@ -98,6 +97,180 @@ short curses_color(short color)
 	return(0);
 }
 
+static int _putch(unsigned char ch, BOOL refresh_now)
+{
+	int		ret;
+	chtype	cha;
+
+	if(!(mode==CIOLIB_MODE_CURSES_IBM))
+	{
+		switch(ch)
+		{
+			case 30:
+				cha=ACS_UARROW;
+				break;
+			case 31:
+				cha=ACS_DARROW;
+				break;
+			case 176:
+				cha=ACS_CKBOARD;
+				break;
+			case 177:
+				cha=ACS_BOARD;
+				break;
+			case 178:
+				cha=ACS_BOARD;
+				break;
+			case 179:
+				cha=ACS_SBSB;
+				break;
+			case 180:
+				cha=ACS_SBSS;
+				break;
+			case 181:
+				cha=ACS_SBSD;
+				break;
+			case 182:
+				cha=ACS_DBDS;
+				break;
+			case 183:
+				cha=ACS_BBDS;
+				break;
+			case 184:
+				cha=ACS_BBSD;
+				break;
+			case 185:
+				cha=ACS_DBDD;
+				break;
+			case 186:
+				cha=ACS_DBDB;
+				break;
+			case 187:
+				cha=ACS_BBDD;
+				break;
+			case 188:
+				cha=ACS_DBBD;
+				break;
+			case 189:
+				cha=ACS_DBBS;
+				break;
+			case 190:
+				cha=ACS_SBBD;
+				break;
+			case 191:
+				cha=ACS_BBSS;
+				break;
+			case 192:
+				cha=ACS_SSBB;
+				break;
+			case 193:
+				cha=ACS_SSBS;
+				break;
+			case 194:
+				cha=ACS_BSSS;
+				break;
+			case 195:
+				cha=ACS_SSSB;
+				break;
+			case 196:
+				cha=ACS_BSBS;
+				break;
+			case 197:
+				cha=ACS_SSSS;
+				break;
+			case 198:
+				cha=ACS_SDSB;
+				break;
+			case 199:
+				cha=ACS_DSDB;
+				break;
+			case 200:
+				cha=ACS_DDBB;
+				break;
+			case 201:
+				cha=ACS_BDDB;
+				break;
+			case 202:
+				cha=ACS_DDBD;
+				break;
+			case 203:
+				cha=ACS_BDDD;
+				break;
+			case 204:
+				cha=ACS_DDDB;
+				break;
+			case 205:
+				cha=ACS_BDBD;
+				break;
+			case 206:
+				cha=ACS_DDDD;
+				break;
+			case 207:
+				cha=ACS_SDBD;
+				break;
+			case 208:
+				cha=ACS_DSBS;
+				break;
+			case 209:
+				cha=ACS_BDSD;
+				break;
+			case 210:
+				cha=ACS_BSDS;
+				break;
+			case 211:
+				cha=ACS_DSBB;
+				break;
+			case 212:
+				cha=ACS_SDBB;
+				break;
+			case 213:
+				cha=ACS_BDSB;
+				break;
+			case 214:
+				cha=ACS_BSDB;
+				break;
+			case 215:
+				cha=ACS_DSDS;
+				break;
+			case 216:
+				cha=ACS_SDSD;
+				break;
+			case 217:
+				cha=ACS_SBBS;
+				break;
+			case 218:
+				cha=ACS_BSSB;
+				break;
+			case 219:
+				cha=ACS_BLOCK;
+				break;
+			default:
+				cha=ch;
+		}
+	}
+	else
+		cha=ch;
+
+	if(!cha)
+		cha=' ';
+	if(cha == ' ')
+		ret=addch(A_BOLD|' ');
+	else if (cha<' ') {
+ 		attron(A_REVERSE);
+		ret=addch(cha+'A'-1);
+		attroff(A_REVERSE);
+	}
+	else
+		ret=addch(cha);
+
+	if(!hold_update) {
+		if(refresh_now)
+			refresh();
+	}
+
+	return(ret);
+}
+
 int curs_puttext(int sx, int sy, int ex, int ey, void *fillbuf)
 {
 	int x,y;
@@ -106,30 +279,28 @@ int curs_puttext(int sx, int sy, int ex, int ey, void *fillbuf)
 	unsigned char fill_char;
 	unsigned char orig_attr;
 	int oldx, oldy;
-	struct text_info	ti;
 	unsigned char *fill;
 
 	fill=fillbuf;
-	gettextinfo(&ti);
 
 	if(		   sx < 1
 			|| sy < 1
 			|| ex < 1
 			|| ey < 1
-			|| sx > ti.screenwidth
-			|| sy > ti.screenheight
+			|| sx > cio_textinfo.screenwidth
+			|| sy > cio_textinfo.screenheight
 			|| sx > ex
 			|| sy > ey
-			|| ex > ti.screenwidth
-			|| ey > ti.screenheight
+			|| ex > cio_textinfo.screenwidth
+			|| ey > cio_textinfo.screenheight
 			|| fill==NULL)
 		return(0);
 
 	getyx(stdscr,oldy,oldx);
 	orig_attr=lastattr;
-	for(y=sy-1;y<=ey-1;y++)
+	for(y=sy-1;y<ey;y++)
 	{
-		for(x=sx-1;x<=ex-1;x++)
+		for(x=sx-1;x<ex;x++)
 		{
 			fill_char=fill[fillpos++];
 			attr=fill[fillpos++];
@@ -436,6 +607,8 @@ void curs_textattr(int attr)
 #endif
 	/* bkgdset(colour); */
 	bkgdset(colour);
+
+	cio_textinfo.attribute=attr;
 }
 
 int curs_kbhit(void)
@@ -455,204 +628,18 @@ int curs_kbhit(void)
 	return(select(fileno(stdin)+1,&rfds,NULL,NULL,&timeout));
 }
 
-void curs_delay(long msec)
-{
-	usleep(msec*1000);
-}
-
-int curs_wherey(void)
-{
-	int x,y;
-	getyx(stdscr,y,x);
-	return(y+1);
-}
-
-int curs_wherex(void)
-{
-	int x,y;
-	getyx(stdscr,y,x);
-	return(x+1);
-}
-
-int _putch(unsigned char ch, BOOL refresh_now)
-{
-	int		ret;
-	chtype	cha;
-
-	if(!(mode==CIOLIB_MODE_CURSES_IBM))
-	{
-		switch(ch)
-		{
-			case 30:
-				cha=ACS_UARROW;
-				break;
-			case 31:
-				cha=ACS_DARROW;
-				break;
-			case 176:
-				cha=ACS_CKBOARD;
-				break;
-			case 177:
-				cha=ACS_BOARD;
-				break;
-			case 178:
-				cha=ACS_BOARD;
-				break;
-			case 179:
-				cha=ACS_SBSB;
-				break;
-			case 180:
-				cha=ACS_SBSS;
-				break;
-			case 181:
-				cha=ACS_SBSD;
-				break;
-			case 182:
-				cha=ACS_DBDS;
-				break;
-			case 183:
-				cha=ACS_BBDS;
-				break;
-			case 184:
-				cha=ACS_BBSD;
-				break;
-			case 185:
-				cha=ACS_DBDD;
-				break;
-			case 186:
-				cha=ACS_DBDB;
-				break;
-			case 187:
-				cha=ACS_BBDD;
-				break;
-			case 188:
-				cha=ACS_DBBD;
-				break;
-			case 189:
-				cha=ACS_DBBS;
-				break;
-			case 190:
-				cha=ACS_SBBD;
-				break;
-			case 191:
-				cha=ACS_BBSS;
-				break;
-			case 192:
-				cha=ACS_SSBB;
-				break;
-			case 193:
-				cha=ACS_SSBS;
-				break;
-			case 194:
-				cha=ACS_BSSS;
-				break;
-			case 195:
-				cha=ACS_SSSB;
-				break;
-			case 196:
-				cha=ACS_BSBS;
-				break;
-			case 197:
-				cha=ACS_SSSS;
-				break;
-			case 198:
-				cha=ACS_SDSB;
-				break;
-			case 199:
-				cha=ACS_DSDB;
-				break;
-			case 200:
-				cha=ACS_DDBB;
-				break;
-			case 201:
-				cha=ACS_BDDB;
-				break;
-			case 202:
-				cha=ACS_DDBD;
-				break;
-			case 203:
-				cha=ACS_BDDD;
-				break;
-			case 204:
-				cha=ACS_DDDB;
-				break;
-			case 205:
-				cha=ACS_BDBD;
-				break;
-			case 206:
-				cha=ACS_DDDD;
-				break;
-			case 207:
-				cha=ACS_SDBD;
-				break;
-			case 208:
-				cha=ACS_DSBS;
-				break;
-			case 209:
-				cha=ACS_BDSD;
-				break;
-			case 210:
-				cha=ACS_BSDS;
-				break;
-			case 211:
-				cha=ACS_DSBB;
-				break;
-			case 212:
-				cha=ACS_SDBB;
-				break;
-			case 213:
-				cha=ACS_BDSB;
-				break;
-			case 214:
-				cha=ACS_BSDB;
-				break;
-			case 215:
-				cha=ACS_DSDS;
-				break;
-			case 216:
-				cha=ACS_SDSD;
-				break;
-			case 217:
-				cha=ACS_SBBS;
-				break;
-			case 218:
-				cha=ACS_BSSB;
-				break;
-			case 219:
-				cha=ACS_BLOCK;
-				break;
-			default:
-				cha=ch;
-		}
-	}
-	else
-		cha=ch;
-
-	if(!cha)
-		cha=' ';
-	if(cha == ' ')
-		ret=addch(A_BOLD|' ');
-	else if (cha<' ') {
- 		attron(A_REVERSE);
-		ret=addch(cha+'A'-1);
-		attroff(A_REVERSE);
-	}
-	else
-		ret=addch(cha);
-
-	if(!hold_update) {
-		if(refresh_now)
-			refresh();
-	}
-
-	return(ret);
-}
-
 void curs_gotoxy(int x, int y)
 {
-	move(y-1,x-1);
+	int absx,absy;
+	absx=x+cio_textinfo.winleft-1;
+	absy=y+cio_textinfo.wintop-1;
+
+	move(absy-1,absx-1);
 	if(!hold_update)
 		refresh();
+
+	cio_textinfo.curx=x;
+	cio_textinfo.cury=y;
 }
 
 void curs_suspend(void)
@@ -715,19 +702,9 @@ int curs_initciolib(long inmode)
 		else
 			mousemask(0,NULL);
 #endif
-	return(1);
-}
 
-void curs_gettextinfo(struct text_info *info)
-{
-	getmaxyx(stdscr, info->screenheight, info->screenwidth);
-	if(has_colors())
-		info->currmode=COLOR_MODE;
-	else
-		info->currmode=MONO;
-	info->curx=curs_wherex();
-	info->cury=curs_wherey();
-	info->attribute=lastattr;
+	curs_textmode(0);
+	return(1);
 }
 
 void curs_setcursortype(int type) {
@@ -735,11 +712,11 @@ void curs_setcursortype(int type) {
 		case _NOCURSOR:
 			curs_set(0);
 			break;
-		
+
 		case _SOLIDCURSOR:
 			curs_set(2);
 			break;
-		
+
 		default:	/* Normal cursor */
 			curs_set(1);
 			break;
@@ -749,144 +726,6 @@ void curs_setcursortype(int type) {
 		refresh();
 }
 
-int curs_putch(int ch)
-{
-#if 0
-	struct text_info ti;
-	int		ret;
-	int		i;
-
-	ret=c;
-	switch(c) {
-		case '\r':
-			gotoxy(1,wherey());
-			break;
-		case '\n':
-			gettextinfo(&ti);
-			if(wherey()==ti.winbottom-ti.wintop+1) {
-				wscroll();
-			}
-			else {
-				gotoxy(wherex(),wherey()+1);
-			}
-			break;
-		case 0x07:
-			beep();
-			break;
-		case 0x08:
-			gotoxy(wherex()-1,wherey());
-			_putch(' ',FALSE);
-			gotoxy(wherex()-1,wherey());
-			break;
-		case '\t':
-			for(i=0;i<10;i++) {
-				if(curs_tabs[i]>wherex()) {
-					while(wherex()<curs_tabs[i]) {
-						putch(' ');
-					}
-					break;
-				}
-			}
-			if(i==10) {
-				putch('\r');
-				putch('\n');
-			}
-			break;
-		default:
-			gettextinfo(&ti);
-			if(wherey()==ti.winbottom-ti.wintop+1
-					&& wherex()==ti.winright-ti.winleft+1) {
-				if(_putch(c,TRUE)==ERR)
-					ret=EOF;
-				else {
-					wscroll();
-					gotoxy(ti.winleft,ti.cury);
-				}
-			}
-			else {
-				if(wherex()==ti.winright-ti.winleft+1) {
-					if(_putch(c,TRUE)==ERR)
-						ret=EOF;
-					else
-						gotoxy(ti.winleft,ti.cury+1);
-				}
-				else {
-					if(_putch(c,TRUE)==ERR)
-						ret=EOF;
-					else
-						gotoxy(ti.curx+1,ti.cury);
-				}
-			}
-			break;
-	}
-#else
-	struct text_info ti;
-	unsigned char buf[2];
-	int i;
-
-	buf[0]=ch;
-	buf[1]=lastattr;
-
-	switch(ch) {
-		case '\r':
-			gotoxy(1,wherey());
-			break;
-		case '\n':
-			gettextinfo(&ti);
-			if(ti.cury==ti.winbottom-ti.wintop+1)
-				wscroll();
-			else
-				gotoxy(ti.curx,ti.cury+1);
-			break;
-		case '\b':
-			gettextinfo(&ti);
-			if(ti.curx>1) {
-				buf[0]=' ';
-				gotoxy(ti.curx-1,ti.cury);
-				puttext(ti.winleft+ti.curx-2, ti.wintop+ti.cury-1,ti.winleft+ti.curx-2, ti.wintop+ti.cury-1,buf);
-			}
-			break;
-		case 7:		/* Bell */
-			beep();
-			break;
-		case '\t':
-			for(i=0;i<10;i++) {
-				if(curs_tabs[i]>wherex()) {
-					while(wherex()<curs_tabs[i]) {
-						putch(' ');
-					}
-					break;
-				}
-			}
-			if(i==10) {
-				putch('\r');
-				putch('\n');
-			}
-			break;
-		default:
-			gettextinfo(&ti);
-			if(ti.cury==ti.winbottom-ti.wintop+1
-					&& ti.curx==ti.winright-ti.winleft+1) {
-				puttext(ti.winleft+ti.curx-1, ti.wintop+ti.cury-1,ti.winleft+ti.curx-1, ti.wintop+ti.cury-1,buf);
-				wscroll();
-				gotoxy(1,ti.cury);
-			}
-			else {
-				if(ti.curx==ti.winright-ti.winleft+1) {
-					puttext(ti.winleft+ti.curx-1, ti.wintop+ti.cury-1,ti.winleft+ti.curx-1, ti.wintop+ti.cury-1,buf);
-					gotoxy(1,ti.cury+1);
-				}
-				else {
-					puttext(ti.winleft+ti.curx-1, ti.wintop+ti.cury-1,ti.winleft+ti.curx-1, ti.wintop+ti.cury-1,buf);
-					gotoxy(ti.curx+1,ti.cury);
-				}
-			}
-			break;
-	}
-	return(ch);
-#endif
-}
-
 int curs_getch(void)
 {
 	int ch;
@@ -1113,20 +952,23 @@ int curs_getch(void)
 	return(ch);
 }
 
-int curs_getche(void)
+void curs_textmode(int mode)
 {
-	int ch;
+	getmaxyx(stdscr, cio_textinfo.screenheight, cio_textinfo.screenwidth);
+	if(has_colors())
+		cio_textinfo.currmode=COLOR_MODE;
+	else
+		cio_textinfo.currmode=MONO;
 
-	if(curs_nextgetch)
-		return(curs_getch());
-	ch=curs_getch();
-	if(ch)
-		putch(ch);
-	return(ch);
-}
+	cio_textinfo.winleft=1;
+	cio_textinfo.wintop=1;
+	cio_textinfo.winright=cio_textinfo.screenwidth;
+	cio_textinfo.winbottom=cio_textinfo.screenheight;
+	cio_textinfo.attribute=7;
+	cio_textinfo.normattr=7;
+	cio_textinfo.curx=1;
+	cio_textinfo.cury=1;
 
-void curs_textmode(int mode)
-{
 	return;
 }
 
@@ -1154,3 +996,8 @@ int curs_showmouse(void)
 */
 	return(-1);
 }
+
+int curs_beep(void)
+{
+	return(beep());
+}
diff --git a/src/conio/curs_cio.h b/src/conio/curs_cio.h
index 2ebea63258edd7e7c3e1b6248e6a14dfff8304ad..beb67f5043f42fbd803619b984e845fca59439ec 100644
--- a/src/conio/curs_cio.h
+++ b/src/conio/curs_cio.h
@@ -49,27 +49,20 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
-short curses_color(short color);
 int curs_puttext(int sx, int sy, int ex, int ey, void *fill);
 int curs_gettext(int sx, int sy, int ex, int ey, void *fill);
 void curs_textattr(int attr);
 int curs_kbhit(void);
-void curs_delay(long msec);
-int curs_wherey(void);
-int curs_wherex(void);
-int _putch(unsigned char ch, BOOL refresh_now);
-int curs_putch(int ch);
 void curs_gotoxy(int x, int y);
+void curs_suspend(void);
+void curs_resume(void);
 int curs_initciolib(long inmode);
-void curs_gettextinfo(struct text_info *info);
 void curs_setcursortype(int type);
 int curs_getch(void);
-int curs_getche(void);
 void curs_textmode(int mode);
-int curs_showmouse(void);
 int curs_hidemouse(void);
-void curs_suspend(void);
-void curs_resume(void);
+int curs_showmouse(void);
+int curs_beep(void);
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/conio/sdl_con.c b/src/conio/sdl_con.c
index a31f21f3433a65a05a7a1ee5713bd28e4cc7636a..9c2c318ba56d498f526ff912f3b7f04d11a50e00 100644
--- a/src/conio/sdl_con.c
+++ b/src/conio/sdl_con.c
@@ -199,8 +199,6 @@ const struct sdl_keyvals sdl_keyval[] =
 	{SDLK_BACKQUOTE, '`', '~', 0, 0x2900},
 	{0, 0, 0, 0, 0}	/** END **/
 };
-const int sdl_tabs[10]={9,17,25,33,41,49,57,65,73,80};
-
 /* *nix copy/paste stuff */
 SDL_sem	*sdl_pastebuf_set;
 SDL_sem	*sdl_pastebuf_copied;
@@ -498,6 +496,18 @@ int sdl_init_mode(int mode)
 	    vstat.vmem[i] = 0x0700;
 	vstat.currattr=7;
 
+	cio_textinfo.attribute=7;
+	cio_textinfo.normattr=7;
+	cio_textinfo.currmode=mode;
+	cio_textinfo.screenheight=vstat.rows;
+	cio_textinfo.screenwidth=vstat.cols;
+	cio_textinfo.curx=1;
+	cio_textinfo.cury=1;
+	cio_textinfo.winleft=1;
+	cio_textinfo.wintop=1;
+	cio_textinfo.winright=cio_textinfo.screenwidth;
+	cio_textinfo.winbottom=cio_textinfo.screenheight;
+
 	vstat.mode=mode;
 	sdl.mutexV(sdl_vstatlock);
 
@@ -676,12 +686,6 @@ int sdl_gettext(int sx, int sy, int ex, int ey, void *fill)
 	return(1);
 }
 
-/* Called from main thread only */
-void sdl_textattr(int attr)
-{
-	vstat.currattr=attr;
-}
-
 /* Called from main thread only */
 int sdl_kbhit(void)
 {
@@ -693,105 +697,6 @@ int sdl_kbhit(void)
 	return(ret);
 }
 
-/* Called from main thread only */
-void sdl_delay(long msec)
-{
-	SLEEP(msec);
-}
-
-/* Called from main thread only */
-int sdl_wherey(void)
-{
-	return(vstat.curs_row+1);
-}
-
-/* Called from main thread only */
-int sdl_wherex(void)
-{
-	return(vstat.curs_col+1);
-}
-
-/* Called from BOTH THREADS */
-int sdl_beep(void)
-{
-	/* ToDo BEEP! */
-	BEEP(440,100);
-	return(0);
-}
-
-/* Put the character _c on the screen at the current cursor position. 
- * The special characters return, linefeed, bell, and backspace are handled
- * properly, as is line wrap and scrolling. The cursor position is updated. 
- */
-/* Called from main thread only */
-int sdl_putch(int ch)
-{
-	struct text_info ti;
-	WORD sch;
-	int i;
-
-	sdl.mutexP(sdl_vstatlock);
-	sch=(vstat.currattr<<8)|ch;
-
-	switch(ch) {
-		case '\r':
-			gettextinfo(&ti);
-			vstat.curs_col=ti.winleft-1;
-			break;
-		case '\n':
-			gettextinfo(&ti);
-			if(wherey()==ti.winbottom-ti.wintop+1)
-				wscroll();
-			else
-				vstat.curs_row++;
-			break;
-		case '\b':
-			if(vstat.curs_col>0)
-				vstat.curs_col--;
-			sdl_draw_char((vstat.currattr<<8)|' ',vstat.curs_col,vstat.curs_row,TRUE);
-			break;
-		case 7:		/* Bell */
-			sdl_beep();
-			break;
-		case '\t':
-			for(i=0;i<10;i++) {
-				if(sdl_tabs[i]>wherex()) {
-					while(wherex()<sdl_tabs[i]) {
-						putch(' ');
-					}
-					break;
-				}
-			}
-			if(i==10) {
-				putch('\r');
-				putch('\n');
-			}
-			break;
-		default:
-			gettextinfo(&ti);
-			if(wherey()==ti.winbottom-ti.wintop+1
-					&& wherex()==ti.winright-ti.winleft+1) {
-				sdl_draw_char(sch,vstat.curs_col,vstat.curs_row,TRUE);
-				wscroll();
-				gotoxy(ti.winleft,wherey());
-			}
-			else {
-				if(wherex()==ti.winright-ti.winleft+1) {
-					sdl_draw_char(sch,vstat.curs_col,vstat.curs_row,TRUE);
-					gotoxy(ti.winleft,ti.cury+1);
-				}
-				else {
-					sdl_draw_char(sch,vstat.curs_col,vstat.curs_row,TRUE);
-					gotoxy(ti.curx+1,ti.cury);
-				}
-			}
-			break;
-	}
-	sdl.mutexV(sdl_vstatlock);
-
-	return(ch);
-}
-
 /* Called from main thread only */
 void sdl_gotoxy(int x, int y)
 {
@@ -801,19 +706,8 @@ void sdl_gotoxy(int x, int y)
 		vstat.curs_col=x-1;
 		sdl_user_func(SDL_USEREVENT_UPDATERECT,0,0,0,0);
 	}
-	sdl.mutexV(sdl_vstatlock);
-}
-
-/* Called from main thread only */
-void sdl_gettextinfo(struct text_info *info)
-{
-	sdl.mutexP(sdl_vstatlock);
-	info->currmode=vstat.mode;
-	info->screenheight=vstat.rows;
-	info->screenwidth=vstat.cols;
-	info->curx=sdl_wherex();
-	info->cury=sdl_wherey();
-	info->attribute=vstat.currattr;
+	cio_textinfo.curx=x;
+	cio_textinfo.cury=y;
 	sdl.mutexV(sdl_vstatlock);
 }
 
@@ -857,21 +751,6 @@ int sdl_getch(void)
 	return(ch);
 }
 
-/* Called from main thread only */
-int sdl_getche(void)
-{
-	int ch;
-
-	while(1) {
-		ch=sdl_getch();
-		if(ch) {
-			putch(ch);
-			return(ch);
-		}
-		sdl_getch();
-	}
-}
-
 /* Called from main thread only */
 void sdl_textmode(int mode)
 {
@@ -1001,7 +880,7 @@ void sdl_add_key(unsigned int keyval)
 	if(keyval <= 0xffff) {
 		sdl.mutexP(sdl_keylock);
 		if(sdl_keynext+1==sdl_key) {
-			sdl_beep();
+			beep();
 			sdl.mutexV(sdl_keylock);
 			return;
 		}
@@ -1009,7 +888,7 @@ void sdl_add_key(unsigned int keyval)
 			if(keyval==CIO_KEY_MOUSE)
 				sdl_pending_mousekeys++;
 			else
-				sdl_beep();
+				beep();
 			sdl.mutexV(sdl_keylock);
 			return;
 		}
diff --git a/src/conio/sdl_con.h b/src/conio/sdl_con.h
index 2edefc2c62bf0528b306e6337546d7385a94ed32..3e0dd7c355ed1d1b043b7661017cfcf9b60ce273 100644
--- a/src/conio/sdl_con.h
+++ b/src/conio/sdl_con.h
@@ -15,19 +15,12 @@ int sdl_screen_redraw(void);
 /* High-level stuff */
 int sdl_puttext(int sx, int sy, int ex, int ey, void *fill);
 int sdl_gettext(int sx, int sy, int ex, int ey, void *fill);
-void sdl_textattr(int attr);
 int sdl_kbhit(void);
 void sdl_delay(long msec);
-int sdl_wherey(void);
-int sdl_wherex(void);
-int sdl_putch(int ch);
 void sdl_gotoxy(int x, int y);
 int sdl_initciolib(long inmode);
-void sdl_gettextinfo(struct text_info *info);
 void sdl_setcursortype(int type);
 int sdl_getch(void);
-int sdl_getche(void);
-int sdl_beep(void);
 void sdl_textmode(int mode);
 void sdl_setname(const char *name);
 void sdl_seticon(const void *, unsigned long size);
diff --git a/src/conio/win32cio.c b/src/conio/win32cio.c
index d63693c946d568daa9f749e95590db80df30c9cd..c8adc0009ebcb3489ea1fcbab82f8b82cd16afb8 100644
--- a/src/conio/win32cio.c
+++ b/src/conio/win32cio.c
@@ -50,8 +50,6 @@
 #include "vidmodes.h"
 #include "win32cio.h"
 
-const int 	cio_tabs[10]={9,17,25,33,41,49,57,65,73,80};
-
 struct keyvals {
 	int	VirtualKeyCode
 		,Key
@@ -154,13 +152,11 @@ const struct keyvals keyval[] =
 	{0, 0, 0, 0, 0}	/** END **/
 };
 
+/* Mouse related stuff */
 static int domouse=1;
 static DWORD last_state=0;
 static int LastX=-1, LastY=-1;
-static int xpos=1;
-static int ypos=1;
 
-static int currattr=7;
 static int modeidx=3;
 
 #if defined(_DEBUG)
@@ -187,7 +183,7 @@ static void dprintf(const char* fmt, ...)
 #endif /* _DEBUG */
 }
 
-WORD DOStoWinAttr(int newattr)
+static WORD DOStoWinAttr(int newattr)
 {
 	WORD ret=0;
 
@@ -210,7 +206,7 @@ WORD DOStoWinAttr(int newattr)
 	return(ret);
 }
 
-unsigned char WintoDOSAttr(WORD newattr)
+static unsigned char WintoDOSAttr(WORD newattr)
 {
 	unsigned char ret=0;
 
@@ -233,7 +229,7 @@ unsigned char WintoDOSAttr(WORD newattr)
 	return(ret);
 }
 
-int win32_getchcode(WORD code, DWORD state)
+static int win32_getchcode(WORD code, DWORD state)
 {
 	int i;
 
@@ -257,7 +253,7 @@ int win32_getchcode(WORD code, DWORD state)
 	return(0);
 }
 
-int win32_keyboardio(int isgetch)
+static int win32_keyboardio(int isgetch)
 {
 	INPUT_RECORD input;
 	DWORD num=0;
@@ -384,16 +380,6 @@ int win32_getch(void)
 	return(ret);
 }
 
-int win32_getche(void)
-{
-	int ch;
-
-	ch=win32_getch();
-	if(ch)
-		putch(ch);
-	return(ch);
-}
-
 #ifndef ENABLE_EXTENDED_FLAGS
 #define ENABLE_INSERT_MODE		0x0020
 #define ENABLE_QUICK_EDIT_MODE	0x0040
@@ -543,6 +529,18 @@ void win32_textmode(int mode)
 		SetConsoleWindowInfo(h,TRUE,&rc);
 		SetConsoleScreenBufferSize(h,sz);
 	}
+
+	cio_textinfo.attribute=7;
+	cio_textinfo.normattr=7;
+	cio_textinfo.currmode=vparams[modeisx].mode;
+	cio_textinfo.screenheightsz.Y;
+	cio_textinfo.screenwidth=sz.X;
+	cio_textinfo.curx=1;
+	cio_textinfo.cury=1;
+	cio_textinfo.winleft=1;
+	cio_textinfo.wintop=1;
+	cio_textinfo.winright=cio_textinfo.screenwidth;
+	cio_textinfo.winbottom=cio_textinfo.screenheight;
 }
 
 int win32_gettext(int left, int top, int right, int bottom, void* buf)
@@ -577,46 +575,19 @@ int win32_gettext(int left, int top, int right, int bottom, void* buf)
 	return 1;
 }
 
-void win32_gettextinfo(struct text_info* info)
-{
-	info->currmode=vparams[modeidx].mode;
-	info->curx=xpos;
-	info->cury=ypos;
-	info->attribute=currattr;
-	info->screenheight=vparams[modeidx].rows;
-	info->screenwidth=vparams[modeidx].cols;
-}
-
 void win32_gotoxy(int x, int y)
 {
 	COORD	cp;
 	HANDLE	h;
 
-	xpos=x;
-	ypos=y;
+	cio_terminfo.curx=x;
+	cio_terminfo.cury=y;
 	cp.X=x-1;
 	cp.Y=y-1;
 	if(!hold_update && (h=GetStdHandle(STD_OUTPUT_HANDLE)) != INVALID_HANDLE_VALUE)
 		SetConsoleCursorPosition(h,cp);
 }
 
-void win32_highvideo(void)
-{
-	win32_textattr(currattr|0x08);
-}
-
-
-void win32_lowvideo(void)
-{
-	win32_textattr(currattr&0xf8);
-}
-
-
-void win32_normvideo(void)
-{
-	win32_textattr(7);
-}
-
 int win32_puttext(int left, int top, int right, int bottom, void* buf)
 {
 	CHAR_INFO *ci;
@@ -649,24 +620,6 @@ int win32_puttext(int left, int top, int right, int bottom, void* buf)
 	return 1;
 }
 
-void win32_textattr(int newattr)
-{
-	/* SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),DOStoWinAttr(newattr)); */
-	currattr=newattr;
-}
-
-
-void win32_textbackground(int newcolor)
-{
-	win32_textattr((currattr&0x0f)|((newcolor&0xf0)<<4));
-}
-
-
-void win32_textcolor(int newcolor)
-{
-	win32_textattr((currattr&0xf0)|((newcolor&0x0f)<<4));
-}
-
 void win32_setcursortype(int type)
 {
 	HANDLE h;
@@ -692,84 +645,6 @@ void win32_setcursortype(int type)
 		SetConsoleCursorInfo(h,&ci);
 }
 
-int win32_wherex(void)
-{
-	return(xpos);
-}
-
-int win32_wherey(void)
-{
-	return(ypos);
-}
-
-int win32_putch(int ch)
-{
-	struct text_info ti;
-	unsigned char buf[2];
-	int i;
-
-	buf[0]=ch;
-	buf[1]=currattr;
-
-	switch(ch) {
-		case '\r':
-			gotoxy(1,wherey());
-			break;
-		case '\n':
-			gettextinfo(&ti);
-			if(ti.cury==ti.winbottom-ti.wintop+1)
-				wscroll();
-			else
-				gotoxy(ti.curx,ti.cury+1);
-			break;
-		case '\b':
-			gettextinfo(&ti);
-			if(ti.curx>1) {
-				buf[0]=' ';
-				gotoxy(ti.curx-1,ti.cury);
-				puttext(ti.winleft+ti.curx-2, ti.wintop+ti.cury-1,ti.winleft+ti.curx-2, ti.wintop+ti.cury-1,buf);
-			}
-			break;
-		case 7:		/* Bell */
-			MessageBeep(MB_OK);
-			break;
-		case '\t':
-			for(i=0;i<10;i++) {
-				if(cio_tabs[i]>wherex()) {
-					while(wherex()<cio_tabs[i]) {
-						putch(' ');
-					}
-					break;
-				}
-			}
-			if(i==10) {
-				putch('\r');
-				putch('\n');
-			}
-			break;
-		default:
-			gettextinfo(&ti);
-			if(ti.cury==ti.winbottom-ti.wintop+1
-					&& ti.curx==ti.winright-ti.winleft+1) {
-				puttext(ti.winleft+ti.curx-1, ti.wintop+ti.cury-1,ti.winleft+ti.curx-1, ti.wintop+ti.cury-1,buf);
-				wscroll();
-				gotoxy(1,ti.cury);
-			}
-			else {
-				if(ti.curx==ti.winright-ti.winleft+1) {
-					puttext(ti.winleft+ti.curx-1, ti.wintop+ti.cury-1,ti.winleft+ti.curx-1, ti.wintop+ti.cury-1,buf);
-					gotoxy(1,ti.cury+1);
-				}
-				else {
-					puttext(ti.winleft+ti.curx-1, ti.wintop+ti.cury-1,ti.winleft+ti.curx-1, ti.wintop+ti.cury-1,buf);
-					gotoxy(ti.curx+1,ti.cury);
-				}
-			}
-			break;
-	}
-	return(ch);
-}
-
 void win32_settitle(const char *title)
 {
 	SetConsoleTitle(title);
@@ -818,8 +693,3 @@ char *win32_getcliptext(void)
 	
 	return(ret);
 }
-
-void win32_delay(long msec)
-{
-	SLEEP(msec);
-}
diff --git a/src/conio/win32cio.h b/src/conio/win32cio.h
index 94c269de31457587c1b48644d12077bac55056ba..aa8e5341bd55aed31db2354a4aa510c0e4619f0e 100644
--- a/src/conio/win32cio.h
+++ b/src/conio/win32cio.h
@@ -37,32 +37,19 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
-void win32_delay(long msec);
 int win32_kbhit(void);
 int win32_getch(void);
-int win32_getche(void);
 int win32_getmouse(struct cio_mouse_event *mevent);
 int win32_hidemouse(void);
 int win32_showmouse(void);
 
 int	win32_gettext(int left, int top, int right, int bottom, void*);
-void	win32_gettextinfo(struct text_info*);
 void	win32_gotoxy(int x, int y);
-void	win32_highvideo(void);
-void	win32_lowvideo(void);
-void	win32_normvideo(void);
 int	win32_puttext(int left, int top, int right, int bottom, void*);
-void	win32_textattr(int newattr);
-void	win32_textbackground(int newcolor);
-void	win32_textcolor(int newcolor);
 void	win32_textmode(int newmode);
 void	win32_setcursortype(int);
 int	win32_getch(void);
-int	win32_getche(void);
 int	win32_kbhit(void);
-int	win32_putch(int);
-int	win32_wherex(void);
-int	win32_wherey(void);
 void	win32_settitle(const char *title);
 int	win32_initciolib(long inmode);
 void win32_copytext(const char *text, size_t buflen);
diff --git a/src/conio/x_cio.c b/src/conio/x_cio.c
index 544ae8459268a1f1f89b40b1af1dd6965fdcc3bb..368d02f82b4e0c1060905b8326de77b2e2f072dd 100644
--- a/src/conio/x_cio.c
+++ b/src/conio/x_cio.c
@@ -50,8 +50,6 @@
 #include "console.h"
 WORD	x_curr_attr=0x0700;
 
-const int x_tabs[10]={9,17,25,33,41,49,57,65,73,80};
-
 int x_puttext(int sx, int sy, int ex, int ey, void *fill)
 {
 	int x,y;
@@ -118,115 +116,17 @@ int x_gettext(int sx, int sy, int ex, int ey, void *fill)
 	return(1);
 }
 
-void x_textattr(int attr)
-{
-	x_curr_attr=attr<<8;
-}
-
 int x_kbhit(void)
 {
 	return(tty_kbhit());
 }
 
-void x_delay(long msec)
-{
-	usleep(msec*1000);
-}
-
-int x_wherey(void)
-{
-	return(CursRow+1);
-}
-
-int x_wherex(void)
-{
-	return(CursCol+1);
-}
-
-/* Put the character _c on the screen at the current cursor position. 
- * The special characters return, linefeed, bell, and backspace are handled
- * properly, as is line wrap and scrolling. The cursor position is updated. 
- */
-int x_putch(int ch)
-{
-	struct text_info ti;
-	WORD sch;
-	int i;
-
-	sch=x_curr_attr|ch;
-
-	switch(ch) {
-		case '\r':
-			gettextinfo(&ti);
-			CursCol=ti.winleft-1;
-			break;
-		case '\n':
-			gettextinfo(&ti);
-			if(wherey()==ti.winbottom-ti.wintop+1)
-				wscroll();
-			else
-				CursRow++;
-			break;
-		case '\b':
-			if(CursCol>0)
-				CursCol--;
-			vmem[CursCol+CursRow*DpyCols]=x_curr_attr|' ';
-			break;
-		case 7:		/* Bell */
-			tty_beep();
-			break;
-		case '\t':
-			for(i=0;i<10;i++) {
-				if(x_tabs[i]>wherex()) {
-					while(wherex()<x_tabs[i]) {
-						putch(' ');
-					}
-					break;
-				}
-			}
-			if(i==10) {
-				putch('\r');
-				putch('\n');
-			}
-			break;
-		default:
-			gettextinfo(&ti);
-			if(wherey()==ti.winbottom-ti.wintop+1
-					&& wherex()==ti.winright-ti.winleft+1) {
-				vmem[CursCol+CursRow*DpyCols]=sch;
-				wscroll();
-				gotoxy(ti.winleft,wherey());
-			}
-			else {
-				if(wherex()==ti.winright-ti.winleft+1) {
-					vmem[CursCol+CursRow*DpyCols]=sch;
-					gotoxy(ti.winleft,ti.cury+1);
-				}
-				else {
-					vmem[CursCol+CursRow*DpyCols]=sch;
-					gotoxy(ti.curx+1,ti.cury);
-				}
-			}
-			break;
-	}
-
-	return(ch);
-}
-
 void x_gotoxy(int x, int y)
 {
-	CursRow=y-1;
-	CursCol=x-1;
-}
-
-void x_gettextinfo(struct text_info *info)
-{
-	info->currmode=CurrMode;
-	info->screenheight=DpyRows+1;
-	info->screenwidth=DpyCols;
-	info->curx=x_wherex();
-	info->cury=x_wherey();
-	info->attribute=x_curr_attr>>8;
+	CursRow=cio_textinfo.wintop+y-2;
+	CursCol=cio_textinfo.winleft+x-2;
+	cio_textinfo.curx=x;
+	cio_textinfo.cury=y;
 }
 
 void x_setcursortype(int type)
@@ -252,18 +152,6 @@ int x_getch(void)
 	return(tty_read(TTYF_BLOCK));
 }
 
-int x_getche(void)
-{
-	int ch;
-
-	if(x_nextchar)
-		return(x_getch());
-	ch=x_getch();
-	if(ch)
-		putch(ch);
-	return(ch);
-}
-
 int x_beep(void)
 {
 	tty_beep();
diff --git a/src/conio/x_cio.h b/src/conio/x_cio.h
index 9a298aa7a63b285b0dc88b3835f23aa5b6f9bdaf..8d623455e9bb78d000a7b24e77e3c8e8d004b3ef 100644
--- a/src/conio/x_cio.h
+++ b/src/conio/x_cio.h
@@ -47,18 +47,11 @@ extern "C" {
 #endif
 int x_puttext(int sx, int sy, int ex, int ey, void *fill);
 int x_gettext(int sx, int sy, int ex, int ey, void *fill);
-void x_textattr(int attr);
 int x_kbhit(void);
-void x_delay(long msec);
-int x_wherey(void);
-int x_wherex(void);
-int x_putch(int ch);
 void x_gotoxy(int x, int y);
 void x_initciolib(long inmode);
-void x_gettextinfo(struct text_info *info);
 void x_setcursortype(int type);
 int x_getch(void);
-int x_getche(void);
 int x_beep(void);
 void x_textmode(int mode);
 void x_setname(const char *name);