File:  [OS/2 SDKs] / pmsdk / samples / calc / calc.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 12:28:19 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: pmsdk-1989, HEAD
Microsoft OS/2 SDK PM 02-24-1989

/****************************** Module Header *********************************/
/*									      */
/* Module Name:  calc.c - Calc application				      */
/*									      */
/* OS/2 Presentation Manager version of Calc, ported from Windows version     */
/*									      */
/* Created by Microsoft Corporation, 1987				      */
/*									      */
/******************************************************************************/

#define INCL_WININPUT
#define INCL_WINPOINTERS
#define INCL_WINMENUS
#define INCL_WINSYS
#define INCL_WINCLIPBOARD
#define INCL_GPIPRIMITIVES
#define INCL_GPIBITMAPS
#define INCL_GPILCIDS
#define INCL_DEV
#define INCL_ERRORS
#define INCL_DOSPROCESS
#define INCL_DOSSEMAPHORES
#define INCL_DOSNLS
#include <os2.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "calc.h"

/******************************************************************************/
/*									      */
/*  GLOBAL VARIABLES							      */
/*									      */
/******************************************************************************/

CHAR  chLastKey, chCurrKey;
CHAR  szreg1[20], szreg2[20], szmem[20], szregx[20];
CHAR  szTitle[30], szErrorString[20], szPlusMinus[2];
SHORT sCharWidth, sCharHeight;
extern BOOL fError;
BOOL  fValueInMemory = FALSE;
BOOL  fMDown = FALSE;		       /* TRUE iff 'm' key depressed  */
UCHAR uchMScan = 0;		       /* scan code for 'm' key       */

#define TOLOWER(x)   ( (((x) >= 'A') && ((x) <= 'Z')) ? (x)|0x20 : (x))
#define WIDTHCONST  28
#define CXCHARS     37
#define CYCHARS     13

HAB hab;
HDC hdcLocal;			    /* Local used for button bitmap */
HPS hpsLocal;
HDC hdcSqr;			    /* Sqr used for square-root bitmap */
HPS hpsSqr;
HBITMAP hbmLocal, hbmSqr;
HMQ  hmqCalc;
HWND hwndCalc, hwndMenu;
HWND hwndCalcFrame;
HPS  hpsCalc;
HDC  hdcCalc;
HPOINTER hptrFinger;

DEVOPENSTRUC dop =		    /* used by DevOpenDC */
{
    NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL
};

static char achKeys[25] =	       /* keyboard keys */
{
    '\271', '0', '.', '\261', '+', '=',
    '\272', '1', '2', '3', '-', 'c',
    '\273', '4', '5', '6', '*', '%',
    '\274', '7', '8', '9', '/', 'q',
    NULL
};

static CHAR achDKeys[25] =    /* 4th key is plusminus */
{
    ' ', '0', '.', '+', '+', '=',
    ' ', '1', '2', '3', '-', 'C',
    ' ', '4', '5', '6', '*', '%',
    ' ', '7', '8', '9', '/', ' ',
    NULL
};

/******************************************************************************/
/*									      */
/*  PROCEDURE DECLARATIONS						      */
/*									      */
/******************************************************************************/

VOID FarStrcpy( PSZ, PSZ);
MPARAM CALLBACK AboutDlgProc( HWND, USHORT, MPARAM, MPARAM);
BOOL CalcInit(VOID);
VOID CalcPaint( HWND, HPS);
VOID CalcTextOut( HPS, INT, INT, PCH, INT);
MRESULT CALLBACK CalcWndProc( HWND, USHORT, MPARAM, MPARAM);
VOID cdecl main(VOID);
VOID DataXCopy( VOID);
VOID DataXPaste( VOID);
VOID DrawNumbers( HPS);
VOID Evaluate(BYTE);
BOOL FlashSqr( HPS, PWPOINT);
VOID FlipKey( HPS, INT, INT);
VOID FrameKey( HPS, INT, INT);
VOID InitCalc( VOID);
BOOL InterpretChar( CHAR);
VOID ProcessKey( PWPOINT);
BOOL PSInit( VOID);
CHAR Translate( PWPOINT);
VOID UpdateDisplay( VOID);


/******************************************************************************/
/******************************************************************************/
VOID CalcTextOut( hps, iX, iY, pch, iCount)

HPS hps;
INT iX, iY;
PCH pch;
INT iCount;
{
    POINTL ptl;

    ptl.x = iX;
    ptl.y = iY;

    GpiSetColor( hps, CLR_BLACK);
    GpiCharStringAt( hps, (PPOINTL)&ptl, (LONG)iCount, (PSZ)pch);
}


/******************************************************************************/
/* Write the appropriate number or error string to the display area	      */
/* and mark memory-in-use if appropriate.				      */
/******************************************************************************/
VOID
UpdateDisplay()
{
    RECTL rcl;

    rcl.xLeft = (6 * sCharWidth);
    rcl.yBottom = 1050 * sCharHeight / 100;
    rcl.xRight = rcl.xLeft + (12 * sCharWidth);
    rcl.yTop = rcl.yBottom + (3 * sCharHeight) / 2;

    WinFillRect( hpsCalc, &rcl, CLR_WHITE);	 /* paint display area white */
    if( fError)
	WinDrawText( hpsCalc
		   , -1
		   , szErrorString
		   , &rcl
		   , CLR_BLACK
		   , CLR_WHITE
		   , DT_RIGHT | DT_VCENTER );
    else
	WinDrawText( hpsCalc
		   , -1
		   , szreg1
		   , &rcl
		   , CLR_BLACK
		   , CLR_WHITE
		   , DT_RIGHT | DT_VCENTER );

    if (fValueInMemory) 		/* little black square shows mem use */
    {
	rcl.xLeft = (6 * sCharWidth);
	rcl.yBottom = 1050 * sCharHeight / 100;
	rcl.xRight = rcl.xLeft + (sCharWidth / 2);
	rcl.yTop = rcl.yBottom + (sCharHeight / 2);
	WinFillRect( hpsCalc, &rcl, CLR_BLACK);
    }
}


/******************************************************************************/
/*  Display helpful info						      */
/******************************************************************************/
MPARAM CALLBACK
AboutDlgProc( hwnd, msg, mp1, mp2)

HWND   hwnd;
USHORT msg;
MPARAM mp1;
MPARAM mp2;
{
    if (msg == WM_COMMAND)
    {
        WinDismissDlg(hwnd, TRUE);
	return(MPFROMSHORT(TRUE));
    }
    else return(WinDefDlgProc( hwnd, msg, mp1, mp2));
}


/******************************************************************************/
/*  General initialization						      */
/******************************************************************************/
BOOL
CalcInit()
{
    hab = WinInitialize( NULL);

    hmqCalc = WinCreateMsgQueue( hab, 0);
    if( !hmqCalc)
        return(FALSE);

    WinLoadString( NULL, NULL, 1, 30, (PSZ)szTitle);
    WinLoadString( NULL, NULL, 2, 20, (PSZ)szErrorString);
    WinLoadString( NULL, NULL, 3, 2, (PSZ)szPlusMinus);

    if (!WinRegisterClass( hab, szTitle, CalcWndProc, CS_SIZEREDRAW, 0))
        return(FALSE);

    hptrFinger = WinLoadPointer( HWND_DESKTOP, (HMODULE)NULL, IDP_FINGER);

    InitCalc(); 			/* arithmetic initialization */

    return(TRUE);
}

/******************************************************************************/
/*  main procedure							      */
/******************************************************************************/
VOID cdecl
main()
{
    QMSG  qmsg;
    ULONG ulFCF;

    if (!CalcInit()) {			    /* general initialization */
	WinAlarm(HWND_DESKTOP, WA_ERROR);
        goto exit;
    }

    if (!PSInit()) {			    /* presentation spaces & bitmaps */
	WinAlarm(HWND_DESKTOP, WA_ERROR);
        goto exit;
    }

    ulFCF = FCF_STANDARD & ~(LONG)(FCF_SIZEBORDER | FCF_MAXBUTTON);
    hwndCalcFrame = WinCreateStdWindow( HWND_DESKTOP
				      , WS_VISIBLE | FS_BORDER
				      , &ulFCF
				      , szTitle
				      , NULL
				      , 0L
				      , NULL
				      , IDR_CALC
				      , &hwndCalc);

    WinSetWindowPos( hwndCalcFrame
		   , (HWND)NULL
		   , 2
		   , 2
		   , CXCHARS * sCharWidth
		   , CYCHARS * sCharHeight
			     + (SHORT)WinQuerySysValue( HWND_DESKTOP
						      , SV_CYTITLEBAR )
			     + (SHORT)WinQuerySysValue( HWND_DESKTOP
						      , SV_CYMENU )
		   , SWP_MOVE | SWP_SIZE );

    while (WinGetMsg( hab, &qmsg, NULL, 0, 0))
	WinDispatchMsg( hab, &qmsg);

exit:					    /* clean up */
    if (hdcSqr) 			    /* square-root bitmap */
    {
	GpiDestroyPS( hpsSqr);
	if (hbmSqr)
	    GpiDeleteBitmap( hbmSqr);
    }

    if (hdcLocal)			    /* keypad button */
    {
	GpiDestroyPS( hpsLocal);
	if (hbmLocal)
	    GpiDeleteBitmap( hbmLocal);
    }

    WinDestroyWindow(hwndCalcFrame);

    WinDestroyMsgQueue(hmqCalc);
    WinTerminate(hab);

    DosExit(EXIT_PROCESS, 0);		    /* exit without error */
}


/******************************************************************************/
/* Calc Window Procedure						      */
/******************************************************************************/
MRESULT CALLBACK
CalcWndProc(hwnd, msg, mp1, mp2)

HWND	hwnd;
USHORT	msg;
MPARAM	mp1;
MPARAM	mp2;
{
    HPS     hps;
    RECTL   rclPaint;
    WPOINT  wpt;
    BOOL    fClip;
    USHORT  usFmtInfo;
    RECTL   rcl;
    SIZEL   sizl;

    switch (msg)
    {
    case WM_CREATE:
	hdcCalc = WinOpenWindowDC( hwnd);
	WinQueryWindowRect( hwnd, &rcl);
	sizl.cx = rcl.xRight - rcl.xLeft;
	sizl.cy = rcl.yTop - rcl.yBottom;
	hpsCalc = GpiCreatePS( hab
			     , hdcCalc
			     , &sizl
			     , GPIA_ASSOC | PU_PELS );
        break;

    case WM_DESTROY:
        WinDestroyPointer(hptrFinger);
	GpiDestroyPS( hpsSqr);
	GpiDeleteBitmap( hbmSqr);
	GpiDestroyPS( hpsLocal);
	GpiDeleteBitmap( hbmLocal);
        break;

    case WM_INITMENU:
        fClip = FALSE;
	if (WinOpenClipbrd( hab))
        {
	    fClip = WinQueryClipbrdFmtInfo( hab, CF_TEXT, &usFmtInfo);
	    WinCloseClipbrd( hab);
        }
	WinSendMsg((HWND)mp2, MM_SETITEMATTR,
		   (MPARAM) MAKELONG(CMD_PASTE, TRUE),
		   (MPARAM) MAKELONG(MIA_DISABLED, fClip ? 0 : MIA_DISABLED));
        break;

    case WM_PAINT:
	hps = WinBeginPaint(hwnd, NULL, &rclPaint);
	CalcPaint( hwnd, hps);			    /* re-draw calculator */
        WinEndPaint(hps);
        break;

    case WM_COMMAND:
	if (fError)
            break;
        switch(LOUSHORT(mp1))
        {
        case CMD_COPY:
	    DataXCopy();		    /* copy to clipboard */
            break;
        case CMD_PASTE:
	    DataXPaste();		    /* paste from clipboard */
            break;
        case CMD_EXIT:
	    WinPostMsg( hwndCalcFrame, WM_QUIT, 0L, 0L);
            break;
        case CMD_ABOUT:
	    WinDlgBox( HWND_DESKTOP
		     , hwndCalcFrame
		     , (PFNWP)AboutDlgProc
		     , NULL
		     , 1
		     , (PSZ)NULL );
            break;
        }
        break;

    case WM_MOUSEMOVE:
	WinSetPointer( HWND_DESKTOP, hptrFinger);
        break;

    case WM_BUTTON1DOWN:
	wpt.x = LOUSHORT(mp1);
	wpt.y = HIUSHORT(mp1);
	ProcessKey( &wpt);
        goto dwp;
        break;

    case WM_CHAR:
	if (SHORT1FROMMP(mp1) & KC_KEYUP)
	{
	    if (CHAR4FROMMP(mp1) == uchMScan)
		fMDown = FALSE; 		/* 'm' key went up */
	}
	else if (SHORT1FROMMP(mp1) & KC_CHAR)
        {
	    if (InterpretChar(CHAR1FROMMP(mp2)))
		UpdateDisplay();
	    else if ((CHAR1FROMMP(mp2)=='m') || (CHAR1FROMMP(mp2)=='M'))
	    {
		uchMScan = CHAR4FROMMP(mp1);	   /* save 'm' key scan code  */
		fMDown = TRUE;			   /* 'm' key went down       */
	    }
        }
        break;

    case WM_ACTIVATE:
        if (HIUSHORT(mp1))
	    WinSetFocus( HWND_DESKTOP, hwndCalc);
	break;

    case WM_SETFOCUS:
	if ((HWNDFROMMP(mp1)==hwndCalc) && !mp2);
	    fMDown = FALSE;			/* since we are losing focus */
	break;

dwp:
    default:
        return(WinDefWindowProc(hwnd, msg, mp1, mp2));
        break;
    }
    return(0L);
}


/******************************************************************************/
/*  translate & interpret keys (ie. locate in logical keyboard) 	      */
/******************************************************************************/
BOOL
InterpretChar( ch)

CHAR ch;
{
    BOOL fDone;
    NPCH pchStep;
    INT  i;

    fDone = FALSE;
    pchStep = achKeys;
    switch (ch)
    {
    case 'n':
	ch = szPlusMinus[0];
        break;
    case 27:                        /* xlate Escape into 'c' */
        ch = 'c';
        break;
    case '\r':                      /* xlate Enter into '=' */
        ch = '=';
        break;
    }

    if (fMDown) 		    /* Do memory keys */
    {
        switch (ch)
        {
        case 'c':
        case 'C':
            ch = '\274';
            break;
        case 'r':
        case 'R':
            ch = '\273';
            break;
        case '+':
            ch = '\272';
            break;
        case '-':
            ch = '\271';
            break;
        }
    }

    while (!fDone && *pchStep)
    {
	if (*pchStep++ == ch)
	    fDone = TRUE;		/* char found in logical keyboard */
    }
    if (fDone)
    {
	chLastKey = chCurrKey;
	i = pchStep - achKeys - 1;
	FlipKey( hpsCalc, i/6, i%6);
	Evaluate( achKeys[i]);
    }
    return (fDone);
}


/******************************************************************************/
/*  briefly reverse the shading on one of the keys			      */
/******************************************************************************/
VOID
FlipKey( hps, iRow, iCol)

HPS hps;
INT iRow, iCol;
{
    RECTL rcl;

    rcl.xLeft = (iCol * 6 * sCharWidth) + (14 * sCharWidth / 10);
    rcl.yBottom = (165 * sCharHeight / 100) + (2 * iRow * sCharHeight);
    rcl.xRight = rcl.xLeft + (11 * sCharWidth / 3);
    rcl.yTop = rcl.yBottom + (7 * sCharHeight / 4);
    WinInvertRect( hps, &rcl);
    DosSleep( 50L);
    WinInvertRect( hps, &rcl);
}


/******************************************************************************/
/*  compute whether a point is over a button and flash the button if so       */
/******************************************************************************/
BOOL
FlashSqr( hps, pwpt)

HPS	 hps;
PWPOINT  pwpt;
{
    INT  iRow, iCol;
    BOOL fDone;

    /* find x range */
    fDone = FALSE;
    iCol = 0;
    iRow = 3;
    while (!fDone && iCol<6)
    {
	if (pwpt->x <	(iCol * 6 * sCharWidth)
		       + (14 * sCharWidth / 10)
		       + (11*sCharWidth/3)	 )
        {
	    if (pwpt->x > (iCol * 6 * sCharWidth) + (14 * sCharWidth / 10))
                fDone = TRUE;
            else
                return FALSE;
        }
        else
	    iCol++;
    }
    if (!fDone)
        return FALSE;
    fDone = FALSE;
    while (!fDone && iRow >= 0)
    {
	if (pwpt->y > ((165 * sCharHeight / 100) + (2 * iRow * sCharHeight)))
        {
	    if (pwpt->y <   (165 * sCharHeight / 100)
			   + (2 * iRow * sCharHeight)
			   + (7 * sCharHeight / 4)     )
                fDone = TRUE;
            else
                return FALSE;
        }
        else
	    iRow--;
    }
    if (!fDone)
        return FALSE;
    pwpt->x = iCol;
    pwpt->y = iRow;
    FlipKey( hps, iRow, iCol);
    return TRUE;
}


/******************************************************************************/
/*  which key is point on?						      */
/******************************************************************************/
CHAR
Translate( pwpt)

PWPOINT pwpt;
{
    return( achKeys[ pwpt->y * 6 + pwpt->x]);
}


/******************************************************************************/
/*  invoke flashing, point-to-key translation, and result-display update      */
/******************************************************************************/
VOID
ProcessKey( pwpt)

PWPOINT pwpt;
{
    BOOL fFlashed;

    chLastKey = chCurrKey;
    fFlashed = FlashSqr( hpsCalc, pwpt);

    if (fFlashed)
	Evaluate( (BYTE)Translate( pwpt));
    UpdateDisplay();
}


/******************************************************************************/
/*  draw a blank key							      */
/******************************************************************************/
VOID
FrameKey(hps, iRow, iCol)

HPS hps;
INT iRow, iCol;
{
    POINTL aptl[3];

    aptl[0].x = (iCol * 6 * sCharWidth) + (14 * sCharWidth / 10);
    aptl[0].y = (165 * sCharHeight / 100) + (2 * iRow * sCharHeight);
    aptl[1].x = (11 * sCharWidth / 3) + (aptl[0].x);
    aptl[1].y = (7 * sCharHeight / 4) + (aptl[0].y);
    aptl[2].x = 0;
    aptl[2].y = 0;
    GpiBitBlt( hps, hpsLocal, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE);
}


/******************************************************************************/
/*  draw the keys and fill in numbers					      */
/******************************************************************************/
VOID
DrawNumbers(hps)

HPS hps;
{
    INT iRow, iCol;

    /* Draw the keys and fill in the numbers we can */
    for (iRow = 0; iRow < 4; iRow++)
    {
	for (iCol = 0; iCol < 6; iCol++)
        {
	    FrameKey( hps, iRow, iCol);
	    CalcTextOut( hps
		       ,   (iCol * 6 * sCharWidth)
			 + (WIDTHCONST * sCharWidth / 10)
		       , (iRow + 1) * 2 * sCharHeight
		       , (PSZ)(achDKeys + (iRow * 6) + iCol)
		       , 1 );
        }
    }
}


/******************************************************************************/
/*  redraw the whole calculator 					      */
/******************************************************************************/
VOID
CalcPaint( hwnd, hps)

HWND hwnd;
HPS  hps;
{
    RECTL      rclDst;
    CHARBUNDLE cbnd;
    INT        iX, iY;

    WinQueryWindowRect( hwnd, &rclDst);
    WinFillRect( hps, &rclDst, CLR_GREEN);

    DrawNumbers(hps);
    CalcTextOut(hps, iX = (11 * sCharWidth / 5) + 1, iY = 2 * sCharHeight,
               (PSZ)"M-", 2);
    CalcTextOut(hps, iX, iY + 2 * sCharHeight, (PSZ)"M+", 2);
    CalcTextOut(hps, iX, iY + 4 * sCharHeight, (PSZ)"MR", 2);
    CalcTextOut(hps, iX, iY + 6 * sCharHeight, (PSZ)"MC", 2);

    /* Draw the minus of the plus/minus button */
    cbnd.usBackMixMode = FM_LEAVEALONE;
    GpiSetAttrs( hps, PRIM_CHAR, CBB_BACK_MIX_MODE, 0L, &cbnd);
    iX =  (3 * 6 * sCharWidth) + (WIDTHCONST * sCharWidth / 10);
    CalcTextOut( hps, iX, iY + sCharHeight / 4, (PSZ)"_", 1);

    /* Draw the square root bitmap */
    rclDst.xLeft = 160 * sCharWidth / 5;
    rclDst.yBottom = 31 * sCharHeight / 4;
    rclDst.xRight = rclDst.xLeft + 2 * sCharWidth;
    rclDst.yTop = rclDst.yBottom + (3 * sCharHeight / 2);
    WinDrawBitmap( hps
		 , hbmSqr
		 , NULL
		 , (PPOINTL)&rclDst
		 , CLR_WHITE
		 , CLR_BLACK
		 , DBM_STRETCH );

    UpdateDisplay();
}


/******************************************************************************/
/*  initialize the bitmaps for a blank key and for the square-root sign       */
/******************************************************************************/
BOOL
PSInit()
{
    HPS 	     hps;
    FONTMETRICS      fm;
    POINTL	     ptl;
    SIZEL	     sizl;
    BITMAPINFOHEADER bmp;
    POINTL	     aptl[4];
    LONG	     alCaps[2];

    /**************************************************************************/
    /*	compute the units of horizontal and vertical distance based on font   */
    /**************************************************************************/
    hps = WinGetPS( HWND_DESKTOP);
    GpiQueryFontMetrics( hps, (LONG)sizeof(FONTMETRICS), &fm);
    sCharHeight = (SHORT)(fm.lEmHeight); /* avg height of uppercase character */
    sCharWidth	= (SHORT)(fm.lEmInc);	 /* usually 'M' increment	      */
    WinReleasePS( hps);

    /**************************************************************************/
    /*	prepare the square root bitmap					      */
    /**************************************************************************/
    hdcSqr = DevOpenDC( hab, OD_MEMORY, "*", 3L, (PDEVOPENDATA)&dop, NULL);
    if( !hdcSqr)
	return(FALSE);

    sizl.cx = sizl.cy = 0L;
    hpsSqr = GpiCreatePS( hab
			, hdcSqr
			, &sizl
			, PU_PELS | GPIT_MICRO | GPIA_ASSOC );
    hbmSqr = GpiLoadBitmap( hpsSqr, NULL, IDB_SQR, 0L, 0L);

    /**************************************************************************/
    /*	prepare the bitmap of a blank key				      */
    /**************************************************************************/
    hdcLocal = DevOpenDC( hab, OD_MEMORY, "*", 3L, (PDEVOPENDATA)&dop, NULL);
    if( !hdcLocal)
	return(FALSE);

    sizl.cx = sizl.cy = 0L;
    hpsLocal = GpiCreatePS( hab
			  , hdcLocal
			  , &sizl
			  , PU_PELS | GPIT_MICRO | GPIA_ASSOC );
    bmp.cbFix = 12;
    bmp.cx = 11 * sCharWidth / 3;
    bmp.cy = sCharHeight * 2;
    DevQueryCaps( hdcLocal, CAPS_COLOR_PLANES, 2L, alCaps);
    bmp.cPlanes = (USHORT)alCaps[0];
    bmp.cBitCount = (USHORT)alCaps[1];
    hbmLocal = GpiCreateBitmap( hpsLocal, &bmp, 0L, NULL, NULL);
    if( !hbmLocal )
	return(FALSE);
    GpiSetBitmap( hpsLocal, hbmLocal);

    aptl[0].x = aptl[0].y = 0;
    aptl[1].x = 11 * sCharWidth / 3;
    aptl[1].y = 7 * sCharHeight / 4;
    aptl[2].x = aptl[2].y = 0;
    aptl[3].x = aptl[1].x;
    aptl[3].y = aptl[1].y;
    GpiSetColor( hpsLocal, CLR_GREEN);	    /* match the background to client */
    GpiBitBlt( hpsLocal, NULL, 2L, aptl, ROP_PATCOPY, BBO_IGNORE);

    /* Draw the rounded rect */
    ptl.x = 0;
    ptl.y = 0;
    GpiSetCurrentPosition( hpsLocal, &ptl);
    ptl.x = (11 * sCharWidth / 3) - 1;
    ptl.y = (7 * sCharHeight / 4) - 1;
    GpiSetColor( hpsLocal, CLR_WHITE);	    /* white interior		      */
    GpiBox( hpsLocal
	  , DRO_FILL
	  , &ptl
	  , (LONG)sCharWidth
	  , (LONG)(sCharHeight / 2) );
    ptl.x = 0;
    ptl.y = 0;
    GpiSetCurrentPosition( hpsLocal, &ptl);
    ptl.x = (11 * sCharWidth / 3) - 1;
    ptl.y = (7 * sCharHeight / 4) - 1;
    GpiSetColor( hpsLocal, CLR_BLACK);	    /* black border		      */
    GpiBox( hpsLocal
	  , DRO_OUTLINE
	  , &ptl
	  , (LONG)sCharWidth
	  , (LONG)(sCharHeight / 2) );
    return( TRUE);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.