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