[comp.sources.misc] v08i094: PD MS-DOS C windowing system

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (10/18/89)

Posting-number: Volume 8, Issue 94
Submitted-by: fredex@cg-atla.UUCP (Fred Smith)
Archive-name: win_fs

Below is a shar of a public domain C language windowing package for MS-DOS
systems. It is said to be compatible with both Microsoft C V 4.00 and later
and also with Turbo C.

PLEASE NOTE that I did not write this and am not supporting it--I am merely
posting it for your edification. The name and address of the author are
given in the documentation. All comments should go to him and not me.

Enjoy!

Fred

#! /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