]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/display.cpp
weak link test is not optimal, as CoreText is already having some symbols defined...
[wxWidgets.git] / src / mac / carbon / display.cpp
CommitLineData
a536e411 1/////////////////////////////////////////////////////////////////////////////
ef1717a9 2// Name: src/mac/carbon/display.cpp
a536e411 3// Purpose: Mac implementation of wxDisplay class
cc9d56b0 4// Author: Ryan Norton & Brian Victor
ef1717a9 5// Modified by: Royce Mitchell III, Vadim Zeitlin
a536e411
JS
6// Created: 06/21/02
7// RCS-ID: $Id$
77ffb593 8// Copyright: (c) wxWidgets team
65571936 9// Licence: wxWindows licence
a536e411
JS
10/////////////////////////////////////////////////////////////////////////////
11
ef1717a9
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
a536e411
JS
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#if wxUSE_DISPLAY
27
df91131c
WS
28#include "wx/display.h"
29
a536e411 30#ifndef WX_PRECOMP
ad9835c9
WS
31 #include "wx/dynarray.h"
32 #include "wx/log.h"
df91131c 33 #include "wx/string.h"
dd05139a 34 #include "wx/gdicmn.h"
a536e411
JS
35#endif
36
9d463591 37#include <Carbon/Carbon.h>
a536e411 38
ef1717a9 39#include "wx/display_impl.h"
a536e411
JS
40
41// ----------------------------------------------------------------------------
ef1717a9 42// display classes implementation
a536e411
JS
43// ----------------------------------------------------------------------------
44
ef1717a9 45class wxDisplayImplMacOSX : public wxDisplayImpl
20b69855
SC
46{
47public:
4e675101 48 wxDisplayImplMacOSX(unsigned n, CGDirectDisplayID id)
f37c35d7
VZ
49 : wxDisplayImpl(n),
50 m_id(id)
51 {
52 }
ef1717a9
VZ
53
54 virtual wxRect GetGeometry() const;
0d045709 55 virtual wxRect GetClientArea() const;
ef1717a9
VZ
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
62private:
20b69855 63 CGDirectDisplayID m_id;
ef1717a9
VZ
64
65 DECLARE_NO_COPY_CLASS(wxDisplayImplMacOSX)
20b69855
SC
66};
67
ef1717a9
VZ
68class wxDisplayFactoryMacOSX : public wxDisplayFactory
69{
70public:
6a5cb3b7 71 wxDisplayFactoryMacOSX() {}
ef1717a9 72
4e675101
PC
73 virtual wxDisplayImpl *CreateDisplay(unsigned n);
74 virtual unsigned GetCount();
ef1717a9
VZ
75 virtual int GetFromPoint(const wxPoint& pt);
76
77protected:
78 DECLARE_NO_COPY_CLASS(wxDisplayFactoryMacOSX)
79};
80
81// ============================================================================
82// wxDisplayFactoryMacOSX implementation
83// ============================================================================
84
4e675101 85unsigned wxDisplayFactoryMacOSX::GetCount()
20b69855
SC
86{
87 CGDisplayCount count;
ef1717a9
VZ
88#ifdef __WXDEBUG__
89 CGDisplayErr err =
90#endif
91 CGGetActiveDisplayList(0, NULL, &count);
20b69855
SC
92
93 wxASSERT(err == CGDisplayNoErr);
a5714345 94
20b69855
SC
95 return count;
96}
97
ef1717a9 98int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint& p)
d0ee33f5 99{
20b69855
SC
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);
a5714345 105
ef1717a9 106 int nWhich = wxNOT_FOUND;
d0ee33f5 107
20b69855
SC
108 if (theCount)
109 {
110 theCount = GetCount();
111 CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount];
112 err = CGGetActiveDisplayList(theCount, theIDs, &theCount);
113 wxASSERT(err == CGDisplayNoErr);
114
a5714345 115 for (nWhich = 0; nWhich < (int) theCount; ++nWhich)
20b69855 116 {
a5714345 117 if (theIDs[nWhich] == theID)
20b69855
SC
118 break;
119 }
d0ee33f5 120
a5714345 121 delete [] theIDs;
d0ee33f5 122
a5714345 123 if (nWhich == (int) theCount)
20b69855
SC
124 {
125 wxFAIL_MSG(wxT("Failed to find display in display list"));
ef1717a9 126 nWhich = wxNOT_FOUND;
20b69855
SC
127 }
128 }
d0ee33f5 129
20b69855 130 return nWhich;
a5714345 131}
20b69855 132
4e675101 133wxDisplayImpl *wxDisplayFactoryMacOSX::CreateDisplay(unsigned n)
20b69855
SC
134{
135 CGDisplayCount theCount = GetCount();
136 CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount];
20b69855 137
ef1717a9
VZ
138#ifdef __WXDEBUG__
139 CGDisplayErr err =
140#endif
141 CGGetActiveDisplayList(theCount, theIDs, &theCount);
a5714345
DS
142
143 wxASSERT( err == CGDisplayNoErr );
ef1717a9 144 wxASSERT( n < theCount );
d0ee33f5 145
f37c35d7 146 wxDisplayImplMacOSX *display = new wxDisplayImplMacOSX(n, theIDs[n]);
d0ee33f5 147
a5714345 148 delete [] theIDs;
ef1717a9
VZ
149
150 return display;
20b69855
SC
151}
152
ef1717a9
VZ
153// ============================================================================
154// wxDisplayImplMacOSX implementation
155// ============================================================================
156
157wxRect wxDisplayImplMacOSX::GetGeometry() const
20b69855 158{
ef1717a9 159 CGRect theRect = CGDisplayBounds(m_id);
d0ee33f5
WS
160 return wxRect( (int)theRect.origin.x,
161 (int)theRect.origin.y,
162 (int)theRect.size.width,
a5714345 163 (int)theRect.size.height ); //floats
20b69855
SC
164}
165
0d045709
VZ
166wxRect 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
20b69855
SC
177static int wxCFDictKeyToInt( CFDictionaryRef desc, CFStringRef key )
178{
a5714345
DS
179 CFNumberRef value = (CFNumberRef) CFDictionaryGetValue( desc, key );
180 if (value == NULL)
181 return 0;
182
20b69855 183 int num = 0;
a5714345 184 CFNumberGetValue( value, kCFNumberIntType, &num );
20b69855 185
20b69855
SC
186 return num;
187}
188
ef1717a9 189wxArrayVideoModes wxDisplayImplMacOSX::GetModes(const wxVideoMode& mode) const
20b69855 190{
a5714345 191 wxArrayVideoModes resultModes;
d0ee33f5 192
ef1717a9 193 CFArrayRef theArray = CGDisplayAvailableModes( m_id );
20b69855 194
a5714345 195 for (CFIndex i = 0; i < CFArrayGetCount(theArray); ++i)
20b69855 196 {
a5714345 197 CFDictionaryRef theValue = (CFDictionaryRef) CFArrayGetValueAtIndex( theArray, i );
d0ee33f5 198
a5714345
DS
199 wxVideoMode theMode(
200 wxCFDictKeyToInt( theValue, kCGDisplayWidth ),
201 wxCFDictKeyToInt( theValue, kCGDisplayHeight ),
202 wxCFDictKeyToInt( theValue, kCGDisplayBitsPerPixel ),
203 wxCFDictKeyToInt( theValue, kCGDisplayRefreshRate ));
d0ee33f5 204
a5714345
DS
205 if (theMode.Matches( mode ))
206 resultModes.Add( theMode );
20b69855 207 }
d0ee33f5 208
a5714345 209 return resultModes;
20b69855
SC
210}
211
ef1717a9 212wxVideoMode wxDisplayImplMacOSX::GetCurrentMode() const
20b69855 213{
ef1717a9 214 CFDictionaryRef theValue = CGDisplayCurrentMode( m_id );
d0ee33f5 215
a5714345
DS
216 return wxVideoMode(
217 wxCFDictKeyToInt( theValue, kCGDisplayWidth ),
218 wxCFDictKeyToInt( theValue, kCGDisplayHeight ),
219 wxCFDictKeyToInt( theValue, kCGDisplayBitsPerPixel ),
220 wxCFDictKeyToInt( theValue, kCGDisplayRefreshRate ));
20b69855
SC
221}
222
ef1717a9 223bool wxDisplayImplMacOSX::ChangeMode( const wxVideoMode& mode )
20b69855 224{
a5714345
DS
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
20b69855 229 boolean_t bExactMatch;
a5714345 230 CFDictionaryRef theCGMode = CGDisplayBestModeForParametersAndRefreshRate(
ef1717a9 231 m_id,
a5714345
DS
232 (size_t)mode.bpp,
233 (size_t)mode.w,
234 (size_t)mode.h,
235 (double)mode.refresh,
236 &bExactMatch );
d0ee33f5 237
20b69855 238 bool bOK = bExactMatch;
d0ee33f5 239
a5714345 240 if (bOK)
ef1717a9 241 bOK = CGDisplaySwitchToMode( m_id, theCGMode ) == CGDisplayNoErr;
20b69855
SC
242
243 return bOK;
244}
245
ef1717a9
VZ
246// ============================================================================
247// wxDisplay::CreateFactory()
248// ============================================================================
249
250/* static */ wxDisplayFactory *wxDisplay::CreateFactory()
20b69855 251{
ef1717a9 252 return new wxDisplayFactoryMacOSX;
20b69855
SC
253}
254
a536e411 255#endif // wxUSE_DISPLAY