home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * Low-level systems routines used by Windows TOOLKIT
- *
- * (C) 1990 Vision Software
- *
- * $Id: lowlevel.c 1.2002 91/05/03 14:30:40 pcalvin beta Locker: pcalvin $
- *
- * Comments:
- *
- * This file consists of the DOS Kludge routines for Binary Screen IO.
- * They are implemented (in general) using Borlands Text Library.
- *
- * Bugs:
- *
- * None documented.
- *
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <conio.h>
- #include <dos.h>
- #include <time.h>
- #include <string.h>
- #include <ctype.h>
- #include <new.h>
-
- #include <stdhdr.h>
- #include <adl.h>
-
- #include "lowlevel.h"
-
- /*
- * Routines to create the "Shadow" for our windows etc..
- */
- STATIC CONST CO coShadow = CoEgaFromCoCo(coDarkGray,coBlack);
- STATIC VOID ShadowRow(ROW row,COL col1,COL col2);
- STATIC VOID ShadowCol(COL col,ROW row1,ROW row2);
-
- /*
- * Clears the screen. If using NNANSI.SYS, this resets
- * the screen location
- */
- STATIC VOID ClearScreen();
-
- /*
- * Fatal memory allocation handler..
- */
- STATIC VOID FatalMemoryError();
-
- /*
- * Run-time dimensions for windows
- */
- ROW rowGlobalWindowBottom;
- COL colGlobalWindowRight;
-
- /*
- * Static array for filling window using gettext/puttext.
- * Large enough to hold entire screen..
- */
- STATIC CCH cchWindowSize;
- STATIC UCHAR *rguchWindow;
-
- /*
- * No shadows in monochrome
- */
- STATIC BOOL fShadows;
-
- /*
- * Generic Environment declarations.
- * Allows automatically setting color
- * mode.
- */
- class ENV
- {
- public:
- ENV(VOID);
- ~ENV(VOID);
- private:
- CURSOR crs;
- };
-
- /*
- * At startup, the cursor is visible. Setting this
- * static member to true ensures the cursor is turned
- * back on after the program is complete..
- */
- BOOL CURSOR::fCurrentState = fTrue;
- STATIC ENV env;
-
- /*
- * System initialization. Turns off the startup cursor, determines
- * the screen lines/max colours etc..
- */
- ENV::ENV() : crs(fFalse)
- {
- text_info y;
-
- /*
- * Initialize random number generator
- */
- randomize();
-
- /*
- * Setup our new-handler..
- */
- set_new_handler(FatalMemoryError);
-
- /*
- * Determine the startup screen conditions.
- */
- ClearScreen();
- gettextinfo(&y);
-
- /*
- * Only activate shadows if there is a colour screen..
- */
- if (y.currmode == C80 || y.currmode == C4350)
- fShadows = fTrue;
- else
- fShadows = fFalse;
-
- /*
- * Finally, initialize the rest of the system
- */
- rowGlobalWindowBottom = y.screenheight;
- colGlobalWindowRight = y.screenwidth;
-
- cchWindowSize = rowGlobalWindowBottom * colGlobalWindowRight * 2;
- rguchWindow = new UCHAR[cchWindowSize];
- FillWindow(1,1,rowGlobalWindowBottom,colGlobalWindowRight,177,coLightBlue,coBlack);
- /*
- * Must be initialized here so it knows how many lines are available
- */
- HELP::Start();
- }
-
- /*
- * Resets the system to the startup condition
- */
- ENV::~ENV()
- {
- CursorColor(coWhite,coBlack);
- window(1,1,colGlobalWindowRight,rowGlobalWindowBottom);
- clrscr();
- }
-
- /*
- * Executes a dos command. May be Nil, in which case
- * we start a new command processor
- */
- EXTERN VOID Command(SZ sz)
- {
- CURSOR crs(fTrue); // Most programs will not do this..
- CHAR error;
-
- gettext(1,1,colGlobalWindowRight,rowGlobalWindowBottom,rguchWindow);
- CursorColor(coWhite,coBlack);
- window(1,1,colGlobalWindowRight,rowGlobalWindowBottom);
- clrscr();
-
- /*
- * Execute command/shell
- */
- if (sz == szNil || sz[0] == chNil)
- system("");
- else
- system(sz);
-
- ClearScreen();
- puttext(1,1,colGlobalWindowRight,rowGlobalWindowBottom,rguchWindow);
- }
-
- /*
- * Creates and executes a does shell
- */
- EXTERN VOID DosShell()
- {
- if (FAskSz("Execute DOS sub-shell?","Press \"Y\" to spawn shell, \"N\" to abort"))
- {
- Command();
- }
- }
-
- EXTERN VOID TerminateApplication()
- {
- if (FAskSz("Terminate Application?","Press \"Y\" to exit, \"N\" to return to application"))
- {
- exit(0);
- }
- }
-
- /*
- * If using NNANSI.SYSs fast scroll option, this resets
- * the screen location
- */
- STATIC VOID ClearScreen()
- {
- printf("\x1b" "[2J");
- }
-
- /*
- * Set Cursor Color
- */
- VOID CursorColor(CO coFore,CO coBack)
- {
- if (fShadows)
- textattr(CoEgaFromCoCo(coFore,coBack));
- else if (coBack == coGreen)
- textattr(coReverse);
- else
- textattr(coNormal);
- }
-
- /*
- * Moves the cursor unconditionally to row,col
- */
- VOID SetGlobalRowCol(ROW row,COL col)
- {
- gotoxy(col,row);
- }
-
- /*
- * Centers a string output at COL
- */
- VOID DisplayCenter(ROW row,COL col,SZ sz,CO coFore,CO coBack)
- {
- Assert(sz != szNil);
- Assert(row > rowNil && row <= rowGlobalWindowBottom);
- Assert(col > colNil && col <= colGlobalWindowRight);
-
- DisplayString(row,col - (strlen(sz) >> 1),sz,coFore,coBack);
- }
-
- /*
- * Displays a window border
- */
- VOID DrawBorder(ROW row1,COL col1,ROW row2,COL col2,BD bd,CO coFore,CO coBack)
- {
- DisplayChar(row1,col1,(bd == bdDouble) ? 201 : 218,coFore,coBack);
- FillRow(row1,col1+1,col2-1,(bd == bdDouble) ? 205 : 196,coFore,coBack);
- DisplayChar(row1,col2,(bd == bdDouble) ? 187 : 191,coFore,coBack);
- FillColumn(row1+1,col1,row2-1,(bd == bdDouble) ? 186 : 179,coFore,coBack);
- FillColumn(row1+1,col2,row2-1,(bd == bdDouble) ? 186 : 179,coFore,coBack);
- DisplayChar(row2,col1,(bd == bdDouble) ? 200 : 192,coFore,coBack);
- FillRow(row2,col1+1,col2-1,(bd == bdDouble) ? 205 : 196,coFore,coBack);
- DisplayChar(row2,col2,(bd == bdDouble) ? 188 : 217,coFore,coBack);
- if (fShadows)
- {
- ShadowRow(row2+1,col1+1,col2+1);
- ShadowCol(row1+1,col2+1,row2+1);
- }
- }
-
- /*
- * Turn on the shadow..
- * First thing to do is make sure the row to effect is entirely visable within
- * the screen.
- */
- VOID ShadowRow(ROW row,COL colLeft,COL colRight)
- {
- if (row > rowGlobalWindowBottom)
- return;
-
- colRight = Min(colRight,colGlobalWindowRight);
- colLeft = Max(colLeft,1);
-
- CCH cchMax = (1+colRight - colLeft) << 1;
- SZTEMP sz;
-
- gettext(colLeft,row,colRight,row,sz);
-
- for (CCH cch = 1;cch < cchMax;cch += 2)
- sz[cch] = coShadow;
-
- puttext(colLeft,row,colRight,row,sz);
- }
-
- /*
- * Shadow for the column
- * Again, the first thing here is to assert the column lies entirely within the
- * boundaries of the screen.
- */
- VOID ShadowCol(ROW rowTop,COL col,ROW rowBottom)
- {
- if (col > colGlobalWindowRight)
- return;
-
- rowBottom = Min(rowBottom,rowGlobalWindowBottom);
- rowTop = Max(rowTop,1);
-
- CCH cchMax = (1+rowBottom - rowTop) << 1;
- SZTEMP sz;
-
- gettext(col,rowTop,col,rowBottom,sz);
-
- for (CCH cch = 1;cch < cchMax;cch += 2)
- sz[cch] = coShadow;
-
- puttext(col,rowTop,col,rowBottom,sz);
- }
-
- /*
- * Display a single character
- */
- VOID DisplayChar(ROW row,COL col,CHAR ch,CO coFore,CO coBack)
- {
- gotoxy(col,row);
- CursorColor(coFore,coBack);
- putch(ch);
- }
-
- /*
- * Draw a null terminated string at row,col
- */
- VOID DisplayString(ROW row,COL col,SZ sz,CO coFore,CO coBack)
- {
- Assert(sz != szNil);
- Assert(row > rowNil && row <= rowGlobalWindowBottom);
- Assert(col > colNil && col <= colGlobalWindowRight);
-
- CursorColor(coFore,coBack);
- gotoxy(col,row);
- while (*sz != chNil)
- putch(*sz++);
- }
-
- /*
- * Null terminated "HotString" the cch'th character is highlighted..
- */
- VOID HotString(ROW row,COL col,CCH cchHotKey,SZ sz,CO coFore,CO coBack)
- {
- Assert(sz != szNil);
- Assert(row > rowNil && row <= rowGlobalWindowBottom);
- Assert(col > colNil && col <= colGlobalWindowRight);
-
- DisplayString(row,col,sz,coFore,coBack);
- DisplayChar(row,col+cchHotKey,sz[cchHotKey],coBlue,coBack);
- }
-
- /*
- * Clears/Fills a window with this colour
- */
- VOID FillWindow(ROW row1,COL col1,ROW row2,COL col2,CHAR ch,CO coFore,CO coBack)
- {
- CCH cchMax = (1+row2-row1) * (1+col2-col1) * 2;
- CO coEga = CoEgaFromCoCo(coFore,coBack);
- CO coMono = (coBack == coGreen) ? coReverse : coNormal;
- CO co = (fShadows) ? coEga : coMono;
-
- gettext(col1,row1,col2,row2,rguchWindow);
-
- for (CCH cch = cchNil; cch < cchMax; cch += 2)
- {
- rguchWindow[cch] = ch;
- rguchWindow[cch+1] = co;
- }
-
- puttext(col1,row1,col2,row2,rguchWindow);
- }
-
- /*
- * Binary Keyboard input. DOS KLUDGE: getch() answers Nil if the key
- * was a control (Ex. F1) the next answer is that key..
- */
- CD CdInput(VOID)
- {
- REGISTER CD cd = getch();
-
- /*
- * Some keys require use to wait for the second answer..
- */
- if (cd == cdNil)
- cd = getch() << 8;
-
- return (cd);
- }
-
- /*
- * Implementation for cursor visibility control. Resets cursor to
- * previous visibilty upon destruction.
- */
- CURSOR::CURSOR(BOOL fShow)
- {
- /*
- * Save the state to be restored after this object goes out of scope
- */
- fFinishState = fCurrentState;
- fCurrentState = fShow;
- Set(fShow);
- }
-
- CURSOR::~CURSOR()
- {
- fCurrentState = fFinishState;
- Set(fFinishState);
- }
-
- VOID CURSOR::Set(BOOL fShow)
- {
- _setcursortype(fShow ? _SOLIDCURSOR : _NOCURSOR);
- }
-
- /*
- * Fatal memory error..
- */
- STATIC VOID FatalMemoryError()
- {
- exit(1);
- }
-