]> git.saurik.com Git - wxWidgets.git/blame - src/unix/displayx11.cpp
Semicolon needed.
[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__
24 #pragma hdrstop
25#endif
26
27#include "wx/display.h"
ef1717a9 28#include "wx/display_impl.h"
428b6942 29#include "wx/intl.h"
73b89f70 30#include "wx/log.h"
b1b3ddd8
JS
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. */
ef1717a9 43extern "C"
b1b3ddd8 44{
ef1717a9
VZ
45 #include <X11/Xlib.h>
46 #include <X11/Xlibint.h>
b1b3ddd8 47
ef1717a9
VZ
48 #include <X11/extensions/Xinerama.h>
49 #ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
50 #include <X11/extensions/xf86vmode.h>
51 #endif
b1b3ddd8
JS
52}
53
ef1717a9
VZ
54// ----------------------------------------------------------------------------
55// helper class to automatically free XineramaQueryScreens() return value
56// ----------------------------------------------------------------------------
57
58class ScreensInfo
b1b3ddd8 59{
ef1717a9
VZ
60public:
61 ScreensInfo()
b1b3ddd8 62 {
ef1717a9 63 m_screens = XineramaQueryScreens((Display *)wxGetDisplay(), &m_num);
b1b3ddd8
JS
64 }
65
ef1717a9 66 ~ScreensInfo()
3cb98121 67 {
ef1717a9 68 XFree(m_screens);
3cb98121
VZ
69 }
70
ef1717a9
VZ
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// ----------------------------------------------------------------------------
b1b3ddd8 83
ef1717a9 84class WXDLLEXPORT wxDisplayImplX11 : public wxDisplayImpl
b1b3ddd8 85{
ef1717a9 86public:
547308b8
VZ
87 wxDisplayImplX11(size_t n, const XineramaScreenInfo& info)
88 : wxDisplayImpl(n),
89 m_rect(info.x_org, info.y_org, info.width, info.height)
ef1717a9
VZ
90 {
91 }
b1b3ddd8 92
ef1717a9
VZ
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
b1b3ddd8 108{
ef1717a9 109public:
1003169e 110 wxDisplayFactoryX11() { }
ef1717a9
VZ
111
112 virtual wxDisplayImpl *CreateDisplay(size_t n);
113 virtual size_t GetCount();
114 virtual int GetFromPoint(const wxPoint& pt);
b1b3ddd8 115
ef1717a9
VZ
116protected:
117 DECLARE_NO_COPY_CLASS(wxDisplayFactoryX11)
118};
119
120// ============================================================================
121// wxDisplayFactoryX11 implementation
122// ============================================================================
123
124size_t wxDisplayFactoryX11::GetCount()
b1b3ddd8 125{
ef1717a9 126 return ScreensInfo().GetCount();
b1b3ddd8
JS
127}
128
ef1717a9 129int wxDisplayFactoryX11::GetFromPoint(const wxPoint& p)
b1b3ddd8 130{
ef1717a9
VZ
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;
b1b3ddd8
JS
145}
146
ef1717a9 147wxDisplayImpl *wxDisplayFactoryX11::CreateDisplay(size_t n)
b1b3ddd8 148{
ef1717a9
VZ
149 ScreensInfo screens;
150
547308b8 151 return n < screens.GetCount() ? new wxDisplayImplX11(n, screens[n]) : NULL;
b1b3ddd8
JS
152}
153
ef1717a9
VZ
154// ============================================================================
155// wxDisplayImplX11 implementation
156// ============================================================================
505c8ccd
VS
157
158#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
159
73b89f70
RN
160//
161// See (http://www.xfree86.org/4.2.0/XF86VidModeDeleteModeLine.3.html) for more
162// info about xf86 video mode extensions
163//
164
2980fc88
RN
165//free private data common to x (usually s3) servers
166#define wxClearXVM(vm) if(vm.privsize) XFree(vm.c_private)
167
a90bf709 168// Correct res rate from GLFW
2980fc88
RN
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)
73b89f70 173
0d5b6a40 174wxArrayVideoModes wxDisplayImplX11::GetModes(const wxVideoMode& mode) const
e07d33e7 175{
73b89f70
RN
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...
2980fc88 191 mode.Matches(wxCVM((*ppXModes[i]))) ) //...?
73b89f70 192 {
2980fc88 193 Modes.Add(wxCVM((*ppXModes[i])));
73b89f70
RN
194 }
195 wxClearXVM((*ppXModes[i]));
196 // XFree(ppXModes[i]); //supposed to free?
197 }
198 XFree(ppXModes);
199 }
200 else //OOPS!
201 {
428b6942 202 wxLogSysError(_("Failed to enumerate video modes"));
73b89f70
RN
203 }
204
205 return Modes;
e07d33e7
RN
206}
207
0d5b6a40 208wxVideoMode wxDisplayImplX11::GetCurrentMode() const
e07d33e7 209{
2980fc88
RN
210 XF86VidModeModeLine VM;
211 int nDotClock;
212 XF86VidModeGetModeLine((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay()),
213 &nDotClock, &VM);
214 wxClearXVM(VM);
215 return wxCVM2(VM, nDotClock);
e07d33e7
RN
216}
217
0d5b6a40 218bool wxDisplayImplX11::ChangeMode(const wxVideoMode& mode)
e07d33e7 219{
a90bf709
VZ
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) )
73b89f70 224 {
a90bf709
VZ
225 wxLogSysError(_("Failed to change video mode"));
226 return false;
227 }
73b89f70 228
a90bf709
VZ
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)
73b89f70 236 {
a90bf709
VZ
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)
2980fc88 249 {
a90bf709 250 //switch!
2980fc88 251 bRet = XF86VidModeSwitchToMode((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay()),
a90bf709 252 ppXModes[i]) == TRUE;
2980fc88 253 }
a90bf709
VZ
254 wxClearXVM((*ppXModes[i]));
255 // XFree(ppXModes[i]); //supposed to free?
73b89f70
RN
256 }
257 }
a90bf709
VZ
258
259 XFree(ppXModes);
260
261 return bRet;
e5804ce7
RN
262}
263
264
265#else // !HAVE_X11_EXTENSIONS_XF86VMODE_H
266
0d5b6a40 267wxArrayVideoModes wxDisplayImplX11::GetModes(const wxVideoMode& mode) const
e5804ce7 268{
ef1717a9
VZ
269 int count_return;
270 int* depths = XListDepths((Display*)wxGetDisplay(), 0, &count_return);
271 wxArrayVideoModes modes;
272 if ( depths )
f2ebd959 273 {
ef1717a9
VZ
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);
f2ebd959 280 }
ef1717a9 281 return modes;
505c8ccd
VS
282}
283
0d5b6a40 284wxVideoMode wxDisplayImplX11::GetCurrentMode() const
505c8ccd
VS
285{
286 // Not implemented
287 return wxVideoMode();
288}
289
0d5b6a40 290bool wxDisplayImplX11::ChangeMode(const wxVideoMode& mode)
505c8ccd
VS
291{
292 // Not implemented
293 return false;
294}
295
296#endif // !HAVE_X11_EXTENSIONS_XF86VMODE_H
297
ef1717a9
VZ
298// ============================================================================
299// wxDisplay::CreateFactory()
300// ============================================================================
301
302/* static */ wxDisplayFactory *wxDisplay::CreateFactory()
303{
547308b8
VZ
304 if ( XineramaIsActive((Display*)wxGetDisplay()) )
305 {
306 return new wxDisplayFactoryX11;
307 }
ef1717a9 308
547308b8 309 return new wxDisplayFactorySingle;
ef1717a9
VZ
310}
311
505c8ccd 312#endif /* wxUSE_DISPLAY */