#include #include #include #include #include #include #include /*=========================================================================*/ /* iolib.c -- library of i/o functions for use from Turbo C */ /* by John Queern, Belleville, IL (public domain) */ /*=========================================================================*/ /* function prototypes */ char *strdel(char st[],int start,int count);/* delete substring from string */ int nonblank (char *st); /* return true if st not blank */ void beep(void); /* a milder "bell" */ void stub(void); /* make sound to signify stub */ void binit(int buffs); /* initialize video buffers */ void savescreen(int i); /* save screen to buff i */ void save2buff(char *buff); /* save " to user's buffer */ void restorescreen(int i); /* restore screen from buff i */ void copyscreen(int i,int j); /* copy buff i to buff j */ void bclear(int b); /* clear buff b */ void bwrite(int b,int x,int y,char st[]); /* write st to buff b at x,y */ void cwrite(int b,int x,int y,char st[], char co[]); /* " " with color map */ void sputsxy(int x,int y,char st[]); /* put string at x,y; keep attr */ void sputchxy(int x,int y,char ch); /* putchar at x,y; keep attrib */ void cputchxy(int x,int y,char ch,int attr); /* " " with new attr */ void border(int color); /* set border color */ void pad(char st[],int len); /* pad a string to length len */ void trim(char st[]); /* trim off trailing blanks, \n's */ char *lcase(char st[]); /* convert string to l.case */ char *ucase(char st[]); /* convert string to u.case */ int getstring(int x,int y,int *c, /* wordStar-like string input */ char st[],int len); /* routine */ int getint(int x,int y,int *i,int w); /* integer input routine */ int getachar(int x,int y,char *ch); /* char input routine */ int getfloat(int x,int y, float *f, /* float input routine */ int w, int d); /** see ioed.c for additional editor-in-a-box functions **/ /*=========================================================================*/ /* definitions and declarations */ #define TRUE 1 #define FALSE 0 #define MAXBUFFERS 10 /* max screen buffers to permit */ typedef unsigned char vscreen[4000]; typedef vscreen far *vptr; vptr sbuff[MAXBUFFERS]; /* screen buffer pointers */ vptr crtscreen; /* physical screen buffer */ char monochrome=0; /* mono flag */ char insert=0; /* insert/overwrite flag */ int insertx=60,inserty=1; /* location of insert/overwrite message */ int colx=0,coly=0; /* location of column info, if present */ int trimblanks=0; /* make true for getstring to trim blanks */ int colons=0; /* make true for getstring to use colons */ int nobeep=0; /* make true to suppress end-field beep */ int bfore=15,bback=0; /* buffer foreground, background colors */ int buffers=0; /* actual buffers initialized */ /*=========================================================================*/ char *strdel(char st[],int start,int count) /* delete chars from string starting at */ { int i,l; l = strlen(st); for (i=start;iMAXBUFFERS) buff=MAXBUFFERS; for ( i = buffers; i < buff; ++i ) { sbuff[i] = (vptr)calloc(1,sizeof(*sbuff[i])); } /* if first time through, determine whether display is monochrome or color */ if (buffers==0) { regs.x.ax = 0; int86(17,®s,®s); /*equipment list call*/ if ( (regs.h.al & 48) == (48) ) { monochrome = TRUE; crtscreen = MK_FP(0xb000,0); } else { monochrome = FALSE; crtscreen = MK_FP(0xb800,0); } } buffers = buff; } /*====================================================*/ void savescreen(int i) { unsigned char b; if (i>=buffers) binit(i+1); /*blank screen*/ /* b = peek(0,1125); outportb(984,(b & 240) | 1); */ if ( monochrome ) { movedata(0xb000,0,FP_SEG(sbuff[i]),FP_OFF(sbuff[i]),4000); } else { movedata(0xb800,0,FP_SEG(sbuff[i]),FP_OFF(sbuff[i]),4000); } /* restore screen */ /* outportb(984,b); */ } /*====================================================*/ void save2buff(char *buff) /* save screen image to user's 4000-char buffer */ { unsigned char b; if ( monochrome ) { movedata(0xb000,0,FP_SEG(buff),FP_OFF(buff),4000); } else { movedata(0xb800,0,FP_SEG(buff),FP_OFF(buff),4000); } } /*====================================================*/ void restorescreen(int i) { unsigned char b; if (i>=buffers) binit(i+1); /*blank screen*/ /* b = peek(0,1125); outportb(984,(b & 240) | 1); */ if ( monochrome ) { movedata(FP_SEG(sbuff[i]),FP_OFF(sbuff[i]),0xb000,0,4000); } else { movedata(FP_SEG(sbuff[i]),FP_OFF(sbuff[i]),0xb800,0,4000); } /* poke(0,1125,b & 223); outportb(984,b & 223); */ } /*====================================================*/ void copyscreen(int i,int j) { if (i>=buffers || j>=buffers) binit(max(i,j)+1); if ((i<0) || (i>4)) { return; } movedata(FP_SEG(sbuff[i]),FP_OFF(sbuff[i]), FP_SEG(sbuff[j]),FP_OFF(sbuff[j]),4000); } /*====================================================*/ void bclear(int b) { int i; if (b>=buffers) binit(b+1); i = 0; while ( i < 4000 ) { (*sbuff[b])[i] = 32; /*ASCII blank*/ (*sbuff[b])[i + 1] = (bback) * 16 + bfore; i += 2; } } /*bclear*/ /*====================================================*/ void bwrite(int b,int x,int y,char st[]) { int i; int p; struct text_info t; if (b>=buffers) binit(b+1); gettextinfo(&t); p = ((y - 1) * (t.screenwidth * 2)) + ((x - 1) * 2) ; /*start position */ for ( i = 0; i < strlen(st); i++) { (*sbuff[b])[p] = st[i]; (*sbuff[b])[p + 1] = (bback) * 16 + bfore; p += 2; } /*for i*/ } /*bwrite*/ /*====================================================*/ void cwrite(int b,int x,int y,char st[], char co[]) /* colored bwrite -- with added color map */ { int i; int p; struct text_info t; if (b>=buffers) binit(b+1); gettextinfo(&t); p = ((y - 1) * (t.screenwidth * 2)) + ((x - 1) * 2) ; /*start position */ for ( i = 0; i < strlen(st); i++) { (*sbuff[b])[p] = st[i]; (*sbuff[b])[p + 1] = co[i]; p += 2; } /*for i*/ } /*bwrite*/ /*====================================================*/ void sputsxy(int x,int y,char st[]) /* bwrite to the physical screen at x,y using existing attribute */ { int i; int p; struct text_info t; gettextinfo(&t); p = ((y - 1) * (t.screenwidth * 2)) + ((x - 1) * 2) ; /*start position */ for ( i = 0; i < strlen(st); i++) { (*crtscreen)[p] = st[i]; p += 2; } /*for i*/ } /* sputsxy */ /*====================================================*/ void sputchxy(int x,int y,char ch) /* putchar to the physical screen at x,y using existing attribute */ { int i; int p; struct text_info t; gettextinfo(&t); p = ((y - 1) * (t.screenwidth * 2)) + ((x - 1) * 2) ; /*start position */ (*crtscreen)[p] = ch; } /* sputchxy */ /*====================================================*/ void cputchxy(int x,int y,char ch,int attr) /* putchar to the physical screen at x,y using given attribute */ { int i; int p; struct text_info t; gettextinfo(&t); p = ((y - 1) * (t.screenwidth * 2)) + ((x - 1) * 2) ; /*start position */ (*crtscreen)[p] = ch; (*crtscreen)[p+1] = attr; } /* cputchxy */ /*=========================================================================*/ void border(int color) { union REGS regs; regs.h.ah = 11; /*set color palette*/ regs.h.bh = 0; regs.h.bl = color; int86(16,®s,®s); /*video services*/ } /*border*/ /*=========================================================================*/ void pad(char st[],int len) /* pad the length of string st to len chars */ { char *cp; int i; /* find end of string */ for (cp=st,i=0; (*cp != 0) && (i= 0) && ((st[i] == ' ') || (st[i] == '\n')) ) i--; if ((st[i] == ' ') || (st[i] == '\n')) st[i]=0; else st[i+1]=0; } } /*=========================================================================*/ char *lcase(char st[]) /* trim and convert string st to lower case */ { trim(st); while (*st != NULL) tolower(*(st++)); return(st); } /*=========================================================================*/ char *ucase(char st[]) /* trim and convert string st to upper case */ { trim(st); while (*st != NULL) toupper(*(st++)); return(st); } /*========================================================================*/ int getstring(int x,int y,int *c,char st[],int len) /* x,y are the position where the field begins; c is the cursor column within the field (0 for 1st position); c is updated by getstring() */ /* return codes (based on exit keystroke): 0: CR, original entry changed 1: CR, original entry unchanged 2: Esc 3: up arrow, ctrl-e 4: left arrow, ctrl-s 5: right arrow, ctrl-d 6: down arrow, ctrl-x 7: ctrl-w 8: End 9: PgUp, ctrl-r 10: PgDn, ctrl-c 11-20: F1..F10 21: ctrl-y 22: ctrl-z 23: ctrl-n 24: Home 25: ctrl-b 26: ctrl-u 27: ctrl-l 28: ctrl-k */ { int _fret, i, n, p, nn; char ch, c2, ch2, *cp; char *blankfield,*model,temp[20]; if (colons) { sputchxy(x-1,y,':'); sputchxy(x+len,y,':'); } if ( insert ) sputsxy(insertx,inserty," INSERT "); else sputsxy(insertx,inserty," OVERWRITE "); model=(char *)calloc(1,len+1); strcpy(model,st); /* make reference copy */ blankfield=(char *)calloc(1,len+1); blankfield[0]=0; pad(blankfield,len); pad(st,len); sputsxy(x,y,st); n = *c; do { gotoxy(x + n,y); ch = getch(); /*handle special characters*/ if ( ch == 0 ) { /* IBM PC special char sequence */ c2 = getch(); /* get second char */ /* return predefined exit codes for F1..F10 (11..20) */ if ((c2 >= 59) && (c2 <= 68)) { _fret = c2 - 48; goto L99; } switch ( c2 ) { case 72 : /* up arrow */ ch = 5; /* convert to ctrl-e */ break; case 80 : /* down arrow */ ch = 24; /* convert to ctrl-x */ break; case 75 : /* left arrow */ ch = 19; /* convert to ctrl-s */ break; case 77 : /* right arrow */ ch = 4; /* convert to ctrl-d */ break; case 73 : /* PgUp */ ch = 18; /* convert to ctrl-r */ break; case 81 : /* PgDn */ ch = 3; /* convert to ctrl-c */ break; case 82 : /* Ins */ ch = 22; /* convert to ctrl-v */ break; case 83 : /* Del */ ch = 7; /* convert to ctrl-g */ break; case 79 : /* End */ _fret = 8; goto L99; case 71 : /* Home */ _fret = 24; /* return code 24 */ goto L99; default: ch = 0; break; } /* switch */ } /* if special */ switch ( ch ) { /* Esc */ case 27 : _fret = 2; goto L99; case 13 : /* CR */ if (strcmp(st,model)==0) _fret = 1; else _fret = 0; if (y<25) (y)++; goto L99; case 5 : /* ctrl-e */ _fret = 3; goto L99; case 19 : /* ctrl-s */ if ( n == 0 ) { _fret = 4; goto L99; } else n--; break; case 4 : /* ctrl-d */ if ( n == len-1 ) { _fret = 5; goto L99; } else n++; break; case 21 : /* ctrl-u */ _fret = 26; goto L99; case 24 : /* ctrl-x */ _fret = 6; goto L99; case 23 : /* ctrl-w */ _fret = 7; goto L99; case 18 : /* ctrl-r */ _fret = 9; goto L99; case 3 : /* ctrl-c */ _fret = 10; goto L99; case 25 : /* ctrl-y */ strcpy(st,blankfield); n = 0; sputsxy(x,y,blankfield); _fret = 21; goto L99; case 26 : /* ctrl-z */ _fret = 22; goto L99; case 2 : /* ctrl-b */ _fret = 25; goto L99; case 14 : /* ctrl-n */ _fret = 23; goto L99; case 11 : /* ctrl-k */ _fret = 28; goto L99; case 12 : /* ctrl-l */ _fret = 27; goto L99; case 22 : /* ctrl-v */ insert = !(insert); if ( insert ) sputsxy(insertx,inserty," INSERT "); else sputsxy(insertx,inserty," OVERWRITE "); break; case 7 : /* ctrl-g */ for ( i = n; i < len - 1; i++ ) st[i] = st[i + 1]; st[len - 1] = ' '; sputsxy(x,y,st); break; case 20 : /* ctrl-t */ p = n; if (st[n] == ' ' ) while ( (p < len-1) && (st[p] == ' ') ) p++; else while ( (p < len-1) && (st[p] != ' ') ) p++; strdel(st,n,(p-n)); pad(st,len); sputsxy(x,y,st); break; case 9 : /* ctrl-i or TAB */ n++; while ((n0)) n--; if (n 0) && (st[n] != ' ')) n--; while ( (n > 0) && (st[n] == ' ')) n--; while ( (n > 0) && (st[n] != ' ' )) n--; if ( st[n] == ' ') n++; gotoxy(x + n,y); break; case 6 : /* ctrl-f */ /* find end of current word */ while ( (n < len - 1) && (st[n] != ' ') ) n++; nn = n; /* find beginning of nextg word */ while ( (n < len-1) && (st[n] == ' ') ) n++; if ( n == len -1) { /* no next word: back up */ n = nn; if (n= 8) && (ch <= 13))){ for ( i = len - 1; i > n ; i-- ) st[i] = st[i - 1]; st[n] = ch; sputsxy(x,y,st); } else { if (!((ch >= 8) && (ch <= 13)) ) { st[n] = ch; sputchxy(x+n,y,ch); /***/ /* gotoxy(x+n,y); */ } } if ( (ch == '\x08') && (n > 0) ) /*backing up*/ n--; else if (ch != '\x08') n++; } break; } /*switch/case*/ if (colx != 0) { sprintf(temp,"%3d",n+1); sputsxy(colx,coly,temp); } } while ( ! ((ch == '\x0D') || (n > len-1)) ); if ( n >= len-1 && !nobeep) beep(); _fret = 0; L99: if (trimblanks) { if ( st[0] != 0 ) { i = len-1; while ( (i >= 0) && (st[i] == ' ') ) i--; if (st[i] == ' ') st[i]=0; else st[i+1]=0; } } if (colons) { sputchxy(x-1,y,' '); sputchxy(x+len,y,' '); } (*c) = n; /* update cursor position */ return(_fret); } /*getstring*/ /*=========================================================================*/ int getint(int x,int y,int *i,int w) { int retcd,ret,col; char temp[80],format[20]; col=0; do { sprintf(format,"%%%dd",w); sprintf(temp,format,*i); retcd = getstring(x,y,&col,temp,w); trim(temp); ret = sscanf(temp, "%d", i); if (ret==0) putch('\a'); } while (ret == 0); sprintf(temp,format,*i); gotoxy(x,y); cputs(temp); return(retcd); } /* getint */ /*=========================================================================*/ int getachar(int x,int y,char *ch) { int retval,col; char temp[2]; col=0; temp[0]=*ch; temp[1]=0; retval = getstring(x,y,&col,temp,1); *ch = temp[0]; return(retval); } /*========================================================================*/ int getfloat(int x,int y, float *f, int w, int d) { int retcd,ret,col; char temp[80],format[20]; col=0; do { sprintf(format,"%%%d.%df",w,d); sprintf(temp,format,*f); retcd = getstring(x,y,&col,temp,w); trim(temp); ret = sscanf(temp, "%f", f); if (ret==0) putch('\a'); } while (ret == 0); sprintf(temp,format,*f); gotoxy(x,y); cputs(temp); return(retcd); } /* getfloat */