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

1.1     ! root        1: /************************************************************************
        !             2: *
        !             3: *   lfthread.c -- Subroutines for thread management for LineFractal.
        !             4: *
        !             5: *   Created by Microsoft Corporation, 1989
        !             6: *
        !             7: ************************************************************************/
        !             8: 
        !             9: #define INCL_WIN
        !            10: #define INCL_GPI
        !            11: #define INCL_DOSSEMAPHORES
        !            12: #define INCL_DOSMEMMGR
        !            13: #define INCL_DOSPROCESS
        !            14: #define INCL_DOSERRORS
        !            15: #include <os2.h>
        !            16: 
        !            17: #include <mt\process.h>
        !            18: #include <mt\stddef.h>
        !            19: 
        !            20: #define INCL_GLOBALS
        !            21: #define INCL_THREADS
        !            22: #include "linefrac.h"
        !            23: 
        !            24: #define INCL_LFCMD
        !            25: #define INCL_LFMAIN
        !            26: #define INCL_LFPS
        !            27: #define INCL_LFUTIL
        !            28: #define INCL_LFTHREAD
        !            29: #define INCL_LFDRAW
        !            30: #include "lffuncs.h"
        !            31: 
        !            32: 
        !            33: 
        !            34: 
        !            35: /************************************************************************
        !            36: *
        !            37: *   Global Variables
        !            38: *
        !            39: ************************************************************************/
        !            40: 
        !            41: extern GLOBALDATA global;
        !            42: 
        !            43: 
        !            44: 
        !            45: 
        !            46: /************************************************************************
        !            47: *
        !            48: *   LfStartThread
        !            49: *
        !            50: *   Do everything needed to start up a background thread drawing
        !            51: *   fractals.
        !            52: *
        !            53: *   This includes:
        !            54: *
        !            55: *      Allocate space for thread structure.
        !            56: *      Initialize fields of thread structure.
        !            57: *      Create a presentation space for the thread.
        !            58: *      Create stack space for the thread.
        !            59: *      Set the thread's semaphore to block -- i.e. don't start
        !            60: *          drawing until everything is ready.
        !            61: *      Start the thread.
        !            62: *      Set the thread's priority to idle time.
        !            63: *
        !            64: ************************************************************************/
        !            65: 
        !            66: #define SIZE_ACCUM_STACK       2048
        !            67: 
        !            68: PTHR
        !            69: LfStartThread(dcType)
        !            70: USHORT dcType;
        !            71: {
        !            72:     PTHR pthr;
        !            73: 
        !            74: 
        !            75:     pthr = NULL;       /* zero out all 32 bits */
        !            76:     if (DosAllocSeg(sizeof(THR), ((PUSHORT)&pthr)+1, 0))
        !            77:        return NULL;
        !            78: 
        !            79:     pthr->dcType = dcType;
        !            80: 
        !            81:     LfPreInitThread(pthr);
        !            82:     if (LfCreatePS(pthr))
        !            83:     {
        !            84:        LfPostInitThread(pthr);
        !            85:        if (DosAllocSeg(SIZE_ACCUM_STACK, &pthr->selStack, 0))
        !            86:            goto lfst_exit;
        !            87: 
        !            88:        DosSemSet(&pthr->lSemRedraw);
        !            89:        pthr->tid = _beginthread(LineFractalThread, MAKEP(pthr->selStack, 0), SIZE_ACCUM_STACK, pthr);
        !            90:        if (pthr->tid == -1)
        !            91:        {
        !            92:            LfDeletePS(pthr);
        !            93:            goto lfst_exit;
        !            94:        }
        !            95:        DosSetPrty(PRTYS_THREAD, PRTYC_IDLETIME, 0, pthr->tid);
        !            96: 
        !            97:        LfSelectXform(global.hwnd, pthr, pthr->usCurXform);
        !            98:        DosSemClear(&pthr->lSemRedraw);
        !            99: 
        !           100:        if (!DevQueryCaps(pthr->hdc, CAPS_HORIZONTAL_RESOLUTION, 2L, (PLONG)&(pthr->AspectRatio)))
        !           101:        {
        !           102:            pthr->AspectRatio.lHorz = 1L;
        !           103:            pthr->AspectRatio.lVert = 1L;
        !           104:        }
        !           105: 
        !           106:        return pthr;
        !           107:     }
        !           108: lfst_exit:
        !           109:     DosFreeSeg(*(((PUSHORT)&pthr)+1));
        !           110:     return NULL;
        !           111: }
        !           112: 
        !           113: 
        !           114: 
        !           115: 
        !           116: /************************************************************************
        !           117: *
        !           118: *   LfPreInitThread
        !           119: *
        !           120: *   Initialize constant values in the thread structure needed from
        !           121: *   the moment the thread starts.  If thread inheritance is enabled,
        !           122: *   then copy as much as possible from the top thread, if there is
        !           123: *   one.
        !           124: *
        !           125: ************************************************************************/
        !           126: 
        !           127: VOID
        !           128: LfPreInitThread(pthr)
        !           129: PTHR pthr;
        !           130: {
        !           131:     pthr->hps          = NULL;
        !           132:     pthr->hdc          = NULL;
        !           133:     pthr->hbm          = NULL;
        !           134:     pthr->fTimeToDie   = FALSE;
        !           135:     pthr->fUpdateAttrs = FALSE;
        !           136:     pthr->fBusy        = FALSE;
        !           137:     pthr->pptl         = NULL;
        !           138:     pthr->cptl         = 0;
        !           139:     pthr->pmatlf       = NULL;
        !           140: 
        !           141:     if (global.fThreadInheritance && global.pThrTop)
        !           142:     {
        !           143:        pthr->cPlanes          = global.pThrTop->cPlanes          ;
        !           144:        pthr->cBitCount        = global.pThrTop->cBitCount        ;
        !           145: 
        !           146:        pthr->cxWCS            = global.pThrTop->cxWCS            ;
        !           147:        pthr->cyWCS            = global.pThrTop->cyWCS            ;
        !           148: 
        !           149:        pthr->fAutoSizePS      = global.pThrTop->fAutoSizePS      ;
        !           150:        pthr->fAutoSelectDims  = global.pThrTop->fAutoSelectDims  ;
        !           151:        pthr->fClearOnRedraw   = global.pThrTop->fClearOnRedraw   ;
        !           152:        pthr->fAutoStartRedraw = global.pThrTop->fAutoStartRedraw ;
        !           153:        pthr->fCollectBounds   = global.pThrTop->fCollectBounds   ;
        !           154: 
        !           155:        pthr->fFracRedraw      = global.pThrTop->fFracRedraw      ;
        !           156:        pthr->fPrimRedraw      = global.pThrTop->fPrimRedraw      ;
        !           157:        pthr->fAttrRedraw      = global.pThrTop->fAttrRedraw      ;
        !           158: 
        !           159:        pthr->lb               = global.pThrTop->lb               ;
        !           160:        pthr->flLineAttrs      = LFA_LINEALL                      ;
        !           161:        pthr->mb               = global.pThrTop->mb               ;
        !           162:        pthr->flMarkerAttrs    = LFA_MARKALL                      ;
        !           163:        pthr->ab               = global.pThrTop->ab               ;
        !           164:        pthr->flAreaAttrs      = LFA_AREAALL                      ;
        !           165:        pthr->ib               = global.pThrTop->ib               ;
        !           166:        pthr->flImageAttrs     = LFA_IMAGEALL                     ;
        !           167: 
        !           168:        pthr->usCurPrim        = global.pThrTop->usCurPrim        ;
        !           169:        pthr->usCurXform       = global.pThrTop->usCurXform       ;
        !           170:        pthr->usRecursion      = global.pThrTop->usRecursion      ;
        !           171:        pthr->usPolygonSides   = global.pThrTop->usPolygonSides   ;
        !           172:        pthr->cptMax           = global.pThrTop->cptMax           ;
        !           173:        pthr->dblXOff          = global.pThrTop->dblXOff          ;
        !           174:        pthr->dblYOff          = global.pThrTop->dblYOff          ;
        !           175:        pthr->dblXScale        = global.pThrTop->dblXScale        ;
        !           176:        pthr->dblYScale        = global.pThrTop->dblYScale        ;
        !           177:        pthr->dblRotation      = global.pThrTop->dblRotation      ;
        !           178:        pthr->flMiscAttrs      = LFA_MISCALL                      ;
        !           179:     }
        !           180:     else
        !           181:     {
        !           182:        pthr->cPlanes          = global.bm.cPlanes;
        !           183:        pthr->cBitCount        = global.bm.cBitCount;
        !           184: 
        !           185:        pthr->cxWCS            = 10000L;
        !           186:        pthr->cyWCS            = 10000L;
        !           187: 
        !           188:        pthr->fAutoSizePS      = TRUE;
        !           189:        pthr->fAutoSelectDims  = TRUE;
        !           190:        pthr->fClearOnRedraw   = TRUE;
        !           191:        pthr->fAutoStartRedraw = FALSE;
        !           192:        pthr->fCollectBounds   = TRUE;
        !           193: 
        !           194:        pthr->fFracRedraw      = TRUE;
        !           195:        pthr->fPrimRedraw      = TRUE;
        !           196:        pthr->fAttrRedraw      = TRUE;
        !           197: 
        !           198:        pthr->lb.lColor        = CLR_NEUTRAL;
        !           199:        pthr->lb.usMixMode     = FM_OVERPAINT;
        !           200:        pthr->lb.fxWidth       = LINEWIDTH_NORMAL;
        !           201: ;       pthr->lb.lGeomWidth    = 1L;
        !           202:        pthr->lb.usType        = LINETYPE_SOLID;
        !           203: ;       pthr->lb.usEnd         = LINEEND_FLAT;
        !           204: ;       pthr->lb.usJoin        = LINEJOIN_BEVEL;
        !           205:        pthr->flLineAttrs      = LFA_LINEALL;
        !           206: 
        !           207:        pthr->mb.lColor        = CLR_NEUTRAL;
        !           208:        pthr->mb.lBackColor    = CLR_BACKGROUND;
        !           209:        pthr->mb.usMixMode     = FM_OVERPAINT;
        !           210:        pthr->mb.usBackMixMode = BM_LEAVEALONE;
        !           211:        pthr->mb.usSet         = LCID_DEFAULT;
        !           212:        pthr->mb.usSymbol      = MARKSYM_DIAMOND;
        !           213: ;       pthr->mb.sizfxCell.cx  = 0L;
        !           214: ;       pthr->mb.sizfxCell.cy  = 0L;
        !           215:        pthr->flMarkerAttrs    = LFA_MARKALL;
        !           216: 
        !           217:        pthr->ab.lColor        = CLR_NEUTRAL;
        !           218:        pthr->ab.lBackColor    = CLR_BACKGROUND;
        !           219:        pthr->ab.usMixMode     = FM_OVERPAINT;
        !           220:        pthr->ab.usBackMixMode = BM_OVERPAINT;
        !           221:        pthr->ab.usSet         = LCID_DEFAULT;
        !           222:        pthr->ab.usSymbol      = PATSYM_NOSHADE;
        !           223: ;       pthr->ab.ptlRefPoint.x = 0L;
        !           224: ;       pthr->ab.ptlRefPoint.y = 0L;
        !           225:        pthr->flAreaAttrs      = LFA_AREAALL;
        !           226: 
        !           227:        pthr->ib.lColor        = CLR_NEUTRAL;
        !           228:        pthr->ib.lBackColor    = CLR_BACKGROUND;
        !           229:        pthr->ib.usMixMode     = FM_OVERPAINT;
        !           230:        pthr->ib.usBackMixMode = FM_OVERPAINT;
        !           231:        pthr->flImageAttrs     = LFA_IMAGEALL;
        !           232: 
        !           233:        pthr->usCurPrim        = IDM_POLYLINE;
        !           234:        pthr->usCurXform       = IDM_SAWTOOTH;
        !           235:        pthr->usRecursion      = 1;
        !           236:        pthr->usPolygonSides   = 3;
        !           237:        pthr->cptMax           = MAX_POINT_COUNT;
        !           238:        pthr->dblXOff          = 0.125;
        !           239:        pthr->dblYOff          = 0.5;
        !           240:        pthr->dblXScale        = 0.75;
        !           241:        pthr->dblYScale        = 0.75;
        !           242:        pthr->dblRotation      = 0.0;
        !           243:        pthr->flMiscAttrs      = LFA_MISCALL;
        !           244:     }
        !           245: 
        !           246: }
        !           247: 
        !           248: 
        !           249: 
        !           250: 
        !           251: /************************************************************************
        !           252: *
        !           253: *   LfPostInitThread
        !           254: *
        !           255: *   Initialize various values in the thread structure which required
        !           256: *   that a PS/DC/BM had been created.  If thread inheritance is enabled,
        !           257: *   then copy as much as possible from the top thread, if there is
        !           258: *   one.
        !           259: *
        !           260: ************************************************************************/
        !           261: 
        !           262: VOID
        !           263: LfPostInitThread(pthr)
        !           264: PTHR pthr;
        !           265: {
        !           266:     if (!(global.fThreadInheritance && global.pThrTop))
        !           267:     {
        !           268:        pthr->lb.lGeomWidth = GpiQueryLineWidthGeom(pthr->hps);
        !           269:        pthr->lb.usEnd      = (USHORT) GpiQueryLineEnd(pthr->hps);
        !           270:        pthr->lb.usJoin     = (USHORT) GpiQueryLineJoin(pthr->hps);
        !           271: 
        !           272:        DevQueryCaps(pthr->hdc, CAPS_MARKER_WIDTH,  1L, (PLONG)&(pthr->mb.sizfxCell.cx));
        !           273:        DevQueryCaps(pthr->hdc, CAPS_MARKER_HEIGHT, 1L, (PLONG)&(pthr->mb.sizfxCell.cy));
        !           274: 
        !           275:        GpiQueryPatternRefPoint(pthr->hps,&(pthr->ab.ptlRefPoint));
        !           276:     }
        !           277: }
        !           278: 
        !           279: 
        !           280: 
        !           281: 
        !           282: /************************************************************************
        !           283: *
        !           284: *   LfKillThread
        !           285: *
        !           286: *   Force the given thread to die and release its resources.
        !           287: *
        !           288: ************************************************************************/
        !           289: 
        !           290: VOID
        !           291: LfKillThread(pthr)
        !           292: PTHR pthr;
        !           293: {
        !           294:     int i, j;
        !           295: 
        !           296: 
        !           297:     /* This does not do anything if there aren't any threads. */
        !           298: 
        !           299:     if (global.cThr && pthr)
        !           300:     {
        !           301:        /****************************************************************
        !           302:        *  Tell the thread to die when it can.
        !           303:        *  If blocked on lSemRedraw, then it will recognize fTimeToDie
        !           304:        *  as soon as it's unblocked.  If it's currently drawing,
        !           305:        *  it will recognize fInterrupted, kick out of the recursion,
        !           306:        *  loop back up to check lSemRedraw, which will be clear, so
        !           307:        *  it'll do as already mentioned.  Set the priority to time-
        !           308:        *  critical to speed things up.
        !           309:        ****************************************************************/
        !           310: 
        !           311:        pthr->fTimeToDie   = TRUE;
        !           312:        pthr->fInterrupted = TRUE;
        !           313:        DosSetPrty(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, pthr->tid);
        !           314:        DosSemClear(&pthr->lSemRedraw);
        !           315: 
        !           316: 
        !           317:        /****************************************************************
        !           318:        *  Once it's decided it must die, it will clean up after
        !           319:        *  itself and exit quietly.  To detect when it has actually
        !           320:        *  exited, so that we can safely free up the stack, we will
        !           321:        *  loop asking for the thread's priority until an error occurs.
        !           322:        *  We will assume that an error implies the thread has exited.
        !           323:        ****************************************************************/
        !           324: 
        !           325:        {
        !           326:            USHORT usT;
        !           327:            USHORT usRet;
        !           328:            while (!(usRet = DosGetPrty(PRTYS_THREAD, &usT, pthr->tid)));
        !           329:            if (usRet != ERROR_INVALID_THREADID)
        !           330:            {
        !           331:                MyMessageBox(global.hwnd,
        !           332:                    "Cannot kill thread");
        !           333:                return;
        !           334:            }
        !           335:        }
        !           336: 
        !           337: 
        !           338:        /****************************************************************
        !           339:        *  Extract the given thread from the group. This is done
        !           340:        *  inside a critical section because the drawing threads
        !           341:        *  call LfIsThreadTop, which reads global.aThr.
        !           342:        ****************************************************************/
        !           343: 
        !           344:        i = 0;
        !           345:        while ((i < global.cThr) && (pthr != global.aThr[i]))
        !           346:            ++i;    /* if i == global.cThr we have a problem */
        !           347:        DosEnterCritSec();
        !           348:        for (j = i; j < global.cThr-1; ++j)
        !           349:            global.aThr[j] = global.aThr[j+1];
        !           350:        global.aThr[j] = NULL;  /* clear out all copies of pthr */
        !           351:        --global.cThr;
        !           352:        DosExitCritSec();
        !           353: 
        !           354: 
        !           355:        /****************************************************************
        !           356:        *  Free up resources allocated for the thread.
        !           357:        ****************************************************************/
        !           358: 
        !           359:        LfDeletePS(pthr);
        !           360:        DosFreeSeg(pthr->selStack);
        !           361:        DosFreeSeg(*(((PUSHORT)&pthr)+1));
        !           362:     }
        !           363: }
        !           364: 
        !           365: 
        !           366: 
        !           367: 
        !           368: /************************************************************************
        !           369: *
        !           370: *   LfBringThreadToTop
        !           371: *
        !           372: *   Bring the specified thread to the top, and invalidate the window
        !           373: *   to force a WM_PAINT message to make the thread's image visible.
        !           374: *   The given thread can be NULL, in which case just set pThrTop to
        !           375: *   NULL.
        !           376: *
        !           377: ************************************************************************/
        !           378: 
        !           379: VOID
        !           380: LfBringThreadToTop(pthr)
        !           381: PTHR pthr;
        !           382: {
        !           383:     int i;
        !           384: 
        !           385: 
        !           386:     /********************************************************************
        !           387:     *  Find the given thread in the group.
        !           388:     ********************************************************************/
        !           389: 
        !           390:     if (pthr)
        !           391:     {
        !           392:        i = 0;
        !           393:        while ((i < global.cThr) && (pthr != global.aThr[i]))
        !           394:            ++i;    /* if i == global.cThr, we have problems */
        !           395:     }
        !           396:     else
        !           397:        i = 32767; /* should cause gp fault if used */
        !           398: 
        !           399: 
        !           400:     /********************************************************************
        !           401:     *  If the user wants the menu items updated, and we're switching
        !           402:     *  away from an active thread, then uncheck the current thread's
        !           403:     *  settings.
        !           404:     ********************************************************************/
        !           405: 
        !           406:     if (global.fUpdateMenusOnThreadSwitch)
        !           407:     {
        !           408:        if (global.pThrTop)
        !           409:        {
        !           410:            UNCHECK_MENU_ITEM(global.hwndFrame, IDM_AUTORESIZE);
        !           411:            UNCHECK_MENU_ITEM(global.hwndFrame, IDM_AUTOSELECTDIMS);
        !           412:            UNCHECK_MENU_ITEM(global.hwndFrame, IDM_CLEARONREDRAW);
        !           413:            UNCHECK_MENU_ITEM(global.hwndFrame, IDM_AUTOSTARTREDRAW);
        !           414:            UNCHECK_MENU_ITEM(global.hwndFrame, IDM_COLLECTBOUNDS);
        !           415:            UNCHECK_MENU_ITEM(global.hwndFrame, IDM_FRACREDRAW);
        !           416:            UNCHECK_MENU_ITEM(global.hwndFrame, IDM_PRIMREDRAW);
        !           417:            UNCHECK_MENU_ITEM(global.hwndFrame, IDM_ATTRREDRAW);
        !           418:            UNCHECK_MENU_ITEM(global.hwndFrame, global.pThrTop->usCurPrim);
        !           419:            UNCHECK_MENU_ITEM(global.hwndFrame, global.pThrTop->usCurXform);
        !           420:            UNCHECK_MENU_ITEM(global.hwndFrame, global.pThrTop->dcType);
        !           421:        }
        !           422:     }
        !           423: 
        !           424: 
        !           425:     /********************************************************************
        !           426:     *  Switch the given thread to the top.
        !           427:     ********************************************************************/
        !           428: 
        !           429:     DosEnterCritSec();
        !           430:     global.iThrTop = i;
        !           431:     global.pThrTop = pthr;
        !           432:     DosExitCritSec();
        !           433: 
        !           434: 
        !           435:     /********************************************************************
        !           436:     *  If we switched in a living thread, then invalidate the entire
        !           437:     *  window. This will cause a WM_PAINT message to be sent, which
        !           438:     *  will display the image from the new top thread. If the user
        !           439:     *  has not disabled updating of the menus, then do that.
        !           440:     ********************************************************************/
        !           441: 
        !           442:     if (pthr)
        !           443:     {
        !           444:        WinInvalidateRect(global.hwnd, NULL, FALSE);
        !           445: 
        !           446:        /* If the user wants menu items updated, then do it now. */
        !           447:        if (global.fUpdateMenusOnThreadSwitch)
        !           448:        {
        !           449:            TOGGLE_MENU_ITEM(global.hwndFrame, IDM_AUTORESIZE,     pthr->fAutoSizePS);
        !           450:            TOGGLE_MENU_ITEM(global.hwndFrame, IDM_AUTOSELECTDIMS,  pthr->fAutoSelectDims);
        !           451:            TOGGLE_MENU_ITEM(global.hwndFrame, IDM_CLEARONREDRAW,   pthr->fClearOnRedraw);
        !           452:            TOGGLE_MENU_ITEM(global.hwndFrame, IDM_AUTOSTARTREDRAW, pthr->fAutoStartRedraw);
        !           453:            TOGGLE_MENU_ITEM(global.hwndFrame, IDM_COLLECTBOUNDS,   pthr->fCollectBounds);
        !           454:            TOGGLE_MENU_ITEM(global.hwndFrame, IDM_FRACREDRAW,     pthr->fFracRedraw);
        !           455:            TOGGLE_MENU_ITEM(global.hwndFrame, IDM_PRIMREDRAW,     pthr->fPrimRedraw);
        !           456:            TOGGLE_MENU_ITEM(global.hwndFrame, IDM_ATTRREDRAW,     pthr->fAttrRedraw);
        !           457:            CHECK_MENU_ITEM (global.hwndFrame, pthr->usCurPrim);
        !           458:            CHECK_MENU_ITEM (global.hwndFrame, pthr->usCurXform);
        !           459:            CHECK_MENU_ITEM (global.hwndFrame, pthr->dcType);
        !           460: 
        !           461:            LfUpdateThreadMenu();
        !           462:        }
        !           463:     }
        !           464: }
        !           465: 
        !           466: 
        !           467: 
        !           468: 
        !           469: /************************************************************************
        !           470: *
        !           471: *   LfIsThreadTop
        !           472: *
        !           473: *   Returns TRUE if the given thread is the top one.  Putting this
        !           474: *   test in a function isolates it and makes it easier to maintain
        !           475: *   a critical section.
        !           476: *
        !           477: ************************************************************************/
        !           478: 
        !           479: BOOL
        !           480: LfIsThreadTop(pthr)
        !           481: PTHR pthr;
        !           482: {
        !           483:     BOOL f;
        !           484: 
        !           485:     f = FALSE;
        !           486:     DosEnterCritSec();
        !           487:     if (pthr == global.pThrTop)
        !           488:        f = TRUE;
        !           489:     DosExitCritSec();
        !           490: 
        !           491:     return f;
        !           492: }
        !           493: 
        !           494: 
        !           495: 
        !           496: 
        !           497: /************************************************************************
        !           498: *
        !           499: *   LfUpdateThreadMenu
        !           500: *
        !           501: *   Brings the "Thread Bring thread to top" submenu in line with the
        !           502: *   currently active threads.
        !           503: *
        !           504: ************************************************************************/
        !           505: 
        !           506: VOID
        !           507: LfUpdateThreadMenu()
        !           508: {
        !           509:     /*
        !           510:      * Enable the numbers for threads that do exist.
        !           511:      * Disable the numbers for threads that don't exist.
        !           512:      * Uncheck everything, then check the right one.
        !           513:      */
        !           514: 
        !           515:     int i;
        !           516: 
        !           517:     for (i = 0; i < global.cThr; ++i)
        !           518:     {
        !           519:        UNCHECK_MENU_ITEM(global.hwndFrame, IDM_THR0TOTOP+i);
        !           520:        ENABLE_MENU_ITEM (global.hwndFrame, IDM_THR0TOTOP+i);
        !           521:     }
        !           522: 
        !           523:     for (     ; i < MAX_THREADS; ++i)
        !           524:     {
        !           525:        UNCHECK_MENU_ITEM(global.hwndFrame, IDM_THR0TOTOP+i);
        !           526:        DISABLE_MENU_ITEM(global.hwndFrame, IDM_THR0TOTOP+i);
        !           527:     }
        !           528: 
        !           529:     CHECK_MENU_ITEM(global.hwndFrame, IDM_THR0TOTOP + global.iThrTop);
        !           530: }

unix.superglobalmegacorp.com

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