]> git.saurik.com Git - wxWidgets.git/blob - src/cocoa/display.mm
wxDisplay cleanup/rewrite:
[wxWidgets.git] / src / cocoa / display.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/cocoa/display.mm
3 // Purpose: Cocoa implementation of wxDisplay class
4 // Author: Ryan Norton
5 // Modified by:
6 // Created: 2004-10-03
7 // RCS-ID: $Id$
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #if wxUSE_DISPLAY
20
21 #ifndef WX_PRECOMP
22 #include "wx/dynarray.h"
23 #endif
24
25 #include "wx/display.h"
26 #include "wx/display_impl.h"
27 #include "wx/gdicmn.h"
28 #include "wx/string.h"
29
30 #import <Foundation/Foundation.h>
31
32 // ----------------------------------------------------------------------------
33 // display classes implementation
34 // ----------------------------------------------------------------------------
35
36 class wxDisplayImplMacOSX : public wxDisplayImpl
37 {
38 public:
39 wxDisplayImplMacOSX(CGDirectDisplayID id_) : m_id(id_) { }
40
41 virtual wxRect GetGeometry() const;
42 virtual wxString GetName() const { return wxString(); }
43
44 virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const;
45 virtual wxVideoMode GetCurrentMode() const;
46 virtual bool ChangeMode(const wxVideoMode& mode);
47
48 private:
49 CGDirectDisplayID m_id;
50
51 DECLARE_NO_COPY_CLASS(wxDisplayImplMacOSX)
52 };
53
54 class wxDisplayFactoryMacOSX : public wxDisplayFactory
55 {
56 public:
57 wxDisplayFactoryMacOSX();
58
59 virtual wxDisplayImpl *CreateDisplay(size_t n);
60 virtual size_t GetCount();
61 virtual int GetFromPoint(const wxPoint& pt);
62
63 protected:
64 DECLARE_NO_COPY_CLASS(wxDisplayFactoryMacOSX)
65 };
66
67 // ============================================================================
68 // wxDisplayFactoryMacOSX implementation
69 // ============================================================================
70
71 size_t wxDisplayFactoryMacOSX::GetCount()
72 {
73 CGDisplayCount count;
74 #ifdef __WXDEBUG__
75 CGDisplayErr err =
76 #endif
77 CGGetActiveDisplayList(0, NULL, &count);
78
79 wxASSERT(err == CGDisplayNoErr);
80
81 return count;
82 }
83
84 int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint& p)
85 {
86 CGPoint thePoint = {(float)p.x, (float)p.y};
87 CGDirectDisplayID theID;
88 CGDisplayCount theCount;
89 CGDisplayErr err = CGGetDisplaysWithPoint(thePoint, 1, &theID, &theCount);
90 wxASSERT(err == CGDisplayNoErr);
91
92 int nWhich = wxNOT_FOUND;
93
94 if (theCount)
95 {
96 theCount = GetCount();
97 CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount];
98 err = CGGetActiveDisplayList(theCount, theIDs, &theCount);
99 wxASSERT(err == CGDisplayNoErr);
100
101 for (nWhich = 0; nWhich < (int) theCount; ++nWhich)
102 {
103 if (theIDs[nWhich] == theID)
104 break;
105 }
106
107 delete [] theIDs;
108
109 if (nWhich == (int) theCount)
110 {
111 wxFAIL_MSG(wxT("Failed to find display in display list"));
112 nWhich = wxNOT_FOUND;
113 }
114 }
115
116 return nWhich;
117 }
118
119 wxDisplayImpl *wxDisplayFactoryMacOSX::CreateDisplay(size_t n)
120 {
121 CGDisplayCount theCount = GetCount();
122 CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount];
123
124 #ifdef __WXDEBUG__
125 CGDisplayErr err =
126 #endif
127 CGGetActiveDisplayList(theCount, theIDs, &theCount);
128
129 wxASSERT( err == CGDisplayNoErr );
130 wxASSERT( n < theCount );
131
132 wxDisplayImplMacOSX *display = new wxDisplayImplMacOSX(theIDs[n]);
133
134 delete [] theIDs;
135
136 return display;
137 }
138
139
140 wxRect wxDisplayImplMacOSX::GetGeometry() const
141 {
142 CGRect theRect = CGDisplayBounds(m_id);
143 return wxRect( (int)theRect.origin.x,
144 (int)theRect.origin.y,
145 (int)theRect.size.width,
146 (int)theRect.size.height ); //floats
147 }
148
149 static int wxCFDictKeyToInt( CFDictionaryRef desc, CFStringRef key )
150 {
151 CFNumberRef value;
152 int num = 0;
153
154 if ( (value = (CFNumberRef) CFDictionaryGetValue(desc, key)) == NULL )
155 return 0;
156 CFNumberGetValue(value, kCFNumberIntType, &num);
157 return num;
158 }
159
160 wxArrayVideoModes wxDisplayImplMacOSX::GetModes(const wxVideoMode& mode) const
161 {
162 wxArrayVideoModes Modes;
163
164 CFArrayRef theArray = CGDisplayAvailableModes(m_id);
165
166 for(CFIndex i = 0; i < CFArrayGetCount(theArray); ++i)
167 {
168 CFDictionaryRef theValue = (CFDictionaryRef) CFArrayGetValueAtIndex(theArray, i);
169
170 wxVideoMode theMode(wxCFDictKeyToInt(theValue, kCGDisplayWidth),
171 wxCFDictKeyToInt(theValue, kCGDisplayHeight),
172 wxCFDictKeyToInt(theValue, kCGDisplayBitsPerPixel),
173 wxCFDictKeyToInt(theValue, kCGDisplayRefreshRate));
174
175 if (theMode.Matches(mode))
176 Modes.Add(theMode);
177 }
178
179 return Modes;
180 }
181
182 wxVideoMode wxDisplayImplMacOSX::GetCurrentMode() const
183 {
184 CFDictionaryRef theValue = CGDisplayCurrentMode (m_id);
185
186 return wxVideoMode(wxCFDictKeyToInt(theValue, kCGDisplayWidth),
187 wxCFDictKeyToInt(theValue, kCGDisplayHeight),
188 wxCFDictKeyToInt(theValue, kCGDisplayBitsPerPixel),
189 wxCFDictKeyToInt(theValue, kCGDisplayRefreshRate));
190 }
191
192 bool wxDisplayImplMacOSX::ChangeMode(const wxVideoMode& mode)
193 {
194 //Changing to default mode (wxDefualtVideoMode) doesn't
195 //work because we don't have access to the system's 'scrn'
196 //resource which holds the user's mode which the system
197 //will return to after this app is done
198 boolean_t bExactMatch;
199 CFDictionaryRef theCGMode = CGDisplayBestModeForParametersAndRefreshRate (
200 m_id,
201 (size_t)mode.bpp,
202 (size_t)mode.w,
203 (size_t)mode.h,
204 (double)mode.refresh,
205 &bExactMatch);
206
207 bool bOK = bExactMatch;
208
209 if(bOK)
210 bOK = CGDisplaySwitchToMode(m_id, theCGMode) == CGDisplayNoErr;
211
212 return bOK;
213 }
214
215 // ============================================================================
216 // wxDisplay::CreateFactory()
217 // ============================================================================
218
219 /* static */ wxDisplayFactory *wxDisplay::CreateFactory()
220 {
221 return new wxDisplayFactoryMac;
222 }
223
224 #endif // wxUSE_DISPLAY
225