#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#.."End of shell archive."
# Contents:  win.doc win.c win.h scrio.c windemo.c
# Wrapped by fredex@cg-atla on Tue Oct 17 12:58:30 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'win.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'win.doc'\"
else
echo shar: Extracting \"'win.doc'\" \(11554 characters\)
sed "s/^X//" >'win.doc' <<'END_OF_FILE'
X
X
X.. C-WIN - A Public Domain 'C' Windowing System
X.. --------------------------------------------
X
X.... Introduction
X.... ============
X
X   This package was developed as a result of my desire to have a windowing
X   system written in a portable language.  In the three years I've been
X   using the 'C' language I've progressed through six compilers.  Each time
X   I've had to make extensive modifications to assembly language
X   subroutines to adapt them to the new compiler environment.  In addition,
X   I've occasionally used commercial libraries of functions for which I've
X   only had executable code.  These libraries, of course, did not work with
X   the new compiler and I was faced with a choice of purchasing a new
X   version of the library or writing my own functions to replace the
X   library routines I was using.  After encountering this agony several
X   times I've come up with a simple solution.  If I don't have the source
X   code to a function, it does not get linked into any of my programs!
X
X   I'm well aware that there are many commercial windowing packages
X   available and some are even willing to give you the source code.  These
X   packages must be outstanding because they sure cost a lot.
X   Nevertheless, here is my first effort at a 'C' windowing package.
X   Humble as it may be the cost is right on.  It is free and you can have
X   the source code.  I don't want to sell it to you and I don't want you to
X   make a contribution if you like it..It is 100% public domain software,
X   do with it as you please.
X
X...     Compilers Supported
X...     ===================
X
X   This software has been developed using both Borland Turbo C V1.0 and
X   Microsoft C V5.00.  I've also tested the code using Microsoft C V4.00.
X   I've tried to write this code in a portable manner and it should compile
X   with little or no change on most of the newer compilers which are
X   following the ANSI standard.  I have used the Microsoft extension
X   keywords "pascal" and "near" to generate more efficient code but, if
X   your compiler doesn't support them, they can be removed without harming
X   anything.
X
X....    Files
X....    =====
X
The package consists of a single header and two source code files:
X
X      WIN.H.    The header file for use by the application code
X..    as well as the windowing library code.
X
X      WIN.C.    The high level windowing functions. All code in
X..    this file is machine independent.
X
X      SCRIO.C.    The low level screen access routines.  This code
X..    is machine dependent and is written for the IBM/PC
X..    and true compatibles.
X
X      WINDEMO.C     A short demo program which shows some of the
X..    windowing functions in action.
X
X...       Video Equipment
X...       ===============
X
X   This code will work properly on both TTL Monchrome and IBM CGA video
X   boards.  In addition, it should work fine on both EGA and VGA boards.
X   Following are some comments related to these video cards:
X
X     -.Monochrome:    The ScrInitialize function will detect a monochrome
X..       mode and automatically convert all attribute bytes
X..       to black and white.  This is done in a manner that
X..       I find to be reasonable, if you disagree change the
X..       code that does the conversion.
X
X     -.CGA:.       Due to the snow generated by most CGA cards if the
X..       video buffer is accessed during video refresh this
X..       code disables the video signal while directly
X..       updating the video buffer.
X
X     -.EGA:.       Currently EGA color modes are treated as CGA.  Most
X..       schemes I've seen to detect an EGA search the EGA
X..       extended BIOS for the IBM copyright notice.  This,
X..       to me, is not a good approach.  I have seen one
X..       method which used an INT 10h function added by the
X..       EGA which caused no harm if an EGA was not
X..       installed.  At the time I read about it I was not
X..       really interested in EGA and now that I am I can't
X..       find the article.  I also don't have access to EGA
X..       documentation so I can't even figure out which
X..       routine was being used..If you know how to detect
X..       EGA add the code to ScrInitialize.  Most EGA's
X..       will work as CGA with the video signal being
X..       disabled but this is not required with the EGA.
X
X     -.VGA:.       Currently VGA color modes are treated as CGA.  I've
X..       never seen a VGA or any docs on it.  If you've got
X..       one, I hope this code works.  If it doesn't,
X..       I'm sorry, but I can't help.
X
X
X...     Room for Improvement
X...     ====================
X
X   The functions included in this package provide the basics for developing
X   an application using a windowed environment.  There is certainly room
X   for improvement and I encourage you to enhance the functionality of
X   this package.  Some suggestions:
X
X    -  Enhance the Move and Hide window functions to support windows which
X       are not fully visible (i.e. partially overlayed).
X
X    -  Use these functions to develop a higher level of support for things
X       like 123 style menus, pull down menus, data entry forms, etc.
X
X    -  Speed up the TextOut functions..These functions rely on the ROM
X       BIOS character out routines as a result of my desire to stay 100%
X       with 'C' code.  I was tempted many times to rip out ScrTextOut and
X       replace it with assembly code which directly accessed the hardware.
X       I've resisted only because the BIOS code is tolerable in most
X       situations and this code is much more portable than assembly code.
X       With higher speed machines becoming more commonplace this problem
X       may diminish.
X
X   I intend to work on some of these enhancements as time permits and I'm
X   sure you can think of many more.  I would be very pleased if people
X   making fixes and enhancements to this code would communicate their work
X   to me.  If we all work together we may be able to come up with a public
X   domain package which rivals those expensive commercial versions.
X
X....  Disclaimer
X....  ==========
X
X   Many people in the software industry are quite happy to sell you
X   software while assuming no responsibility for its functionality or
X   usefulness..I am happy to give you this software but I also cannot
X   accept any responsibility for it.  I've tested this code and to the best
X   of my knowledge it works and contains no errors.  I simply state that I
X   think it is both functional and useful, I do not guarantee it.  You need
X   to test the code to determine if it will be useful to you.  If you
X   encounter problems with it, fix them.  That's why you wanted the source
X   in the first place, right?
X
X.... Bob Withers
X...      649 Meadowbrook St
X...      Allen, Texas 75002
X
X... Functions Available in WIN.C
X... ============================
X
WinExplodeWindow       Draws an exploding window on the screen. The
X..       screen area behind the window is not saved, the
X..       window is simply drawn.
X
WinDrawWindow.       Draws a window on the screen without saving the
X..       screen area behind the window.
X
WinCreateWindow        Creates a screen window and displays it at the
X..       requested location.  The are behind the window
X..       is saved and will be restored when the window
X..       is destroyed.
X
WinDestroyWindow       Destroys a previously created window.  The
X..       saved screen area is restored and all resources
X..       allocated to support the window are freed.
X
WinScrollWindowUp      Scrolls a window up one line.
X
WinScrollWindowDown    Scrolls a window down one line.
X
WinSetCursorPos        Positions the cursor either relative to an
X..       open window or to absolute screen locations.
X
WinClearScreen.       Clears a window (or the entire screen) to the
X..       requested color attribute.
X
WinTextOut.       Displays a string within the requested window
X..       at the current cursor location (for the
X..       selected window).  If the string would extend
X..       beyond the window it is truncated.
X
WinCenterText.       Centers a text string within a window on the
X..       requested row.
X
WinMoveWindow.       Moves an existing window to a new location on
X..       the screen.  There are a couple of caveats in
X..       this version of the package:
X... 1)  The window must be fully visible (i.e. no
X...     other window overlaying any part of it)
X...     for this routine to work properly.
X... 2)  It is the callers responsibility to
X...     insure that the moved window will still
X...     fit on the screen at the new location.
X... 3)  The size of the window may not be changed,
X...     it can only be moved to a new location.
X
WinGetWindowRow        Returns the absolute row (1 relative) of the
X..       selected window.
X
WinGetWindowCol        Returns the absolute column (1 relative) of
X..       the selected window.
X
WinGetWindowWidth      Returns the number of columns available for
X..       text within the selected window. If the
X..       window was created with a border, this value
X..       will be two less than the width specified in
X..       the create call.
X
WinGetWindowHeight     Returns the number of rows available for text
X..       within the selected window.  If the window was
X..       created with a border, this value will be two
X..       less than the height specified in the create
X..       call.
X
WinGetWindowClr        Returns the background color of a window.
X
WinGetWindowBdrClr     Returns the border color of a window.
X
WinGetBorderType       Returns the border type of a window.
X
WinHideWindow.       Removes a window from the screen.  The window
X..       still exists and is saved in it's current state.
X..       All the caveats listed under WinMoveWindow
X..       apply to the function.
X
WinShowWindow.       Shows a window which is hidden and frees the
X..       buffer used to hold the current state of the
X..       window.
X
WinInitialize.       Initializes the window package..This function
X..       must be called once before any of the other
X..       functions in this package are used.  It should
X..       NEVER be called while windows are open or the
X..       buffers allocated to support them will be
X..       stranded and their handles will no longer be
X..       valid.
X
WinTerminate.       Assures that all open windows are closed.
X
X
X...Functions Available in SCRIO.C
X...==============================
X
ScrGetRectSize.      Calculates the number of bytes required to
X..      store a screen image.
X
ScreenClearRect       Clears a rectangle on the screen to the passed
X..      color value.
X
ScrSaveRect.      Save a screen rectangle in a buffer provided
X..      by the caller.
X
ScrRestoreRect.      Restores a saved screen image from a buffer
X..      passed by the caller.
X
ScrSetCursorPos       Positions the cursor to an absolute screen
X..      location (1 relative).
X
ScrGetCursorPos       Gets the absolute screen location of the cursor.
X
ScrCursorOn.      Enables the screen cursor.
X
ScrCursorOff.      Disables the screen cursor.
X
ScrTextOut.      Displays a text string to the video screen.
X
ScrDrawRect.      Draws the selected border around a screen
X..      retangle.
X
ScrInitialize.      Determines the video equipment installed on the
X..      machine. This routine is called by WinInitialize
X..      and does not need to invoked by the user code.
X
END_OF_FILE
if test 11554 -ne `wc -c <'win.doc'`; then
    echo shar: \"'win.doc'\" unpacked with wrong size!
fi
chmod +x 'win.doc'
# end of 'win.doc'
fi
if test -f 'win.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'win.c'\"
else
echo shar: Extracting \"'win.c'\" \(25998 characters\)
sed "s/^X//" >'win.c' <<'END_OF_FILE'
X
X/***************************************************************************/
X/* WIN.    - Routines which provide windowing functionality..   */
X/*.........   */
X/*.........   */
X/*.........   */
X/***************************************************************************/
X/*...     Modification Log....   */
X/***************************************************************************/
X/* Version   Date   Programmer. -----------  Description  --------------- */
X/*.........   */
X/* V01.00   112787  Bob Withers  Program intially complete...   */
X/*.........   */
X/*.........   */
X/***************************************************************************/
X
X#include <stdlib.h>
X#include <stddef.h>
X#include <string.h>
X#include "win.h"
X
X#define MAX_WINDOWS..   20
X
X
struct sWinData
X{
X    BYTE..cRow;
X    BYTE..cCol;
X    BYTE..cWidth;
X    BYTE..cHeight;
X    BYTE..cWinWidth;
X    BYTE..cWinHeight;
X    BYTE..cWinClr;
X    BYTE..cBdrType;
X    BYTE..cBdrClr;
X    BYTE..cCurRow;
X    BYTE..cCurCol;
X    char.       *pHidden;
X    char..cSaveData[1];
X};
typedef struct sWinData WINDATA;
typedef struct sWinData *PWINDATA;
X
static PWINDATA .WinHandle[MAX_WINDOWS + 1];
X
X
X/***************************************************************************/
X/*  WinCvtHandle    - Convert a window handle into a pointer to the.   */
X/*..      window information data structure...   */
X/*  Parms:........   */
X/*    hWnd.    - handle to the window....   */
X/*.........   */
X/*  Return Value:     pointer to WINDATA or NULL if invalid handle.   */
X/***************************************************************************/
X
static PWINDATA near pascal WinCvtHandle(hWnd)
HWND.   hWnd;
X{
X    if (hWnd < 0 || hWnd > MAX_WINDOWS)
X.return(NULL);
X    return(WinHandle[hWnd]);
X}
X
X
X/***************************************************************************/
X/*  WinGetHandle    - Return an unused window handle....   */
X/*.........   */
X/*  Parms:.      None......   */
X/*.........   */
X/*  Return Value:     Window handle or NULL if none available..   */
X/***************************************************************************/
X
static HWND near pascal WinGetHandle()
X{
X    register int. i;
X
X    for (i = 1; i <= MAX_WINDOWS; ++i)
X    {
X.if (NULL == WinHandle[i])
X.    return(i);
X    }
X    return(NULL);
X}
X
X
X/***************************************************************************/
X/*  WinExplodeWindow - Draws an exploded window on the screen...   */
X/*.........   */
X/*  Parms:........   */
X/*    nRow.    - Top row of requested window (1 relative)..   */
X/*    nCol.    - Left column of requested window (1 relative).   */
X/*    nWidth.    - Width (in columns) of requested window..   */
X/*    nHeight.    - Height (in rows) of requested window..   */
X/*    nWinClr.    - Color of the window background...   */
X/*    nBdrType.    - Type of border for this window (defined in WIN.H)    */
X/*...  NO_BOX.....   */
X/*...  DBL_LINE_TOP_BOTTOM....   */
X/*...  DBL_LINE_SIDES....   */
X/*...  DBL_LINE_ALL_SIDES....   */
X/*...  SNGL_LINE_ALL_SIDES....   */
X/*...  GRAPHIC_BOX.....   */
X/*...  NO_WIND_BORDER....   */
X/*    nBdrClr.    - Color or the window border...   */
X/*.........   */
X/*  Return Value:     None......   */
X/***************************************************************************/
X
void near pascal WinExplodeWindow(nRow, nCol, nWidth, nHeight,
X....  nWinClr, nBdrType, nBdrClr)
short.   nRow, nCol, nWidth, nHeight;
short.   nWinClr, nBdrType, nBdrClr;
X{
X    register short     nLRR, nLRC, nX1, nY1, nX2, nY2;
X
X    nLRR  = nRow + nHeight - 1;
X    nLRC  = nCol + nWidth - 1;
X    nX1   = (nRow + (nHeight >> 1)) - 1;
X    nY1   = (nCol + (nWidth >> 1)) - 3;
X    nX2   = nX1 + 2;
X    nY2   = nY1 + 5;
X    while (TRUE)
X    {
X.ScrClearRect(nX1, nY1, nY2 - nY1 + 1, nX2 - nX1 + 1, nWinClr);
X.ScrDrawRect(nX1, nY1, nY2 - nY1 + 1, nX2 - nX1 + 1,
X..    nBdrClr, nBdrType);
X.if (nX1 == nRow && nY1 == nCol && nX2 == nLRR && nY2 == nLRC)
X.    break;
X.nX1 = (nX1 - 1 < nRow) ? nRow : nX1 - 1;
X.nY1 = (nY1 - 3 < nCol) ? nCol : nY1 - 3;
X.nX2 = (nX2 + 1 > nLRR) ? nLRR : nX2 + 1;
X.nY2 = (nY2 + 3 > nLRC) ? nLRC : nY2 + 3;
X    }
X    return;
X}
X
X
X
X/***************************************************************************/
X/*  WinDrawWindow    - Draws a window on the screen without creating the   */
X/*..       WINDATA structure or saving the previous screen.   */
X/*..       contents......   */
X/*.........   */
X/*  Parms:........   */
X/*    nRow.    - Top row of requested window (1 relative)..   */
X/*    nCol.    - Left column of requested window (1 relative).   */
X/*    nWidth.    - Width (in columns) of requested window..   */
X/*    nHeight.    - Height (in rows) of requested window..   */
X/*    nWinClr.    - Color of the window background...   */
X/*    nBdrType.    - Type of border for this window (defined in WIN.H)    */
X/*...  NO_BOX.....   */
X/*...  DBL_LINE_TOP_BOTTOM....   */
X/*...  DBL_LINE_SIDES....   */
X/*...  DBL_LINE_ALL_SIDES....   */
X/*...  SNGL_LINE_ALL_SIDES....   */
X/*...  GRAPHIC_BOX.....   */
X/*...  NO_WIND_BORDER....   */
X/*    nBdrClr.    - Color or the window border...   */
X/*    bExplodeWin   - Boolean value requesting either a pop-up or.   */
X/*..      exploding window.....   */
X/*...  TRUE. ==> Exploding window...   */
X/*...  FALSE  ==> Pop-up window...   */
X/*.........   */
X/*  Return Value:     None......   */
X/***************************************************************************/
X
void pascal WinDrawWindow(nRow, nCol, nWidth, nHeight,
X...  nWinClr, nBdrType, nBdrClr, bExplodeWin)
short.   nRow, nCol, nWidth, nHeight;
short.   nWinClr, nBdrType, nBdrClr;
short.   bExplodeWin;
X{
X    if (bExplodeWin)
X.WinExplodeWindow(nRow, nCol, nWidth, nHeight,
X... nWinClr, nBdrType, nBdrClr);
X    else
X    {
X.ScrClearRect(nRow, nCol, nWidth, nHeight, nWinClr);
X.ScrDrawRect(nRow, nCol, nWidth, nHeight, nBdrClr, nBdrType);
X    }
X    return;
X}
X
X
X/***************************************************************************/
X/*  WinCreateWindow - Create a window with the requested attributes and    */
X/*..      return a handle which may be used to identify this   */
X/*..      particular window in future calls...   */
X/*  Parms:........   */
X/*    nRow.    - Top row of requested window (1 relative)..   */
X/*    nCol.    - Left column of requested window (1 relative).   */
X/*    nWidth.    - Width (in columns) of requested window..   */
X/*    nHeight.    - Height (in rows) of requested window..   */
X/*    nWinClr.    - Color of the window background...   */
X/*    nBdrType.    - Type of border for this window (defined in WIN.H)    */
X/*...  NO_BOX.....   */
X/*...  DBL_LINE_TOP_BOTTOM....   */
X/*...  DBL_LINE_SIDES....   */
X/*...  DBL_LINE_ALL_SIDES....   */
X/*...  SNGL_LINE_ALL_SIDES....   */
X/*...  GRAPHIC_BOX.....   */
X/*...  NO_WIND_BORDER....   */
X/*    nBdrClr.    - Color or the window border...   */
X/*    bExplodeWin   - Boolean value requesting either a pop-up or.   */
X/*..      exploding window.....   */
X/*...  TRUE. ==> Exploding window...   */
X/*...  FALSE  ==> Pop-up window...   */
X/*.........   */
X/*  Return Value:.......   */
X/*    hWnd.    - Handle of the created window or NULL if an error.   */
X/*..      prevented the creation....   */
X/***************************************************************************/
X
HWND pascal WinCreateWindow(nRow, nCol, nWidth, nHeight,
X...    nWinClr, nBdrType, nBdrClr, bExplodeWin)
short.   nRow, nCol, nWidth, nHeight;
short.   nWinClr, nBdrType, nBdrClr;
short.   bExplodeWin;
X{
X    register PWINDATA.     pWinData;
X    auto     HWND.     hWnd;
X
X    hWnd = WinGetHandle();
X    if (NULL == hWnd)
X.return(hWnd);
X    pWinData = (PWINDATA) malloc(sizeof(WINDATA)
X...       + ScrGetRectSize(nWidth, nHeight));
X    if ((PWINDATA) NULL != pWinData)
X    {
X.WinHandle[hWnd]    = pWinData;
X.pWinData->cRow.   = (BYTE) nRow;
X.pWinData->cCol.   = (BYTE) nCol;
X.pWinData->cWidth   = pWinData->cWinWidth  = (BYTE) nWidth;
X.pWinData->cHeight  = pWinData->cWinHeight = (BYTE) nHeight;
X.pWinData->cWinClr  = (BYTE) nWinClr;
X.pWinData->cBdrType = (BYTE) nBdrType;
X.pWinData->cBdrClr  = (BYTE) nBdrClr;
X.pWinData->cCurRow  = pWinData->cCurCol = (BYTE) 1;
X.pWinData->pHidden  = NULL;
X.if (NO_WIND_BORDER != nBdrType)
X.{
X.    pWinData->cWinWidth  -= 2;
X.    pWinData->cWinHeight -= 2;
X.}
X.ScrSaveRect(nRow, nCol, nWidth, nHeight, pWinData->cSaveData);
X.if (bExplodeWin)
X.    WinExplodeWindow(nRow, nCol, nWidth, nHeight,
X...     nWinClr, nBdrType, nBdrClr);
X.else
X.{
X.    ScrClearRect(nRow, nCol, nWidth, nHeight, nWinClr);
X.    ScrDrawRect(nRow, nCol, nWidth, nHeight, nBdrClr, nBdrType);
X.}
X.WinSetCursorPos((HWND) pWinData, 1, 1);
X    }
X    return(hWnd);
X}
X
X
X/***************************************************************************/
X/*  WinDestoryWindow - Destroy the window represented by hWnd and replace  */
X/*..       the previous screen contents saved when the window  */
X/*..       was created......   */
X/*  Parms:........   */
X/*    hWnd.    - Handle to the window to be destroyed..   */
X/*.........   */
X/*  Return Value:     TRUE => window destroyed, FALSE => invalid handle    */
X/***************************************************************************/
X
BOOL pascal WinDestroyWindow(hWnd)
HWND.   hWnd;
X{
X    register PWINDATA.    pWinData;
X
X    pWinData = WinCvtHandle(hWnd);
X    if (NULL == pWinData)
X.return(FALSE);
X    ScrRestoreRect(pWinData->cRow, pWinData->cCol, pWinData->cWidth,
X..   pWinData->cHeight, pWinData->cSaveData);
X    if (NULL != pWinData->pHidden)
X.free(pWinData->pHidden);
X    free((char *) pWinData);
X    WinHandle[hWnd] = NULL;
X    return(TRUE);
X}
X
X
X/***************************************************************************/
X/*  WinScrollWindowUp  - Scrolls the requested window up one line..   */
X/*.........   */
X/*  Parms:........   */
X/*    hWnd.    - Handle to the window to be scrolled..   */
X/*.........   */
X/*  Return Value:     None......   */
X/***************************************************************************/
X
void pascal WinScrollWindowUp(hWnd)
HWND.     hWnd;
X{
X    register PWINDATA.    pWinData;
X    auto     short.    nRow, nCol;
X
X    pWinData = WinCvtHandle(hWnd);
X    if (NULL == pWinData)
X.return;
X    if (NULL == pWinData->pHidden)
X    {
X.nRow = pWinData->cRow;
X.nCol = pWinData->cCol;
X.if (NO_WIND_BORDER != pWinData->cBdrType)
X.{
X.    nRow++;
X.    nCol++;
X.}
X.ScrScrollRectUp(nRow, nCol, pWinData->cWinWidth,
X...pWinData->cWinHeight, 1, pWinData->cWinClr);
X    }
X    return;
X}
X
X
X/***************************************************************************/
X/*  WinScrollWindowDown - Scrolls the requested window down one line..   */
X/*.........   */
X/*  Parms:........   */
X/*    hWnd.    - Handle to the window to be scrolled..   */
X/*.........   */
X/*  Return Value:     None......   */
X/***************************************************************************/
X
void pascal WinScrollWindowDown(hWnd)
HWND.     hWnd;
X{
X    register PWINDATA.    pWinData;
X    auto     short.    nRow, nCol;
X
X    pWinData = WinCvtHandle(hWnd);
X    if (NULL == pWinData)
X.return;
X    if (NULL == pWinData->pHidden)
X    {
X.nRow = pWinData->cRow;
X.nCol = pWinData->cCol;
X.if (NO_WIND_BORDER != pWinData->cBdrType)
X.{
X.    nRow++;
X.    nCol++;
X.}
X.ScrScrollRectDown(nRow, nCol, pWinData->cWinWidth,
X...  pWinData->cWinHeight, 1, pWinData->cWinClr);
X    }
X    return;
X}
X
X
X/***************************************************************************/
X/*  WinSetCursorPos - Position the cursor relative to the selected window. */
X/*..      The upper left hand corner of the window is (1,1)    */
X/*.........   */
X/*  Parms:........   */
X/*    hWnd.    - Handle to the window to position the cusor in.   */
X/*    nRow.    - Row to position cursor to within window (1 relative) */
X/*    nCol.    - Col to position cursor to within window (1 relative) */
X/*.........   */
X/*  Return Value:     None......   */
X/***************************************************************************/
X
void pascal WinSetCursorPos(hWnd, nRow, nCol)
HWND..hWnd;
short..nRow, nCol;
X{
X    register PWINDATA.    pWinData;
X    auto     short.    nMaxRow, nMaxCol;
X
X    if (NULL == hWnd)
X    {
X.ScrSetCursorPos(nRow, nCol);
X.return;
X    }
X    pWinData = WinCvtHandle(hWnd);
X    if (NULL == pWinData)
X.return;
X    if (nRow > pWinData->cWinHeight && nCol > pWinData->cWinWidth)
X.return;
X    pWinData->cCurRow = (BYTE) nRow;
X    pWinData->cCurCol = (BYTE) nCol;
X    nRow = nRow + pWinData->cRow - 1;
X    nCol = nCol + pWinData->cCol - 1;
X    if (NO_WIND_BORDER != pWinData->cBdrType)
X    {
X.++nRow;
X.++nCol;
X    }
X    ScrSetCursorPos(nRow, nCol);
X    return;
X}
X
X
X/***************************************************************************/
X/*  WinClearScreen - Clear a window to the desired color...   */
X/*.........   */
X/*  Parms:........   */
X/*    hWnd.   - Handle to the window to be cleared ..   */
X/*..     (A handle of NULL clears the entire screen).   */
X/*    nColor.   - Color to be used in clearing the window..   */
X/*.........   */
X/*  Return Value:    None......   */
X/***************************************************************************/
X
void pascal WinClearScreen(hWnd, nColor)
HWND.    hWnd;
short.    nColor;
X{
X    register PWINDATA.    pWinData;
X    auto     short.    nRow, nCol;
X
X    if (NULL == hWnd)
X.ScrClearRect(1, 1, 80, 25, nColor);
X    else
X    {
X.pWinData = WinCvtHandle(hWnd);
X.if (NULL == pWinData)
X.    return;
X.nRow. = pWinData->cRow;
X.nCol. = pWinData->cCol;
X.if (NO_WIND_BORDER != pWinData->cBdrType)
X.{
X.    ++nRow;
X.    ++nCol;
X.}
X.pWinData->cWinClr = (BYTE) nColor;
X.ScrClearRect(nRow, nCol, pWinData->cWinWidth, pWinData->cWinHeight,
X..     pWinData->cWinClr);
X    }
X    return;
X}
X
X
X/***************************************************************************/
X/*  WinTextOut.   - Display a string to the requested window at the.   */
X/*..     current cursor location (for that window) using the   */
X/*..     passed color attribute.....   */
X/*..     If the string extends beyond the boundries of the.   */
X/*..     window it will be truncated....   */
X/*  Parms:........   */
X/*    hWnd.   - Handle of the window....   */
X/*    pStr.   - Pointer to the NULL terminated string to display.   */
X/*    nAttr.   - Color attribute to be used in displaying the string   */
X/*.........   */
X/*  Return Value:    None......   */
X/***************************************************************************/
X
void pascal WinTextOut(hWnd, pStr, nAttr)
HWND.    hWnd;
char.   *pStr;
short.    nAttr;
X{
X    register PWINDATA.pWinData;
X    auto     short.nCount;
X    auto     short.nRow, nCol;
X
X    pWinData = WinCvtHandle(hWnd);
X    if (NULL == pWinData)
X.return;
X    ScrGetCursorPos(&nRow, &nCol);
X    WinSetCursorPos(hWnd, pWinData->cCurRow, pWinData->cCurCol);
X    nCount = pWinData->cWinWidth - pWinData->cCurCol + 1;
X    ScrTextOut(pStr, nAttr, nCount);
X    ScrSetCursorPos(nRow, nCol);
X    return;
X}
X
X
X/***************************************************************************/
X/*  WinCenterText  - Centers a text string in a window. ..   */
X/*.........   */
X/*  Parms:........   */
X/*    hWnd.   - Handle of the window....   */
X/*    nRow.   - Window row to place the string on...   */
X/*    pStr.   - Pointer to the string to be displayed..   */
X/*    nColor.   - Color attribute used to display the string .   */
X/*.........   */
X/*  Return Value:    None......   */
X/***************************************************************************/
void pascal WinCenterText(hWnd, nRow, pStr, nColor)
HWND.    hWnd;
short.    nRow;
char.   *pStr;
short.    nColor;
X{
X    if (NULL == WinCvtHandle(hWnd))
X.return;
X    WinSetCursorPos(hWnd, nRow, (WinGetWindowWidth(hWnd) - strlen(pStr)) / 2);
X    WinTextOut(hWnd, pStr, nColor);
X    return;
X}
X
X
X/***************************************************************************/
X/*  WinMoveWindow  - Move an existing window to a new screen location..   */
X/*..     In this version the window to be moved MUST be fully  */
X/*..     visible on the screen for WinMoveWindow to perform    */
X/*..     properly..If the window being moved is completely or */
X/*..     partially under another window the screen will not    */
X/*..     be left in the correct state (i.e. garbage on screen).*/
X/*..     It is the callers responsibility to insure that the   */
X/*..     window is not being moved off the screen..Even with  */
X/*..     these restriction this can be a handy routine and is  */
X/*..     included for that reason..A future release of the    */
X/*..     package may fix these shortcomings...   */
X/*.........   */
X/*  Parms:........   */
X/*    hWnd.   - Handle to the window to be moved...   */
X/*    nRow.   - Move the window to this row...   */
X/*    nCol.   - Move the window to this column...   */
X/*.........   */
X/*  Return Value:    None......   */
X/***************************************************************************/
X
void pascal WinMoveWindow(hWnd, nRow, nCol)
HWND.    hWnd;
short.    nRow, nCol;
X{
X    register PWINDATA.    pWinData;
X    register char.   *pBuf;
X
X    pWinData = WinCvtHandle(hWnd);
X    if (NULL == pWinData)
X.return;
X    if (NULL != pWinData->pHidden)
X    {
X.pWinData->cRow = (BYTE) nRow;
X.pWinData->cCol = (BYTE) nCol;
X.return;
X    }
X    pBuf     = malloc(ScrGetRectSize(pWinData->cWidth, pWinData->cHeight));
X    if (NULL != pBuf)
X    {
X.ScrSaveRect(pWinData->cRow, pWinData->cCol,
X..    pWinData->cWidth, pWinData->cHeight, pBuf);
X.ScrRestoreRect(pWinData->cRow, pWinData->cCol,
X..       pWinData->cWidth, pWinData->cHeight,
X..       pWinData->cSaveData);
X.ScrSaveRect(nRow, nCol, pWinData->cWidth, pWinData->cHeight,
X..    pWinData->cSaveData);
X.ScrRestoreRect(nRow, nCol, pWinData->cWidth, pWinData->cHeight, pBuf);
X.pWinData->cRow = (BYTE) nRow;
X.pWinData->cCol = (BYTE) nCol;
X.free(pBuf);
X    }
X    return;
X}
X
X
X/***************************************************************************/
X/*  WinGetWindowRow - Returns the row value currently associated with the  */
X/*..      passed window handle.....   */
X/*  Parms:........   */
X/*    hWnd.   - Handle to the window....   */
X/*.........   */
X/*  Return Value:    Row the window currently resides at..   */
X/***************************************************************************/
X
short pascal WinGetWindowRow(hWnd)
HWND.    hWnd;
X{
X    register PWINDATA.   pWinData;
X
X    pWinData = WinCvtHandle(hWnd);
X    if (NULL == pWinData)
X.return(0);
X    return(pWinData->cRow);
X}
X
X
X/***************************************************************************/
X/*  WinGetWindowCol - Returns the col value currently associated with the  */
X/*..      passed window handle.....   */
X/*  Parms:........   */
X/*    hWnd.   - Handle to the window....   */
X/*.........   */
X/*  Return Value:    Column the window currently resides at..   */
X/***************************************************************************/
X
short pascal WinGetWindowCol(hWnd)
HWND.    hWnd;
X{
X    register PWINDATA.    pWinData;
X
X    pWinData = WinCvtHandle(hWnd);
X    if (NULL == pWinData)
X.return(0);
X    return(pWinData->cCol);
X}
X
X
X/***************************************************************************/
X/*  WinGetWindowWidth - Returns the column width of the passed window..   */
X/*.........   */
X/*  Parms:........   */
X/*    hWnd.   - Handle to the window....   */
X/*.........   */
X/*  Return Value:    Number of columns in the window...   */
X/***************************************************************************/
X
short pascal WinGetWindowWidth(hWnd)
HWND.    hWnd;
X{
X    register PWINDATA.   pWinData;
X
X    pWinData = WinCvtHandle(hWnd);
X    if (NULL == pWinData)
X.return(0);
X    return(pWinData->cWinWidth);
X}
X
X
X/***************************************************************************/
X/*  WinGetWindowHeight - Returns the number of rows in the passed window.  */
X/*.........   */
X/*  Parms:........   */
X/*    hWnd.   - Handle to the window....   */
X/*.........   */
X/*  Return Value:    Number of rows in the window...   */
X/***************************************************************************/
X
short pascal WinGetWindowHeight(hWnd)
HWND.    hWnd;
X{
X    register PWINDATA.    pWinData;
X
X    pWinData = WinCvtHandle(hWnd);
X    if (NULL == pWinData)
X.return(0);
X    return(pWinData->cWinHeight);
X}
X
X
X/***************************************************************************/
X/*  WinGetWindowClr - Get the window background color...   */
X/*.........   */
X/*  Parms:........   */
X/*    hWnd.   - Handle to the window....   */
X/*.........   */
X/*  Return Value:    Returns the attribute for the window color .   */
X/***************************************************************************/
X
short pascal WinGetWindowClr(hWnd)
HWND.    hWnd;
X{
X    register PWINDATA.    pWinData;
X
X    pWinData = WinCvtHandle(hWnd);
X    if (NULL == pWinData)
X.return(0);
X    return(pWinData->cWinClr);
X}
X
X
X/***************************************************************************/
X/*  WinGetWindowBdrClr - Get the window border color...   */
X/*.........   */
X/*  Parms:........   */
X/*    hWnd.   - Handle to the window....   */
X/*.........   */
X/*  Return Value:    Returns the attribute for the window border color.   */
X/***************************************************************************/
X
short pascal WinGetWindowBdrClr(hWnd)
HWND.    hWnd;
X{
X    register PWINDATA.    pWinData;
X
X    pWinData = WinCvtHandle(hWnd);
X    if (NULL == pWinData)
X.return(0);
X    return(pWinData->cBdrClr);
X}
X
X
X/***************************************************************************/
X/*  WinGetBorderType - Gets the border type of the passed window.   */
X/*.........   */
X/*  Parms:........   */
X/*    hWnd.   - Handle to the window....   */
X/*.........   */
X/*  Return Value:    Returns the window border type...   */
X/***************************************************************************/
X
short pascal WinGetBorderType(hWnd)
HWND.    hWnd;
X{
X    register PWINDATA.    pWinData;
X
X    pWinData = WinCvtHandle(hWnd);
X    if (NULL == pWinData)
X.return(0);
X    return(pWinData->cBdrType);
X}
X
X
X/***************************************************************************/
X/*  WinHideWindow  - Removes a window from the screen, saving it's         */
X/*..     contents..The window can later be placed back on.   */
X/*..     the screen via WinShowWindow().  Note that in this    */
X/*..     release the window MUST be fully visible for this.   */
X/*..     operating to work correctly....   */
X/*  Parms:........   */
X/*    hWnd.   - Handle to the window....   */
X/*.........   */
X/*  Return Value:    TRUE => window hidden, FALSE => buf alloc failed.   */
X/***************************************************************************/
X
BOOL pascal WinHideWindow(hWnd)
HWND.    hWnd;
X{
X    register PWINDATA.   pWinData;
X    auto     char.  *pBuf;
X    auto     short.   nBufSize;
X    auto     short.   nRow, nCol, nWidth, nHeight;
X
X    pWinData = WinCvtHandle(hWnd);
X    if (NULL == pWinData)
X.return(FALSE);
X    nRow     = pWinData->cRow;
X    nCol     = pWinData->cCol;
X    nWidth   = pWinData->cWidth;
X    nHeight  = pWinData->cHeight;
X    nBufSize = ScrGetRectSize(nWidth, nHeight);
X    if (NULL != pWinData->pHidden)
X.free(pWinData->pHidden);
X    pBuf     = malloc(nBufSize);
X    if (NULL == pBuf)
X.return(FALSE);
X    ScrSaveRect(nRow, nCol, nWidth, nHeight, pBuf);
X    ScrRestoreRect(nRow, nCol, nWidth, nHeight, pWinData->cSaveData);
X    pWinData->pHidden = pBuf;
X    return(TRUE);
X}
X
X
X/***************************************************************************/
X/*  WinShowWindow  - Places a hidden window back on the screen and frees   */
X/*..     the buffer used to hold the window image...   */
X/*  Parms:........   */
X/*    hWnd.   - Handle to the window....   */
X/*.........   */
X/*  Return Value:    TRUE => window shown, FALSE => window wasn't hidden   */
X/***************************************************************************/
X
BOOL pascal WinShowWindow(hWnd)
HWND.     hWnd;
X{
X    register PWINDATA.    pWinData;
X
X    pWinData = WinCvtHandle(hWnd);
X    if (NULL == pWinData)
X.return(FALSE);
X    if (NULL == pWinData->pHidden)
X.return(FALSE);
X    ScrRestoreRect(pWinData->cRow, pWinData->cCol, pWinData->cWidth,
X..   pWinData->cHeight, pWinData->pHidden);
X    free(pWinData->pHidden);
X    pWinData->pHidden = NULL;
X    return(TRUE);
X}
X
X
X/***************************************************************************/
X/*  WinInitialize  - Init the windowing system. ...   */
X/*.........   */
X/*  Parms:.     None......   */
X/*.........   */
X/*  Return Value:    None......   */
X/***************************************************************************/
X
void pascal WinInitialize()
X{
X    ScrInitialize();
X    memset((char *) WinHandle, NULL, sizeof(WinHandle));
X    return;
X}
X
X
X/***************************************************************************/
X/*  WinTerminate   - Clean up the windowing package...   */
X/*.........   */
X/*  Parms:.     None......   */
X/*.........   */
X/*  Return Value:    None......   */
X/***************************************************************************/
X
void pascal WinTerminate()
X{
X    register short     i;
X
X    for (i = 1; i <= MAX_WINDOWS; ++i)
X    {
X.if (WinHandle[i] != NULL)
X.    WinDestroyWindow(i);
X    }
X    return;
X}
END_OF_FILE
if test 25998 -ne `wc -c <'win.c'`; then
    echo shar: \"'win.c'\" unpacked with wrong size!
fi
chmod +x 'win.c'
# end of 'win.c'
fi
if test -f 'win.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'win.h'\"
else
echo shar: Extracting \"'win.h'\" \(4168 characters\)
sed "s/^X//" >'win.h' <<'END_OF_FILE'
X#ifndef WIN_H
X#define WIN_H
X
X#define ANSI_PROTO.      1
X
X#ifndef TRUE
X#define TRUE..      1
X#define FALSE..      0
X#endif
X
X#define BLACK..      0x0
X#define BLUE..      0x1
X#define GREEN..      0x2
X#define CYAN..      0x3
X#define RED..      0x4
X#define MAGENTA .      0x5
X#define YELLOW..      0x6
X#define WHITE..      0x7
X#define REV_BLACK.      0x0
X#define REV_BLUE.      0x10
X#define REV_GREEN.      0x20
X#define REV_CYAN.      0x30
X#define REV_RED .      0x40
X#define REV_MAGENTA.      0x50
X#define REV_YELLOW.      0x60
X#define REV_WHITE.      0x70
X#define HI_INTENSITY.      0x8
X#define BLINK..      0x80
X
X#define NO_BOX..      0
X#define DBL_LINE_TOP_BOTTOM   1
X#define DBL_LINE_SIDES.      2
X#define DBL_LINE_ALL_SIDES    3
X#define SNGL_LINE_ALL_SIDES   4
X#define GRAPHIC_BOX.      5
X#define NO_WIND_BORDER.      99
X
X#define VIDEO_MONO.      0
X#define VIDEO_CGA.      1
X#define VIDEO_EGA.      2
X#define VIDEO_VGA.      3
X
typedef short..      HWND;
typedef unsigned char.      BYTE;
typedef short..      BOOL;
X
X
X.... /*  WIN.C  */
X#if ANSI_PROTO
void. pascal    WinDrawWindow(short, short, short, short,
X.... short, short, short, short);
HWND. pascal    WinCreateWindow(short, short, short, short,
X....   short, short, short, short);
BOOL. pascal    WinDestroyWindow(HWND);
void. pascal    WinScrollWindowUp(HWND);
void. pascal    WinScrollWindowDown(HWND);
void. pascal    WinSetCursorPos(HWND, short, short);
void. pascal    WinClearScreen(HWND, short);
void. pascal    WinTextOut(HWND, char *, short);
void. pascal    WinCenterText(HWND, short, char *, short);
void. pascal    WinMoveWindow(HWND, short, short);
short. pascal    WinGetWindowRow(HWND);
short. pascal    WinGetWindowCol(HWND);
short. pascal    WinGetWindowWidth(HWND);
short. pascal    WinGetWindowHeight(HWND);
short. pascal    WinGetWindowClr(HWND);
short. pascal    WinGetWindowBdrClr(HWND);
short. pascal    WinGetBorderType(HWND);
BOOL. pascal    WinHideWindow(HWND);
BOOL. pascal    WinShowWindow(HWND);
void. pascal    WinInitialize(void);
void. pascal    WinTerminate(void);
X#else
void. pascal    WinDrawWindow();
HWND. pascal    WinCreateWindow();
BOOL. pascal    WinDestroyWindow();
void. pascal    WinScrollWindowUp();
void. pascal    WinScrollWindowDown();
void. pascal    WinSetCursorPos();
void. pascal    WinClearScreen();
void. pascal    WinTextOut();
void. pascal    WinCenterText();
void. pascal    WinMoveWindow();
short. pascal    WinGetWindowRow();
short. pascal    WinGetWindowCol();
short. pascal    WinGetWindowWidth();
short. pascal    WinGetWindowHeight();
short. pascal    WinGetWindowClr();
short. pascal    WinGetWindowBdrClr();
short. pascal    WinGetBorderType();
BOOL. pascal    WinHideWindow();
BOOL. pascal    WinShowWindow();
void. pascal    WinInitialize();
void. pascal    WinTerminate();
X#endif
X
X..../*  SCRIO.C  */
X#if ANSI_PROTO
short. pascal    ScrGetRectSize(short, short);
void. pascal    ScrClearRect(short, short, short, short, short);
void. pascal    ScrSaveRect(short, short, short, short, char *);
void. pascal    ScrRestoreRect(short, short, short, short, char *);
void. pascal    ScrScrollRectUp(short, short, short, short,
X....   short, short);
void. pascal    ScrScrollRectDown(short, short, short, short,
X....     short, short);
void. pascal    ScrSetCursorPos(short, short);
void. pascal    ScrGetCursorPos(short *, short *);
void. pascal    ScrCursorOn(void);
void. pascal    ScrCursorOff(void);
void. pascal    ScrTextOut(char *, short, short);
void. pascal    ScrDrawRect(short, short, short, short, short, short);
void. pascal    ScrInitialize(void);
X#else
short. pascal    ScrGetRectSize();
void. pascal    ScrClearRect();
void. pascal    ScrSaveRect();
void. pascal    ScrRestoreRect();
void. pascal    ScrScrollRectUp();
void. pascal    ScrScrollRectDown();
void. pascal    ScrSetCursorPos();
void. pascal    ScrGetCursorPos();
void. pascal    ScrCursorOn();
void. pascal    ScrCursorOff();
void. pascal    ScrTextOut();
void. pascal    ScrDrawRect();
void. pascal    ScrInitialize();
X#endif
X
X#endif
X
END_OF_FILE
if test 4168 -ne `wc -c <'win.h'`; then
    echo shar: \"'win.h'\" unpacked with wrong size!
fi
chmod +x 'win.h'
# end of 'win.h'
fi
if test -f 'scrio.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'scrio.c'\"
else
echo shar: Extracting \"'scrio.c'\" \(19021 characters\)
sed "s/^X//" >'scrio.c' <<'END_OF_FILE'
X
X/***************************************************************************/
X/* SCRIO    - Routines which directly access the video screen..   */
X/*.........   */
X/*.........   */
X/*.........   */
X/***************************************************************************/
X/*...     Modification Log....   */
X/***************************************************************************/
X/* Version   Date   Programmer. -----------  Description  --------------- */
X/*.........   */
X/* V01.00   112787  Bob Withers  Program intially complete...   */
X/*.........   */
X/*.........   */
X/***************************************************************************/
X
X#include <stdlib.h>
X#include <stddef.h>
X#include <dos.h>
X#include <string.h>
X#include "win.h"
X
X#define MAXDIM(array)..   (sizeof(array) / sizeof(array[0]))
X
X#define SCR_BYTES_PER_ROW.   160
X#define CGA_MODE_SEL..   0x3d8
X#define CGA_ENABLE..   0x29
X#define CGA_DISABLE..   0x21
X
X#define BIOS_VID_INT..   0x10
X#define BIOS_VID_SET_CRTMODE.   0
X#define BIOS_VID_SET_CURSORTYPE    1
X#define BIOS_VID_SET_CURSORPOS.   2
X#define BIOS_VID_GET_CURSORPOS.   3
X#define BIOS_VID_SCROLL_UP.   6
X#define BIOS_VID_SCROLL_DOWN.   7
X#define BIOS_VID_WRITE_CHATTR.   9
X#define BIOS_VID_GET_CRTMODE.   15
X
X
struct sBoxType
X{
X    BYTE..cUpperLeft;
X    BYTE..cLowerLeft;
X    BYTE..cUpperRight;
X    BYTE..cLowerRight;
X    BYTE..cLeft;
X    BYTE..cRight;
X    BYTE..cTop;
X    BYTE..cBottom;
X};
typedef struct sBoxType BOXTYPE;
X
X
unsigned..uScrSeg .= 0xb800;
unsigned..uCsrType.= 0x0107;
short...nCurrActivePage = 0;
short...nVideoCard.= VIDEO_CGA;
short...nScrCols.= 80;
X
X
X/***************************************************************************/
X/*  ScrCvtAttr.  - Test for a monochrome video card and convert the.   */
X/*..    requested attribute to black & white as best we can    */
X/*..    and still honor the callers request...   */
X/*  Parms:........   */
X/*    nAttr.  - The passed color attribute. ...   */
X/*.........   */
X/*  Return Value:   A converted black & white attribute if the current.   */
X/*..    video mode is monochrome.....   */
X/***************************************************************************/
X
static short near pascal ScrCvtAttr(nAttr)
register short.  nAttr;
X{
X    short     nRev, nClr, nBlink, nIntensity;
X
X    if (VIDEO_MONO != nVideoCard)
X.return(nAttr);
X    nIntensity = nAttr & 0x40;
X    nBlink     = nAttr & 0x80;
X    nRev       = nAttr & 0x70;
X    nClr       = nAttr & 0x07;
X    if (REV_BLACK == nRev)
X.nClr = WHITE;
X    else
X    {
X.nRev = REV_WHITE;
X.nClr = BLACK;
X    }
X    return(nRev | nClr | nBlink | nIntensity);
X}
X
X
X/***************************************************************************/
X/*  ScrEnableVideoCGA - Test the current video equipment for a snowy CGA   */
X/*...card.  If running on a CGA enable/disable the.   */
X/*...video signal based on the passed parameter which   */
X/*...MUST be one of the predefined constants CGA_ENABLE */
X/*...or CGA_DISABLE.  If the current video equipment is */
X/*...not a CGA, the routine returns without taking any  */
X/*...action. .....   */
X/*  Parms:........   */
X/*    nStatus.      - Enable or disable the CGA video signal..   */
X/*...    CGA_ENABLE or CGA_DISABLE...   */
X/*.........   */
X/*  Return Value:.None......   */
X/***************************************************************************/
X
static void pascal ScrEnableVideoCGA(nStatus)
short.    nStatus;
X{
X    if (VIDEO_CGA == nVideoCard)
X.outp(CGA_MODE_SEL, nStatus);
X    return;
X}
X
X
X/***************************************************************************/
X/*  ScrGetRectSize - This routine will calculate and return the number of  */
X/*..     bytes required to store a screen image which is nWidth*/
X/*..     columns by nHeight rows.....   */
X/*  Parms:........   */
X/*    nWidth.   - Column width of the screen rectangle..   */
X/*    nHeight.   - Number of rows in the screen rectangle..   */
X/*.........   */
X/*  Return Value:    Size in bytes required to store the screen rectangle  */
X/***************************************************************************/
X
short pascal ScrGetRectSize(nWidth, nHeight)
short.    nWidth, nHeight;
X{
X    return(nWidth * nHeight * 2);
X}
X
X
X/***************************************************************************/
X/*  ScrClearRect - This routine will clear a screen rectangle to the.   */
X/*..   color attribute passed.....   */
X/*  Parms:........   */
X/*    nRow. - Row of the screen rectangle....   */
X/*    nCol. - Column of the screen rectangle...   */
X/*    nWidth. - Width in columns of the screen rectangle..   */
X/*    nHeight. - Number of rows in the screen rectangle..   */
X/*    nAttr. - Color attribute used to clear screen rectangle.   */
X/*.........   */
X/*  Return Value:  None ......   */
X/***************************************************************************/
X
void pascal ScrClearRect(nRow, nCol, nWidth, nHeight, nAttr)
short... nRow, nCol, nWidth, nHeight, nAttr;
X{
X    auto     union REGS     r;
X
X    nAttr  = ScrCvtAttr(nAttr);
X    r.h.ah = (BYTE) BIOS_VID_SCROLL_UP;
X    r.h.al = 0;
X    r.h.bh = (BYTE) nAttr;
X    r.h.ch = (BYTE) (nRow - 1);
X    r.h.cl = (BYTE) (nCol - 1);
X    r.h.dh = (BYTE) (nRow + nHeight - 2);
X    r.h.dl = (BYTE) (nCol + nWidth - 2);
X    int86(BIOS_VID_INT, &r, &r);
X    return;
X}
X
X
X/***************************************************************************/
X/*  ScrSaveRect - This routine will save a screen rectangle in a caller    */
X/*..  supplied buffer area.  nRow, nCol define the row and.   */
X/*..  column of the upper left corner of the rectangle..   */
X/*  Parms:........   */
X/*    nRow.- Row of the screen rectangle....   */
X/*    nCol.- Column of the screen rectangle...   */
X/*    nWidth.- Width in columns of the screen rectangle..   */
X/*    nHeight.- Number of rows in the screen rectangle..   */
X/*    pBuf.- Buffer used to store the saved screen rectangle.   */
X/*.........   */
X/*  Return Value:  None ......   */
X/***************************************************************************/
X
void pascal ScrSaveRect(nRow, nCol, nWidth, nHeight, pBuf)
short.   nRow, nCol, nWidth, nHeight;
char.  *pBuf;
X{
X    register unsigned.    uNumRows;
X    register unsigned.    uColLen;
X    auto     unsigned.    uScrOfs;
X    auto     unsigned.    uBufSeg, uBufOfs;
X    auto     char far.   *fpBuf;
X
X    uColLen = nWidth * 2;
X    uScrOfs = ((nRow - 1) * SCR_BYTES_PER_ROW) + (nCol - 1) * 2;
X    fpBuf   = (char far *) pBuf;
X    uBufSeg = FP_SEG(fpBuf);
X    uBufOfs = FP_OFF(fpBuf);
X    ScrEnableVideoCGA(CGA_DISABLE);
X    for (uNumRows = nHeight; uNumRows > 0; --uNumRows)
X    {
X.movedata(uScrSeg, uScrOfs, uBufSeg, uBufOfs, uColLen);
X.uScrOfs += SCR_BYTES_PER_ROW;
X.uBufOfs += uColLen;
X    }
X    ScrEnableVideoCGA(CGA_ENABLE);
X    return;
X}
X
X
X/***************************************************************************/
X/*  ScrRestoreRect - This routine will restore a screen rectangle from.   */
X/*..     a previously saved caller buffer..nRow and nCol.   */
X/*..     define the upper left corner of the rectangle on.   */
X/*..     the screen and are not required to be the same.   */
X/*..     coordinates used in the save call.  nWidth and.   */
X/*..     nHeight should remain unchanged from the save call    */
X/*..     but are not required to do so....   */
X/*  Parms:........   */
X/*    nRow.- Row of the screen rectangle....   */
X/*    nCol.- Column of the screen rectangle...   */
X/*    nWidth.- Width in columns of the screen rectangle..   */
X/*    nHeight.- Number of rows in the screen rectangle..   */
X/*    pBuf.- Buffer used to restore the saved screen rectangle.   */
X/*.........   */
X/*  Return Value:  None ......   */
X/***************************************************************************/
X
void pascal ScrRestoreRect(nRow, nCol, nWidth, nHeight, pBuf)
short.   nRow, nCol, nWidth, nHeight;
char.  *pBuf;
X{
X    register unsigned.    uNumRows;
X    register unsigned.    uColLen;
X    auto     unsigned.    uScrOfs;
X    auto     unsigned.    uBufSeg, uBufOfs;
X    auto     char far.   *fpBuf;
X
X    uColLen = nWidth * 2;
X    uScrOfs = ((nRow - 1) * SCR_BYTES_PER_ROW) + (nCol - 1) * 2;
X    fpBuf   = (char far *) pBuf;
X    uBufSeg = FP_SEG(fpBuf);
X    uBufOfs = FP_OFF(fpBuf);
X    ScrEnableVideoCGA(CGA_DISABLE);
X    for (uNumRows = nHeight; uNumRows > 0; --uNumRows)
X    {
X.movedata(uBufSeg, uBufOfs, uScrSeg, uScrOfs, uColLen);
X.uScrOfs += SCR_BYTES_PER_ROW;
X.uBufOfs += uColLen;
X    }
X    ScrEnableVideoCGA(CGA_ENABLE);
X    return;
X}
X
X
X/***************************************************************************/
X/*  ScrScrollRectUp   - Scrolls a screen rectangle up the requested number */
X/*...of lines......   */
X/*  Parms:........   */
X/*    nRow.- Row of the screen rectangle....   */
X/*    nCol.- Column of the screen rectangle...   */
X/*    nWidth.- Width in columns of the screen rectangle..   */
X/*    nHeight.- Number of rows in the screen rectangle..   */
X/*    nNoRows.- Number of rows to scroll....   */
X/*    nAttr.- Color attribute to fill blank line on bottom..   */
X/*.........   */
X/*  Return Value:  None ......   */
X/***************************************************************************/
X
void pascal ScrScrollRectUp(nRow, nCol, nWidth, nHeight, nNoRows, nAttr)
short. nRow, nCol, nWidth, nHeight, nNoRows, nAttr;
X{
X    auto     union REGS      r;
X
X    nAttr  = ScrCvtAttr(nAttr);
X    r.h.ah = BIOS_VID_SCROLL_UP;
X    r.h.al = (BYTE) nNoRows;
X    r.h.bh = (BYTE) nAttr;
X    r.h.ch = (BYTE) (nRow - 1);
X    r.h.cl = (BYTE) (nCol - 1);
X    r.h.dh = (BYTE) (nRow + nHeight - 2);
X    r.h.dl = (BYTE) (nCol + nWidth - 2);
X    int86(BIOS_VID_INT, &r, &r);
X    return;
X}
X
X
X/***************************************************************************/
X/*  ScrScrollRectDown - Scrolls a screen rectangle up the requested number */
X/*...of lines......   */
X/*  Parms:........   */
X/*    nRow.- Row of the screen rectangle....   */
X/*    nCol.- Column of the screen rectangle...   */
X/*    nWidth.- Width in columns of the screen rectangle..   */
X/*    nHeight.- Number of rows in the screen rectangle..   */
X/*    nNoRows.- Number of rows to scroll....   */
X/*    nAttr.- Color attribute to fill blank lines on top..   */
X/*.........   */
X/*  Return Value:  None ......   */
X/***************************************************************************/
X
void pascal ScrScrollRectDown(nRow, nCol, nWidth, nHeight, nNoRows, nAttr)
short. nRow, nCol, nWidth, nHeight, nNoRows, nAttr;
X{
X    auto     union REGS      r;
X
X    nAttr  = ScrCvtAttr(nAttr);
X    r.h.ah = BIOS_VID_SCROLL_DOWN;
X    r.h.al = (BYTE) nNoRows;
X    r.h.bh = (BYTE) nAttr;
X    r.h.ch = (BYTE) (nRow - 1);
X    r.h.cl = (BYTE) (nCol - 1);
X    r.h.dh = (BYTE) (nRow + nHeight - 2);
X    r.h.dl = (BYTE) (nCol + nWidth - 2);
X    int86(BIOS_VID_INT, &r, &r);
X    return;
X}
X
X
X/***************************************************************************/
X/*  ScrSetCursorPos - This routine will position the cursor to an absolute */
X/*..      screen coordinate using the BIOS video services..   */
X/*  Parms:........   */
X/*    nRow.    - Absolute screen row....   */
X/*    nCol.    - Absolute screen column....   */
X/*.........   */
X/*  Return Value      None......   */
X/***************************************************************************/
X
void pascal ScrSetCursorPos(nRow, nCol)
short.    nRow, nCol;
X{
X    auto     union REGS     r;
X
X    r.h.ah = BIOS_VID_SET_CURSORPOS;
X    r.h.dh = (BYTE) (nRow - 1);
X    r.h.dl = (BYTE) (nCol - 1);
X    r.h.bh = (BYTE) nCurrActivePage;
X    int86(BIOS_VID_INT, &r, &r);
X    return;
X}
X
X
X/***************************************************************************/
X/*  ScrGetCursorPos - This routine will return the current absolute.   */
X/*..      cursor position......   */
X/*  Parms:........   */
X/*    nRow.    - Pointer to location to save current row..   */
X/*    nCol.    - Pointer to location to save current column.   */
X/*.........   */
X/*  Return Value:     None......   */
X/***************************************************************************/
X
void pascal ScrGetCursorPos(nRow, nCol)
short.    *nRow, *nCol;
X{
X    auto     union REGS     r;
X
X    r.h.ah = BIOS_VID_GET_CURSORPOS;
X    r.h.bh = (BYTE) nCurrActivePage;
X    int86(BIOS_VID_INT, &r, &r);
X    *nRow  = r.h.dh + 1;
X    *nCol  = r.h.dl + 1;
X    return;
X}
X
X
X/***************************************************************************/
X/*  ScrCusrosOn     - Enables the screen cursor....   */
X/*.........   */
X/*  Parms:.      None......   */
X/*.........   */
X/*  Return Value:     None......   */
X/***************************************************************************/
X
void pascal ScrCursorOn()
X{
X    auto     union REGS     r;
X
X    r.h.ah = BIOS_VID_SET_CURSORTYPE;
X    r.x.cx = uCsrType;
X    int86(BIOS_VID_INT, &r, &r);
X    return;
X}
X
X
X/***************************************************************************/
X/*  ScrCusrosOff    - Disables the screen cursor....   */
X/*.........   */
X/*  Parms:.      None......   */
X/*.........   */
X/*  Return Value:     None......   */
X/***************************************************************************/
X
void pascal ScrCursorOff()
X{
X    auto     union REGS     r;
X
X    r.h.ah = BIOS_VID_SET_CURSORTYPE;
X    r.x.cx = 0x0f00;
X    int86(BIOS_VID_INT, &r, &r);
X    return;
X}
X
X
X/***************************************************************************/
X/*  ScrTextOut - This function uses the BIOS write character and attribute */
X/*.. service routine to display a string within a window.  The */
X/*.. passed nCount is used to limit a string from overflowing  */
X/*.. a window boundry......   */
X/*  Parms:........   */
X/*    pStr     - Pointer to the string to be displayed...   */
X/*    nAttr    - Color attribute used to display string ..   */
X/*    nCount   - Maximum number of characters to dispalay..   */
X/*.........   */
X/*  Return Value: None.......   */
X/***************************************************************************/
X
void pascal ScrTextOut(pStr, nAttr, nCount)
register char.*pStr;
short.. nAttr, nCount;
X{
X    register short.    i;
X    auto     short.    nRow, nCol;
X    auto     union REGS     r, r1;
X
X    ScrGetCursorPos(&nRow, &nCol);
X    nAttr  = ScrCvtAttr(nAttr);
X    r.h.ah = BIOS_VID_WRITE_CHATTR;
X    r.h.bh = (BYTE) nCurrActivePage;
X    r.h.bl = (BYTE) nAttr;
X    r.x.cx = 1;
X    while (*pStr && nCount-- > 0)
X    {
X.ScrSetCursorPos(nRow, nCol++);
X.r.h.al = *pStr++;
X.int86(BIOS_VID_INT, &r, &r1);
X    }
X    return;
X}
X
X
X/***************************************************************************/
X/*  ScrDrawRect - This routine is used to draw borders around a screen.   */
X/*..  window.  The passed parameters define the rectangle.   */
X/*..  being used by the window as well as the border color.   */
X/*..  and type.......   */
X/*  Parms:........   */
X/*    nRow.- Top row of screen border....   */
X/*    nCol.- Left column of screen border....   */
X/*    nWidth.- Column width of the window....   */
X/*    nHeight.- Number of rows in the window....   */
X/*    nColor.- Color attribute for the window border ..   */
X/*    nType.- Type of border to be displayed...   */
X/*.........   */
X/*  Return Value: None.......   */
X/***************************************************************************/
X
void pascal ScrDrawRect(nRow, nCol, nWidth, nHeight, nColor, nType)
short.    nRow, nCol, nWidth, nHeight, nColor, nType;
X{
X    register short.   i;
X    auto     union REGS    r, r1;
X    static   BOXTYPE.   BoxTypes[] =
X    {
X.{  32,.32,  32,  32,  32,  32,  32,  32 }, /* NO_BOX..   */
X.{ 213, 212, 184, 190, 179, 179, 205, 205 }, /* DBL_LINE_TOP_BOTTOM */
X.{ 214, 211, 183, 189, 186, 186, 196, 196 }, /* DBL_LINE_SIDES.   */
X.{ 201, 200, 187, 188, 186, 186, 205, 205 }, /* DBL_LINE_ALL_SIDES  */
X.{ 218, 192, 191, 217, 179, 179, 196, 196 }, /* SNGL_LINE_ALL_SIDES */
X.{ 219, 219, 219, 219, 219, 219, 223, 220 }  /* GRAPHIC BOX     */
X    };
X
X    if (nType < 0 || nType >= MAXDIM(BoxTypes))
X.return;
X    if (nWidth < 2 || nHeight < 2)
X.return;
X    nColor = ScrCvtAttr(nColor);
X
X    /* Draw upper left corner */
X    ScrSetCursorPos(nRow, nCol);
X    r.h.ah = (BYTE) BIOS_VID_WRITE_CHATTR;
X    r.h.al = (BYTE) BoxTypes[nType].cUpperLeft;
X    r.h.bh = (BYTE) nCurrActivePage;
X    r.h.bl = (BYTE) nColor;
X    r.x.cx = 1;
X    int86(BIOS_VID_INT, &r, &r1);
X
X    /* Draw upper right corner */
X    ScrSetCursorPos(nRow, nCol + nWidth - 1);
X    r.h.al = (BYTE) BoxTypes[nType].cUpperRight;
X    int86(BIOS_VID_INT, &r, &r1);
X
X    /* Draw lower left corner */
X    ScrSetCursorPos(nRow + nHeight - 1, nCol);
X    r.h.al = (BYTE) BoxTypes[nType].cLowerLeft;
X    int86(BIOS_VID_INT, &r, &r1);
X
X    /* Draw lower right corner */
X    ScrSetCursorPos(nRow + nHeight - 1, nCol + nWidth - 1);
X    r.h.al = (BYTE) BoxTypes[nType].cLowerRight;
X    int86(BIOS_VID_INT, &r, &r1);
X
X    if (nHeight > 2)
X    {
X./* Draw left side line */
X.r.h.al = (BYTE) BoxTypes[nType].cLeft;
X.for (i = 1; i <= nHeight - 2; ++i)
X.{
X.    ScrSetCursorPos(nRow + i, nCol);
X.    int86(BIOS_VID_INT, &r, &r1);
X.}
X
X./* Draw right side line */
X.r.h.al = (BYTE) BoxTypes[nType].cRight;
X.for (i = 1; i <= nHeight - 2; ++i)
X.{
X.    ScrSetCursorPos(nRow + i, nCol + nWidth - 1);
X.    int86(BIOS_VID_INT, &r, &r1);
X.}
X    }
X
X    if (nWidth > 2)
X    {
X./* Draw top line */
X.ScrSetCursorPos(nRow, nCol + 1);
X.r.h.al = (BYTE) BoxTypes[nType].cTop;
X.r.x.cx = nWidth - 2;
X.int86(BIOS_VID_INT, &r, &r1);
X
X./* Draw bottom line */
X.ScrSetCursorPos(nRow + nHeight - 1, nCol + 1);
X.r.h.al = BoxTypes[nType].cBottom;
X.int86(BIOS_VID_INT, &r, &r1);
X    }
X
X    return;
X}
X
X
X/***************************************************************************/
X/*  ScrInitialize - Determine type of video card and init global data..   */
X/*.........   */
X/*  Parms:.    None......   */
X/*.........   */
X/*  Return Value:   None......   */
X/***************************************************************************/
X
void pascal ScrInitialize()
X{
X    auto     union REGS     r;
X
X    r.h.ah = BIOS_VID_GET_CURSORPOS;
X    r.h.bh = (BYTE) nCurrActivePage;
X    int86(BIOS_VID_INT, &r, &r);
X    uCsrType = r.x.cx;
X
X    r.h.ah = BIOS_VID_GET_CRTMODE;
X    int86(BIOS_VID_INT, &r, &r);
X    nScrCols.    = r.h.ah;
X    nCurrActivePage = r.h.bh;
X.if (7 == r.h.al)
X    {
X.uScrSeg    = 0xb000;
X.nVideoCard = VIDEO_MONO;
X.return;
X    }
X    r.h.ah = BIOS_VID_SET_CRTMODE;
X    r.h.al = 3;
X.int86(BIOS_VID_INT, &r, &r);
X    uScrSeg    = 0xb800;
X    nVideoCard = VIDEO_CGA;
X    return;
X}
END_OF_FILE
if test 19021 -ne `wc -c <'scrio.c'`; then
    echo shar: \"'scrio.c'\" unpacked with wrong size!
fi
chmod +x 'scrio.c'
# end of 'scrio.c'
fi
if test -f 'windemo.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'windemo.c'\"
else
echo shar: Extracting \"'windemo.c'\" \(6095 characters\)
sed "s/^X//" >'windemo.c' <<'END_OF_FILE'
X
X#include <stdlib.h>
X#include <stddef.h>
X#include <time.h>
X#include <conio.h>
X#include "win.h"
X
X
static void Delay(nSeconds)
short.   nSeconds;
X{
X    auto     time_t    lQuitTime;
X
X    time(&lQuitTime);
X    lQuitTime += (time_t) nSeconds;
X    while (time(NULL) < lQuitTime)
X.;
X    return;
X}
X
X
X
static HWND IntroWindow()
X{
X    register HWND. hWnd;
X    auto     short. nTxtClr   = WHITE | REV_BLUE | HI_INTENSITY;
X    auto     short. nBriteClr = YELLOW | REV_BLUE | HI_INTENSITY;
X
X    hWnd = WinCreateWindow(7, 10, 60, 10, nTxtClr,
X...   SNGL_LINE_ALL_SIDES, nTxtClr, TRUE);
X    WinCenterText(hWnd, 1, "Welcome to C-WIN", nTxtClr);
X    WinCenterText(hWnd, 3, "a public domain contribution by", nTxtClr);
X    WinCenterText(hWnd, 5, "Bob Withers", nBriteClr);
X    WinCenterText(hWnd, 6, "649 Meadowbrook St", nBriteClr);
X    WinCenterText(hWnd, 7, "Allen, Texas 75002", nBriteClr);
X    Delay(5);
X    WinMoveWindow(hWnd, 1, 10);
X    return(hWnd);
X}
X
X
static void DocWindow()
X{
X    register HWND     hWnd;
X    auto     short    nTxtClr = REV_WHITE | BLUE;
X
X    hWnd = WinCreateWindow(9, 10, 60, 16, nTxtClr,
X...   DBL_LINE_ALL_SIDES, nTxtClr, FALSE);
X    WinCenterText(hWnd, 1, "C-WIN Version 1.00", nTxtClr);
X    WinSetCursorPos(hWnd, 3, 2);
X    WinTextOut(hWnd,
X.       "C-WIN is a collection of simple windowing routines for",
X.       nTxtClr);
X    WinSetCursorPos(hWnd, 4, 2);
X    WinTextOut(hWnd,
X.       "the IBM/PC and true clones. The package was written with",
X.       nTxtClr);
X    WinSetCursorPos(hWnd, 5, 2);
X    WinTextOut(hWnd,
X.       "the Microsoft C Compiler V5.00 and has been tested under",
X.       nTxtClr);
X    WinSetCursorPos(hWnd, 6, 2);
X    WinTextOut(hWnd,
X.       "the Turbo-C as well as Quick-C compilers. In the past I",
X.       nTxtClr);
X    WinSetCursorPos(hWnd, 7, 2);
X    WinTextOut(hWnd,
X.       "have developed several windowing packages for the PC but",
X.       nTxtClr);
X    WinSetCursorPos(hWnd, 8, 2);
X    WinTextOut(hWnd,
X.       "always in assembly language. I wanted a package written",
X.       nTxtClr);
X    WinSetCursorPos(hWnd, 9, 2);
X    WinTextOut(hWnd,
X.       "in C to allow it to easily be ported to other compilers.",
X.       nTxtClr);
X    WinSetCursorPos(hWnd, 10, 2);
X    WinTextOut(hWnd,
X.       "C-WIN is the result of my first efforts at this goal.",
X.       nTxtClr);
X    WinSetCursorPos(hWnd, 11, 2);
X    WinTextOut(hWnd,
X.       "I'm releasing it to the public domain in the hopes that",
X.       nTxtClr);
X    WinSetCursorPos(hWnd, 12, 2);
X    WinTextOut(hWnd,
X.       "others may find it a suitable base for their own work.",
X.       nTxtClr);
X    WinCenterText(hWnd, 14, "* Press any key to continue *",
X.       REV_RED | WHITE | HI_INTENSITY);
X    getch();
X    WinDestroyWindow(hWnd);
X    return;
X}
X
X
static void ShowBorders()
X{
X    register short.i;
X    auto     short.nTxtClr = REV_WHITE | BLUE;
X    auto     HWND.hWnd[6];
X    static   char      *pText[] = {  "Windows can",
X....     "be drawn with",
X....     "various borders,",
X....     "or with",
X....     "no border",
X....     "at all!"
X....  };
X
X    for (i = 0; i < 6; ++i)
X    {
X.hWnd[i] = WinCreateWindow(2 + i * 2, 2 + i * 2, 30, 6,
X....  nTxtClr, i,
X....  REV_WHITE | i | HI_INTENSITY, TRUE);
X.WinCenterText(hWnd[i], 1, pText[i], nTxtClr);
X.Delay(1);
X    }
X    Delay(5);
X    for (i = 5; i >= 0; --i)
X    {
X.WinMoveWindow(hWnd[i], 2 + (5 - i) * 2, 50 - (5 - i) * 2);
X.Delay(1);
X    }
X    Delay(5);
X    for (i = 0; i < 6; ++i)
X.WinMoveWindow(hWnd[i], 2 + i * 2, 1);
X    Delay(5);
X    for (i = 5; i >= 0; --i)
X.WinDestroyWindow(hWnd[i]);
X    return;
X}
X
X
void HideShowWindow(hHideWnd)
HWND.    hHideWnd;
X{
X    auto     HWND    hWnd;
X    auto     short   nTxtClr = REV_MAGENTA | BLUE | HI_INTENSITY;
X
X    hWnd = WinCreateWindow(1, 1, 30, 6, nTxtClr, NO_BOX, nTxtClr, FALSE);
X    WinCenterText(hWnd, 1, "Windows can be hidden", nTxtClr);
X    Delay(5);
X    WinHideWindow(hHideWnd);
X    WinCenterText(hWnd, 2, "Moved while hidden", nTxtClr);
X    Delay(2);
X    WinMoveWindow(hHideWnd, 7, 10);
X    WinCenterText(hWnd, 3, "and", nTxtClr);
X    WinCenterText(hWnd, 4, "re-shown at any time", nTxtClr);
X    Delay(5);
X    WinShowWindow(hHideWnd);
X    WinDestroyWindow(hWnd);
X    return;
X}
X
X
void ScrollWindow(hWnd)
register HWND. hWnd;
X{
X    auto     short     nRow, nCol;
X    auto     short     nWidth, nHeight;
X    auto     short     nWinClr;
X    auto     short     nNoRows;
X    auto     char     *pBuf;
X
X    nRow    = WinGetWindowRow(hWnd);
X    nCol    = WinGetWindowCol(hWnd);
X    nWidth  = WinGetWindowWidth(hWnd);
X    nHeight = nNoRows = WinGetWindowHeight(hWnd);
X    nWinClr = WinGetWindowClr(hWnd);
X    if (WinGetBorderType(hWnd) != NO_WIND_BORDER)
X    {
X.nWidth.+= 2;
X.nHeight += 2;
X    }
X    pBuf = malloc(ScrGetRectSize(nWidth, nHeight));
X    if (NULL == pBuf)
X.return;
X    ScrSaveRect(nRow, nCol, nWidth, nHeight, pBuf);
X    WinScrollWindowUp(hWnd);
X    WinScrollWindowUp(hWnd);
X    WinCenterText(hWnd, nNoRows, "Windows can be scrolled up", nWinClr);
X    Delay(2);
X    WinScrollWindowUp(hWnd);
X    Delay(2);
X    WinScrollWindowUp(hWnd);
X    Delay(2);
X    WinScrollWindowDown(hWnd);
X    WinScrollWindowDown(hWnd);
X    WinCenterText(hWnd, 1, "Windows can be scrolled down", nWinClr);
X    Delay(2);
X    WinScrollWindowDown(hWnd);
X    Delay(2);
X    WinScrollWindowDown(hWnd);
X    Delay(2);
X    ScrRestoreRect(nRow, nCol, nWidth, nHeight, pBuf);
X    free(pBuf);
X    WinCenterText(hWnd, nNoRows, " Press any key to end demo ",
X..  REV_RED | WHITE | HI_INTENSITY);
X    return;
X}
X
X
main()
X{
X    auto     HWND      hIntroWnd;
X
X    WinInitialize();
X    ScrCursorOff();
X    WinClearScreen(NULL, BLACK);
X    hIntroWnd = IntroWindow();
X    DocWindow();
X    WinMoveWindow(hIntroWnd, 16, 10);
X    ShowBorders();
X    HideShowWindow(hIntroWnd);
X    ScrollWindow(hIntroWnd);
X    getch();
X    WinDestroyWindow(hIntroWnd);
X    WinTerminate();
X    ScrCursorOn();
X    return(0);
X}
END_OF_FILE
if test 6095 -ne `wc -c <'windemo.c'`; then
    echo shar: \"'windemo.c'\" unpacked with wrong size!
fi
chmod +x 'windemo.c'
# end of 'windemo.c'
fi
echo shar: End of shell archive.
exit 0


