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