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