]> git.saurik.com Git - wxWidgets.git/blame - src/x11/glcanvas.cpp
send selection events when Ctrl-clicking an item repeeatedly in a multiselection...
[wxWidgets.git] / src / x11 / glcanvas.cpp
CommitLineData
dc3065a5 1///////////////////////////////////////////////////////////////////////////////
521bf4ff 2// Name: src/x11/glcanvas.cpp
77ffb593 3// Purpose: wxGLCanvas, for using OpenGL with wxWidgets
83df96d6
JS
4// Uses the GLX extension.
5// Author: Julian Smart and Wolfram Gloger
dc3065a5 6// Modified by: Vadim Zeitlin to update to new API
83df96d6
JS
7// Created: 1995, 1999
8// RCS-ID: $Id$
9// Copyright: (c) Julian Smart, Wolfram Gloger
521bf4ff 10// Licence: wxWindows licence
dc3065a5
VZ
11///////////////////////////////////////////////////////////////////////////////
12
13// TODO: merge this with wxGTK version in some src/unix/glcanvasx11.cpp
14
15// ============================================================================
16// declarations
17// ============================================================================
18
19// ----------------------------------------------------------------------------
20// headers
21// ----------------------------------------------------------------------------
83df96d6 22
521bf4ff
WS
23// for compilers that support precompilation, includes "wx.h".
24#include "wx/wxprec.h"
25
26#if defined(__BORLANDC__)
670f9935 27 #pragma hdrstop
521bf4ff 28#endif
83df96d6
JS
29
30#if wxUSE_GLCANVAS
31
32#include "wx/glcanvas.h"
e4db172a
WS
33
34#ifndef WX_PRECOMP
35 #include "wx/log.h"
670f9935 36 #include "wx/app.h"
de6185e2 37 #include "wx/utils.h"
e4db172a
WS
38#endif
39
83df96d6
JS
40#ifdef __VMS
41# pragma message disable nosimpint
42#endif
1807c27d 43#include <X11/Xlib.h>
83df96d6
JS
44#ifdef __VMS
45# pragma message enable nosimpint
46#endif
1807c27d
MB
47#include "wx/x11/private.h"
48
dc3065a5
VZ
49// ----------------------------------------------------------------------------
50// local functions
51// ----------------------------------------------------------------------------
34fdf762 52
dc3065a5 53static inline Window wxGetClientAreaWindow(const wxWindow* win)
1807c27d 54{
dc3065a5 55 return (Window)win->
1807c27d 56#ifdef __WXMOTIF__
dc3065a5 57 GetClientXWindow();
1807c27d 58#else
dc3065a5 59 GetClientAreaWindow();
1807c27d
MB
60#endif
61}
83df96d6 62
dc3065a5
VZ
63// ============================================================================
64// implementation
65// ============================================================================
83df96d6 66
dc3065a5
VZ
67// ----------------------------------------------------------------------------
68// wxGLContext
69// ----------------------------------------------------------------------------
521bf4ff 70
dc3065a5 71IMPLEMENT_CLASS(wxGLContext, wxObject)
83df96d6 72
dc3065a5 73wxGLContext::wxGLContext(wxGLCanvas *win, const wxGLContext *other)
83df96d6 74{
dc3065a5
VZ
75 XVisualInfo *vi = (XVisualInfo *) win->m_vi;
76 wxASSERT_MSG( vi, wxT("invalid visual in wxGLCanvas") );
83df96d6 77
dc3065a5
VZ
78 m_glContext = glXCreateContext( (Display *)wxGetDisplay(),
79 vi,
80 other ? other->m_glContext : None,
81 GL_TRUE);
521bf4ff 82
dc3065a5 83 wxASSERT_MSG( m_glContext, wxT("Couldn't create OpenGL context") );
83df96d6
JS
84}
85
86wxGLContext::~wxGLContext()
87{
dc3065a5
VZ
88 if (!m_glContext)
89 return;
521bf4ff 90
83df96d6
JS
91 if (m_glContext == glXGetCurrentContext())
92 {
33980f0d 93 glXMakeCurrent( (Display*) wxGetDisplay(), None, NULL);
83df96d6 94 }
521bf4ff 95
33980f0d 96 glXDestroyContext( (Display*) wxGetDisplay(), m_glContext );
83df96d6
JS
97}
98
dc3065a5 99void wxGLContext::SetCurrent(const wxGLCanvas& win) const
83df96d6
JS
100{
101 if (m_glContext)
102 {
33980f0d 103 Display* display = (Display*) wxGetDisplay();
dc3065a5 104 glXMakeCurrent(display, wxGetClientAreaWindow(&win), m_glContext);
83df96d6
JS
105 }
106}
107
dc3065a5
VZ
108// ----------------------------------------------------------------------------
109// wxGLCanvas
110// ----------------------------------------------------------------------------
83df96d6 111
dc3065a5 112IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
83df96d6 113
dc3065a5
VZ
114wxGLCanvas::wxGLCanvas(wxWindow *parent,
115 wxWindowID id,
116 const int *attribList,
117 const wxPoint& pos,
118 const wxSize& size,
119 long style,
120 const wxString& name,
121 const wxPalette& palette)
83df96d6 122{
dc3065a5 123 Create(parent, id, pos, size, style, name, attribList, palette);
83df96d6
JS
124}
125
dc3065a5 126bool wxGLCanvas::Create(wxWindow *parent,
83df96d6 127 wxWindowID id,
dc3065a5
VZ
128 const wxPoint& pos,
129 const wxSize& size,
130 long style,
131 const wxString& name,
132 const int *attribList,
133 const wxPalette& palette)
521bf4ff 134{
dc3065a5 135 m_vi = NULL;
83df96d6 136
dc3065a5
VZ
137 if ( !wxWindow::Create(parent, id, pos, size, style, name) )
138 return false;
83df96d6 139
83df96d6
JS
140 XVisualInfo *vi, vi_templ;
141 XWindowAttributes xwa;
142 int val, n;
143
33980f0d 144 Display* display = (Display*) wxGetDisplay();
83df96d6
JS
145
146 // Check for the presence of the GLX extension
521bf4ff
WS
147 if(!glXQueryExtension(display, NULL, NULL))
148 {
dc3065a5 149 wxLogDebug(wxT("wxGLCanvas: GLX extension is missing"));
521bf4ff 150 return false;
83df96d6
JS
151 }
152
153 if(attribList) {
154 int data[512], arg=0, p=0;
521bf4ff 155
83df96d6
JS
156 while( (attribList[arg]!=0) && (p<512) )
157 {
158 switch( attribList[arg++] )
159 {
160 case WX_GL_RGBA: data[p++] = GLX_RGBA; break;
161 case WX_GL_BUFFER_SIZE:
162 data[p++]=GLX_BUFFER_SIZE; data[p++]=attribList[arg++]; break;
163 case WX_GL_LEVEL:
164 data[p++]=GLX_LEVEL; data[p++]=attribList[arg++]; break;
165 case WX_GL_DOUBLEBUFFER: data[p++] = GLX_DOUBLEBUFFER; break;
166 case WX_GL_STEREO: data[p++] = GLX_STEREO; break;
167 case WX_GL_AUX_BUFFERS:
168 data[p++]=GLX_AUX_BUFFERS; data[p++]=attribList[arg++]; break;
169 case WX_GL_MIN_RED:
170 data[p++]=GLX_RED_SIZE; data[p++]=attribList[arg++]; break;
171 case WX_GL_MIN_GREEN:
172 data[p++]=GLX_GREEN_SIZE; data[p++]=attribList[arg++]; break;
173 case WX_GL_MIN_BLUE:
174 data[p++]=GLX_BLUE_SIZE; data[p++]=attribList[arg++]; break;
175 case WX_GL_MIN_ALPHA:
176 data[p++]=GLX_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
521bf4ff 177 case WX_GL_DEPTH_SIZE:
83df96d6 178 data[p++]=GLX_DEPTH_SIZE; data[p++]=attribList[arg++]; break;
521bf4ff 179 case WX_GL_STENCIL_SIZE:
83df96d6
JS
180 data[p++]=GLX_STENCIL_SIZE; data[p++]=attribList[arg++]; break;
181 case WX_GL_MIN_ACCUM_RED:
182 data[p++]=GLX_ACCUM_RED_SIZE; data[p++]=attribList[arg++]; break;
183 case WX_GL_MIN_ACCUM_GREEN:
184 data[p++]=GLX_ACCUM_GREEN_SIZE; data[p++]=attribList[arg++]; break;
185 case WX_GL_MIN_ACCUM_BLUE:
186 data[p++]=GLX_ACCUM_BLUE_SIZE; data[p++]=attribList[arg++]; break;
187 case WX_GL_MIN_ACCUM_ALPHA:
188 data[p++]=GLX_ACCUM_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
189 default:
190 break;
191 }
521bf4ff
WS
192 }
193 data[p] = 0;
83df96d6 194
83df96d6 195 // Get an appropriate visual
dc3065a5 196 vi = glXChooseVisual(display, DefaultScreen(display), data);
670f9935 197 if(!vi) return false;
521bf4ff 198
83df96d6
JS
199 // Here we should make sure that vi is the same visual as the
200 // one used by the xwindow drawable in wxCanvas. However,
201 // there is currently no mechanism for this in wx_canvs.cc.
dc3065a5
VZ
202 }
203 else // default attributes
204 {
521bf4ff 205 // By default, we use the visual of xwindow
dc3065a5 206 XGetWindowAttributes(display, wxGetClientAreaWindow(this), &xwa);
521bf4ff
WS
207 vi_templ.visualid = XVisualIDFromVisual(xwa.visual);
208 vi = XGetVisualInfo(display, VisualIDMask, &vi_templ, &n);
670f9935 209 if(!vi) return false;
521bf4ff 210 glXGetConfig(display, vi, GLX_USE_GL, &val);
670f9935 211 if(!val) return false;
83df96d6
JS
212 }
213
214 m_vi = vi; // safe for later use
521bf4ff 215
670f9935 216 wxCHECK_MSG( m_vi, false, wxT("required visual couldn't be found") );
83df96d6 217
521bf4ff 218 return true;
83df96d6
JS
219}
220
dc3065a5 221wxGLCanvas::~wxGLCanvas()
83df96d6
JS
222{
223 XVisualInfo *vi = (XVisualInfo *) m_vi;
521bf4ff 224
dc3065a5
VZ
225 if (vi)
226 XFree( vi );
83df96d6
JS
227}
228
229void wxGLCanvas::SwapBuffers()
230{
dc3065a5 231 glXSwapBuffers((Display *)wxGetDisplay(), wxGetClientAreaWindow(this));
83df96d6
JS
232}
233
dc3065a5 234int wxGLCanvas::GetColourIndex(const wxColour& col_)
83df96d6 235{
dc3065a5 236 wxColour& col = wx_const_cast(wxColour&, col_);
83df96d6 237
dc3065a5
VZ
238#ifdef __WXMOTIF__
239 col.AllocColour(GetXDisplay());
240#else
241 col.CalcPixel(wxTheApp->GetMainColormap(wxGetDisplay()));
242#endif
83df96d6 243
dc3065a5 244 return col.GetPixel();
83df96d6
JS
245}
246
dc3065a5 247#endif // wxUSE_GLCANVAS