]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/display.cpp
Use new function GetItemLabel
[wxWidgets.git] / src / mac / carbon / display.cpp
... / ...
CommitLineData
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
56class wxDisplayImplMacOSX : public wxDisplayImpl
57{
58public:
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
73private:
74 CGDirectDisplayID m_id;
75
76 DECLARE_NO_COPY_CLASS(wxDisplayImplMacOSX)
77};
78
79class wxDisplayFactoryMacOSX : public wxDisplayFactory
80{
81public:
82 wxDisplayFactoryMacOSX() {}
83
84 virtual wxDisplayImpl *CreateDisplay(unsigned n);
85 virtual unsigned GetCount();
86 virtual int GetFromPoint(const wxPoint& pt);
87
88protected:
89 DECLARE_NO_COPY_CLASS(wxDisplayFactoryMacOSX)
90};
91
92// ============================================================================
93// wxDisplayFactoryMacOSX implementation
94// ============================================================================
95
96unsigned 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
109int 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
144wxDisplayImpl *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
168wxRect 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
177wxRect 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
188static 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
200wxArrayVideoModes 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
223wxVideoMode 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
234bool 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
268class wxDisplayImplMac : public wxDisplayImpl
269{
270public:
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
284private:
285 GDHandle m_hndl;
286
287 DECLARE_NO_COPY_CLASS(wxDisplayImplMac)
288};
289
290class wxDisplayFactoryMac : public wxDisplayFactory
291{
292public:
293 wxDisplayFactoryMac();
294
295 virtual wxDisplayImpl *CreateDisplay(unsigned n);
296 virtual unsigned GetCount();
297 virtual int GetFromPoint(const wxPoint& pt);
298
299protected:
300 DECLARE_NO_COPY_CLASS(wxDisplayFactoryMac)
301};
302
303// ============================================================================
304// wxDisplayFactoryMac implementation
305// ============================================================================
306
307unsigned 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
319int 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
340wxDisplayImpl *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
362wxRect 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
370struct DMModeIteratorRec
371{
372 wxArrayVideoModes* pModes;
373 const wxVideoMode* pMatchMode;
374};
375
376pascal 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
407struct DMModeInfoRec
408{
409 const wxVideoMode* pMode;
410 VDSwitchInfoRec sMode;
411 bool bMatched;
412};
413
414pascal 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
444struct DMModeTransRec
445{
446 wxVideoMode Mode;
447 const VDSwitchInfoRec* psMode;
448 bool bMatched;
449};
450
451pascal 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
477wxArrayVideoModes 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
529wxVideoMode 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
599bool 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