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
);
64 CGDirectDisplayID m_id
;
66 wxDECLARE_NO_COPY_CLASS(wxDisplayImplMacOSX
);
69 class wxDisplayFactoryMacOSX
: public wxDisplayFactory
72 wxDisplayFactoryMacOSX() {}
74 virtual wxDisplayImpl
*CreateDisplay(unsigned n
);
75 virtual unsigned GetCount();
76 virtual int GetFromPoint(const wxPoint
& pt
);
79 wxDECLARE_NO_COPY_CLASS(wxDisplayFactoryMacOSX
);
82 // ============================================================================
83 // wxDisplayFactoryMacOSX implementation
84 // ============================================================================
86 unsigned wxDisplayFactoryMacOSX::GetCount()
89 CGDisplayErr err
= CGGetActiveDisplayList(0, NULL
, &count
);
91 wxCHECK_MSG( err
== CGDisplayNoErr
, 0, "CGGetActiveDisplayList() failed" );
96 int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint
& p
)
98 CGPoint thePoint
= {(float)p
.x
, (float)p
.y
};
99 CGDirectDisplayID theID
;
100 CGDisplayCount theCount
;
101 CGDisplayErr err
= CGGetDisplaysWithPoint(thePoint
, 1, &theID
, &theCount
);
102 wxASSERT(err
== CGDisplayNoErr
);
104 int nWhich
= wxNOT_FOUND
;
108 theCount
= GetCount();
109 CGDirectDisplayID
* theIDs
= new CGDirectDisplayID
[theCount
];
110 err
= CGGetActiveDisplayList(theCount
, theIDs
, &theCount
);
111 wxASSERT(err
== CGDisplayNoErr
);
113 for (nWhich
= 0; nWhich
< (int) theCount
; ++nWhich
)
115 if (theIDs
[nWhich
] == theID
)
121 if (nWhich
== (int) theCount
)
123 wxFAIL_MSG(wxT("Failed to find display in display list"));
124 nWhich
= wxNOT_FOUND
;
131 wxDisplayImpl
*wxDisplayFactoryMacOSX::CreateDisplay(unsigned n
)
133 CGDisplayCount theCount
= GetCount();
134 CGDirectDisplayID
* theIDs
= new CGDirectDisplayID
[theCount
];
136 CGDisplayErr err
= CGGetActiveDisplayList(theCount
, theIDs
, &theCount
);
137 wxCHECK_MSG( err
== CGDisplayNoErr
, NULL
, "CGGetActiveDisplayList() failed" );
139 wxASSERT( n
< theCount
);
141 wxDisplayImplMacOSX
*display
= new wxDisplayImplMacOSX(n
, theIDs
[n
]);
148 // ============================================================================
149 // wxDisplayImplMacOSX implementation
150 // ============================================================================
152 wxRect
wxDisplayImplMacOSX::GetGeometry() const
154 CGRect theRect
= CGDisplayBounds(m_id
);
155 return wxRect( (int)theRect
.origin
.x
,
156 (int)theRect
.origin
.y
,
157 (int)theRect
.size
.width
,
158 (int)theRect
.size
.height
); //floats
161 wxRect
wxDisplayImplMacOSX::GetClientArea() const
163 // VZ: I don't know how to get client area for arbitrary display but
164 // wxGetClientDisplayRect() does work correctly for at least the main
165 // one (TODO: do it correctly for the other displays too)
167 return wxGetClientDisplayRect();
169 return wxDisplayImpl::GetClientArea();
172 static int wxCFDictKeyToInt( CFDictionaryRef desc
, CFStringRef key
)
174 CFNumberRef value
= (CFNumberRef
) CFDictionaryGetValue( desc
, key
);
179 CFNumberGetValue( value
, kCFNumberIntType
, &num
);
184 wxArrayVideoModes
wxDisplayImplMacOSX::GetModes(const wxVideoMode
& mode
) const
186 wxArrayVideoModes resultModes
;
188 CFArrayRef theArray
= CGDisplayAvailableModes( m_id
);
190 for (CFIndex i
= 0; i
< CFArrayGetCount(theArray
); ++i
)
192 CFDictionaryRef theValue
= (CFDictionaryRef
) CFArrayGetValueAtIndex( theArray
, i
);
195 wxCFDictKeyToInt( theValue
, kCGDisplayWidth
),
196 wxCFDictKeyToInt( theValue
, kCGDisplayHeight
),
197 wxCFDictKeyToInt( theValue
, kCGDisplayBitsPerPixel
),
198 wxCFDictKeyToInt( theValue
, kCGDisplayRefreshRate
));
200 if (theMode
.Matches( mode
))
201 resultModes
.Add( theMode
);
207 wxVideoMode
wxDisplayImplMacOSX::GetCurrentMode() const
209 CFDictionaryRef theValue
= CGDisplayCurrentMode( m_id
);
212 wxCFDictKeyToInt( theValue
, kCGDisplayWidth
),
213 wxCFDictKeyToInt( theValue
, kCGDisplayHeight
),
214 wxCFDictKeyToInt( theValue
, kCGDisplayBitsPerPixel
),
215 wxCFDictKeyToInt( theValue
, kCGDisplayRefreshRate
));
218 bool wxDisplayImplMacOSX::ChangeMode( const wxVideoMode
& mode
)
220 // Changing to default mode (wxDefaultVideoMode) doesn't
221 // work because we don't have access to the system's 'scrn'
222 // resource which holds the user's mode which the system
223 // will return to after this app is done
224 boolean_t bExactMatch
;
225 CFDictionaryRef theCGMode
= CGDisplayBestModeForParametersAndRefreshRate(
227 (size_t)mode
.GetDepth(),
228 (size_t)mode
.GetWidth(),
229 (size_t)mode
.GetHeight(),
230 (double)mode
.GetRefresh(),
233 bool bOK
= bExactMatch
;
236 bOK
= CGDisplaySwitchToMode( m_id
, theCGMode
) == CGDisplayNoErr
;
241 // ============================================================================
242 // wxDisplay::CreateFactory()
243 // ============================================================================
245 /* static */ wxDisplayFactory
*wxDisplay::CreateFactory()
247 return new wxDisplayFactoryMacOSX
;
252 /* static */ wxDisplayFactory
*wxDisplay::CreateFactory()
254 return new wxDisplayFactorySingle
;
259 #endif // wxUSE_DISPLAY