1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/osx/core/display.cpp 
   3 // Purpose:     Mac implementation of wxDisplay class 
   4 // Author:      Ryan Norton & Brian Victor 
   5 // Modified by: Royce Mitchell III, Vadim Zeitlin 
   7 // Copyright:   (c) wxWidgets team 
   8 // Licence:     wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  11 // ============================================================================ 
  13 // ============================================================================ 
  15 // ---------------------------------------------------------------------------- 
  17 // ---------------------------------------------------------------------------- 
  19 #include "wx/wxprec.h" 
  27 #include "wx/display.h" 
  30     #include "wx/dynarray.h" 
  32     #include "wx/string.h" 
  33     #include "wx/gdicmn.h" 
  36 #include "wx/display_impl.h" 
  37 #include "wx/osx/private.h" 
  39 #if wxOSX_USE_COCOA_OR_CARBON 
  41 // ---------------------------------------------------------------------------- 
  42 // display classes implementation 
  43 // ---------------------------------------------------------------------------- 
  45 class wxDisplayImplMacOSX 
: public wxDisplayImpl
 
  48     wxDisplayImplMacOSX(unsigned n
, CGDirectDisplayID id
) 
  54     virtual wxRect 
GetGeometry() const; 
  55     virtual wxRect 
GetClientArea() const; 
  56     virtual wxString 
GetName() const { return wxString(); } 
  58     virtual wxArrayVideoModes 
GetModes(const wxVideoMode
& mode
) const; 
  59     virtual wxVideoMode 
GetCurrentMode() const; 
  60     virtual bool ChangeMode(const wxVideoMode
& mode
); 
  62     virtual bool IsPrimary() const; 
  65     CGDirectDisplayID m_id
; 
  67     wxDECLARE_NO_COPY_CLASS(wxDisplayImplMacOSX
); 
  70 class wxDisplayFactoryMacOSX 
: public wxDisplayFactory
 
  73     wxDisplayFactoryMacOSX() {} 
  75     virtual wxDisplayImpl 
*CreateDisplay(unsigned n
); 
  76     virtual unsigned GetCount(); 
  77     virtual int GetFromPoint(const wxPoint
& pt
); 
  80     wxDECLARE_NO_COPY_CLASS(wxDisplayFactoryMacOSX
); 
  83 // ============================================================================ 
  84 // wxDisplayFactoryMacOSX implementation 
  85 // ============================================================================ 
  87 // gets all displays that are not mirror displays 
  89 static CGDisplayErr 
wxOSXGetDisplayList(CGDisplayCount maxDisplays
, 
  90                                    CGDirectDisplayID 
*displays
, 
  91                                    CGDisplayCount 
*displayCount
) 
  93     CGDisplayErr error 
= kCGErrorSuccess
; 
  94     CGDisplayCount onlineCount
; 
  96     error 
= CGGetOnlineDisplayList(0,NULL
,&onlineCount
); 
  97     if ( error 
== kCGErrorSuccess 
) 
 100         if ( onlineCount 
> 0 ) 
 102             CGDirectDisplayID 
*onlineDisplays 
= new CGDirectDisplayID
[onlineCount
]; 
 103             error 
= CGGetOnlineDisplayList(onlineCount
,onlineDisplays
,&onlineCount
); 
 104             if ( error 
== kCGErrorSuccess 
) 
 106                 for ( CGDisplayCount i 
= 0; i 
< onlineCount
; ++i 
) 
 108                     if ( CGDisplayMirrorsDisplay(onlineDisplays
[i
]) != kCGNullDirectDisplay 
) 
 111                     if ( displays 
== NULL 
) 
 115                         if ( *displayCount 
< maxDisplays 
) 
 117                             displays
[*displayCount
] = onlineDisplays
[i
]; 
 123             delete[] onlineDisplays
; 
 130 unsigned wxDisplayFactoryMacOSX::GetCount() 
 132     CGDisplayCount count
; 
 133     CGDisplayErr err 
= wxOSXGetDisplayList(0, NULL
, &count
); 
 135     wxCHECK_MSG( err 
== CGDisplayNoErr
, 0, "wxOSXGetDisplayList() failed" ); 
 140 int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint
& p
) 
 142     CGPoint thePoint 
= {(float)p
.x
, (float)p
.y
}; 
 143     CGDirectDisplayID theID
; 
 144     CGDisplayCount theCount
; 
 145     CGDisplayErr err 
= CGGetDisplaysWithPoint(thePoint
, 1, &theID
, &theCount
); 
 146     wxASSERT(err 
== CGDisplayNoErr
); 
 148     int nWhich 
= wxNOT_FOUND
; 
 152         theCount 
= GetCount(); 
 153         CGDirectDisplayID
* theIDs 
= new CGDirectDisplayID
[theCount
]; 
 154         err 
= wxOSXGetDisplayList(theCount
, theIDs
, &theCount
); 
 155         wxASSERT(err 
== CGDisplayNoErr
); 
 157         for (nWhich 
= 0; nWhich 
< (int) theCount
; ++nWhich
) 
 159             if (theIDs
[nWhich
] == theID
) 
 165         if (nWhich 
== (int) theCount
) 
 167             wxFAIL_MSG(wxT("Failed to find display in display list")); 
 168             nWhich 
= wxNOT_FOUND
; 
 175 wxDisplayImpl 
*wxDisplayFactoryMacOSX::CreateDisplay(unsigned n
) 
 177     CGDisplayCount theCount 
= GetCount(); 
 178     CGDirectDisplayID
* theIDs 
= new CGDirectDisplayID
[theCount
]; 
 180     CGDisplayErr err 
= wxOSXGetDisplayList(theCount
, theIDs
, &theCount
); 
 181     wxCHECK_MSG( err 
== CGDisplayNoErr
, NULL
, "wxOSXGetDisplayList() failed" ); 
 183     wxASSERT( n 
< theCount 
); 
 185     wxDisplayImplMacOSX 
*display 
= new wxDisplayImplMacOSX(n
, theIDs
[n
]); 
 192 // ============================================================================ 
 193 // wxDisplayImplMacOSX implementation 
 194 // ============================================================================ 
 196 bool wxDisplayImplMacOSX::IsPrimary() const 
 198     return CGDisplayIsMain(m_id
); 
 201 wxRect 
wxDisplayImplMacOSX::GetGeometry() const 
 203     CGRect theRect 
= CGDisplayBounds(m_id
); 
 204     return wxRect( (int)theRect
.origin
.x
, 
 205                    (int)theRect
.origin
.y
, 
 206                    (int)theRect
.size
.width
, 
 207                    (int)theRect
.size
.height 
); //floats 
 210 wxRect 
wxDisplayImplMacOSX::GetClientArea() const 
 212     // VZ: I don't know how to get client area for arbitrary display but 
 213     //     wxGetClientDisplayRect() does work correctly for at least the main 
 214     //     one (TODO: do it correctly for the other displays too) 
 216         return wxGetClientDisplayRect(); 
 218     return wxDisplayImpl::GetClientArea(); 
 221 static int wxCFDictKeyToInt( CFDictionaryRef desc
, CFStringRef key 
) 
 223     CFNumberRef value 
= (CFNumberRef
) CFDictionaryGetValue( desc
, key 
); 
 228     CFNumberGetValue( value
, kCFNumberIntType
, &num 
); 
 233 wxArrayVideoModes 
wxDisplayImplMacOSX::GetModes(const wxVideoMode
& mode
) const 
 235     wxArrayVideoModes resultModes
; 
 237     CFArrayRef theArray 
= CGDisplayAvailableModes( m_id 
); 
 239     for (CFIndex i 
= 0; i 
< CFArrayGetCount(theArray
); ++i
) 
 241         CFDictionaryRef theValue 
= (CFDictionaryRef
) CFArrayGetValueAtIndex( theArray
, i 
); 
 244             wxCFDictKeyToInt( theValue
, kCGDisplayWidth 
), 
 245             wxCFDictKeyToInt( theValue
, kCGDisplayHeight 
), 
 246             wxCFDictKeyToInt( theValue
, kCGDisplayBitsPerPixel 
), 
 247             wxCFDictKeyToInt( theValue
, kCGDisplayRefreshRate 
)); 
 249         if (theMode
.Matches( mode 
)) 
 250             resultModes
.Add( theMode 
); 
 256 wxVideoMode 
wxDisplayImplMacOSX::GetCurrentMode() const 
 258     CFDictionaryRef theValue 
= CGDisplayCurrentMode( m_id 
); 
 261         wxCFDictKeyToInt( theValue
, kCGDisplayWidth 
), 
 262         wxCFDictKeyToInt( theValue
, kCGDisplayHeight 
), 
 263         wxCFDictKeyToInt( theValue
, kCGDisplayBitsPerPixel 
), 
 264         wxCFDictKeyToInt( theValue
, kCGDisplayRefreshRate 
)); 
 267 bool wxDisplayImplMacOSX::ChangeMode( const wxVideoMode
& mode 
) 
 269 #ifndef __WXOSX_IPHONE__ 
 270     if (mode 
== wxDefaultVideoMode
) 
 272         CGRestorePermanentDisplayConfiguration(); 
 277     boolean_t bExactMatch
; 
 278     CFDictionaryRef theCGMode 
= CGDisplayBestModeForParametersAndRefreshRate( 
 280         (size_t)mode
.GetDepth(), 
 281         (size_t)mode
.GetWidth(), 
 282         (size_t)mode
.GetHeight(), 
 283         (double)mode
.GetRefresh(), 
 286     bool bOK 
= bExactMatch
; 
 289         bOK 
= CGDisplaySwitchToMode( m_id
, theCGMode 
) == CGDisplayNoErr
; 
 294 // ============================================================================ 
 295 // wxDisplay::CreateFactory() 
 296 // ============================================================================ 
 298 /* static */ wxDisplayFactory 
*wxDisplay::CreateFactory() 
 300     return new wxDisplayFactoryMacOSX
; 
 305 /* static */ wxDisplayFactory 
*wxDisplay::CreateFactory() 
 307     return new wxDisplayFactorySingle
; 
 312 #endif // wxUSE_DISPLAY