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