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
8 // Copyright: (c) wxWidgets team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #include "wx/wxprec.h"
28 #include "wx/display.h"
31 #include "wx/dynarray.h"
33 #include "wx/string.h"
34 #include "wx/gdicmn.h"
37 #include "wx/display_impl.h"
38 #include "wx/osx/private.h"
40 #if wxOSX_USE_COCOA_OR_CARBON
42 // ----------------------------------------------------------------------------
43 // display classes implementation
44 // ----------------------------------------------------------------------------
46 class wxDisplayImplMacOSX
: public wxDisplayImpl
49 wxDisplayImplMacOSX(unsigned n
, CGDirectDisplayID id
)
55 virtual wxRect
GetGeometry() const;
56 virtual wxRect
GetClientArea() const;
57 virtual wxString
GetName() const { return wxString(); }
59 virtual wxArrayVideoModes
GetModes(const wxVideoMode
& mode
) const;
60 virtual wxVideoMode
GetCurrentMode() const;
61 virtual bool ChangeMode(const wxVideoMode
& mode
);
63 virtual bool IsPrimary() const;
66 CGDirectDisplayID m_id
;
68 wxDECLARE_NO_COPY_CLASS(wxDisplayImplMacOSX
);
71 class wxDisplayFactoryMacOSX
: public wxDisplayFactory
74 wxDisplayFactoryMacOSX() {}
76 virtual wxDisplayImpl
*CreateDisplay(unsigned n
);
77 virtual unsigned GetCount();
78 virtual int GetFromPoint(const wxPoint
& pt
);
81 wxDECLARE_NO_COPY_CLASS(wxDisplayFactoryMacOSX
);
84 // ============================================================================
85 // wxDisplayFactoryMacOSX implementation
86 // ============================================================================
88 // gets all displays that are not mirror displays
90 static CGDisplayErr
wxOSXGetDisplayList(CGDisplayCount maxDisplays
,
91 CGDirectDisplayID
*displays
,
92 CGDisplayCount
*displayCount
)
94 CGDisplayErr error
= kCGErrorSuccess
;
95 CGDisplayCount onlineCount
;
97 error
= CGGetOnlineDisplayList(0,NULL
,&onlineCount
);
98 if ( error
== kCGErrorSuccess
)
101 if ( onlineCount
> 0 )
103 CGDirectDisplayID
*onlineDisplays
= new CGDirectDisplayID
[onlineCount
];
104 error
= CGGetOnlineDisplayList(onlineCount
,onlineDisplays
,&onlineCount
);
105 if ( error
== kCGErrorSuccess
)
107 for ( CGDisplayCount i
= 0; i
< onlineCount
; ++i
)
109 if ( CGDisplayMirrorsDisplay(onlineDisplays
[i
]) != kCGNullDirectDisplay
)
112 if ( displays
== NULL
)
116 if ( *displayCount
< maxDisplays
)
118 displays
[*displayCount
] = onlineDisplays
[i
];
124 delete[] onlineDisplays
;
131 unsigned wxDisplayFactoryMacOSX::GetCount()
133 CGDisplayCount count
;
134 CGDisplayErr err
= wxOSXGetDisplayList(0, NULL
, &count
);
136 wxCHECK_MSG( err
== CGDisplayNoErr
, 0, "wxOSXGetDisplayList() failed" );
141 int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint
& p
)
143 CGPoint thePoint
= {(float)p
.x
, (float)p
.y
};
144 CGDirectDisplayID theID
;
145 CGDisplayCount theCount
;
146 CGDisplayErr err
= CGGetDisplaysWithPoint(thePoint
, 1, &theID
, &theCount
);
147 wxASSERT(err
== CGDisplayNoErr
);
149 int nWhich
= wxNOT_FOUND
;
153 theCount
= GetCount();
154 CGDirectDisplayID
* theIDs
= new CGDirectDisplayID
[theCount
];
155 err
= wxOSXGetDisplayList(theCount
, theIDs
, &theCount
);
156 wxASSERT(err
== CGDisplayNoErr
);
158 for (nWhich
= 0; nWhich
< (int) theCount
; ++nWhich
)
160 if (theIDs
[nWhich
] == theID
)
166 if (nWhich
== (int) theCount
)
168 wxFAIL_MSG(wxT("Failed to find display in display list"));
169 nWhich
= wxNOT_FOUND
;
176 wxDisplayImpl
*wxDisplayFactoryMacOSX::CreateDisplay(unsigned n
)
178 CGDisplayCount theCount
= GetCount();
179 CGDirectDisplayID
* theIDs
= new CGDirectDisplayID
[theCount
];
181 CGDisplayErr err
= wxOSXGetDisplayList(theCount
, theIDs
, &theCount
);
182 wxCHECK_MSG( err
== CGDisplayNoErr
, NULL
, "wxOSXGetDisplayList() failed" );
184 wxASSERT( n
< theCount
);
186 wxDisplayImplMacOSX
*display
= new wxDisplayImplMacOSX(n
, theIDs
[n
]);
193 // ============================================================================
194 // wxDisplayImplMacOSX implementation
195 // ============================================================================
197 bool wxDisplayImplMacOSX::IsPrimary() const
199 return CGDisplayIsMain(m_id
);
202 wxRect
wxDisplayImplMacOSX::GetGeometry() const
204 CGRect theRect
= CGDisplayBounds(m_id
);
205 return wxRect( (int)theRect
.origin
.x
,
206 (int)theRect
.origin
.y
,
207 (int)theRect
.size
.width
,
208 (int)theRect
.size
.height
); //floats
211 wxRect
wxDisplayImplMacOSX::GetClientArea() const
213 // VZ: I don't know how to get client area for arbitrary display but
214 // wxGetClientDisplayRect() does work correctly for at least the main
215 // one (TODO: do it correctly for the other displays too)
217 return wxGetClientDisplayRect();
219 return wxDisplayImpl::GetClientArea();
222 static int wxCFDictKeyToInt( CFDictionaryRef desc
, CFStringRef key
)
224 CFNumberRef value
= (CFNumberRef
) CFDictionaryGetValue( desc
, key
);
229 CFNumberGetValue( value
, kCFNumberIntType
, &num
);
234 wxArrayVideoModes
wxDisplayImplMacOSX::GetModes(const wxVideoMode
& mode
) const
236 wxArrayVideoModes resultModes
;
238 CFArrayRef theArray
= CGDisplayAvailableModes( m_id
);
240 for (CFIndex i
= 0; i
< CFArrayGetCount(theArray
); ++i
)
242 CFDictionaryRef theValue
= (CFDictionaryRef
) CFArrayGetValueAtIndex( theArray
, i
);
245 wxCFDictKeyToInt( theValue
, kCGDisplayWidth
),
246 wxCFDictKeyToInt( theValue
, kCGDisplayHeight
),
247 wxCFDictKeyToInt( theValue
, kCGDisplayBitsPerPixel
),
248 wxCFDictKeyToInt( theValue
, kCGDisplayRefreshRate
));
250 if (theMode
.Matches( mode
))
251 resultModes
.Add( theMode
);
257 wxVideoMode
wxDisplayImplMacOSX::GetCurrentMode() const
259 CFDictionaryRef theValue
= CGDisplayCurrentMode( m_id
);
262 wxCFDictKeyToInt( theValue
, kCGDisplayWidth
),
263 wxCFDictKeyToInt( theValue
, kCGDisplayHeight
),
264 wxCFDictKeyToInt( theValue
, kCGDisplayBitsPerPixel
),
265 wxCFDictKeyToInt( theValue
, kCGDisplayRefreshRate
));
268 bool wxDisplayImplMacOSX::ChangeMode( const wxVideoMode
& mode
)
270 // Changing to default mode (wxDefaultVideoMode) doesn't
271 // work because we don't have access to the system's 'scrn'
272 // resource which holds the user's mode which the system
273 // will return to after this app is done
274 boolean_t bExactMatch
;
275 CFDictionaryRef theCGMode
= CGDisplayBestModeForParametersAndRefreshRate(
277 (size_t)mode
.GetDepth(),
278 (size_t)mode
.GetWidth(),
279 (size_t)mode
.GetHeight(),
280 (double)mode
.GetRefresh(),
283 bool bOK
= bExactMatch
;
286 bOK
= CGDisplaySwitchToMode( m_id
, theCGMode
) == CGDisplayNoErr
;
291 // ============================================================================
292 // wxDisplay::CreateFactory()
293 // ============================================================================
295 /* static */ wxDisplayFactory
*wxDisplay::CreateFactory()
297 return new wxDisplayFactoryMacOSX
;
302 /* static */ wxDisplayFactory
*wxDisplay::CreateFactory()
304 return new wxDisplayFactorySingle
;
309 #endif // wxUSE_DISPLAY