Annotation of pmsdk/samples/linefrac/lfcmd.c, revision 1.1

1.1     ! root        1: /************************************************************************
        !             2: *
        !             3: *   lfcmd.c -- Subroutines for menu command processing for LineFractal.
        !             4: *
        !             5: *   Created by Microsoft Corporation, 1989
        !             6: *
        !             7: ************************************************************************/
        !             8: 
        !             9: #define INCL_WIN
        !            10: #define INCL_GPI
        !            11: #define INCL_BITMAPFILEFORMAT
        !            12: #define INCL_DOSSEMAPHORES
        !            13: #define INCL_DOSMEMMGR
        !            14: #define INCL_DOSPROCESS
        !            15: #include <os2.h>
        !            16: 
        !            17: #include <mt\stdio.h>
        !            18: #include <mt\stdlib.h>
        !            19: #include <mt\math.h>
        !            20: 
        !            21: #include "opendlg.h"
        !            22: 
        !            23: #define INCL_GLOBALS
        !            24: #define INCL_THREADS
        !            25: #include "linefrac.h"
        !            26: 
        !            27: #define INCL_LFCMD
        !            28: #define INCL_LFDLG
        !            29: #define INCL_LFMAIN
        !            30: #define INCL_LFTHREAD
        !            31: #define INCL_LFPS
        !            32: #define INCL_LFDRAW
        !            33: #define INCL_LFUTIL
        !            34: #define INCL_LFFILE
        !            35: #include "lffuncs.h"
        !            36: 
        !            37: 
        !            38: 
        !            39: 
        !            40: /************************************************************************
        !            41: *
        !            42: *   Macros
        !            43: *
        !            44: *   Helper macros for repetitious code.
        !            45: *
        !            46: ************************************************************************/
        !            47: 
        !            48: #define UPDATE_MENU_BOOL(var, val)                             \
        !            49:        {                                                       \
        !            50:            TOGGLE_BOOL((var));                                 \
        !            51:            TOGGLE_MENU_ITEM(global.hwndFrame, (val), (var));   \
        !            52:        }
        !            53: 
        !            54: #define UPDATE_MENU_LIST(var, val)                             \
        !            55:        {                                                       \
        !            56:            UNCHECK_MENU_ITEM(global.hwndFrame, (var));         \
        !            57:            (var) = (val);                                      \
        !            58:            CHECK_MENU_ITEM(global.hwndFrame, (var));           \
        !            59:        }
        !            60: 
        !            61: 
        !            62: 
        !            63: 
        !            64: /************************************************************************
        !            65: *
        !            66: *   Global Variables
        !            67: *
        !            68: *   global     Global data block.
        !            69: *   aulRops    Array of BitBlt rops available for pasting.
        !            70: *   aXform     Array of built-in transforms and default positioning
        !            71: *                and sizing information.
        !            72: *
        !            73: ************************************************************************/
        !            74: 
        !            75: extern GLOBALDATA global;
        !            76: extern XFORMDATA  aXform[];
        !            77: 
        !            78: ULONG aulRops[] =
        !            79: {
        !            80:       ROP_SRCCOPY,
        !            81:       ROP_SRCAND,
        !            82:       ROP_SRCPAINT,
        !            83:       ROP_SRCINVERT,
        !            84:     (~ROP_SRCCOPY)   & 0xFF,
        !            85:     (~ROP_SRCAND)    & 0xFF,
        !            86:     (~ROP_SRCPAINT)  & 0xFF,
        !            87:     (~ROP_SRCINVERT) & 0xFF
        !            88: };
        !            89: 
        !            90: char *pszAttrs = "Previous attributes not read yet.";
        !            91: 
        !            92: 
        !            93: 
        !            94: 
        !            95: /************************************************************************
        !            96: *
        !            97: *   LfCommand
        !            98: *
        !            99: *   Dispatches menu commands to the proper handlers.
        !           100: *
        !           101: ************************************************************************/
        !           102: 
        !           103: VOID
        !           104: LfCommand(hwnd, id)
        !           105: HWND hwnd;
        !           106: USHORT id;
        !           107: {
        !           108:     switch (id)
        !           109:     {
        !           110: 
        !           111:     /********************************************************************
        !           112:     *
        !           113:     *  File menu
        !           114:     *
        !           115:     ********************************************************************/
        !           116: 
        !           117:     case IDM_LOAD:
        !           118:     case IDM_SAVE:
        !           119:     case IDM_ABOUT:
        !           120:        LfFileMenu(hwnd, id);
        !           121:        break;
        !           122: 
        !           123:     /********************************************************************
        !           124:     *
        !           125:     *  Edit menu
        !           126:     *
        !           127:     ********************************************************************/
        !           128: 
        !           129:     case IDM_SELECT:
        !           130:     case IDM_SELECTALL:
        !           131:     case IDM_CUT:
        !           132:     case IDM_COPY:
        !           133:     case IDM_PASTE:
        !           134:     case IDM_USECLIPBRD:
        !           135:     case IDM_PASTES:
        !           136:     case IDM_PASTEDSA:
        !           137:     case IDM_PASTEDSO:
        !           138:     case IDM_PASTEDSX:
        !           139:     case IDM_PASTESN:
        !           140:     case IDM_PASTEDSAN:
        !           141:     case IDM_PASTEDSON:
        !           142:     case IDM_PASTEDSXN:
        !           143:        LfEditMenu(hwnd, id);
        !           144:        break;
        !           145: 
        !           146:     /********************************************************************
        !           147:     *
        !           148:     *  Thread menu
        !           149:     *
        !           150:     ********************************************************************/
        !           151: 
        !           152:     case IDM_DCPOSTSCRIPT:
        !           153:     case IDM_DCPROPRINTER:
        !           154:     case IDM_DCDIRECT:
        !           155:     case IDM_DCMEMORY:
        !           156:     case IDM_EDITTHREADPARAMS:
        !           157:     case IDM_THR0TOTOP:
        !           158:     case IDM_THR1TOTOP:
        !           159:     case IDM_THR2TOTOP:
        !           160:     case IDM_THR3TOTOP:
        !           161:     case IDM_THR4TOTOP:
        !           162:     case IDM_THR5TOTOP:
        !           163:     case IDM_THR6TOTOP:
        !           164:     case IDM_THR7TOTOP:
        !           165:     case IDM_THR8TOTOP:
        !           166:     case IDM_THR9TOTOP:
        !           167:     case IDM_KILLTOPTHREAD:
        !           168:     case IDM_KILLALLTHREADS:
        !           169:     case IDM_AUTOSWITCH:
        !           170:     case IDM_SWITCHDELAY:
        !           171:     case IDM_UPDATEMENUS:
        !           172:     case IDM_THREADINHERITANCE:
        !           173:        LfThreadMenu(hwnd, id);
        !           174:        break;
        !           175: 
        !           176:     /********************************************************************
        !           177:     *
        !           178:     *  Control menu
        !           179:     *
        !           180:     ********************************************************************/
        !           181: 
        !           182:     case IDM_CLEARBITMAP:
        !           183:     case IDM_COPYBITMAPTOSCREEN:
        !           184:     case IDM_SQUAREBITMAP:
        !           185:     case IDM_RESIZEBITMAPTOWINDOW:
        !           186:     case IDM_MOUSECHANGESRECURSION:
        !           187:     case IDM_ANIMATEPTR:
        !           188:     case IDM_PTRPREFERENCES:
        !           189:     case IDM_TIMERDELAY:
        !           190:        if (LfControlMenu(hwnd, id))
        !           191:            goto lfcmd_redraw;
        !           192:        break;
        !           193: 
        !           194:     /********************************************************************
        !           195:     *
        !           196:     *  Fractal menu
        !           197:     *
        !           198:     ********************************************************************/
        !           199: 
        !           200:     case IDM_SHARKTOOTH:
        !           201:     case IDM_SAWTOOTH:
        !           202:     case IDM_KOCH:
        !           203:     case IDM_SPACEFILLER:
        !           204:     case IDM_STOVE:
        !           205:     case IDM_SQUAREWAVE:
        !           206:     case IDM_HOURGLASS:
        !           207:     case IDM_FRACREDRAW:
        !           208:        if (LfFractalMenu(hwnd, id))
        !           209:            goto lfcmd_redraw;
        !           210:        break;
        !           211: 
        !           212:     /********************************************************************
        !           213:     *
        !           214:     *  Primitive menu
        !           215:     *
        !           216:     ********************************************************************/
        !           217: 
        !           218:     case IDM_POLYLINE:
        !           219:     case IDM_POLYFILLET:
        !           220:     case IDM_POLYSPLINE:
        !           221:     case IDM_POLYMARKER:
        !           222:     case IDM_PEANO:
        !           223:     case IDM_PRIMREDRAW:
        !           224:        if (LfPrimitiveMenu(hwnd, id))
        !           225:            goto lfcmd_redraw;
        !           226:        break;
        !           227: 
        !           228:     /********************************************************************
        !           229:     *
        !           230:     *  Attributes menu
        !           231:     *
        !           232:     ********************************************************************/
        !           233: 
        !           234:     case IDM_LINEATTRS:
        !           235:     case IDM_MARKERATTRS:
        !           236:     case IDM_AREAATTRS:
        !           237:     case IDM_IMAGEATTRS:
        !           238:     case IDM_MISCATTRS:
        !           239:     case IDM_DIMENSIONS:
        !           240:     case IDM_DRAGDIMS:
        !           241:     case IDM_ATTRREDRAW:
        !           242:        if (LfAttributesMenu(hwnd, id))
        !           243:            goto lfcmd_redraw;
        !           244:        break;
        !           245: 
        !           246:     /********************************************************************
        !           247:     *
        !           248:     *  Environment menu
        !           249:     *
        !           250:     ********************************************************************/
        !           251: 
        !           252:     case IDM_AUTORESIZE:
        !           253:     case IDM_AUTOSELECTDIMS:
        !           254:     case IDM_CLEARONREDRAW:
        !           255:     case IDM_AUTOSTARTREDRAW:
        !           256:     case IDM_COLLECTBOUNDS:
        !           257:        LfEnvironmentMenu(hwnd, id);
        !           258:        break;
        !           259: 
        !           260:     /********************************************************************
        !           261:     *
        !           262:     *  Control menu, continued.  These two commands dovetail
        !           263:     *  conveniently,  so they are placed out of sequence here.
        !           264:     *
        !           265:     ********************************************************************/
        !           266: 
        !           267: lfcmd_redraw:
        !           268:     case IDM_REDRAW:
        !           269:        DosSemClear(&(global.pThrTop)->lSemRedraw);
        !           270: 
        !           271:        /* Fall through to restart the drawing. */
        !           272: 
        !           273:     case IDM_ABORT:
        !           274:        global.pThrTop->fInterrupted = TRUE;
        !           275:        break;
        !           276:     }
        !           277: }
        !           278: 
        !           279: 
        !           280: 
        !           281: 
        !           282: /************************************************************************
        !           283: *
        !           284: *   LfFileMenu
        !           285: *
        !           286: *   These commands allow the loading and saving of bitmaps from threads
        !           287: *   with memory DC's.  The about box shows the version number, title,
        !           288: *   and author.
        !           289: *
        !           290: ************************************************************************/
        !           291: 
        !           292: VOID
        !           293: LfFileMenu(hwnd, id)
        !           294: HWND hwnd;
        !           295: USHORT id;
        !           296: {
        !           297:     switch (id)
        !           298:     {
        !           299:     case IDM_LOAD:
        !           300:        if (global.pThrTop->dcType == IDM_DCMEMORY)
        !           301:            LfReadFile(hwnd, global.pThrTop);
        !           302:        else
        !           303:            MyMessageBox(hwnd, "Cannot load bitmap into a\nnon-memory DC.");
        !           304:        break;
        !           305: 
        !           306:     case IDM_SAVE:
        !           307:        if (global.pThrTop->dcType == IDM_DCMEMORY)
        !           308:            LfWriteFile(hwnd, global.pThrTop);
        !           309:        else
        !           310:            MyMessageBox(hwnd, "Cannot save bitmap from a\nnon-memory DC.");
        !           311:        break;
        !           312: 
        !           313:     case IDM_ABOUT:
        !           314:        WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)AboutDlg, NULL,
        !           315:                       IDR_ABOUTDLG, NULL );
        !           316:        break;
        !           317:     }
        !           318: }
        !           319: 
        !           320: 
        !           321: 
        !           322: 
        !           323: /************************************************************************
        !           324: *
        !           325: *   LfEditMenu
        !           326: *
        !           327: *   These commands allow for cutting, copying, and pasting of rectangles
        !           328: *   of bits.  The user can drag a rectangle or select the entire surface.
        !           329: *   The GpiBitBlt rop to use when pasting can be any of those listed.
        !           330: *   The user can specify that the system clipboard be used for storing
        !           331: *   the cut or copied bits, or that a private bitmap be used.
        !           332: *
        !           333: ************************************************************************/
        !           334: 
        !           335: VOID
        !           336: LfEditMenu(hwnd, id)
        !           337: HWND hwnd;
        !           338: USHORT id;
        !           339: {
        !           340:     switch (id)
        !           341:     {
        !           342:     case IDM_SELECT:
        !           343:        global.fSelecting = TRUE;
        !           344:        break;
        !           345: 
        !           346:     case IDM_SELECTALL:
        !           347:        LfSelectAll(hwnd);
        !           348:        break;
        !           349: 
        !           350:     case IDM_CUT:
        !           351:        if (global.fShowSelectRc)
        !           352:            LfCut(hwnd);
        !           353:        break;
        !           354: 
        !           355:     case IDM_COPY:
        !           356:        if (global.fShowSelectRc)
        !           357:            LfCopy(hwnd);
        !           358:        break;
        !           359: 
        !           360:     case IDM_PASTE:
        !           361:        if (global.fHaveSelectRc)
        !           362:        {
        !           363:            HPS hps;
        !           364: 
        !           365:            global.fPasting = TRUE;
        !           366:            if (global.fShowSelectRc && global.fTempSelect)
        !           367:            {
        !           368:                hps = WinGetPS(hwnd);
        !           369:                LfShowSelectRc(hps, &global.rclSelect);
        !           370:                WinReleasePS(hps);
        !           371:                global.fShowSelectRc = FALSE;
        !           372:                global.fTempSelect = FALSE;
        !           373:            }
        !           374:            if (!global.fShowSelectRc)
        !           375:            {
        !           376:                global.fShowSelectRc = TRUE;
        !           377:                hps = WinGetPS(hwnd);
        !           378:                LfShowSelectRc(hps, &global.rclCutCopy);
        !           379:                WinReleasePS(hps);
        !           380:            }
        !           381:        }
        !           382:        break;
        !           383: 
        !           384:     case IDM_USECLIPBRD:
        !           385:        UPDATE_MENU_BOOL(global.fUseClipbrd, IDM_USECLIPBRD);
        !           386:        break;
        !           387: 
        !           388:     /********************************************************************/
        !           389: 
        !           390:     case IDM_PASTES:
        !           391:     case IDM_PASTEDSA:
        !           392:     case IDM_PASTEDSO:
        !           393:     case IDM_PASTEDSX:
        !           394:     case IDM_PASTESN:
        !           395:     case IDM_PASTEDSAN:
        !           396:     case IDM_PASTEDSON:
        !           397:     case IDM_PASTEDSXN:
        !           398:        UNCHECK_MENU_ITEM(global.hwndFrame, global.usRopIndex+IDM_PASTES);
        !           399:        global.usRopIndex = id - IDM_PASTES;
        !           400:        CHECK_MENU_ITEM(global.hwndFrame, global.usRopIndex+IDM_PASTES);
        !           401:        global.ulPasteROP = aulRops[global.usRopIndex];
        !           402:        break;
        !           403:     }
        !           404: }
        !           405: 
        !           406: 
        !           407: 
        !           408: 
        !           409: /************************************************************************
        !           410: *
        !           411: *   LfThreadMenu
        !           412: *
        !           413: *   These commands allow the creation, viewing, editing, and deletion
        !           414: *   of up to 10 independently drawing threads. The middle group
        !           415: *   allow for simple animation by cycling through the threads at
        !           416: *   a user-selectable rate.  The updating of menus can be disabled to
        !           417: *   allow a faster thread-switch rate. The last group determine how
        !           418: *   new threads will look and act.  If inheritance is enabled, a new
        !           419: *   thread will be drawn with the attributes of the top thread, otherwise
        !           420: *   it will use the program's default values.
        !           421: *
        !           422: ************************************************************************/
        !           423: 
        !           424: VOID
        !           425: LfThreadMenu(hwnd, id)
        !           426: HWND hwnd;
        !           427: USHORT id;
        !           428: {
        !           429:     static char *szError1 = "Could not start thread.";
        !           430: 
        !           431:     switch (id)
        !           432:     {
        !           433:     case IDM_DCPOSTSCRIPT:
        !           434:     case IDM_DCPROPRINTER:
        !           435:        break;  /* not implemented yet */
        !           436: 
        !           437:     case IDM_DCDIRECT:
        !           438:        {
        !           439:            PTHR pthr;
        !           440: 
        !           441:            if (global.cThr < MAX_THREADS)
        !           442:                if (pthr = LfStartThread(IDM_DCDIRECT))
        !           443:                {
        !           444:                    (global.aThr)[global.cThr] = pthr;
        !           445:                    ++global.cThr;
        !           446:                    pthr->dcType = id;
        !           447: 
        !           448:                    LfBringThreadToTop(pthr);
        !           449:                    break;
        !           450:                }
        !           451:            MyMessageBox(hwnd, szError1);
        !           452:        }
        !           453:        break;
        !           454: 
        !           455:     case IDM_DCMEMORY:
        !           456: 
        !           457:        if (global.cThr < MAX_THREADS)
        !           458:        {
        !           459:            if (global.fFirstThread)
        !           460:            {
        !           461:                global.bm.cx        = (USHORT) (global.rcl.xRight - global.rcl.xLeft);
        !           462:                global.bm.cy        = (USHORT) (global.rcl.yTop   - global.rcl.yBottom);
        !           463:                global.bm.cPlanes   = 0;
        !           464:                global.bm.cBitCount = 0;
        !           465:                global.fFirstThread = FALSE;
        !           466:            }
        !           467:            else if (global.fThreadInheritance)
        !           468:            {
        !           469:                global.bm.cx        = (USHORT) global.pThrTop->rcl.xRight;
        !           470:                global.bm.cy        = (USHORT) global.pThrTop->rcl.yTop;
        !           471:                global.bm.cPlanes   = global.pThrTop->cPlanes;
        !           472:                global.bm.cBitCount = global.pThrTop->cBitCount;
        !           473:            }
        !           474:            else
        !           475:            {
        !           476:                global.bm.cx        = (USHORT) (global.rcl.xRight - global.rcl.xLeft);
        !           477:                global.bm.cy        = (USHORT) (global.rcl.yTop   - global.rcl.yBottom);
        !           478:                global.bm.cPlanes   = 0;
        !           479:                global.bm.cBitCount = 0;
        !           480:                if (!WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)BitmapParamsDlg, NULL,
        !           481:                               IDR_BITMAPPARAMSDLG, NULL ))
        !           482:                    break;      /* if user hit "cancel", don't start thread */
        !           483:            }
        !           484: 
        !           485:            {
        !           486:                PTHR pthr;
        !           487: 
        !           488:                if (pthr = LfStartThread(IDM_DCMEMORY))
        !           489:                {
        !           490:                    (global.aThr)[global.cThr] = pthr;
        !           491:                    ++global.cThr;
        !           492:                    pthr->dcType = id;
        !           493: 
        !           494:                    LfBringThreadToTop(pthr);
        !           495:                    break;
        !           496:                }
        !           497:            }
        !           498:        }
        !           499:        MyMessageBox(hwnd, szError1);
        !           500:        break;
        !           501: 
        !           502:     case IDM_EDITTHREADPARAMS:
        !           503:        if (global.pThrTop->dcType == IDM_DCMEMORY)
        !           504:        {
        !           505:            USHORT cxT, cyT, cpT, cbT;
        !           506: 
        !           507:            cxT = global.bm.cx        = (USHORT) global.pThrTop->rcl.xRight;
        !           508:            cyT = global.bm.cy        = (USHORT) global.pThrTop->rcl.yTop;
        !           509:            cpT = global.bm.cPlanes   = global.pThrTop->cPlanes;
        !           510:            cbT = global.bm.cBitCount = global.pThrTop->cBitCount;
        !           511: 
        !           512:            if (WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)BitmapParamsDlg, NULL,
        !           513:                           IDR_BITMAPPARAMSDLG, NULL ))
        !           514:                if ((cxT != global.bm.cx)      ||
        !           515:                    (cyT != global.bm.cy)      ||
        !           516:                    (cpT != global.bm.cPlanes) ||
        !           517:                    (cbT != global.bm.cBitCount))
        !           518:                    LfResizePS(global.pThrTop);
        !           519:        }
        !           520:        else
        !           521:            MyMessageBox(hwnd, "No editable DC parameters.");
        !           522:        break;
        !           523: 
        !           524:     case IDM_THR0TOTOP:
        !           525:     case IDM_THR1TOTOP:
        !           526:     case IDM_THR2TOTOP:
        !           527:     case IDM_THR3TOTOP:
        !           528:     case IDM_THR4TOTOP:
        !           529:     case IDM_THR5TOTOP:
        !           530:     case IDM_THR6TOTOP:
        !           531:     case IDM_THR7TOTOP:
        !           532:     case IDM_THR8TOTOP:
        !           533:     case IDM_THR9TOTOP:
        !           534:        {
        !           535:            USHORT i;
        !           536: 
        !           537:            if ((i = id-IDM_THR0TOTOP) < global.cThr)
        !           538:                LfBringThreadToTop(global.aThr[i]);
        !           539:        }
        !           540:        break;
        !           541: 
        !           542:     case IDM_KILLTOPTHREAD:
        !           543:        {
        !           544:            PTHR pthr;
        !           545: 
        !           546:            pthr = global.pThrTop;
        !           547:            if (global.cThr > 1)
        !           548:            {
        !           549:                SHORT i;
        !           550: 
        !           551:                if ((i = global.iThrTop+1) == global.cThr)
        !           552:                    i -= 2;
        !           553:                LfBringThreadToTop(global.aThr[i]);
        !           554:            }
        !           555:            else
        !           556:                LfBringThreadToTop(NULL);
        !           557: 
        !           558:            LfKillThread(pthr);
        !           559:            LfBringThreadToTop(global.pThrTop);     /* update global.iThrTop and menu */
        !           560: 
        !           561:            /* If no threads left, then start over. */
        !           562:            if (global.cThr == 0)
        !           563:            {
        !           564:                global.fFirstThread = TRUE;
        !           565:                WinSendMsg(hwnd, WM_COMMAND, (MPARAM)IDM_DCMEMORY, 0);
        !           566:            }
        !           567:        }
        !           568:        break;
        !           569: 
        !           570:     case IDM_KILLALLTHREADS:
        !           571:        {
        !           572:            SHORT i;
        !           573: 
        !           574:            /* Delete them all and start over. */
        !           575:            LfBringThreadToTop(NULL);
        !           576:            for (i = global.cThr-1; i >= 0; --i)
        !           577:                LfKillThread(global.aThr[i]);
        !           578:            global.fFirstThread = TRUE;
        !           579:            WinSendMsg(hwnd, WM_COMMAND, (MPARAM)IDM_DCMEMORY, 0);
        !           580:        }
        !           581:        break;
        !           582: 
        !           583:     /********************************************************************/
        !           584: 
        !           585:     case IDM_AUTOSWITCH:
        !           586:        UPDATE_MENU_BOOL(global.fAutoSwitch, IDM_AUTOSWITCH);
        !           587:        if (global.fAutoSwitch)
        !           588:            WinStartTimer(global.hab, global.hwnd, IDT_AUTOSWITCH, global.usSwitchDelay);
        !           589:        else
        !           590:            WinStopTimer(global.hab, global.hwnd, IDT_AUTOSWITCH);
        !           591:        break;
        !           592: 
        !           593:     case IDM_SWITCHDELAY:
        !           594:        WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)SwitchDelayDlg, NULL,
        !           595:                       IDR_SWITCHDELAYDLG, NULL );
        !           596:        break;
        !           597: 
        !           598:     case IDM_UPDATEMENUS:
        !           599:        UPDATE_MENU_BOOL(global.fUpdateMenusOnThreadSwitch, IDM_UPDATEMENUS);
        !           600:        break;
        !           601: 
        !           602:     /********************************************************************/
        !           603: 
        !           604:     case IDM_THREADINHERITANCE:
        !           605:        UPDATE_MENU_BOOL(global.fThreadInheritance, IDM_THREADINHERITANCE);
        !           606:        break;
        !           607: 
        !           608:     }
        !           609: }
        !           610: 
        !           611: 
        !           612: 
        !           613: 
        !           614: /************************************************************************
        !           615: *
        !           616: *   LfControlMenu
        !           617: *
        !           618: *   These commands cause global effects.  The top set cause immediate
        !           619: *   results.  The bottom set determine how the program reacts to
        !           620: *   certain events (mouse movement and button messages, timer messages).
        !           621: *
        !           622: ************************************************************************/
        !           623: 
        !           624: BOOL
        !           625: LfControlMenu(hwnd, id)
        !           626: HWND hwnd;
        !           627: USHORT id;
        !           628: {
        !           629:     BOOL fRedraw = FALSE;
        !           630: 
        !           631:     switch (id)
        !           632:     {
        !           633:     case IDM_CLEARBITMAP:
        !           634:        LfClearRect(global.pThrTop, NULL);
        !           635:        break;
        !           636: 
        !           637:     case IDM_COPYBITMAPTOSCREEN:
        !           638:        if (global.pThrTop->hps)
        !           639:            WinInvalidateRect(global.hwnd, &(global.pThrTop)->rcl, FALSE);
        !           640:        break;
        !           641: 
        !           642:     case IDM_SQUAREBITMAP:
        !           643:        LfSquareBitmap(hwnd);
        !           644:        break;
        !           645: 
        !           646:     case IDM_RESIZEBITMAPTOWINDOW:
        !           647:        LfResizeBitmapToWindow();
        !           648:        fRedraw = TRUE;
        !           649:        break;
        !           650: 
        !           651:     /********************************************************************/
        !           652: 
        !           653:     case IDM_MOUSECHANGESRECURSION:
        !           654:        UPDATE_MENU_BOOL(global.fMouseChangesRecursion, IDM_MOUSECHANGESRECURSION);
        !           655:        break;
        !           656: 
        !           657:     case IDM_ANIMATEPTR:
        !           658:        UPDATE_MENU_BOOL(global.fAnimatePtr, IDM_ANIMATEPTR);
        !           659:        if (global.fAnimatePtr)
        !           660:            global.usPtrIncr = 1;
        !           661:        else
        !           662:        {
        !           663:            global.usPtrIncr = 0;
        !           664:            global.usCurPtr  = global.usUserPtr;
        !           665:        }
        !           666:        break;
        !           667: 
        !           668:     case IDM_PTRPREFERENCES:
        !           669:        WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)PtrPreferencesDlg, NULL,
        !           670:                       IDR_PTRPREFERENCESDLG, NULL );
        !           671:        break;
        !           672: 
        !           673:     case IDM_TIMERDELAY:
        !           674:        WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)TimerDelayDlg, NULL,
        !           675:                       IDR_TIMERDELAYDLG, NULL );
        !           676:        break;
        !           677:     }
        !           678: 
        !           679:     return fRedraw;
        !           680: }
        !           681: 
        !           682: 
        !           683: 
        !           684: 
        !           685: /************************************************************************
        !           686: *
        !           687: *   LfFractalMenu
        !           688: *
        !           689: *   These commands select the fractal similarity transform, i.e. the
        !           690: *   basic fractal shape, for a thread.
        !           691: *
        !           692: ************************************************************************/
        !           693: 
        !           694: BOOL
        !           695: LfFractalMenu(hwnd, id)
        !           696: HWND hwnd;
        !           697: USHORT id;
        !           698: {
        !           699:     BOOL fRedraw = FALSE;
        !           700: 
        !           701:     switch (id)
        !           702:     {
        !           703:     case IDM_SHARKTOOTH:
        !           704:     case IDM_SAWTOOTH:
        !           705:     case IDM_KOCH:
        !           706:     case IDM_SPACEFILLER:
        !           707:     case IDM_STOVE:
        !           708:     case IDM_SQUAREWAVE:
        !           709:     case IDM_HOURGLASS:
        !           710:        LfSelectXform(hwnd, global.pThrTop, id);
        !           711:        if (global.pThrTop->fFracRedraw)
        !           712:            fRedraw = TRUE;
        !           713:        break;
        !           714: 
        !           715:     /********************************************************************/
        !           716: 
        !           717:     case IDM_FRACREDRAW:
        !           718:        UPDATE_MENU_BOOL(global.pThrTop->fFracRedraw, IDM_FRACREDRAW);
        !           719:        break;
        !           720:     }
        !           721: 
        !           722:     return fRedraw;
        !           723: }
        !           724: 
        !           725: 
        !           726: 
        !           727: 
        !           728: /************************************************************************
        !           729: *
        !           730: *   LfPrimitiveMenu
        !           731: *
        !           732: *   These commands select the drawing primitive used to output the
        !           733: *   fractal for a thread.
        !           734: *
        !           735: ************************************************************************/
        !           736: 
        !           737: BOOL
        !           738: LfPrimitiveMenu(hwnd, id)
        !           739: HWND hwnd;
        !           740: USHORT id;
        !           741: {
        !           742:     BOOL fRedraw = FALSE;
        !           743: 
        !           744:     switch (id)
        !           745:     {
        !           746:     case IDM_POLYLINE:
        !           747:     case IDM_POLYFILLET:
        !           748:     case IDM_POLYSPLINE:
        !           749:     case IDM_POLYMARKER:
        !           750:     case IDM_PEANO:
        !           751:        LfSelectPrim(hwnd, global.pThrTop, id);
        !           752:        if (global.pThrTop->fPrimRedraw)
        !           753:            fRedraw = TRUE;
        !           754:        break;
        !           755: 
        !           756:     /********************************************************************/
        !           757: 
        !           758:     case IDM_PRIMREDRAW:
        !           759:        UPDATE_MENU_BOOL(global.pThrTop->fPrimRedraw, IDM_PRIMREDRAW);
        !           760:        break;
        !           761:     }
        !           762: 
        !           763:     return fRedraw;
        !           764: }
        !           765: 
        !           766: 
        !           767: 
        !           768: 
        !           769: /************************************************************************
        !           770: *
        !           771: *   LfAttributesMenu
        !           772: *
        !           773: *   These commands allow the user to alter all the drawing attributes
        !           774: *   of a fractal (color, mix mode, marker symbol, etc.), as well as
        !           775: *   some fractal-related attributes such as width, height, offset,
        !           776: *   number of sides to polygonal frame, and rotation.  Each thread
        !           777: *   has an independent set of all these attributes.
        !           778: *
        !           779: ************************************************************************/
        !           780: 
        !           781: BOOL
        !           782: LfAttributesMenu(hwnd, id)
        !           783: HWND hwnd;
        !           784: USHORT id;
        !           785: {
        !           786:     BOOL fRedraw = FALSE;
        !           787: 
        !           788:     switch (id)
        !           789:     {
        !           790:     case IDM_LINEATTRS:
        !           791:        if (global.fUpdateAttrs && (global.flLineAttrs & LFA_LINEALL))
        !           792:            MyMessageBox(hwnd, pszAttrs);
        !           793:        if (WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)LineAttrsDlg, NULL,
        !           794:                       IDR_LINEATTRSDLG, NULL ))
        !           795:            fRedraw = TRUE;
        !           796:        break;
        !           797: 
        !           798:     case IDM_MARKERATTRS:
        !           799:        if (global.fUpdateAttrs && (global.flMarkerAttrs & LFA_MARKALL))
        !           800:            MyMessageBox(hwnd, pszAttrs);
        !           801:        if (WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)MarkerAttrsDlg, NULL,
        !           802:                       IDR_MARKERATTRSDLG, NULL ))
        !           803:            fRedraw = TRUE;
        !           804:        break;
        !           805: 
        !           806:     case IDM_AREAATTRS:
        !           807:        if (global.fUpdateAttrs && (global.flAreaAttrs & LFA_AREAALL))
        !           808:            MyMessageBox(hwnd, pszAttrs);
        !           809:        if (WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)AreaAttrsDlg, NULL,
        !           810:                       IDR_AREAATTRSDLG, NULL ))
        !           811:            fRedraw = TRUE;
        !           812:        break;
        !           813: 
        !           814:     case IDM_IMAGEATTRS:
        !           815:        if (global.fUpdateAttrs && (global.flImageAttrs & LFA_IMAGEALL))
        !           816:            MyMessageBox(hwnd, pszAttrs);
        !           817:        if (WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)ImageAttrsDlg, NULL,
        !           818:                       IDR_IMAGEATTRSDLG, NULL ))
        !           819:            fRedraw = TRUE;
        !           820:        break;
        !           821: 
        !           822:     case IDM_MISCATTRS:
        !           823:        if (global.fUpdateAttrs && (global.flMiscAttrs & (LFA_RECURSION |
        !           824:                LFA_CPTMAX | LFA_POLYGONSIDES | LFA_ROTATION)))
        !           825:            MyMessageBox(hwnd, pszAttrs);
        !           826:        if (WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)MiscAttrsDlg, NULL,
        !           827:                       IDR_MISCATTRSDLG, NULL ))
        !           828:            fRedraw = TRUE;
        !           829:        break;
        !           830: 
        !           831:     case IDM_DIMENSIONS:
        !           832:        if (global.fUpdateAttrs && (global.flMiscAttrs & (LFA_XOFF |
        !           833:                LFA_YOFF | LFA_XSCALE | LFA_YSCALE)))
        !           834:            MyMessageBox(hwnd, pszAttrs);
        !           835:        if (WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)DimensionsDlg, NULL,
        !           836:                       IDR_DIMENSIONSDLG, NULL ))
        !           837:            fRedraw = TRUE;
        !           838:        break;
        !           839: 
        !           840:     case IDM_DRAGDIMS:
        !           841:        global.fTracking = TRUE;
        !           842:        break;
        !           843: 
        !           844:     /********************************************************************/
        !           845: 
        !           846:     case IDM_ATTRREDRAW:
        !           847:        UPDATE_MENU_BOOL(global.pThrTop->fAttrRedraw, IDM_ATTRREDRAW);
        !           848:        break;
        !           849:     }
        !           850: 
        !           851:     if (fRedraw)
        !           852:        if (global.pThrTop->fAttrRedraw)
        !           853:            return TRUE;
        !           854:     return FALSE;
        !           855: }
        !           856: 
        !           857: 
        !           858: 
        !           859: 
        !           860: /************************************************************************
        !           861: *
        !           862: *   LfEnvironmentMenu
        !           863: *
        !           864: *   These commands alter the way a thread reacts to system and program
        !           865: *   events by toggling certain flags.  Each thread has its own
        !           866: *   environment flags.
        !           867: *
        !           868: ************************************************************************/
        !           869: 
        !           870: VOID
        !           871: LfEnvironmentMenu(hwnd, id)
        !           872: HWND hwnd;
        !           873: USHORT id;
        !           874: {
        !           875:     switch (id)
        !           876:     {
        !           877:     case IDM_AUTORESIZE:
        !           878:        UPDATE_MENU_BOOL(global.pThrTop->fAutoSizePS, IDM_AUTORESIZE);
        !           879:        break;
        !           880: 
        !           881:     case IDM_AUTOSELECTDIMS:
        !           882:        UPDATE_MENU_BOOL(global.pThrTop->fAutoSelectDims, IDM_AUTOSELECTDIMS);
        !           883:        break;
        !           884: 
        !           885:     case IDM_CLEARONREDRAW:
        !           886:        UPDATE_MENU_BOOL(global.pThrTop->fClearOnRedraw, IDM_CLEARONREDRAW);
        !           887:        break;
        !           888: 
        !           889:     case IDM_AUTOSTARTREDRAW:
        !           890:        UPDATE_MENU_BOOL(global.pThrTop->fAutoStartRedraw, IDM_AUTOSTARTREDRAW);
        !           891:        if (global.pThrTop->fAutoStartRedraw)
        !           892:            LfStartRedrawTimer();
        !           893:        break;
        !           894: 
        !           895:     case IDM_COLLECTBOUNDS:
        !           896:        UPDATE_MENU_BOOL(global.pThrTop->fCollectBounds, IDM_COLLECTBOUNDS);
        !           897:        break;
        !           898: 
        !           899:     }
        !           900: 
        !           901:     hwnd;      /* this prevents an "unused variable" warning message */
        !           902: }
        !           903: 
        !           904: 
        !           905: 
        !           906: 
        !           907: /************************************************************************
        !           908: *
        !           909: *   LfSelectDimension
        !           910: *
        !           911: *   Set the dimensions of the next fractal by dragging a rectangle
        !           912: *   on the screen.
        !           913: *
        !           914: ************************************************************************/
        !           915: 
        !           916: VOID
        !           917: LfSelectDimension(hwnd, pt)
        !           918: HWND hwnd;
        !           919: POINTS pt;
        !           920: {
        !           921:     TRACKINFO ti;
        !           922:     LONG lXExt, lYExt;
        !           923: 
        !           924: 
        !           925:     WinSendMsg(global.hwndFrame, WM_QUERYTRACKINFO, (MPARAM)TF_MOVE, (MPARAM)&ti);
        !           926: 
        !           927:     ti.cxBorder   = 1;
        !           928:     ti.cyBorder   = 1;
        !           929:     ti.rclTrack.xLeft  = (LONG)pt.x;
        !           930:     ti.rclTrack.yBottom = (LONG)pt.y;
        !           931:     ti.rclTrack.xRight = (LONG)pt.x;
        !           932:     ti.rclTrack.yTop   = (LONG)pt.y;
        !           933:     ti.fs = TF_RIGHT | TF_TOP;
        !           934:     ti.ptlMinTrackSize.x = 1L;
        !           935:     ti.ptlMinTrackSize.y = 1L;
        !           936: 
        !           937:     if (WinTrackRect(hwnd, NULL, &ti))
        !           938:     {
        !           939:        lXExt = (global.pThrTop->rcl).xRight - (global.pThrTop->rcl).xLeft;
        !           940:        lYExt = (global.pThrTop->rcl).yTop   - (global.pThrTop->rcl).yBottom;
        !           941: 
        !           942:        global.dblXScale = (double)(ti.rclTrack.xRight - ti.rclTrack.xLeft)   / (double)lXExt;
        !           943:        global.dblYScale = (double)(ti.rclTrack.yTop   - ti.rclTrack.yBottom) / (double)lYExt;
        !           944:        global.dblXOff   = (double) ti.rclTrack.xLeft   / (double)lXExt;
        !           945:        global.dblYOff   = (double) ti.rclTrack.yBottom / (double)lYExt;
        !           946: 
        !           947:        global.flMiscAttrs |= LFA_XSCALE | LFA_YSCALE | LFA_XOFF | LFA_YOFF;
        !           948: 
        !           949:        global.pThrTop->fUpdateAttrs = TRUE;
        !           950:        global.fUpdateAttrs          = TRUE;
        !           951:     }
        !           952: }
        !           953: 
        !           954: 
        !           955: 
        !           956: 
        !           957: /************************************************************************
        !           958: *
        !           959: *   LfSquareBitmap
        !           960: *
        !           961: *   Resize the window horizontally to so that the client area is a
        !           962: *   square.
        !           963: *
        !           964: ************************************************************************/
        !           965: 
        !           966: VOID
        !           967: LfSquareBitmap(hwnd)
        !           968: HWND hwnd;
        !           969: {
        !           970:     SWP swp;
        !           971:     HWND hwndDesk;
        !           972:     RECTL rcl;
        !           973: 
        !           974:     if (hwnd == global.hwnd)
        !           975:        if (hwndDesk = WinQueryDesktopWindow(global.hab, NULL))
        !           976:            if (WinQueryWindowPos(global.hwndFrame, (PSWP)&swp))
        !           977:            {
        !           978:                rcl.xLeft   = 0L;
        !           979:                rcl.yBottom = 0L;
        !           980:                rcl.xRight  = swp.cx;
        !           981:                rcl.yTop    = swp.cy;
        !           982:                if (WinCalcFrameRect(global.hwndFrame, &rcl, TRUE))
        !           983:                {
        !           984:                    rcl.xRight  = (SHORT)((LONG)rcl.yTop   *
        !           985:                                  global.pThrTop->AspectRatio.lHorz /
        !           986:                                  global.pThrTop->AspectRatio.lVert);
        !           987: 
        !           988:                    if (WinCalcFrameRect(global.hwndFrame, &rcl, FALSE))
        !           989:                        WinSetWindowPos(global.hwndFrame, 0, swp.x, swp.y,
        !           990:                            (SHORT)rcl.xRight, (SHORT)rcl.yTop,
        !           991:                            SWP_SIZE);
        !           992:                }
        !           993:            }
        !           994: }
        !           995: 
        !           996: 
        !           997: 
        !           998: 
        !           999: /************************************************************************
        !          1000: *
        !          1001: *   LfResizeBitmapToWindow
        !          1002: *
        !          1003: *   Resize the bitmap to match the windows dimensions exactly.
        !          1004: *
        !          1005: ************************************************************************/
        !          1006: 
        !          1007: VOID
        !          1008: LfResizeBitmapToWindow()
        !          1009: {
        !          1010:     global.bm.cx = (USHORT) (global.rcl.xRight - global.rcl.xLeft);
        !          1011:     global.bm.cy = (USHORT) (global.rcl.yTop   - global.rcl.yBottom);
        !          1012:     global.bm.cPlanes  = global.pThrTop->cPlanes;
        !          1013:     global.bm.cBitCount = global.pThrTop->cBitCount;
        !          1014: 
        !          1015:     LfResizePS(global.pThrTop);
        !          1016: }
        !          1017: 
        !          1018: 
        !          1019: 
        !          1020: 
        !          1021: /************************************************************************
        !          1022: *
        !          1023: *   LfSelect
        !          1024: *
        !          1025: *   Select a rectangle to cut or copy to the clipboard.
        !          1026: *
        !          1027: ************************************************************************/
        !          1028: 
        !          1029: VOID
        !          1030: LfSelect(hwnd, pt)
        !          1031: HWND hwnd;
        !          1032: POINTS pt;
        !          1033: {
        !          1034:     HPS hps;
        !          1035:     TRACKINFO ti;
        !          1036:     PRECTL prcl;
        !          1037: 
        !          1038: 
        !          1039:     if (global.fShowSelectRc)
        !          1040:     {
        !          1041:        global.fShowSelectRc = FALSE;
        !          1042:        hps = WinGetPS(hwnd);
        !          1043:        if (global.fTempSelect)
        !          1044:        {
        !          1045:            prcl = &global.rclSelect;
        !          1046:            global.fTempSelect = FALSE;
        !          1047:        }
        !          1048:        else
        !          1049:            prcl = &global.rclCutCopy;
        !          1050:        LfShowSelectRc(hps, prcl);
        !          1051:        WinReleasePS(hps);
        !          1052:     }
        !          1053: 
        !          1054:     WinSendMsg(global.hwndFrame, WM_QUERYTRACKINFO, (MPARAM)TF_MOVE, (MPARAM)&ti);
        !          1055: 
        !          1056:     ti.cxBorder = 1;
        !          1057:     ti.cyBorder = 1;
        !          1058:     ti.rclTrack.xLeft  = (LONG)pt.x;
        !          1059:     ti.rclTrack.yBottom = (LONG)pt.y;
        !          1060:     ti.rclTrack.xRight = (LONG)pt.x;
        !          1061:     ti.rclTrack.yTop   = (LONG)pt.y;
        !          1062:     ti.fs = TF_RIGHT | TF_TOP;
        !          1063:     ti.ptlMinTrackSize.x = 1L;
        !          1064:     ti.ptlMinTrackSize.y = 1L;
        !          1065: 
        !          1066:     if (WinTrackRect(hwnd, NULL, &ti))
        !          1067:     {
        !          1068:        global.rclSelect.xLeft   = ti.rclTrack.xLeft;
        !          1069:        global.rclSelect.yBottom = ti.rclTrack.yBottom;
        !          1070:        global.rclSelect.xRight  = ti.rclTrack.xRight;
        !          1071:        global.rclSelect.yTop    = ti.rclTrack.yTop;
        !          1072: 
        !          1073:        global.fShowSelectRc = TRUE;
        !          1074:        global.fTempSelect   = TRUE;
        !          1075:        hps = WinGetPS(hwnd);
        !          1076:        LfShowSelectRc(hps, &global.rclSelect);
        !          1077:        WinReleasePS(hps);
        !          1078:     }
        !          1079: }
        !          1080: 
        !          1081: 
        !          1082: 
        !          1083: 
        !          1084: /************************************************************************
        !          1085: *
        !          1086: *   LfSelectAll
        !          1087: *
        !          1088: *   Select the entire surface to cut or copy to the clipboard.
        !          1089: *
        !          1090: ************************************************************************/
        !          1091: 
        !          1092: VOID
        !          1093: LfSelectAll(hwnd)
        !          1094: HWND hwnd;
        !          1095: {
        !          1096:     HPS hps;
        !          1097: 
        !          1098:     global.rclSelect = global.pThrTop->rcl;
        !          1099: 
        !          1100:     global.fShowSelectRc = TRUE;
        !          1101:     global.fTempSelect  = TRUE;
        !          1102:     hps = WinGetPS(hwnd);
        !          1103:     LfShowSelectRc(hps, &global.rclSelect);
        !          1104:     WinReleasePS(hps);
        !          1105: }
        !          1106: 
        !          1107: 
        !          1108: 
        !          1109: 
        !          1110: /************************************************************************
        !          1111: *
        !          1112: *   LfCut
        !          1113: *
        !          1114: *   Cuts the selected rectangle from the bitmap and puts it in the
        !          1115: *   clipboard.
        !          1116: *
        !          1117: ************************************************************************/
        !          1118: 
        !          1119: VOID
        !          1120: LfCut(hwnd)
        !          1121: HWND hwnd;
        !          1122: {
        !          1123:     if (LfCopy(hwnd))
        !          1124:        LfClearRect(global.pThrTop, &global.rclCutCopy);
        !          1125: }
        !          1126: 
        !          1127: 
        !          1128: 
        !          1129: 
        !          1130: /************************************************************************
        !          1131: *
        !          1132: *   LfCopy
        !          1133: *
        !          1134: *   Copies the selected rectangle from the bitmap the clipboard.
        !          1135: *
        !          1136: ************************************************************************/
        !          1137: 
        !          1138: BOOL
        !          1139: LfCopy(hwnd)
        !          1140: HWND hwnd;
        !          1141: {
        !          1142:     HPS hps;
        !          1143:     PRECTL prcl;
        !          1144:     SIZEL size;
        !          1145:     BITMAPINFOHEADER bminfo;
        !          1146:     POINTL  aptl[4];
        !          1147: 
        !          1148: 
        !          1149: 
        !          1150:     global.fShowSelectRc = FALSE;
        !          1151:     hps = WinGetPS(hwnd);
        !          1152:     if (global.fTempSelect)
        !          1153:     {
        !          1154:        prcl = &global.rclSelect;
        !          1155:        global.fTempSelect = FALSE;
        !          1156:     }
        !          1157:     else
        !          1158:        prcl = &global.rclCutCopy;
        !          1159:     LfShowSelectRc(hps, prcl);
        !          1160:     WinReleasePS(hps);
        !          1161: 
        !          1162:     if (global.fUseClipbrd)
        !          1163:     {
        !          1164:        if (WinOpenClipbrd(global.hab))
        !          1165:        {
        !          1166:            global.fHaveSelectRc = TRUE;
        !          1167:            global.rclCutCopy.xLeft   = global.rclSelect.xLeft;
        !          1168:            global.rclCutCopy.yBottom = global.rclSelect.yBottom;
        !          1169:            global.rclCutCopy.xRight  = global.rclSelect.xRight;
        !          1170:            global.rclCutCopy.yTop    = global.rclSelect.yTop;
        !          1171: 
        !          1172:            /* copy bits here */
        !          1173: 
        !          1174:            WinCloseClipbrd(global.hab);
        !          1175: 
        !          1176:            return TRUE;
        !          1177:        }
        !          1178:     }
        !          1179:     else
        !          1180:     {
        !          1181:        global.fHaveSelectRc = TRUE;
        !          1182:        global.rclCutCopy.xLeft   = global.rclSelect.xLeft;
        !          1183:        global.rclCutCopy.yBottom = global.rclSelect.yBottom;
        !          1184:        global.rclCutCopy.xRight  = global.rclSelect.xRight;
        !          1185:        global.rclCutCopy.yTop    = global.rclSelect.yTop;
        !          1186: 
        !          1187:        if (global.fHaveCutCopyDC)
        !          1188:        {
        !          1189:            GpiSetBitmap(global.CutCopyPS, NULL);
        !          1190:            GpiDeleteBitmap(global.CutCopyBM);
        !          1191:            GpiDestroyPS(global.CutCopyPS);
        !          1192:            DevCloseDC(global.CutCopyDC);
        !          1193:            global.fHaveCutCopyDC = FALSE;
        !          1194:        }
        !          1195: 
        !          1196:        global.CutCopyDC = DevOpenDC(global.hab, OD_MEMORY, "*", 0L, NULL, NULL);
        !          1197:        if (!global.CutCopyDC)
        !          1198:            return FALSE;
        !          1199: 
        !          1200:        size.cx = 0L;
        !          1201:        size.cy = 0L;
        !          1202:        global.CutCopyPS = GpiCreatePS(global.hab, global.CutCopyDC, &size,
        !          1203:                                 PU_PELS|GPIT_MICRO|GPIA_ASSOC);
        !          1204:        if (!global.CutCopyPS)
        !          1205:            goto lfc_error_close_dc;
        !          1206: 
        !          1207: 
        !          1208:        bminfo.cbFix = sizeof(BITMAPINFOHEADER);
        !          1209:        bminfo.cx = (USHORT) (global.rclCutCopy.xRight - global.rclCutCopy.xLeft);
        !          1210:        bminfo.cy = (USHORT) (global.rclCutCopy.yTop   - global.rclCutCopy.yBottom);
        !          1211:        bminfo.cPlanes   = global.pThrTop->cPlanes;
        !          1212:        bminfo.cBitCount = global.pThrTop->cBitCount;
        !          1213:        global.CutCopyBM = GpiCreateBitmap(global.CutCopyPS, &bminfo, 0L, 0L, 0L);
        !          1214:        if (!global.CutCopyBM)
        !          1215:            goto lfc_error_destroy_ps;
        !          1216:        GpiSetBitmap(global.CutCopyPS, global.CutCopyBM);
        !          1217: 
        !          1218:        aptl[0].x = 0L;
        !          1219:        aptl[0].y = 0L;
        !          1220:        aptl[1].x = global.rclCutCopy.xRight - global.rclCutCopy.xLeft;
        !          1221:        aptl[1].y = global.rclCutCopy.yTop   - global.rclCutCopy.yBottom;
        !          1222:        aptl[2].x = global.rclCutCopy.xLeft;
        !          1223:        aptl[2].y = global.rclCutCopy.yBottom;
        !          1224: 
        !          1225:        GpiBitBlt(global.CutCopyPS, global.pThrTop->hps, 3L, aptl, ROP_SRCCOPY, NULL);
        !          1226: 
        !          1227:        global.fHaveCutCopyDC = TRUE;
        !          1228:        return TRUE;
        !          1229: 
        !          1230: 
        !          1231: lfc_error_destroy_ps:
        !          1232:        GpiDestroyPS(global.CutCopyPS);
        !          1233: lfc_error_close_dc:
        !          1234:        DevCloseDC(global.CutCopyDC);
        !          1235:        return FALSE;
        !          1236:     }
        !          1237: 
        !          1238:     return FALSE;
        !          1239: }
        !          1240: 
        !          1241: 
        !          1242: 
        !          1243: 
        !          1244: /************************************************************************
        !          1245: *
        !          1246: *   LfPaste
        !          1247: *
        !          1248: *   Pastes the selected rectangle from the clipboard to the bitmap.
        !          1249: *   Hides the selection rectangle before calling WinTrackRect.
        !          1250: *
        !          1251: ************************************************************************/
        !          1252: 
        !          1253: VOID
        !          1254: LfPaste(hwnd)
        !          1255: HWND hwnd;
        !          1256: {
        !          1257:     HPS hps;
        !          1258:     PRECTL prcl;
        !          1259:     TRACKINFO ti;
        !          1260:     POINTL    aptl[4];
        !          1261: 
        !          1262: 
        !          1263:     if (global.fShowSelectRc)
        !          1264:     {
        !          1265:        global.fShowSelectRc = FALSE;
        !          1266:        hps = WinGetPS(hwnd);
        !          1267:        if (global.fTempSelect)
        !          1268:        {
        !          1269:            prcl = &global.rclSelect;
        !          1270:            global.fTempSelect = FALSE;
        !          1271:        }
        !          1272:        else
        !          1273:            prcl = &global.rclCutCopy;
        !          1274:        LfShowSelectRc(hps, prcl);
        !          1275:        WinReleasePS(hps);
        !          1276:     }
        !          1277: 
        !          1278:     WinSendMsg(global.hwndFrame, WM_QUERYTRACKINFO, (MPARAM)TF_MOVE, (MPARAM)&ti);
        !          1279: 
        !          1280:     ti.cxBorder = 1;
        !          1281:     ti.cyBorder = 1;
        !          1282:     ti.rclTrack.xLeft  = global.rclCutCopy.xLeft;
        !          1283:     ti.rclTrack.yBottom = global.rclCutCopy.yBottom;
        !          1284:     ti.rclTrack.xRight = global.rclCutCopy.xRight;
        !          1285:     ti.rclTrack.yTop   = global.rclCutCopy.yTop;
        !          1286:     ti.fs = TF_MOVE;
        !          1287:     ti.ptlMinTrackSize.x = 1L;
        !          1288:     ti.ptlMinTrackSize.y = 1L;
        !          1289: 
        !          1290:     if (WinTrackRect(hwnd, NULL, &ti))
        !          1291:     {
        !          1292:        if (global.fUseClipbrd)
        !          1293:        {
        !          1294:            if (WinOpenClipbrd(global.hab))
        !          1295:            {
        !          1296:                /* copy bits here */
        !          1297:                WinCloseClipbrd(global.hab);
        !          1298:            }
        !          1299:        }
        !          1300:        else
        !          1301:        {
        !          1302:            aptl[0].x = ti.rclTrack.xLeft;
        !          1303:            aptl[0].y = ti.rclTrack.yBottom;
        !          1304:            aptl[1].x = ti.rclTrack.xLeft   + (global.rclCutCopy.xRight - global.rclCutCopy.xLeft);
        !          1305:            aptl[1].y = ti.rclTrack.yBottom + (global.rclCutCopy.yTop   - global.rclCutCopy.yBottom);
        !          1306:            aptl[2].x = 0L;
        !          1307:            aptl[2].y = 0L;
        !          1308: 
        !          1309:            GpiBitBlt(global.pThrTop->hps, global.CutCopyPS, 3L, aptl, global.ulPasteROP, NULL);
        !          1310:            WinInvalidateRect(global.hwnd, &(ti.rclTrack), FALSE);
        !          1311:        }
        !          1312:     }
        !          1313: }
        !          1314: 
        !          1315: 
        !          1316: 
        !          1317: 
        !          1318: /************************************************************************
        !          1319: *
        !          1320: *   LfSelectXform
        !          1321: *
        !          1322: *   Select a similarity transform.
        !          1323: *
        !          1324: ************************************************************************/
        !          1325: 
        !          1326: VOID
        !          1327: LfSelectXform(hwnd, pthr, id)
        !          1328: HWND hwnd;
        !          1329: PTHR pthr;
        !          1330: USHORT id;
        !          1331: {
        !          1332:     BOOL fAlreadySaidIt = FALSE;
        !          1333: 
        !          1334: 
        !          1335:     if ((id != pthr->usCurXform) ||
        !          1336:        ((id != global.usCurXform) && global.fUpdateAttrs))
        !          1337:     {
        !          1338:        if (global.fUpdateAttrs && (global.flMiscAttrs & LFA_CURXFORM))
        !          1339:        {
        !          1340:            MyMessageBox(hwnd, pszAttrs);
        !          1341:            fAlreadySaidIt = TRUE;
        !          1342:        }
        !          1343: 
        !          1344:        global.flMiscAttrs |= LFA_CURXFORM;
        !          1345: 
        !          1346:        if (LfIsThreadTop(pthr))
        !          1347:        {
        !          1348:            if (fAlreadySaidIt)
        !          1349:                UNCHECK_MENU_ITEM(global.hwndFrame, global.usCurXform);
        !          1350:            else
        !          1351:                UNCHECK_MENU_ITEM(global.hwndFrame, pthr->usCurXform);
        !          1352:            global.usCurXform = id;
        !          1353:            CHECK_MENU_ITEM(global.hwndFrame, id);
        !          1354:        }
        !          1355:        else
        !          1356:            global.usCurXform = id;
        !          1357: 
        !          1358:        pthr->fUpdateAttrs  = TRUE;
        !          1359:        global.fUpdateAttrs = TRUE;
        !          1360:     }
        !          1361: 
        !          1362:     if (pthr->fAutoSelectDims)
        !          1363:     {
        !          1364:        if (global.fUpdateAttrs && (global.flMiscAttrs & (LFA_XSCALE |
        !          1365:                 LFA_YSCALE | LFA_XOFF | LFA_YOFF | LFA_POLYGONSIDES)))
        !          1366:            if (!fAlreadySaidIt)
        !          1367:                MyMessageBox(hwnd, pszAttrs);
        !          1368: 
        !          1369:        global.dblXScale      = aXform[id - IDM_SHARKTOOTH].xScale;
        !          1370:        global.dblYScale      = aXform[id - IDM_SHARKTOOTH].yScale;
        !          1371:        global.dblXOff        = aXform[id - IDM_SHARKTOOTH].xOff;
        !          1372:        global.dblYOff        = aXform[id - IDM_SHARKTOOTH].yOff;
        !          1373:        global.usPolygonSides = aXform[id - IDM_SHARKTOOTH].usSides;
        !          1374: 
        !          1375:        global.flMiscAttrs |= LFA_XSCALE | LFA_YSCALE | LFA_XOFF | LFA_YOFF |
        !          1376:                              LFA_POLYGONSIDES;
        !          1377:        pthr->fUpdateAttrs  = TRUE;
        !          1378:        global.fUpdateAttrs = TRUE;
        !          1379:     }
        !          1380: }
        !          1381: 
        !          1382: 
        !          1383: 
        !          1384: 
        !          1385: /************************************************************************
        !          1386: *
        !          1387: *   LfSelectPrim
        !          1388: *
        !          1389: *   Select a drawing primitive.
        !          1390: *
        !          1391: ************************************************************************/
        !          1392: 
        !          1393: VOID
        !          1394: LfSelectPrim(hwnd, pthr, id)
        !          1395: HWND hwnd;
        !          1396: PTHR pthr;
        !          1397: USHORT id;
        !          1398: {
        !          1399:     BOOL fAlreadySaidIt = FALSE;
        !          1400: 
        !          1401: 
        !          1402:     if ((id != pthr->usCurPrim) ||
        !          1403:        ((id != global.usCurPrim) && global.fUpdateAttrs))
        !          1404:     {
        !          1405:        if (global.fUpdateAttrs && (global.flMiscAttrs & LFA_CURPRIM))
        !          1406:        {
        !          1407:            MyMessageBox(hwnd, "Previous attributes not read yet.");
        !          1408:            fAlreadySaidIt = TRUE;
        !          1409:        }
        !          1410: 
        !          1411:        if (LfIsThreadTop(pthr))
        !          1412:        {
        !          1413:            if (fAlreadySaidIt)
        !          1414:                UNCHECK_MENU_ITEM(global.hwndFrame, global.usCurPrim);
        !          1415:            else
        !          1416:                UNCHECK_MENU_ITEM(global.hwndFrame, pthr->usCurPrim);
        !          1417:            global.usCurPrim = id;
        !          1418:            CHECK_MENU_ITEM(global.hwndFrame, id);
        !          1419:        }
        !          1420:        else
        !          1421:            global.usCurPrim = id;
        !          1422: 
        !          1423:        global.flMiscAttrs |= LFA_CURPRIM;
        !          1424:        pthr->fUpdateAttrs  = TRUE;
        !          1425:        global.fUpdateAttrs = TRUE;
        !          1426:     }
        !          1427: }

unix.superglobalmegacorp.com

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