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