diff --git a/src/uifc/uifc.c b/src/uifc/uifc.c
index b2f2576965db7ca6ef8efb757b3d83de59bad2c2..60f64a6ed334b98581b5d01be4e3801d46af38f7 100644
--- a/src/uifc/uifc.c
+++ b/src/uifc/uifc.c
@@ -61,19 +61,31 @@ DosSleep(msec ? msec : 1);
 
 #define HELP 1
 
-char hclr,lclr,bclr,cclr,savnum=0,show_free_mem=0
-	,helpdatfile[256]=""
-	,helpixbfile[256]=""
-	,*helpfile=0,*helpbuf=0
-	,blk_scrn[MAX_BFLN],savdepth=0,changes=0,uifc_status=0;
-uint scrn_len;
-win_t sav[MAX_BUFS];
-uint cursor,helpline=0,max_opts=MAX_OPTS;
-
-extern int daylight=0;
-extern long timezone=0;
-
-void bottomline(int line);
+static char hclr,lclr,bclr,cclr,show_free_mem=0;
+static int cursor;
+static char* helpfile=0;
+static uint helpline=0;
+static char blk_scrn[MAX_BFLN];
+static win_t sav[MAX_BUFS];
+static uint max_opts=MAX_OPTS;
+static uifcapi_t* api;
+
+/* Prototypes */
+static int  uprintf(char x, char y, char attr, char *fmt,...);
+static void bottomline(int line);
+static char *utimestr(time_t *intime);
+static void help();
+
+/* API routines */
+static void uifcbail(void);
+static int uscrn(char *str);
+static int ulist(int mode, char left, int top, char width, int *dflt, int *bar
+	,char *title, char **option);
+static int uinput(int imode, char left, char top, char *prompt, char *str
+	,char len ,int kmode);
+static void umsg(char *str);
+static void upop(char *str);
+static void sethelp(int line, char* file);
 
 #ifdef __FLAT__
 int inkey(int mode)
@@ -97,9 +109,10 @@ return(bioskey(0));
 }
 #endif
 
-uint mousecursor=0x28;
+static uint mousecursor=0x28;
 
-int uifcini()
+/* Returns 0 on success */
+int uifcini(uifcapi_t* uifcapi)
 {
 	int 	i;
 	struct	text_info txtinfo;
@@ -107,6 +120,20 @@ int uifcini()
 	union	REGS r;
 #endif
 
+    if(uifcapi==NULL || uifcapi->size!=sizeof(uifcapi_t))
+        return(-1);
+
+    api=uifcapi;
+
+    /* install function handlers */            
+    api->bail=uifcbail;
+    api->scrn=uscrn;
+    api->msg=umsg;
+    api->pop=upop;
+    api->list=ulist;
+    api->input=uinput;
+    api->sethelp=sethelp;
+
     clrscr();
     gettextinfo(&txtinfo);
     /* unsupported mode? */
@@ -117,18 +144,18 @@ int uifcini()
         gettextinfo(&txtinfo);
     }
 
-    scrn_len=txtinfo.screenheight;
-    if(scrn_len<MIN_LINES || scrn_len>MAX_LINES) {
+    api->scrn_len=txtinfo.screenheight;
+    if(api->scrn_len<MIN_LINES || api->scrn_len>MAX_LINES) {
         cprintf("\7UIFC: Screen length (%u) must be between %d and %d lines\r\n"
-            ,scrn_len,MIN_LINES,MAX_LINES);
-        exit(1);
+            ,api->scrn_len,MIN_LINES,MAX_LINES);
+        return(-2);
     }
-    scrn_len--; /* account for status line */
+    api->scrn_len--; /* account for status line */
 
     if(txtinfo.screenwidth<80) {
         cprintf("\7UIFC: Screen width (%u) must be at least 80 characters\r\n"
             ,txtinfo.screenwidth);
-        exit(1);
+        return(-3);
     }
 
 #ifndef __FLAT__
@@ -159,8 +186,8 @@ int uifcini()
     #endif
 
 
-    if(!(uifc_status&UIFC_COLOR)
-        && (uifc_status&UIFC_MONO
+    if(!(api->mode&UIFC_COLOR)
+        && (api->mode&UIFC_MONO
             || txtinfo.currmode==MONO || txtinfo.currmode==BW80)) {
         bclr=BLACK;
         hclr=WHITE;
@@ -180,10 +207,10 @@ int uifcini()
     cursor=_NOCURSOR;
     _setcursortype(cursor);
 
-    return(scrn_len);
+    return(0);
 }
 
-void hidemouse(void)
+static void hidemouse(void)
 {
 #ifndef __FLAT__
 	union  REGS r;
@@ -194,7 +221,7 @@ if(uifc_status&UIFC_MOUSE) {
 #endif
 }
 
-void showmouse(void)
+static void showmouse(void)
 {
 #ifndef __FLAT__
 	union  REGS r;
@@ -222,14 +249,14 @@ int uscrn(char *str)
     clreol();
     gotoxy(3,1);
     cputs(str);
-    if(!puttext(1,2,80,scrn_len,blk_scrn))
+    if(!puttext(1,2,80,api->scrn_len,blk_scrn))
         return(-1);
-    gotoxy(1,scrn_len+1);
+    gotoxy(1,api->scrn_len+1);
     clreol();
     return(0);
 }
 
-void scroll_text(int x1, int y1, int x2, int y2, int down)
+static void scroll_text(int x1, int y1, int x2, int y2, int down)
 {
 	uchar buf[MAX_BFLN];
 
@@ -244,7 +271,7 @@ else
 /* Updates time in upper left corner of screen with current time in ASCII/  */
 /* Unix format																*/
 /****************************************************************************/
-void timedisplay()
+static void timedisplay()
 {
 	static time_t savetime;
 	time_t now;
@@ -287,7 +314,7 @@ INT_86(0x33,&r,&r);  /* Clears any buffered mouse clicks */
 
 #endif
 
-if(mode&WIN_SAV && savnum>=MAX_BUFS-1)
+if(mode&WIN_SAV && api->savnum>=MAX_BUFS-1)
 	putch(7);
 i=0;
 if(mode&WIN_INS) bline|=BL_INS;
@@ -302,8 +329,8 @@ while(opts<max_opts && opts<MAX_OPTS)
 if(mode&WIN_XTR && opts<max_opts && opts<MAX_OPTS)
 	option[opts++][0]=0;
 height=opts+4;
-if(top+height>scrn_len-3)
-	height=(scrn_len-3)-top;
+if(top+height>api->scrn_len-3)
+	height=(api->scrn_len-3)-top;
 if(!width || width<strlen(title)+6) {
 	width=strlen(title)+6;
 	for(i=0;i<opts;i++) {
@@ -317,39 +344,39 @@ if(mode&WIN_L2R)
 else if(mode&WIN_RHT)
 	left=SCRN_RIGHT-(width+4+left);
 if(mode&WIN_T2B)
-	top=(scrn_len/2)-(height/2)-2;
+	top=(api->scrn_len/2)-(height/2)-2;
 else if(mode&WIN_BOT)
-	top=scrn_len-height-3-top;
-if(mode&WIN_SAV && savdepth==savnum) {
-	if((sav[savnum].buf=(char *)MALLOC((width+3)*(height+2)*2))==NULL) {
+	top=api->scrn_len-height-3-top;
+if(mode&WIN_SAV && api->savdepth==api->savnum) {
+	if((sav[api->savnum].buf=(char *)MALLOC((width+3)*(height+2)*2))==NULL) {
 		cprintf("UIFC line %d: error allocating %u bytes."
             ,__LINE__,(width+3)*(height+2)*2);
 		return(-1); }
 	gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT+left+width+1
-		,SCRN_TOP+top+height,sav[savnum].buf);
-	sav[savnum].left=SCRN_LEFT+left;
-	sav[savnum].top=SCRN_TOP+top;
-	sav[savnum].right=SCRN_LEFT+left+width+1;
-	sav[savnum].bot=SCRN_TOP+top+height;
-	savdepth++; }
+		,SCRN_TOP+top+height,sav[api->savnum].buf);
+	sav[api->savnum].left=SCRN_LEFT+left;
+	sav[api->savnum].top=SCRN_TOP+top;
+	sav[api->savnum].right=SCRN_LEFT+left+width+1;
+	sav[api->savnum].bot=SCRN_TOP+top+height;
+	api->savdepth++; }
 else if(mode&WIN_SAV
-	&& (sav[savnum].left!=SCRN_LEFT+left
-	|| sav[savnum].top!=SCRN_TOP+top
-	|| sav[savnum].right!=SCRN_LEFT+left+width+1
-	|| sav[savnum].bot!=SCRN_TOP+top+height)) { /* dimensions have changed */
-	puttext(sav[savnum].left,sav[savnum].top,sav[savnum].right,sav[savnum].bot
-		,sav[savnum].buf);	/* put original window back */
-	FREE(sav[savnum].buf);
-	if((sav[savnum].buf=(char *)MALLOC((width+3)*(height+2)*2))==NULL) {
+	&& (sav[api->savnum].left!=SCRN_LEFT+left
+	|| sav[api->savnum].top!=SCRN_TOP+top
+	|| sav[api->savnum].right!=SCRN_LEFT+left+width+1
+	|| sav[api->savnum].bot!=SCRN_TOP+top+height)) { /* dimensions have changed */
+	puttext(sav[api->savnum].left,sav[api->savnum].top,sav[api->savnum].right,sav[api->savnum].bot
+		,sav[api->savnum].buf);	/* put original window back */
+	FREE(sav[api->savnum].buf);
+	if((sav[api->savnum].buf=(char *)MALLOC((width+3)*(height+2)*2))==NULL) {
 		cprintf("UIFC line %d: error allocating %u bytes."
             ,__LINE__,(width+3)*(height+2)*2);
 		return(-1); }
 	gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT+left+width+1
-		,SCRN_TOP+top+height,sav[savnum].buf);	  /* save again */
-	sav[savnum].left=SCRN_LEFT+left;
-	sav[savnum].top=SCRN_TOP+top;
-	sav[savnum].right=SCRN_LEFT+left+width+1;
-	sav[savnum].bot=SCRN_TOP+top+height; }
+		,SCRN_TOP+top+height,sav[api->savnum].buf);	  /* save again */
+	sav[api->savnum].left=SCRN_LEFT+left;
+	sav[api->savnum].top=SCRN_TOP+top;
+	sav[api->savnum].right=SCRN_LEFT+left+width+1;
+	sav[api->savnum].bot=SCRN_TOP+top+height; }
 
 
 #ifndef __FLAT__
@@ -366,8 +393,8 @@ if(show_free_mem) {
 if(mode&WIN_ORG) { /* Clear around menu */
 	if(top)
 		puttext(SCRN_LEFT,SCRN_TOP,SCRN_RIGHT+2,SCRN_TOP+top-1,blk_scrn);
-	if(SCRN_TOP+height+top<=scrn_len)
-		puttext(SCRN_LEFT,SCRN_TOP+height+top,SCRN_RIGHT+2,scrn_len,blk_scrn);
+	if(SCRN_TOP+height+top<=api->scrn_len)
+		puttext(SCRN_LEFT,SCRN_TOP+height+top,SCRN_RIGHT+2,api->scrn_len,blk_scrn);
 	if(left)
 		puttext(SCRN_LEFT,SCRN_TOP+top,SCRN_LEFT+left-1,SCRN_TOP+height+top
 			,blk_scrn);
@@ -378,7 +405,7 @@ ptr=win;
 *(ptr++)='�';
 *(ptr++)=hclr|(bclr<<4);
 
-if(uifc_status&UIFC_MOUSE) {
+if(api->mode&UIFC_MOUSE) {
 	*(ptr++)='[';
 	*(ptr++)=hclr|(bclr<<4);
 	*(ptr++)='�';
@@ -524,12 +551,12 @@ while(1) {
 #if 0					/* debug */
 	gotoxy(30,1);
 	cprintf("y=%2d h=%2d c=%2d b=%2d s=%2d o=%2d"
-		,y,height,*cur,bar ? *bar :0xff,savdepth,opts);
+		,y,height,*cur,bar ? *bar :0xff,api->savdepth,opts);
 #endif
 	if(!show_free_mem)
 		timedisplay();
 #ifndef __FLAT__
-	if(uifc_status&UIFC_MOUSE) {
+	if(api->mode&UIFC_MOUSE) {
 
 		r.w.ax=0x0003;		/* Get button status and mouse position */
 		INT_86(0x33,&r,&r);
@@ -596,12 +623,12 @@ while(1) {
 					showmouse(); }
 				else if(mode&WIN_SAV) {
 					hidemouse();
-					puttext(sav[savnum].left,sav[savnum].top
-						,sav[savnum].right,sav[savnum].bot
-						,sav[savnum].buf);
+					puttext(sav[api->savnum].left,sav[api->savnum].top
+						,sav[api->savnum].right,sav[api->savnum].bot
+						,sav[api->savnum].buf);
 					showmouse();
-					FREE(sav[savnum].buf);
-					savdepth--; }
+					FREE(sav[api->savnum].buf);
+					api->savdepth--; }
 				return(*cur); }
 			else if(r.w.cx/8>=SCRN_LEFT+left+3
 				&& r.w.cx/8<=SCRN_LEFT+left+5
@@ -616,7 +643,7 @@ while(1) {
 
 		if(r.w.bx) {	  /* Right button down, same as ESC */
 hitesc:
-            if(mode&WIN_ESC || (mode&WIN_CHE && changes)
+            if(mode&WIN_ESC || (mode&WIN_CHE && api->changes)
                 && !(mode&WIN_SAV)) {
                 hidemouse();
                 gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT
@@ -628,12 +655,12 @@ hitesc:
                 showmouse(); }
             else if(mode&WIN_SAV) {
 				hidemouse();
-                puttext(sav[savnum].left,sav[savnum].top
-                    ,sav[savnum].right,sav[savnum].bot
-                    ,sav[savnum].buf);
+                puttext(sav[api->savnum].left,sav[api->savnum].top
+                    ,sav[api->savnum].right,sav[api->savnum].bot
+                    ,sav[api->savnum].buf);
 				showmouse();
-                FREE(sav[savnum].buf);
-                savdepth--; }
+                FREE(sav[api->savnum].buf);
+                api->savdepth--; }
             return(-1); }
 				}
 #endif
@@ -1057,15 +1084,15 @@ hitesc:
 							showmouse(); }
 						else if(mode&WIN_SAV) {
 							hidemouse();
-							puttext(sav[savnum].left,sav[savnum].top
-								,sav[savnum].right,sav[savnum].bot
-								,sav[savnum].buf);
+							puttext(sav[api->savnum].left,sav[api->savnum].top
+								,sav[api->savnum].right,sav[api->savnum].bot
+								,sav[api->savnum].buf);
 							showmouse();
-							FREE(sav[savnum].buf);
-							savdepth--; }
+							FREE(sav[api->savnum].buf);
+							api->savdepth--; }
 						return(*cur);
 					case ESC:
-						if(mode&WIN_ESC || (mode&WIN_CHE && changes)
+						if(mode&WIN_ESC || (mode&WIN_CHE && api->changes)
 							&& !(mode&WIN_SAV)) {
 							hidemouse();
 							gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT
@@ -1077,12 +1104,12 @@ hitesc:
 							showmouse(); }
 						else if(mode&WIN_SAV) {
 							hidemouse();
-							puttext(sav[savnum].left,sav[savnum].top
-								,sav[savnum].right,sav[savnum].bot
-								,sav[savnum].buf);
+							puttext(sav[api->savnum].left,sav[api->savnum].top
+								,sav[api->savnum].right,sav[api->savnum].bot
+								,sav[api->savnum].buf);
 							showmouse();
-							FREE(sav[savnum].buf);
-							savdepth--; }
+							FREE(sav[api->savnum].buf);
+							api->savdepth--; }
 						return(-1); } } }
 	else
 		mswait(1);
@@ -1108,7 +1135,7 @@ else
 	slen=6;
 width=plen+slen+max;
 if(mode&WIN_T2B)
-	top=(scrn_len/2)-(height/2)-2;
+	top=(api->scrn_len/2)-(height/2)-2;
 if(mode&WIN_L2R)
 	left=36-(width/2);
 if(mode&WIN_SAV)
@@ -1189,13 +1216,13 @@ void umsg(char *str)
 	int i=0;
 	char *ok[2]={"OK",""};
 
-if(uifc_status&UIFC_INMSG)	/* non-cursive */
+if(api->mode&UIFC_INMSG)	/* non-cursive */
 	return;
-uifc_status|=UIFC_INMSG;
-if(savdepth) savnum++;
+api->mode|=UIFC_INMSG;
+if(api->savdepth) api->savnum++;
 ulist(WIN_SAV|WIN_MID,0,0,0,&i,0,str,ok);
-if(savdepth) savnum--;
-uifc_status&=~UIFC_INMSG;
+if(api->savdepth) api->savnum--;
+api->mode&=~UIFC_INMSG;
 }
 
 /****************************************************************************/
@@ -1203,7 +1230,7 @@ uifc_status&=~UIFC_INMSG;
 /* Different modes - K_* macros. ESC aborts input.                          */
 /* Cursor should be at END of where string prompt will be placed.           */
 /****************************************************************************/
-int getstr(char *outstr, int max, long mode)
+static int getstr(char *outstr, int max, long mode)
 {
 	uchar   ch,str[256],ins=0,buf[256],y;
 	int     i,j,k,f=0;	/* i=offset, j=length */
@@ -1226,7 +1253,7 @@ if(mode&K_EDIT) {
 	i=j=strlen(str);
 	while(inkey(1)==0) {
 #ifndef __FLAT__
-		if(uifc_status&UIFC_MOUSE) {
+		if(api->mode&UIFC_MOUSE) {
 			r.w.ax=0x0006;		/* Get button release information */
 			r.w.bx=0x0000;		/* Left button */
 			INT_86(0x33,&r,&r);
@@ -1261,7 +1288,7 @@ while(1) {
 
 	if(i>j) j=i;
 #ifndef __FLAT__
-	if(uifc_status&UIFC_MOUSE) {
+	if(api->mode&UIFC_MOUSE) {
 		r.w.ax=0x0006;		/* Get button release information */
 		r.w.bx=0x0000;		/* Left button */
 		INT_86(0x33,&r,&r);
@@ -1383,53 +1410,33 @@ str[j]=0;
 if(mode&K_EDIT) {
 	truncsp(str);
 	if(strcmp(outstr,str))
-		changes=1; }
+		api->changes=1; }
 else {
 	if(j)
-		changes=1; }
+		api->changes=1; }
 strcpy(outstr,str);
 cursor=_NOCURSOR;
 _setcursortype(cursor);
 return(j);
 }
 
-#if defined(SCFG)
-/****************************************************************************/
-/* Performs printf() through local assembly routines                        */
-/* Called from everywhere                                                   */
-/****************************************************************************/
-int lprintf(char *fmat, ...)
-{
-	va_list argptr;
-	char sbuf[512];
-	int chcount;
-
-va_start(argptr,fmat);
-chcount=vsprintf(sbuf,fmat,argptr);
-va_end(argptr);
-cputs(sbuf);
-return(chcount);
-}
-
-#endif
-
 /****************************************************************************/
 /* Performs printf() through puttext() routine								*/
 /****************************************************************************/
-int uprintf(char x, char y, char attr, char *fmat, ...)
+static int uprintf(char x, char y, char attr, char *fmat, ...)
 {
 	va_list argptr;
 	char str[256],buf[512];
 	int i,j;
 
-va_start(argptr,fmat);
-vsprintf(str,fmat,argptr);
-va_end(argptr);
-for(i=j=0;str[i];i++) {
-	buf[j++]=str[i];
-	buf[j++]=attr; }
-puttext(x,y,x+(i-1),y,buf);
-return(i);
+    va_start(argptr,fmat);
+    vsprintf(str,fmat,argptr);
+    va_end(argptr);
+    for(i=j=0;str[i];i++) {
+        buf[j++]=str[i];
+        buf[j++]=attr; }
+    puttext(x,y,x+(i-1),y,buf);
+    return(i);
 }
 
 
@@ -1439,35 +1446,35 @@ return(i);
 void bottomline(int line)
 {
 	int i=4;
-uprintf(i,scrn_len+1,bclr|(cclr<<4),"F1 ");
+uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"F1 ");
 i+=3;
-uprintf(i,scrn_len+1,BLACK|(cclr<<4),"Help  ");
+uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Help  ");
 i+=6;
 if(line&BL_GET) {
-	uprintf(i,scrn_len+1,bclr|(cclr<<4),"F5 ");
+	uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"F5 ");
 	i+=3;
-	uprintf(i,scrn_len+1,BLACK|(cclr<<4),"Copy Item  ");
+	uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Copy Item  ");
 	i+=11; }
 if(line&BL_PUT) {
-	uprintf(i,scrn_len+1,bclr|(cclr<<4),"F6 ");
+	uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"F6 ");
 	i+=3;
-	uprintf(i,scrn_len+1,BLACK|(cclr<<4),"Paste  ");
+	uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Paste  ");
     i+=7; }
 if(line&BL_INS) {
-	uprintf(i,scrn_len+1,bclr|(cclr<<4),"INS ");
+	uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"INS ");
 	i+=4;
-	uprintf(i,scrn_len+1,BLACK|(cclr<<4),"Add Item  ");
+	uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Add Item  ");
 	i+=10; }
 if(line&BL_DEL) {
-	uprintf(i,scrn_len+1,bclr|(cclr<<4),"DEL ");
+	uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"DEL ");
     i+=4;
-	uprintf(i,scrn_len+1,BLACK|(cclr<<4),"Delete Item  ");
+	uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Delete Item  ");
 	i+=13; }
-uprintf(i,scrn_len+1,bclr|(cclr<<4),"ESC ");
+uprintf(i,api->scrn_len+1,bclr|(cclr<<4),"ESC ");
 i+=4;
-uprintf(i,scrn_len+1,BLACK|(cclr<<4),"Exit");
+uprintf(i,api->scrn_len+1,BLACK|(cclr<<4),"Exit");
 i+=4;
-gotoxy(i,scrn_len+1);
+gotoxy(i,api->scrn_len+1);
 textattr(BLACK|(cclr<<4));
 clreol();
 }
@@ -1610,6 +1617,13 @@ showmouse();
 }
 
 #if HELP
+
+void sethelp(int line, char* file)
+{
+    helpline=line;
+    helpfile=file;
+}
+
 /************************************************************/
 /* Help (F1) key function. Uses helpbuf as the help input.	*/
 /************************************************************/
@@ -1695,10 +1709,10 @@ for(j=k;j<k+(24*2);j+=2)
 	buf[j]='�';
 buf[j]='�';
 
-if(!helpbuf) {
-	if((fp=_fsopen(helpixbfile,"rb",SH_DENYWR))==NULL)
+if(!api->helpbuf) {
+	if((fp=_fsopen(api->helpixbfile,"rb",SH_DENYWR))==NULL)
 		sprintf(hbuf," ERROR  Cannot open help index:\r\n          %s"
-			,helpixbfile);
+			,api->helpixbfile);
     else {
         p=strrchr(helpfile,'/');
         if(p==NULL)
@@ -1721,17 +1735,17 @@ if(!helpbuf) {
 		fclose(fp);
 		if(l==-1L)
 			sprintf(hbuf," ERROR  Cannot locate help key (%s:%u) in:\r\n"
-				"         %s",p,helpline,helpixbfile);
+				"         %s",p,helpline,api->helpixbfile);
 		else {
-			if((fp=_fsopen(helpdatfile,"rb",SH_DENYWR))==NULL)
+			if((fp=_fsopen(api->helpdatfile,"rb",SH_DENYWR))==NULL)
 				sprintf(hbuf," ERROR  Cannot open help file:\r\n          %s"
-					,helpdatfile);
+					,api->helpdatfile);
 			else {
 				fseek(fp,l,SEEK_SET);
 				fread(hbuf,HELPBUF_SIZE,1,fp);
 				fclose(fp); } } } }
 else
-    strcpy(hbuf,helpbuf);
+    strcpy(hbuf,api->helpbuf);
 
 len=strlen(hbuf);
 
@@ -1757,7 +1771,7 @@ while(1) {
 		inkey(0);
 		break; }
 #ifndef __FLAT__
-	if(uifc_status&UIFC_MOUSE) {
+	if(api->mode&UIFC_MOUSE) {
 		r.w.ax=0x0006;		/* Get button release information */
 		r.w.bx=0x0000;		/* Left button */
 		INT_86(0x33,&r,&r);
diff --git a/src/uifc/uifc.h b/src/uifc/uifc.h
index ea3946c7e7a84d8916b362601811c5c5cda6bd4e..8720e052f89d48082f8a0f9af50a109511e7f571 100644
--- a/src/uifc/uifc.h
+++ b/src/uifc/uifc.h
@@ -35,8 +35,6 @@
  * Note: If this box doesn't appear square, then you need to fix your tabs.	*
  ****************************************************************************/
 
-#include <io.h>
-#include <dos.h>
 #include <time.h>
 #include <fcntl.h>
 #include <alloc.h>
@@ -45,9 +43,18 @@
 #include <string.h>
 #include <stdarg.h>
 #include <stdlib.h>
+#if defined(_WIN32)
+    #include <windows.h>
+#endif
 #if !defined(__unix__)
+    #include <io.h>
     #include <conio.h>
 #endif
+#if (defined(__unix__) || defined(_WIN32)) && !defined(__FLAT__)
+    #define __FLAT__
+#else
+    #include <dos.h>
+#endif
 
 /* OS Specific */
 #if defined(__FLAT__)
@@ -102,7 +109,7 @@
 #endif
 
 #ifdef __FLAT__
-	#define MAX_OPTS	1000
+	#define MAX_OPTS	10000
 	#define MSK_ON		0xf0000000
 	#define MSK_OFF 	0x0fffffff
 	#define MSK_INS 	0x10000000
@@ -128,11 +135,13 @@
 #define uint unsigned int
 #endif
 
+                            /* Bits in uifcapi_t.mode */
 #define UIFC_INMSG	(1<<0)	/* Currently in Message Routine non-recursive */
 #define UIFC_MOUSE	(1<<1)	/* Mouse installed and available */
 #define UIFC_MONO	(1<<2)	/* Force monochrome mode */
 #define UIFC_COLOR	(1<<3)	/* Force color mode */
 
+                            /* Bits in uifcapi_t.list mode */
 #define WIN_ORG 	(1<<0)	/* Original menu - destroy valid screen area */
 #define WIN_SAV 	(1<<1)	/* Save existing text and replace when finished */
 #define WIN_ACT 	(1<<2)	/* Menu remains active after a selection */
@@ -171,8 +180,6 @@
 
 #define HELPBUF_SIZE 4000
 
-#define SETHELP(where)	helpline=__LINE__; helpfile=__FILE__
-
 #ifndef TAB
 									/* Control characters */
 #define STX 	0x02				/* Start of text			^B	*/
@@ -199,46 +206,53 @@
 #define ulong unsigned long
 #endif
 
+#ifndef BOOL
+#define BOOL    int
+#define TRUE    1
+#define FALSE   0
+#endif
 
 typedef struct {
-	char	left,top,right,bot,*buf;
-	} win_t;
+	uint    left,top,right,bot;
+    uchar   *buf;
+} win_t;
 
-
-/* LCLOLL.ASM */
-int lclini(int);
-void lclxy(int,int);
-int lclwx(void);
-int lclwy(void);
-int lclatr(int);
-void lputc(int);
-long lputs(char far *);
+#if !defined(__FLAT__)
+    /* LCLOLL.ASM */
+    int lclini(int);
+    void lclxy(int,int);
+    int lclwx(void);
+    int lclwy(void);
+    int lclatr(int);
+    void lputc(int);
+    long lputs(char far *);
+#endif    
 
 #if defined(__OS2__) || !defined(__FLAT__)
 void mswait(int msecs);
 extern mswtyp;
 #endif
 
-extern char lclr,hclr,bclr,cclr,blk_scrn[MAX_BFLN],savdepth
-	,changes,show_free_mem,savnum,uifc_status,*helpfile,*helpbuf
-	,helpdatfile[256]
-	,helpixbfile[256];
-extern win_t sav[MAX_BUFS];
-extern uint cursor,helpline,scrn_len;
-
-int uifcini(void);
-int uscrn(char *str);
-int ulist(int mode, char left, int top, char width, int *dflt, int *bar
-	,char *title, char **option);
-int uinput(int imode, char left, char top, char *prompt, char *str
-	,char len ,int kmode);
-int  uprintf(char x, char y, char attr, char *fmt,...);
-void umsg(char *str);
-void upop(char *str);
-int  getstr(char *str, int maxlen, long mode);
-void timedisplay();
-int  lprintf(char *fmt,...);
-char *utimestr(time_t *intime);
-void help(void);
-void truncsp(char *str);
-void uifcbail(void);
+typedef struct {
+    size_t  size;
+    long    mode;
+    BOOL    changes;
+    uint    savdepth;
+    uint    savnum;
+    uint    scrn_len;
+    char*   helpbuf;
+    char    helpdatfile[256];
+    char    helpixbfile[256];
+    void    (*bail) (void);
+    int     (*scrn) (char* str);
+    void    (*msg)  (char* str);
+    void    (*pop)  (char* str);
+    int     (*list) (int mode, char left, int top, char width, int* dflt
+                        ,int* bar, char *title, char** option);
+    int     (*input)(int imode, char left, char top, char* prompt, char* str
+            	        ,char len, int kmode);
+    void    (*sethelp)(int line, char* file);
+} uifcapi_t;
+
+int uifcini(uifcapi_t*);
+int uifcinix(uifcapi_t*);
diff --git a/src/uifc/uifcx.c b/src/uifc/uifcx.c
index 7693af363ee1878839b67756da5df86bb21a2151..5bd068e42cffb0494f1a8bf669fdc08d270c28c4 100644
--- a/src/uifc/uifcx.c
+++ b/src/uifc/uifcx.c
@@ -36,20 +36,45 @@
 #include "uifc.h"
 #include <share.h>
 
-char helpdatfile[256]=""
-	,helpixbfile[256]=""
-	,*helpfile=0,*helpbuf=0
-	,changes=0,uifc_status=0;
-char savnum, savdepth;   /* unused */    
-uint scrn_len;
-uint cursor,helpline=0,max_opts=MAX_OPTS;
-
-int uifcini()
+static char *helpfile=0;
+static uint helpline=0;
+static uifcapi_t* api;
+
+/* Prototypes */
+static void help();
+
+/* API routines */
+static void uifcbail(void);
+static int uscrn(char *str);
+static int ulist(int mode, char left, int top, char width, int *dflt, int *bar
+	,char *title, char **option);
+static int uinput(int imode, char left, char top, char *prompt, char *str
+	,char len ,int kmode);
+static void umsg(char *str);
+static void upop(char *str);
+static void sethelp(int line, char* file);
+
+int uifcinix(uifcapi_t* uifcapi)
 {
+
+    if(uifcapi==NULL || uifcapi->size!=sizeof(uifcapi_t))
+        return(-1);
+
+    api=uifcapi;
+
+    /* install function handlers */
+    api->bail=uifcbail;
+    api->scrn=uscrn;
+    api->msg=umsg;
+    api->pop=upop;
+    api->list=ulist;
+    api->input=uinput;
+    api->sethelp=sethelp;
+
     setvbuf(stdout,NULL,_IONBF,0);
-    scrn_len=24;
-    
-    return(scrn_len);
+    api->scrn_len=24;
+
+    return(0);
 }
 
 
@@ -94,7 +119,7 @@ int ulist(int mode, char left, int top, char width, int *cur, int *bar
     int optnumlen;
     int yesno=0;
 
-    for(opts=0;opts<max_opts && opts<MAX_OPTS;opts++)
+    for(opts=0;opts<MAX_OPTS;opts++)
     	if(option[opts][0]==0)
     		break;
 
@@ -120,7 +145,7 @@ int ulist(int mode, char left, int top, char width, int *cur, int *bar
             printf("\n[%s]\n",title);
             for(i=0;i<opts;i++) {
                 printf("%*d: %s\n",optnumlen,i+1,option[i]);
-                if(i && !(i%(scrn_len-2))) {
+                if(i && !(i%(api->scrn_len-2))) {
                     printf("More? ");
                     str[0]=0;
                     fgets(str,sizeof(str)-1,stdin);
@@ -176,7 +201,6 @@ int ulist(int mode, char left, int top, char width, int *cur, int *bar
                 if(i>0 && i<=opts+1)
         			return((i-1)|MSK_INS);
                 return(which("Add before",opts+1)|MSK_INS);
-                break;
             case 'D':   /* Delete */
 				if(!opts)
     				break;
@@ -185,7 +209,6 @@ int ulist(int mode, char left, int top, char width, int *cur, int *bar
                 if(opts==1)
                     return(MSK_DEL);
                 return(which("Delete",opts)|MSK_DEL);
-                break;
             case 'C':   /* Copy/Get */
 				if(!opts)
     				break;
@@ -194,7 +217,6 @@ int ulist(int mode, char left, int top, char width, int *cur, int *bar
                 if(opts==1)
                     return(MSK_GET);
                 return(which("Copy",opts)|MSK_GET);
-                break;
             case 'P':   /* Paste/Put */
 				if(!opts)
     				break;
@@ -203,7 +225,6 @@ int ulist(int mode, char left, int top, char width, int *cur, int *bar
                 if(opts==1)
                     return(MSK_PUT);
                 return(which("Paste",opts)|MSK_PUT);
-                break;
         }
     }
 }
@@ -212,13 +233,23 @@ int ulist(int mode, char left, int top, char width, int *cur, int *bar
 /*************************************************************************/
 /* This function is a windowed input string input routine.               */
 /*************************************************************************/
-int uinput(int mode, char left, char top, char *prompt, char *str,
+int uinput(int mode, char left, char top, char *prompt, char *outstr,
 	char max, int kmode)
 {
-    printf("%s (maxlen=%u): ",prompt,max);
-    fgets(str,max,stdin);
-    truncsp(str);
-    return(strlen(str));
+    char str[256];
+    
+    while(1) {
+        printf("%s (maxlen=%u): ",prompt,max);
+        fgets(str,max,stdin);
+        truncsp(str);
+        if(strcmp(str,"?"))
+            break;
+        help();
+    }
+	if(strcmp(outstr,str))
+		api->changes=1;
+    strcpy(outstr,str);    
+    return(strlen(outstr));
 }
 
 /****************************************************************************/
@@ -252,6 +283,12 @@ void upop(char *str)
         printf("\r%-79s",str);
 }
 
+void sethelp(int line, char* file)
+{
+    helpline=line;
+    helpfile=file;
+}
+
 /************************************************************/
 /* Help (F1) key function. Uses helpbuf as the help input.	*/
 /************************************************************/
@@ -264,10 +301,10 @@ void help()
 	FILE *fp;
 
     printf("\n");
-    if(!helpbuf) {
-        if((fp=_fsopen(helpixbfile,"rb",SH_DENYWR))==NULL)
+    if(!api->helpbuf) {
+        if((fp=_fsopen(api->helpixbfile,"rb",SH_DENYWR))==NULL)
             sprintf(hbuf,"ERROR: Cannot open help index: %s"
-                ,helpixbfile);
+                ,api->helpixbfile);
         else {
             p=strrchr(helpfile,'/');
             if(p==NULL)
@@ -290,18 +327,23 @@ void help()
             fclose(fp);
             if(l==-1L)
                 sprintf(hbuf,"ERROR: Cannot locate help key (%s:%u) in: %s"
-                    ,p,helpline,helpixbfile);
+                    ,p,helpline,api->helpixbfile);
             else {
-                if((fp=_fsopen(helpdatfile,"rb",SH_DENYWR))==NULL)
+                if((fp=_fsopen(api->helpdatfile,"rb",SH_DENYWR))==NULL)
                     sprintf(hbuf,"ERROR: Cannot open help file: %s"
-                        ,helpdatfile);
+                        ,api->helpdatfile);
                 else {
                     fseek(fp,l,SEEK_SET);
                     fread(hbuf,HELPBUF_SIZE,1,fp);
                     fclose(fp); } } } }
     else
-        strcpy(hbuf,helpbuf);
+        strcpy(hbuf,api->helpbuf);
 
     puts(hbuf);
+    if(strlen(hbuf)>200) {
+        printf("Hit enter");
+        getc(stdin);
+    }
 }
 
+