]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/glcanvas.cpp
Minimum is now GTK+ 2.4
[wxWidgets.git] / src / gtk / glcanvas.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/gtk/glcanvas.cpp
3// Purpose: wxGLCanvas, for using OpenGL/Mesa with wxWidgets and GTK
4// Author: Robert Roebling
5// Modified by:
6// Created: 17/08/98
7// RCS-ID: $Id$
8// Copyright: (c) Robert Roebling
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#if wxUSE_GLCANVAS
16
17#include "wx/glcanvas.h"
18
19#ifndef WX_PRECOMP
20 #include "wx/app.h"
21 #include "wx/frame.h"
22 #include "wx/colour.h"
23 #include "wx/module.h"
24#endif // WX_PRECOMP
25
26#include <gtk/gtk.h>
27#include <gdk/gdkx.h>
28
29#include "wx/gtk/win_gtk.h"
30
31#if WXWIN_COMPATIBILITY_2_8
32
33//-----------------------------------------------------------------------------
34// "realize" from m_wxwindow: used to create m_glContext implicitly
35//-----------------------------------------------------------------------------
36
37extern "C" {
38static gint
39gtk_glwindow_realized_callback( GtkWidget *WXUNUSED(widget), wxGLCanvas *win )
40{
41 win->GTKInitImplicitContext();
42
43 return FALSE;
44}
45}
46
47#endif // WXWIN_COMPATIBILITY_2_8
48
49//-----------------------------------------------------------------------------
50// "map" from m_wxwindow
51//-----------------------------------------------------------------------------
52
53extern "C" {
54static gint
55gtk_glwindow_map_callback( GtkWidget * WXUNUSED(widget), wxGLCanvas *win )
56{
57 wxPaintEvent event( win->GetId() );
58 event.SetEventObject( win );
59 win->GetEventHandler()->ProcessEvent( event );
60
61 win->m_exposed = false;
62 win->GetUpdateRegion().Clear();
63
64 return FALSE;
65}
66}
67
68//-----------------------------------------------------------------------------
69// "expose_event" of m_wxwindow
70//-----------------------------------------------------------------------------
71
72extern "C" {
73static gboolean
74gtk_glwindow_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxGLCanvas *win )
75{
76 win->m_exposed = true;
77
78 win->GetUpdateRegion().Union( gdk_event->area.x,
79 gdk_event->area.y,
80 gdk_event->area.width,
81 gdk_event->area.height );
82 return false;
83}
84}
85
86//-----------------------------------------------------------------------------
87// "size_allocate" of m_wxwindow
88//-----------------------------------------------------------------------------
89
90extern "C" {
91static void
92gtk_glcanvas_size_callback(GtkWidget *WXUNUSED(widget),
93 GtkAllocation * WXUNUSED(alloc),
94 wxGLCanvas *win)
95{
96 if (!win->m_hasVMT)
97 return;
98
99 wxSizeEvent event( wxSize(win->m_width,win->m_height), win->GetId() );
100 event.SetEventObject( win );
101 win->GetEventHandler()->ProcessEvent( event );
102}
103}
104
105//---------------------------------------------------------------------------
106// wxGlCanvas
107//---------------------------------------------------------------------------
108
109IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
110
111wxGLCanvas::wxGLCanvas(wxWindow *parent,
112 wxWindowID id,
113 const int *attribList,
114 const wxPoint& pos,
115 const wxSize& size,
116 long style,
117 const wxString& name,
118 const wxPalette& palette)
119#if WXWIN_COMPATIBILITY_2_8
120 : m_createImplicitContext(false)
121#endif
122{
123 Create(parent, id, pos, size, style, name, attribList, palette);
124}
125
126#if WXWIN_COMPATIBILITY_2_8
127
128wxGLCanvas::wxGLCanvas(wxWindow *parent,
129 wxWindowID id,
130 const wxPoint& pos,
131 const wxSize& size,
132 long style,
133 const wxString& name,
134 const int *attribList,
135 const wxPalette& palette)
136 : m_createImplicitContext(true)
137{
138 Create(parent, id, pos, size, style, name, attribList, palette);
139}
140
141wxGLCanvas::wxGLCanvas(wxWindow *parent,
142 const wxGLContext *shared,
143 wxWindowID id,
144 const wxPoint& pos,
145 const wxSize& size,
146 long style,
147 const wxString& name,
148 const int *attribList,
149 const wxPalette& palette)
150 : m_createImplicitContext(true)
151{
152 m_sharedContext = wx_const_cast(wxGLContext *, shared);
153
154 Create(parent, id, pos, size, style, name, attribList, palette);
155}
156
157wxGLCanvas::wxGLCanvas(wxWindow *parent,
158 const wxGLCanvas *shared,
159 wxWindowID id,
160 const wxPoint& pos, const wxSize& size,
161 long style, const wxString& name,
162 const int *attribList,
163 const wxPalette& palette )
164 : m_createImplicitContext(true)
165{
166 m_sharedContextOf = wx_const_cast(wxGLCanvas *, shared);
167
168 Create(parent, id, pos, size, style, name, attribList, palette);
169}
170
171#endif // WXWIN_COMPATIBILITY_2_8
172
173bool wxGLCanvas::Create(wxWindow *parent,
174 wxWindowID id,
175 const wxPoint& pos,
176 const wxSize& size,
177 long style,
178 const wxString& name,
179 const int *attribList,
180 const wxPalette& WXUNUSED_UNLESS_DEBUG(palette))
181{
182 wxASSERT_MSG( !palette.IsOk(), _T("palettes not supported") );
183
184 m_exposed = false;
185 m_noExpose = true;
186 m_nativeSizeEvent = true;
187
188 if ( !InitVisual(attribList) )
189 return false;
190
191 XVisualInfo * const xvi = GetXVisualInfo();
192
193 GdkVisual *visual;
194 GdkColormap *colormap;
195
196 // MR: This needs a fix for lower gtk+ versions too. Might need to rethink logic (FIXME)
197#if defined(__WXGTK20__) && GTK_CHECK_VERSION(2,2,0)
198 if (!gtk_check_version(2,2,0))
199 {
200 wxWindow::Create( parent, id, pos, size, style, name );
201
202 m_glWidget = m_wxwindow;
203
204 GdkScreen *screen = gtk_widget_get_screen( m_glWidget );
205 colormap = gdk_screen_get_default_colormap(screen);
206 visual = gdk_colormap_get_visual(colormap);
207
208 if (GDK_VISUAL_XVISUAL(visual)->visualid != xvi->visualid)
209 {
210 visual = gdk_x11_screen_lookup_visual( screen, xvi->visualid );
211 colormap = gdk_colormap_new(visual, FALSE);
212 }
213
214 gtk_widget_set_colormap( m_glWidget, colormap );
215 }
216 else
217#endif // GTK+ >= 2.2
218 {
219 visual = gdkx_visual_get( xvi->visualid );
220 colormap = gdk_colormap_new( visual, TRUE );
221
222 gtk_widget_push_colormap( colormap );
223
224 wxWindow::Create( parent, id, pos, size, style, name );
225 m_glWidget = m_wxwindow;
226 }
227
228 gtk_widget_set_double_buffered( m_glWidget, FALSE );
229
230#if WXWIN_COMPATIBILITY_2_8
231 g_signal_connect(m_wxwindow, "realize", G_CALLBACK(gtk_glwindow_realized_callback), this);
232#endif // WXWIN_COMPATIBILITY_2_8
233 g_signal_connect(m_wxwindow, "map", G_CALLBACK(gtk_glwindow_map_callback), this);
234 g_signal_connect(m_wxwindow, "expose_event", G_CALLBACK(gtk_glwindow_expose_callback), this);
235 g_signal_connect(m_widget, "size_allocate", G_CALLBACK(gtk_glcanvas_size_callback), this);
236
237 if (gtk_check_version(2,2,0) != NULL)
238 {
239 gtk_widget_pop_colormap();
240 }
241
242#if WXWIN_COMPATIBILITY_2_8
243 // if our parent window is already visible, we had been realized before we
244 // connected to the "realize" signal and hence our m_glContext hasn't been
245 // initialized yet and we have to do it now
246 if (GTK_WIDGET_REALIZED(m_wxwindow))
247 gtk_glwindow_realized_callback( m_wxwindow, this );
248#endif // WXWIN_COMPATIBILITY_2_8
249
250 if (GTK_WIDGET_MAPPED(m_wxwindow))
251 gtk_glwindow_map_callback( m_wxwindow, this );
252
253 return true;
254}
255
256Window wxGLCanvas::GetXWindow() const
257{
258 GdkWindow *window = GTK_PIZZA(m_wxwindow)->bin_window;
259 return window ? GDK_WINDOW_XWINDOW(window) : 0;
260}
261
262void wxGLCanvas::OnInternalIdle()
263{
264 if (m_exposed)
265 {
266 wxPaintEvent event( GetId() );
267 event.SetEventObject( this );
268 GetEventHandler()->ProcessEvent( event );
269
270 m_exposed = false;
271 GetUpdateRegion().Clear();
272 }
273
274 wxWindow::OnInternalIdle();
275}
276
277#if WXWIN_COMPATIBILITY_2_8
278
279void wxGLCanvas::GTKInitImplicitContext()
280{
281 if ( !m_glContext && m_createImplicitContext )
282 {
283 wxGLContext *share = m_sharedContext;
284 if ( !share && m_sharedContextOf )
285 share = m_sharedContextOf->m_glContext;
286
287 m_glContext = new wxGLContext(this, share);
288 }
289}
290
291#endif // WXWIN_COMPATIBILITY_2_8
292
293#endif // wxUSE_GLCANVAS