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