home *** CD-ROM | disk | FTP | other *** search
- /*
- File: GDeviceUtilities.cp
-
- Contains: Lame utilities to deal with GDevices
-
- Written by: Kent Miller
-
- Copyright: © 1995 Apple Computer
-
- Change History (most recent first):
-
- */
-
- #include <Displays.h>
-
- //SuperFly Includes
- #include "GDeviceUtilities.h"
- #include "LinkedList.h"
-
- SInt16 CountActiveScreenDevices(void)
- {
- GDHandle theGD;
- SInt16 count = 1;
-
- theGD = DMGetFirstScreenDevice(true);
-
- while ( theGD )
- {
- theGD = DMGetNextScreenDevice(theGD, true);
- if (theGD)
- count++;
- }
-
- return count;
- }
-
-
- //returns the offset to (almost) center r2 in r1
- void CenterRectInRect (Rect *r1, Rect *r2, SInt16 *hOffset, SInt16 *vOffset)
- {
- SInt16 hCenter1, hCenter2,
- vCenter1, vCenter2;
-
- //Find global center of first rectangle
- hCenter1 = r1->left + ((r1->right - r1->left) / 2);
- vCenter1 = r1->top + ((r1->bottom - r1->top) / 2);
-
- //Find global center of second rectangle
- hCenter2 = r2->left + ((r2->right - r2->left) / 2);
- vCenter2 = r2->top + ((r2->bottom - r2->top) / 2);
-
- *hOffset = hCenter1 - hCenter2;
- *vOffset = vCenter1 - vCenter2;
- }
-
- TLinkedList *BuildAListOfUniqueDevices(void)
- //Routine to build a linked list of devices that are "unique" with regard to
- //their coordinates.
- {
- GDHandle tempGD, mirroredGD;
- TLinkedList *myGDList;
-
- myGDList = new TLinkedList;
-
- //First build a linked list with all the GDHandles
- tempGD = DMGetFirstScreenDevice( dmOnlyActiveDisplays );
- while (tempGD)
- {
- myGDList->AddToList(tempGD);
- tempGD = DMGetNextScreenDevice( tempGD, dmOnlyActiveDisplays );
- }
-
- //Then, walk the list again and remove all the devices that the display manager
- //tells us are mirrored to this one.
- tempGD = (GDHandle) myGDList->GetFirstListElem();
-
- while (tempGD)
- {
- mirroredGD = tempGD;
- //Display manager will give us devices in a loop, so we need to stop when we
- //get the original one back.
- while ((noErr == DMGetNextMirroredDevice( mirroredGD, &mirroredGD )) && (mirroredGD != tempGD))
- myGDList->RemoveFromList(mirroredGD);
-
- tempGD = (GDHandle) myGDList->GetNextListElem(tempGD);
- }
-
- return myGDList;
- }
-
- SInt16 CountUniqueDeviceRects(void)
- //Count the number of unique device gdRects.
- //That is, if 2 display are mirrored their gdRects overlap, so they only count once
- //in this function.
- {
- TLinkedList *myGDList;
- SInt16 uniqueCount;
-
- myGDList = (TLinkedList *) BuildAListOfUniqueDevices();
-
- uniqueCount = myGDList->CountListItems();
-
- delete myGDList;
-
- return uniqueCount;
- }
-
-
- Boolean IsThisDeviceOverlapped(DisplayIDType theDisplayID)
- //Build a region out of all active GDevices except the one we're interested in.
- //Then, if the device we're interested in intersects with that region, then it must be
- //overlapped.
- //
- //Another way to do this would to use the Display Manager GetNextMirroredDevice call.
- {
- GDHandle tempGD, thisWindowsGD;
- RgnHandle desktopRgn, tempRgn;
- Boolean overlapped = false;
-
- desktopRgn = NewRgn();
- tempRgn = NewRgn();
-
- if ( (desktopRgn != nil) && (tempRgn != nil) )
- {
- //Don't give me the main device if you fail
- DMGetGDeviceByDisplayID( theDisplayID, &thisWindowsGD, false );
-
- tempGD = DMGetFirstScreenDevice( dmOnlyActiveDisplays );
-
- //Build a region of all active devices except the one I'm interested in
- while ( tempGD )
- {
- if ( tempGD != thisWindowsGD )
- {
- RectRgn ( tempRgn, &(**tempGD).gdRect );
- UnionRgn ( desktopRgn, tempRgn, desktopRgn );
- }
- //Next active GDDevice
- tempGD = DMGetNextScreenDevice( tempGD, dmOnlyActiveDisplays );
- }
-
- RectRgn ( tempRgn, &(**thisWindowsGD).gdRect );
- SectRgn ( desktopRgn, tempRgn, tempRgn );
- if (! EmptyRgn(tempRgn) )
- overlapped = true;
-
- DisposeRgn(desktopRgn);
- DisposeRgn(tempRgn);
- }
-
- return overlapped;
- }
-
- void MirrorAllDisplays(Boolean mirroringOn)
- {
- GDHandle firstGD, nextGD;
- Handle displayState;
-
- firstGD = DMGetFirstScreenDevice( dmOnlyActiveDisplays );
- nextGD = firstGD;
- displayState = nil;
-
- if (DMBeginConfigureDisplays(&displayState))
- return;
-
- if (mirroringOn)
- {
- while (nextGD)
- {
- (void) DMMirrorDevices(firstGD, nextGD, displayState);
- nextGD = DMGetNextScreenDevice(nextGD, dmOnlyActiveDisplays);
- }
- }
- else
- {
- while (nextGD)
- {
- (void) DMUnmirrorDevice(nextGD, displayState);
- nextGD = DMGetNextScreenDevice(nextGD, dmOnlyActiveDisplays);
- }
- }
-
- (void) DMEndConfigureDisplays(displayState);
-
- }
-
-
- Boolean
- MenuBarOnThisScreen(GDHandle thisGD)
- {
- GDHandle nextGD;
- Boolean mainDevice = false;
- OSErr err;
-
- //Is this device the main device
- if (TestDeviceAttribute (thisGD, mainScreen)) //Account for the menu bar
- mainDevice = true;
- else
- {
- nextGD = thisGD;
- do
- {
- err = DMGetNextMirroredDevice(nextGD, &nextGD);
- if (err != noErr) //mirroring may not be supported by current software
- break;
-
- if (nextGD != nil)
- if (TestDeviceAttribute (nextGD, mainScreen)) //Account for the menu bar
- {
- mainDevice = true;
- break;
- }
- } while ((nextGD != nil) && (nextGD != thisGD));
-
- }
-
- return mainDevice;
-
- }