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