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