home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Boldly Go Collection
/
version40.iso
/
TS
/
17A
/
DRWIN101.ZIP
/
WUTIL2.C
< prev
Wrap
C/C++ Source or Header
|
1991-07-23
|
22KB
|
452 lines
/****************************************************************************/
/* wutil2.c */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* More windowing funcs. */
/****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include "strutil.h"
#include "scrutil.h"
#include "wutil.h"
/****************************************************************************/
/* wgetsfield */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* This function reads a string in from a window. It ends when CR is */
/* pressed. It reads the string from a field of width w located at the */
/* window's current cursor position. If w is 0, the rest of the row is */
/* used. Use the cursor and editing keys. Ctrl-Y will clear the string. */
/* a is the attribute to use for the string's characters. */
/*-----------------------------Arguments------------------------------------*/
/* WIND *ww window in which to get string */
/* BYTE *s string to receive characters */
/* int n maximum number of characters to read */
/* int w width of the field for entry */
/* WORD a attribute for characters, 0=same as window's */
/*-----------------------------Return value---------------------------------*/
/* Returns the key pressed to end the sequence. */
/*-----------------------------Constraints/Gotchas--------------------------*/
/*--Date--------Programmer----------Comments--------------------------------*/
/* 1990.11.08 dr initial code */
/****************************************************************************/
int wgetsfield(WIND *ww,char *s,int n,int w,WORD a)
{
#define INS_SIZ 0x000C
int sr,sc; /*starting row and column of field*/
WORD sa,ss; /*starting attribute and curs size*/
WORD os=INS_SIZ; /*overwrite cursor size*/
int l; /*length of string*/
int c=0; /*cursor position inside window*/
int o=0; /*offset of first cell in window*/
int i; /*local*/
int ch; /*character read*/
wflags sf; /*flags*/
char end=0; /*end of routine*/
char ins=0; /*insert mode*/
if (!winitd) return 0; /*windows not initialized*/
if (ww==NULL) return 0; /*bad window pointer*/
sr=ww->row; /*get current row*/
sc=ww->col; /*get current col*/
sa=ww->attr; /*get current attribute*/
if (a==0) a=sa; /*if no attribute, use current*/
ss=ww->csiz; /*get current cursor size*/
sf=ww->fl; /*save the flags*/
ww->fl.wrap=0; /*no wrap*/
ww->fl.scroll=0; /*no scroll*/
n--; /*decrement so lengths are easy*/
l=strlen(s); /*get starting string length*/
if (l>n) l=0; /*if bigger than allowed, kill*/
if (l>n) return 0; /*if n was 0, then return*/
if (ins) /*if insert mode..*/
ww->csiz=DEF_CSIZE; /*..set cursor size to default*/
else /*otherwise..*/
ww->csiz=os; /*..set size to overstrike size*/
wupd=1; /*window updating is on*/
ww->fl.alive=1; /*make sure window is visible*/
wfront(ww); /*bring window to front*/
if (w<=1) w=ww->cols-sc; /*if no width, use rest of row*/
if (w<=1) return 0; /*will not fit on row*/
while (!end) { /*go 'til end*/
wupd=0; /*turn off update 'til done*/
wsetcpos(ww,sr,sc); /*start position*/
ww->attr=sa; /*original attributes*/
for (i=0;i<w;i++) wputc(ww,' '); /*blank out requested region*/
wsetcpos(ww,sr,sc); /*back to start*/
ww->attr=a; /*use passed attributes*/
for (i=0;i<w;i++) { /*start writing the string*/
if ((o+i)==l) break; /*if end of string, end it*/
wputc(ww,s[o+i]); /*write out string characters*/
} /*for*/
wsetcpos(ww,sr,sc+c); /*place cursor*/
wupdate(ww); /*update windows*/
ch=wgetc(ww); /*get input character from kb*/
switch (ch) {
case C_Y: /*ctrl-Y clears line*/
case A_D:
l=0;
o=0;
c=0;
break;
case DEL: /*DEL and BS move left and delete*/
case BS:
if ((o+c)==0)
break;
else {
c--;
if (c<0) {
c=0;
if (o) o--;
}
} /*else delete should be ok*/
/*fall through to delete*/
case _DEL: /*Del deletes the current character*/
case C_G: /*make sure any changes work w/above*/
if ((o+c)>=l) break;
l--;
for (i=o+c;i<l;i++) s[i]=s[i+1];
if (o&&(c<(w-1))) {
o--;
c++;
}
break;
case _LTAR: /*move left*/
case C_S:
c--;
if (c<0) {
c=0;
if (o) o--;
}
break;
case C_LTAR: /*move left one word*/
i=o+c;
if (i==0) break;
i--; /*look for space==>not-space*/
while (i && !(isspace(s[i-1]) && !isspace(s[i])) ) i--;
if (i>o) /*if still in window*/
c=i-o;
else {
c=0;
o=i;
}
break;
case _RTAR: /*move right*/
case C_D:
c++;
if ((o+c)>l)
c--;
else {
if (c>=w) { o++; c=w-1; }
}
break;
case C_RTAR: /*move right one word*/
i=o+c;
if (i>=l) break; /*already at end*/
i++; /*look for space==>not-space*/
while ((i<l) && !(isspace(s[i-1]) && !isspace(s[i])) ) i++;
c=i-o;
while (c>=w) { /*if not still in window*/
c--;
o++;
}
break;
case _HOME: /*go to beginning of string*/
case A_H:
case C_A:
c=0;
o=0;
break;
case _END: /*go to end of string*/
case C_F:
case A_E:
if (l<w) {
o=0;
c=l;
}
else {
o=l-w+1;
c=w-1;
}
break;
case C_HOME: /*delete from beginning*/
l-=o+c; /*subtract off chars up to cursor*/
for (i=0;i<l;i++) s[i]=s[o+c+i];
o=0;
c=0;
s[l]=0;
break;
case C_END: /*delete to end*/
l=o+c;
s[l]=0;
break;
case _INS: /*toggle insert mode*/
case C_V:
case A_I:
ins=!ins;
if (ins)
wsetcsiz(ww,DEF_CSIZE); /*use default cursor size on ins*/
else
wsetcsiz(ww,os); /*use big cursor for overwrite*/
break;
default:
if ((ch>=0x100)||(ch==ESC)||(ch==CR))
end=1; /*special char...hit the road*/
else if (ch>=' ') { /*if normal char, place in string*/
if (!ins) {
if ((o+c)>=n) break; /*if no room, stop*/
s[o+c]=ch;
c++;
if (c>=w) { c=w-1; o++; }
if ((o+c)>l) l=o+c;
} /*if overwrite*/
else if (l<n) {
l++;
for (i=l;i>(o+c);i--) s[i]=s[i-1];
s[o+c]=ch;
c++;
if (c>=w) { c=w-1; o++; }
if ((o+c)>l) l=o+c;
} /*else insert mode and string not already too long*/
} /*if not special key*/
} /*switch*/
} /*while*/
s[l]=0; /*mark end of string*/
wupd=0; /*turn off update 'til done*/
wsetcpos(ww,sr,sc); /*start position*/
ww->attr=sa; /*original attributes*/
for (i=0;i<w;i++) wputc(ww,' '); /*blank out requested region*/
wsetcpos(ww,sr,sc); /*back to start*/
for (i=0;i<w;i++) { /*start writing the string*/
if ((o+i)==l) break; /*if end of string, end it*/
wputc(ww,s[o+i]); /*write out string characters*/
} /*for*/
wsetcpos(ww,sr,sc); /*place cursor*/
wsetcsiz(ww,ss); /*restore starting size*/
ww->fl=sf; /*restore original flags*/
wupdate(ww); /*update windows*/
return ch; /*return the char that caused end*/
} /*wgetsfield*/
/****************************************************************************/
/* wgetfields */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* This function gets data from input fields in various formats. The */
/* fields are described in an array of WFIELDs. Unsupplied formats will */
/* be provided (see xxxx_FMT macros in wutil.h). */
/*-----------------------------Arguments------------------------------------*/
/* WIND *w window in which input is to occur */
/* WFIELD *f pointer to first element of WFIELD array */
/* int nf number of fields; if 0, go 'til first data ptr NULL */
/* WORD a attribute for highlighted field */
/*-----------------------------Return value---------------------------------*/
/* Returns character used to exit the data entry process; 0 on error. */
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Constraints/Gotchas--------------------------*/
/*--Date--------Programmer----------Comments--------------------------------*/
/* 1990.01.01 A. Turing initial code */
/****************************************************************************/
int wgetfields(WIND *w,WFIELD *f,int nf,WORD a) /*gets info from fields*/
{
WFIELD *fp; /*local field pointer*/
int i; /*local index*/
if (!winitd) return 0; /*windows not available*/
if (w==NULL) return 0; /*bad window*/
if (f==NULL) return 0; /*bad field pointer*/
if (nf==0) for (fp=f;fp->d;fp++) nf++; /*calculate number of fields*/
if (nf==0) return 0; /*no fields*/
for (i=0;i<nf;i++) {
switch(f[i].t) { /*switch on type*/
case WCHAR: if (!f[i].f) f[i].f=WCHAR_FMT; break;
case WUCHAR: if (!f[i].f) f[i].f=WUCHAR_FMT; break;
case WINT: if (!f[i].f) f[i].f=WINT_FMT; break;
case WUINT: if (!f[i].f) f[i].f=WUINT_FMT; break;
case WLONG: if (!f[i].f) f[i].f=WLONG_FMT; break;
case WULONG: if (!f[i].f) f[i].f=WULONG_FMT; break;
case WFLOAT: if (!f[i].f) f[i].f=WFLOAT_FMT; break;
case WDOUBLE: if (!f[i].f) f[i].f=WDOUBLE_FMT; break;
case WLDOUBLE: if (!f[i].f) f[i].f=WLDOUBLE_FMT; break;
case WSTRING: if (!f[i].f) f[i].f=WSTRING_FMT; break;
default: return 0; /*illegal type specified*/
} /*switch on type*/
} /*for*/
/*all fields look good now...*/
for (i=0;i<nf;i++) {
} /*for*/
return ESC;
} /*wgetfields*/
/****************************************************************************/
/* wfile */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* This function displays the specified text file in a window. It does */
/* NOT clear the window when finished, nor does it hide the window. */
/* A FF (formfeed) can be used to force a page break within the file. */
/*-----------------------------Arguments------------------------------------*/
/* WIND *w window in which to show the file */
/* char *fn name of file to show */
/*-----------------------------Return value---------------------------------*/
/* Returns 1 on success, 0 on error (bad window or unsuccessful file */
/* open). */
/*--Date--------Programmer----------Comments--------------------------------*/
/* 1990.11.09 dr initial code */
/****************************************************************************/
int wfile(WIND *w,char *fn)
{
char s[256];
char *p;
FILE *f;
int r=0;
wflags fl;
int c=0;
if (!winitd) return 0; /*if not init'd, return*/
if (w==NULL) return 0; /*if bad pointer, return*/
f=fopen(fn,"rt"); /*try to open the helpfile*/
if (f==NULL) return 0; /*if not there, return*/
wupd=0; /*build screen before updating*/
fl=w->fl; /*save flags for later*/
w->fl.scroll=1; /*scrolling on*/
w->fl.wrap=0; /*no wrap, though*/
w->fl.alive=1; /*active window*/
wfront(w); /*push window to front*/
wclr(w); /*clear it*/
wupdate(w); /*now display it*/
while (fgets(s,256,f)!=NULL) { /*go 'til EOF*/
p=strchr(s,FF); /*look for page break*/
if ((r>=(w->rows-1))||p) { /*end of page*/
if (p) *p=' '; /*clear end of page*/
if (w->col) wputc(w,'\n'); /*if not at end of line*/
wputs(w,"***press any key, <ESC> to quit***");
c=wgetc(w); /*get key from user*/
wputc(w,'\r'); /*go to beg of row*/
wclreor(w); /*clear it*/
if (c==ESC) break; /*if person hit ESC, end*/
r=0;
} /*if end of page*/
wputs(w,s);
r++;
} /*while not EOF*/
if (c!=ESC) {
if (w->col) wputc(w,'\n'); /*if not at end of line*/
wputs(w,"***press any key***"); /*put out prompt*/
wgetc(w); /*get keypress from user*/
wputc(w,'\r'); /*go to beg of row*/
wclreor(w); /*clear it*/
} /*if at end*/
w->fl=fl; /*restore the window's flags*/
fclose(f); /*close the file*/
return 1; /*report success*/
} /*wfile*/
/****************************************************************************/
/* hotlen */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* This function returns the length of a string, less the number of */
/* "hotkey" flag characters in the string. A hotkey can be used to */
/* indicate any number of things -- it is used by wputshot() to indicate */
/* that an alternative attribute is to be selected. A double hotkey */
/* sequence is reduced to a single occurrence of the key: */
/* hotlen("&Test",'&') == 4 */
/* hotlen("%Hot=%%",'&') == 5 */
/*-----------------------------Arguments------------------------------------*/
/* char* s pointer to string to count */
/* char hotkey char to use as hotkey flag */
/*-----------------------------Return value---------------------------------*/
/* Returns length of string, less hotkey flags. */
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Examples-------------------------------------*/
/*-----------------------------Constraints/Gotchas--------------------------*/
/*--Date--------Programmer----------Comments--------------------------------*/
/* 1990.01.01 A. Turing initial code */
/****************************************************************************/
int hotlen(char* s,char hotkey)
{
int l=0; /*length of hotkey string*/
while (*s) { /*go 'til end of string*/
l++;
if (*s++==hotkey) { /*if hotkey..*/
if (*s) s++; /*..if somthin' there, skip it*/
} /*else hotkey*/
} /*while*/
return l;
} /*hotlen*/
/****************************************************************************/
/* wputshot */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* This function puts out a string to a window, using an alternative */
/* attribute for those characters labelled as hotkeys (preceded by the */
/* hotkey argument). */
/*-----------------------------Arguments------------------------------------*/
/* WIND* w window in which to write the string */
/* char* s string to write */
/* WORD hat hotkey attribute */
/* char hotkey hotkey flag indicator */
/*-----------------------------Return value---------------------------------*/
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Examples-------------------------------------*/
/* This example writes a command bar to a window: */
/* w=wopen(0,NULL, 0,0, 1,80, ATTR(BLACK,LIGHTGRAY)); */
/* wputshot(w,"&F&1-&Help &F&2-&Save",ATTR(RED,LIGHTGRAY),'&'); */
/*-----------------------------Constraints/Gotchas--------------------------*/
/*--Date--------Programmer----------Comments--------------------------------*/
/* 1990.01.01 A. Turing initial code */
/****************************************************************************/
void wputshot(WIND* w,char *s,WORD hat,char hotkey)
{
char twupd; /*windowing update flag*/
WORD wat; /*current window attribute*/
twupd=wupd; /*save update flag*/
wupd=0; /*no updating 'til done*/
wat=w->attr; /*save current window attributes*/
for (;*s;s++) { /*go through each char*/
if (*s!=hotkey) { /*..normal char*/
wputc(w,*s); /*....write it*/
continue; /*....continue looping*/
} /*if normal char*/
s++; /*..go to next char*/
if (!*s) s--; /*..if nothing after &, double it*/
if (*s==hotkey) /*..hot key doubled*/
wputc(w,*s); /*....put out hotkey indicator*/
else {
w->attr=hat; /*..switch to hotkey attributes*/
wputc(w,*s); /*..put out the char*/
w->attr=wat; /*..go back to window attributes*/
} /*if writing with hat*/
} /*for each char*/
wupd=twupd; /*restore update flag*/
if (wupd) wupdate(w); /*update if necessary*/
} /*wputshot*/