]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/unix/displayx11.cpp
fixed fatal buffer overwrite in wxMBConvUTF16swap::MB2WC()
[wxWidgets.git] / src / unix / displayx11.cpp
... / ...
CommitLineData
1///////////////////////////////////////////////////////////////////////////
2// Name: src/unix/displayx11.cpp
3// Purpose: Unix/X11 implementation of wxDisplay class
4// Author: Brian Victor, Vadim Zeitlin
5// Modified by:
6// Created: 12/05/02
7// RCS-ID: $Id$
8// Copyright: (c) wxWidgets team
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#include "wx/display.h"
28#include "wx/display_impl.h"
29#include "wx/intl.h"
30#include "wx/log.h"
31
32#ifndef WX_PRECOMP
33 #include "wx/dynarray.h"
34 #include "wx/gdicmn.h"
35 #include "wx/string.h"
36 #include "wx/utils.h"
37#endif /* WX_PRECOMP */
38
39#if wxUSE_DISPLAY
40
41/* These must be included after the wx files. Otherwise the Data macro in
42 * Xlibint.h conflicts with a function declaration in wx/list.h. */
43extern "C"
44{
45 #include <X11/Xlib.h>
46 #include <X11/Xlibint.h>
47
48 #include <X11/extensions/Xinerama.h>
49 #ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
50 #include <X11/extensions/xf86vmode.h>
51 #endif
52}
53
54// ----------------------------------------------------------------------------
55// helper class to automatically free XineramaQueryScreens() return value
56// ----------------------------------------------------------------------------
57
58class ScreensInfo
59{
60public:
61 ScreensInfo()
62 {
63 m_screens = XineramaQueryScreens((Display *)wxGetDisplay(), &m_num);
64 }
65
66 ~ScreensInfo()
67 {
68 XFree(m_screens);
69 }
70
71 operator const XineramaScreenInfo *() const { return m_screens; }
72
73 size_t GetCount() const { return wx_static_cast(size_t, m_num); }
74
75private:
76 XineramaScreenInfo *m_screens;
77 int m_num;
78};
79
80// ----------------------------------------------------------------------------
81// display and display factory classes
82// ----------------------------------------------------------------------------
83
84class WXDLLEXPORT wxDisplayImplX11 : public wxDisplayImpl
85{
86public:
87 wxDisplayImplX11(size_t n, const XineramaScreenInfo& info)
88 : wxDisplayImpl(n),
89 m_rect(info.x_org, info.y_org, info.width, info.height)
90 {
91 }
92
93 virtual wxRect GetGeometry() const { return m_rect; }
94 virtual wxString GetName() const { return wxString(); }
95
96 virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const;
97 virtual wxVideoMode GetCurrentMode() const;
98 virtual bool ChangeMode(const wxVideoMode& mode);
99
100private:
101 wxRect m_rect;
102 int m_depth;
103
104 DECLARE_NO_COPY_CLASS(wxDisplayImplX11)
105};
106
107class wxDisplayFactoryX11 : public wxDisplayFactory
108{
109public:
110 wxDisplayFactoryX11() { }
111
112 virtual wxDisplayImpl *CreateDisplay(size_t n);
113 virtual size_t GetCount();
114 virtual int GetFromPoint(const wxPoint& pt);
115
116protected:
117 DECLARE_NO_COPY_CLASS(wxDisplayFactoryX11)
118};
119
120// ============================================================================
121// wxDisplayFactoryX11 implementation
122// ============================================================================
123
124size_t wxDisplayFactoryX11::GetCount()
125{
126 return ScreensInfo().GetCount();
127}
128
129int wxDisplayFactoryX11::GetFromPoint(const wxPoint& p)
130{
131 ScreensInfo screens;
132
133 const size_t numscreens(screens.GetCount());
134 for ( size_t i = 0; i < numscreens; ++i )
135 {
136 const XineramaScreenInfo& s = screens[i];
137 if ( p.x >= s.x_org && p.x < s.x_org + s.width &&
138 p.y >= s.y_org && p.y < s.y_org + s.height )
139 {
140 return i;
141 }
142 }
143
144 return wxNOT_FOUND;
145}
146
147wxDisplayImpl *wxDisplayFactoryX11::CreateDisplay(size_t n)
148{
149 ScreensInfo screens;
150
151 return n < screens.GetCount() ? new wxDisplayImplX11(n, screens[n]) : NULL;
152}
153
154// ============================================================================
155// wxDisplayImplX11 implementation
156// ============================================================================
157
158#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
159
160//
161// See (http://www.xfree86.org/4.2.0/XF86VidModeDeleteModeLine.3.html) for more
162// info about xf86 video mode extensions
163//
164
165//free private data common to x (usually s3) servers
166#define wxClearXVM(vm) if(vm.privsize) XFree(vm.c_private)
167
168// Correct res rate from GLFW
169#define wxCRR2(v,dc) (int) (((1000.0f * (float) dc) /*PIXELS PER SECOND */) / ((float) v.htotal * v.vtotal /*PIXELS PER FRAME*/) + 0.5f)
170#define wxCRR(v) wxCRR2(v,v.dotclock)
171#define wxCVM2(v, dc) wxVideoMode(v.hdisplay, v.vdisplay, DefaultDepth((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay())), wxCRR2(v,dc))
172#define wxCVM(v) wxCVM2(v, v.dotclock)
173
174wxArrayVideoModes wxDisplayImplX11::GetModes(const wxVideoMode& mode) const
175{
176 //Convenience...
177 Display* pDisplay = (Display*) wxGetDisplay(); //default display
178 int nScreen = DefaultScreen(pDisplay); //default screen of (default) display...
179
180 //Some variables..
181 XF86VidModeModeInfo** ppXModes; //Enumerated Modes (Don't forget XFree() :))
182 int nNumModes; //Number of modes enumerated....
183
184 wxArrayVideoModes Modes; //modes to return...
185
186 if (XF86VidModeGetAllModeLines(pDisplay, nScreen, &nNumModes, &ppXModes) == TRUE)
187 {
188 for (int i = 0; i < nNumModes; ++i)
189 {
190 if (mode == wxDefaultVideoMode || //According to display.h All modes valid if dafault mode...
191 mode.Matches(wxCVM((*ppXModes[i]))) ) //...?
192 {
193 Modes.Add(wxCVM((*ppXModes[i])));
194 }
195 wxClearXVM((*ppXModes[i]));
196 // XFree(ppXModes[i]); //supposed to free?
197 }
198 XFree(ppXModes);
199 }
200 else //OOPS!
201 {
202 wxLogSysError(_("Failed to enumerate video modes"));
203 }
204
205 return Modes;
206}
207
208wxVideoMode wxDisplayImplX11::GetCurrentMode() const
209{
210 XF86VidModeModeLine VM;
211 int nDotClock;
212 XF86VidModeGetModeLine((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay()),
213 &nDotClock, &VM);
214 wxClearXVM(VM);
215 return wxCVM2(VM, nDotClock);
216}
217
218bool wxDisplayImplX11::ChangeMode(const wxVideoMode& mode)
219{
220 XF86VidModeModeInfo** ppXModes; //Enumerated Modes (Don't forget XFree() :))
221 int nNumModes; //Number of modes enumerated....
222
223 if( !XF86VidModeGetAllModeLines((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay()), &nNumModes, &ppXModes) )
224 {
225 wxLogSysError(_("Failed to change video mode"));
226 return false;
227 }
228
229 bool bRet = false;
230 if (mode == wxDefaultVideoMode)
231 {
232 bRet = XF86VidModeSwitchToMode((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay()),
233 ppXModes[0]) == TRUE;
234
235 for (int i = 0; i < nNumModes; ++i)
236 {
237 wxClearXVM((*ppXModes[i]));
238 // XFree(ppXModes[i]); //supposed to free?
239 }
240 }
241 else
242 {
243 for (int i = 0; i < nNumModes; ++i)
244 {
245 if (!bRet &&
246 ppXModes[i]->hdisplay == mode.w &&
247 ppXModes[i]->vdisplay == mode.h &&
248 wxCRR((*ppXModes[i])) == mode.refresh)
249 {
250 //switch!
251 bRet = XF86VidModeSwitchToMode((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay()),
252 ppXModes[i]) == TRUE;
253 }
254 wxClearXVM((*ppXModes[i]));
255 // XFree(ppXModes[i]); //supposed to free?
256 }
257 }
258
259 XFree(ppXModes);
260
261 return bRet;
262}
263
264
265#else // !HAVE_X11_EXTENSIONS_XF86VMODE_H
266
267wxArrayVideoModes wxDisplayImplX11::GetModes(const wxVideoMode& mode) const
268{
269 int count_return;
270 int* depths = XListDepths((Display*)wxGetDisplay(), 0, &count_return);
271 wxArrayVideoModes modes;
272 if ( depths )
273 {
274 for ( int x = 0; x < count_return; ++x )
275 {
276 modes.Add(wxVideoMode(m_rect.GetWidth(), m_rect.GetHeight(), depths[x]));
277 }
278
279 XFree(depths);
280 }
281 return modes;
282}
283
284wxVideoMode wxDisplayImplX11::GetCurrentMode() const
285{
286 // Not implemented
287 return wxVideoMode();
288}
289
290bool wxDisplayImplX11::ChangeMode(const wxVideoMode& mode)
291{
292 // Not implemented
293 return false;
294}
295
296#endif // !HAVE_X11_EXTENSIONS_XF86VMODE_H
297
298// ============================================================================
299// wxDisplay::CreateFactory()
300// ============================================================================
301
302/* static */ wxDisplayFactory *wxDisplay::CreateFactory()
303{
304 if ( XineramaIsActive((Display*)wxGetDisplay()) )
305 {
306 return new wxDisplayFactoryX11;
307 }
308
309 return new wxDisplayFactorySingle;
310}
311
312#endif /* wxUSE_DISPLAY */