home *** CD-ROM | disk | FTP | other *** search
/ Boldly Go Collection / version40.iso / TS / 17A / DRWIN101.ZIP / WUTIL2.C < prev   
C/C++ Source or Header  |  1991-07-23  |  22KB  |  452 lines

  1. /****************************************************************************/
  2. /*  wutil2.c                                                                */
  3. /****************************************************************************/
  4. /*-----------------------------Description----------------------------------*/
  5. /*  More windowing funcs.                                                   */
  6. /****************************************************************************/
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <stdarg.h>
  10. #include <string.h>
  11. #include <conio.h>
  12. #include <dos.h>
  13.  
  14. #include "strutil.h"
  15. #include "scrutil.h"
  16. #include "wutil.h"
  17.  
  18.  
  19. /****************************************************************************/
  20. /*  wgetsfield                                                              */
  21. /****************************************************************************/
  22. /*-----------------------------Description----------------------------------*/
  23. /*  This function reads a string in from a window.  It ends when CR is      */
  24. /*  pressed.  It reads the string from a field of width w located at the    */
  25. /*  window's current cursor position.  If w is 0, the rest of the row is    */
  26. /*  used.  Use the cursor and editing keys.  Ctrl-Y will clear the string.  */
  27. /*  a is the attribute to use for the string's characters.                  */
  28. /*-----------------------------Arguments------------------------------------*/
  29. /*  WIND *ww           window in which to get string                        */
  30. /*  BYTE *s            string to receive characters                         */
  31. /*  int  n             maximum number of characters to read                 */
  32. /*  int  w             width of the field for entry                         */
  33. /*  WORD a             attribute for characters, 0=same as window's         */
  34. /*-----------------------------Return value---------------------------------*/
  35. /*  Returns the key pressed to end the sequence.                            */
  36. /*-----------------------------Constraints/Gotchas--------------------------*/
  37. /*--Date--------Programmer----------Comments--------------------------------*/
  38. /*  1990.11.08  dr                  initial code                            */
  39. /****************************************************************************/
  40. int  wgetsfield(WIND *ww,char *s,int n,int w,WORD a)
  41. {
  42. #define INS_SIZ        0x000C
  43.   int sr,sc;                           /*starting row and column of field*/
  44.   WORD sa,ss;                          /*starting attribute and curs size*/
  45.   WORD os=INS_SIZ;                     /*overwrite cursor size*/
  46.   int l;                               /*length of string*/
  47.   int c=0;                             /*cursor position inside window*/
  48.   int o=0;                             /*offset of first cell in window*/
  49.   int i;                               /*local*/
  50.   int ch;                              /*character read*/
  51.   wflags sf;                           /*flags*/
  52.   char end=0;                          /*end of routine*/
  53.   char ins=0;                          /*insert mode*/
  54.  
  55.   if (!winitd) return 0;               /*windows not initialized*/
  56.   if (ww==NULL) return 0;              /*bad window pointer*/
  57.   sr=ww->row;                          /*get current row*/
  58.   sc=ww->col;                          /*get current col*/
  59.   sa=ww->attr;                         /*get current attribute*/
  60.   if (a==0) a=sa;                      /*if no attribute, use current*/
  61.   ss=ww->csiz;                         /*get current cursor size*/
  62.   sf=ww->fl;                           /*save the flags*/
  63.   ww->fl.wrap=0;                       /*no wrap*/
  64.   ww->fl.scroll=0;                     /*no scroll*/
  65.   n--;                                 /*decrement so lengths are easy*/
  66.   l=strlen(s);                         /*get starting string length*/
  67.   if (l>n) l=0;                        /*if bigger than allowed, kill*/
  68.   if (l>n) return 0;                   /*if n was 0, then return*/
  69.   if (ins)                             /*if insert mode..*/
  70.     ww->csiz=DEF_CSIZE;                /*..set cursor size to default*/
  71.   else                                 /*otherwise..*/
  72.     ww->csiz=os;                       /*..set size to overstrike size*/
  73.   wupd=1;                              /*window updating is on*/
  74.   ww->fl.alive=1;                      /*make sure window is visible*/
  75.   wfront(ww);                          /*bring window to front*/
  76.   if (w<=1) w=ww->cols-sc;             /*if no width, use rest of row*/
  77.   if (w<=1) return 0;                  /*will not fit on row*/
  78.  
  79.   while (!end) {                       /*go 'til end*/
  80.  
  81.     wupd=0;                            /*turn off update 'til done*/
  82.     wsetcpos(ww,sr,sc);                /*start position*/
  83.     ww->attr=sa;                       /*original attributes*/
  84.     for (i=0;i<w;i++) wputc(ww,' ');   /*blank out requested region*/
  85.     wsetcpos(ww,sr,sc);                /*back to start*/
  86.     ww->attr=a;                        /*use passed attributes*/
  87.     for (i=0;i<w;i++) {                /*start writing the string*/
  88.       if ((o+i)==l) break;             /*if end of string, end it*/
  89.       wputc(ww,s[o+i]);                /*write out string characters*/
  90.     }   /*for*/
  91.     wsetcpos(ww,sr,sc+c);              /*place cursor*/
  92.     wupdate(ww);                       /*update windows*/
  93.  
  94.     ch=wgetc(ww);                      /*get input character from kb*/
  95.     switch (ch) {
  96.     case C_Y:                          /*ctrl-Y clears line*/
  97.     case A_D:
  98.       l=0;
  99.       o=0;
  100.       c=0;
  101.       break;
  102.     case DEL:                          /*DEL and BS move left and delete*/
  103.     case BS:
  104.       if ((o+c)==0)
  105.         break;
  106.       else {
  107.         c--;
  108.         if (c<0) {
  109.           c=0;
  110.           if (o) o--;
  111.         }
  112.       }   /*else delete should be ok*/
  113.       /*fall through to delete*/
  114.     case _DEL:                         /*Del deletes the current character*/
  115.     case C_G:                          /*make sure any changes work w/above*/
  116.       if ((o+c)>=l) break;
  117.       l--;
  118.       for (i=o+c;i<l;i++) s[i]=s[i+1];
  119.       if (o&&(c<(w-1))) {
  120.         o--;
  121.         c++;
  122.       }
  123.       break;
  124.     case _LTAR:                        /*move left*/
  125.     case C_S:
  126.       c--;
  127.       if (c<0) {
  128.         c=0;
  129.         if (o) o--;
  130.       }
  131.       break;
  132.     case C_LTAR:                       /*move left one word*/
  133.       i=o+c;
  134.       if (i==0) break;
  135.       i--;                             /*look for space==>not-space*/
  136.       while (i && !(isspace(s[i-1]) && !isspace(s[i])) ) i--;
  137.       if (i>o)                         /*if still in window*/
  138.         c=i-o;
  139.       else {
  140.         c=0;
  141.         o=i;
  142.       }
  143.       break;
  144.     case _RTAR:                        /*move right*/
  145.     case C_D:
  146.       c++;
  147.       if ((o+c)>l)
  148.         c--;
  149.       else {
  150.         if (c>=w) { o++; c=w-1; }
  151.       }
  152.       break;
  153.     case C_RTAR:                       /*move right one word*/
  154.       i=o+c;
  155.       if (i>=l) break;                 /*already at end*/
  156.       i++;                             /*look for space==>not-space*/
  157.       while ((i<l) && !(isspace(s[i-1]) && !isspace(s[i])) ) i++;
  158.       c=i-o;
  159.       while (c>=w) {                   /*if not still in window*/
  160.         c--;
  161.         o++;
  162.       }
  163.       break;
  164.     case _HOME:                        /*go to beginning of string*/
  165.     case A_H:
  166.     case C_A:
  167.       c=0;
  168.       o=0;
  169.       break;
  170.     case _END:                         /*go to end of string*/
  171.     case C_F:
  172.     case A_E:
  173.       if (l<w) {
  174.         o=0;
  175.         c=l;
  176.       }
  177.       else {
  178.         o=l-w+1;
  179.         c=w-1;
  180.       }
  181.       break;
  182.     case C_HOME:                       /*delete from beginning*/
  183.       l-=o+c;                          /*subtract off chars up to cursor*/
  184.       for (i=0;i<l;i++) s[i]=s[o+c+i];
  185.       o=0;
  186.       c=0;
  187.       s[l]=0;
  188.       break;
  189.     case C_END:                        /*delete to end*/
  190.       l=o+c;
  191.       s[l]=0;
  192.       break;
  193.     case _INS:                         /*toggle insert mode*/
  194.     case C_V:
  195.     case A_I:
  196.       ins=!ins;
  197.       if (ins)
  198.         wsetcsiz(ww,DEF_CSIZE);        /*use default cursor size on ins*/
  199.       else
  200.         wsetcsiz(ww,os);               /*use big cursor for overwrite*/
  201.       break;
  202.     default:
  203.       if ((ch>=0x100)||(ch==ESC)||(ch==CR))
  204.         end=1;                         /*special char...hit the road*/
  205.       else if (ch>=' ') {              /*if normal char, place in string*/
  206.         if (!ins) {
  207.           if ((o+c)>=n) break;         /*if no room, stop*/
  208.           s[o+c]=ch;
  209.           c++;
  210.           if (c>=w) { c=w-1; o++; }
  211.           if ((o+c)>l) l=o+c;
  212.         }   /*if overwrite*/
  213.         else if (l<n) {
  214.           l++;
  215.           for (i=l;i>(o+c);i--) s[i]=s[i-1];
  216.           s[o+c]=ch;
  217.           c++;
  218.           if (c>=w) { c=w-1; o++; }
  219.           if ((o+c)>l) l=o+c;
  220.         }   /*else insert mode and string not already too long*/
  221.       }   /*if not special key*/
  222.     }   /*switch*/
  223.   }   /*while*/
  224.   s[l]=0;                            /*mark end of string*/
  225.   wupd=0;                            /*turn off update 'til done*/
  226.   wsetcpos(ww,sr,sc);                /*start position*/
  227.   ww->attr=sa;                       /*original attributes*/
  228.   for (i=0;i<w;i++) wputc(ww,' ');   /*blank out requested region*/
  229.   wsetcpos(ww,sr,sc);                /*back to start*/
  230.   for (i=0;i<w;i++) {                /*start writing the string*/
  231.     if ((o+i)==l) break;             /*if end of string, end it*/
  232.     wputc(ww,s[o+i]);                /*write out string characters*/
  233.   }   /*for*/
  234.   wsetcpos(ww,sr,sc);                /*place cursor*/
  235.   wsetcsiz(ww,ss);                   /*restore starting size*/
  236.   ww->fl=sf;                         /*restore original flags*/
  237.   wupdate(ww);                       /*update windows*/
  238.   return ch;                         /*return the char that caused end*/
  239. }   /*wgetsfield*/
  240.  
  241.  
  242. /****************************************************************************/
  243. /*  wgetfields                                                              */
  244. /****************************************************************************/
  245. /*-----------------------------Description----------------------------------*/
  246. /*  This function gets data from input fields in various formats.  The      */
  247. /*  fields are described in an array of WFIELDs.  Unsupplied formats will   */
  248. /*  be provided (see xxxx_FMT macros in wutil.h).                           */
  249. /*-----------------------------Arguments------------------------------------*/
  250. /*  WIND *w            window in which input is to occur                    */
  251. /*  WFIELD *f          pointer to first element of WFIELD array             */
  252. /*  int nf             number of fields; if 0, go 'til first data ptr NULL  */
  253. /*  WORD a             attribute for highlighted field                      */
  254. /*-----------------------------Return value---------------------------------*/
  255. /*  Returns character used to exit the data entry process; 0 on error.      */
  256. /*-----------------------------Global constants-----------------------------*/
  257. /*-------------------Mod-------Global variables-----------------------------*/
  258. /*-----------------------------Functions called-----------------------------*/
  259. /*-----------------------------Constraints/Gotchas--------------------------*/
  260. /*--Date--------Programmer----------Comments--------------------------------*/
  261. /*  1990.01.01  A. Turing           initial code                            */
  262. /****************************************************************************/
  263. int  wgetfields(WIND *w,WFIELD *f,int nf,WORD a)    /*gets info from fields*/
  264. {
  265.   WFIELD *fp;                          /*local field pointer*/
  266.   int i;                               /*local index*/
  267.  
  268.   if (!winitd) return 0;               /*windows not available*/
  269.   if (w==NULL) return 0;               /*bad window*/
  270.   if (f==NULL) return 0;               /*bad field pointer*/
  271.   if (nf==0) for (fp=f;fp->d;fp++) nf++;   /*calculate number of fields*/
  272.   if (nf==0) return 0;                 /*no fields*/
  273.   for (i=0;i<nf;i++) {
  274.     switch(f[i].t) {                   /*switch on type*/
  275.     case WCHAR:    if (!f[i].f) f[i].f=WCHAR_FMT;     break;
  276.     case WUCHAR:   if (!f[i].f) f[i].f=WUCHAR_FMT;    break;
  277.     case WINT:     if (!f[i].f) f[i].f=WINT_FMT;      break;
  278.     case WUINT:    if (!f[i].f) f[i].f=WUINT_FMT;     break;
  279.     case WLONG:    if (!f[i].f) f[i].f=WLONG_FMT;     break;
  280.     case WULONG:   if (!f[i].f) f[i].f=WULONG_FMT;    break;
  281.     case WFLOAT:   if (!f[i].f) f[i].f=WFLOAT_FMT;    break;
  282.     case WDOUBLE:  if (!f[i].f) f[i].f=WDOUBLE_FMT;   break;
  283.     case WLDOUBLE: if (!f[i].f) f[i].f=WLDOUBLE_FMT;  break;
  284.     case WSTRING:  if (!f[i].f) f[i].f=WSTRING_FMT;   break;
  285.     default: return 0;                 /*illegal type specified*/
  286.     }   /*switch on type*/
  287.   }   /*for*/
  288.  
  289. /*all fields look good now...*/
  290.   for (i=0;i<nf;i++) {
  291.   }   /*for*/
  292.   return ESC;
  293. }   /*wgetfields*/
  294.  
  295.  
  296. /****************************************************************************/
  297. /*  wfile                                                                   */
  298. /****************************************************************************/
  299. /*-----------------------------Description----------------------------------*/
  300. /*  This function displays the specified text file in a window.  It does    */
  301. /*  NOT clear the window when finished, nor does it hide the window.        */
  302. /*  A FF (formfeed) can be used to force a page break within the file.      */
  303. /*-----------------------------Arguments------------------------------------*/
  304. /*  WIND *w            window in which to show the file                     */
  305. /*  char *fn           name of file to show                                 */
  306. /*-----------------------------Return value---------------------------------*/
  307. /*  Returns 1 on success, 0 on error (bad window or unsuccessful file       */
  308. /*  open).                                                                  */
  309. /*--Date--------Programmer----------Comments--------------------------------*/
  310. /*  1990.11.09  dr                  initial code                            */
  311. /****************************************************************************/
  312. int  wfile(WIND *w,char *fn)
  313. {
  314.   char s[256];
  315.   char *p;
  316.   FILE *f;
  317.   int r=0;
  318.   wflags fl;
  319.   int c=0;
  320.  
  321.   if (!winitd) return 0;               /*if not init'd, return*/
  322.   if (w==NULL) return 0;               /*if bad pointer, return*/
  323.   f=fopen(fn,"rt");                    /*try to open the helpfile*/
  324.   if (f==NULL) return 0;               /*if not there, return*/
  325.  
  326.   wupd=0;                              /*build screen before updating*/
  327.   fl=w->fl;                            /*save flags for later*/
  328.   w->fl.scroll=1;                      /*scrolling on*/
  329.   w->fl.wrap=0;                        /*no wrap, though*/
  330.   w->fl.alive=1;                       /*active window*/
  331.   wfront(w);                           /*push window to front*/
  332.   wclr(w);                             /*clear it*/
  333.   wupdate(w);                          /*now display it*/
  334.  
  335.   while (fgets(s,256,f)!=NULL) {       /*go 'til EOF*/
  336.     p=strchr(s,FF);                    /*look for page break*/
  337.     if ((r>=(w->rows-1))||p) {         /*end of page*/
  338.       if (p) *p=' ';                   /*clear end of page*/
  339.       if (w->col) wputc(w,'\n');       /*if not at end of line*/
  340.       wputs(w,"***press any key, <ESC> to quit***");
  341.       c=wgetc(w);                      /*get key from user*/
  342.       wputc(w,'\r');                   /*go to beg of row*/
  343.       wclreor(w);                      /*clear it*/
  344.       if (c==ESC) break;               /*if person hit ESC, end*/
  345.       r=0;
  346.     }   /*if end of page*/
  347.     wputs(w,s);
  348.     r++;
  349.   }   /*while not EOF*/
  350.   if (c!=ESC) {
  351.     if (w->col) wputc(w,'\n');         /*if not at end of line*/
  352.     wputs(w,"***press any key***");    /*put out prompt*/
  353.     wgetc(w);                          /*get keypress from user*/
  354.     wputc(w,'\r');                     /*go to beg of row*/
  355.     wclreor(w);                        /*clear it*/
  356.   }   /*if at end*/
  357.   w->fl=fl;                            /*restore the window's flags*/
  358.   fclose(f);                           /*close the file*/
  359.   return 1;                            /*report success*/
  360. }   /*wfile*/
  361.  
  362.  
  363. /****************************************************************************/
  364. /*  hotlen                                                                  */
  365. /****************************************************************************/
  366. /*-----------------------------Description----------------------------------*/
  367. /*  This function returns the length of a string, less the number of        */
  368. /*  "hotkey" flag characters in the string.  A hotkey can be used to        */
  369. /*  indicate any number of things -- it is used by wputshot() to indicate   */
  370. /*  that an alternative attribute is to be selected.  A double hotkey       */
  371. /*  sequence is reduced to a single occurrence of the key:                  */
  372. /*    hotlen("&Test",'&')   == 4                                            */
  373. /*    hotlen("%Hot=%%",'&') == 5                                            */
  374. /*-----------------------------Arguments------------------------------------*/
  375. /*  char* s            pointer to string to count                           */
  376. /*  char hotkey        char to use as hotkey flag                           */
  377. /*-----------------------------Return value---------------------------------*/
  378. /*  Returns length of string, less hotkey flags.                            */
  379. /*-----------------------------Global constants-----------------------------*/
  380. /*-------------------Mod-------Global variables-----------------------------*/
  381. /*-----------------------------Functions called-----------------------------*/
  382. /*-----------------------------Examples-------------------------------------*/
  383. /*-----------------------------Constraints/Gotchas--------------------------*/
  384. /*--Date--------Programmer----------Comments--------------------------------*/
  385. /*  1990.01.01  A. Turing           initial code                            */
  386. /****************************************************************************/
  387. int  hotlen(char* s,char hotkey)
  388. {
  389.   int l=0;                             /*length of hotkey string*/
  390.   while (*s) {                         /*go 'til end of string*/
  391.     l++;
  392.     if (*s++==hotkey) {                /*if hotkey..*/
  393.       if (*s) s++;                     /*..if somthin' there, skip it*/
  394.     }   /*else hotkey*/
  395.   }   /*while*/
  396.   return l;
  397. }   /*hotlen*/
  398.  
  399.  
  400. /****************************************************************************/
  401. /*  wputshot                                                                */
  402. /****************************************************************************/
  403. /*-----------------------------Description----------------------------------*/
  404. /*  This function puts out a string to a window, using an alternative       */
  405. /*  attribute for those characters labelled as hotkeys (preceded by the     */
  406. /*  hotkey argument).                                                       */
  407. /*-----------------------------Arguments------------------------------------*/
  408. /*  WIND* w            window in which to write the string                  */
  409. /*  char* s            string to write                                      */
  410. /*  WORD  hat          hotkey attribute                                     */
  411. /*  char  hotkey       hotkey flag indicator                                */
  412. /*-----------------------------Return value---------------------------------*/
  413. /*-----------------------------Global constants-----------------------------*/
  414. /*-------------------Mod-------Global variables-----------------------------*/
  415. /*-----------------------------Functions called-----------------------------*/
  416. /*-----------------------------Examples-------------------------------------*/
  417. /*  This example writes a command bar to a window:                          */
  418. /*    w=wopen(0,NULL, 0,0, 1,80, ATTR(BLACK,LIGHTGRAY));                    */
  419. /*    wputshot(w,"&F&1-&Help  &F&2-&Save",ATTR(RED,LIGHTGRAY),'&');         */
  420. /*-----------------------------Constraints/Gotchas--------------------------*/
  421. /*--Date--------Programmer----------Comments--------------------------------*/
  422. /*  1990.01.01  A. Turing           initial code                            */
  423. /****************************************************************************/
  424. void wputshot(WIND* w,char *s,WORD hat,char hotkey)
  425. {
  426.   char twupd;                          /*windowing update flag*/
  427.   WORD wat;                            /*current window attribute*/
  428.  
  429.   twupd=wupd;                          /*save update flag*/
  430.   wupd=0;                              /*no updating 'til done*/
  431.   wat=w->attr;                         /*save current window attributes*/
  432.   for (;*s;s++) {                      /*go through each char*/
  433.     if (*s!=hotkey) {                  /*..normal char*/
  434.       wputc(w,*s);                     /*....write it*/
  435.       continue;                        /*....continue looping*/
  436.     }   /*if normal char*/
  437.     s++;                               /*..go to next char*/
  438.     if (!*s) s--;                      /*..if nothing after &, double it*/
  439.     if (*s==hotkey)                    /*..hot key doubled*/
  440.       wputc(w,*s);                     /*....put out hotkey indicator*/
  441.     else {
  442.       w->attr=hat;                     /*..switch to hotkey attributes*/
  443.       wputc(w,*s);                     /*..put out the char*/
  444.       w->attr=wat;                     /*..go back to window attributes*/
  445.     }   /*if writing with hat*/
  446.   }   /*for each char*/
  447.   wupd=twupd;                          /*restore update flag*/
  448.   if (wupd) wupdate(w);                /*update if necessary*/
  449. }   /*wputshot*/
  450.  
  451.  
  452.