]> git.saurik.com Git - wxWidgets.git/blame - src/osx/core/display.cpp
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / src / osx / core / display.cpp
CommitLineData
489468fe 1/////////////////////////////////////////////////////////////////////////////
96dabe43 2// Name: src/osx/core/display.cpp
489468fe
SC
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
489468fe
SC
7// Copyright: (c) wxWidgets team
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
19#include "wx/wxprec.h"
20
21#ifdef __BORLANDC__
22 #pragma hdrstop
23#endif
24
25#if wxUSE_DISPLAY
26
27#include "wx/display.h"
28
29#ifndef WX_PRECOMP
30 #include "wx/dynarray.h"
31 #include "wx/log.h"
32 #include "wx/string.h"
33 #include "wx/gdicmn.h"
34#endif
35
489468fe 36#include "wx/display_impl.h"
b2680ced
SC
37#include "wx/osx/private.h"
38
39#if wxOSX_USE_COCOA_OR_CARBON
489468fe
SC
40
41// ----------------------------------------------------------------------------
42// display classes implementation
43// ----------------------------------------------------------------------------
44
45class wxDisplayImplMacOSX : public wxDisplayImpl
46{
47public:
48 wxDisplayImplMacOSX(unsigned n, CGDirectDisplayID id)
49 : wxDisplayImpl(n),
50 m_id(id)
51 {
52 }
53
54 virtual wxRect GetGeometry() const;
55 virtual wxRect GetClientArea() const;
56 virtual wxString GetName() const { return wxString(); }
57
58 virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const;
59 virtual wxVideoMode GetCurrentMode() const;
60 virtual bool ChangeMode(const wxVideoMode& mode);
61
4c58f5c2
SC
62 virtual bool IsPrimary() const;
63
489468fe
SC
64private:
65 CGDirectDisplayID m_id;
66
c0c133e1 67 wxDECLARE_NO_COPY_CLASS(wxDisplayImplMacOSX);
489468fe
SC
68};
69
70class wxDisplayFactoryMacOSX : public wxDisplayFactory
71{
72public:
73 wxDisplayFactoryMacOSX() {}
74
75 virtual wxDisplayImpl *CreateDisplay(unsigned n);
76 virtual unsigned GetCount();
77 virtual int GetFromPoint(const wxPoint& pt);
78
79protected:
c0c133e1 80 wxDECLARE_NO_COPY_CLASS(wxDisplayFactoryMacOSX);
489468fe
SC
81};
82
83// ============================================================================
84// wxDisplayFactoryMacOSX implementation
85// ============================================================================
86
4c58f5c2
SC
87// gets all displays that are not mirror displays
88
89static CGDisplayErr wxOSXGetDisplayList(CGDisplayCount maxDisplays,
90 CGDirectDisplayID *displays,
91 CGDisplayCount *displayCount)
92{
93 CGDisplayErr error = kCGErrorSuccess;
94 CGDisplayCount onlineCount;
ce00f59b 95
4c58f5c2
SC
96 error = CGGetOnlineDisplayList(0,NULL,&onlineCount);
97 if ( error == kCGErrorSuccess )
98 {
99 *displayCount = 0;
100 if ( onlineCount > 0 )
101 {
102 CGDirectDisplayID *onlineDisplays = new CGDirectDisplayID[onlineCount];
103 error = CGGetOnlineDisplayList(onlineCount,onlineDisplays,&onlineCount);
104 if ( error == kCGErrorSuccess )
105 {
106 for ( CGDisplayCount i = 0; i < onlineCount; ++i )
107 {
108 if ( CGDisplayMirrorsDisplay(onlineDisplays[i]) != kCGNullDirectDisplay )
109 continue;
ce00f59b 110
4c58f5c2
SC
111 if ( displays == NULL )
112 *displayCount += 1;
113 else
114 {
115 if ( *displayCount < maxDisplays )
116 {
117 displays[*displayCount] = onlineDisplays[i];
118 *displayCount += 1;
119 }
120 }
121 }
122 }
123 delete[] onlineDisplays;
124 }
ce00f59b 125
4c58f5c2
SC
126 }
127 return error;
128}
129
489468fe
SC
130unsigned wxDisplayFactoryMacOSX::GetCount()
131{
132 CGDisplayCount count;
4c58f5c2 133 CGDisplayErr err = wxOSXGetDisplayList(0, NULL, &count);
489468fe 134
4c58f5c2 135 wxCHECK_MSG( err == CGDisplayNoErr, 0, "wxOSXGetDisplayList() failed" );
489468fe
SC
136
137 return count;
138}
139
140int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint& p)
141{
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);
147
148 int nWhich = wxNOT_FOUND;
149
150 if (theCount)
151 {
152 theCount = GetCount();
153 CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount];
4c58f5c2 154 err = wxOSXGetDisplayList(theCount, theIDs, &theCount);
489468fe
SC
155 wxASSERT(err == CGDisplayNoErr);
156
157 for (nWhich = 0; nWhich < (int) theCount; ++nWhich)
158 {
159 if (theIDs[nWhich] == theID)
160 break;
161 }
162
163 delete [] theIDs;
164
165 if (nWhich == (int) theCount)
166 {
167 wxFAIL_MSG(wxT("Failed to find display in display list"));
168 nWhich = wxNOT_FOUND;
169 }
170 }
171
172 return nWhich;
173}
174
175wxDisplayImpl *wxDisplayFactoryMacOSX::CreateDisplay(unsigned n)
176{
177 CGDisplayCount theCount = GetCount();
178 CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount];
179
4c58f5c2
SC
180 CGDisplayErr err = wxOSXGetDisplayList(theCount, theIDs, &theCount);
181 wxCHECK_MSG( err == CGDisplayNoErr, NULL, "wxOSXGetDisplayList() failed" );
489468fe 182
489468fe
SC
183 wxASSERT( n < theCount );
184
185 wxDisplayImplMacOSX *display = new wxDisplayImplMacOSX(n, theIDs[n]);
186
187 delete [] theIDs;
188
189 return display;
190}
191
192// ============================================================================
193// wxDisplayImplMacOSX implementation
194// ============================================================================
195
4c58f5c2
SC
196bool wxDisplayImplMacOSX::IsPrimary() const
197{
198 return CGDisplayIsMain(m_id);
199}
200
489468fe
SC
201wxRect wxDisplayImplMacOSX::GetGeometry() const
202{
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
208}
209
210wxRect wxDisplayImplMacOSX::GetClientArea() const
211{
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)
215 if ( IsPrimary() )
216 return wxGetClientDisplayRect();
217
218 return wxDisplayImpl::GetClientArea();
219}
220
221static int wxCFDictKeyToInt( CFDictionaryRef desc, CFStringRef key )
222{
223 CFNumberRef value = (CFNumberRef) CFDictionaryGetValue( desc, key );
224 if (value == NULL)
225 return 0;
226
227 int num = 0;
228 CFNumberGetValue( value, kCFNumberIntType, &num );
229
230 return num;
231}
232
233wxArrayVideoModes wxDisplayImplMacOSX::GetModes(const wxVideoMode& mode) const
234{
235 wxArrayVideoModes resultModes;
236
237 CFArrayRef theArray = CGDisplayAvailableModes( m_id );
238
239 for (CFIndex i = 0; i < CFArrayGetCount(theArray); ++i)
240 {
241 CFDictionaryRef theValue = (CFDictionaryRef) CFArrayGetValueAtIndex( theArray, i );
242
243 wxVideoMode theMode(
244 wxCFDictKeyToInt( theValue, kCGDisplayWidth ),
245 wxCFDictKeyToInt( theValue, kCGDisplayHeight ),
246 wxCFDictKeyToInt( theValue, kCGDisplayBitsPerPixel ),
247 wxCFDictKeyToInt( theValue, kCGDisplayRefreshRate ));
248
249 if (theMode.Matches( mode ))
250 resultModes.Add( theMode );
251 }
252
253 return resultModes;
254}
255
256wxVideoMode wxDisplayImplMacOSX::GetCurrentMode() const
257{
258 CFDictionaryRef theValue = CGDisplayCurrentMode( m_id );
259
260 return wxVideoMode(
261 wxCFDictKeyToInt( theValue, kCGDisplayWidth ),
262 wxCFDictKeyToInt( theValue, kCGDisplayHeight ),
263 wxCFDictKeyToInt( theValue, kCGDisplayBitsPerPixel ),
264 wxCFDictKeyToInt( theValue, kCGDisplayRefreshRate ));
265}
266
267bool wxDisplayImplMacOSX::ChangeMode( const wxVideoMode& mode )
268{
c20389eb
VZ
269#ifndef __WXOSX_IPHONE__
270 if (mode == wxDefaultVideoMode)
271 {
272 CGRestorePermanentDisplayConfiguration();
273 return true;
274 }
275#endif
276
489468fe
SC
277 boolean_t bExactMatch;
278 CFDictionaryRef theCGMode = CGDisplayBestModeForParametersAndRefreshRate(
279 m_id,
280 (size_t)mode.GetDepth(),
281 (size_t)mode.GetWidth(),
282 (size_t)mode.GetHeight(),
283 (double)mode.GetRefresh(),
284 &bExactMatch );
285
286 bool bOK = bExactMatch;
287
288 if (bOK)
289 bOK = CGDisplaySwitchToMode( m_id, theCGMode ) == CGDisplayNoErr;
290
291 return bOK;
292}
293
294// ============================================================================
295// wxDisplay::CreateFactory()
296// ============================================================================
297
298/* static */ wxDisplayFactory *wxDisplay::CreateFactory()
299{
300 return new wxDisplayFactoryMacOSX;
301}
302
b2680ced
SC
303#else
304
305/* static */ wxDisplayFactory *wxDisplay::CreateFactory()
306{
307 return new wxDisplayFactorySingle;
308}
309
310#endif
311
489468fe 312#endif // wxUSE_DISPLAY