--- sbbs/uifc/uifc.c 2018/04/24 16:37:53 1.1.1.2 +++ sbbs/uifc/uifc.c 2018/04/24 16:41:22 1.1.1.3 @@ -1,9 +1,43 @@ -#line 1 "UIFC.C" +/* uifc.c */ -/* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ +/* Original implementation of UIFC (user interface) library based on conio */ -#include "UIFC.h" +/* $Id: uifc.c,v 1.1.1.3 2018/04/24 16:41:22 root Exp $ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU Lesser General Public License for more details: lgpl.txt or * + * http://www.fsf.org/copyleft/lesser.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#include "uifc.h" #include +#include #if defined(__OS2__) @@ -15,6 +49,9 @@ void mswait(int msec) DosSleep(msec ? msec : 1); } +#elif defined(_WIN32) + #include + #define mswait(x) Sleep(x) #elif defined(__FLAT__) #define mswait(x) delay(x) #endif @@ -25,20 +62,33 @@ DosSleep(msec ? msec : 1); #define BL_GET (1<<2) /* Get key */ #define BL_PUT (1<<3) /* Put key */ -#define HELP 1 - -char hclr,lclr,bclr,cclr,scrn_len,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; -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(int x, int y, char attr, char *fmt,...); +static void bottomline(int line); +static char *utimestr(time_t *intime); +static void help(void); +static int getstr(char *outstr, int max, long mode); + +/* API routines */ +static void uifcbail(void); +static int uscrn(char *str); +static int ulist(int mode, int left, int top, int width, int *dflt, int *bar + ,char *title, char **option); +static int uinput(int imode, int left, int top, char *prompt, char *str + ,int len ,int kmode); +static void umsg(char *str); +static void upop(char *str); +static void sethelp(int line, char* file); +static void timedisplay(void); #ifdef __FLAT__ int inkey(int mode) @@ -62,9 +112,13 @@ return(bioskey(0)); } #endif -uint mousecursor=0x28; +static uint mousecursor=0x28; -void uifcini() +/****************************************************************************/ +/* Initialization function, see uifc.h for details. */ +/* Returns 0 on success. */ +/****************************************************************************/ +int uifcini(uifcapi_t* uifcapi) { int i; struct text_info txtinfo; @@ -72,72 +126,130 @@ void uifcini() union REGS r; #endif -putenv("TZ=UCT0"); /* Fix for Watcom C++ EDT default */ + if(uifcapi==NULL || uifcapi->size!=sizeof(uifcapi_t)) + return(-1); -gettextinfo(&txtinfo); + api=uifcapi; -scrn_len=txtinfo.screenheight; -scrn_len--; -clrscr(); -if(scrn_len>50) { - cputs("\7UIFC: Can't operate in video modes beyond 80x50\r\n"); - exit(1); } - -if(txtinfo.screenwidth<80) { - cputs("\7UIFC: Can't operate in video modes less than 80x25\r\n"); - exit(1); } + /* install function handlers */ + api->bail=uifcbail; + api->scrn=uscrn; + api->msg=umsg; + api->pop=upop; + api->list=ulist; + api->input=uinput; + api->sethelp=sethelp; + api->showhelp=help; + api->showbuf=NULL; + api->timedisplay=timedisplay; + + if(api->scrn_len!=0) { + switch(api->scrn_len) { + case 14: + textmode(C80X14); + break; + case 21: + textmode(C80X21); + break; + case 25: + textmode(C80); + break; + case 28: + textmode(C80X28); + break; + case 43: + textmode(C80X43); + break; + case 50: + textmode(C80X50); + break; + case 60: + textmode(C80X60); + break; + default: + textmode(C4350); + break; + } + } + + clrscr(); + gettextinfo(&txtinfo); + /* unsupported mode? */ + if(txtinfo.screenheightMAX_LINES + || txtinfo.screenwidth<80) { + textmode(C80); /* set mode to 80x25*/ + gettextinfo(&txtinfo); + } + + api->scrn_len=txtinfo.screenheight; + if(api->scrn_lenscrn_len>MAX_LINES) { + cprintf("\7UIFC: Screen length (%u) must be between %d and %d lines\r\n" + ,api->scrn_len,MIN_LINES,MAX_LINES); + return(-2); + } + 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); + return(-3); + } + api->scrn_width=txtinfo.screenwidth; #ifndef __FLAT__ -r.w.ax=0x0000; /* reset mouse and get driver status */ -INT_86(0x33,&r,&r); + r.w.ax=0x0000; /* reset mouse and get driver status */ + INT_86(0x33,&r,&r); -if(r.w.ax==0xffff) { /* mouse driver installed */ - uifc_status|=UIFC_MOUSE; + if(r.w.ax==0xffff) { /* mouse driver installed */ + uifc_status|=UIFC_MOUSE; - r.w.ax=0x0020; /* enable mouse driver */ - INT_86(0x33,&r,&r); + r.w.ax=0x0020; /* enable mouse driver */ + INT_86(0x33,&r,&r); - r.w.ax=0x000a; /* set text pointer type */ - r.w.bx=0x0000; /* software cursor */ - r.w.cx=0x77ff; - r.w.dx=mousecursor<<8; - INT_86(0x33,&r,&r); + r.w.ax=0x000a; /* set text pointer type */ + r.w.bx=0x0000; /* software cursor */ + r.w.cx=0x77ff; + r.w.dx=mousecursor<<8; + INT_86(0x33,&r,&r); - r.w.ax=0x0013; /* set double speed threshold */ - r.w.dx=32; /* double speed threshold */ - INT_86(0x33,&r,&r); + r.w.ax=0x0013; /* set double speed threshold */ + r.w.dx=32; /* double speed threshold */ + INT_86(0x33,&r,&r); - r.w.ax=0x0001; /* show mouse pointer */ - INT_86(0x33,&r,&r); } + r.w.ax=0x0001; /* show mouse pointer */ + INT_86(0x33,&r,&r); } -#endif + #endif -if(!(uifc_status&UIFC_COLOR) - && (uifc_status&UIFC_MONO - || txtinfo.currmode==MONO || txtinfo.currmode==BW80)) { - bclr=BLACK; - hclr=WHITE; - lclr=LIGHTGRAY; - cclr=LIGHTGRAY; } -else { - textmode(C80); - bclr=BLUE; - hclr=YELLOW; - lclr=WHITE; - cclr=CYAN; } -for(i=0;i<8000;i+=2) { - blk_scrn[i]='°'; - blk_scrn[i+1]=cclr|(bclr<<4); } + if(!(api->mode&UIFC_COLOR) + && (api->mode&UIFC_MONO + || txtinfo.currmode==MONO || txtinfo.currmode==BW80)) { + bclr=BLACK; + hclr=WHITE; + lclr=LIGHTGRAY; + cclr=LIGHTGRAY; + } else { + bclr=BLUE; + hclr=YELLOW; + lclr=WHITE; + cclr=CYAN; + } + for(i=0;iscrn_len,blk_scrn)) + return(-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]; @@ -195,16 +312,37 @@ else puttext(x1,y1,x2,y2-1,buf+(((x2-x1)+1)*2)); } -/**************************************************************************/ -/* General menu display function. SCRN_* macros define virtual screen */ -/* limits. *cur is a pointer to the current option. Returns option number */ -/* positive value for selected option or -1 for ESC, -2 for INS or -3 for */ -/* DEL. Menus can centered left to right and top to bottom automatically. */ -/* mode bits are set with macros WIN_* */ -/* option is an array of char arrays, first element of last char array */ -/* must be NULL. */ -/**************************************************************************/ -int ulist(int mode, char left, int top, char width, int *cur, int *bar +/****************************************************************************/ +/* Updates time in upper left corner of screen with current time in ASCII/ */ +/* Unix format */ +/****************************************************************************/ +static void timedisplay(void) +{ + static time_t savetime; + time_t now; + +now=time(NULL); +if(difftime(now,savetime)>=60) { + uprintf(55,1,bclr|(cclr<<4),utimestr(&now)); + savetime=now; } +} + +/****************************************************************************/ +/* Truncates white-space chars off end of 'str' */ +/****************************************************************************/ +static void truncsp(char *str) +{ + uint c; + + c=strlen(str); + while(c && (uchar)str[c-1]<=' ') c--; + str[c]=0; +} + +/****************************************************************************/ +/* General menu function, see uifc.h for details. */ +/****************************************************************************/ +int ulist(int mode, int left, int top, int width, int *cur, int *bar , char *title, char **option) { uchar line[256],shade[256],win[MAX_BFLN],*ptr,a,b,c,longopt @@ -227,7 +365,7 @@ INT_86(0x33,&r,&r); /* Clears any buffe #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; @@ -236,14 +374,14 @@ if(mode&WIN_GET) bline|=BL_GET; if(mode&WIN_PUT) bline|=BL_PUT; bottomline(bline); while(optsscrn_len-3) - height=(scrn_len-3)-top; +if(top+height>api->scrn_len-3) + height=(api->scrn_len-3)-top; if(!width || widthscrn_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) { - cprintf("UIFC: error allocating %u bytes.",(width+3)*(height+2)*2); + 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) { - cprintf("UIFC: error allocating %u bytes.",(width+3)*(height+2)*2); + && (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 __OS2__ +#ifndef __FLAT__ if(show_free_mem) { #if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__) uprintf(58,1,bclr|(cclr<<4),"%10ld bytes free",farcoreleft()); @@ -304,8 +444,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); @@ -316,7 +456,7 @@ ptr=win; *(ptr++)='É'; *(ptr++)=hclr|(bclr<<4); -if(uifc_status&UIFC_MOUSE) { +if(api->mode&UIFC_MOUSE) { *(ptr++)='['; *(ptr++)=hclr|(bclr<<4); *(ptr++)='þ'; @@ -462,12 +602,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); @@ -534,12 +674,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 @@ -554,7 +694,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 @@ -566,12 +706,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 @@ -689,7 +829,7 @@ hitesc: ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); showmouse(); } break; -/* +#if 0 case 0x49; /* PgUp */ case 0x51; /* PgDn */ if(!opts || (*cur)==(opts-1)) @@ -706,7 +846,7 @@ hitesc: puttext(SCRN_LEFT+3+left,SCRN_TOP+y ,SCRN_LEFT+left+width-2,SCRN_TOP+y,line); - for(i=(opts+4)-height,j=0;isavnum].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) + case '\b': /* backspace */ + if(mode&WIN_ESC || (mode&WIN_CHE && api->changes) && !(mode&WIN_SAV)) { hidemouse(); gettext(SCRN_LEFT+left,SCRN_TOP+top,SCRN_LEFT @@ -1015,15 +1151,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(-1); } } } else - mswait(0); + mswait(1); } } @@ -1031,8 +1167,8 @@ hitesc: /*************************************************************************/ /* This function is a windowed input string input routine. */ /*************************************************************************/ -int uinput(int mode, char left, char top, char *prompt, char *str, - char max, int kmode) +int uinput(int mode, int left, int top, char *prompt, char *str, + int max, int kmode) { unsigned char c,tmp[81],save_buf[2048],in_win[2048] ,shade[160],width,height=3; @@ -1046,7 +1182,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) @@ -1064,7 +1200,7 @@ in_win[i++]='º'; in_win[i++]=hclr|(bclr<<4); if(plen) { - in_win[i++]=SP; + in_win[i++]=' '; in_win[i++]=lclr|(bclr<<4); } for(c=0;prompt[c];c++) { @@ -1077,7 +1213,7 @@ if(plen) { c++; } for(c=0;cmode&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; -} - -/****************************************************************************/ -/* Updates time in upper left corner of screen with current time in ASCII/ */ -/* Unix format */ -/****************************************************************************/ -void timedisplay() -{ - static time_t savetime; - time_t now; - -now=time(NULL); -if(difftime(now,savetime)>=60) { - uprintf(55,1,bclr|(cclr<<4),timestr(&now)); - savetime=now; } +if(api->savdepth) api->savnum--; +api->mode&=~UIFC_INMSG; } /****************************************************************************/ @@ -1156,10 +1277,10 @@ if(difftime(now,savetime)>=60) { /* 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 str[256],ch,ins=0,buf[256],y; - int i,j,k,f=0; /* i=offset, j=length */ + uchar ch,str[256],ins=0,buf[256],y; + int i,j,k,f=0; /* i=offset, j=length */ #ifndef __FLAT__ union REGS r; #endif @@ -1179,7 +1300,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); @@ -1195,7 +1316,7 @@ if(mode&K_EDIT) { _setcursortype(cursor); return(-1); } } #endif - mswait(0); + mswait(1); } f=inkey(0); gotoxy(wherex()-i,y); @@ -1214,7 +1335,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); @@ -1236,9 +1357,7 @@ while(1) { if(!ch) { switch(k>>8) { case 0x3b: /* F1 Help */ - #if HELP help(); - #endif continue; case 0x4b: /* left arrow */ if(i) { @@ -1273,7 +1392,7 @@ while(1) { gettext(wherex()+1,y,wherex()+(j-i),y,buf); puttext(wherex(),y,wherex()+(j-i)-1,y,buf); gotoxy(wherex()+(j-i),y); - putch(SP); + putch(' '); gotoxy(wherex()-((j-i)+1),y); for(k=i;k=SP || (ch==1 && mode&K_MSG)) && i=' ' || (ch==1 && mode&K_MSG)) && ichanges=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(int x, int 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); } /****************************************************************************/ -/* display bottom line of screen in inverse */ +/* Display bottom line of screen in inverse */ /****************************************************************************/ 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),"Get Item "); - i+=10; } + 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),"Put Item "); - i+=10; } + 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(); } @@ -1430,7 +1529,7 @@ clreol(); /* Generates a 24 character ASCII string that represents the time_t pointer */ /* Used as a replacement for ctime() */ /*****************************************************************************/ -char *timestr(time_t *intime) +char *utimestr(time_t *intime) { static char str[25]; char wday[4],mon[4],mer[3],hour; @@ -1511,58 +1610,54 @@ return(str); } /****************************************************************************/ -/* Truncates white-space chars off end of 'str' and terminates at first tab */ +/* Status popup/down function, see uifc.h for details. */ /****************************************************************************/ -void truncsp(char *str) -{ - char c,tmp[256]; - -tmp[0]=TAB; -tmp[1]=0; -str[strcspn(str,tmp)]=0; -c=strlen(str); -while(c && (uchar)str[c-1]<=SP) c--; -str[c]=0; -} - void upop(char *str) { static char sav[26*3*2]; char buf[26*3*2]; int i,j,k; -hidemouse(); -if(!str) { - puttext(28,12,53,14,sav); + hidemouse(); + if(!str) { + puttext(28,12,53,14,sav); + showmouse(); + return; } + gettext(28,12,53,14,sav); + memset(buf,' ',25*3*2); + for(i=1;i<26*3*2;i+=2) + buf[i]=(hclr|(bclr<<4)); + buf[0]='Ú'; + for(i=2;i<25*2;i+=2) + buf[i]='Ä'; + buf[i]='¿'; i+=2; + buf[i]='³'; i+=2; + i+=2; + k=strlen(str); + i+=(((23-k)/2)*2); + for(j=0;jhelpbuf) { + if((fp=_fsopen(api->helpixbfile,"rb",SH_DENYWR))==NULL) + sprintf(hbuf," ERROR  Cannot open help index:\r\n %s" + ,api->helpixbfile); else { - if((fp=_fsopen(helpdatfile,"rb",SH_DENYWR))==NULL) - sprintf(hbuf," ERROR  Cannot open help file:\r\n %s" - ,helpdatfile); + p=strrchr(helpfile,'/'); + if(p==NULL) + p=strrchr(helpfile,'\\'); + if(p==NULL) + p=helpfile; + else + p++; + l=-1L; + while(!feof(fp)) { + if(!fread(str,12,1,fp)) + break; + str[12]=0; + fread(&line,2,1,fp); + if(stricmp(str,p) || line!=helpline) { + fseek(fp,4,SEEK_CUR); + continue; } + fread(&l,4,1,fp); + break; } + fclose(fp); + if(l==-1L) + sprintf(hbuf," ERROR  Cannot locate help key (%s:%u) in:\r\n" + " %s",p,helpline,api->helpixbfile); else { - fseek(fp,l,SEEK_SET); - fread(hbuf,HELPBUF_SIZE,1,fp); - fclose(fp); } } } } -else - strcpy(hbuf,helpbuf); + if((fp=_fsopen(api->helpdatfile,"rb",SH_DENYWR))==NULL) + sprintf(hbuf," ERROR  Cannot open help file:\r\n %s" + ,api->helpdatfile); + else { + fseek(fp,l,SEEK_SET); + fread(hbuf,HELPBUF_SIZE,1,fp); + fclose(fp); } } } } + else + strcpy(hbuf,api->helpbuf); -len=strlen(hbuf); + len=strlen(hbuf); -i+=78*2; -for(j=0;jmode&UIFC_MOUSE) { + r.w.ax=0x0006; /* Get button release information */ + r.w.bx=0x0000; /* Left button */ + INT_86(0x33,&r,&r); + if(r.w.bx) /* Left button release same as CR */ + break; + r.w.ax=0x0006; /* Get button release information */ + r.w.bx=0x0001; /* Right button */ + INT_86(0x33,&r,&r); + if(r.w.bx) /* Left button release same as CR */ + break; } + #endif + mswait(1); + } -hidemouse(); -puttext(1,1,80,25,savscrn); -showmouse(); -FREE(savscrn); -FREE(buf); -_setcursortype(cursor); + hidemouse(); + puttext(1,1,80,25,savscrn); + showmouse(); + FREE(savscrn); + FREE(buf); + _setcursortype(cursor); } -#endif - -#if defined(__WIN32__) && !defined(__DPMI32__) -int delay(int ms) -{ - clock_t start; - -start=clock(); -while(clock()-start