]> git.saurik.com Git - wxWidgets.git/blame - src/unix/glx11.cpp
button text uses fg color, not text color
[wxWidgets.git] / src / unix / glx11.cpp
CommitLineData
498ace9e
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/univ/glx11.cpp
3// Purpose: code common to all X11-based wxGLCanvas implementations
4// Author: Vadim Zeitlin
5// Created: 2007-04-15
6// RCS-ID: $Id$
7// Copyright: (c) 2007 Vadim Zeitlin <vadim@wxwindows.org>
8// Licence: wxWindows licence
9///////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
19// for compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#if wxUSE_GLCANVAS
23
24#ifndef WX_PRECOMP
50c95f69 25 #include "wx/log.h"
498ace9e
VZ
26#endif //WX_PRECOMP
27
28#include "wx/glcanvas.h"
29
30// ============================================================================
31// wxGLContext implementation
32// ============================================================================
33
34IMPLEMENT_CLASS(wxGLContext, wxObject)
35
36wxGLContext::wxGLContext(wxGLCanvas *gc, const wxGLContext *other)
37{
38 if ( wxGLCanvas::GetGLXVersion() >= 13 )
39 {
40 GLXFBConfig *fbc = gc->GetGLXFBConfig();
41 wxCHECK_RET( fbc, _T("invalid GLXFBConfig for OpenGL") );
42
43 m_glContext = glXCreateNewContext( wxGetX11Display(), fbc[0], GLX_RGBA_TYPE,
44 other ? other->m_glContext : None,
45 GL_TRUE );
46 }
47 else // GLX <= 1.2
48 {
49 XVisualInfo *vi = gc->GetXVisualInfo();
50 wxCHECK_RET( vi, _T("invalid visual for OpenGL") );
51
52 m_glContext = glXCreateContext( wxGetX11Display(), vi,
53 other ? other->m_glContext : None,
54 GL_TRUE );
55 }
56
57 wxASSERT_MSG( m_glContext, _T("Couldn't create OpenGL context") );
58}
59
60wxGLContext::~wxGLContext()
61{
62 if ( !m_glContext )
63 return;
64
65 if ( m_glContext == glXGetCurrentContext() )
66 MakeCurrent(None, NULL);
67
68 glXDestroyContext( wxGetX11Display(), m_glContext );
69}
70
5ec69e96 71bool wxGLContext::SetCurrent(const wxGLCanvas& win) const
498ace9e
VZ
72{
73 if ( !m_glContext )
5ec69e96 74 return false;
498ace9e
VZ
75
76 const Window xid = win.GetXWindow();
5ec69e96 77 wxCHECK2_MSG( xid, return false, _T("window must be shown") );
498ace9e 78
5ec69e96 79 return MakeCurrent(xid, m_glContext);
498ace9e
VZ
80}
81
82// wrapper around glXMakeContextCurrent/glXMakeCurrent depending on GLX
83// version
84/* static */
5ec69e96 85bool wxGLContext::MakeCurrent(GLXDrawable drawable, GLXContext context)
498ace9e
VZ
86{
87 if (wxGLCanvas::GetGLXVersion() >= 13)
5ec69e96 88 return glXMakeContextCurrent( wxGetX11Display(), drawable, drawable, context);
498ace9e 89 else // GLX <= 1.2 doesn't have glXMakeContextCurrent()
5ec69e96 90 return glXMakeCurrent( wxGetX11Display(), drawable, context);
498ace9e
VZ
91}
92
93// ============================================================================
94// wxGLCanvasX11 implementation
95// ============================================================================
96
97// ----------------------------------------------------------------------------
98// initialization methods and dtor
99// ----------------------------------------------------------------------------
100
101wxGLCanvasX11::wxGLCanvasX11()
102{
103 m_fbc = NULL;
104 m_vi = NULL;
105}
106
107bool wxGLCanvasX11::InitVisual(const int *attribList)
108{
109 return InitXVisualInfo(attribList, &m_fbc, &m_vi);
110}
111
112wxGLCanvasX11::~wxGLCanvasX11()
113{
114 if ( m_fbc && m_fbc != ms_glFBCInfo )
115 XFree(m_fbc);
116
117 if ( m_vi && m_vi != ms_glVisualInfo )
118 XFree(m_vi);
119}
120
121// ----------------------------------------------------------------------------
122// working with GL attributes
123// ----------------------------------------------------------------------------
124
125bool
126wxGLCanvasX11::ConvertWXAttrsToGL(const int *wxattrs, int *glattrs, size_t n)
127{
128 wxCHECK_MSG( n >= 16, false, _T("GL attributes buffer too small") );
129
130 if ( !wxattrs )
131 {
06e6496e
VZ
132 size_t i = 0;
133
134 // use double-buffered true colour by default
135 glattrs[i++] = GLX_RGBA; glattrs[i++] = True;
136 glattrs[i++] = GLX_DOUBLEBUFFER; glattrs[i++] = True;
137
138 if ( GetGLXVersion() < 13 )
498ace9e
VZ
139 {
140 // default settings if attriblist = 0
498ace9e
VZ
141 glattrs[i++] = GLX_DEPTH_SIZE; glattrs[i++] = 1;
142 glattrs[i++] = GLX_RED_SIZE; glattrs[i++] = 1;
143 glattrs[i++] = GLX_GREEN_SIZE; glattrs[i++] = 1;
144 glattrs[i++] = GLX_BLUE_SIZE; glattrs[i++] = 1;
145 glattrs[i++] = GLX_ALPHA_SIZE; glattrs[i++] = 0;
498ace9e 146 }
06e6496e
VZ
147 //else: recent GLX can choose the defaults on its own just fine
148
149 glattrs[i] = None;
150
151 wxASSERT_MSG( i < n, _T("GL attributes buffer too small") );
498ace9e
VZ
152 }
153 else // have non-default attributes
154 {
155 size_t p = 0;
156 for ( int arg = 0; wxattrs[arg] != 0; )
157 {
158 // check if we have any space left, knowing that we may insert 2
159 // more elements during this loop iteration and we always need to
160 // terminate the list with None (hence -3)
06e6496e 161 if ( p > n - 3 )
498ace9e
VZ
162 return false;
163
498ace9e
VZ
164 switch ( wxattrs[arg++] )
165 {
498ace9e
VZ
166 case WX_GL_BUFFER_SIZE:
167 glattrs[p++] = GLX_BUFFER_SIZE;
168 break;
169
170 case WX_GL_LEVEL:
171 glattrs[p++] = GLX_LEVEL;
172 break;
173
85866f52
VZ
174 // the following boolean attributes don't have values in wx
175 // API (they're turned on if specified) but do have them in
176 // OpenGL, so do put them into glattrs and also skip the
177 // copy of wx value after switch by using "continue"
178 // instead of "break"
06e6496e
VZ
179 case WX_GL_RGBA:
180 glattrs[p++] = GLX_RGBA;
181 glattrs[p++] = True;
182 continue;
183
498ace9e
VZ
184 case WX_GL_DOUBLEBUFFER:
185 glattrs[p++] = GLX_DOUBLEBUFFER;
a15107c0 186 glattrs[p++] = True;
498ace9e
VZ
187 continue;
188
189 case WX_GL_STEREO:
190 glattrs[p++] = GLX_STEREO;
85866f52
VZ
191 glattrs[p++] = True;
192 continue;
193
498ace9e
VZ
194
195 case WX_GL_AUX_BUFFERS:
196 glattrs[p++] = GLX_AUX_BUFFERS;
197 break;
198
199 case WX_GL_MIN_RED:
200 glattrs[p++] = GLX_RED_SIZE;
201 break;
202
203 case WX_GL_MIN_GREEN:
204 glattrs[p++] = GLX_GREEN_SIZE;
205 break;
206
207 case WX_GL_MIN_BLUE:
208 glattrs[p++] = GLX_BLUE_SIZE;
209 break;
210
211 case WX_GL_MIN_ALPHA:
212 glattrs[p++] = GLX_ALPHA_SIZE;
213 break;
214
215 case WX_GL_DEPTH_SIZE:
216 glattrs[p++] = GLX_DEPTH_SIZE;
217 break;
218
219 case WX_GL_STENCIL_SIZE:
220 glattrs[p++] = GLX_STENCIL_SIZE;
221 break;
222
223 case WX_GL_MIN_ACCUM_RED:
224 glattrs[p++] = GLX_ACCUM_RED_SIZE;
225 break;
226
227 case WX_GL_MIN_ACCUM_GREEN:
228 glattrs[p++] = GLX_ACCUM_GREEN_SIZE;
229 break;
230
231 case WX_GL_MIN_ACCUM_BLUE:
232 glattrs[p++] = GLX_ACCUM_BLUE_SIZE;
233 break;
234
235 case WX_GL_MIN_ACCUM_ALPHA:
236 glattrs[p++] = GLX_ACCUM_ALPHA_SIZE;
237 break;
238
239 default:
240 wxLogDebug(_T("Unsupported OpenGL attribute %d"),
241 wxattrs[arg - 1]);
242 continue;
243 }
244
245 // copy attribute value as is
246 glattrs[p++] = wxattrs[arg++];
247 }
248
249 glattrs[p] = None;
250 }
251
252 return true;
253}
254
255/* static */
256bool
257wxGLCanvasX11::InitXVisualInfo(const int *attribList,
258 GLXFBConfig **pFBC,
259 XVisualInfo **pXVisual)
260{
261 int data[512];
262 if ( !ConvertWXAttrsToGL(attribList, data, WXSIZEOF(data)) )
263 return false;
264
265 Display * const dpy = wxGetX11Display();
266
267 if ( GetGLXVersion() >= 13 )
268 {
269 int returned;
270 *pFBC = glXChooseFBConfig(dpy, DefaultScreen(dpy), data, &returned);
271
272 if ( *pFBC )
273 {
274 *pXVisual = glXGetVisualFromFBConfig(wxGetX11Display(), **pFBC);
275 if ( !*pXVisual )
276 {
277 XFree(*pFBC);
278 *pFBC = NULL;
279 }
280 }
281 }
282 else // GLX <= 1.2
283 {
284 *pFBC = NULL;
285 *pXVisual = glXChooseVisual(dpy, DefaultScreen(dpy), data);
286 }
287
288 return *pXVisual != NULL;
289}
290
3f20f7d8
VZ
291/* static */
292bool
293wxGLCanvasBase::IsDisplaySupported(const int *attribList)
294{
295 GLXFBConfig *fbc = NULL;
296 XVisualInfo *vi = NULL;
297
298 const bool
299 isSupported = wxGLCanvasX11::InitXVisualInfo(attribList, &fbc, &vi);
300
301 if ( fbc )
302 XFree(fbc);
303 if ( vi )
304 XFree(vi);
305
306 return isSupported;
307}
308
498ace9e
VZ
309// ----------------------------------------------------------------------------
310// default visual management
311// ----------------------------------------------------------------------------
312
313XVisualInfo *wxGLCanvasX11::ms_glVisualInfo = NULL;
314GLXFBConfig *wxGLCanvasX11::ms_glFBCInfo = NULL;
315
316/* static */
317bool wxGLCanvasX11::InitDefaultVisualInfo(const int *attribList)
318{
319 FreeDefaultVisualInfo();
320
321 return InitXVisualInfo(attribList, &ms_glFBCInfo, &ms_glVisualInfo);
322}
323
324/* static */
325void wxGLCanvasX11::FreeDefaultVisualInfo()
326{
327 if ( ms_glFBCInfo )
328 {
329 XFree(ms_glFBCInfo);
330 ms_glFBCInfo = NULL;
331 }
332
333 if ( ms_glVisualInfo )
334 {
335 XFree(ms_glVisualInfo);
336 ms_glVisualInfo = NULL;
337 }
338}
339
340// ----------------------------------------------------------------------------
341// other GL methods
342// ----------------------------------------------------------------------------
343
344/* static */
345int wxGLCanvasX11::GetGLXVersion()
346{
347 static int s_glxVersion = 0;
348 if ( s_glxVersion == 0 )
349 {
350 // check the GLX version
351 int glxMajorVer, glxMinorVer;
352 bool ok = glXQueryVersion(wxGetX11Display(), &glxMajorVer, &glxMinorVer);
353 wxASSERT_MSG( ok, _T("GLX version not found") );
354 if (!ok)
355 s_glxVersion = 10; // 1.0 by default
356 else
357 s_glxVersion = glxMajorVer*10 + glxMinorVer;
358 }
359
360 return s_glxVersion;
361}
362
5ec69e96 363bool wxGLCanvasX11::SwapBuffers()
498ace9e
VZ
364{
365 const Window xid = GetXWindow();
5ec69e96 366 wxCHECK2_MSG( xid, return false, _T("window must be shown") );
498ace9e
VZ
367
368 glXSwapBuffers(wxGetX11Display(), xid);
5ec69e96 369 return true;
498ace9e
VZ
370}
371
372bool wxGLCanvasX11::IsShownOnScreen() const
373{
374 return GetXWindow() && wxGLCanvasBase::IsShownOnScreen();
375}
376
377#endif // wxUSE_GLCANVAS
378