]> git.saurik.com Git - wxWidgets.git/blob - src/osx/core/display.cpp
45dcdd802f1c46a8bc3fcb7d2e27064b39fc999f
[wxWidgets.git] / src / osx / core / display.cpp
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
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 #include "wx/display_impl.h"
38 #include "wx/osx/private.h"
39
40 #if wxOSX_USE_COCOA_OR_CARBON
41
42 // ----------------------------------------------------------------------------
43 // display classes implementation
44 // ----------------------------------------------------------------------------
45
46 class wxDisplayImplMacOSX : public wxDisplayImpl
47 {
48 public:
49 wxDisplayImplMacOSX(unsigned n, CGDirectDisplayID id)
50 : wxDisplayImpl(n),
51 m_id(id)
52 {
53 }
54
55 virtual wxRect GetGeometry() const;
56 virtual wxRect GetClientArea() const;
57 virtual wxString GetName() const { return wxString(); }
58
59 virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const;
60 virtual wxVideoMode GetCurrentMode() const;
61 virtual bool ChangeMode(const wxVideoMode& mode);
62
63 private:
64 CGDirectDisplayID m_id;
65
66 DECLARE_NO_COPY_CLASS(wxDisplayImplMacOSX)
67 };
68
69 class wxDisplayFactoryMacOSX : public wxDisplayFactory
70 {
71 public:
72 wxDisplayFactoryMacOSX() {}
73
74 virtual wxDisplayImpl *CreateDisplay(unsigned n);
75 virtual unsigned GetCount();
76 virtual int GetFromPoint(const wxPoint& pt);
77
78 protected:
79 DECLARE_NO_COPY_CLASS(wxDisplayFactoryMacOSX)
80 };
81
82 // ============================================================================
83 // wxDisplayFactoryMacOSX implementation
84 // ============================================================================
85
86 unsigned wxDisplayFactoryMacOSX::GetCount()
87 {
88 CGDisplayCount count;
89 #ifdef __WXDEBUG__
90 CGDisplayErr err =
91 #endif
92 CGGetActiveDisplayList(0, NULL, &count);
93
94 wxASSERT(err == CGDisplayNoErr);
95
96 return count;
97 }
98
99 int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint& p)
100 {
101 CGPoint thePoint = {(float)p.x, (float)p.y};
102 CGDirectDisplayID theID;
103 CGDisplayCount theCount;
104 CGDisplayErr err = CGGetDisplaysWithPoint(thePoint, 1, &theID, &theCount);
105 wxASSERT(err == CGDisplayNoErr);
106
107 int nWhich = wxNOT_FOUND;
108
109 if (theCount)
110 {
111 theCount = GetCount();
112 CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount];
113 err = CGGetActiveDisplayList(theCount, theIDs, &theCount);
114 wxASSERT(err == CGDisplayNoErr);
115
116 for (nWhich = 0; nWhich < (int) theCount; ++nWhich)
117 {
118 if (theIDs[nWhich] == theID)
119 break;
120 }
121
122 delete [] theIDs;
123
124 if (nWhich == (int) theCount)
125 {
126 wxFAIL_MSG(wxT("Failed to find display in display list"));
127 nWhich = wxNOT_FOUND;
128 }
129 }
130
131 return nWhich;
132 }
133
134 wxDisplayImpl *wxDisplayFactoryMacOSX::CreateDisplay(unsigned n)
135 {
136 CGDisplayCount theCount = GetCount();
137 CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount];
138
139 #ifdef __WXDEBUG__
140 CGDisplayErr err =
141 #endif
142 CGGetActiveDisplayList(theCount, theIDs, &theCount);
143
144 wxASSERT( err == CGDisplayNoErr );
145 wxASSERT( n < theCount );
146
147 wxDisplayImplMacOSX *display = new wxDisplayImplMacOSX(n, theIDs[n]);
148
149 delete [] theIDs;
150
151 return display;
152 }
153
154 // ============================================================================
155 // wxDisplayImplMacOSX implementation
156 // ============================================================================
157
158 wxRect wxDisplayImplMacOSX::GetGeometry() const
159 {
160 CGRect theRect = CGDisplayBounds(m_id);
161 return wxRect( (int)theRect.origin.x,
162 (int)theRect.origin.y,
163 (int)theRect.size.width,
164 (int)theRect.size.height ); //floats
165 }
166
167 wxRect wxDisplayImplMacOSX::GetClientArea() const
168 {
169 // VZ: I don't know how to get client area for arbitrary display but
170 // wxGetClientDisplayRect() does work correctly for at least the main
171 // one (TODO: do it correctly for the other displays too)
172 if ( IsPrimary() )
173 return wxGetClientDisplayRect();
174
175 return wxDisplayImpl::GetClientArea();
176 }
177
178 static int wxCFDictKeyToInt( CFDictionaryRef desc, CFStringRef key )
179 {
180 CFNumberRef value = (CFNumberRef) CFDictionaryGetValue( desc, key );
181 if (value == NULL)
182 return 0;
183
184 int num = 0;
185 CFNumberGetValue( value, kCFNumberIntType, &num );
186
187 return num;
188 }
189
190 wxArrayVideoModes wxDisplayImplMacOSX::GetModes(const wxVideoMode& mode) const
191 {
192 wxArrayVideoModes resultModes;
193
194 CFArrayRef theArray = CGDisplayAvailableModes( m_id );
195
196 for (CFIndex i = 0; i < CFArrayGetCount(theArray); ++i)
197 {
198 CFDictionaryRef theValue = (CFDictionaryRef) CFArrayGetValueAtIndex( theArray, i );
199
200 wxVideoMode theMode(
201 wxCFDictKeyToInt( theValue, kCGDisplayWidth ),
202 wxCFDictKeyToInt( theValue, kCGDisplayHeight ),
203 wxCFDictKeyToInt( theValue, kCGDisplayBitsPerPixel ),
204 wxCFDictKeyToInt( theValue, kCGDisplayRefreshRate ));
205
206 if (theMode.Matches( mode ))
207 resultModes.Add( theMode );
208 }
209
210 return resultModes;
211 }
212
213 wxVideoMode wxDisplayImplMacOSX::GetCurrentMode() const
214 {
215 CFDictionaryRef theValue = CGDisplayCurrentMode( m_id );
216
217 return wxVideoMode(
218 wxCFDictKeyToInt( theValue, kCGDisplayWidth ),
219 wxCFDictKeyToInt( theValue, kCGDisplayHeight ),
220 wxCFDictKeyToInt( theValue, kCGDisplayBitsPerPixel ),
221 wxCFDictKeyToInt( theValue, kCGDisplayRefreshRate ));
222 }
223
224 bool wxDisplayImplMacOSX::ChangeMode( const wxVideoMode& mode )
225 {
226 // Changing to default mode (wxDefaultVideoMode) doesn't
227 // work because we don't have access to the system's 'scrn'
228 // resource which holds the user's mode which the system
229 // will return to after this app is done
230 boolean_t bExactMatch;
231 CFDictionaryRef theCGMode = CGDisplayBestModeForParametersAndRefreshRate(
232 m_id,
233 (size_t)mode.GetDepth(),
234 (size_t)mode.GetWidth(),
235 (size_t)mode.GetHeight(),
236 (double)mode.GetRefresh(),
237 &bExactMatch );
238
239 bool bOK = bExactMatch;
240
241 if (bOK)
242 bOK = CGDisplaySwitchToMode( m_id, theCGMode ) == CGDisplayNoErr;
243
244 return bOK;
245 }
246
247 // ============================================================================
248 // wxDisplay::CreateFactory()
249 // ============================================================================
250
251 /* static */ wxDisplayFactory *wxDisplay::CreateFactory()
252 {
253 return new wxDisplayFactoryMacOSX;
254 }
255
256 #else
257
258 /* static */ wxDisplayFactory *wxDisplay::CreateFactory()
259 {
260 return new wxDisplayFactorySingle;
261 }
262
263 #endif
264
265 #endif // wxUSE_DISPLAY