]> git.saurik.com Git - wxWidgets.git/blob - src/unix/displayx11.cpp
Implemented resolution changing using X11 video extentions\nBe sure to link with...
[wxWidgets.git] / src / unix / displayx11.cpp
1 ///////////////////////////////////////////////////////////////////////////
2 // Name: displayx11.cpp
3 // Purpose: Unix/X11 implementation of wxDisplay class
4 // Author: Brian Victor
5 // Modified by:
6 // Created: 12/05/02
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWindows team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "display.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #include "wx/display.h"
24 #include "wx/log.h"
25
26 #ifndef WX_PRECOMP
27 #include "wx/dynarray.h"
28 #include "wx/gdicmn.h"
29 #include "wx/string.h"
30 #include "wx/utils.h"
31 #endif /* WX_PRECOMP */
32
33 #if wxUSE_DISPLAY
34
35 /* These must be included after the wx files. Otherwise the Data macro in
36 * Xlibint.h conflicts with a function declaration in wx/list.h. */
37 extern "C" {
38 #include <X11/Xlib.h>
39 #include <X11/Xlibint.h>
40 #include <X11/extensions/Xinerama.h>
41 #include <X11/extensions/xf86vmode.h>
42 }
43
44 //free private data common to x (usually s3) servers
45 #define wxClearXVM(vm) if(vm.privsize) XFree(vm.c_private)
46 class wxDisplayUnixPriv
47 {
48 public:
49 wxRect m_rect;
50 int m_depth;
51 XF86VidModeModeInfo m_DefaultVidMode;
52 ~wxDisplayUnixPriv()
53 {
54 wxClearXVM(m_DefaultVidMode);
55 }
56 };
57
58 size_t wxDisplayBase::GetCount()
59 {
60 Display *disp = (Display*)wxGetDisplay();
61
62 if ( XineramaIsActive(disp) )
63 {
64 XineramaScreenInfo *screenarr;
65 int numscreens;
66 screenarr = XineramaQueryScreens(disp, &numscreens);
67 XFree(screenarr);
68 return numscreens;
69 }
70 else
71 {
72 return 1;
73 }
74 }
75
76 int wxDisplayBase::GetFromPoint(const wxPoint &p)
77 {
78 Display *disp = (Display*)wxGetDisplay();
79
80 if ( XineramaIsActive(disp) )
81 {
82 int which_screen = -1;
83 XineramaScreenInfo *screenarr;
84 int numscreens;
85 screenarr = XineramaQueryScreens(disp, &numscreens);
86
87 int i;
88 for (i = 0; i < numscreens; ++i)
89 {
90 if (p.x >= screenarr[i].x_org &&
91 p.x <= screenarr[i].x_org + screenarr[i].width &&
92 p.y >= screenarr[i].y_org &&
93 p.y <= screenarr[i].y_org + screenarr[i].height)
94 {
95 which_screen = i;
96 }
97 }
98
99 XFree(screenarr);
100 return which_screen;
101 }
102 else
103 {
104 wxSize size = wxGetDisplaySize();
105 if (p.x >= 0 &&
106 p.x <= size.GetWidth() &&
107 p.y > 0 &&
108 p.y <= size.GetHeight())
109 {
110 return 0;
111 }
112
113 return -1;
114 }
115
116 }
117
118 wxDisplay::wxDisplay(size_t index) : wxDisplayBase ( index ), m_priv( new wxDisplayUnixPriv )
119 {
120 Display *disp = (Display*)wxGetDisplay();
121
122 if ( XineramaIsActive(disp) )
123 {
124 XineramaScreenInfo *screenarr;
125 int numscreens;
126 screenarr = XineramaQueryScreens(disp, &numscreens);
127 m_priv->m_rect = wxRect(screenarr[index].x_org, screenarr[index].y_org,
128 screenarr[index].width, screenarr[index].height);
129 m_priv->m_depth = DefaultDepth(disp, DefaultScreen(disp));
130 XFree(screenarr);
131 }
132 else
133 {
134 wxSize size = wxGetDisplaySize();
135 m_priv->m_rect = wxRect(0, 0, size.GetWidth(), size.GetHeight());
136 m_priv->m_depth = wxDisplayDepth();
137 }
138
139
140 XF86VidModeModeLine VM;
141 int nDotClock;
142
143 XF86VidModeGetModeLine((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay()),
144 &nDotClock, &VM);
145
146 //A XF86VidModeModeLine is a XF86ModeModeInfo without the dotclock
147 //field. It would be nice to mayby use a memcpy() here instead of
148 //all this?
149 m_priv->m_DefaultVidMode.dotclock = nDotClock;
150 m_priv->m_DefaultVidMode.hdisplay = VM.hdisplay;
151 m_priv->m_DefaultVidMode.hsyncstart = VM.hsyncstart;
152 m_priv->m_DefaultVidMode.hsyncend = VM.hsyncend;
153 m_priv->m_DefaultVidMode.htotal = VM.htotal;
154 m_priv->m_DefaultVidMode.hskew = VM.hskew;
155 m_priv->m_DefaultVidMode.vdisplay = VM.vdisplay;
156 m_priv->m_DefaultVidMode.vsyncstart = VM.vsyncstart;
157 m_priv->m_DefaultVidMode.vsyncend = VM.vsyncend;
158 m_priv->m_DefaultVidMode.vtotal = VM.vtotal;
159 m_priv->m_DefaultVidMode.flags = VM.flags;
160 m_priv->m_DefaultVidMode.privsize = VM.privsize;
161 m_priv->m_DefaultVidMode.c_private = VM.c_private;
162 }
163
164 wxDisplay::~wxDisplay()
165 {
166 delete m_priv;
167 }
168
169 wxRect wxDisplay::GetGeometry() const
170 {
171 return m_priv->m_rect;
172 }
173
174 int wxDisplay::GetDepth() const
175 {
176 return m_priv->m_depth;
177 }
178
179 wxString wxDisplay::GetName() const
180 {
181 return wxEmptyString;
182 }
183
184 //
185 // See (http://www.xfree86.org/4.2.0/XF86VidModeDeleteModeLine.3.html) for more
186 // info about xf86 video mode extensions
187 //
188
189 #define wxCVM(v) wxVideoMode(v.hdisplay, v.vdisplay, v.dotclock /*BPP in X? */,((v.hsyncstart + v.vsyncstart) / 2) )
190 #define wxCVM2(v) wxVideoMode(v.hdisplay, v.vdisplay, 0 /*BPP in X? */,((v.hsyncstart + v.vsyncstart) / 2) )
191
192 wxArrayVideoModes wxDisplay::GetModes(const wxVideoMode& mode) const
193 {
194 //Convenience...
195 Display* pDisplay = (Display*) wxGetDisplay(); //default display
196 int nScreen = DefaultScreen(pDisplay); //default screen of (default) display...
197
198 //Some variables..
199 XF86VidModeModeInfo** ppXModes; //Enumerated Modes (Don't forget XFree() :))
200 int nNumModes; //Number of modes enumerated....
201
202 wxArrayVideoModes Modes; //modes to return...
203
204 if (XF86VidModeGetAllModeLines(pDisplay, nScreen, &nNumModes, &ppXModes) == TRUE)
205 {
206 for (int i = 0; i < nNumModes; ++i)
207 {
208 if (mode == wxDefaultVideoMode || //According to display.h All modes valid if dafault mode...
209 mode.Matches(wxCVM2((*ppXModes[i]))) ) //...?
210 {
211 Modes.Add(wxCVM2((*ppXModes[i])));
212 }
213 wxClearXVM((*ppXModes[i]));
214 // XFree(ppXModes[i]); //supposed to free?
215 }
216 XFree(ppXModes);
217 }
218 else //OOPS!
219 {
220 wxLogSysError("XF86VidModeGetAllModeLines Failed in wxX11Display::GetModes()!");
221 }
222
223 return Modes;
224 }
225
226 wxVideoMode wxDisplay::GetCurrentMode() const
227 {
228 return wxCVM2(m_priv->m_DefaultVidMode);
229 }
230
231 bool wxDisplay::ChangeMode(const wxVideoMode& mode)
232 {
233 if (mode == wxDefaultVideoMode)
234 {
235 return XF86VidModeSwitchToMode((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay()),
236 &m_priv->m_DefaultVidMode) == TRUE;
237 }
238 else //This gets kind of tricky AND complicated :) :\ :( :)
239 {
240 bool bRet = false;
241 //Some variables..
242 XF86VidModeModeInfo** ppXModes; //Enumerated Modes (Don't forget XFree() :))
243 int nNumModes; //Number of modes enumerated....
244
245 if(XF86VidModeGetAllModeLines((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay()), &nNumModes, &ppXModes) == TRUE)
246 {
247 for (int i = 0; i < nNumModes; ++i)
248 {
249 if (!bRet &&
250 ppXModes[i]->hdisplay == mode.w &&
251 ppXModes[i]->vdisplay == mode.h &&
252 ((ppXModes[i]->hsyncstart + ppXModes[i]->vsyncstart) / 2) == mode.refresh)
253 {
254 //switch!
255 bRet = XF86VidModeSwitchToMode((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay()),
256 ppXModes[i]) == TRUE;
257 }
258 wxClearXVM((*ppXModes[i]));
259 // XFree(ppXModes[i]); //supposed to free?
260 }
261 XFree(ppXModes);
262
263 return bRet;
264 }
265 else //OOPS!
266 {
267 wxLogSysError("XF86VidModeGetAllModeLines Failed in wxX11Display::ChangeMode()!");
268 return false;
269 }
270 }
271 }
272
273 #endif /* wxUSE_DISPLAY */
274