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