home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************/
- /* MODULE wutil.c */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This module contains windowing utilities for use in text mode on IBM */
- /* PC's. */
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /* These functions will only work on an IBM PC in text mode. */
- /* Function descriptions will NOT list those functions available in both */
- /* Turbo C and Microsoft C (such as int86() in [dos.h]). It is assumed */
- /* that the reader is familiar with these non-ANSII functions. */
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 (c) D. Rogers initial code */
- /****************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #include <conio.h>
- #include <dos.h>
-
- #include "strutil.h"
- #include "scrutil.h"
- #include "wutil.h"
-
-
- char winitd=0; /*flag for windows initialization*/
- char wupd=1; /*flag for updating*/
- char wcga=0; /*don't check for CGA retrace scan*/
- WORD wscr_size=0; /*bytes in original screen*/
- WORD *vscr; /*pointer to virtual screen*/
- WORD far *vidp; /*pointer to video segment*/
- WIND *wscr; /*original screen, base window*/
- WIND *wact; /*current active window pointer*/
-
-
- /****************************************************************************/
- /* winit */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function initializes the windowing environment. Make sure this */
- /* function is not called twice without calling wpurge(). */
- /*-----------------------------Arguments------------------------------------*/
- /*-----------------------------Return value---------------------------------*/
- /* winit() returns 1 if everything checks out ok, 0 otherwise (if no */
- /* memory was available for the virtual screen, etc.). */
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- int winit(void)
- {
- WORD rs,cs; /*rows and columns on original screen*/
-
- if (winitd) return 0; /*if already initialized*/
- switch (getsmod()) { /*check the mode*/
- case MONO_80_25:
- vidp=MONO_POINTER; /*...set mono video pointer*/
- break;
- case TEXT_40_25_BW:
- case TEXT_40_25:
- case TEXT_80_25_BW:
- case TEXT_80_25:
- case TEXT_80_HI:
- vidp=COLOR_POINTER; /*...set color video pointer*/
- break;
- default:
- return 0; /*..unknown/nontext video mode*/
- } /*switch on video mode*/
-
- rs=getsrows(); /*rows available on screen*/
- cs=getscols(); /*columns available on screen*/
- wscr_size=rs*cs*2; /*get number of bytes in original scr*/
- vscr=(WORD *)malloc(wscr_size); /*set up virtual screen*/
- if (vscr==NULL) return 0; /*oops! no room*/
- wscr=(WIND *)malloc(sizeof(WIND)+wscr_size);
- wact=wscr; /*active is base*/
- if (wscr==NULL) { free(vscr); return 0; } /*oops! no room*/
-
- /*set first window to be original screen...*/
- wscr->rows=rs; /*set rows as calc'd above*/
- wscr->cols=cs; /*set cols as calc'd above*/
- wscr->srow=0; /*window starts in row 0 on screen*/
- wscr->scol=0; /*window starts in column 0 on screen*/
- wscr->row =getcrow(); /*save screen cursor row*/
- wscr->col =getccol(); /*save screen cursor column*/
- wscr->csiz=getcsiz(); /*save screen cursor size*/
- wscr->attr=(BLACK<<4)+LIGHTGRAY; /*default low intensity white on black*/
- wscr->fchr=' '; /*default to space as fill char*/
- wscr->battr=wscr->attr; /*no border, but set attribute anyway*/
- wscr->prompt=NULL; /*set prompt pointer*/
- wscr->bord=0; /*no border*/
- wscr->fl.wrap=1; /*wrap text at end of line*/
- wscr->fl.scroll=1; /*scroll window at bottom*/
- wscr->fl.moves=0; /*no window moving allowed*/
- wscr->fl.sizes=0; /*no window resizing*/
- wscr->fl.alive=1; /*definitely show this window*/
- wscr->fl.saved=0; /*not yet saved*/
- wscr->fl.showcr=0; /*don't show little note character*/
- wscr->fl.showlf=0; /*ditto for LF one*/
- wscr->fl.showbs=0; /*ditto for BS one*/
- wscr->wprv=NULL; /*previous window is nonexistent*/
- wscr->wnxt=NULL; /*next window is also nonexistent*/
-
- #if defined(__TINY__)||defined(__SMALL__)||defined(__MEDIUM__)
- memcpynfi(wscr->wtxt,vidp,wscr_size); /*save screen into text buffer*/
- #else
- memcpyi(wscr->wtxt,vidp,wscr_size); /*save screen into text buffer*/
- #endif
- memcpyi(vscr,wscr->wtxt,wscr_size); /*update virtual screen*/
-
- winitd=1; /*indicate that now initialized*/
- return 1; /*all done!*/
- } /*winit*/
-
-
- /****************************************************************************/
- /* wvscr */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function writes the virtual screen into the real screen. */
- /*-----------------------------Arguments------------------------------------*/
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void wvscr(void)
- {
- if (wcga) ; /*check for CGA retrace scan here*/
-
- #if defined(__TINY__)||defined(__SMALL__)||defined(__MEDIUM__)
- memcpyfni(vidp,vscr,wscr_size); /*copy virtual to actual screen*/
- #else
- memcpyi(vidp,vscr,wscr_size); /*copy virtual to actual screen*/
- #endif
- } /*wvscr*/
-
-
- /****************************************************************************/
- /* wsetDOSscr, wgetDOSscr */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* These functions allow easy access to DOS system calls. */
- /* wsetDOSscr() makes the base window, wscr, the active window and hides */
- /* all other windows. It should be called before calling system() or */
- /* spawnXXX() (or execXXX()). Upon return, you should call wgetDOSscr(). */
- /* wgetDOSscr() copies the screen into the base window, wscr, and unhides */
- /* all windows previously hidden. */
- /*-----------------------------Arguments------------------------------------*/
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Global constants-----------------------------*/
- /*-------------------Mod-------Global variables-----------------------------*/
- /*-----------------------------Functions called-----------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 A. Turing initial code */
- /****************************************************************************/
- void wsetDOSscr(void)
- {
- WIND *w;
-
- if (!winitd) return; /*return at end*/
- wupd=1; /*turn on update*/
- w=wscr->wnxt;
- while (w!=NULL) {
- w->fl.saved=0;
- if (w->fl.alive) { /*if not hidden..*/
- w->fl.alive=0; /*..hide and*/
- w->fl.saved=1; /*..indicate we've done so*/
- } /*if not hidden*/
- w=w->wnxt;
- } /*while*/
- wupdate(NULL);
- } /*wsetDOSscr*/
-
-
- void wgetDOSscr(void)
- {
- WIND *w;
-
- if (!winitd) return; /*return at end*/
- wupd=1; /*turn on update*/
- wscr->row =getcrow(); /*save screen cursor row*/
- wscr->col =getccol(); /*save screen cursor column*/
- wscr->csiz=getcsiz(); /*save screen cursor size*/
- #if defined(__TINY__)||defined(__SMALL__)||defined(__MEDIUM__)
- memcpynfi(wscr->wtxt,vidp,wscr_size); /*save screen into text buffer*/
- #else
- memcpyi(wscr->wtxt,vidp,wscr_size); /*save screen into text buffer*/
- #endif
- w=wscr->wnxt;
- while (w!=NULL) {
- if (w->fl.saved) w->fl.alive=1; /*if hidden by wsetDOSscr, unhide*/
- w->fl.saved=0;
- w=w->wnxt;
- } /*while*/
- wupdate(NULL);
- } /*wgetDOSscr*/
-
-
- /****************************************************************************/
- /* wvbord */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function writes the border for a window to the virtual screen. */
- /*-----------------------------Arguments------------------------------------*/
- /* WIND *w window for which border is to be made */
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void wvbord(WIND *w)
- {
- #define TOPLEFT 0 /*mneumonics for graphics chars...*/
- #define HORIZ 1
- #define TOP_T 2
- #define TOPRIGHT 3
- #define VERT 4
- #define LEFT_T 5
- #define MIDDLE 6
- #define RIGHT_T 7
- #define BOTLEFT 8
- #define BOT_T 9
- #define BOTRIGHT 10
- static BYTE *gcs[2]={ /*text mode graphics characters*/
- "\xDA\xC4\xC2\xBF\xB3\xC3\xC5\xB4\xC0\xC1\xD9\x00",
- "\xC9\xCD\xCB\xBB\xBA\xCC\xCE\xB9\xC8\xCA\xBC\x00"
- };
- BYTE gc[12]; /*text mode graphics characters copy*/
- WORD ac; /*attribute:character*/
- WORD *vp; /*pointer into virtual screen*/
- BYTE *p; /*pointer to prompt*/
- WORD k; /*row/col counter*/
- WORD l; /*length*/
-
- if (w->bord) { /*if border around window*/
- ac=0; /*clear ac*/
- HI(ac)=w->battr; /*get border attribute*/
- if (w->bord>2) w->bord=1; /*make sure a legal value*/
- memcpyi(gc,gcs[w->bord-1],12); /*copy text graphics characters*/
- l=0; /*initialize length to 0*/
- p=w->prompt; /*point to prompt*/
- if (p!=NULL) l=strlen(p); /*get length of prompt*/
- vp=(WORD *)vscr; /*start at top of screen*/
- vp+=((w->srow-1)*wscr->cols); /*offset to first border row*/
- vp+=(w->scol-1); /*offset to correct column*/
- *vp++=ac|gc[TOPLEFT]; /*write top left character*/
- for (k=0;k<w->cols;k++) { /*go through each column*/
- if (k<l) /*if still writing prompt...*/
- *vp++=ac|*p++; /*...write out prompt character*/
- else /*otherwise...*/
- *vp++=ac|gc[HORIZ]; /*...write out horizontal bar*/
- } /*for*/
- *vp++=ac|gc[TOPRIGHT]; /*write top right character*/
- ac|=gc[VERT];
- for (k=0;k<w->rows;k++) { /*write out side walls on each row*/
- vp+=(wscr->cols-w->cols-2); /*point to left side wall*/
- *vp++=ac; /*write out vertical character*/
- vp+=w->cols; /*go to right wall*/
- *vp++=ac; /*write out vertical character*/
- } /*for*/
- ac&=0xFF00; /*clear out the vertical character*/
- vp+=(wscr->cols-w->cols-2); /*point to bottom left*/
- *vp++=ac|gc[BOTLEFT]; /*write bottom left character*/
- for (k=0;k<w->cols;k++) /*go through each column*/
- *vp++=ac|gc[HORIZ]; /*write out horizontal*/
- *vp++=ac|gc[BOTRIGHT]; /*write bottom right character*/
- } /*if border*/
- } /*wvbord*/
-
-
- /****************************************************************************/
- /* wupdate */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function updates the screen, starting with the base window and */
- /* going up. */
- /*-----------------------------Arguments------------------------------------*/
- /* WIND *w window at which to start updating (NULL=from base) */
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void wupdate(WIND *w)
- {
- WORD *vp; /*pointer into virtual screen*/
- WORD *tp; /*window text pointer*/
- WORD r; /*row counter*/
-
- if (!winitd) return; /*return at end*/
- wupd=1; /*turn on update*/
- if (!w) w=wscr; /*if starting at base*/
- for (;w!=NULL;w=w->wnxt) { /*go through each window*/
- if (!w->fl.alive) continue; /*if not alive, don't update*/
- wact=w; /*make active window this window*/
- if (w->bord) wvbord(w); /*write out border if there is one*/
- vp=(WORD *)vscr; /*start at top of screen*/
- vp+=(w->srow*wscr->cols); /*offset to correct row*/
- vp+=w->scol; /*offset to correct column*/
- tp=w->wtxt; /*start in window*/
- for (r=0;r<w->rows;r++) { /*go through each row*/
- memcpyi(vp,tp,w->cols<<1); /*copying each line into virt screen*/
- vp+=wscr->cols; /*inc virtual screen pointer 1 row*/
- tp+=w->cols; /*inc window pointer 1 window row*/
- } /*for each row*/
- } /*for each window*/
- wvscr(); /*write virtual screen to real screen*/
- setcsiz(wact->csiz); /*set cursor size*/
- setcpos(wact->srow+wact->row,wact->scol+wact->col); /*set curs position*/
- } /*wupdate*/
-
-
- /****************************************************************************/
- /* wpurge */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function closes all windows and frees up all memory used by the */
- /* windowing environment. After calling wpurge(), you are allowed to */
- /* call winit() once again. */
- /*-----------------------------Arguments------------------------------------*/
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void wpurge(void)
- {
- WIND *wn;
- WORD r,c,s; /*cursor row, column, size*/
-
- if (!winitd) return;
- memcpyi(vscr,wscr->wtxt,wscr_size); /*first save original screen*/
- r=wscr->row; /*save original row*/
- c=wscr->col; /*save original column*/
- s=wscr->csiz; /*save original cursor size*/
- wact=wscr->wnxt; /*start at first window*/
- while (wact!=NULL) { /*go through each window from start*/
- wn=wact->wnxt; /*get pointer to next window*/
- free(wact); /*return memory to system*/
- wact=wn; /*update pointer to window*/
- } /*while*/
- wvscr(); /*write virtual screen to screen*/
- free(wscr); /*free up the base window memory*/
- free(vscr); /*free memory for virtual screen*/
- setcsiz(s); /*restore original cursor size*/
- setcpos(r,c); /*restore cursor position*/
- wupd=1; /*turn on update*/
- winitd=0; /*not initialized anymore*/
- } /*wpurge*/
-
-
- /****************************************************************************/
- /* wclose */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function closes a window by its window id. */
- /*-----------------------------Arguments------------------------------------*/
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void wclose(WIND *w)
- {
- if (!winitd) if (!winit()) return; /*if not initialized, return*/
- if (w==NULL) return; /*return if bad pointer*/
- (w->wprv)->wnxt=(w->wnxt); /*set previous to point to next*/
- if (w->wnxt) (w->wnxt)->wprv=(w->wprv); /*set next to point to previous*/
- free(w); /*return memory to system*/
- if (wupd) wupdate(NULL); /*update screen*/
- } /*wclose*/
-
-
- /****************************************************************************/
- /* wopen */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function opens a window with the given position and dimensions. */
- /*-----------------------------Arguments------------------------------------*/
- /* WORD bord number of graphic lines in border */
- /* char *p pointer to prompt to appear in border */
- /* WORD sr absolute screen row of upper left corner of window */
- /* WORD sc absolute screen column of up-left corner of window */
- /* WORD rows number of rows in window */
- /* WORD cols number of columns in window */
- /* WORD attr initial character attribute (colors) for window */
- /*-----------------------------Return value---------------------------------*/
- /* wopen() returns a pointer (WIND *) to the window just opened. This */
- /* pointer is then used when calling the other windowing functions. */
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- WIND *wopen(WORD bord,char *p,WORD sr,WORD sc,WORD rows,WORD cols,WORD attr)
- {
- WORD wsiz; /*size of window*/
- WORD ac; /*attribute:character*/
- WORD *tp; /*pointer to window's text*/
-
- if (!winitd) if (!winit()) return NULL; /*make sure initialized*/
- if (bord>2) bord=0; /*border is 0 (no border), 1 or 2*/
- if (!attr) attr=LIGHTGRAY; /*set default attribute*/
- if (sr>=wscr->rows) sr=1; /*check screen row*/
- if (sc>=wscr->cols) sc=1; /*check screen column*/
- if ((sr+rows)>wscr->rows) rows=wscr->rows-sr-1; /*check last row*/
- if ((sc+cols)>wscr->cols) cols=wscr->cols-sc-1; /*check last column*/
- if ((rows==0)||(cols==0)) return NULL; /*couldn't recover*/
- wsiz=(rows*cols)<<1; /*window size in bytes*/
- wact->wnxt=(WIND *)malloc(sizeof(WIND)+wsiz); /*get memory*/
- if (wact->wnxt==NULL) return NULL; /*no room!*/
- (wact->wnxt)->wprv=wact; /*make new window point to old*/
- wact=wact->wnxt; /*make active window point to new*/
- wact->rows=rows; /*rows as provided*/
- wact->cols=cols; /*columns as provided*/
- wact->srow=sr; /*window starts in row 0 on screen*/
- wact->scol=sc; /*window starts in column 0 on screen*/
- wact->row =0; /*normal cursor row*/
- wact->col =0; /*normal cursor column*/
- wact->csiz=DEF_CSIZE; /*cursor size is default size*/
- wact->attr=attr; /*default low intensity white on black*/
- wact->fchr=' '; /*fill character for clearing*/
- wact->prompt=p; /*set prompt pointer*/
- wact->bord=bord; /*border lines as prescribed*/
- wact->battr=attr; /*set border attribute*/
- wact->fl.wrap=1; /*wrap text at end of line*/
- wact->fl.scroll=1; /*scroll window at bottom*/
- wact->fl.moves=0; /*no window moving allowed*/
- wact->fl.sizes=0; /*no window resizing*/
- wact->fl.alive=1; /*show it*/
- wact->fl.saved=0; /*not saved yet*/
- wact->fl.showcr=0; /*don't show little note character*/
- wact->fl.showlf=0; /*ditto for LF one*/
- wact->fl.showbs=0; /*ditto for BS one*/
- wact->wnxt=NULL; /*next window is nonexistent*/
- HI(ac)=wact->attr; /*put attribute for clearing*/
- LO(ac)=wact->fchr; /*use clearing fill character*/
- wsiz>>=1; /*size goes from bytes to words*/
- tp=wact->wtxt; /*point to text of window*/
- for (;wsiz>0;wsiz--) *tp++=ac; /*load clearing character into text*/
- if (wupd) wupdate(wact); /*update the screen*/
- return wact; /*return the window id*/
- } /*wopen*/
-
-
- /****************************************************************************/
- /* wgetcrow, wgetccol, wgetcsiz */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* These functions get the cursor row, column and size, respectively, of */
- /* the specified window. */
- /*-----------------------------Arguments------------------------------------*/
- /* WIND *w window from*/
- /*-----------------------------Return value---------------------------------*/
- /* Returns row, column or size of window. */
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- WORD wgetcrow(WIND *w)
- {
- if ((w==NULL)||!winitd) return 0; /*returns*/
- return (w->row);
- } /*wgetcrow*/
-
- WORD wgetccol(WIND *w)
- {
- if ((w==NULL)||!winitd) return 0; /*returns*/
- return (w->col);
- } /*wgetccol*/
-
- WORD wgetcsiz(WIND *w)
- {
- if ((w==NULL)||!winitd) return 0; /*returns*/
- return (w->csiz);
- } /*wgetccol*/
-
-
- /****************************************************************************/
- /* wsetcpos */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function sets the cursor position within a window. */
- /*-----------------------------Arguments------------------------------------*/
- /* WIND *w window for which cursor position is to be set */
- /* WORD row row to set */
- /* WORD col column to set */
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void wsetcpos(WIND *w,WORD row,WORD col)
- {
- if ((w==NULL)||!winitd) return; /*if not initialized, hit the road*/
- if ((row<w->rows)&&(col<w->cols)) { /*if legal row,column*/
- w->row=row; /*set row*/
- w->col=col; /*set column*/
- if (wupd&&ptrcmp(w,wact)) /*if this is the active window...*/
- setcpos(w->srow+w->row,w->scol+w->col); /*...display cursor*/
- } /*if r,c ok*/
- } /*wsetcpos*/
-
-
- /****************************************************************************/
- /* wsetcsiz */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function sets the cursor size of the specified window. If the */
- /* window is the active one, it sets the size immediately on the screen. */
- /*-----------------------------Arguments------------------------------------*/
- /* WIND *w window for cursor sizing */
- /* WORD siz size (start and stop scan lines) of cursor */
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void wsetcsiz(WIND *w,WORD siz)
- {
- if ((w==NULL)||!winitd) return; /*return if stupid*/
- w->csiz=siz; /*set window cursor size*/
- if (wupd&&w->fl.alive&&ptrcmp(w,wact))
- setcsiz(w->csiz); /*set on screen if active window*/
- } /*wsetcsiz*/
-
-
- /****************************************************************************/
- /* wfcolor, wbcolor, wsetattr, wgetattr */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* These functions set the foreground and background colors of the given */
- /* window, respectively. */
- /*-----------------------------Arguments------------------------------------*/
- /* WIND *w window whose attribute is to change */
- /* WORD color color for foreground/background */
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /* Only the first 8 colors may be used as background colors (BLACK up to */
- /* LIGHTGRAY). Higher colors which are used as background colors will */
- /* result in a blinking attribute (see the BLINK constant in [wutil.h]). */
- /* In monochrome mode, some adaptors turn on underscore for various */
- /* attribute settings. */
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void wfcolor(WIND *w,WORD color)
- {
- if ((w==NULL)||!winitd) return; /*leave*/
- w->attr&=0xF0; /*clear foreground portion*/
- w->attr|=(color&0x0F); /*insert new foreground color*/
- } /*wfcolor*/
-
- void wbcolor(WIND *w,WORD color)
- {
- if ((w==NULL)||!winitd) return; /*leave*/
- w->attr&=0x0F; /*clear out previous background*/
- w->attr|=((color<<4)&0xF0); /*insert new background*/
- } /*wbcolor*/
-
-
- WORD wsetattr(WIND* w,WORD attr)
- {
- WORD a; /*old attribute*/
- if ((w==NULL)||!winitd) return 0; /*leave*/
- a=w->attr; /*save old attribute*/
- w->attr=attr; /*set attribute*/
- return a; /*return old attribute*/
- } /*wsetattr*/
-
-
- WORD wgetattr(WIND *w)
- {
- if ((w==NULL)||!winitd) return 0; /*leave*/
- return w->attr;
- } /*wgetattr*/
-
-
- /****************************************************************************/
- /* wclr, wclrbor, wclreor, wclrbow, wclreow */
- /****************************************************************************/
- void wclr(WIND *w)
- {
- WORD k; /*counter*/
- WORD *tp; /*text pointer*/
- WORD ac; /*attribute:character*/
-
- if ((w==NULL)||!winitd) return; /*leave if bad*/
- k=w->rows*w->cols; /*calculate window size*/
- tp=w->wtxt; /*point to window text*/
- HI(ac)=(BYTE)w->attr; /*set up attribute*/
- LO(ac)=(BYTE)w->fchr; /*set up fill character*/
- for (;(k);k--) *tp++=ac; /*fill window with character*/
- w->row=0; /*reset row*/
- w->col=0; /*and column*/
- if (wupd) wupdate(w); /*update window if necessary*/
- } /*wclr*/
-
- void wclrbor(WIND *w)
- {
- WORD c; /*column counter*/
- WORD *tp; /*text pointer*/
- WORD ac; /*attribute:character*/
-
- if ((w==NULL)||!winitd) return; /*leave if bad*/
- if (w->row>=w->rows) w->row=w->rows-1;
- if (w->col>=w->cols) w->col=w->cols-1;
- tp=w->wtxt; /*point to window text*/
- tp+=w->row*w->cols; /*point to start of row*/
- HI(ac)=(BYTE)w->attr; /*set up attribute*/
- LO(ac)=(BYTE)w->fchr; /*set up fill character*/
- for (c=0;c<=w->col;c++) *tp++=ac; /*fill character to cursor*/
- if (wupd) wupdate(w); /*update window if necessary*/
- } /*wclrbor*/
-
- void wclreor(WIND *w)
- {
- WORD c; /*column counter*/
- WORD *tp; /*text pointer*/
- WORD ac; /*attribute:character*/
-
- if ((w==NULL)||!winitd) return; /*leave if bad*/
- if (w->row>=w->rows) w->row=w->rows-1;
- if (w->col>=w->cols) w->col=w->cols-1;
- tp=w->wtxt; /*point to window text*/
- tp+=w->row*w->cols; /*point to start of row*/
- tp+=w->col; /*point to column of row*/
- HI(ac)=(BYTE)w->attr; /*set up attribute*/
- LO(ac)=(BYTE)w->fchr; /*set up fill character*/
- for (c=w->col;c<w->cols;c++) *tp++=ac; /*fill character from cursor*/
- if (wupd) wupdate(w); /*update window if necessary*/
- } /*wclreor*/
-
- void wclrbow(WIND *w)
- {
- WORD k; /*counter*/
- WORD *tp; /*text pointer*/
- WORD ac; /*attribute:character*/
-
- if ((w==NULL)||!winitd) return; /*leave if bad*/
- if (w->row>=w->rows) w->row=w->rows-1;
- if (w->col>=w->cols) w->col=w->cols-1;
- tp=w->wtxt; /*point to window text*/
- k=w->row*w->cols; /*go up to row*/
- k+=w->col+1; /*go up to column, inclusive*/
- HI(ac)=(BYTE)w->attr; /*set up attribute*/
- LO(ac)=(BYTE)w->fchr; /*set up fill character*/
- for (;(k);k--) *tp++=ac; /*fill character to cursor*/
- if (wupd) wupdate(w); /*update window if necessary*/
- } /*wclrbow*/
-
- void wclreow(WIND *w)
- {
- WORD k; /*counter*/
- WORD *tp; /*text pointer*/
- WORD ac; /*attribute:character*/
-
- if ((w==NULL)||!winitd) return; /*leave if bad*/
- if (w->row>=w->rows) w->row=w->rows-1;
- if (w->col>=w->cols) w->col=w->cols-1;
- tp=w->wtxt; /*point to window text*/
- tp+=w->row*w->cols; /*to row*/
- tp+=w->col; /*to column*/
- k=(w->rows-w->row-1)*w->cols; /*go up to row*/
- k+=(w->cols-w->col); /*go from column, inclusive*/
- HI(ac)=(BYTE)w->attr; /*set up attribute*/
- LO(ac)=(BYTE)w->fchr; /*set up fill character*/
- for (;(k);k--) *tp++=ac; /*fill character from cursor*/
- if (wupd) wupdate(w); /*update window if necessary*/
- } /*wclreow*/
-
-
- /****************************************************************************/
- /* wfront */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function brings the designated window to the front (makes it the */
- /* active window). */
- /*-----------------------------Arguments------------------------------------*/
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void wfront(WIND *w)
- {
- if (!winitd) return; /*leave if no windows yet*/
- if (w==NULL) return; /*leave if bad window*/
- if (!ptrcmp(w,wact)&&!ptrcmp(w,wscr)) { /*do nothing if already active*/
- (w->wprv)->wnxt=w->wnxt; /*make prev's next be my next*/
- (w->wnxt)->wprv=w->wprv; /*make next's prev be my prev*/
- wact->wnxt=w; /*make current active point to me*/
- w->wprv=wact; /*point back at current active*/
- w->wnxt=NULL; /*turn off forward pointer*/
- wact=w; /*i'm active now*/
- } /*if need to rearrange*/
- w->fl.alive=1; /*unhide it*/
- if (wupd) wupdate(w); /*update if already active*/
- } /*wfront*/
-
-
- /****************************************************************************/
- /* wback */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function pushes the specified window to the back (i.e., just in */
- /* front of the base window). */
- /*-----------------------------Arguments------------------------------------*/
- /* WIND *w window to push back */
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void wback(WIND *w)
- {
- if (!winitd) return; /*leave if no windows yet*/
- if (w==NULL) return; /*leave if bad window*/
- if (!ptrcmp(w,wscr)) { /*do nothing if base window*/
- (w->wprv)->wnxt=w->wnxt; /*make prev's next be my next*/
- if (w->wnxt!=NULL) (w->wnxt)->wprv=w->wprv; /*make next's prev be prev*/
- (wscr->wnxt)->wprv=w; /*have window atop base point to me*/
- w->wnxt=wscr->wnxt; /*point to just past base window*/
- w->wprv=wscr; /*point back at base*/
- wscr->wnxt=w; /*have base point to me*/
- } /*if need to rearrange*/
- if (wupd) wupdate(NULL); /*update even if already active*/
- } /*wback*/
-
-
- void whide(WIND *w)
- {
- if (w==NULL) return;
- w->fl.alive=0;
- wback(w);
- } /*whide*/
-
-
- /****************************************************************************/
- /* wdelrow */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function deletes the current row from the given window. It puts */
- /* a blank line at the bottom of the window (with the current attribute). */
- /*-----------------------------Arguments------------------------------------*/
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void wdelrow(WIND *w)
- {
- WORD *tp; /*pointer to window text*/
- WORD r; /*local row counter*/
- WORD ac; /*atrr:char*/
- WORD n; /*number of bytes to copy*/
-
- if (!winitd) return; /*check initialization*/
- if (w==NULL) return; /*check window pointer*/
- w->col=0; /*resets column*/
- if (w->row>=w->rows) { /*make sure row is ok*/
- w->row=w->rows-1; /*reset to last row*/
- } /*if bad row*/
- tp=w->wtxt; /*point to top of text*/
- tp+=w->row*w->cols; /*go to current row*/
- n=w->cols<<1; /*bytes to copy per row*/
- for (r=w->row;r<(w->rows-1);r++) { /*go through each row but last*/
- memcpyi(tp,(tp+w->cols),n); /*copy next row of BYTEs*/
- tp+=w->cols; /*point to next row of WORDs*/
- } /*for*/
- HI(ac)=w->attr; /*load attribute*/
- LO(ac)=w->fchr; /*load fill char to clear*/
- for (r=0;r<w->cols;r++) *tp++=ac; /*clear last line*/
- if (wupd) wupdate(w); /*update window*/
- } /*wdelrow*/
-
-
- /****************************************************************************/
- /* winsrow */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function inserts a row at the current cursor position. It fills */
- /* the row with blanks of the current attribute setting, and deletes the */
- /* bottom row of the window. */
- /*-----------------------------Arguments------------------------------------*/
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void winsrow(WIND *w)
- {
- WORD *tp,*tp2; /*pointer to window text*/
- WORD r; /*local row counter*/
- WORD ac; /*atrr:char*/
- WORD n; /*number of bytes*/
-
- if (!winitd) return; /*check initialization*/
- if (w==NULL) return; /*check window pointer*/
- w->col=0; /*reset column*/
- if (w->row>=w->rows) { /*make sure row is ok*/
- w->row=w->rows-1; /*reset to last row*/
- } /*if bad row*/
- tp=w->wtxt; /*point to top of text*/
- tp+=(w->rows-1)*w->cols; /*go to last row*/
- n=w->cols<<1; /*number of bytes=2*words*/
- for (r=(w->rows-1);r>w->row;r--) { /*go through each row but current*/
- tp2=tp;
- tp2-=w->cols;
- memcpyi(tp,tp2,n); /*copy from prev row of BYTEs*/
- tp=tp2; /*point to previous row of WORDs*/
- } /*for*/
- HI(ac)=w->attr; /*load attribute*/
- LO(ac)=w->fchr; /*load fill char since clearing*/
- for (r=0;r<w->cols;r++) *tp++=ac; /*clear current row*/
- if (wupd) wupdate(w); /*update window*/
- } /*winsrow*/
-
-
- /****************************************************************************/
- /* wputc */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function writes a single character out to the window. */
- /*-----------------------------Arguments------------------------------------*/
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void wputc(WIND *w,int c)
- {
- WORD *tp; /*point to window's text*/
- WORD ac=0; /*attribute:character*/
- BYTE twupd; /*locally store wupd*/
- BYTE show=1;
-
- if ((w==NULL)||!winitd) return; /*return*/
- if (w->row>=w->rows) w->row=w->rows-1; /*check row*/
- if (w->col>=w->cols) w->col=w->cols-1; /*check column*/
- switch (c) { /*check for special chars*/
- case 0x0D: /*on CR...*/
- if (w->fl.showcr) break;
- show=0;
- w->col=0; /*...go to beginning of line*/
- break;
- case 0x0A: /*on LF (newline)...*/
- if (w->fl.showlf) break;
- show=0;
- (w->row)++; /*...go to next row*/
- w->col=0; /*...beginning thereof*/
- break;
- case 0x08: /*if BS...*/
- if (w->fl.showbs) break;
- show=0;
- if (w->col==0) { /*see if first column*/
- if (w->fl.wrap&&(w->row>0)) { /*is wrap enabled?*/
- w->col=w->cols-1; /*...back one row*/
- (w->row)--; /*...at the end*/
- } /*if not first row and wrap enabled*/
- } /*if first column*/
- else
- (w->col)--; /*just decrement column*/
- break;
- default:
- ;
- } /*switch*/
- if (show) { /*see if showing after translation*/
- HI(ac)=w->attr; /*set up current attribute*/
- LO(ac)=(BYTE)c; /*set up passed character*/
- tp=w->wtxt; /*point to text*/
- tp+=(w->row*w->cols); /*go to row in window's text*/
- tp+=w->col; /*go to column in window's text*/
- *tp=ac; /*copy character*/
- (w->col)++; /*ready for next character*/
- } /*if showing character*/
- if (w->col>=w->cols) { /*if wrapped*/
- if (w->fl.wrap) { /*if wrapping enabled...*/
- (w->row)++; /*...go to next row*/
- w->col=0; /*...at beginning*/
- } /*otherwise...*/
- else w->col=w->cols-1; /*...just leave cursor at end*/
- } /*if wrapped around end of row*/
- if (w->row>=w->rows) { /*if scrolled*/
- if (w->fl.scroll) { /*if scrolling enabled...*/
- w->row=0; /*...set to first row for delrow call*/
- twupd=wupd; /*...save wupd setting*/
- wupd=0; /*...don't update when deleting row*/
- wdelrow(w); /*...delete top row of window*/
- wupd=twupd; /*...restore wupd setting*/
- w->row=w->rows-1; /*...set to last row*/
- w->col=0; /*...set to first column in row*/
- } /*otherwise...*/
- else w->row=0; /*...go back to top of window*/
- } /*if scrolled at end of screen*/
- if (wupd) wupdate(w);
- } /*wputc*/
-
-
- /****************************************************************************/
- /* wputs */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function writes a string to a specified window. */
- /*-----------------------------Arguments------------------------------------*/
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void wputs(WIND *w,char *s)
- {
- BYTE twupd;
-
- if (!winitd) if (!winit()) return; /*return if can't initialize*/
- if (w==NULL) return; /*return if can't find window*/
- twupd=wupd; /*save update flag*/
- wupd=0; /*do wputc's before updating screen*/
- while (*s) wputc(w,*s++); /*write out each character*/
- wupd=twupd; /*reset internal flag*/
- if (wupd) wupdate(w); /*update screen*/
- } /*wputs*/
-
-
- /****************************************************************************/
- /* wputns */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function writes n characters to the screen, regardless of the */
- /* presence of a NUL character. */
- /*-----------------------------Arguments------------------------------------*/
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void wputns(WIND *w,char *s,int n)
- {
- BYTE twupd;
-
- if (!winitd) if (!winit()) return; /*return if can't initialize*/
- if (w==NULL) return; /*return if can't find window*/
- twupd=wupd; /*save update flag*/
- wupd=0; /*do wputc's before updating screen*/
- while (n--) wputc(w,*s++); /*write out each character*/
- wupd=twupd; /*reset internal flag*/
- if (wupd) wupdate(w); /*update screen*/
- } /*wputs*/
-
-
- /****************************************************************************/
- /* wputrcs */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function positions the cursor in a window, then writes out the */
- /* specified string */
- /*-----------------------------Arguments------------------------------------*/
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void wputrcs(WIND *w,WORD r,WORD c,char *s)
- {
- BYTE twupd;
-
- if ((w==NULL)||!winit) return; /*leave*/
- if ((r>=w->rows)||(c>=w->cols)) return;
- w->row=r;
- w->col=c;
- twupd=wupd; /*save update flag*/
- wupd=0;
- while (*s) wputc(w,*s++); /*write out string*/
- wupd=twupd; /*restore update flag*/
- if (wupd) wupdate(w); /*update*/
- } /*wputrcs*/
-
-
- /****************************************************************************/
- /* wprintf */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function performs a printf to the given window. */
- /*-----------------------------Arguments------------------------------------*/
- /* WIND *w window for printf */
- /* BYTE *fmt format for printf */
- /*-----------------------------Return value---------------------------------*/
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- void cdecl wprintf(WIND *w,char *fmt,...)
- {
- #define MAX_DATUM 256
- static BYTE bs[MAX_DATUM]; /*256 bytes max for formatted data*/
- va_list va; /*variable argument list*/
-
- va_start(va,fmt); /*point to argument list*/
- if ((w==NULL)||!winitd) return; /*leave if bad*/
- vsprintf(bs,fmt,va); /*write to string*/
- wputs(w,bs); /*write to window*/
- va_end(va); /*close variable list pointers*/
- } /*wprintf*/
-
-
- /****************************************************************************/
- /* wgetc */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function gets a character from the specified window at the */
- /* current cursor position. The given window is first made active. */
- /*-----------------------------Arguments------------------------------------*/
- /* WIND *w window to use to read the character */
- /*-----------------------------Return value---------------------------------*/
- /* wgetc() returns the ASCII code of the key pressed. If a special */
- /* function key is pressed, it returns the scan code plus 0x100 (256). */
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- int wgetc(WIND *w)
- {
- int c; /*character*/
-
- if ((w==NULL)||!winitd) return 0; /*return if not initialized*/
- w->fl.alive=1; /*make sure it's alive*/
- if (!ptrcmp(w,wact)) wfront(w); /*bring window to front if necessary*/
- #if 0
- while (!kbhit()) {
- if (scrollhit()) wmovew(w); /*move window*/
- } /*while key not hit*/
- #endif
- c=(BYTE)getch(); /*get character*/
- if (c) /*if normal character...*/
- return (c); /*...just return it*/
- else /*otherwise...*/
- return (0x100+getch()); /*...add 0x100 to next char*/
- } /*wgetc*/
-
- int wgetce(WIND *w) /*get char and echo*/
- {
- int c;
- c=wgetc(w); /*get char*/
- if ((c>0)&&(c<0x100)) wputc(w,c); /*and echo*/
- return (c);
- }
-
-
- /****************************************************************************/
- /* wgets */
- /****************************************************************************/
- /*-----------------------------Description----------------------------------*/
- /* This function reads a string in from a window. It ends when CR is */
- /* pressed, or when ESC is pressed. The CR is NOT included in the */
- /* return string. */
- /*-----------------------------Arguments------------------------------------*/
- /* WIND *w window */
- /* BYTE *s string to receive characters */
- /* int n maximum number of characters to read */
- /*-----------------------------Return value---------------------------------*/
- /* wgets() returns the number of characters actually received. */
- /*-----------------------------Constraints/Gotchas--------------------------*/
- /*--Date--------Programmer----------Comments--------------------------------*/
- /* 1990.01.01 D. Rogers initial code */
- /****************************************************************************/
- int wgets(WIND *w,char *s,int n)
- {
- WORD k;
- int c;
-
- if (!winitd) return 0; /*leave if not initialized*/
- if (w==NULL) return 0; /*leave if bad pointer*/
- if (n<2) return 0; /*leave if no chars to get*/
- n--; /*leave room for NUL at string's end*/
- k=0; /*initialize counter*/
- c=0; /*keep loop alive*/
- while (c!=0x0D) { /*while not done*/
- c=wgetc(w); /*get a character from the window*/
- switch (c) {
- case 0x0D: /*carriage return*/
- break;
- case 0x1B: /*escape character*/
- k=0; /*reset string to 0*/
- c=0x0D; /*tell loop we're done*/
- break;
- case 0x08:
- if (k) {
- wupd=0; /*turn off the automatic updates*/
- wputc(w,'\x08'); /*write out a backspace*/
- wputc(w,w->fchr); /*write out a fill character*/
- wupd=1; /*turn updating back on*/
- wputc(w,'\x08'); /*write out another backspace*/
- k--; /*go back one in string*/
- }
- break;
- default:
- if ((k<n)&&(c<0x100)) { /*if not special key*/
- s[k++]=(BYTE)c; /*load char and increment position*/
- wputc(w,c); /*put out character*/
- } /*if printable*/
- } /*switch*/
- } /*while*/
- s[k]=0; /*put end marker in string*/
- return (k); /*return number of chars read*/
- } /*wgets*/
-
-
-