home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / The Hacks! / Switcher 98 / SwitcherMain.c < prev   
Encoding:
C/C++ Source or Header  |  1998-06-21  |  14.8 KB  |  734 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        SwitcherMain.c
  3.     
  4.     Contains:    Switcher 98.
  5.  
  6.     Written by:    Mike Neil
  7.     
  8.     Copyright:    © 1998 Mike Neil
  9.  
  10.     Change History (most recent first):
  11.  
  12. */
  13.  
  14. #include <Processes.h>
  15. #include <CodeFragments.h>
  16. #include <QDOffscreen.h>
  17. #include <Quickdraw.h>
  18. #include <StringCompare.h>
  19. #include <Patches.h>
  20. #include <Traps.h>
  21. #include <string.h>
  22.  
  23.  
  24. struct OffscreenInfo
  25. {
  26.     Ptr                    fOffscreen;
  27.     Ptr                    fScreen;
  28.     UInt32                fBufferSize;
  29.     UInt16                fRowBytes;
  30.     UInt16                fRowWidth;
  31.     UInt16                fHeight;
  32.     UInt16                fWidth;
  33. };
  34.  
  35. struct ProcessData
  36. {
  37.     ProcessSerialNumber        fPSN;
  38.     GWorldPtr                fSavedScreen;
  39. };
  40.  
  41. GWorldPtr                sArrows = nil;
  42. OffscreenInfo            sScreen;
  43. ProcessData                sProcs[64];
  44. UInt16                    sMaxProc = 0;
  45. UInt16                    sFinderProc = 0;
  46. UInt16                    sLastProc = 0;
  47. RgnHandle                sArrowRgn = nil;
  48. Rect                    sArrowRect;
  49. PicHandle                sArrowPic = nil;
  50. GetNextEventFilterUPP    sMyJGNE = nil;
  51. GetNextEventFilterUPP    sTheirJGNE = nil;
  52. Boolean                    sQuit = false;
  53. UInt16                    sSlideInProgress = 0;
  54. Boolean                    sSlideDir;
  55. ProcessSerialNumber        sCurPSN;
  56. WindowPtr                sWindow = nil;
  57. Rect                    sScreenRect;
  58. Rect                    sSmallScreen;
  59. Rect                    sWinRect;
  60.  
  61.  
  62. pascal void     MyGetNextEventFilterProc(EventRecord *theEvent, Boolean *result);
  63.  
  64. pascal OSErr     ShowHideProcessPriv(const ProcessSerialNumber *PSN, Boolean show);
  65. Boolean         Init(void);
  66. void             Term(void);
  67. Boolean         NewOffscreen(void);
  68. void             DisposeOffscreen(void);
  69. void             SwitchToOffscreen(void);
  70. void             SwitchToScreen(void);
  71. void             SlideToScreen(Boolean rightToLeft);
  72. void             CycleApp(Boolean inNext);
  73. void            DrawWindow(void);
  74.  
  75.  
  76.  
  77. EXTERN_API( UniversalProcHandle )
  78. GetTrapVector                    (UInt16                 trapNumber);
  79.  
  80. pascal OSErr
  81. ShowHideProcessPriv(const ProcessSerialNumber *PSN, Boolean show)
  82. {
  83.     // Now call through MixedMode to the trap
  84.     return (OSErr)CallUniversalProc(
  85.                     *GetTrapVector(_OSDispatch),
  86.                     kStackDispatchedPascalStackBased |
  87.                         RESULT_SIZE(kTwoByteCode) |
  88.                         DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
  89.                         DISPATCHED_STACK_ROUTINE_PARAMETER(1, kFourByteCode) |
  90.                         DISPATCHED_STACK_ROUTINE_PARAMETER(2, kOneByteCode),
  91.                     0x60,
  92.                     PSN,
  93.                     show);
  94. }
  95.  
  96.  
  97. Boolean Init(void)
  98. {
  99.     OSErr            error;
  100.     GDHandle        mainScreen;
  101.     PixMapHandle    mainPix;
  102.     short            width;
  103.     GrafPtr            winMgrPort = LMGetWMgrPort();
  104.     
  105.     /* Initialize all the needed managers. */
  106.     InitGraf(&qd.thePort);
  107.     InitFonts();
  108.     InitWindows();
  109.     InitMenus();
  110.     TEInit();
  111.     InitDialogs(nil);
  112.     InitCursor();
  113.     
  114.     mainScreen = GetMainDevice();
  115.     mainPix = (*mainScreen)->gdPMap;
  116.     if (mainPix == nil)
  117.         return false;
  118.  
  119.     width = (*mainPix)->bounds.right - (*mainPix)->bounds.left;
  120.     SetRect(&sArrowRect, width - 32, 0, width, LMGetMBarHeight());
  121.     error = NewGWorld(&sArrows, 0, &sArrowRect, nil, GetMainDevice(), noNewDevice);
  122.     if (error != noErr)
  123.         return false;
  124.     
  125.     CopyBits(&qd.screenBits, (BitMap *)*sArrows->portPixMap, &sArrowRect, &sArrows->portRect, srcCopy, nil);
  126.     
  127.     sArrowRgn = NewRgn();
  128.     RectRgn(sArrowRgn, &sArrowRect);
  129.     DiffRgn(winMgrPort->visRgn, sArrowRgn, winMgrPort->visRgn);
  130.     
  131.     sArrowPic = (PicHandle)Get1Resource('PICT', 1024);
  132.     if (sArrowPic == nil)
  133.         return false;
  134.     
  135.     LoadResource((Handle)sArrowPic);
  136.     DetachResource((Handle)sArrowPic);
  137.     
  138.     {
  139.         CGrafPtr        savePort;
  140.         GDHandle        gdh;
  141.         
  142.         GetGWorld(&savePort, &gdh);
  143.         SetGWorld(sArrows, GetMainDevice());
  144.         
  145.         DrawPicture(sArrowPic, &(**sArrowPic).picFrame);
  146.         
  147.         SetGWorld(savePort, gdh);
  148.     }
  149.     
  150.     sMyJGNE = NewGetNextEventFilterProc(MyGetNextEventFilterProc);
  151.     sTheirJGNE = LMGetGNEFilter();
  152.     LMSetGNEFilter(sMyJGNE);
  153.     
  154.     sWinRect = (*mainPix)->bounds;
  155.     InsetRect(&sWinRect, 10, 10);
  156.     sWinRect.top = sWinRect.top + LMGetMBarHeight() + 16;
  157.     
  158.     SetMenuBar(GetNewMBar(128));
  159.     DrawMenuBar();
  160.     
  161.     sWindow = NewCWindow(nil, &sWinRect, "\pSwitcher 98", true, documentProc, (WindowPtr)(-1), true, 0);
  162.     
  163.     sSmallScreen = (*mainPix)->bounds;
  164.     sScreenRect = (*mainPix)->bounds;
  165.     sSmallScreen.bottom = sSmallScreen.bottom >> 2;
  166.     sSmallScreen.right = sSmallScreen.right >> 2;
  167.     
  168.     return true;
  169. }
  170.  
  171. void Term(void)
  172. {
  173.     GrafPtr        winMgrPort = LMGetWMgrPort();
  174.     
  175.     UnionRgn(winMgrPort->visRgn, sArrowRgn, winMgrPort->visRgn);
  176.     DisposeRgn(sArrowRgn);
  177.     
  178.     LMSetGNEFilter(sTheirJGNE);
  179. }
  180.  
  181. pascal void MyGetNextEventFilterProc(EventRecord *theEvent, Boolean *result)
  182. {
  183.     if ((theEvent->what == mouseDown) || (theEvent->what == mouseUp))
  184.     {
  185.         if (PtInRect(theEvent->where, &sArrowRect))
  186.         {
  187.             if (theEvent->what == mouseDown)
  188.             {
  189.                 if (theEvent->where.h - sArrowRect.left < 13)
  190.                 {
  191.                     CycleApp(true);
  192.                 }
  193.                 else if (theEvent->where.h - sArrowRect.left < 19)
  194.                 {
  195.                     CopyBits(&qd.screenBits, (BitMap *)*sProcs[sLastProc].fSavedScreen->portPixMap, &sScreenRect, &sSmallScreen, srcCopy, nil);
  196.                     
  197.                     ShowHideProcessPriv(&sCurPSN, true);
  198.                     
  199.                     if (sLastProc != sFinderProc)
  200.                         ShowHideProcessPriv(&sProcs[sLastProc].fPSN, false);
  201.                     
  202.                     SetFrontProcess(&sCurPSN);
  203.                     
  204.                     if (theEvent->modifiers & controlKey)
  205.                         sQuit = true;
  206.                 }
  207.                 else
  208.                 {
  209.                     CycleApp(false);    
  210.                 }
  211.             }
  212.             
  213.             return;
  214.         }
  215.     }
  216.     
  217.     if ((theEvent->what == keyDown) || (theEvent->what == autoKey))
  218.     {
  219.         if (theEvent->modifiers & cmdKey)
  220.         {
  221.             char    s = (theEvent->message & charCodeMask);
  222.             
  223.             if (s == ']')
  224.             {
  225.                 CycleApp(false);
  226.                 return;
  227.             }
  228.             else if (s == '[')
  229.             {
  230.                 CycleApp(true);
  231.             return;
  232.             }
  233.         }
  234.     }
  235.     
  236.     if (sSlideInProgress != 0)
  237.     {
  238.         sSlideInProgress--;
  239.         if (sSlideInProgress == 0)
  240.         {
  241.             SlideToScreen(sSlideDir);
  242.         }
  243.     }
  244.     
  245.     CallGetNextEventFilterProc(sTheirJGNE, theEvent, result);
  246. }
  247.  
  248. Boolean NewOffscreen(void)
  249. {
  250.     GDHandle        mainScreen;
  251.     PixMapHandle    mainPix;
  252.     UInt32            bufferSize;
  253.     UInt32            height;
  254.     Ptr                buffer;
  255.     
  256.     mainScreen = GetMainDevice();
  257.     mainPix = (*mainScreen)->gdPMap;
  258.     if (mainPix == nil)
  259.         return false;
  260.         
  261.     height = (*mainPix)->bounds.bottom - (*mainPix)->bounds.top;
  262.     bufferSize = (UInt32)((*mainPix)->rowBytes & 0x3fff) * height;
  263.     
  264.     buffer = NewPtrSys(bufferSize);
  265.     if (buffer == nil)
  266.         return false;
  267.         
  268.     mainScreen = GetMainDevice();
  269.     mainPix = (*mainScreen)->gdPMap;
  270.     if (mainPix == nil)
  271.         return false;
  272.  
  273.     memcpy(buffer, (*mainPix)->baseAddr, bufferSize);
  274.     
  275.     sScreen.fOffscreen = buffer;
  276.     sScreen.fScreen = (*mainPix)->baseAddr;
  277.     sScreen.fBufferSize = bufferSize;
  278.     sScreen.fRowBytes = (*mainPix)->rowBytes & 0x3fff;
  279.     sScreen.fWidth = (*mainPix)->bounds.right - (*mainPix)->bounds.left;
  280.     sScreen.fRowWidth = sScreen.fWidth;
  281.     switch ((*mainPix)->pixelSize)
  282.     {
  283.         case 1:
  284.             sScreen.fRowWidth = sScreen.fRowWidth >> 3;
  285.         break;
  286.         
  287.         case 2:
  288.             sScreen.fRowWidth = sScreen.fRowWidth >> 2;
  289.         break;
  290.         
  291.         case 4:
  292.             sScreen.fRowWidth = sScreen.fRowWidth >> 1;
  293.         break;
  294.         
  295.         case 16:
  296.             sScreen.fRowWidth = sScreen.fRowWidth << 1;
  297.         break;
  298.         
  299.         case 32:
  300.             sScreen.fRowWidth = sScreen.fRowWidth << 2;
  301.         break;
  302.     };
  303.     
  304.     sScreen.fRowWidth = sScreen.fRowWidth >> 3;
  305.     
  306.     sScreen.fHeight = height;
  307.  
  308.     return true;
  309. }
  310.  
  311. void SwitchToOffscreen(void)
  312. {
  313.     GDHandle        mainScreen;
  314.     PixMapHandle    mainPix;
  315.     
  316.     HideCursor();
  317.     
  318.     mainScreen = GetMainDevice();
  319.     mainPix = (*mainScreen)->gdPMap;
  320.     if (mainPix == nil)
  321.         return;
  322.  
  323.     memcpy(sScreen.fOffscreen, sScreen.fScreen, sScreen.fBufferSize);
  324.     (*mainPix)->baseAddr = sScreen.fOffscreen;
  325.     
  326.     ShowCursor();
  327. }
  328.  
  329. void SwitchToScreen(void)
  330. {
  331.     GDHandle        mainScreen;
  332.     PixMapHandle    mainPix;
  333.  
  334.     mainScreen = GetMainDevice();
  335.     mainPix = (*mainScreen)->gdPMap;
  336.     if (mainPix == nil)
  337.         return;
  338.  
  339.     memcpy(sScreen.fScreen, sScreen.fOffscreen, sScreen.fBufferSize);
  340.     (*mainPix)->baseAddr = sScreen.fScreen;
  341. }
  342.  
  343. void SlideToScreen(Boolean rightToLeft)
  344. {
  345.     GDHandle        mainScreen;
  346.     PixMapHandle    mainPix;
  347.     double            *src, *dest;
  348.     UInt32            scrollPos;
  349.     UInt32            slideAmount = 8;
  350.     
  351.     HideCursor();
  352.     
  353.     {
  354.         GrafPtr        savePort;
  355.         GrafPtr        winMgrPort = LMGetWMgrPort();
  356.         RgnHandle    savedRgn;
  357.         RgnHandle    vizRgn;
  358.         
  359.         GetPort(&savePort);
  360.         SetPort(winMgrPort);
  361.         
  362.         savedRgn = winMgrPort->clipRgn;
  363.         winMgrPort->clipRgn = sArrowRgn;
  364.         vizRgn = winMgrPort->visRgn;
  365.         winMgrPort->visRgn = sArrowRgn;
  366.         
  367.         CopyBits((BitMap *)*sArrows->portPixMap, &qd.screenBits, &sArrows->portRect, &sArrowRect, srcCopy, nil);
  368.         
  369.         winMgrPort->clipRgn = savedRgn;
  370.         winMgrPort->visRgn = vizRgn;
  371.         
  372.         SetPort(savePort);
  373.     }
  374.  
  375.     if (rightToLeft)
  376.     {
  377.         for (scrollPos = slideAmount; scrollPos <= (sScreen.fRowWidth); scrollPos = scrollPos + slideAmount)
  378.         {
  379.             for (UInt32    vPos = 0; vPos < sScreen.fHeight; vPos++)
  380.             {
  381.                 src = (double *)(sScreen.fScreen + (vPos * sScreen.fRowBytes));
  382.                 dest = (double *)(sScreen.fScreen + (vPos * sScreen.fRowBytes));
  383.                 src = src + slideAmount;
  384.                 
  385.                 for (UInt32 hPos = 0; hPos < (sScreen.fRowWidth) - slideAmount; hPos++)
  386.                 {
  387.                     *dest++ = *src++;
  388.                 }
  389.                 
  390.                 for (UInt32 lastBit = 0; lastBit < slideAmount; lastBit++)
  391.                 {
  392.                     src = (double *)(sScreen.fOffscreen + (vPos * sScreen.fRowBytes));
  393.                     *dest++ = src[scrollPos - slideAmount + lastBit];
  394.                 }
  395.             }
  396.         }
  397.     }
  398.     else
  399.     {
  400.         UInt32    width = (sScreen.fRowWidth);
  401.         for (scrollPos = slideAmount; scrollPos <= width; scrollPos = scrollPos + slideAmount)
  402.         {
  403.             for (UInt32    vPos = 0; vPos < sScreen.fHeight; vPos++)
  404.             {
  405.                 src = (double *)(sScreen.fScreen + (vPos * sScreen.fRowBytes));
  406.                 dest = (double *)(sScreen.fScreen + (vPos * sScreen.fRowBytes));
  407.                 src = src + width;
  408.                 dest = dest + width;
  409.                 src = src - slideAmount;
  410.                 
  411.                 for (UInt32 hPos = 0; hPos < width - slideAmount; hPos++)
  412.                 {
  413.                     dest--;
  414.                     src--;
  415.                     *dest = *src;
  416.                 }
  417.                 
  418.                 for (UInt32 lastBit = 0; lastBit < slideAmount; lastBit++)
  419.                 {
  420.                     src = (double *)(sScreen.fOffscreen + (vPos * sScreen.fRowBytes));
  421.                     dest--;
  422.                     *dest = src[width - scrollPos - lastBit + slideAmount - 1];
  423.                 }
  424.             }
  425.         }
  426.     }
  427.     
  428.     mainScreen = GetMainDevice();
  429.     mainPix = (*mainScreen)->gdPMap;
  430.     if (mainPix == nil)
  431.         return;
  432.  
  433.     (*mainPix)->baseAddr = sScreen.fScreen;
  434.  
  435.     ShowCursor();
  436. }
  437.  
  438. void DisposeOffscreen(void)
  439. {
  440.     GDHandle        mainScreen;
  441.     PixMapHandle    mainPix;
  442.  
  443.     mainScreen = GetMainDevice();
  444.     mainPix = (*mainScreen)->gdPMap;
  445.     if (mainPix == nil)
  446.         return;
  447.  
  448.     (*mainPix)->baseAddr = sScreen.fScreen;
  449.     DisposePtr(sScreen.fOffscreen);
  450. }
  451.  
  452. void CycleAppIndex(UInt16 inNext)
  453. {    
  454.     SwitchToOffscreen();    
  455.         
  456.     if (inNext != sFinderProc)
  457.         ShowHideProcessPriv(&sProcs[inNext].fPSN, true);
  458.     
  459.     if (sLastProc != sFinderProc)
  460.         ShowHideProcessPriv(&sProcs[sLastProc].fPSN, false);
  461.     SetFrontProcess(&sProcs[inNext].fPSN);
  462.     
  463.     sSlideInProgress = 6;
  464.     
  465.     sLastProc = inNext;
  466.     
  467.     sSlideDir = true;
  468. }
  469.  
  470. void CycleApp(Boolean inNext)
  471. {
  472.     UInt16        nextApp;
  473.     Boolean        same;
  474.     
  475.     SameProcess(&sProcs[sLastProc].fPSN, &sCurPSN, &same);
  476.     
  477.     if (!same)
  478.         CopyBits(&qd.screenBits, (BitMap *)*sProcs[sLastProc].fSavedScreen->portPixMap, &sScreenRect, &sSmallScreen, srcCopy, nil);
  479.  
  480.     SwitchToOffscreen();    
  481.         
  482.     if (inNext)
  483.         if (sLastProc == sMaxProc - 1)
  484.             nextApp = 0;
  485.         else
  486.             nextApp = (sLastProc + 1);
  487.     else
  488.         if (sLastProc == 0)
  489.             nextApp = sMaxProc - 1;
  490.         else
  491.             nextApp = (sLastProc - 1);
  492.     
  493.     if (nextApp != sFinderProc)
  494.         ShowHideProcessPriv(&sProcs[nextApp].fPSN, true);
  495.     
  496.     if (sLastProc != sFinderProc)
  497.         ShowHideProcessPriv(&sProcs[sLastProc].fPSN, false);
  498.     SetFrontProcess(&sProcs[nextApp].fPSN);
  499.     
  500.     sSlideInProgress = 6;
  501.     
  502.     sLastProc = nextApp;
  503.     
  504.     sSlideDir = inNext;
  505. }
  506.  
  507. void DrawWindow(void)
  508. {
  509.     Rect    destRect;
  510.     Rect    tempRect;
  511.     short    hSkip, vSkip;
  512.     
  513.     SetPort(sWindow);
  514.     
  515.     destRect = sSmallScreen;
  516.     hSkip = ((sWinRect.right - sWinRect.left) - (sSmallScreen.right * 3)) / 4;
  517.     vSkip = ((sWinRect.bottom - sWinRect.top) - (sSmallScreen.bottom * 3)) / 4;
  518.     
  519.     for (UInt16 foo = 0; foo < sMaxProc; foo++)
  520.     {
  521.         tempRect = destRect;
  522.         OffsetRect(&tempRect, ((hSkip + sSmallScreen.right) * (foo % 3)) + hSkip, ((vSkip + sSmallScreen.bottom) * ((foo / 3) % 3)) + vSkip);
  523.         
  524.         CopyBits((BitMap *)*sProcs[foo].fSavedScreen->portPixMap, &sWindow->portBits, &sSmallScreen, &tempRect, srcCopy, nil);
  525.     }
  526. }
  527.  
  528. void HandleClick(Point inPoint)
  529. {
  530.     short    hSkip, vSkip;
  531.     short    x, y;
  532.     UInt16    index;
  533.     
  534.     SetPort(sWindow);
  535.     GlobalToLocal(&inPoint);
  536.     
  537.     hSkip = ((sWinRect.right - sWinRect.left) - (sSmallScreen.right * 3)) / 4;
  538.     vSkip = ((sWinRect.bottom - sWinRect.top) - (sSmallScreen.bottom * 3)) / 4;
  539.     
  540.     x = (inPoint.h / (sSmallScreen.right + hSkip));
  541.     y = (inPoint.v / (sSmallScreen.bottom + vSkip));
  542.     
  543.     index = x + (y * 3);
  544.     
  545.     if (index >= sMaxProc)
  546.         return;
  547.         
  548.     CycleAppIndex(index);
  549. }
  550.  
  551. void HandleMouseDown(EventRecord *event)
  552. {
  553.     WindowPtr    whichWindow;
  554.     
  555.     switch (FindWindow(event->where, &whichWindow)) {
  556.         case inSysWindow:
  557.             SystemClick(event, whichWindow);
  558.             break;
  559.         case inMenuBar:
  560. //            DoCommand(MenuSelect(event->where));
  561.             break;
  562.         case inContent:
  563.             SelectWindow(whichWindow);
  564.             if (whichWindow == sWindow)
  565.             {
  566.                 HandleClick(event->where);
  567.             }
  568.             break;
  569.         case inDrag:
  570.             if (whichWindow != sWindow)
  571.                 DragWindow (whichWindow, event->where, &qd.screenBits.bounds);
  572.             else
  573.                 SysBeep(10);
  574.             break;
  575.         case inGrow:
  576.             break;
  577.         case inGoAway:
  578.             break;
  579.         case inZoomIn:
  580.             break;
  581.         case inZoomOut:
  582.             break;
  583.         default:
  584.             break;
  585.     }
  586. }
  587.  
  588. void HandleEvent(void)
  589. {
  590.     WindowPtr             window = nil;
  591.     EventRecord            event;
  592.     Boolean             ok;
  593.     
  594.     ok = WaitNextEvent(everyEvent, &event, 0, nil);
  595.  
  596.     if (ok)
  597.     switch (event.what)
  598.     {
  599.         case mouseDown:
  600.             HandleMouseDown(&event);
  601.             break;
  602.  
  603.         case mouseUp:
  604.             break;
  605.  
  606.         case keyDown: 
  607.         case autoKey:
  608.             if ((event.modifiers & cmdKey) != 0)
  609.             {
  610.             }
  611.             break;
  612.  
  613.         case keyUp: 
  614.             break;
  615.  
  616.         case updateEvt:
  617.             window = (WindowPtr)event.message;
  618.             BeginUpdate(window);
  619.             DrawWindow();
  620.             EndUpdate(window);
  621.             break;
  622.  
  623.         case activateEvt:
  624.             window = (WindowPtr)event.message;
  625.             break;
  626.  
  627.         case osEvt:
  628.             {
  629.                 char kind = *(char*)&event.message;
  630.                 
  631.                 if (kind == suspendResumeMessage)
  632.                 {
  633.                     Boolean suspend = (event.message & resumeFlag) == 0;
  634.                     if (suspend)
  635.                     {
  636.                         ShowHideProcessPriv(&sCurPSN, false);
  637.                     }
  638.                     else
  639.                     {
  640.                     }        
  641.                 }
  642.             }
  643.             break;
  644.     }
  645. }
  646.  
  647.  
  648.  
  649.  
  650. void main(void)
  651. {
  652.     OSErr                    error = noErr;
  653.     OSErr                    hideError = noErr;
  654.     ProcessSerialNumber        psn;
  655.     ProcessInfoRec            processInfo;
  656.     Str255                    name;
  657.     FSSpec                    spec;
  658.     Boolean                    direction = true;
  659.     SInt16                    dir = 1;
  660.     
  661.     if (!Init())
  662.     {
  663.         SysBeep(10);
  664.         ExitToShell();
  665.     }
  666.     
  667.     if (!NewOffscreen())
  668.     {
  669.         SysBeep(10);
  670.         ExitToShell();
  671.     }
  672.     
  673.     GetCurrentProcess(&sCurPSN);
  674.     
  675.     psn.highLongOfPSN = kNoProcess;
  676.     psn.lowLongOfPSN = kNoProcess;
  677.     
  678.     processInfo.processInfoLength = sizeof(ProcessInfoRec);
  679.     processInfo.processName = name;
  680.     processInfo.processAppSpec = &spec;
  681.     
  682.     while(error == noErr)
  683.     {
  684.         error = GetNextProcess(&psn);
  685.         if (error == noErr)
  686.         {
  687.             error = GetProcessInformation(&psn, &processInfo);
  688.             if (error == noErr)
  689.             {
  690.                 if (!(processInfo.processMode & modeOnlyBackground))
  691.                 {
  692.                     Boolean    same;
  693.                     
  694.                     SameProcess(&psn, &sCurPSN, &same);
  695.                     
  696.                     if (!same)
  697.                     {
  698.                         sProcs[sMaxProc].fPSN = psn;
  699.                         error = NewGWorld(&sProcs[sMaxProc].fSavedScreen, 0, &sSmallScreen, nil, GetMainDevice(), noNewDevice);
  700.                         if (error != noErr)
  701.                             sQuit = true;
  702.                         
  703.                         if (!EqualString(name, "\pFinder", false, false))
  704.                             hideError = ShowHideProcessPriv(&psn, false);
  705.                         else
  706.                         {
  707.                             sFinderProc = sMaxProc;
  708.                             SetFrontProcess(&psn);
  709.                         }
  710.                         
  711.                         sMaxProc++;
  712.                     }
  713.                 }
  714.             }
  715.         }
  716.     }
  717.     
  718.     SwitchToOffscreen();
  719.     SlideToScreen(true);
  720.     
  721.     sLastProc = sFinderProc;
  722.     
  723.     while (sQuit == false)
  724.     {
  725.         HandleEvent();
  726.     }
  727.  
  728.     DisposeOffscreen();
  729.     
  730.     Term();
  731. }
  732.  
  733.  
  734.