home *** CD-ROM | disk | FTP | other *** search
- /*
- File: SwitcherMain.c
-
- Contains: Switcher 98.
-
- Written by: Mike Neil
-
- Copyright: © 1998 Mike Neil
-
- Change History (most recent first):
-
- */
-
- #include <Processes.h>
- #include <CodeFragments.h>
- #include <QDOffscreen.h>
- #include <Quickdraw.h>
- #include <StringCompare.h>
- #include <Patches.h>
- #include <Traps.h>
- #include <string.h>
-
-
- struct OffscreenInfo
- {
- Ptr fOffscreen;
- Ptr fScreen;
- UInt32 fBufferSize;
- UInt16 fRowBytes;
- UInt16 fRowWidth;
- UInt16 fHeight;
- UInt16 fWidth;
- };
-
- struct ProcessData
- {
- ProcessSerialNumber fPSN;
- GWorldPtr fSavedScreen;
- };
-
- GWorldPtr sArrows = nil;
- OffscreenInfo sScreen;
- ProcessData sProcs[64];
- UInt16 sMaxProc = 0;
- UInt16 sFinderProc = 0;
- UInt16 sLastProc = 0;
- RgnHandle sArrowRgn = nil;
- Rect sArrowRect;
- PicHandle sArrowPic = nil;
- GetNextEventFilterUPP sMyJGNE = nil;
- GetNextEventFilterUPP sTheirJGNE = nil;
- Boolean sQuit = false;
- UInt16 sSlideInProgress = 0;
- Boolean sSlideDir;
- ProcessSerialNumber sCurPSN;
- WindowPtr sWindow = nil;
- Rect sScreenRect;
- Rect sSmallScreen;
- Rect sWinRect;
-
-
- pascal void MyGetNextEventFilterProc(EventRecord *theEvent, Boolean *result);
-
- pascal OSErr ShowHideProcessPriv(const ProcessSerialNumber *PSN, Boolean show);
- Boolean Init(void);
- void Term(void);
- Boolean NewOffscreen(void);
- void DisposeOffscreen(void);
- void SwitchToOffscreen(void);
- void SwitchToScreen(void);
- void SlideToScreen(Boolean rightToLeft);
- void CycleApp(Boolean inNext);
- void DrawWindow(void);
-
-
-
- EXTERN_API( UniversalProcHandle )
- GetTrapVector (UInt16 trapNumber);
-
- pascal OSErr
- ShowHideProcessPriv(const ProcessSerialNumber *PSN, Boolean show)
- {
- // Now call through MixedMode to the trap
- return (OSErr)CallUniversalProc(
- *GetTrapVector(_OSDispatch),
- kStackDispatchedPascalStackBased |
- RESULT_SIZE(kTwoByteCode) |
- DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(1, kFourByteCode) |
- DISPATCHED_STACK_ROUTINE_PARAMETER(2, kOneByteCode),
- 0x60,
- PSN,
- show);
- }
-
-
- Boolean Init(void)
- {
- OSErr error;
- GDHandle mainScreen;
- PixMapHandle mainPix;
- short width;
- GrafPtr winMgrPort = LMGetWMgrPort();
-
- /* Initialize all the needed managers. */
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
-
- mainScreen = GetMainDevice();
- mainPix = (*mainScreen)->gdPMap;
- if (mainPix == nil)
- return false;
-
- width = (*mainPix)->bounds.right - (*mainPix)->bounds.left;
- SetRect(&sArrowRect, width - 32, 0, width, LMGetMBarHeight());
- error = NewGWorld(&sArrows, 0, &sArrowRect, nil, GetMainDevice(), noNewDevice);
- if (error != noErr)
- return false;
-
- CopyBits(&qd.screenBits, (BitMap *)*sArrows->portPixMap, &sArrowRect, &sArrows->portRect, srcCopy, nil);
-
- sArrowRgn = NewRgn();
- RectRgn(sArrowRgn, &sArrowRect);
- DiffRgn(winMgrPort->visRgn, sArrowRgn, winMgrPort->visRgn);
-
- sArrowPic = (PicHandle)Get1Resource('PICT', 1024);
- if (sArrowPic == nil)
- return false;
-
- LoadResource((Handle)sArrowPic);
- DetachResource((Handle)sArrowPic);
-
- {
- CGrafPtr savePort;
- GDHandle gdh;
-
- GetGWorld(&savePort, &gdh);
- SetGWorld(sArrows, GetMainDevice());
-
- DrawPicture(sArrowPic, &(**sArrowPic).picFrame);
-
- SetGWorld(savePort, gdh);
- }
-
- sMyJGNE = NewGetNextEventFilterProc(MyGetNextEventFilterProc);
- sTheirJGNE = LMGetGNEFilter();
- LMSetGNEFilter(sMyJGNE);
-
- sWinRect = (*mainPix)->bounds;
- InsetRect(&sWinRect, 10, 10);
- sWinRect.top = sWinRect.top + LMGetMBarHeight() + 16;
-
- SetMenuBar(GetNewMBar(128));
- DrawMenuBar();
-
- sWindow = NewCWindow(nil, &sWinRect, "\pSwitcher 98", true, documentProc, (WindowPtr)(-1), true, 0);
-
- sSmallScreen = (*mainPix)->bounds;
- sScreenRect = (*mainPix)->bounds;
- sSmallScreen.bottom = sSmallScreen.bottom >> 2;
- sSmallScreen.right = sSmallScreen.right >> 2;
-
- return true;
- }
-
- void Term(void)
- {
- GrafPtr winMgrPort = LMGetWMgrPort();
-
- UnionRgn(winMgrPort->visRgn, sArrowRgn, winMgrPort->visRgn);
- DisposeRgn(sArrowRgn);
-
- LMSetGNEFilter(sTheirJGNE);
- }
-
- pascal void MyGetNextEventFilterProc(EventRecord *theEvent, Boolean *result)
- {
- if ((theEvent->what == mouseDown) || (theEvent->what == mouseUp))
- {
- if (PtInRect(theEvent->where, &sArrowRect))
- {
- if (theEvent->what == mouseDown)
- {
- if (theEvent->where.h - sArrowRect.left < 13)
- {
- CycleApp(true);
- }
- else if (theEvent->where.h - sArrowRect.left < 19)
- {
- CopyBits(&qd.screenBits, (BitMap *)*sProcs[sLastProc].fSavedScreen->portPixMap, &sScreenRect, &sSmallScreen, srcCopy, nil);
-
- ShowHideProcessPriv(&sCurPSN, true);
-
- if (sLastProc != sFinderProc)
- ShowHideProcessPriv(&sProcs[sLastProc].fPSN, false);
-
- SetFrontProcess(&sCurPSN);
-
- if (theEvent->modifiers & controlKey)
- sQuit = true;
- }
- else
- {
- CycleApp(false);
- }
- }
-
- return;
- }
- }
-
- if ((theEvent->what == keyDown) || (theEvent->what == autoKey))
- {
- if (theEvent->modifiers & cmdKey)
- {
- char s = (theEvent->message & charCodeMask);
-
- if (s == ']')
- {
- CycleApp(false);
- return;
- }
- else if (s == '[')
- {
- CycleApp(true);
- return;
- }
- }
- }
-
- if (sSlideInProgress != 0)
- {
- sSlideInProgress--;
- if (sSlideInProgress == 0)
- {
- SlideToScreen(sSlideDir);
- }
- }
-
- CallGetNextEventFilterProc(sTheirJGNE, theEvent, result);
- }
-
- Boolean NewOffscreen(void)
- {
- GDHandle mainScreen;
- PixMapHandle mainPix;
- UInt32 bufferSize;
- UInt32 height;
- Ptr buffer;
-
- mainScreen = GetMainDevice();
- mainPix = (*mainScreen)->gdPMap;
- if (mainPix == nil)
- return false;
-
- height = (*mainPix)->bounds.bottom - (*mainPix)->bounds.top;
- bufferSize = (UInt32)((*mainPix)->rowBytes & 0x3fff) * height;
-
- buffer = NewPtrSys(bufferSize);
- if (buffer == nil)
- return false;
-
- mainScreen = GetMainDevice();
- mainPix = (*mainScreen)->gdPMap;
- if (mainPix == nil)
- return false;
-
- memcpy(buffer, (*mainPix)->baseAddr, bufferSize);
-
- sScreen.fOffscreen = buffer;
- sScreen.fScreen = (*mainPix)->baseAddr;
- sScreen.fBufferSize = bufferSize;
- sScreen.fRowBytes = (*mainPix)->rowBytes & 0x3fff;
- sScreen.fWidth = (*mainPix)->bounds.right - (*mainPix)->bounds.left;
- sScreen.fRowWidth = sScreen.fWidth;
- switch ((*mainPix)->pixelSize)
- {
- case 1:
- sScreen.fRowWidth = sScreen.fRowWidth >> 3;
- break;
-
- case 2:
- sScreen.fRowWidth = sScreen.fRowWidth >> 2;
- break;
-
- case 4:
- sScreen.fRowWidth = sScreen.fRowWidth >> 1;
- break;
-
- case 16:
- sScreen.fRowWidth = sScreen.fRowWidth << 1;
- break;
-
- case 32:
- sScreen.fRowWidth = sScreen.fRowWidth << 2;
- break;
- };
-
- sScreen.fRowWidth = sScreen.fRowWidth >> 3;
-
- sScreen.fHeight = height;
-
- return true;
- }
-
- void SwitchToOffscreen(void)
- {
- GDHandle mainScreen;
- PixMapHandle mainPix;
-
- HideCursor();
-
- mainScreen = GetMainDevice();
- mainPix = (*mainScreen)->gdPMap;
- if (mainPix == nil)
- return;
-
- memcpy(sScreen.fOffscreen, sScreen.fScreen, sScreen.fBufferSize);
- (*mainPix)->baseAddr = sScreen.fOffscreen;
-
- ShowCursor();
- }
-
- void SwitchToScreen(void)
- {
- GDHandle mainScreen;
- PixMapHandle mainPix;
-
- mainScreen = GetMainDevice();
- mainPix = (*mainScreen)->gdPMap;
- if (mainPix == nil)
- return;
-
- memcpy(sScreen.fScreen, sScreen.fOffscreen, sScreen.fBufferSize);
- (*mainPix)->baseAddr = sScreen.fScreen;
- }
-
- void SlideToScreen(Boolean rightToLeft)
- {
- GDHandle mainScreen;
- PixMapHandle mainPix;
- double *src, *dest;
- UInt32 scrollPos;
- UInt32 slideAmount = 8;
-
- HideCursor();
-
- {
- GrafPtr savePort;
- GrafPtr winMgrPort = LMGetWMgrPort();
- RgnHandle savedRgn;
- RgnHandle vizRgn;
-
- GetPort(&savePort);
- SetPort(winMgrPort);
-
- savedRgn = winMgrPort->clipRgn;
- winMgrPort->clipRgn = sArrowRgn;
- vizRgn = winMgrPort->visRgn;
- winMgrPort->visRgn = sArrowRgn;
-
- CopyBits((BitMap *)*sArrows->portPixMap, &qd.screenBits, &sArrows->portRect, &sArrowRect, srcCopy, nil);
-
- winMgrPort->clipRgn = savedRgn;
- winMgrPort->visRgn = vizRgn;
-
- SetPort(savePort);
- }
-
- if (rightToLeft)
- {
- for (scrollPos = slideAmount; scrollPos <= (sScreen.fRowWidth); scrollPos = scrollPos + slideAmount)
- {
- for (UInt32 vPos = 0; vPos < sScreen.fHeight; vPos++)
- {
- src = (double *)(sScreen.fScreen + (vPos * sScreen.fRowBytes));
- dest = (double *)(sScreen.fScreen + (vPos * sScreen.fRowBytes));
- src = src + slideAmount;
-
- for (UInt32 hPos = 0; hPos < (sScreen.fRowWidth) - slideAmount; hPos++)
- {
- *dest++ = *src++;
- }
-
- for (UInt32 lastBit = 0; lastBit < slideAmount; lastBit++)
- {
- src = (double *)(sScreen.fOffscreen + (vPos * sScreen.fRowBytes));
- *dest++ = src[scrollPos - slideAmount + lastBit];
- }
- }
- }
- }
- else
- {
- UInt32 width = (sScreen.fRowWidth);
- for (scrollPos = slideAmount; scrollPos <= width; scrollPos = scrollPos + slideAmount)
- {
- for (UInt32 vPos = 0; vPos < sScreen.fHeight; vPos++)
- {
- src = (double *)(sScreen.fScreen + (vPos * sScreen.fRowBytes));
- dest = (double *)(sScreen.fScreen + (vPos * sScreen.fRowBytes));
- src = src + width;
- dest = dest + width;
- src = src - slideAmount;
-
- for (UInt32 hPos = 0; hPos < width - slideAmount; hPos++)
- {
- dest--;
- src--;
- *dest = *src;
- }
-
- for (UInt32 lastBit = 0; lastBit < slideAmount; lastBit++)
- {
- src = (double *)(sScreen.fOffscreen + (vPos * sScreen.fRowBytes));
- dest--;
- *dest = src[width - scrollPos - lastBit + slideAmount - 1];
- }
- }
- }
- }
-
- mainScreen = GetMainDevice();
- mainPix = (*mainScreen)->gdPMap;
- if (mainPix == nil)
- return;
-
- (*mainPix)->baseAddr = sScreen.fScreen;
-
- ShowCursor();
- }
-
- void DisposeOffscreen(void)
- {
- GDHandle mainScreen;
- PixMapHandle mainPix;
-
- mainScreen = GetMainDevice();
- mainPix = (*mainScreen)->gdPMap;
- if (mainPix == nil)
- return;
-
- (*mainPix)->baseAddr = sScreen.fScreen;
- DisposePtr(sScreen.fOffscreen);
- }
-
- void CycleAppIndex(UInt16 inNext)
- {
- SwitchToOffscreen();
-
- if (inNext != sFinderProc)
- ShowHideProcessPriv(&sProcs[inNext].fPSN, true);
-
- if (sLastProc != sFinderProc)
- ShowHideProcessPriv(&sProcs[sLastProc].fPSN, false);
- SetFrontProcess(&sProcs[inNext].fPSN);
-
- sSlideInProgress = 6;
-
- sLastProc = inNext;
-
- sSlideDir = true;
- }
-
- void CycleApp(Boolean inNext)
- {
- UInt16 nextApp;
- Boolean same;
-
- SameProcess(&sProcs[sLastProc].fPSN, &sCurPSN, &same);
-
- if (!same)
- CopyBits(&qd.screenBits, (BitMap *)*sProcs[sLastProc].fSavedScreen->portPixMap, &sScreenRect, &sSmallScreen, srcCopy, nil);
-
- SwitchToOffscreen();
-
- if (inNext)
- if (sLastProc == sMaxProc - 1)
- nextApp = 0;
- else
- nextApp = (sLastProc + 1);
- else
- if (sLastProc == 0)
- nextApp = sMaxProc - 1;
- else
- nextApp = (sLastProc - 1);
-
- if (nextApp != sFinderProc)
- ShowHideProcessPriv(&sProcs[nextApp].fPSN, true);
-
- if (sLastProc != sFinderProc)
- ShowHideProcessPriv(&sProcs[sLastProc].fPSN, false);
- SetFrontProcess(&sProcs[nextApp].fPSN);
-
- sSlideInProgress = 6;
-
- sLastProc = nextApp;
-
- sSlideDir = inNext;
- }
-
- void DrawWindow(void)
- {
- Rect destRect;
- Rect tempRect;
- short hSkip, vSkip;
-
- SetPort(sWindow);
-
- destRect = sSmallScreen;
- hSkip = ((sWinRect.right - sWinRect.left) - (sSmallScreen.right * 3)) / 4;
- vSkip = ((sWinRect.bottom - sWinRect.top) - (sSmallScreen.bottom * 3)) / 4;
-
- for (UInt16 foo = 0; foo < sMaxProc; foo++)
- {
- tempRect = destRect;
- OffsetRect(&tempRect, ((hSkip + sSmallScreen.right) * (foo % 3)) + hSkip, ((vSkip + sSmallScreen.bottom) * ((foo / 3) % 3)) + vSkip);
-
- CopyBits((BitMap *)*sProcs[foo].fSavedScreen->portPixMap, &sWindow->portBits, &sSmallScreen, &tempRect, srcCopy, nil);
- }
- }
-
- void HandleClick(Point inPoint)
- {
- short hSkip, vSkip;
- short x, y;
- UInt16 index;
-
- SetPort(sWindow);
- GlobalToLocal(&inPoint);
-
- hSkip = ((sWinRect.right - sWinRect.left) - (sSmallScreen.right * 3)) / 4;
- vSkip = ((sWinRect.bottom - sWinRect.top) - (sSmallScreen.bottom * 3)) / 4;
-
- x = (inPoint.h / (sSmallScreen.right + hSkip));
- y = (inPoint.v / (sSmallScreen.bottom + vSkip));
-
- index = x + (y * 3);
-
- if (index >= sMaxProc)
- return;
-
- CycleAppIndex(index);
- }
-
- void HandleMouseDown(EventRecord *event)
- {
- WindowPtr whichWindow;
-
- switch (FindWindow(event->where, &whichWindow)) {
- case inSysWindow:
- SystemClick(event, whichWindow);
- break;
- case inMenuBar:
- // DoCommand(MenuSelect(event->where));
- break;
- case inContent:
- SelectWindow(whichWindow);
- if (whichWindow == sWindow)
- {
- HandleClick(event->where);
- }
- break;
- case inDrag:
- if (whichWindow != sWindow)
- DragWindow (whichWindow, event->where, &qd.screenBits.bounds);
- else
- SysBeep(10);
- break;
- case inGrow:
- break;
- case inGoAway:
- break;
- case inZoomIn:
- break;
- case inZoomOut:
- break;
- default:
- break;
- }
- }
-
- void HandleEvent(void)
- {
- WindowPtr window = nil;
- EventRecord event;
- Boolean ok;
-
- ok = WaitNextEvent(everyEvent, &event, 0, nil);
-
- if (ok)
- switch (event.what)
- {
- case mouseDown:
- HandleMouseDown(&event);
- break;
-
- case mouseUp:
- break;
-
- case keyDown:
- case autoKey:
- if ((event.modifiers & cmdKey) != 0)
- {
- }
- break;
-
- case keyUp:
- break;
-
- case updateEvt:
- window = (WindowPtr)event.message;
- BeginUpdate(window);
- DrawWindow();
- EndUpdate(window);
- break;
-
- case activateEvt:
- window = (WindowPtr)event.message;
- break;
-
- case osEvt:
- {
- char kind = *(char*)&event.message;
-
- if (kind == suspendResumeMessage)
- {
- Boolean suspend = (event.message & resumeFlag) == 0;
- if (suspend)
- {
- ShowHideProcessPriv(&sCurPSN, false);
- }
- else
- {
- }
- }
- }
- break;
- }
- }
-
-
-
-
- void main(void)
- {
- OSErr error = noErr;
- OSErr hideError = noErr;
- ProcessSerialNumber psn;
- ProcessInfoRec processInfo;
- Str255 name;
- FSSpec spec;
- Boolean direction = true;
- SInt16 dir = 1;
-
- if (!Init())
- {
- SysBeep(10);
- ExitToShell();
- }
-
- if (!NewOffscreen())
- {
- SysBeep(10);
- ExitToShell();
- }
-
- GetCurrentProcess(&sCurPSN);
-
- psn.highLongOfPSN = kNoProcess;
- psn.lowLongOfPSN = kNoProcess;
-
- processInfo.processInfoLength = sizeof(ProcessInfoRec);
- processInfo.processName = name;
- processInfo.processAppSpec = &spec;
-
- while(error == noErr)
- {
- error = GetNextProcess(&psn);
- if (error == noErr)
- {
- error = GetProcessInformation(&psn, &processInfo);
- if (error == noErr)
- {
- if (!(processInfo.processMode & modeOnlyBackground))
- {
- Boolean same;
-
- SameProcess(&psn, &sCurPSN, &same);
-
- if (!same)
- {
- sProcs[sMaxProc].fPSN = psn;
- error = NewGWorld(&sProcs[sMaxProc].fSavedScreen, 0, &sSmallScreen, nil, GetMainDevice(), noNewDevice);
- if (error != noErr)
- sQuit = true;
-
- if (!EqualString(name, "\pFinder", false, false))
- hideError = ShowHideProcessPriv(&psn, false);
- else
- {
- sFinderProc = sMaxProc;
- SetFrontProcess(&psn);
- }
-
- sMaxProc++;
- }
- }
- }
- }
- }
-
- SwitchToOffscreen();
- SlideToScreen(true);
-
- sLastProc = sFinderProc;
-
- while (sQuit == false)
- {
- HandleEvent();
- }
-
- DisposeOffscreen();
-
- Term();
- }
-
-
-