source: abuse/branches/pd/imlib/port/mac/RequestVideo.c @ 528

Last change on this file since 528 was 49, checked in by Sam Hocevar, 15 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 25.7 KB
Line 
1/*------------------------------------------------------------------------------
2#
3#       MacOSª Sample Code
4#       
5#       Written by: Eric Anderson
6#        AppleLink: ERIC3
7#        AOL: ERICTHREE
8#
9#       Display Manager sample code
10#
11#       RequestVideo
12#
13#       RequestVideo.c  -       C Code
14#
15#       Copyright © 1995 Apple Computer, Inc.
16#       All rights reserved.
17#
18#       5/31/95         ewa             Added RVGetCurrentVideoSetting and RVConfirmVideoRequest routines
19#                                               to make it easy to revert back to where you came from and to give
20#                                               the user a chance to confirm the new setting if the new mode was
21#                                               valid (ie: the card supports it) but not safe (the monitor may not).
22#       5/24/95         ewa             Give the kAllValidModesBit requestFlags option for safe only or all
23#                                               valid resolution timings.
24#
25#
26#
27#       Components:     PlayVideo.c                     
28#                               RequestVideo.c         
29#                               RequestVideo.h         
30#                               RequestVideo.rsrc               
31#
32#       RequestVideo demonstrates the usage of the Display Manager introduced
33#       with the PowerMacs and integrated into the system under System 7.5. With
34#       the RequestVideo sample code library, developers will be able to explore
35#       the Display Manager API by changing bit depth and screen resolution on
36#       multisync displays on built-in, NuBus, and PCI based video. Display Manager 1.0
37#       is built into the Systems included with the first PowerMacs up through System 7.5.
38#       Display Manager 2.0 is included with the release of the new PCI based PowerMacs,
39#       and will be included in post 7.5 System Software releases.
40#       
41#       It is a good idea to reset the screen(s) to the original setting before exit
42#       since the call to RVSetVideoAsScreenPrefs() may not do the right thing under
43#       Display Manager 1.0 with certain video drivers.
44#
45#       For information on the use of this sample code, please the documentation in the Read Me file
46------------------------------------------------------------------------------*/
47
48#include "RequestVideo.h"
49
50// Internal includes
51#include <Dialogs.h>
52#include <ROMDefs.h>
53#include <Devices.h>
54#include <Errors.h>
55#include <GestaltEqu.h>
56#include <Memory.h>
57#include <Palettes.h>
58#include <Slots.h>
59#include <StdIO.h>
60#include <Displays.h>
61
62#include <stdlib.h>
63
64//--------------------------------------------------------------
65//
66// Internal defines, structs, typedefs, and routine declarations
67//
68//--------------------------------------------------------------
69#define         KMonoDev                        0                                               // false (handy definitions for gdDevType settings)
70#define         kColorDev                       1                                               // true
71#define         char_Enter                      0x03                                    // for our filter proc
72#define         char_Return                     0x0D                                    //
73#define         iRevertItem                     1                                               // User buttons
74#define         iConfirmItem            2                                               //
75#define         kSecondsToConfirm       8                                               // seconds before confirm dialog is taken down
76#define         rConfirmSwtchAlrt       2735                                    // ID of alert dialog
77
78struct DepthInfo {
79        VDSwitchInfoRec                 depthSwitchInfo;                        // This is the switch mode to choose this timing/depth
80        VPBlock                                 depthVPBlock;                           // VPBlock (including size, depth and format)
81};
82typedef struct DepthInfo DepthInfo;
83
84struct ListIteratorDataRec {
85        VDTimingInfoRec                 displayModeTimingInfo;          // Contains timing flags and such
86        unsigned long                   depthBlockCount;                        // How many depths available for a particular timing
87        DepthInfo                               *depthBlocks;                           // Array of DepthInfo
88};
89typedef struct ListIteratorDataRec ListIteratorDataRec;
90
91void GetRequestTheDM1Way (              VideoRequestRecPtr requestRecPtr,
92                                                                GDHandle walkDevice);
93
94void GetRequestTheDM2Way (              VideoRequestRecPtr requestRecPtr,
95                                                                GDHandle walkDevice,
96                                                                DMDisplayModeListIteratorUPP myModeIteratorProc,
97                                                                DMListIndexType theDisplayModeCount,
98                                                                DMListType *theDisplayModeList);
99
100pascal void ModeListIterator (  void *userData,
101                                                                DMListIndexType itemIndex,
102                                                                DMDisplayModeListEntryPtr displaymodeInfo);
103
104Boolean FindBestMatch (                 VideoRequestRecPtr requestRecPtr,
105                                                                short bitDepth,
106                                                                unsigned long horizontal,
107                                                                unsigned long vertical);
108
109void GravitateMonitors (void);
110
111pascal Boolean ConfirmAlertFilter (DialogPtr dlg, EventRecord *evt, short *itemHit);
112
113//--------------------------------------------------------------
114//
115// Implementation of sample code
116//
117//--------------------------------------------------------------
118OSErr RVSetVideoRequest (VideoRequestRecPtr requestRecPtr)
119{
120        GDHandle                aMonitor;
121        Boolean                 displayMgrPresent;
122        unsigned long   displayMgrVersion;
123        OSErr                   err;
124        Boolean                 isColor;
125        long                    value = 0;
126
127        Gestalt(gestaltDisplayMgrVers, (long*)&displayMgrVersion);
128        Gestalt(gestaltDisplayMgrAttr,&value);
129        displayMgrPresent=value&(1<<gestaltDisplayMgrPresent);
130        if (displayMgrPresent)
131        {
132                if (requestRecPtr->displayMode && requestRecPtr->depthMode)
133                {
134                        if (requestRecPtr->availBitDepth == 1)  // Based on avail bit depth,
135                                isColor = KMonoDev;                                     // set the device to a mono device, or
136                        else isColor = kColorDev;                               // set the device to a color device
137                        SetDeviceAttribute(requestRecPtr->screenDevice,gdDevType,isColor);             
138                       
139                        // see how many monitors we have, aMonitor will be nil if we have only one.
140                        aMonitor = DMGetFirstScreenDevice (dmOnlyActiveDisplays);                       // get the first guy
141                        aMonitor = DMGetNextScreenDevice ( aMonitor, dmOnlyActiveDisplays );    // get the next guy
142                       
143                        if (nil == aMonitor || displayMgrVersion >= 0x00020000)
144                        {
145                                // only call DMSetDisplayMode if we have one monitor or DM2.0 is installed
146                                // since DM1.0 does not automatically gravitate monitors and our gravitate code
147                                // is not implemented.
148                                err = DMSetDisplayMode( requestRecPtr->screenDevice,    // GDevice
149                                                requestRecPtr->displayMode,                                             // DM1.0 uses this
150                                                &requestRecPtr->depthMode,                                              // DM1.0 uses this
151                                                (unsigned long) &(requestRecPtr->switchInfo),   // DM2.0 uses this rather than displayMode/depthMode combo
152                                                nil);
153                                if (noErr == err)
154                                {
155                                        // Do the monitor gravitate here if we are using a version less than DM2.0
156                                        if (displayMgrVersion < 0x00020000)
157                                                GravitateMonitors ();
158                                }
159                                else if (kDMDriverNotDisplayMgrAwareErr == err)
160                                {
161                                        // DM not supported by driver, so all we can do is set the bit depth
162                                        err = SetDepth (requestRecPtr->screenDevice, requestRecPtr->depthMode, gdDevType, isColor);
163                                }
164                        }
165                        else
166                        {
167                                // we have more than one monitor and DM1.0 is installed, so all we can do is set the bit depth
168                                err = SetDepth (requestRecPtr->screenDevice, requestRecPtr->depthMode, gdDevType, isColor);
169                        }
170                       
171                        return (err);   // we did try to set the request
172                }
173        }
174        return (-1);    // return a generic error
175}
176
177// This extern should be removed once this function is formally defined in Displays.h
178extern pascal OSErr DMUseScreenPrefs(Boolean usePrefs, Handle displayState)
179 THREEWORDINLINE(0x303C, 0x03EC, 0xABEB);
180
181OSErr RVSetVideoAsScreenPrefs (void)
182{
183        Handle          displaystate;
184        Boolean         displayMgrPresent;
185        long            value = 0;
186
187        Gestalt(gestaltDisplayMgrAttr,&value);
188        displayMgrPresent=value&(1<<gestaltDisplayMgrPresent);
189        if (displayMgrPresent)
190        {
191                DMBeginConfigureDisplays (&displaystate);       // Tell the world it is about to change
192                DMUseScreenPrefs (true, displaystate);          // Make the change
193                DMEndConfigureDisplays (displaystate);          // Tell the world the change is over
194               
195                return (noErr); // we (maybe) set the world back to a known setting
196        }
197        return (-1);    // return a generic error
198}
199
200OSErr RVGetCurrentVideoSetting (VideoRequestRecPtr requestRecPtr)
201{
202        unsigned long           displayMgrVersion;
203        OSErr                           error = paramErr;
204        CntrlParam                      pBlock;
205        VDSwitchInfoRec         switchInfo;
206        AuxDCEHandle            theDCE;
207        VDSwitchInfoRec         videoMode;             
208
209        requestRecPtr->availBitDepth                    = 0;    // init to default - you can do it if it is important to you
210        requestRecPtr->availHorizontal                  = 0;
211        requestRecPtr->availVertical                    = 0;
212        requestRecPtr->availFlags                               = 0;
213        requestRecPtr->displayMode                              = -1;
214        requestRecPtr->depthMode                                = -1;
215        requestRecPtr->switchInfo.csMode                = 0;
216        requestRecPtr->switchInfo.csData                = 0;
217        requestRecPtr->switchInfo.csPage                = 0;
218        requestRecPtr->switchInfo.csBaseAddr    = 0;
219        requestRecPtr->switchInfo.csReserved    = 0;
220       
221        Gestalt(gestaltDisplayMgrVers, (long*)&displayMgrVersion);
222        if (requestRecPtr->screenDevice)
223        {
224                if (displayMgrVersion >= 0x00020000)
225                {       // get the info the DM 2.0 way
226                        error = DMGetDisplayMode(requestRecPtr->screenDevice, &switchInfo);
227                        if (noErr == error)
228                        {
229                                requestRecPtr->depthMode                        = switchInfo.csMode;
230                                requestRecPtr->displayMode                      = switchInfo.csData;
231                                requestRecPtr->switchInfo.csMode        = switchInfo.csMode;
232                                requestRecPtr->switchInfo.csData        = switchInfo.csData;
233                        }
234                        return (error); // we (maybe) set the world back to a known setting
235                }
236                else
237                {       // get the info the DM 1.0 way
238                        videoMode.csMode = -1;          // init to bogus value
239                        videoMode.csData = -1;          // init to bogus value                 
240                        pBlock.ioNamePtr = nil;
241                        pBlock.ioCRefNum = (*(requestRecPtr->screenDevice))->gdRefNum;
242                        pBlock.csCode = cscGetCurMode;
243                        *(Ptr *)&pBlock.csParam[0] = (Ptr)&videoMode;
244                               
245                        error = PBStatusSync((ParmBlkPtr )&pBlock);     // ask the driver first....since we trust it the most
246                               
247                        if ( noErr == error && ((-1 == videoMode.csMode) || (-1 == videoMode.csData)) )
248                                error = statusErr;
249                       
250                        if (noErr != error)     // if the driver has no clue fill it videoMode by hand as a last resort
251                        {       
252                                theDCE = (AuxDCEHandle)GetDCtlEntry((*(requestRecPtr->screenDevice))->gdRefNum);
253                               
254                                if( theDCE )
255                                {
256                                        videoMode.csData = (unsigned char)(*theDCE)->dCtlSlotId;
257                                        videoMode.csMode = (*(requestRecPtr->screenDevice))->gdMode;
258                                        error = noErr;
259                                }
260                        }
261                        if (noErr == error)     // Set our data
262                        {
263                                requestRecPtr->displayMode                      = videoMode.csData;
264                                requestRecPtr->depthMode                        = videoMode.csMode;
265                                requestRecPtr->switchInfo.csMode        = videoMode.csMode;
266                                requestRecPtr->switchInfo.csData        = videoMode.csData;
267                        }
268                        return (error); // we (maybe) set the world back to a known setting
269                }
270        }
271        return (-1);
272}
273
274pascal Boolean ConfirmAlertFilter(DialogPtr theDialog, EventRecord *theEvent, short *itemHit)
275{
276        char charCode;
277        Boolean enterORreturn;
278        Boolean returnValue = false;
279
280        if (0 == GetWRefCon(theDialog))
281                SetWRefCon (theDialog,TickCount());
282        else
283        {
284                if (GetWRefCon(theDialog) + kSecondsToConfirm * 60 < TickCount())
285                {
286                        returnValue = true;
287                        theEvent->what = nullEvent;
288                        *itemHit = 1;
289                }
290                else
291                {
292                        if (theEvent->what == keyDown)
293                        {
294                                charCode = (char)theEvent->message & charCodeMask;
295                                enterORreturn = (charCode == (char)char_Return) || (charCode == (char)char_Enter);
296                                if (enterORreturn)
297                                {
298                                        theEvent->what = nullEvent;
299                                        returnValue = true;
300                                        *itemHit = iRevertItem;
301                                        if (enterORreturn && (0 != (theEvent->modifiers & optionKey)))
302                                        {
303                                                *itemHit = iConfirmItem;
304                                        }
305                                }
306                        }
307                }
308        }
309        return (returnValue);
310}
311
312OSErr RVConfirmVideoRequest (VideoRequestRecPtr requestRecPtr)
313{
314        short                   alertReturn;            // Alert() return value
315        ModalFilterUPP  confirmFilterUPP;       // got to have us one of them new fangled UPP thingies
316       
317        if (requestRecPtr->availFlags & 1<<kModeValidNotSafeBit)
318        {       // new mode is valid but not safe, so ask user to confirm
319                SetCursor(&qd.arrow);                                                                           // have to show the arrow
320
321                confirmFilterUPP = NewModalFilterProc (ConfirmAlertFilter);     // create a new modal filter proc UPP
322                alertReturn = Alert(rConfirmSwtchAlrt, confirmFilterUPP);       // alert the user
323                DisposeRoutineDescriptor (confirmFilterUPP);                            // of course there is no DisposeModalFilterProc...
324               
325                if (alertReturn != iConfirmItem)
326                        return (-1);                                                    // tell the caller to switch back to a known setting
327                else return (noErr);                                            // all is well with the new setting, just leave it
328        }
329        return (noErr);                                                                 // the mode was safe, so do nothing
330}
331
332
333OSErr RVRequestVideoSetting (VideoRequestRecPtr requestRecPtr)
334{
335        Boolean                                                 displayMgrPresent;
336        short                                                   iCount = 0;                                     // just a counter of GDevices we have seen
337        DMDisplayModeListIteratorUPP    myModeIteratorProc = nil;       // for DM2.0 searches
338        SpBlock                                                 spBlock;
339        Boolean                                                 suppliedGDevice;       
340        DisplayIDType                                   theDisplayID;                           // for DM2.0 searches
341        DMListIndexType                                 theDisplayModeCount;            // for DM2.0 searches
342        DMListType                                              theDisplayModeList;                     // for DM2.0 searches
343        long                                                    value = 0;
344        GDHandle                                                walkDevice = nil;                       // for everybody
345
346        Gestalt(gestaltDisplayMgrAttr,&value);
347        displayMgrPresent=value&(1<<gestaltDisplayMgrPresent);
348        displayMgrPresent=displayMgrPresent && (SVersion(&spBlock)==noErr);     // need slot manager
349        if (displayMgrPresent)
350        {
351                // init the needed data before we start
352                if (requestRecPtr->screenDevice)                                                        // user wants a specifc device?
353                {
354                        walkDevice = requestRecPtr->screenDevice;
355                        suppliedGDevice = true;
356                }
357                else
358                {
359                        walkDevice = DMGetFirstScreenDevice (dmOnlyActiveDisplays);                     // for everybody
360                        suppliedGDevice = false;
361                }
362               
363                myModeIteratorProc = NewDMDisplayModeListIteratorProc(ModeListIterator);        // for DM2.0 searches
364       
365                // Note that we are hosed if somebody changes the gdevice list behind our backs while we are iterating....
366                // ...now do the loop if we can start
367                if( walkDevice && myModeIteratorProc) do // start the search
368                {
369                        iCount++;               // GDevice we are looking at (just a counter)
370                        if( noErr == DMGetDisplayIDByGDevice( walkDevice, &theDisplayID, false ) )      // DM1.0 does not need this, but it fits in the loop
371                        {
372                                theDisplayModeCount = 0;        // for DM2.0 searches
373                                if (noErr == DMNewDisplayModeList(theDisplayID, 0, 0, &theDisplayModeCount, &theDisplayModeList) )
374                                {
375                                        // search NuBus & PCI the new kool way through Display Manager 2.0
376                                        GetRequestTheDM2Way (requestRecPtr, walkDevice, myModeIteratorProc, theDisplayModeCount, &theDisplayModeList);
377                                        DMDisposeList(theDisplayModeList);      // now toss the lists for this gdevice and go on to the next one
378                                }
379                                else
380                                {
381                                        // search NuBus only the old disgusting way through the slot manager
382                                        GetRequestTheDM1Way (requestRecPtr, walkDevice);
383                                }
384                        }
385                } while ( !suppliedGDevice && nil != (walkDevice = DMGetNextScreenDevice ( walkDevice, dmOnlyActiveDisplays )) );       // go until no more gdevices
386                if( myModeIteratorProc )
387                        DisposeRoutineDescriptor(myModeIteratorProc);
388                return (noErr); // we were able to get the look for a match
389        }
390        return (-1);            // return a generic error
391}
392
393void GetRequestTheDM1Way (VideoRequestRecPtr requestRecPtr, GDHandle walkDevice)
394{
395        AuxDCEHandle myAuxDCEHandle;
396        unsigned long   depthMode;
397        unsigned long   displayMode;
398        OSErr                   error;
399        OSErr                   errorEndOfTimings;
400        short                   height;
401        short                   jCount = 0;
402        Boolean                 modeOk;
403        SpBlock                 spAuxBlock;
404        SpBlock                 spBlock;
405        unsigned long   switchFlags;
406        VPBlock                 *vpData;
407        short                   width;
408
409        myAuxDCEHandle = (AuxDCEHandle) GetDCtlEntry((**walkDevice).gdRefNum); 
410        spBlock.spSlot = (**myAuxDCEHandle).dCtlSlot;
411        spBlock.spID = (**myAuxDCEHandle).dCtlSlotId;
412        spBlock.spExtDev = (**myAuxDCEHandle).dCtlExtDev;
413        spBlock.spHwDev = 0;                                                            // we are going to get this pup
414        spBlock.spParamData = 1<<foneslot;                                      // this slot, enabled, and it better be here.
415        spBlock.spTBMask = 3;                                                           // don't have constants for this yet
416        errorEndOfTimings = SGetSRsrc(&spBlock);                        // get the spDrvrHW so we know the ID of this puppy. This is important
417                                                                                                                // since some video cards support more than one display, and the spDrvrHW
418                                                                                                                // ID can, and will, be used to differentiate them.
419       
420        if ( noErr == errorEndOfTimings )
421        {
422                // reinit the param block for the SGetTypeSRsrc loop, keep the spDrvrHW we just got
423                spBlock.spID = 0;                                                               // start at zero,
424                spBlock.spTBMask = 2;                                                   // 0b0010 - ignore DrvrSW - why ignore the SW side? Is it not important for video?
425                spBlock.spParamData = (1<<fall) + (1<<foneslot) + (1<<fnext);   // 0b0111 - this slot, enabled or disabled, so we even get 640x399 on Blackbird
426                spBlock.spCategory=catDisplay;
427                spBlock.spCType=typeVideo;
428                errorEndOfTimings = SGetTypeSRsrc(&spBlock);    // but only on 7.0 systems, not a problem since we require DM1.0
429               
430                // now, loop through all the timings for this GDevice
431                if ( noErr == errorEndOfTimings ) do
432                {
433                        // now, loop through all possible depth modes for this timing mode
434                        displayMode = (unsigned char)spBlock.spID;      // "timing mode, ie:resource ref number"
435                        for (jCount = firstVidMode; jCount<= sixthVidMode; jCount++)
436                        {
437                                depthMode = jCount;             // vid mode
438                                error = DMCheckDisplayMode(walkDevice,displayMode,depthMode,&switchFlags,0,&modeOk);
439       
440                                // only if the mode is safe or we override it with the kAllValidModesBit request flag
441                                if (    noErr == error &&
442                                                modeOk &&
443                                                (       switchFlags & 1<<kNoSwitchConfirmBit ||
444                                                        requestRecPtr->requestFlags & 1<<kAllValidModesBit
445                                                )
446                                        )
447                                {
448                                        // have a good displayMode/depthMode combo - now lets look inside
449                                        spAuxBlock = spBlock;                           // don't ruin the iteration spBlock!!
450                                        spAuxBlock.spID = depthMode;            // vid mode
451                                        error=SFindStruct(&spAuxBlock);         // get back a new spsPointer
452                                        if (noErr == error)                                     // keep going if no errorÉ
453                                        {
454                                                spAuxBlock.spID = 0x01;                 // mVidParams request
455                                                error=SGetBlock (&spAuxBlock);  // use the new spPointer and get back...a NewPtr'ed spResult
456                                                if (noErr == error)                             // Ékeep going if no errorÉ
457                                                {                                                               // We have data! lets have a look
458                                                        vpData = (VPBlock*)spAuxBlock.spResult;
459                                                        height = vpData->vpBounds.bottom;       // left and top are usually zero
460                                                        width = vpData->vpBounds.right;
461                                                       
462                                                        if (FindBestMatch (requestRecPtr, vpData->vpPixelSize, vpData->vpBounds.right, vpData->vpBounds.bottom))
463                                                        {
464                                                                requestRecPtr->screenDevice = walkDevice;
465                                                                requestRecPtr->availBitDepth = vpData->vpPixelSize;
466                                                                requestRecPtr->availHorizontal = vpData->vpBounds.right;
467                                                                requestRecPtr->availVertical = vpData->vpBounds.bottom;
468                                                                requestRecPtr->displayMode = displayMode;
469                                                                requestRecPtr->depthMode = depthMode;
470                                                                requestRecPtr->switchInfo.csMode = depthMode;                           // fill in for completeness
471                                                                requestRecPtr->switchInfo.csData = displayMode;
472                                                                requestRecPtr->switchInfo.csPage = 0;
473                                                                requestRecPtr->switchInfo.csBaseAddr = 0;
474                                                                requestRecPtr->switchInfo.csReserved = 0;
475                                                                if (switchFlags & 1<<kNoSwitchConfirmBit)
476                                                                        requestRecPtr->availFlags = 0;                                                  // mode safe
477                                                                else requestRecPtr->availFlags = 1<<kModeValidNotSafeBit;       // mode valid but not safe, requires user validation of mode switch
478                                                        }
479
480                                                        if (spAuxBlock.spResult) DisposePtr ((Ptr)spAuxBlock.spResult); // toss this puppy when done
481                                                }
482                                        }
483                                }
484                        }
485                        // go around again, looking for timing modes for this GDevice
486                        spBlock.spTBMask = 2;           // ignore DrvrSW
487                        spBlock.spParamData =  (1<<fall) + (1<<foneslot) + (1<<fnext);  // next resource, this slot, whether enabled or disabled
488                        errorEndOfTimings = SGetTypeSRsrc(&spBlock);    // and get the next timing mode
489                } while ( noErr == errorEndOfTimings ); // until the end of this GDevice
490        }
491
492}
493
494pascal void ModeListIterator(void *userData, DMListIndexType, DMDisplayModeListEntryPtr displaymodeInfo)
495{
496        unsigned long                   depthCount;
497        short                                   iCount;
498        ListIteratorDataRec             *myIterateData          = (ListIteratorDataRec*) userData;
499        DepthInfo                               *myDepthInfo;
500       
501        // set user data in a round about way
502        myIterateData->displayModeTimingInfo            = *displaymodeInfo->displayModeTimingInfo;
503       
504        // now get the DMDepthInfo info into memory we own
505        depthCount = displaymodeInfo->displayModeDepthBlockInfo->depthBlockCount;
506        myDepthInfo = (DepthInfo*)NewPtrClear(depthCount * sizeof(DepthInfo));
507
508        // set the info for the caller
509        myIterateData->depthBlockCount = depthCount;
510        myIterateData->depthBlocks = myDepthInfo;
511
512        // and fill out all the entries
513        if (depthCount) for (iCount=0; iCount < depthCount; iCount++)
514        {
515                myDepthInfo[iCount].depthSwitchInfo =
516                        *displaymodeInfo->displayModeDepthBlockInfo->depthVPBlock[iCount].depthSwitchInfo;
517                myDepthInfo[iCount].depthVPBlock =
518                        *displaymodeInfo->displayModeDepthBlockInfo->depthVPBlock[iCount].depthVPBlock;
519        }
520}
521
522void GetRequestTheDM2Way (      VideoRequestRecPtr requestRecPtr,
523                                                        GDHandle walkDevice,
524                                                        DMDisplayModeListIteratorUPP myModeIteratorProc,
525                                                        DMListIndexType theDisplayModeCount,
526                                                        DMListType *theDisplayModeList)
527{
528        short                                   jCount;
529        short                                   kCount;
530        ListIteratorDataRec             searchData;
531
532        searchData.depthBlocks = nil;
533        // get the mode lists for this GDevice
534        for (jCount=0; jCount<theDisplayModeCount; jCount++)            // get info on all the resolution timings
535        {
536                DMGetIndexedDisplayModeFromList(*theDisplayModeList, jCount, 0, myModeIteratorProc, &searchData);
537               
538                // for all the depths for this resolution timing (mode)...
539                if (searchData.depthBlockCount) for (kCount = 0; kCount < searchData.depthBlockCount; kCount++)
540                {
541                        // only if the mode is valid and is safe or we override it with the kAllValidModesBit request flag
542                        if      (       searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeValid &&
543                                        (       searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeSafe ||
544                                                requestRecPtr->requestFlags & 1<<kAllValidModesBit
545                                        )
546                                )
547                        {
548                                if (FindBestMatch (     requestRecPtr,
549                                                                        searchData.depthBlocks[kCount].depthVPBlock.vpPixelSize,
550                                                                        searchData.depthBlocks[kCount].depthVPBlock.vpBounds.right,
551                                                                        searchData.depthBlocks[kCount].depthVPBlock.vpBounds.bottom))
552                                {
553                                        requestRecPtr->screenDevice = walkDevice;
554                                        requestRecPtr->availBitDepth = searchData.depthBlocks[kCount].depthVPBlock.vpPixelSize;
555                                        requestRecPtr->availHorizontal = searchData.depthBlocks[kCount].depthVPBlock.vpBounds.right;
556                                        requestRecPtr->availVertical = searchData.depthBlocks[kCount].depthVPBlock.vpBounds.bottom;
557                                       
558                                        // now set the important info for DM to set the display
559                                        requestRecPtr->depthMode = searchData.depthBlocks[kCount].depthSwitchInfo.csMode;
560                                        requestRecPtr->displayMode = searchData.depthBlocks[kCount].depthSwitchInfo.csData;
561                                        requestRecPtr->switchInfo = searchData.depthBlocks[kCount].depthSwitchInfo;
562                                        if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeSafe)
563                                                requestRecPtr->availFlags = 0;                                                  // mode safe
564                                        else requestRecPtr->availFlags = 1<<kModeValidNotSafeBit;       // mode valid but not safe, requires user validation of mode switch
565       
566                                }
567                        }
568
569                }
570       
571                if (searchData.depthBlocks)
572                {
573                        DisposePtr ((Ptr)searchData.depthBlocks);       // toss for this timing mode of this gdevice
574                        searchData.depthBlocks = nil;                           // init it just so we know
575                }
576        }
577}
578
579Boolean FindBestMatch (VideoRequestRecPtr requestRecPtr, short bitDepth, unsigned long horizontal, unsigned long vertical)
580{
581        // ¥¥ do the big comparison ¥¥
582        // first time only if   (no mode yet) and
583        //                                              (bounds are greater/equal or kMaximizeRes not set) and
584        //                                              (depth is less/equal or kShallowDepth not set) and
585        //                                              (request match or kAbsoluteRequest not set)
586        if      (       nil == requestRecPtr->displayMode
587                        &&
588                        (       (horizontal >= requestRecPtr->reqHorizontal &&
589                                vertical >= requestRecPtr->reqVertical)
590                                ||                                                                                                             
591                                !(requestRecPtr->requestFlags & 1<<kMaximizeResBit)     
592                        )
593                        &&
594                        (       bitDepth <= requestRecPtr->reqBitDepth ||       
595                                !(requestRecPtr->requestFlags & 1<<kShallowDepthBit)           
596                        )
597                        &&
598                        (       (horizontal == requestRecPtr->reqHorizontal && 
599                                vertical == requestRecPtr->reqVertical &&
600                                bitDepth == requestRecPtr->reqBitDepth)
601                                ||
602                                !(requestRecPtr->requestFlags & 1<<kAbsoluteRequestBit)
603                        )
604                )
605                {
606                        // go ahead and set the new values
607                        return (true);
608                }
609        else    // can we do better than last time?
610        {
611                // if   (kBitDepthPriority set and avail not equal req) and
612                //              ((depth is greater avail and depth is less/equal req) or kShallowDepth not set) and
613                //              (avail depth less reqested and new greater avail)
614                //              (request match or kAbsoluteRequest not set)
615                if      (       (       requestRecPtr->requestFlags & 1<<kBitDepthPriorityBit &&
616                                        requestRecPtr->availBitDepth != requestRecPtr->reqBitDepth
617                                )
618                                &&
619                                (       (       bitDepth > requestRecPtr->availBitDepth &&
620                                                bitDepth <= requestRecPtr->reqBitDepth
621                                        )
622                                        ||
623                                        !(requestRecPtr->requestFlags & 1<<kShallowDepthBit)   
624                                )
625                                &&
626                                (       requestRecPtr->availBitDepth < requestRecPtr->reqBitDepth &&
627                                        bitDepth > requestRecPtr->availBitDepth
628                                )
629                                &&
630                                (       (horizontal == requestRecPtr->reqHorizontal && 
631                                        vertical == requestRecPtr->reqVertical &&
632                                        bitDepth == requestRecPtr->reqBitDepth)
633                                        ||
634                                        !(requestRecPtr->requestFlags & 1<<kAbsoluteRequestBit)
635                                )
636                        )
637                {
638                        // go ahead and set the new values
639                        return (true);
640                }
641                else
642                {
643                        // match resolution: minimize Æh & Æv
644                        if      (       abs((requestRecPtr->reqHorizontal - horizontal)) <=
645                                        abs((requestRecPtr->reqHorizontal - requestRecPtr->availHorizontal)) &&
646                                        abs((requestRecPtr->reqVertical - vertical)) <=
647                                        abs((requestRecPtr->reqVertical - requestRecPtr->availVertical))
648                                )
649                        {
650                                // now we have a smaller or equal delta
651                                //      if (h or v greater/equal to request or kMaximizeRes not set)
652                                if (    (horizontal >= requestRecPtr->reqHorizontal &&
653                                                vertical >= requestRecPtr->reqVertical)
654                                                ||
655                                                !(requestRecPtr->requestFlags & 1<<kMaximizeResBit)
656                                        )
657                                {
658                                        // if   (depth is equal or kBitDepthPriority not set) and
659                                        //              (depth is less/equal or kShallowDepth not set) and
660                                        //              ([h or v not equal] or [avail depth less reqested and new greater avail] or depth equal avail) and
661                                        //              (request match or kAbsoluteRequest not set)
662                                        if      (       (       requestRecPtr->availBitDepth == bitDepth ||                     
663                                                                !(requestRecPtr->requestFlags & 1<<kBitDepthPriorityBit)
664                                                        )
665                                                        &&
666                                                        (       bitDepth <= requestRecPtr->reqBitDepth ||       
667                                                                !(requestRecPtr->requestFlags & 1<<kShallowDepthBit)           
668                                                        )
669                                                        &&
670                                                        (       (requestRecPtr->availHorizontal != horizontal ||
671                                                                requestRecPtr->availVertical != vertical)
672                                                                ||
673                                                                (requestRecPtr->availBitDepth < requestRecPtr->reqBitDepth &&
674                                                                bitDepth > requestRecPtr->availBitDepth)
675                                                                ||
676                                                                (bitDepth == requestRecPtr->reqBitDepth)
677                                                        )
678                                                        &&
679                                                        (       (horizontal == requestRecPtr->reqHorizontal && 
680                                                                vertical == requestRecPtr->reqVertical &&
681                                                                bitDepth == requestRecPtr->reqBitDepth)
682                                                                ||
683                                                                !(requestRecPtr->requestFlags & 1<<kAbsoluteRequestBit)
684                                                        )
685                                                )
686                                        {
687                                                // go ahead and set the new values
688                                                return (true);
689                                        }
690                                }
691                        }
692                }
693        }
694        return (false);
695}
696
697void GravitateMonitors (void)
698{
699        // do the magic gravitation here
700}
Note: See TracBrowser for help on using the repository browser.