]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/glcanvas.cpp
corrected off by 1 error in cMB2WC() call (thanks valgrind)
[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), GtkAllocation* alloc, wxGLCanvas *win )
93{
94 if (!win->m_hasVMT)
95 return;
96
97 wxSizeEvent event( wxSize(win->m_width,win->m_height), win->GetId() );
98 event.SetEventObject( win );
99 win->GetEventHandler()->ProcessEvent( event );
100}
101}
102
103//---------------------------------------------------------------------------
104// wxGlCanvas
105//---------------------------------------------------------------------------
106
107IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
108
109wxGLCanvas::wxGLCanvas(wxWindow *parent,
110 wxWindowID id,
111 const int *attribList,
112 const wxPoint& pos,
113 const wxSize& size,
114 long style,
115 const wxString& name,
116 const wxPalette& palette)
117#if WXWIN_COMPATIBILITY_2_8
118 : m_createImplicitContext(false)
119#endif
120{
121 Create(parent, id, pos, size, style, name, attribList, palette);
122}
123
124#if WXWIN_COMPATIBILITY_2_8
125
126wxGLCanvas::wxGLCanvas(wxWindow *parent,
127 wxWindowID id,
128 const wxPoint& pos,
129 const wxSize& size,
130 long style,
131 const wxString& name,
132 const int *attribList,
133 const wxPalette& palette)
134 : m_createImplicitContext(true)
135{
136 Create(parent, id, pos, size, style, name, attribList, palette);
137}
138
139wxGLCanvas::wxGLCanvas(wxWindow *parent,
140 const wxGLContext *shared,
141 wxWindowID id,
142 const wxPoint& pos,
143 const wxSize& size,
144 long style,
145 const wxString& name,
146 const int *attribList,
147 const wxPalette& palette)
148 : m_createImplicitContext(true)
149{
150 m_sharedContext = wx_const_cast(wxGLContext *, shared);
151
152 Create(parent, id, pos, size, style, name, attribList, palette);
153}
154
155wxGLCanvas::wxGLCanvas(wxWindow *parent,
156 const wxGLCanvas *shared,
157 wxWindowID id,
158 const wxPoint& pos, const wxSize& size,
159 long style, const wxString& name,
160 const int *attribList,
161 const wxPalette& palette )
162 : m_createImplicitContext(true)
163{
164 m_sharedContextOf = wx_const_cast(wxGLCanvas *, shared);
165
166 Create(parent, id, pos, size, style, name, attribList, palette);
167}
168
169#endif // WXWIN_COMPATIBILITY_2_8
170
171bool wxGLCanvas::Create(wxWindow *parent,
172 wxWindowID id,
173 const wxPoint& pos,
174 const wxSize& size,
175 long style,
176 const wxString& name,
177 const int *attribList,
178 const wxPalette& palette)
179{
180 m_exposed = false;
181 m_noExpose = true;
182 m_nativeSizeEvent = true;
183
184 if ( !InitVisual(attribList) )
185 return false;
186
187 XVisualInfo * const xvi = GetXVisualInfo();
188
189 GdkVisual *visual;
190 GdkColormap *colormap;
191
192 // MR: This needs a fix for lower gtk+ versions too. Might need to rethink logic (FIXME)
193#if defined(__WXGTK20__) && GTK_CHECK_VERSION(2,2,0)
194 if (!gtk_check_version(2,2,0))
195 {
196 wxWindow::Create( parent, id, pos, size, style, name );
197
198 m_glWidget = m_wxwindow;
199
200 GdkScreen *screen = gtk_widget_get_screen( m_glWidget );
201 colormap = gdk_screen_get_default_colormap(screen);
202 visual = gdk_colormap_get_visual(colormap);
203
204 if (GDK_VISUAL_XVISUAL(visual)->visualid != xvi->visualid)
205 {
206 visual = gdk_x11_screen_lookup_visual( screen, xvi->visualid );
207 colormap = gdk_colormap_new(visual, FALSE);
208 }
209
210 gtk_widget_set_colormap( m_glWidget, colormap );
211 }
212 else
213#endif // GTK+ >= 2.2
214 {
215 visual = gdkx_visual_get( xvi->visualid );
216 colormap = gdk_colormap_new( visual, TRUE );
217
218 gtk_widget_push_colormap( colormap );
219
220 wxWindow::Create( parent, id, pos, size, style, name );
221 m_glWidget = m_wxwindow;
222 }
223
224 gtk_widget_set_double_buffered( m_glWidget, FALSE );
225
226#if WXWIN_COMPATIBILITY_2_8
227 g_signal_connect(m_wxwindow, "realize", G_CALLBACK(gtk_glwindow_realized_callback), this);
228#endif // WXWIN_COMPATIBILITY_2_8
229 g_signal_connect(m_wxwindow, "map", G_CALLBACK(gtk_glwindow_map_callback), this);
230 g_signal_connect(m_wxwindow, "expose_event", G_CALLBACK(gtk_glwindow_expose_callback), this);
231 g_signal_connect(m_widget, "size_allocate", G_CALLBACK(gtk_glcanvas_size_callback), this);
232
233 if (gtk_check_version(2,2,0) != NULL)
234 {
235 gtk_widget_pop_colormap();
236 }
237
238#if WXWIN_COMPATIBILITY_2_8
239 // if our parent window is already visible, we had been realized before we
240 // connected to the "realize" signal and hence our m_glContext hasn't been
241 // initialized yet and we have to do it now
242 if (GTK_WIDGET_REALIZED(m_wxwindow))
243 gtk_glwindow_realized_callback( m_wxwindow, this );
244#endif // WXWIN_COMPATIBILITY_2_8
245
246 if (GTK_WIDGET_MAPPED(m_wxwindow))
247 gtk_glwindow_map_callback( m_wxwindow, this );
248
249 return true;
250}
251
252Window wxGLCanvas::GetXWindow() const
253{
254 GdkWindow *window = GTK_PIZZA(m_wxwindow)->bin_window;
255 return window ? GDK_WINDOW_XWINDOW(window) : 0;
256}
257
258void wxGLCanvas::OnInternalIdle()
259{
260 if (m_exposed)
261 {
262 wxPaintEvent event( GetId() );
263 event.SetEventObject( this );
264 GetEventHandler()->ProcessEvent( event );
265
266 m_exposed = false;
267 GetUpdateRegion().Clear();
268 }
269
270 wxWindow::OnInternalIdle();
271}
272
273#if WXWIN_COMPATIBILITY_2_8
274
275void wxGLCanvas::GTKInitImplicitContext()
276{
277 if ( !m_glContext && m_createImplicitContext )
278 {
279 wxGLContext *share = m_sharedContext;
280 if ( !share && m_sharedContextOf )
281 share = m_sharedContextOf->m_glContext;
282
283 m_glContext = new wxGLContext(this, share);
284 }
285}
286
287#endif // WXWIN_COMPATIBILITY_2_8
288
289#endif // wxUSE_GLCANVAS