fixed build after last commit
[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(size_t n, CGDirectDisplayID id_)
40         : wxDisplayImpl(n),
41           m_id(id_)
42     {
43     }
44
45     virtual wxRect GetGeometry() const;
46     virtual wxString GetName() const { return wxString(); }
47
48     virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const;
49     virtual wxVideoMode GetCurrentMode() const;
50     virtual bool ChangeMode(const wxVideoMode& mode);
51
52 private:
53     CGDirectDisplayID m_id;
54
55     DECLARE_NO_COPY_CLASS(wxDisplayImplMacOSX)
56 };
57
58 class wxDisplayFactoryMacOSX : public wxDisplayFactory
59 {
60 public:
61     wxDisplayFactoryMacOSX() { }
62
63     virtual wxDisplayImpl *CreateDisplay(size_t n);
64     virtual size_t GetCount();
65     virtual int GetFromPoint(const wxPoint& pt);
66
67 protected:
68     DECLARE_NO_COPY_CLASS(wxDisplayFactoryMacOSX)
69 };
70
71 // ============================================================================
72 // wxDisplayFactoryMacOSX implementation
73 // ============================================================================
74
75 size_t wxDisplayFactoryMacOSX::GetCount()
76 {
77     CGDisplayCount count;
78 #ifdef __WXDEBUG__
79     CGDisplayErr err =
80 #endif
81     CGGetActiveDisplayList(0, NULL, &count);
82
83     wxASSERT(err == CGDisplayNoErr);
84
85     return count;
86 }
87
88 int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint& p)
89 {
90     CGPoint thePoint = {(float)p.x, (float)p.y};
91     CGDirectDisplayID theID;
92     CGDisplayCount theCount;
93     CGDisplayErr err = CGGetDisplaysWithPoint(thePoint, 1, &theID, &theCount);
94     wxASSERT(err == CGDisplayNoErr);
95
96     int nWhich = wxNOT_FOUND;
97
98     if (theCount)
99     {
100         theCount = GetCount();
101         CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount];
102         err = CGGetActiveDisplayList(theCount, theIDs, &theCount);
103         wxASSERT(err == CGDisplayNoErr);
104
105         for (nWhich = 0; nWhich < (int) theCount; ++nWhich)
106         {
107             if (theIDs[nWhich] == theID)
108                 break;
109         }
110
111         delete [] theIDs;
112
113         if (nWhich == (int) theCount)
114         {
115             wxFAIL_MSG(wxT("Failed to find display in display list"));
116             nWhich = wxNOT_FOUND;
117         }
118     }
119
120     return nWhich;
121 }
122
123 wxDisplayImpl *wxDisplayFactoryMacOSX::CreateDisplay(size_t n)
124 {
125     CGDisplayCount theCount = GetCount();
126     CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount];
127
128 #ifdef __WXDEBUG__
129     CGDisplayErr err =
130 #endif
131     CGGetActiveDisplayList(theCount, theIDs, &theCount);
132
133     wxASSERT( err == CGDisplayNoErr );
134     wxASSERT( n < theCount );
135
136     wxDisplayImplMacOSX *display = new wxDisplayImplMacOSX(n, theIDs[n]);
137
138     delete [] theIDs;
139
140     return display;
141 }
142
143
144 wxRect wxDisplayImplMacOSX::GetGeometry() const
145 {
146     CGRect theRect = CGDisplayBounds(m_id);
147     return wxRect(  (int)theRect.origin.x,
148                     (int)theRect.origin.y,
149                     (int)theRect.size.width,
150                     (int)theRect.size.height  ); //floats
151 }
152
153 static int wxCFDictKeyToInt( CFDictionaryRef desc, CFStringRef key )
154 {
155     CFNumberRef value;
156     int num = 0;
157
158     if ( (value = (CFNumberRef) CFDictionaryGetValue(desc, key)) == NULL )
159         return 0;
160     CFNumberGetValue(value, kCFNumberIntType, &num);
161     return num;
162 }
163
164 wxArrayVideoModes wxDisplayImplMacOSX::GetModes(const wxVideoMode& mode) const
165 {
166     wxArrayVideoModes Modes;
167
168     CFArrayRef theArray = CGDisplayAvailableModes(m_id);
169
170     for(CFIndex i = 0; i < CFArrayGetCount(theArray); ++i)
171     {
172         CFDictionaryRef theValue = (CFDictionaryRef) CFArrayGetValueAtIndex(theArray, i);
173
174         wxVideoMode theMode(wxCFDictKeyToInt(theValue, kCGDisplayWidth),
175                             wxCFDictKeyToInt(theValue, kCGDisplayHeight),
176                             wxCFDictKeyToInt(theValue, kCGDisplayBitsPerPixel),
177                             wxCFDictKeyToInt(theValue, kCGDisplayRefreshRate));
178
179         if (theMode.Matches(mode))
180             Modes.Add(theMode);
181     }
182
183     return Modes;
184 }
185
186 wxVideoMode wxDisplayImplMacOSX::GetCurrentMode() const
187 {
188     CFDictionaryRef theValue = CGDisplayCurrentMode (m_id);
189
190     return wxVideoMode(wxCFDictKeyToInt(theValue, kCGDisplayWidth),
191                             wxCFDictKeyToInt(theValue, kCGDisplayHeight),
192                             wxCFDictKeyToInt(theValue, kCGDisplayBitsPerPixel),
193                             wxCFDictKeyToInt(theValue, kCGDisplayRefreshRate));
194 }
195
196 bool wxDisplayImplMacOSX::ChangeMode(const wxVideoMode& mode)
197 {
198     //Changing to default mode (wxDefualtVideoMode) doesn't
199     //work because we don't have access to the system's 'scrn'
200     //resource which holds the user's mode which the system
201     //will return to after this app is done
202     boolean_t bExactMatch;
203     CFDictionaryRef theCGMode = CGDisplayBestModeForParametersAndRefreshRate (
204                                         m_id,
205                                         (size_t)mode.bpp,
206                                         (size_t)mode.w,
207                                         (size_t)mode.h,
208                                         (double)mode.refresh,
209                                         &bExactMatch);
210
211     bool bOK = bExactMatch;
212
213     if(bOK)
214         bOK = CGDisplaySwitchToMode(m_id, theCGMode) == CGDisplayNoErr;
215
216     return bOK;
217 }
218
219 // ============================================================================
220 // wxDisplay::CreateFactory()
221 // ============================================================================
222
223 /* static */ wxDisplayFactory *wxDisplay::CreateFactory()
224 {
225     return new wxDisplayFactoryMacOSX;
226 }
227
228 #endif // wxUSE_DISPLAY
229