Annotation of pmsdk/samples/calc/calc.c, revision 1.1.1.2

1.1.1.2 ! root        1: /****************************** Module Header *********************************/
        !             2: /*                                                                           */
        !             3: /* Module Name:  calc.c - Calc application                                   */
        !             4: /*                                                                           */
        !             5: /* OS/2 Presentation Manager version of Calc, ported from Windows version     */
        !             6: /*                                                                           */
        !             7: /* Created by Microsoft Corporation, 1987                                    */
        !             8: /*                                                                           */
        !             9: /******************************************************************************/
        !            10: 
        !            11: #define INCL_WININPUT
        !            12: #define INCL_WINPOINTERS
        !            13: #define INCL_WINMENUS
        !            14: #define INCL_WINSYS
        !            15: #define INCL_WINCLIPBOARD
        !            16: #define INCL_GPIPRIMITIVES
        !            17: #define INCL_GPIBITMAPS
        !            18: #define INCL_GPILCIDS
1.1       root       19: #define INCL_DEV
                     20: #define INCL_ERRORS
                     21: #define INCL_DOSPROCESS
                     22: #define INCL_DOSSEMAPHORES
                     23: #define INCL_DOSNLS
                     24: #include <os2.h>
                     25: #include <string.h>
                     26: #include <stdlib.h>
                     27: #include <stdio.h>
                     28: #include "calc.h"
                     29: 
1.1.1.2 ! root       30: /******************************************************************************/
        !            31: /*                                                                           */
        !            32: /*  GLOBAL VARIABLES                                                         */
        !            33: /*                                                                           */
        !            34: /******************************************************************************/
        !            35: 
        !            36: CHAR  chLastKey, chCurrKey;
        !            37: CHAR  szreg1[20], szreg2[20], szmem[20], szregx[20];
        !            38: CHAR  szTitle[30], szErrorString[20], szPlusMinus[2];
        !            39: SHORT sCharWidth, sCharHeight;
1.1       root       40: extern BOOL fError;
1.1.1.2 ! root       41: BOOL  fValueInMemory = FALSE;
        !            42: BOOL  fMDown = FALSE;                 /* TRUE iff 'm' key depressed  */
        !            43: UCHAR uchMScan = 0;                   /* scan code for 'm' key       */
1.1       root       44: 
                     45: #define TOLOWER(x)   ( (((x) >= 'A') && ((x) <= 'Z')) ? (x)|0x20 : (x))
                     46: #define WIDTHCONST  28
                     47: #define CXCHARS     37
                     48: #define CYCHARS     13
                     49: 
                     50: HAB hab;
                     51: HDC hdcLocal;                      /* Local used for button bitmap */
                     52: HPS hpsLocal;
                     53: HDC hdcSqr;                        /* Sqr used for square-root bitmap */
                     54: HPS hpsSqr;
                     55: HBITMAP hbmLocal, hbmSqr;
                     56: HMQ  hmqCalc;
                     57: HWND hwndCalc, hwndMenu;
                     58: HWND hwndCalcFrame;
1.1.1.2 ! root       59: HPS  hpsCalc;
        !            60: HDC  hdcCalc;
1.1       root       61: HPOINTER hptrFinger;
                     62: 
                     63: DEVOPENSTRUC dop =                 /* used by DevOpenDC */
                     64: {
                     65:     NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL
                     66: };
                     67: 
1.1.1.2 ! root       68: static char achKeys[25] =             /* keyboard keys */
1.1       root       69: {
                     70:     '\271', '0', '.', '\261', '+', '=',
                     71:     '\272', '1', '2', '3', '-', 'c',
                     72:     '\273', '4', '5', '6', '*', '%',
                     73:     '\274', '7', '8', '9', '/', 'q',
                     74:     NULL
                     75: };
                     76: 
1.1.1.2 ! root       77: static CHAR achDKeys[25] =    /* 4th key is plusminus */
1.1       root       78: {
                     79:     ' ', '0', '.', '+', '+', '=',
                     80:     ' ', '1', '2', '3', '-', 'C',
                     81:     ' ', '4', '5', '6', '*', '%',
                     82:     ' ', '7', '8', '9', '/', ' ',
                     83:     NULL
                     84: };
                     85: 
1.1.1.2 ! root       86: /******************************************************************************/
        !            87: /*                                                                           */
        !            88: /*  PROCEDURE DECLARATIONS                                                   */
        !            89: /*                                                                           */
        !            90: /******************************************************************************/
1.1       root       91: 
1.1.1.2 ! root       92: VOID FarStrcpy( PSZ, PSZ);
        !            93: MPARAM CALLBACK AboutDlgProc( HWND, USHORT, MPARAM, MPARAM);
1.1       root       94: BOOL CalcInit(VOID);
                     95: VOID CalcPaint( HWND, HPS);
1.1.1.2 ! root       96: VOID CalcTextOut( HPS, INT, INT, PCH, INT);
        !            97: MRESULT CALLBACK CalcWndProc( HWND, USHORT, MPARAM, MPARAM);
1.1       root       98: VOID cdecl main(VOID);
                     99: VOID DataXCopy( VOID);
                    100: VOID DataXPaste( VOID);
                    101: VOID DrawNumbers( HPS);
                    102: VOID Evaluate(BYTE);
1.1.1.2 ! root      103: BOOL FlashSqr( HPS, PWPOINT);
        !           104: VOID FlipKey( HPS, INT, INT);
1.1       root      105: VOID FrameKey( HPS, INT, INT);
                    106: VOID InitCalc( VOID);
                    107: BOOL InterpretChar( CHAR);
1.1.1.2 ! root      108: VOID ProcessKey( PWPOINT);
1.1       root      109: BOOL PSInit( VOID);
1.1.1.2 ! root      110: CHAR Translate( PWPOINT);
1.1       root      111: VOID UpdateDisplay( VOID);
                    112: 
                    113: 
1.1.1.2 ! root      114: /******************************************************************************/
        !           115: /******************************************************************************/
        !           116: VOID CalcTextOut( hps, iX, iY, pch, iCount)
        !           117: 
        !           118: HPS hps;
        !           119: INT iX, iY;
        !           120: PCH pch;
        !           121: INT iCount;
        !           122: {
        !           123:     POINTL ptl;
1.1       root      124: 
1.1.1.2 ! root      125:     ptl.x = iX;
        !           126:     ptl.y = iY;
1.1       root      127: 
1.1.1.2 ! root      128:     GpiSetColor( hps, CLR_BLACK);
        !           129:     GpiCharStringAt( hps, (PPOINTL)&ptl, (LONG)iCount, (PSZ)pch);
        !           130: }
        !           131: 
        !           132: 
        !           133: /******************************************************************************/
        !           134: /* Write the appropriate number or error string to the display area          */
        !           135: /* and mark memory-in-use if appropriate.                                    */
        !           136: /******************************************************************************/
        !           137: VOID
        !           138: UpdateDisplay()
1.1       root      139: {
                    140:     RECTL rcl;
                    141: 
1.1.1.2 ! root      142:     rcl.xLeft = (6 * sCharWidth);
        !           143:     rcl.yBottom = 1050 * sCharHeight / 100;
        !           144:     rcl.xRight = rcl.xLeft + (12 * sCharWidth);
        !           145:     rcl.yTop = rcl.yBottom + (3 * sCharHeight) / 2;
        !           146: 
        !           147:     WinFillRect( hpsCalc, &rcl, CLR_WHITE);     /* paint display area white */
        !           148:     if( fError)
        !           149:        WinDrawText( hpsCalc
        !           150:                   , -1
        !           151:                   , szErrorString
        !           152:                   , &rcl
        !           153:                   , CLR_BLACK
        !           154:                   , CLR_WHITE
        !           155:                   , DT_RIGHT | DT_VCENTER );
1.1       root      156:     else
1.1.1.2 ! root      157:        WinDrawText( hpsCalc
        !           158:                   , -1
        !           159:                   , szreg1
        !           160:                   , &rcl
        !           161:                   , CLR_BLACK
        !           162:                   , CLR_WHITE
        !           163:                   , DT_RIGHT | DT_VCENTER );
1.1       root      164: 
                    165:     if (fValueInMemory)                /* little black square shows mem use */
                    166:     {
1.1.1.2 ! root      167:        rcl.xLeft = (6 * sCharWidth);
        !           168:        rcl.yBottom = 1050 * sCharHeight / 100;
        !           169:        rcl.xRight = rcl.xLeft + (sCharWidth / 2);
        !           170:        rcl.yTop = rcl.yBottom + (sCharHeight / 2);
        !           171:        WinFillRect( hpsCalc, &rcl, CLR_BLACK);
1.1       root      172:     }
                    173: }
                    174: 
                    175: 
1.1.1.2 ! root      176: /******************************************************************************/
        !           177: /*  Display helpful info                                                     */
        !           178: /******************************************************************************/
        !           179: MPARAM CALLBACK
        !           180: AboutDlgProc( hwnd, msg, mp1, mp2)
1.1       root      181: 
1.1.1.2 ! root      182: HWND   hwnd;
1.1       root      183: USHORT msg;
                    184: MPARAM mp1;
                    185: MPARAM mp2;
                    186: {
                    187:     if (msg == WM_COMMAND)
                    188:     {
                    189:         WinDismissDlg(hwnd, TRUE);
                    190:        return(MPFROMSHORT(TRUE));
                    191:     }
1.1.1.2 ! root      192:     else return(WinDefDlgProc( hwnd, msg, mp1, mp2));
1.1       root      193: }
                    194: 
                    195: 
1.1.1.2 ! root      196: /******************************************************************************/
        !           197: /*  General initialization                                                   */
        !           198: /******************************************************************************/
        !           199: BOOL
        !           200: CalcInit()
1.1       root      201: {
1.1.1.2 ! root      202:     hab = WinInitialize( NULL);
1.1       root      203: 
                    204:     hmqCalc = WinCreateMsgQueue( hab, 0);
1.1.1.2 ! root      205:     if( !hmqCalc)
1.1       root      206:         return(FALSE);
                    207: 
1.1.1.2 ! root      208:     WinLoadString( NULL, NULL, 1, 30, (PSZ)szTitle);
        !           209:     WinLoadString( NULL, NULL, 2, 20, (PSZ)szErrorString);
        !           210:     WinLoadString( NULL, NULL, 3, 2, (PSZ)szPlusMinus);
        !           211: 
        !           212:     if (!WinRegisterClass( hab, szTitle, CalcWndProc, CS_SIZEREDRAW, 0))
        !           213:         return(FALSE);
1.1       root      214: 
1.1.1.2 ! root      215:     hptrFinger = WinLoadPointer( HWND_DESKTOP, (HMODULE)NULL, IDP_FINGER);
1.1       root      216: 
                    217:     InitCalc();                        /* arithmetic initialization */
                    218: 
                    219:     return(TRUE);
                    220: }
                    221: 
1.1.1.2 ! root      222: /******************************************************************************/
        !           223: /*  main procedure                                                           */
        !           224: /******************************************************************************/
        !           225: VOID cdecl
        !           226: main()
1.1       root      227: {
1.1.1.2 ! root      228:     QMSG  qmsg;
        !           229:     ULONG ulFCF;
1.1       root      230: 
                    231:     if (!CalcInit()) {                     /* general initialization */
1.1.1.2 ! root      232:        WinAlarm(HWND_DESKTOP, WA_ERROR);
1.1       root      233:         goto exit;
                    234:     }
                    235: 
                    236:     if (!PSInit()) {                       /* presentation spaces & bitmaps */
1.1.1.2 ! root      237:        WinAlarm(HWND_DESKTOP, WA_ERROR);
1.1       root      238:         goto exit;
                    239:     }
                    240: 
1.1.1.2 ! root      241:     ulFCF = FCF_STANDARD & ~(LONG)(FCF_SIZEBORDER | FCF_MAXBUTTON);
        !           242:     hwndCalcFrame = WinCreateStdWindow( HWND_DESKTOP
        !           243:                                      , WS_VISIBLE | FS_BORDER
        !           244:                                      , &ulFCF
        !           245:                                      , szTitle
        !           246:                                      , NULL
        !           247:                                      , 0L
        !           248:                                      , NULL
        !           249:                                      , IDR_CALC
        !           250:                                      , &hwndCalc);
        !           251: 
        !           252:     WinSetWindowPos( hwndCalcFrame
        !           253:                   , (HWND)NULL
        !           254:                   , 2
        !           255:                   , 2
        !           256:                   , CXCHARS * sCharWidth
        !           257:                   , CYCHARS * sCharHeight
        !           258:                             + (SHORT)WinQuerySysValue( HWND_DESKTOP
        !           259:                                                      , SV_CYTITLEBAR )
        !           260:                             + (SHORT)WinQuerySysValue( HWND_DESKTOP
        !           261:                                                      , SV_CYMENU )
        !           262:                   , SWP_MOVE | SWP_SIZE );
1.1       root      263: 
1.1.1.2 ! root      264:     while (WinGetMsg( hab, &qmsg, NULL, 0, 0))
        !           265:        WinDispatchMsg( hab, &qmsg);
1.1       root      266: 
                    267: exit:                                      /* clean up */
                    268:     if (hdcSqr)                            /* square-root bitmap */
                    269:     {
                    270:        GpiDestroyPS( hpsSqr);
                    271:        if (hbmSqr)
                    272:            GpiDeleteBitmap( hbmSqr);
                    273:     }
                    274: 
                    275:     if (hdcLocal)                          /* keypad button */
                    276:     {
                    277:        GpiDestroyPS( hpsLocal);
                    278:        if (hbmLocal)
                    279:            GpiDeleteBitmap( hbmLocal);
                    280:     }
                    281: 
                    282:     WinDestroyWindow(hwndCalcFrame);
                    283: 
                    284:     WinDestroyMsgQueue(hmqCalc);
                    285:     WinTerminate(hab);
                    286: 
                    287:     DosExit(EXIT_PROCESS, 0);              /* exit without error */
                    288: }
                    289: 
                    290: 
1.1.1.2 ! root      291: /******************************************************************************/
        !           292: /* Calc Window Procedure                                                     */
        !           293: /******************************************************************************/
        !           294: MRESULT CALLBACK
        !           295: CalcWndProc(hwnd, msg, mp1, mp2)
        !           296: 
        !           297: HWND   hwnd;
        !           298: USHORT msg;
        !           299: MPARAM mp1;
        !           300: MPARAM mp2;
        !           301: {
        !           302:     HPS     hps;
        !           303:     RECTL   rclPaint;
        !           304:     WPOINT  wpt;
        !           305:     BOOL    fClip;
        !           306:     USHORT  usFmtInfo;
        !           307:     RECTL   rcl;
        !           308:     SIZEL   sizl;
1.1       root      309: 
                    310:     switch (msg)
                    311:     {
                    312:     case WM_CREATE:
1.1.1.2 ! root      313:        hdcCalc = WinOpenWindowDC( hwnd);
        !           314:        WinQueryWindowRect( hwnd, &rcl);
        !           315:        sizl.cx = rcl.xRight - rcl.xLeft;
        !           316:        sizl.cy = rcl.yTop - rcl.yBottom;
        !           317:        hpsCalc = GpiCreatePS( hab
        !           318:                             , hdcCalc
        !           319:                             , &sizl
        !           320:                             , GPIA_ASSOC | PU_PELS );
1.1       root      321:         break;
                    322: 
                    323:     case WM_DESTROY:
                    324:         WinDestroyPointer(hptrFinger);
                    325:        GpiDestroyPS( hpsSqr);
                    326:        GpiDeleteBitmap( hbmSqr);
                    327:        GpiDestroyPS( hpsLocal);
                    328:        GpiDeleteBitmap( hbmLocal);
                    329:         break;
                    330: 
                    331:     case WM_INITMENU:
                    332:         fClip = FALSE;
1.1.1.2 ! root      333:        if (WinOpenClipbrd( hab))
1.1       root      334:         {
1.1.1.2 ! root      335:            fClip = WinQueryClipbrdFmtInfo( hab, CF_TEXT, &usFmtInfo);
        !           336:            WinCloseClipbrd( hab);
1.1       root      337:         }
                    338:        WinSendMsg((HWND)mp2, MM_SETITEMATTR,
                    339:                   (MPARAM) MAKELONG(CMD_PASTE, TRUE),
                    340:                   (MPARAM) MAKELONG(MIA_DISABLED, fClip ? 0 : MIA_DISABLED));
                    341:         break;
                    342: 
                    343:     case WM_PAINT:
                    344:        hps = WinBeginPaint(hwnd, NULL, &rclPaint);
                    345:        CalcPaint( hwnd, hps);                      /* re-draw calculator */
                    346:         WinEndPaint(hps);
                    347:         break;
                    348: 
                    349:     case WM_COMMAND:
                    350:        if (fError)
                    351:             break;
                    352:         switch(LOUSHORT(mp1))
                    353:         {
                    354:         case CMD_COPY:
                    355:            DataXCopy();                    /* copy to clipboard */
                    356:             break;
                    357:         case CMD_PASTE:
                    358:            DataXPaste();                   /* paste from clipboard */
                    359:             break;
                    360:         case CMD_EXIT:
1.1.1.2 ! root      361:            WinPostMsg( hwndCalcFrame, WM_QUIT, 0L, 0L);
1.1       root      362:             break;
                    363:         case CMD_ABOUT:
1.1.1.2 ! root      364:            WinDlgBox( HWND_DESKTOP
        !           365:                     , hwndCalcFrame
        !           366:                     , (PFNWP)AboutDlgProc
        !           367:                     , NULL
        !           368:                     , 1
        !           369:                     , (PSZ)NULL );
1.1       root      370:             break;
                    371:         }
                    372:         break;
                    373: 
                    374:     case WM_MOUSEMOVE:
1.1.1.2 ! root      375:        WinSetPointer( HWND_DESKTOP, hptrFinger);
1.1       root      376:         break;
                    377: 
                    378:     case WM_BUTTON1DOWN:
1.1.1.2 ! root      379:        wpt.x = LOUSHORT(mp1);
        !           380:        wpt.y = HIUSHORT(mp1);
        !           381:        ProcessKey( &wpt);
1.1       root      382:         goto dwp;
                    383:         break;
                    384: 
                    385:     case WM_CHAR:
                    386:        if (SHORT1FROMMP(mp1) & KC_KEYUP)
                    387:        {
1.1.1.2 ! root      388:            if (CHAR4FROMMP(mp1) == uchMScan)
1.1       root      389:                fMDown = FALSE;                 /* 'm' key went up */
                    390:        }
                    391:        else if (SHORT1FROMMP(mp1) & KC_CHAR)
                    392:         {
                    393:            if (InterpretChar(CHAR1FROMMP(mp2)))
                    394:                UpdateDisplay();
                    395:            else if ((CHAR1FROMMP(mp2)=='m') || (CHAR1FROMMP(mp2)=='M'))
                    396:            {
1.1.1.2 ! root      397:                uchMScan = CHAR4FROMMP(mp1);       /* save 'm' key scan code  */
        !           398:                fMDown = TRUE;                     /* 'm' key went down       */
1.1       root      399:            }
                    400:         }
                    401:         break;
                    402: 
                    403:     case WM_ACTIVATE:
                    404:         if (HIUSHORT(mp1))
1.1.1.2 ! root      405:            WinSetFocus( HWND_DESKTOP, hwndCalc);
1.1       root      406:        break;
                    407: 
                    408:     case WM_SETFOCUS:
                    409:        if ((HWNDFROMMP(mp1)==hwndCalc) && !mp2);
                    410:            fMDown = FALSE;                     /* since we are losing focus */
                    411:        break;
                    412: 
                    413: dwp:
                    414:     default:
                    415:         return(WinDefWindowProc(hwnd, msg, mp1, mp2));
                    416:         break;
                    417:     }
                    418:     return(0L);
                    419: }
                    420: 
                    421: 
1.1.1.2 ! root      422: /******************************************************************************/
        !           423: /*  translate & interpret keys (ie. locate in logical keyboard)              */
        !           424: /******************************************************************************/
        !           425: BOOL
        !           426: InterpretChar( ch)
1.1       root      427: 
1.1.1.2 ! root      428: CHAR ch;
1.1       root      429: {
                    430:     BOOL fDone;
1.1.1.2 ! root      431:     NPCH pchStep;
        !           432:     INT  i;
1.1       root      433: 
                    434:     fDone = FALSE;
1.1.1.2 ! root      435:     pchStep = achKeys;
1.1       root      436:     switch (ch)
                    437:     {
                    438:     case 'n':
                    439:        ch = szPlusMinus[0];
                    440:         break;
                    441:     case 27:                        /* xlate Escape into 'c' */
                    442:         ch = 'c';
                    443:         break;
                    444:     case '\r':                      /* xlate Enter into '=' */
                    445:         ch = '=';
                    446:         break;
                    447:     }
                    448: 
                    449:     if (fMDown)                    /* Do memory keys */
                    450:     {
                    451:         switch (ch)
                    452:         {
                    453:         case 'c':
                    454:         case 'C':
                    455:             ch = '\274';
                    456:             break;
                    457:         case 'r':
                    458:         case 'R':
                    459:             ch = '\273';
                    460:             break;
                    461:         case '+':
                    462:             ch = '\272';
                    463:             break;
                    464:         case '-':
                    465:             ch = '\271';
                    466:             break;
                    467:         }
                    468:     }
                    469: 
1.1.1.2 ! root      470:     while (!fDone && *pchStep)
1.1       root      471:     {
1.1.1.2 ! root      472:        if (*pchStep++ == ch)
1.1       root      473:            fDone = TRUE;               /* char found in logical keyboard */
                    474:     }
                    475:     if (fDone)
                    476:     {
1.1.1.2 ! root      477:        chLastKey = chCurrKey;
        !           478:        i = pchStep - achKeys - 1;
        !           479:        FlipKey( hpsCalc, i/6, i%6);
        !           480:        Evaluate( achKeys[i]);
1.1       root      481:     }
                    482:     return (fDone);
                    483: }
                    484: 
                    485: 
1.1.1.2 ! root      486: /******************************************************************************/
        !           487: /*  briefly reverse the shading on one of the keys                           */
        !           488: /******************************************************************************/
        !           489: VOID
        !           490: FlipKey( hps, iRow, iCol)
1.1       root      491: 
                    492: HPS hps;
1.1.1.2 ! root      493: INT iRow, iCol;
1.1       root      494: {
                    495:     RECTL rcl;
                    496: 
1.1.1.2 ! root      497:     rcl.xLeft = (iCol * 6 * sCharWidth) + (14 * sCharWidth / 10);
        !           498:     rcl.yBottom = (165 * sCharHeight / 100) + (2 * iRow * sCharHeight);
        !           499:     rcl.xRight = rcl.xLeft + (11 * sCharWidth / 3);
        !           500:     rcl.yTop = rcl.yBottom + (7 * sCharHeight / 4);
        !           501:     WinInvertRect( hps, &rcl);
        !           502:     DosSleep( 50L);
        !           503:     WinInvertRect( hps, &rcl);
1.1       root      504: }
                    505: 
                    506: 
1.1.1.2 ! root      507: /******************************************************************************/
        !           508: /*  compute whether a point is over a button and flash the button if so       */
        !           509: /******************************************************************************/
        !           510: BOOL
        !           511: FlashSqr( hps, pwpt)
1.1       root      512: 
1.1.1.2 ! root      513: HPS     hps;
        !           514: PWPOINT  pwpt;
1.1       root      515: {
1.1.1.2 ! root      516:     INT  iRow, iCol;
1.1       root      517:     BOOL fDone;
                    518: 
                    519:     /* find x range */
                    520:     fDone = FALSE;
1.1.1.2 ! root      521:     iCol = 0;
        !           522:     iRow = 3;
        !           523:     while (!fDone && iCol<6)
        !           524:     {
        !           525:        if (pwpt->x <   (iCol * 6 * sCharWidth)
        !           526:                       + (14 * sCharWidth / 10)
        !           527:                       + (11*sCharWidth/3)       )
1.1       root      528:         {
1.1.1.2 ! root      529:            if (pwpt->x > (iCol * 6 * sCharWidth) + (14 * sCharWidth / 10))
1.1       root      530:                 fDone = TRUE;
                    531:             else
                    532:                 return FALSE;
                    533:         }
                    534:         else
1.1.1.2 ! root      535:            iCol++;
1.1       root      536:     }
                    537:     if (!fDone)
                    538:         return FALSE;
                    539:     fDone = FALSE;
1.1.1.2 ! root      540:     while (!fDone && iRow >= 0)
1.1       root      541:     {
1.1.1.2 ! root      542:        if (pwpt->y > ((165 * sCharHeight / 100) + (2 * iRow * sCharHeight)))
1.1       root      543:         {
1.1.1.2 ! root      544:            if (pwpt->y <   (165 * sCharHeight / 100)
        !           545:                           + (2 * iRow * sCharHeight)
        !           546:                           + (7 * sCharHeight / 4)     )
1.1       root      547:                 fDone = TRUE;
                    548:             else
                    549:                 return FALSE;
                    550:         }
                    551:         else
1.1.1.2 ! root      552:            iRow--;
1.1       root      553:     }
                    554:     if (!fDone)
                    555:         return FALSE;
1.1.1.2 ! root      556:     pwpt->x = iCol;
        !           557:     pwpt->y = iRow;
        !           558:     FlipKey( hps, iRow, iCol);
1.1       root      559:     return TRUE;
                    560: }
                    561: 
                    562: 
1.1.1.2 ! root      563: /******************************************************************************/
        !           564: /*  which key is point on?                                                   */
        !           565: /******************************************************************************/
        !           566: CHAR
        !           567: Translate( pwpt)
1.1       root      568: 
1.1.1.2 ! root      569: PWPOINT pwpt;
1.1       root      570: {
1.1.1.2 ! root      571:     return( achKeys[ pwpt->y * 6 + pwpt->x]);
1.1       root      572: }
                    573: 
                    574: 
1.1.1.2 ! root      575: /******************************************************************************/
        !           576: /*  invoke flashing, point-to-key translation, and result-display update      */
        !           577: /******************************************************************************/
        !           578: VOID
        !           579: ProcessKey( pwpt)
1.1       root      580: 
1.1.1.2 ! root      581: PWPOINT pwpt;
1.1       root      582: {
1.1.1.2 ! root      583:     BOOL fFlashed;
1.1       root      584: 
1.1.1.2 ! root      585:     chLastKey = chCurrKey;
        !           586:     fFlashed = FlashSqr( hpsCalc, pwpt);
1.1       root      587: 
                    588:     if (fFlashed)
1.1.1.2 ! root      589:        Evaluate( (BYTE)Translate( pwpt));
1.1       root      590:     UpdateDisplay();
                    591: }
                    592: 
                    593: 
1.1.1.2 ! root      594: /******************************************************************************/
        !           595: /*  draw a blank key                                                         */
        !           596: /******************************************************************************/
        !           597: VOID
        !           598: FrameKey(hps, iRow, iCol)
1.1       root      599: 
                    600: HPS hps;
1.1.1.2 ! root      601: INT iRow, iCol;
1.1       root      602: {
                    603:     POINTL aptl[3];
                    604: 
1.1.1.2 ! root      605:     aptl[0].x = (iCol * 6 * sCharWidth) + (14 * sCharWidth / 10);
        !           606:     aptl[0].y = (165 * sCharHeight / 100) + (2 * iRow * sCharHeight);
        !           607:     aptl[1].x = (11 * sCharWidth / 3) + (aptl[0].x);
        !           608:     aptl[1].y = (7 * sCharHeight / 4) + (aptl[0].y);
1.1       root      609:     aptl[2].x = 0;
                    610:     aptl[2].y = 0;
                    611:     GpiBitBlt( hps, hpsLocal, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE);
                    612: }
                    613: 
                    614: 
1.1.1.2 ! root      615: /******************************************************************************/
        !           616: /*  draw the keys and fill in numbers                                        */
        !           617: /******************************************************************************/
        !           618: VOID
        !           619: DrawNumbers(hps)
1.1       root      620: 
                    621: HPS hps;
                    622: {
1.1.1.2 ! root      623:     INT iRow, iCol;
1.1       root      624: 
                    625:     /* Draw the keys and fill in the numbers we can */
1.1.1.2 ! root      626:     for (iRow = 0; iRow < 4; iRow++)
1.1       root      627:     {
1.1.1.2 ! root      628:        for (iCol = 0; iCol < 6; iCol++)
1.1       root      629:         {
1.1.1.2 ! root      630:            FrameKey( hps, iRow, iCol);
        !           631:            CalcTextOut( hps
        !           632:                       ,   (iCol * 6 * sCharWidth)
        !           633:                         + (WIDTHCONST * sCharWidth / 10)
        !           634:                       , (iRow + 1) * 2 * sCharHeight
        !           635:                       , (PSZ)(achDKeys + (iRow * 6) + iCol)
        !           636:                       , 1 );
1.1       root      637:         }
                    638:     }
                    639: }
                    640: 
                    641: 
1.1.1.2 ! root      642: /******************************************************************************/
        !           643: /*  redraw the whole calculator                                              */
        !           644: /******************************************************************************/
        !           645: VOID
        !           646: CalcPaint( hwnd, hps)
1.1       root      647: 
                    648: HWND hwnd;
1.1.1.2 ! root      649: HPS  hps;
1.1       root      650: {
1.1.1.2 ! root      651:     RECTL      rclDst;
1.1       root      652:     CHARBUNDLE cbnd;
1.1.1.2 ! root      653:     INT        iX, iY;
1.1       root      654: 
                    655:     WinQueryWindowRect( hwnd, &rclDst);
                    656:     WinFillRect( hps, &rclDst, CLR_GREEN);
                    657: 
                    658:     DrawNumbers(hps);
1.1.1.2 ! root      659:     CalcTextOut(hps, iX = (11 * sCharWidth / 5) + 1, iY = 2 * sCharHeight,
1.1       root      660:                (PSZ)"M-", 2);
1.1.1.2 ! root      661:     CalcTextOut(hps, iX, iY + 2 * sCharHeight, (PSZ)"M+", 2);
        !           662:     CalcTextOut(hps, iX, iY + 4 * sCharHeight, (PSZ)"MR", 2);
        !           663:     CalcTextOut(hps, iX, iY + 6 * sCharHeight, (PSZ)"MC", 2);
1.1       root      664: 
                    665:     /* Draw the minus of the plus/minus button */
                    666:     cbnd.usBackMixMode = FM_LEAVEALONE;
                    667:     GpiSetAttrs( hps, PRIM_CHAR, CBB_BACK_MIX_MODE, 0L, &cbnd);
1.1.1.2 ! root      668:     iX =  (3 * 6 * sCharWidth) + (WIDTHCONST * sCharWidth / 10);
        !           669:     CalcTextOut( hps, iX, iY + sCharHeight / 4, (PSZ)"_", 1);
1.1       root      670: 
                    671:     /* Draw the square root bitmap */
1.1.1.2 ! root      672:     rclDst.xLeft = 160 * sCharWidth / 5;
        !           673:     rclDst.yBottom = 31 * sCharHeight / 4;
        !           674:     rclDst.xRight = rclDst.xLeft + 2 * sCharWidth;
        !           675:     rclDst.yTop = rclDst.yBottom + (3 * sCharHeight / 2);
        !           676:     WinDrawBitmap( hps
        !           677:                 , hbmSqr
        !           678:                 , NULL
        !           679:                 , (PPOINTL)&rclDst
        !           680:                 , CLR_WHITE
        !           681:                 , CLR_BLACK
        !           682:                 , DBM_STRETCH );
1.1       root      683: 
                    684:     UpdateDisplay();
                    685: }
                    686: 
                    687: 
1.1.1.2 ! root      688: /******************************************************************************/
        !           689: /*  initialize the bitmaps for a blank key and for the square-root sign       */
        !           690: /******************************************************************************/
        !           691: BOOL
        !           692: PSInit()
        !           693: {
        !           694:     HPS             hps;
        !           695:     FONTMETRICS      fm;
        !           696:     POINTL          ptl;
        !           697:     SIZEL           sizl;
1.1       root      698:     BITMAPINFOHEADER bmp;
1.1.1.2 ! root      699:     POINTL          aptl[4];
        !           700:     LONG            alCaps[2];
1.1       root      701: 
1.1.1.2 ! root      702:     /**************************************************************************/
        !           703:     /* compute the units of horizontal and vertical distance based on font   */
        !           704:     /**************************************************************************/
1.1       root      705:     hps = WinGetPS( HWND_DESKTOP);
1.1.1.2 ! root      706:     GpiQueryFontMetrics( hps, (LONG)sizeof(FONTMETRICS), &fm);
        !           707:     sCharHeight = (SHORT)(fm.lEmHeight); /* avg height of uppercase character */
        !           708:     sCharWidth = (SHORT)(fm.lEmInc);    /* usually 'M' increment             */
1.1       root      709:     WinReleasePS( hps);
                    710: 
1.1.1.2 ! root      711:     /**************************************************************************/
        !           712:     /* prepare the square root bitmap                                        */
        !           713:     /**************************************************************************/
1.1       root      714:     hdcSqr = DevOpenDC( hab, OD_MEMORY, "*", 3L, (PDEVOPENDATA)&dop, NULL);
                    715:     if( !hdcSqr)
                    716:        return(FALSE);
                    717: 
                    718:     sizl.cx = sizl.cy = 0L;
1.1.1.2 ! root      719:     hpsSqr = GpiCreatePS( hab
        !           720:                        , hdcSqr
        !           721:                        , &sizl
        !           722:                        , PU_PELS | GPIT_MICRO | GPIA_ASSOC );
1.1       root      723:     hbmSqr = GpiLoadBitmap( hpsSqr, NULL, IDB_SQR, 0L, 0L);
                    724: 
1.1.1.2 ! root      725:     /**************************************************************************/
        !           726:     /* prepare the bitmap of a blank key                                     */
        !           727:     /**************************************************************************/
        !           728:     hdcLocal = DevOpenDC( hab, OD_MEMORY, "*", 3L, (PDEVOPENDATA)&dop, NULL);
        !           729:     if( !hdcLocal)
        !           730:        return(FALSE);
        !           731: 
        !           732:     sizl.cx = sizl.cy = 0L;
        !           733:     hpsLocal = GpiCreatePS( hab
        !           734:                          , hdcLocal
        !           735:                          , &sizl
        !           736:                          , PU_PELS | GPIT_MICRO | GPIA_ASSOC );
        !           737:     bmp.cbFix = 12;
        !           738:     bmp.cx = 11 * sCharWidth / 3;
        !           739:     bmp.cy = sCharHeight * 2;
1.1       root      740:     DevQueryCaps( hdcLocal, CAPS_COLOR_PLANES, 2L, alCaps);
                    741:     bmp.cPlanes = (USHORT)alCaps[0];
                    742:     bmp.cBitCount = (USHORT)alCaps[1];
                    743:     hbmLocal = GpiCreateBitmap( hpsLocal, &bmp, 0L, NULL, NULL);
                    744:     if( !hbmLocal )
                    745:        return(FALSE);
                    746:     GpiSetBitmap( hpsLocal, hbmLocal);
                    747: 
                    748:     aptl[0].x = aptl[0].y = 0;
1.1.1.2 ! root      749:     aptl[1].x = 11 * sCharWidth / 3;
        !           750:     aptl[1].y = 7 * sCharHeight / 4;
1.1       root      751:     aptl[2].x = aptl[2].y = 0;
                    752:     aptl[3].x = aptl[1].x;
                    753:     aptl[3].y = aptl[1].y;
1.1.1.2 ! root      754:     GpiSetColor( hpsLocal, CLR_GREEN);     /* match the background to client */
1.1       root      755:     GpiBitBlt( hpsLocal, NULL, 2L, aptl, ROP_PATCOPY, BBO_IGNORE);
                    756: 
1.1.1.2 ! root      757:     /* Draw the rounded rect */
1.1       root      758:     ptl.x = 0;
                    759:     ptl.y = 0;
                    760:     GpiSetCurrentPosition( hpsLocal, &ptl);
1.1.1.2 ! root      761:     ptl.x = (11 * sCharWidth / 3) - 1;
        !           762:     ptl.y = (7 * sCharHeight / 4) - 1;
        !           763:     GpiSetColor( hpsLocal, CLR_WHITE);     /* white interior                 */
        !           764:     GpiBox( hpsLocal
        !           765:          , DRO_FILL
        !           766:          , &ptl
        !           767:          , (LONG)sCharWidth
        !           768:          , (LONG)(sCharHeight / 2) );
1.1       root      769:     ptl.x = 0;
                    770:     ptl.y = 0;
                    771:     GpiSetCurrentPosition( hpsLocal, &ptl);
1.1.1.2 ! root      772:     ptl.x = (11 * sCharWidth / 3) - 1;
        !           773:     ptl.y = (7 * sCharHeight / 4) - 1;
        !           774:     GpiSetColor( hpsLocal, CLR_BLACK);     /* black border                   */
        !           775:     GpiBox( hpsLocal
        !           776:          , DRO_OUTLINE
        !           777:          , &ptl
        !           778:          , (LONG)sCharWidth
        !           779:          , (LONG)(sCharHeight / 2) );
1.1       root      780:     return( TRUE);
                    781: }

unix.superglobalmegacorp.com

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