home *** CD-ROM | disk | FTP | other *** search
/ Boldly Go Collection / version40.iso / TS / 17A / DRWIN101.ZIP / WUTIL.C < prev    next >
C/C++ Source or Header  |  1991-08-19  |  60KB  |  1,110 lines

  1. /****************************************************************************/
  2. /*  MODULE wutil.c                                                          */
  3. /****************************************************************************/
  4. /*-----------------------------Description----------------------------------*/
  5. /*  This module contains windowing utilities for use in text mode on IBM    */
  6. /*  PC's.                                                                   */
  7. /*-----------------------------Constraints/Gotchas--------------------------*/
  8. /*  These functions will only work on an IBM PC in text mode.               */
  9. /*  Function descriptions will NOT list those functions available in both   */
  10. /*  Turbo C and Microsoft C (such as int86() in [dos.h]).  It is assumed    */
  11. /*  that the reader is familiar with these non-ANSII functions.             */
  12. /*--Date--------Programmer----------Comments--------------------------------*/
  13. /*  1990.01.01  (c) D. Rogers       initial code                            */
  14. /****************************************************************************/
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <stdarg.h>
  18. #include <string.h>
  19. #include <conio.h>
  20. #include <dos.h>
  21.  
  22. #include "strutil.h"
  23. #include "scrutil.h"
  24. #include "wutil.h"
  25.  
  26.  
  27. char winitd=0;                         /*flag for windows initialization*/
  28. char wupd=1;                           /*flag for updating*/
  29. char wcga=0;                           /*don't check for CGA retrace scan*/
  30. WORD wscr_size=0;                      /*bytes in original screen*/
  31. WORD *vscr;                            /*pointer to virtual screen*/
  32. WORD far *vidp;                        /*pointer to video segment*/
  33. WIND *wscr;                            /*original screen, base window*/
  34. WIND *wact;                            /*current active window pointer*/
  35.  
  36.  
  37. /****************************************************************************/
  38. /*  winit                                                                   */
  39. /****************************************************************************/
  40. /*-----------------------------Description----------------------------------*/
  41. /*  This function initializes the windowing environment.  Make sure this    */
  42. /*  function is not called twice without calling wpurge().                  */
  43. /*-----------------------------Arguments------------------------------------*/
  44. /*-----------------------------Return value---------------------------------*/
  45. /*  winit() returns 1 if everything checks out ok, 0 otherwise (if no       */
  46. /*  memory was available for the virtual screen, etc.).                     */
  47. /*-----------------------------Constraints/Gotchas--------------------------*/
  48. /*--Date--------Programmer----------Comments--------------------------------*/
  49. /*  1990.01.01  D. Rogers           initial code                            */
  50. /****************************************************************************/
  51. int winit(void)
  52. {
  53.   WORD rs,cs;                          /*rows and columns on original screen*/
  54.  
  55.   if (winitd) return 0;                /*if already initialized*/
  56.   switch (getsmod()) {                 /*check the mode*/
  57.   case MONO_80_25:
  58.     vidp=MONO_POINTER;                 /*...set mono video pointer*/
  59.     break;
  60.   case TEXT_40_25_BW:
  61.   case TEXT_40_25:
  62.   case TEXT_80_25_BW:
  63.   case TEXT_80_25:
  64.   case TEXT_80_HI:
  65.     vidp=COLOR_POINTER;                /*...set color video pointer*/
  66.     break;
  67.   default:
  68.     return 0;                          /*..unknown/nontext video mode*/
  69.   }   /*switch on video mode*/
  70.  
  71.   rs=getsrows();                       /*rows available on screen*/
  72.   cs=getscols();                       /*columns available on screen*/
  73.   wscr_size=rs*cs*2;                   /*get number of bytes in original scr*/
  74.   vscr=(WORD *)malloc(wscr_size);      /*set up virtual screen*/
  75.   if (vscr==NULL) return 0;            /*oops! no room*/
  76.   wscr=(WIND *)malloc(sizeof(WIND)+wscr_size);
  77.   wact=wscr;                           /*active is base*/
  78.   if (wscr==NULL) { free(vscr); return 0; }   /*oops! no room*/
  79.  
  80. /*set first window to be original screen...*/
  81.   wscr->rows=rs;                       /*set rows as calc'd above*/
  82.   wscr->cols=cs;                       /*set cols as calc'd above*/
  83.   wscr->srow=0;                        /*window starts in row 0 on screen*/
  84.   wscr->scol=0;                        /*window starts in column 0 on screen*/
  85.   wscr->row =getcrow();                /*save screen cursor row*/
  86.   wscr->col =getccol();                /*save screen cursor column*/
  87.   wscr->csiz=getcsiz();                /*save screen cursor size*/
  88.   wscr->attr=(BLACK<<4)+LIGHTGRAY;     /*default low intensity white on black*/
  89.   wscr->fchr=' ';                      /*default to space as fill char*/
  90.   wscr->battr=wscr->attr;              /*no border, but set attribute anyway*/
  91.   wscr->prompt=NULL;                   /*set prompt pointer*/
  92.   wscr->bord=0;                        /*no border*/
  93.   wscr->fl.wrap=1;                     /*wrap text at end of line*/
  94.   wscr->fl.scroll=1;                   /*scroll window at bottom*/
  95.   wscr->fl.moves=0;                    /*no window moving allowed*/
  96.   wscr->fl.sizes=0;                    /*no window resizing*/
  97.   wscr->fl.alive=1;                    /*definitely show this window*/
  98.   wscr->fl.saved=0;                    /*not yet saved*/
  99.   wscr->fl.showcr=0;                   /*don't show little note character*/
  100.   wscr->fl.showlf=0;                   /*ditto for LF one*/
  101.   wscr->fl.showbs=0;                   /*ditto for BS one*/
  102.   wscr->wprv=NULL;                     /*previous window is nonexistent*/
  103.   wscr->wnxt=NULL;                     /*next window is also nonexistent*/
  104.  
  105. #if defined(__TINY__)||defined(__SMALL__)||defined(__MEDIUM__)
  106.   memcpynfi(wscr->wtxt,vidp,wscr_size); /*save screen into text buffer*/
  107. #else
  108.   memcpyi(wscr->wtxt,vidp,wscr_size);  /*save screen into text buffer*/
  109. #endif
  110.   memcpyi(vscr,wscr->wtxt,wscr_size);  /*update virtual screen*/
  111.  
  112.   winitd=1;                            /*indicate that now initialized*/
  113.   return 1;                            /*all done!*/
  114. }   /*winit*/
  115.  
  116.  
  117. /****************************************************************************/
  118. /*  wvscr                                                                   */
  119. /****************************************************************************/
  120. /*-----------------------------Description----------------------------------*/
  121. /*  This function writes the virtual screen into the real screen.           */
  122. /*-----------------------------Arguments------------------------------------*/
  123. /*-----------------------------Return value---------------------------------*/
  124. /*-----------------------------Constraints/Gotchas--------------------------*/
  125. /*--Date--------Programmer----------Comments--------------------------------*/
  126. /*  1990.01.01  D. Rogers           initial code                            */
  127. /****************************************************************************/
  128. void wvscr(void)
  129. {
  130.   if (wcga) ;                          /*check for CGA retrace scan here*/
  131.  
  132. #if defined(__TINY__)||defined(__SMALL__)||defined(__MEDIUM__)
  133.   memcpyfni(vidp,vscr,wscr_size);      /*copy virtual to actual screen*/
  134. #else
  135.   memcpyi(vidp,vscr,wscr_size);        /*copy virtual to actual screen*/
  136. #endif
  137. }   /*wvscr*/
  138.  
  139.  
  140. /****************************************************************************/
  141. /*  wsetDOSscr, wgetDOSscr                                                  */
  142. /****************************************************************************/
  143. /*-----------------------------Description----------------------------------*/
  144. /*  These functions allow easy access to DOS system calls.                  */
  145. /*  wsetDOSscr() makes the base window, wscr, the active window and hides   */
  146. /*  all other windows.  It should be called before calling system() or      */
  147. /*  spawnXXX() (or execXXX()).  Upon return, you should call wgetDOSscr().  */
  148. /*  wgetDOSscr() copies the screen into the base window, wscr, and unhides  */
  149. /*  all windows previously hidden.                                          */
  150. /*-----------------------------Arguments------------------------------------*/
  151. /*-----------------------------Return value---------------------------------*/
  152. /*-----------------------------Global constants-----------------------------*/
  153. /*-------------------Mod-------Global variables-----------------------------*/
  154. /*-----------------------------Functions called-----------------------------*/
  155. /*-----------------------------Constraints/Gotchas--------------------------*/
  156. /*--Date--------Programmer----------Comments--------------------------------*/
  157. /*  1990.01.01  A. Turing           initial code                            */
  158. /****************************************************************************/
  159. void wsetDOSscr(void)
  160. {
  161.   WIND *w;
  162.  
  163.   if (!winitd) return;                 /*return at end*/
  164.   wupd=1;                              /*turn on update*/
  165.   w=wscr->wnxt;
  166.   while (w!=NULL) {
  167.     w->fl.saved=0;
  168.     if (w->fl.alive) {                 /*if not hidden..*/
  169.       w->fl.alive=0;                   /*..hide and*/
  170.       w->fl.saved=1;                   /*..indicate we've done so*/
  171.     }   /*if not hidden*/
  172.     w=w->wnxt;
  173.   }   /*while*/
  174.   wupdate(NULL);
  175. }   /*wsetDOSscr*/
  176.  
  177.  
  178. void wgetDOSscr(void)
  179. {
  180.   WIND *w;
  181.  
  182.   if (!winitd) return;                 /*return at end*/
  183.   wupd=1;                              /*turn on update*/
  184.   wscr->row =getcrow();                /*save screen cursor row*/
  185.   wscr->col =getccol();                /*save screen cursor column*/
  186.   wscr->csiz=getcsiz();                /*save screen cursor size*/
  187. #if defined(__TINY__)||defined(__SMALL__)||defined(__MEDIUM__)
  188.   memcpynfi(wscr->wtxt,vidp,wscr_size); /*save screen into text buffer*/
  189. #else
  190.   memcpyi(wscr->wtxt,vidp,wscr_size);  /*save screen into text buffer*/
  191. #endif
  192.   w=wscr->wnxt;
  193.   while (w!=NULL) {
  194.     if (w->fl.saved) w->fl.alive=1;    /*if hidden by wsetDOSscr, unhide*/
  195.     w->fl.saved=0;
  196.     w=w->wnxt;
  197.   }   /*while*/
  198.   wupdate(NULL);
  199. }   /*wgetDOSscr*/
  200.  
  201.  
  202. /****************************************************************************/
  203. /*  wvbord                                                                  */
  204. /****************************************************************************/
  205. /*-----------------------------Description----------------------------------*/
  206. /*  This function writes the border for a window to the virtual screen.     */
  207. /*-----------------------------Arguments------------------------------------*/
  208. /*  WIND *w            window for which border is to be made                */
  209. /*-----------------------------Return value---------------------------------*/
  210. /*-----------------------------Constraints/Gotchas--------------------------*/
  211. /*--Date--------Programmer----------Comments--------------------------------*/
  212. /*  1990.01.01  D. Rogers           initial code                            */
  213. /****************************************************************************/
  214. void wvbord(WIND *w)
  215. {
  216. #define TOPLEFT    0                   /*mneumonics for graphics chars...*/
  217. #define HORIZ      1
  218. #define TOP_T      2
  219. #define TOPRIGHT   3
  220. #define VERT       4
  221. #define LEFT_T     5
  222. #define MIDDLE     6
  223. #define RIGHT_T    7
  224. #define BOTLEFT    8
  225. #define BOT_T      9
  226. #define BOTRIGHT   10
  227.   static BYTE *gcs[2]={                /*text mode graphics characters*/
  228.     "\xDA\xC4\xC2\xBF\xB3\xC3\xC5\xB4\xC0\xC1\xD9\x00",
  229.     "\xC9\xCD\xCB\xBB\xBA\xCC\xCE\xB9\xC8\xCA\xBC\x00"
  230.   };
  231.   BYTE gc[12];                         /*text mode graphics characters copy*/
  232.   WORD ac;                             /*attribute:character*/
  233.   WORD *vp;                            /*pointer into virtual screen*/
  234.   BYTE *p;                             /*pointer to prompt*/
  235.   WORD k;                              /*row/col counter*/
  236.   WORD l;                              /*length*/
  237.  
  238.   if (w->bord) {                       /*if border around window*/
  239.     ac=0;                              /*clear ac*/
  240.     HI(ac)=w->battr;                   /*get border attribute*/
  241.     if (w->bord>2) w->bord=1;          /*make sure a legal value*/
  242.     memcpyi(gc,gcs[w->bord-1],12);     /*copy text graphics characters*/
  243.     l=0;                               /*initialize length to 0*/
  244.     p=w->prompt;                       /*point to prompt*/
  245.     if (p!=NULL) l=strlen(p);          /*get length of prompt*/
  246.     vp=(WORD *)vscr;                   /*start at top of screen*/
  247.     vp+=((w->srow-1)*wscr->cols);      /*offset to first border row*/
  248.     vp+=(w->scol-1);                   /*offset to correct column*/
  249.     *vp++=ac|gc[TOPLEFT];              /*write top left character*/
  250.     for (k=0;k<w->cols;k++) {          /*go through each column*/
  251.       if (k<l)                         /*if still writing prompt...*/
  252.         *vp++=ac|*p++;                 /*...write out prompt character*/
  253.       else                             /*otherwise...*/
  254.         *vp++=ac|gc[HORIZ];            /*...write out horizontal bar*/
  255.     }   /*for*/
  256.     *vp++=ac|gc[TOPRIGHT];             /*write top right character*/
  257.     ac|=gc[VERT];
  258.     for (k=0;k<w->rows;k++) {          /*write out side walls on each row*/
  259.       vp+=(wscr->cols-w->cols-2);      /*point to left side wall*/
  260.       *vp++=ac;                        /*write out vertical character*/
  261.       vp+=w->cols;                     /*go to right wall*/
  262.       *vp++=ac;                        /*write out vertical character*/
  263.     }   /*for*/
  264.     ac&=0xFF00;                        /*clear out the vertical character*/
  265.     vp+=(wscr->cols-w->cols-2);        /*point to bottom left*/
  266.     *vp++=ac|gc[BOTLEFT];              /*write bottom left character*/
  267.     for (k=0;k<w->cols;k++)            /*go through each column*/
  268.       *vp++=ac|gc[HORIZ];              /*write out horizontal*/
  269.     *vp++=ac|gc[BOTRIGHT];             /*write bottom right character*/
  270.   }   /*if border*/
  271. }   /*wvbord*/
  272.  
  273.  
  274. /****************************************************************************/
  275. /*  wupdate                                                                 */
  276. /****************************************************************************/
  277. /*-----------------------------Description----------------------------------*/
  278. /*  This function updates the screen, starting with the base window and     */
  279. /*  going up.                                                               */
  280. /*-----------------------------Arguments------------------------------------*/
  281. /*  WIND *w            window at which to start updating (NULL=from base)   */
  282. /*-----------------------------Return value---------------------------------*/
  283. /*-----------------------------Constraints/Gotchas--------------------------*/
  284. /*--Date--------Programmer----------Comments--------------------------------*/
  285. /*  1990.01.01  D. Rogers           initial code                            */
  286. /****************************************************************************/
  287. void wupdate(WIND *w)
  288. {
  289.   WORD *vp;                            /*pointer into virtual screen*/
  290.   WORD *tp;                            /*window text pointer*/
  291.   WORD r;                              /*row counter*/
  292.  
  293.   if (!winitd) return;                 /*return at end*/
  294.   wupd=1;                              /*turn on update*/
  295.   if (!w) w=wscr;                      /*if starting at base*/
  296.   for (;w!=NULL;w=w->wnxt) {           /*go through each window*/
  297.     if (!w->fl.alive) continue;        /*if not alive, don't update*/
  298.     wact=w;                            /*make active window this window*/
  299.     if (w->bord) wvbord(w);            /*write out border if there is one*/
  300.     vp=(WORD *)vscr;                   /*start at top of screen*/
  301.     vp+=(w->srow*wscr->cols);          /*offset to correct row*/
  302.     vp+=w->scol;                       /*offset to correct column*/
  303.     tp=w->wtxt;                        /*start in window*/
  304.     for (r=0;r<w->rows;r++) {          /*go through each row*/
  305.       memcpyi(vp,tp,w->cols<<1);       /*copying each line into virt screen*/
  306.       vp+=wscr->cols;                  /*inc virtual screen pointer 1 row*/
  307.       tp+=w->cols;                     /*inc window pointer 1 window row*/
  308.     }   /*for each row*/
  309.   }   /*for each window*/
  310.   wvscr();                             /*write virtual screen to real screen*/
  311.   setcsiz(wact->csiz);                 /*set cursor size*/
  312.   setcpos(wact->srow+wact->row,wact->scol+wact->col);   /*set curs position*/
  313. }   /*wupdate*/
  314.  
  315.  
  316. /****************************************************************************/
  317. /*  wpurge                                                                  */
  318. /****************************************************************************/
  319. /*-----------------------------Description----------------------------------*/
  320. /*  This function closes all windows and frees up all memory used by the    */
  321. /*  windowing environment.  After calling wpurge(), you are allowed to      */
  322. /*  call winit() once again.                                                */
  323. /*-----------------------------Arguments------------------------------------*/
  324. /*-----------------------------Return value---------------------------------*/
  325. /*-----------------------------Constraints/Gotchas--------------------------*/
  326. /*--Date--------Programmer----------Comments--------------------------------*/
  327. /*  1990.01.01  D. Rogers           initial code                            */
  328. /****************************************************************************/
  329. void wpurge(void)
  330. {
  331.   WIND *wn;
  332.   WORD r,c,s;                          /*cursor row, column, size*/
  333.  
  334.   if (!winitd) return;
  335.   memcpyi(vscr,wscr->wtxt,wscr_size);  /*first save original screen*/
  336.   r=wscr->row;                         /*save original row*/
  337.   c=wscr->col;                         /*save original column*/
  338.   s=wscr->csiz;                        /*save original cursor size*/
  339.   wact=wscr->wnxt;                     /*start at first window*/
  340.   while (wact!=NULL) {                 /*go through each window from start*/
  341.     wn=wact->wnxt;                     /*get pointer to next window*/
  342.     free(wact);                        /*return memory to system*/
  343.     wact=wn;                           /*update pointer to window*/
  344.   }   /*while*/
  345.   wvscr();                             /*write virtual screen to screen*/
  346.   free(wscr);                          /*free up the base window memory*/
  347.   free(vscr);                          /*free memory for virtual screen*/
  348.   setcsiz(s);                          /*restore original cursor size*/
  349.   setcpos(r,c);                        /*restore cursor position*/
  350.   wupd=1;                              /*turn on update*/
  351.   winitd=0;                            /*not initialized anymore*/
  352. }   /*wpurge*/
  353.  
  354.  
  355. /****************************************************************************/
  356. /*  wclose                                                                  */
  357. /****************************************************************************/
  358. /*-----------------------------Description----------------------------------*/
  359. /*  This function closes a window by its window id.                         */
  360. /*-----------------------------Arguments------------------------------------*/
  361. /*-----------------------------Return value---------------------------------*/
  362. /*-----------------------------Constraints/Gotchas--------------------------*/
  363. /*--Date--------Programmer----------Comments--------------------------------*/
  364. /*  1990.01.01  D. Rogers           initial code                            */
  365. /****************************************************************************/
  366. void wclose(WIND *w)
  367. {
  368.   if (!winitd) if (!winit()) return;   /*if not initialized, return*/
  369.   if (w==NULL) return;                 /*return if bad pointer*/
  370.   (w->wprv)->wnxt=(w->wnxt);           /*set previous to point to next*/
  371.   if (w->wnxt) (w->wnxt)->wprv=(w->wprv);  /*set next to point to previous*/
  372.   free(w);                             /*return memory to system*/
  373.   if (wupd) wupdate(NULL);             /*update screen*/
  374. }   /*wclose*/
  375.  
  376.  
  377. /****************************************************************************/
  378. /*  wopen                                                                   */
  379. /****************************************************************************/
  380. /*-----------------------------Description----------------------------------*/
  381. /*  This function opens a window with the given position and dimensions.    */
  382. /*-----------------------------Arguments------------------------------------*/
  383. /*  WORD bord          number of graphic lines in border                    */
  384. /*  char *p            pointer to prompt to appear in border                */
  385. /*  WORD sr            absolute screen row of upper left corner of window   */
  386. /*  WORD sc            absolute screen column of up-left corner of window   */
  387. /*  WORD rows          number of rows in window                             */
  388. /*  WORD cols          number of columns in window                          */
  389. /*  WORD attr          initial character attribute (colors) for window      */
  390. /*-----------------------------Return value---------------------------------*/
  391. /*  wopen() returns a pointer (WIND *) to the window just opened.  This     */
  392. /*  pointer is then used when calling the other windowing functions.        */
  393. /*-----------------------------Constraints/Gotchas--------------------------*/
  394. /*--Date--------Programmer----------Comments--------------------------------*/
  395. /*  1990.01.01  D. Rogers           initial code                            */
  396. /****************************************************************************/
  397. WIND *wopen(WORD bord,char *p,WORD sr,WORD sc,WORD rows,WORD cols,WORD attr)
  398. {
  399.   WORD wsiz;                           /*size of window*/
  400.   WORD ac;                             /*attribute:character*/
  401.   WORD *tp;                            /*pointer to window's text*/
  402.  
  403.   if (!winitd) if (!winit()) return NULL;   /*make sure initialized*/
  404.   if (bord>2) bord=0;                  /*border is 0 (no border), 1 or 2*/
  405.   if (!attr) attr=LIGHTGRAY;           /*set default attribute*/
  406.   if (sr>=wscr->rows) sr=1;            /*check screen row*/
  407.   if (sc>=wscr->cols) sc=1;            /*check screen column*/
  408.   if ((sr+rows)>wscr->rows) rows=wscr->rows-sr-1;  /*check last row*/
  409.   if ((sc+cols)>wscr->cols) cols=wscr->cols-sc-1;  /*check last column*/
  410.   if ((rows==0)||(cols==0)) return NULL;           /*couldn't recover*/
  411.   wsiz=(rows*cols)<<1;                 /*window size in bytes*/
  412.   wact->wnxt=(WIND *)malloc(sizeof(WIND)+wsiz);  /*get memory*/
  413.   if (wact->wnxt==NULL) return NULL;   /*no room!*/
  414.   (wact->wnxt)->wprv=wact;             /*make new window point to old*/
  415.   wact=wact->wnxt;                     /*make active window point to new*/
  416.   wact->rows=rows;                     /*rows as provided*/
  417.   wact->cols=cols;                     /*columns as provided*/
  418.   wact->srow=sr;                       /*window starts in row 0 on screen*/
  419.   wact->scol=sc;                       /*window starts in column 0 on screen*/
  420.   wact->row =0;                        /*normal cursor row*/
  421.   wact->col =0;                        /*normal cursor column*/
  422.   wact->csiz=DEF_CSIZE;                /*cursor size is default size*/
  423.   wact->attr=attr;                     /*default low intensity white on black*/
  424.   wact->fchr=' ';                      /*fill character for clearing*/
  425.   wact->prompt=p;                      /*set prompt pointer*/
  426.   wact->bord=bord;                     /*border lines as prescribed*/
  427.   wact->battr=attr;                    /*set border attribute*/
  428.   wact->fl.wrap=1;                     /*wrap text at end of line*/
  429.   wact->fl.scroll=1;                   /*scroll window at bottom*/
  430.   wact->fl.moves=0;                    /*no window moving allowed*/
  431.   wact->fl.sizes=0;                    /*no window resizing*/
  432.   wact->fl.alive=1;                    /*show it*/
  433.   wact->fl.saved=0;                    /*not saved yet*/
  434.   wact->fl.showcr=0;                   /*don't show little note character*/
  435.   wact->fl.showlf=0;                   /*ditto for LF one*/
  436.   wact->fl.showbs=0;                   /*ditto for BS one*/
  437.   wact->wnxt=NULL;                     /*next window is nonexistent*/
  438.   HI(ac)=wact->attr;                   /*put attribute for clearing*/
  439.   LO(ac)=wact->fchr;                   /*use clearing fill character*/
  440.   wsiz>>=1;                            /*size goes from bytes to words*/
  441.   tp=wact->wtxt;                       /*point to text of window*/
  442.   for (;wsiz>0;wsiz--) *tp++=ac;       /*load clearing character into text*/
  443.   if (wupd) wupdate(wact);             /*update the screen*/
  444.   return wact;                         /*return the window id*/
  445. }   /*wopen*/
  446.  
  447.  
  448. /****************************************************************************/
  449. /*  wgetcrow, wgetccol, wgetcsiz                                            */
  450. /****************************************************************************/
  451. /*-----------------------------Description----------------------------------*/
  452. /*  These functions get the cursor row, column and size, respectively, of   */
  453. /*  the specified window.                                                   */
  454. /*-----------------------------Arguments------------------------------------*/
  455. /*  WIND *w            window from*/
  456. /*-----------------------------Return value---------------------------------*/
  457. /*  Returns row, column or size of window.                                  */
  458. /*-----------------------------Constraints/Gotchas--------------------------*/
  459. /*--Date--------Programmer----------Comments--------------------------------*/
  460. /*  1990.01.01  D. Rogers           initial code                            */
  461. /****************************************************************************/
  462. WORD wgetcrow(WIND *w)
  463. {
  464.   if ((w==NULL)||!winitd) return 0;    /*returns*/
  465.   return (w->row);
  466. }   /*wgetcrow*/
  467.  
  468. WORD wgetccol(WIND *w)
  469. {
  470.   if ((w==NULL)||!winitd) return 0;    /*returns*/
  471.   return (w->col);
  472. }   /*wgetccol*/
  473.  
  474. WORD wgetcsiz(WIND *w)
  475. {
  476.   if ((w==NULL)||!winitd) return 0;    /*returns*/
  477.   return (w->csiz);
  478. }   /*wgetccol*/
  479.  
  480.  
  481. /****************************************************************************/
  482. /*  wsetcpos                                                                */
  483. /****************************************************************************/
  484. /*-----------------------------Description----------------------------------*/
  485. /*  This function sets the cursor position within a window.                 */
  486. /*-----------------------------Arguments------------------------------------*/
  487. /*  WIND *w            window for which cursor position is to be set        */
  488. /*  WORD row           row to set                                           */
  489. /*  WORD col           column to set                                        */
  490. /*-----------------------------Return value---------------------------------*/
  491. /*-----------------------------Constraints/Gotchas--------------------------*/
  492. /*--Date--------Programmer----------Comments--------------------------------*/
  493. /*  1990.01.01  D. Rogers           initial code                            */
  494. /****************************************************************************/
  495. void wsetcpos(WIND *w,WORD row,WORD col)
  496. {
  497.   if ((w==NULL)||!winitd) return;      /*if not initialized, hit the road*/
  498.   if ((row<w->rows)&&(col<w->cols)) {  /*if legal row,column*/
  499.     w->row=row;                        /*set row*/
  500.     w->col=col;                        /*set column*/
  501.     if (wupd&&ptrcmp(w,wact))          /*if this is the active window...*/
  502.       setcpos(w->srow+w->row,w->scol+w->col);   /*...display cursor*/
  503.   }   /*if r,c ok*/
  504. }   /*wsetcpos*/
  505.  
  506.  
  507. /****************************************************************************/
  508. /*  wsetcsiz                                                                */
  509. /****************************************************************************/
  510. /*-----------------------------Description----------------------------------*/
  511. /*  This function sets the cursor size of the specified window.  If the     */
  512. /*  window is the active one, it sets the size immediately on the screen.   */
  513. /*-----------------------------Arguments------------------------------------*/
  514. /*  WIND *w            window for cursor sizing                             */
  515. /*  WORD siz           size (start and stop scan lines) of cursor           */
  516. /*-----------------------------Return value---------------------------------*/
  517. /*-----------------------------Constraints/Gotchas--------------------------*/
  518. /*--Date--------Programmer----------Comments--------------------------------*/
  519. /*  1990.01.01  D. Rogers           initial code                            */
  520. /****************************************************************************/
  521. void wsetcsiz(WIND *w,WORD siz)
  522. {
  523.   if ((w==NULL)||!winitd) return;      /*return if stupid*/
  524.   w->csiz=siz;                         /*set window cursor size*/
  525.   if (wupd&&w->fl.alive&&ptrcmp(w,wact))
  526.     setcsiz(w->csiz);                  /*set on screen if active window*/
  527. }   /*wsetcsiz*/
  528.  
  529.  
  530. /****************************************************************************/
  531. /*  wfcolor, wbcolor, wsetattr, wgetattr                                    */
  532. /****************************************************************************/
  533. /*-----------------------------Description----------------------------------*/
  534. /*  These functions set the foreground and background colors of the given   */
  535. /*  window, respectively.                                                   */
  536. /*-----------------------------Arguments------------------------------------*/
  537. /*  WIND *w            window whose attribute is to change                  */
  538. /*  WORD color         color for foreground/background                      */
  539. /*-----------------------------Return value---------------------------------*/
  540. /*-----------------------------Constraints/Gotchas--------------------------*/
  541. /*  Only the first 8 colors may be used as background colors (BLACK up to   */
  542. /*  LIGHTGRAY).  Higher colors which are used as background colors will     */
  543. /*  result in a blinking attribute (see the BLINK constant in [wutil.h]).   */
  544. /*  In monochrome mode, some adaptors turn on underscore for various        */
  545. /*  attribute settings.                                                     */
  546. /*--Date--------Programmer----------Comments--------------------------------*/
  547. /*  1990.01.01  D. Rogers           initial code                            */
  548. /****************************************************************************/
  549. void wfcolor(WIND *w,WORD color)
  550. {
  551.   if ((w==NULL)||!winitd) return;      /*leave*/
  552.   w->attr&=0xF0;                       /*clear foreground portion*/
  553.   w->attr|=(color&0x0F);               /*insert new foreground color*/
  554. }   /*wfcolor*/
  555.  
  556. void wbcolor(WIND *w,WORD color)
  557. {
  558.   if ((w==NULL)||!winitd) return;      /*leave*/
  559.   w->attr&=0x0F;                       /*clear out previous background*/
  560.   w->attr|=((color<<4)&0xF0);          /*insert new background*/
  561. }   /*wbcolor*/
  562.  
  563.  
  564. WORD wsetattr(WIND* w,WORD attr)
  565. {
  566.   WORD a;                              /*old attribute*/
  567.   if ((w==NULL)||!winitd) return 0;    /*leave*/
  568.   a=w->attr;                           /*save old attribute*/
  569.   w->attr=attr;                        /*set attribute*/
  570.   return a;                            /*return old attribute*/
  571. }   /*wsetattr*/
  572.  
  573.  
  574. WORD wgetattr(WIND *w)
  575. {
  576.   if ((w==NULL)||!winitd) return 0;    /*leave*/
  577.   return w->attr;
  578. }   /*wgetattr*/
  579.  
  580.  
  581. /****************************************************************************/
  582. /*  wclr, wclrbor, wclreor, wclrbow, wclreow                                */
  583. /****************************************************************************/
  584. void wclr(WIND *w)
  585. {
  586.   WORD k;                              /*counter*/
  587.   WORD *tp;                            /*text pointer*/
  588.   WORD ac;                             /*attribute:character*/
  589.  
  590.   if ((w==NULL)||!winitd) return;      /*leave if bad*/
  591.   k=w->rows*w->cols;                   /*calculate window size*/
  592.   tp=w->wtxt;                          /*point to window text*/
  593.   HI(ac)=(BYTE)w->attr;                /*set up attribute*/
  594.   LO(ac)=(BYTE)w->fchr;                /*set up fill character*/
  595.   for (;(k);k--) *tp++=ac;             /*fill window with character*/
  596.   w->row=0;                            /*reset row*/
  597.   w->col=0;                            /*and column*/
  598.   if (wupd) wupdate(w);                /*update window if necessary*/
  599. }   /*wclr*/
  600.  
  601. void wclrbor(WIND *w)
  602. {
  603.   WORD c;                              /*column counter*/
  604.   WORD *tp;                            /*text pointer*/
  605.   WORD ac;                             /*attribute:character*/
  606.  
  607.   if ((w==NULL)||!winitd) return;      /*leave if bad*/
  608.   if (w->row>=w->rows) w->row=w->rows-1;
  609.   if (w->col>=w->cols) w->col=w->cols-1;
  610.   tp=w->wtxt;                          /*point to window text*/
  611.   tp+=w->row*w->cols;                  /*point to start of row*/
  612.   HI(ac)=(BYTE)w->attr;                /*set up attribute*/
  613.   LO(ac)=(BYTE)w->fchr;                /*set up fill character*/
  614.   for (c=0;c<=w->col;c++) *tp++=ac;    /*fill character to cursor*/
  615.   if (wupd) wupdate(w);                /*update window if necessary*/
  616. }   /*wclrbor*/
  617.  
  618. void wclreor(WIND *w)
  619. {
  620.   WORD c;                              /*column counter*/
  621.   WORD *tp;                            /*text pointer*/
  622.   WORD ac;                             /*attribute:character*/
  623.  
  624.   if ((w==NULL)||!winitd) return;      /*leave if bad*/
  625.   if (w->row>=w->rows) w->row=w->rows-1;
  626.   if (w->col>=w->cols) w->col=w->cols-1;
  627.   tp=w->wtxt;                          /*point to window text*/
  628.   tp+=w->row*w->cols;                  /*point to start of row*/
  629.   tp+=w->col;                          /*point to column of row*/
  630.   HI(ac)=(BYTE)w->attr;                /*set up attribute*/
  631.   LO(ac)=(BYTE)w->fchr;                /*set up fill character*/
  632.   for (c=w->col;c<w->cols;c++) *tp++=ac;   /*fill character from cursor*/
  633.   if (wupd) wupdate(w);                /*update window if necessary*/
  634. }   /*wclreor*/
  635.  
  636. void wclrbow(WIND *w)
  637. {
  638.   WORD k;                              /*counter*/
  639.   WORD *tp;                            /*text pointer*/
  640.   WORD ac;                             /*attribute:character*/
  641.  
  642.   if ((w==NULL)||!winitd) return;      /*leave if bad*/
  643.   if (w->row>=w->rows) w->row=w->rows-1;
  644.   if (w->col>=w->cols) w->col=w->cols-1;
  645.   tp=w->wtxt;                          /*point to window text*/
  646.   k=w->row*w->cols;                    /*go up to row*/
  647.   k+=w->col+1;                         /*go up to column, inclusive*/
  648.   HI(ac)=(BYTE)w->attr;                /*set up attribute*/
  649.   LO(ac)=(BYTE)w->fchr;                /*set up fill character*/
  650.   for (;(k);k--) *tp++=ac;             /*fill character to cursor*/
  651.   if (wupd) wupdate(w);                /*update window if necessary*/
  652. }   /*wclrbow*/
  653.  
  654. void wclreow(WIND *w)
  655. {
  656.   WORD k;                              /*counter*/
  657.   WORD *tp;                            /*text pointer*/
  658.   WORD ac;                             /*attribute:character*/
  659.  
  660.   if ((w==NULL)||!winitd) return;      /*leave if bad*/
  661.   if (w->row>=w->rows) w->row=w->rows-1;
  662.   if (w->col>=w->cols) w->col=w->cols-1;
  663.   tp=w->wtxt;                          /*point to window text*/
  664.   tp+=w->row*w->cols;                  /*to row*/
  665.   tp+=w->col;                          /*to column*/
  666.   k=(w->rows-w->row-1)*w->cols;        /*go up to row*/
  667.   k+=(w->cols-w->col);                 /*go from column, inclusive*/
  668.   HI(ac)=(BYTE)w->attr;                /*set up attribute*/
  669.   LO(ac)=(BYTE)w->fchr;                /*set up fill character*/
  670.   for (;(k);k--) *tp++=ac;             /*fill character from cursor*/
  671.   if (wupd) wupdate(w);                /*update window if necessary*/
  672. }   /*wclreow*/
  673.  
  674.  
  675. /****************************************************************************/
  676. /*  wfront                                                                  */
  677. /****************************************************************************/
  678. /*-----------------------------Description----------------------------------*/
  679. /*  This function brings the designated window to the front (makes it the   */
  680. /*  active window).                                                         */
  681. /*-----------------------------Arguments------------------------------------*/
  682. /*-----------------------------Return value---------------------------------*/
  683. /*-----------------------------Constraints/Gotchas--------------------------*/
  684. /*--Date--------Programmer----------Comments--------------------------------*/
  685. /*  1990.01.01  D. Rogers           initial code                            */
  686. /****************************************************************************/
  687. void wfront(WIND *w)
  688. {
  689.   if (!winitd) return;                 /*leave if no windows yet*/
  690.   if (w==NULL) return;                 /*leave if bad window*/
  691.   if (!ptrcmp(w,wact)&&!ptrcmp(w,wscr)) {   /*do nothing if already active*/
  692.     (w->wprv)->wnxt=w->wnxt;           /*make prev's next be my next*/
  693.     (w->wnxt)->wprv=w->wprv;           /*make next's prev be my prev*/
  694.     wact->wnxt=w;                      /*make current active point to me*/
  695.     w->wprv=wact;                      /*point back at current active*/
  696.     w->wnxt=NULL;                      /*turn off forward pointer*/
  697.     wact=w;                            /*i'm active now*/
  698.   }   /*if need to rearrange*/
  699.   w->fl.alive=1;                       /*unhide it*/
  700.   if (wupd) wupdate(w);                /*update if already active*/
  701. }   /*wfront*/
  702.  
  703.  
  704. /****************************************************************************/
  705. /*  wback                                                                   */
  706. /****************************************************************************/
  707. /*-----------------------------Description----------------------------------*/
  708. /*  This function pushes the specified window to the back (i.e., just in    */
  709. /*  front of the base window).                                              */
  710. /*-----------------------------Arguments------------------------------------*/
  711. /*  WIND *w            window to push back                                  */
  712. /*-----------------------------Return value---------------------------------*/
  713. /*-----------------------------Constraints/Gotchas--------------------------*/
  714. /*--Date--------Programmer----------Comments--------------------------------*/
  715. /*  1990.01.01  D. Rogers           initial code                            */
  716. /****************************************************************************/
  717. void wback(WIND *w)
  718. {
  719.   if (!winitd) return;                 /*leave if no windows yet*/
  720.   if (w==NULL) return;                 /*leave if bad window*/
  721.   if (!ptrcmp(w,wscr)) {               /*do nothing if base window*/
  722.     (w->wprv)->wnxt=w->wnxt;           /*make prev's next be my next*/
  723.     if (w->wnxt!=NULL) (w->wnxt)->wprv=w->wprv;   /*make next's prev be prev*/
  724.     (wscr->wnxt)->wprv=w;              /*have window atop base point to me*/
  725.     w->wnxt=wscr->wnxt;                /*point to just past base window*/
  726.     w->wprv=wscr;                      /*point back at base*/
  727.     wscr->wnxt=w;                      /*have base point to me*/
  728.   }   /*if need to rearrange*/
  729.   if (wupd) wupdate(NULL);              /*update even if already active*/
  730. }   /*wback*/
  731.  
  732.  
  733. void whide(WIND *w)
  734. {
  735.   if (w==NULL) return;
  736.   w->fl.alive=0;
  737.   wback(w);
  738. }   /*whide*/
  739.  
  740.  
  741. /****************************************************************************/
  742. /*  wdelrow                                                                 */
  743. /****************************************************************************/
  744. /*-----------------------------Description----------------------------------*/
  745. /*  This function deletes the current row from the given window.  It puts   */
  746. /*  a blank line at the bottom of the window (with the current attribute).  */
  747. /*-----------------------------Arguments------------------------------------*/
  748. /*-----------------------------Return value---------------------------------*/
  749. /*-----------------------------Constraints/Gotchas--------------------------*/
  750. /*--Date--------Programmer----------Comments--------------------------------*/
  751. /*  1990.01.01  D. Rogers           initial code                            */
  752. /****************************************************************************/
  753. void wdelrow(WIND *w)
  754. {
  755.   WORD *tp;                            /*pointer to window text*/
  756.   WORD r;                              /*local row counter*/
  757.   WORD ac;                             /*atrr:char*/
  758.   WORD n;                              /*number of bytes to copy*/
  759.  
  760.   if (!winitd) return;                 /*check initialization*/
  761.   if (w==NULL) return;                 /*check window pointer*/
  762.   w->col=0;                            /*resets column*/
  763.   if (w->row>=w->rows) {               /*make sure row is ok*/
  764.     w->row=w->rows-1;                  /*reset to last row*/
  765.   }   /*if bad row*/
  766.   tp=w->wtxt;                          /*point to top of text*/
  767.   tp+=w->row*w->cols;                  /*go to current row*/
  768.   n=w->cols<<1;                        /*bytes to copy per row*/
  769.   for (r=w->row;r<(w->rows-1);r++) {   /*go through each row but last*/
  770.     memcpyi(tp,(tp+w->cols),n);        /*copy next row of BYTEs*/
  771.     tp+=w->cols;                       /*point to next row of WORDs*/
  772.   }   /*for*/
  773.   HI(ac)=w->attr;                      /*load attribute*/
  774.   LO(ac)=w->fchr;                      /*load fill char to clear*/
  775.   for (r=0;r<w->cols;r++) *tp++=ac;    /*clear last line*/
  776.   if (wupd) wupdate(w);                /*update window*/
  777. }   /*wdelrow*/
  778.  
  779.  
  780. /****************************************************************************/
  781. /*  winsrow                                                                 */
  782. /****************************************************************************/
  783. /*-----------------------------Description----------------------------------*/
  784. /*  This function inserts a row at the current cursor position.  It fills   */
  785. /*  the row with blanks of the current attribute setting, and deletes the   */
  786. /*  bottom row of the window.                                               */
  787. /*-----------------------------Arguments------------------------------------*/
  788. /*-----------------------------Return value---------------------------------*/
  789. /*-----------------------------Constraints/Gotchas--------------------------*/
  790. /*--Date--------Programmer----------Comments--------------------------------*/
  791. /*  1990.01.01  D. Rogers           initial code                            */
  792. /****************************************************************************/
  793. void winsrow(WIND *w)
  794. {
  795.   WORD *tp,*tp2;                       /*pointer to window text*/
  796.   WORD r;                              /*local row counter*/
  797.   WORD ac;                             /*atrr:char*/
  798.   WORD n;                              /*number of bytes*/
  799.  
  800.   if (!winitd) return;                 /*check initialization*/
  801.   if (w==NULL) return;                 /*check window pointer*/
  802.   w->col=0;                            /*reset column*/
  803.   if (w->row>=w->rows) {               /*make sure row is ok*/
  804.     w->row=w->rows-1;                  /*reset to last row*/
  805.   }   /*if bad row*/
  806.   tp=w->wtxt;                          /*point to top of text*/
  807.   tp+=(w->rows-1)*w->cols;             /*go to last row*/
  808.   n=w->cols<<1;                        /*number of bytes=2*words*/
  809.   for (r=(w->rows-1);r>w->row;r--) {   /*go through each row but current*/
  810.     tp2=tp;
  811.     tp2-=w->cols;
  812.     memcpyi(tp,tp2,n);                 /*copy from prev row of BYTEs*/
  813.     tp=tp2;                            /*point to previous row of WORDs*/
  814.   }   /*for*/
  815.   HI(ac)=w->attr;                      /*load attribute*/
  816.   LO(ac)=w->fchr;                      /*load fill char since clearing*/
  817.   for (r=0;r<w->cols;r++) *tp++=ac;    /*clear current row*/
  818.   if (wupd) wupdate(w);                /*update window*/
  819. }   /*winsrow*/
  820.  
  821.  
  822. /****************************************************************************/
  823. /*  wputc                                                                   */
  824. /****************************************************************************/
  825. /*-----------------------------Description----------------------------------*/
  826. /*  This function writes a single character out to the window.              */
  827. /*-----------------------------Arguments------------------------------------*/
  828. /*-----------------------------Return value---------------------------------*/
  829. /*-----------------------------Constraints/Gotchas--------------------------*/
  830. /*--Date--------Programmer----------Comments--------------------------------*/
  831. /*  1990.01.01  D. Rogers           initial code                            */
  832. /****************************************************************************/
  833. void wputc(WIND *w,int c)
  834. {
  835.   WORD *tp;                            /*point to window's text*/
  836.   WORD ac=0;                           /*attribute:character*/
  837.   BYTE twupd;                          /*locally store wupd*/
  838.   BYTE show=1;
  839.  
  840.   if ((w==NULL)||!winitd) return;      /*return*/
  841.   if (w->row>=w->rows) w->row=w->rows-1;   /*check row*/
  842.   if (w->col>=w->cols) w->col=w->cols-1;   /*check column*/
  843.   switch (c) {                         /*check for special chars*/
  844.     case 0x0D:                         /*on CR...*/
  845.       if (w->fl.showcr) break;
  846.       show=0;
  847.       w->col=0;                        /*...go to beginning of line*/
  848.       break;
  849.     case 0x0A:                         /*on LF (newline)...*/
  850.       if (w->fl.showlf) break;
  851.       show=0;
  852.       (w->row)++;                      /*...go to next row*/
  853.       w->col=0;                        /*...beginning thereof*/
  854.       break;
  855.     case 0x08:                         /*if BS...*/
  856.       if (w->fl.showbs) break;
  857.       show=0;
  858.       if (w->col==0) {                 /*see if first column*/
  859.         if (w->fl.wrap&&(w->row>0)) {  /*is wrap enabled?*/
  860.           w->col=w->cols-1;            /*...back one row*/
  861.           (w->row)--;                  /*...at the end*/
  862.         }   /*if not first row and wrap enabled*/
  863.       }   /*if first column*/
  864.       else
  865.         (w->col)--;                    /*just decrement column*/
  866.       break;
  867.     default:
  868.       ;
  869.   }   /*switch*/
  870.   if (show) {                          /*see if showing after translation*/
  871.     HI(ac)=w->attr;                    /*set up current attribute*/
  872.     LO(ac)=(BYTE)c;                    /*set up passed character*/
  873.     tp=w->wtxt;                        /*point to text*/
  874.     tp+=(w->row*w->cols);              /*go to row in window's text*/
  875.     tp+=w->col;                        /*go to column in window's text*/
  876.     *tp=ac;                            /*copy character*/
  877.     (w->col)++;                        /*ready for next character*/
  878.   }   /*if showing character*/
  879.   if (w->col>=w->cols) {               /*if wrapped*/
  880.     if (w->fl.wrap) {                  /*if wrapping enabled...*/
  881.       (w->row)++;                      /*...go to next row*/
  882.       w->col=0;                        /*...at beginning*/
  883.     }                                  /*otherwise...*/
  884.     else w->col=w->cols-1;             /*...just leave cursor at end*/
  885.   }   /*if wrapped around end of row*/
  886.   if (w->row>=w->rows) {               /*if scrolled*/
  887.     if (w->fl.scroll) {                /*if scrolling enabled...*/
  888.       w->row=0;                        /*...set to first row for delrow call*/
  889.       twupd=wupd;                      /*...save wupd setting*/
  890.       wupd=0;                          /*...don't update when deleting row*/
  891.       wdelrow(w);                      /*...delete top row of window*/
  892.       wupd=twupd;                      /*...restore wupd setting*/
  893.       w->row=w->rows-1;                /*...set to last row*/
  894.       w->col=0;                        /*...set to first column in row*/
  895.     }                                  /*otherwise...*/
  896.     else w->row=0;                     /*...go back to top of window*/
  897.   }   /*if scrolled at end of screen*/
  898.   if (wupd) wupdate(w);
  899. }   /*wputc*/
  900.  
  901.  
  902. /****************************************************************************/
  903. /*  wputs                                                                   */
  904. /****************************************************************************/
  905. /*-----------------------------Description----------------------------------*/
  906. /*  This function writes a string to a specified window.                    */
  907. /*-----------------------------Arguments------------------------------------*/
  908. /*-----------------------------Return value---------------------------------*/
  909. /*-----------------------------Constraints/Gotchas--------------------------*/
  910. /*--Date--------Programmer----------Comments--------------------------------*/
  911. /*  1990.01.01  D. Rogers           initial code                            */
  912. /****************************************************************************/
  913. void wputs(WIND *w,char *s)
  914. {
  915.   BYTE twupd;
  916.  
  917.   if (!winitd) if (!winit()) return;   /*return if can't initialize*/
  918.   if (w==NULL) return;                 /*return if can't find window*/
  919.   twupd=wupd;                          /*save update flag*/
  920.   wupd=0;                              /*do wputc's before updating screen*/
  921.   while (*s) wputc(w,*s++);            /*write out each character*/
  922.   wupd=twupd;                          /*reset internal flag*/
  923.   if (wupd) wupdate(w);                /*update screen*/
  924. }   /*wputs*/
  925.  
  926.  
  927. /****************************************************************************/
  928. /*  wputns                                                                  */
  929. /****************************************************************************/
  930. /*-----------------------------Description----------------------------------*/
  931. /*  This function writes n characters to the screen, regardless of the      */
  932. /*  presence of a NUL character.                                            */
  933. /*-----------------------------Arguments------------------------------------*/
  934. /*-----------------------------Return value---------------------------------*/
  935. /*-----------------------------Constraints/Gotchas--------------------------*/
  936. /*--Date--------Programmer----------Comments--------------------------------*/
  937. /*  1990.01.01  D. Rogers           initial code                            */
  938. /****************************************************************************/
  939. void wputns(WIND *w,char *s,int n)
  940. {
  941.   BYTE twupd;
  942.  
  943.   if (!winitd) if (!winit()) return;   /*return if can't initialize*/
  944.   if (w==NULL) return;                 /*return if can't find window*/
  945.   twupd=wupd;                          /*save update flag*/
  946.   wupd=0;                              /*do wputc's before updating screen*/
  947.   while (n--) wputc(w,*s++);           /*write out each character*/
  948.   wupd=twupd;                          /*reset internal flag*/
  949.   if (wupd) wupdate(w);                /*update screen*/
  950. }   /*wputs*/
  951.  
  952.  
  953. /****************************************************************************/
  954. /*  wputrcs                                                                 */
  955. /****************************************************************************/
  956. /*-----------------------------Description----------------------------------*/
  957. /*  This function positions the cursor in a window, then writes out the     */
  958. /*  specified string                                                        */
  959. /*-----------------------------Arguments------------------------------------*/
  960. /*-----------------------------Return value---------------------------------*/
  961. /*-----------------------------Constraints/Gotchas--------------------------*/
  962. /*--Date--------Programmer----------Comments--------------------------------*/
  963. /*  1990.01.01  D. Rogers           initial code                            */
  964. /****************************************************************************/
  965. void wputrcs(WIND *w,WORD r,WORD c,char *s)
  966. {
  967.   BYTE twupd;
  968.  
  969.   if ((w==NULL)||!winit) return;       /*leave*/
  970.   if ((r>=w->rows)||(c>=w->cols)) return;
  971.   w->row=r;
  972.   w->col=c;
  973.   twupd=wupd;                          /*save update flag*/
  974.   wupd=0;
  975.   while (*s) wputc(w,*s++);            /*write out string*/
  976.   wupd=twupd;                          /*restore update flag*/
  977.   if (wupd) wupdate(w);                /*update*/
  978. }   /*wputrcs*/
  979.  
  980.  
  981. /****************************************************************************/
  982. /*  wprintf                                                                 */
  983. /****************************************************************************/
  984. /*-----------------------------Description----------------------------------*/
  985. /*  This function performs a printf to the given window.                    */
  986. /*-----------------------------Arguments------------------------------------*/
  987. /*  WIND *w            window for printf                                    */
  988. /*  BYTE *fmt          format for printf                                    */
  989. /*-----------------------------Return value---------------------------------*/
  990. /*-----------------------------Constraints/Gotchas--------------------------*/
  991. /*--Date--------Programmer----------Comments--------------------------------*/
  992. /*  1990.01.01  D. Rogers           initial code                            */
  993. /****************************************************************************/
  994. void cdecl wprintf(WIND *w,char *fmt,...)
  995. {
  996. #define MAX_DATUM   256
  997.   static BYTE bs[MAX_DATUM];                  /*256 bytes max for formatted data*/
  998.   va_list va;                          /*variable argument list*/
  999.  
  1000.   va_start(va,fmt);                    /*point to argument list*/
  1001.   if ((w==NULL)||!winitd) return;      /*leave if bad*/
  1002.   vsprintf(bs,fmt,va);                 /*write to string*/
  1003.   wputs(w,bs);                         /*write to window*/
  1004.   va_end(va);                          /*close variable list pointers*/
  1005. }   /*wprintf*/
  1006.  
  1007.  
  1008. /****************************************************************************/
  1009. /*  wgetc                                                                   */
  1010. /****************************************************************************/
  1011. /*-----------------------------Description----------------------------------*/
  1012. /*  This function gets a character from the specified window at the         */
  1013. /*  current cursor position.  The given window is first made active.        */
  1014. /*-----------------------------Arguments------------------------------------*/
  1015. /*  WIND *w            window to use to read the character                  */
  1016. /*-----------------------------Return value---------------------------------*/
  1017. /*  wgetc() returns the ASCII code of the key pressed.  If a special        */
  1018. /*  function key is pressed, it returns the scan code plus 0x100 (256).     */
  1019. /*-----------------------------Constraints/Gotchas--------------------------*/
  1020. /*--Date--------Programmer----------Comments--------------------------------*/
  1021. /*  1990.01.01  D. Rogers           initial code                            */
  1022. /****************************************************************************/
  1023. int  wgetc(WIND *w)
  1024. {
  1025.   int c;                               /*character*/
  1026.  
  1027.   if ((w==NULL)||!winitd) return 0;    /*return if not initialized*/
  1028.   w->fl.alive=1;                       /*make sure it's alive*/
  1029.   if (!ptrcmp(w,wact)) wfront(w);      /*bring window to front if necessary*/
  1030. #if 0
  1031.   while (!kbhit()) {
  1032.     if (scrollhit()) wmovew(w);        /*move window*/
  1033.   }   /*while key not hit*/
  1034. #endif
  1035.   c=(BYTE)getch();                     /*get character*/
  1036.   if (c)                               /*if normal character...*/
  1037.     return (c);                        /*...just return it*/
  1038.   else                                 /*otherwise...*/
  1039.     return (0x100+getch());            /*...add 0x100 to next char*/
  1040. }   /*wgetc*/
  1041.  
  1042. int  wgetce(WIND *w)                   /*get char and echo*/
  1043. {
  1044.   int c;
  1045.   c=wgetc(w);                          /*get char*/
  1046.   if ((c>0)&&(c<0x100)) wputc(w,c);    /*and echo*/
  1047.   return (c);
  1048. }
  1049.  
  1050.  
  1051. /****************************************************************************/
  1052. /*  wgets                                                                   */
  1053. /****************************************************************************/
  1054. /*-----------------------------Description----------------------------------*/
  1055. /*  This function reads a string in from a window.  It ends when CR is      */
  1056. /*  pressed, or when ESC is pressed.  The CR is NOT included in the         */
  1057. /*  return string.                                                          */
  1058. /*-----------------------------Arguments------------------------------------*/
  1059. /*  WIND *w            window                                               */
  1060. /*  BYTE *s            string to receive characters                         */
  1061. /*  int  n             maximum number of characters to read                 */
  1062. /*-----------------------------Return value---------------------------------*/
  1063. /*  wgets() returns the number of characters actually received.             */
  1064. /*-----------------------------Constraints/Gotchas--------------------------*/
  1065. /*--Date--------Programmer----------Comments--------------------------------*/
  1066. /*  1990.01.01  D. Rogers           initial code                            */
  1067. /****************************************************************************/
  1068. int  wgets(WIND *w,char *s,int n)
  1069. {
  1070.   WORD k;
  1071.   int c;
  1072.  
  1073.   if (!winitd) return 0;               /*leave if not initialized*/
  1074.   if (w==NULL) return 0;               /*leave if bad pointer*/
  1075.   if (n<2) return 0;                   /*leave if no chars to get*/
  1076.   n--;                                 /*leave room for NUL at string's end*/
  1077.   k=0;                                 /*initialize counter*/
  1078.   c=0;                                 /*keep loop alive*/
  1079.   while (c!=0x0D) {                    /*while not done*/
  1080.     c=wgetc(w);                        /*get a character from the window*/
  1081.     switch (c) {
  1082.       case 0x0D:                       /*carriage return*/
  1083.         break;
  1084.       case 0x1B:                       /*escape character*/
  1085.         k=0;                           /*reset string to 0*/
  1086.         c=0x0D;                        /*tell loop we're done*/
  1087.         break;
  1088.       case 0x08:
  1089.         if (k) {
  1090.           wupd=0;                      /*turn off the automatic updates*/
  1091.           wputc(w,'\x08');             /*write out a backspace*/
  1092.           wputc(w,w->fchr);            /*write out a fill character*/
  1093.           wupd=1;                      /*turn updating back on*/
  1094.           wputc(w,'\x08');             /*write out another backspace*/
  1095.           k--;                         /*go back one in string*/
  1096.         }
  1097.         break;
  1098.       default:
  1099.         if ((k<n)&&(c<0x100)) {        /*if not special key*/
  1100.           s[k++]=(BYTE)c;              /*load char and increment position*/
  1101.           wputc(w,c);                  /*put out character*/
  1102.         }   /*if printable*/
  1103.     }   /*switch*/
  1104.   }   /*while*/
  1105.   s[k]=0;                              /*put end marker in string*/
  1106.   return (k);                          /*return number of chars read*/
  1107. }   /*wgets*/
  1108.  
  1109.  
  1110.