]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/display.cpp
Fix for non-CG mode
[wxWidgets.git] / src / mac / carbon / display.cpp
CommitLineData
a536e411 1/////////////////////////////////////////////////////////////////////////////
ef1717a9 2// Name: src/mac/carbon/display.cpp
a536e411 3// Purpose: Mac implementation of wxDisplay class
cc9d56b0 4// Author: Ryan Norton & Brian Victor
ef1717a9 5// Modified by: Royce Mitchell III, Vadim Zeitlin
a536e411
JS
6// Created: 06/21/02
7// RCS-ID: $Id$
77ffb593 8// Copyright: (c) wxWidgets team
65571936 9// Licence: wxWindows licence
a536e411
JS
10/////////////////////////////////////////////////////////////////////////////
11
ef1717a9
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
a536e411
JS
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#if wxUSE_DISPLAY
27
df91131c
WS
28#include "wx/display.h"
29
a536e411 30#ifndef WX_PRECOMP
ad9835c9
WS
31 #include "wx/dynarray.h"
32 #include "wx/log.h"
df91131c 33 #include "wx/string.h"
dd05139a 34 #include "wx/gdicmn.h"
a536e411
JS
35#endif
36
37#ifdef __DARWIN__
38 #include <Carbon/Carbon.h>
39#else
7c4a8e41 40 #include <Gestalt.h>
a536e411
JS
41 #include <Displays.h>
42 #include <Quickdraw.h>
a5714345 43 #include <Video.h> // for VDSwitchInfoRec
7c4a8e41 44 #include <FixMath.h>
cd17aeff 45 #include <Debugging.h>
a536e411
JS
46#endif
47
ef1717a9 48#include "wx/display_impl.h"
a536e411
JS
49
50// ----------------------------------------------------------------------------
ef1717a9 51// display classes implementation
a536e411
JS
52// ----------------------------------------------------------------------------
53
20b69855
SC
54#ifdef __WXMAC_OSX__
55
ef1717a9 56class wxDisplayImplMacOSX : public wxDisplayImpl
20b69855
SC
57{
58public:
4e675101 59 wxDisplayImplMacOSX(unsigned n, CGDirectDisplayID id)
f37c35d7
VZ
60 : wxDisplayImpl(n),
61 m_id(id)
62 {
63 }
ef1717a9
VZ
64
65 virtual wxRect GetGeometry() const;
0d045709 66 virtual wxRect GetClientArea() const;
ef1717a9
VZ
67 virtual wxString GetName() const { return wxString(); }
68
69 virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const;
70 virtual wxVideoMode GetCurrentMode() const;
71 virtual bool ChangeMode(const wxVideoMode& mode);
72
73private:
20b69855 74 CGDirectDisplayID m_id;
ef1717a9
VZ
75
76 DECLARE_NO_COPY_CLASS(wxDisplayImplMacOSX)
20b69855
SC
77};
78
ef1717a9
VZ
79class wxDisplayFactoryMacOSX : public wxDisplayFactory
80{
81public:
6a5cb3b7 82 wxDisplayFactoryMacOSX() {}
ef1717a9 83
4e675101
PC
84 virtual wxDisplayImpl *CreateDisplay(unsigned n);
85 virtual unsigned GetCount();
ef1717a9
VZ
86 virtual int GetFromPoint(const wxPoint& pt);
87
88protected:
89 DECLARE_NO_COPY_CLASS(wxDisplayFactoryMacOSX)
90};
91
92// ============================================================================
93// wxDisplayFactoryMacOSX implementation
94// ============================================================================
95
4e675101 96unsigned wxDisplayFactoryMacOSX::GetCount()
20b69855
SC
97{
98 CGDisplayCount count;
ef1717a9
VZ
99#ifdef __WXDEBUG__
100 CGDisplayErr err =
101#endif
102 CGGetActiveDisplayList(0, NULL, &count);
20b69855
SC
103
104 wxASSERT(err == CGDisplayNoErr);
a5714345 105
20b69855
SC
106 return count;
107}
108
ef1717a9 109int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint& p)
d0ee33f5 110{
20b69855
SC
111 CGPoint thePoint = {(float)p.x, (float)p.y};
112 CGDirectDisplayID theID;
113 CGDisplayCount theCount;
114 CGDisplayErr err = CGGetDisplaysWithPoint(thePoint, 1, &theID, &theCount);
115 wxASSERT(err == CGDisplayNoErr);
a5714345 116
ef1717a9 117 int nWhich = wxNOT_FOUND;
d0ee33f5 118
20b69855
SC
119 if (theCount)
120 {
121 theCount = GetCount();
122 CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount];
123 err = CGGetActiveDisplayList(theCount, theIDs, &theCount);
124 wxASSERT(err == CGDisplayNoErr);
125
a5714345 126 for (nWhich = 0; nWhich < (int) theCount; ++nWhich)
20b69855 127 {
a5714345 128 if (theIDs[nWhich] == theID)
20b69855
SC
129 break;
130 }
d0ee33f5 131
a5714345 132 delete [] theIDs;
d0ee33f5 133
a5714345 134 if (nWhich == (int) theCount)
20b69855
SC
135 {
136 wxFAIL_MSG(wxT("Failed to find display in display list"));
ef1717a9 137 nWhich = wxNOT_FOUND;
20b69855
SC
138 }
139 }
d0ee33f5 140
20b69855 141 return nWhich;
a5714345 142}
20b69855 143
4e675101 144wxDisplayImpl *wxDisplayFactoryMacOSX::CreateDisplay(unsigned n)
20b69855
SC
145{
146 CGDisplayCount theCount = GetCount();
147 CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount];
20b69855 148
ef1717a9
VZ
149#ifdef __WXDEBUG__
150 CGDisplayErr err =
151#endif
152 CGGetActiveDisplayList(theCount, theIDs, &theCount);
a5714345
DS
153
154 wxASSERT( err == CGDisplayNoErr );
ef1717a9 155 wxASSERT( n < theCount );
d0ee33f5 156
f37c35d7 157 wxDisplayImplMacOSX *display = new wxDisplayImplMacOSX(n, theIDs[n]);
d0ee33f5 158
a5714345 159 delete [] theIDs;
ef1717a9
VZ
160
161 return display;
20b69855
SC
162}
163
ef1717a9
VZ
164// ============================================================================
165// wxDisplayImplMacOSX implementation
166// ============================================================================
167
168wxRect wxDisplayImplMacOSX::GetGeometry() const
20b69855 169{
ef1717a9 170 CGRect theRect = CGDisplayBounds(m_id);
d0ee33f5
WS
171 return wxRect( (int)theRect.origin.x,
172 (int)theRect.origin.y,
173 (int)theRect.size.width,
a5714345 174 (int)theRect.size.height ); //floats
20b69855
SC
175}
176
0d045709
VZ
177wxRect wxDisplayImplMacOSX::GetClientArea() const
178{
179 // VZ: I don't know how to get client area for arbitrary display but
180 // wxGetClientDisplayRect() does work correctly for at least the main
181 // one (TODO: do it correctly for the other displays too)
182 if ( IsPrimary() )
183 return wxGetClientDisplayRect();
184
185 return wxDisplayImpl::GetClientArea();
186}
187
20b69855
SC
188static int wxCFDictKeyToInt( CFDictionaryRef desc, CFStringRef key )
189{
a5714345
DS
190 CFNumberRef value = (CFNumberRef) CFDictionaryGetValue( desc, key );
191 if (value == NULL)
192 return 0;
193
20b69855 194 int num = 0;
a5714345 195 CFNumberGetValue( value, kCFNumberIntType, &num );
20b69855 196
20b69855
SC
197 return num;
198}
199
ef1717a9 200wxArrayVideoModes wxDisplayImplMacOSX::GetModes(const wxVideoMode& mode) const
20b69855 201{
a5714345 202 wxArrayVideoModes resultModes;
d0ee33f5 203
ef1717a9 204 CFArrayRef theArray = CGDisplayAvailableModes( m_id );
20b69855 205
a5714345 206 for (CFIndex i = 0; i < CFArrayGetCount(theArray); ++i)
20b69855 207 {
a5714345 208 CFDictionaryRef theValue = (CFDictionaryRef) CFArrayGetValueAtIndex( theArray, i );
d0ee33f5 209
a5714345
DS
210 wxVideoMode theMode(
211 wxCFDictKeyToInt( theValue, kCGDisplayWidth ),
212 wxCFDictKeyToInt( theValue, kCGDisplayHeight ),
213 wxCFDictKeyToInt( theValue, kCGDisplayBitsPerPixel ),
214 wxCFDictKeyToInt( theValue, kCGDisplayRefreshRate ));
d0ee33f5 215
a5714345
DS
216 if (theMode.Matches( mode ))
217 resultModes.Add( theMode );
20b69855 218 }
d0ee33f5 219
a5714345 220 return resultModes;
20b69855
SC
221}
222
ef1717a9 223wxVideoMode wxDisplayImplMacOSX::GetCurrentMode() const
20b69855 224{
ef1717a9 225 CFDictionaryRef theValue = CGDisplayCurrentMode( m_id );
d0ee33f5 226
a5714345
DS
227 return wxVideoMode(
228 wxCFDictKeyToInt( theValue, kCGDisplayWidth ),
229 wxCFDictKeyToInt( theValue, kCGDisplayHeight ),
230 wxCFDictKeyToInt( theValue, kCGDisplayBitsPerPixel ),
231 wxCFDictKeyToInt( theValue, kCGDisplayRefreshRate ));
20b69855
SC
232}
233
ef1717a9 234bool wxDisplayImplMacOSX::ChangeMode( const wxVideoMode& mode )
20b69855 235{
a5714345
DS
236 // Changing to default mode (wxDefaultVideoMode) doesn't
237 // work because we don't have access to the system's 'scrn'
238 // resource which holds the user's mode which the system
239 // will return to after this app is done
20b69855 240 boolean_t bExactMatch;
a5714345 241 CFDictionaryRef theCGMode = CGDisplayBestModeForParametersAndRefreshRate(
ef1717a9 242 m_id,
a5714345
DS
243 (size_t)mode.bpp,
244 (size_t)mode.w,
245 (size_t)mode.h,
246 (double)mode.refresh,
247 &bExactMatch );
d0ee33f5 248
20b69855 249 bool bOK = bExactMatch;
d0ee33f5 250
a5714345 251 if (bOK)
ef1717a9 252 bOK = CGDisplaySwitchToMode( m_id, theCGMode ) == CGDisplayNoErr;
20b69855
SC
253
254 return bOK;
255}
256
ef1717a9
VZ
257// ============================================================================
258// wxDisplay::CreateFactory()
259// ============================================================================
260
261/* static */ wxDisplayFactory *wxDisplay::CreateFactory()
20b69855 262{
ef1717a9 263 return new wxDisplayFactoryMacOSX;
20b69855
SC
264}
265
ef1717a9 266#else // !__WXMAC_OSX__
20b69855 267
ef1717a9 268class wxDisplayImplMac : public wxDisplayImpl
a536e411
JS
269{
270public:
4e675101 271 wxDisplayImplMac(unsigned n, GDHandle hndl)
f37c35d7
VZ
272 : wxDisplayImpl(n),
273 m_hndl(hndl)
274 {
275 }
ef1717a9
VZ
276
277 virtual wxRect GetGeometry() const;
278 virtual wxString GetName() const { return wxString(); }
279
280 virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const;
281 virtual wxVideoMode GetCurrentMode() const;
282 virtual bool ChangeMode(const wxVideoMode& mode);
283
284private:
e40298d5 285 GDHandle m_hndl;
ef1717a9
VZ
286
287 DECLARE_NO_COPY_CLASS(wxDisplayImplMac)
288};
289
290class wxDisplayFactoryMac : public wxDisplayFactory
291{
292public:
293 wxDisplayFactoryMac();
294
4e675101
PC
295 virtual wxDisplayImpl *CreateDisplay(unsigned n);
296 virtual unsigned GetCount();
ef1717a9
VZ
297 virtual int GetFromPoint(const wxPoint& pt);
298
299protected:
300 DECLARE_NO_COPY_CLASS(wxDisplayFactoryMac)
a536e411
JS
301};
302
ef1717a9
VZ
303// ============================================================================
304// wxDisplayFactoryMac implementation
305// ============================================================================
306
4e675101 307unsigned wxDisplayFactoryMac::GetCount()
a536e411 308{
4e675101 309 unsigned num = 0;
ef1717a9
VZ
310 GDHandle hndl = DMGetFirstScreenDevice(true);
311 while(hndl)
a536e411
JS
312 {
313 num++;
314 hndl = DMGetNextScreenDevice(hndl, true);
315 }
316 return num;
317}
318
ef1717a9 319int wxDisplayFactoryMac::GetFromPoint(const wxPoint &p)
a536e411 320{
4e675101 321 unsigned num = 0;
ef1717a9
VZ
322 GDHandle hndl = DMGetFirstScreenDevice(true);
323 while(hndl)
a536e411
JS
324 {
325 Rect screenrect = (*hndl)->gdRect;
326 if (p.x >= screenrect.left &&
327 p.x <= screenrect.right &&
328 p.y >= screenrect.top &&
329 p.y <= screenrect.bottom)
330 {
331 return num;
332 }
333 num++;
334 hndl = DMGetNextScreenDevice(hndl, true);
335 }
a5714345 336
ef1717a9 337 return wxNOT_FOUND;
a536e411
JS
338}
339
4e675101 340wxDisplayImpl *wxDisplayFactoryMac::CreateDisplay(unsigned n)
a536e411 341{
4e675101 342 unsigned nOrig = n;
f37c35d7 343
ef1717a9
VZ
344 GDHandle hndl = DMGetFirstScreenDevice(true);
345 while(hndl)
a536e411 346 {
ef1717a9
VZ
347 if (n == 0)
348 {
f37c35d7 349 return new wxDisplayImplMac(nOrig, hndl);
ef1717a9
VZ
350 }
351 n--;
a536e411
JS
352 hndl = DMGetNextScreenDevice(hndl, true);
353 }
a536e411 354
ef1717a9 355 return NULL;
a536e411
JS
356}
357
ef1717a9
VZ
358// ============================================================================
359// wxDisplayImplMac implementation
360// ============================================================================
a536e411 361
ef1717a9 362wxRect wxDisplayImplMac::GetGeometry() const
a536e411 363{
ef1717a9
VZ
364 Rect screenrect = (*m_hndl)->gdRect;
365 return wxRect(screenrect.left, screenrect.top,
366 screenrect.right - screenrect.left,
367 screenrect.bottom - screenrect.top);
1e1cc1ce
DS
368}
369
1ed1a609
SC
370struct DMModeIteratorRec
371{
d0ee33f5
WS
372 wxArrayVideoModes* pModes;
373 const wxVideoMode* pMatchMode;
1ed1a609
SC
374};
375
a5714345
DS
376pascal void DMModeListIteratorProc(
377 void* pData,
378 DMListIndexType nIndex,
379 DMDisplayModeListEntryPtr pInfo)
1ed1a609
SC
380{
381 DMModeIteratorRec* pInfoData = (DMModeIteratorRec*) pData;
382
a5714345 383 // Note that in testing the refresh rate is always 0 on my ibook - RN
1ed1a609
SC
384 int refresh = (int) Fix2Long(pInfo->displayModeResolutionInfo->csRefreshRate);
385
1ed1a609
SC
386#define pDBI pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthVPBlock
387
a5714345
DS
388 for (unsigned long i = 0; i < pInfo->displayModeDepthBlockInfo->depthBlockCount; ++i)
389 {
390 if (wxVideoMode( (int) pInfo->displayModeResolutionInfo->csHorizontalPixels,
d0ee33f5
WS
391 (int) pInfo->displayModeResolutionInfo->csVerticalLines,
392 (int) pDBI->vpPixelSize,
393 refresh).Matches(*pInfoData->pMatchMode) )
394 {
a5714345
DS
395 pInfoData->pModes->Add(
396 wxVideoMode(
397 (int) pInfo->displayModeResolutionInfo->csHorizontalPixels,
398 (int) pInfo->displayModeResolutionInfo->csVerticalLines,
399 (int) pDBI->vpPixelSize,
400 refresh ) );
d0ee33f5 401 }
d0ee33f5 402 }
a5714345
DS
403
404#undef pDBI
1ed1a609
SC
405}
406
407struct DMModeInfoRec
408{
d0ee33f5
WS
409 const wxVideoMode* pMode;
410 VDSwitchInfoRec sMode;
411 bool bMatched;
1ed1a609
SC
412};
413
a5714345
DS
414pascal void DMModeInfoProc(
415 void* pData,
416 DMListIndexType nIndex,
417 DMDisplayModeListEntryPtr pInfo )
1ed1a609 418{
d0ee33f5
WS
419 DMModeInfoRec* pInfoData = (DMModeInfoRec*) pData;
420 Fixed refresh = Long2Fix(pInfoData->pMode->refresh);
1ed1a609 421
1ed1a609 422#define pDBI pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthVPBlock
a5714345
DS
423
424 for (unsigned long i = 0; i < pInfo->displayModeDepthBlockInfo->depthBlockCount; ++i)
425 {
d0ee33f5
WS
426 if (pInfoData->pMode->w == (int&) pInfo->displayModeResolutionInfo->csHorizontalPixels &&
427 pInfoData->pMode->h == (int&) pInfo->displayModeResolutionInfo->csVerticalLines &&
428 pInfoData->pMode->bpp == (int) pDBI->vpPixelSize &&
429 refresh == pInfo->displayModeResolutionInfo->csRefreshRate)
430 {
a5714345
DS
431 memcpy(
432 &pInfoData->sMode,
433 pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthSwitchInfo,
434 sizeof(VDSwitchInfoRec));
d0ee33f5
WS
435 pInfoData->sMode.csMode = pDBI->vpPixelSize;
436 pInfoData->bMatched = true;
437 break;
438 }
d0ee33f5 439 }
a5714345
DS
440
441#undef pDBI
1ed1a609
SC
442}
443
444struct DMModeTransRec
445{
d0ee33f5
WS
446 wxVideoMode Mode;
447 const VDSwitchInfoRec* psMode;
448 bool bMatched;
1ed1a609
SC
449};
450
a5714345
DS
451pascal void DMModeTransProc(
452 void* pData,
453 DMListIndexType nIndex,
454 DMDisplayModeListEntryPtr pInfo)
1ed1a609 455{
d0ee33f5 456 DMModeTransRec* pInfoData = (DMModeTransRec*) pData;
1ed1a609 457
1ed1a609 458#define pDBI pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthVPBlock
a5714345
DS
459
460 for (unsigned long i = 0; i < pInfo->displayModeDepthBlockInfo->depthBlockCount; ++i)
461 {
d0ee33f5
WS
462 if (pInfoData->psMode->csData == pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthSwitchInfo->csData)
463 {
a5714345
DS
464 pInfoData->Mode = wxVideoMode(
465 (int) pInfo->displayModeResolutionInfo->csHorizontalPixels,
466 (int) pInfo->displayModeResolutionInfo->csVerticalLines,
467 (int) pDBI->vpPixelSize,
468 (int) Fix2Long(pInfo->displayModeResolutionInfo->csRefreshRate) );
d0ee33f5
WS
469 pInfoData->bMatched = true;
470 break;
471 }
d0ee33f5 472 }
a5714345
DS
473
474#undef pDBI
1ed1a609
SC
475}
476
ef1717a9 477wxArrayVideoModes wxDisplayImplMac::GetModes(const wxVideoMode& mode) const
1e1cc1ce 478{
1ed1a609 479 wxArrayVideoModes Modes;
1ed1a609 480 unsigned long dwDMVer;
1ed1a609 481
a5714345
DS
482 // Check DM version == 2
483 // (for backward compatibility only - 7.5.3+ use 2.0)
484 Gestalt( gestaltDisplayMgrVers, (long*) &dwDMVer );
485 if (dwDMVer >= 0x020000)
1ed1a609 486 {
d0ee33f5
WS
487 DMListIndexType nNumModes;
488 DMListType pModes;
489 DMDisplayModeListIteratorUPP uppMLI;
490 DisplayIDType nDisplayID;
cc9d56b0 491 OSErr err;
1ed1a609 492
ef1717a9 493 err = DMGetDisplayIDByGDevice(m_hndl, &nDisplayID, false);
a5714345 494 verify_noerr( err );
d0ee33f5 495
a5714345 496 // Create a new list...
cc9d56b0 497 err = DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes);
a5714345 498 wxASSERT_MSG( err == noErr, wxT("Could not create a new display mode list") );
1ed1a609 499
d0ee33f5 500 uppMLI = NewDMDisplayModeListIteratorUPP(DMModeListIteratorProc);
a5714345 501 wxASSERT( uppMLI );
1ed1a609 502
d0ee33f5
WS
503 DMModeIteratorRec sModeInfo;
504 sModeInfo.pModes = &Modes;
505 sModeInfo.pMatchMode = &mode;
a5714345 506
d0ee33f5
WS
507 for (DMListIndexType i = 0; i < nNumModes; ++i)
508 {
cc9d56b0 509 err = DMGetIndexedDisplayModeFromList(pModes, i, NULL, uppMLI, &sModeInfo);
a5714345 510 verify_noerr( err );
d0ee33f5 511 }
d0ee33f5 512
a5714345 513 DisposeDMDisplayModeListIteratorUPP(uppMLI);
cc9d56b0 514 err = DMDisposeList(pModes);
a5714345 515 verify_noerr( err );
1ed1a609 516 }
a5714345 517 else // DM 1.0, 1.2, 1.x
1ed1a609 518 {
a5714345
DS
519 wxLogSysError(
520 wxString::Format(
521 wxT("Display Manager Version %u Not Supported! Present? %s"),
522 (unsigned int) dwDMVer / 0x10000,
523 (dwDMVer & (1 << gestaltDisplayMgrPresent) ? wxT("Yes") : wxT("No")) ) );
1ed1a609
SC
524 }
525
526 return Modes;
1e1cc1ce
DS
527}
528
ef1717a9 529wxVideoMode wxDisplayImplMac::GetCurrentMode() const
1e1cc1ce 530{
1ed1a609
SC
531 unsigned long dwDMVer;
532 wxVideoMode RetMode;
d0ee33f5 533
a5714345
DS
534 // Check DM version == 2
535 // (for backward compatibility only - 7.5.3+ use 2.0)
536 Gestalt( gestaltDisplayMgrVers, (long*) &dwDMVer );
537 if (dwDMVer >= 0x020000)
1ed1a609 538 {
a5714345
DS
539 VDSwitchInfoRec sMode; // Note: csMode member also contains the bit depth
540 OSErr err;
541
ef1717a9 542 err = DMGetDisplayMode( m_hndl, &sMode );
a5714345 543 if (err == noErr)
d0ee33f5
WS
544 {
545 DMListIndexType nNumModes;
546 DMListType pModes;
547 DMDisplayModeListIteratorUPP uppMLI;
548 DisplayIDType nDisplayID;
1ed1a609 549
ef1717a9 550 err = DMGetDisplayIDByGDevice(m_hndl, &nDisplayID, false);
a5714345 551 verify_noerr( err );
d0ee33f5 552
a5714345 553 // Create a new list...
cc9d56b0 554 err = DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes);
a5714345 555 wxASSERT_MSG( err == noErr, wxT("Could not create a new display mode list") );
d0ee33f5
WS
556
557 uppMLI = NewDMDisplayModeListIteratorUPP(DMModeTransProc);
a5714345 558 wxASSERT( uppMLI );
d0ee33f5
WS
559
560 DMModeTransRec sModeInfo;
561 sModeInfo.bMatched = false;
562 sModeInfo.psMode = &sMode;
563 for (DMListIndexType i = 0; i < nNumModes; ++i)
564 {
cc9d56b0 565 err = DMGetIndexedDisplayModeFromList(pModes, i, NULL, uppMLI, &sModeInfo);
a5714345 566 verify_noerr( err );
1ed1a609 567
d0ee33f5
WS
568 if ( sModeInfo.bMatched )
569 {
570 RetMode = sModeInfo.Mode;
571 break;
572 }
573 }
574
575 DisposeDMDisplayModeListIteratorUPP(uppMLI);
cc9d56b0 576 err = DMDisposeList(pModes);
a5714345 577 verify_noerr( err );
d0ee33f5 578 }
a5714345 579 else // Can't get current mode?
d0ee33f5 580 {
a5714345
DS
581 wxLogSysError(
582 wxString::Format(
583 wxT("Couldn't obtain current display mode!!!\ndwDMVer:%u"),
584 (unsigned int) dwDMVer));
d0ee33f5 585 }
1ed1a609 586 }
a5714345 587 else // DM ver 1
1ed1a609 588 {
a5714345
DS
589 wxLogSysError(
590 wxString::Format(
591 wxT("Display Manager Version %u Not Supported! Present? %s"),
592 (unsigned int) dwDMVer / 0x10000,
593 (dwDMVer & (1 << gestaltDisplayMgrPresent) ? wxT("Yes") : wxT("No")) ) );
1ed1a609 594 }
d0ee33f5 595
1ed1a609 596 return RetMode;
1e1cc1ce
DS
597}
598
ef1717a9 599bool wxDisplayImplMac::ChangeMode(const wxVideoMode& mode)
1e1cc1ce 600{
1ed1a609 601 unsigned long dwDMVer;
a5714345
DS
602
603 Gestalt( gestaltDisplayMgrVers, (long*)&dwDMVer );
1ed1a609
SC
604 if (GetCount() == 1 || dwDMVer >= 0x020000)
605 {
d0ee33f5
WS
606 if (mode == wxDefaultVideoMode)
607 {
a5714345
DS
608 return true;
609
610#if 0
1ed1a609 611//#ifndef __DARWIN__
d0ee33f5
WS
612// Handle hDisplayState;
613// if (DMBeginConfigureDisplays(&hDisplayState) != noErr)
614// {
615// wxLogSysError(wxT("Could not lock display for display mode changing!"));
616// return false;
617// }
a5714345 618//
d0ee33f5
WS
619// wxASSERT( DMUseScreenPrefs(true, hDisplayState) == noErr);
620// DMEndConfigureDisplays(hDisplayState);
621// return true;
1ed1a609 622//#else
a5714345
DS
623 // hmmmmm....
624// return true;
1ed1a609 625//#endif
a5714345 626#endif
d0ee33f5
WS
627 }
628
629 //0 & NULL for params 2 & 3 of DMSetVideoMode signal it to use defaults (current mode)
630 //DM 2.0+ doesn't use params 2 & 3 of DMSetDisplayMode
631 //so we have to use this icky structure
632 VDSwitchInfoRec sMode;
a5714345 633 memset( &sMode, 0, sizeof(VDSwitchInfoRec) );
d0ee33f5
WS
634
635 DMListIndexType nNumModes;
636 DMListType pModes;
637 DMDisplayModeListIteratorUPP uppMLI;
638 DisplayIDType nDisplayID;
cc9d56b0 639 OSErr err;
1ed1a609 640
ef1717a9 641 err = DMGetDisplayIDByGDevice(m_hndl, &nDisplayID, false);
a5714345 642 verify_noerr( err );
d0ee33f5 643
a5714345 644 // Create a new list...
cc9d56b0 645 err = DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes);
d0ee33f5 646 wxASSERT_MSG(err == noErr, wxT("Could not create a new display mode list") );
1ed1a609 647
d0ee33f5
WS
648 uppMLI = NewDMDisplayModeListIteratorUPP(DMModeInfoProc);
649 wxASSERT(uppMLI);
1ed1a609 650
d0ee33f5
WS
651 DMModeInfoRec sModeInfo;
652 sModeInfo.bMatched = false;
653 sModeInfo.pMode = &mode;
654 unsigned int i;
a5714345
DS
655
656 for (i = 0; i < nNumModes; ++i)
d0ee33f5 657 {
cc9d56b0 658 err = DMGetIndexedDisplayModeFromList(pModes, i, NULL, uppMLI, &sModeInfo);
a5714345 659 verify_noerr( err );
d0ee33f5
WS
660
661 if (sModeInfo.bMatched)
662 {
663 sMode = sModeInfo.sMode;
664 break;
665 }
666 }
a5714345
DS
667
668 if (i == nNumModes)
d0ee33f5
WS
669 return false;
670
671 DisposeDMDisplayModeListIteratorUPP(uppMLI);
672
cc9d56b0 673 err = DMDisposeList(pModes);
a5714345 674 verify_noerr( err );
1ed1a609 675
d0ee33f5
WS
676 // For the really paranoid -
677 // unsigned long flags;
678 // Boolean bok;
ef1717a9 679 // wxASSERT(noErr == DMCheckDisplayMode(m_hndl, sMode.csData,
d0ee33f5
WS
680 // sMode.csMode, &flags, NULL, &bok));
681 // wxASSERT(bok);
682
683 Handle hDisplayState;
684 if (DMBeginConfigureDisplays(&hDisplayState) != noErr)
685 {
686 wxLogSysError(wxT("Could not lock display for display mode changing!"));
a5714345 687
d0ee33f5
WS
688 return false;
689 }
690
691 unsigned long dwBPP = (unsigned long) mode.bpp;
a5714345 692 err = DMSetDisplayMode(
ef1717a9 693 m_hndl, sMode.csData,
a5714345
DS
694 (unsigned long*) &(dwBPP),
695 NULL, //(unsigned long) &sMode
696 hDisplayState );
697
698 if (err != noErr)
d0ee33f5
WS
699 {
700 DMEndConfigureDisplays(hDisplayState);
ef1717a9 701 wxLogError(wxT("Could not set the display mode"));
a5714345 702
1ed1a609 703 return false;
d0ee33f5 704 }
a5714345 705
d0ee33f5 706 DMEndConfigureDisplays(hDisplayState);
1ed1a609 707 }
a5714345 708 else // DM 1.0, 1.2, 1.x
1ed1a609 709 {
a5714345
DS
710 wxLogSysError(
711 wxString::Format(
712 wxT("Monitor gravitation not supported yet. dwDMVer:%u"),
713 (unsigned int) dwDMVer));
714
d0ee33f5 715 return false;
1ed1a609 716 }
d0ee33f5 717
1ed1a609 718 return true;
a536e411
JS
719}
720
ef1717a9
VZ
721// ============================================================================
722// wxDisplay::CreateFactory()
723// ============================================================================
724
725/* static */ wxDisplayFactory *wxDisplay::CreateFactory()
a536e411 726{
ef1717a9 727 return new wxDisplayFactoryMac;
a536e411
JS
728}
729
20b69855
SC
730#endif // !OSX
731
a536e411 732#endif // wxUSE_DISPLAY