]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk1/glcanvas.cpp
Add wxEvtHandler::CallAfter() for asynchronous method calls.
[wxWidgets.git] / src / gtk1 / glcanvas.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/gtk1/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
26extern "C"
27{
28#include "gtk/gtk.h"
29#include "gdk/gdk.h"
30#include "gdk/gdkx.h"
31}
32
33#include "wx/gtk1/win_gtk.h"
34#include "wx/gtk1/private.h"
35
36//-----------------------------------------------------------------------------
37// idle system
38//-----------------------------------------------------------------------------
39
40extern void wxapp_install_idle_handler();
41extern bool g_isIdle;
42
43#if WXWIN_COMPATIBILITY_2_8
44
45//-----------------------------------------------------------------------------
46// "realize" from m_wxwindow: used to create m_glContext implicitly
47//-----------------------------------------------------------------------------
48
49extern "C" {
50static gint
51gtk_glwindow_realized_callback( GtkWidget *WXUNUSED(widget), wxGLCanvas *win )
52{
53 win->GTKInitImplicitContext();
54
55 return FALSE;
56}
57}
58
59#endif // WXWIN_COMPATIBILITY_2_8
60
61//-----------------------------------------------------------------------------
62// "map" from m_wxwindow
63//-----------------------------------------------------------------------------
64
65extern "C" {
66static gint
67gtk_glwindow_map_callback( GtkWidget * WXUNUSED(widget), wxGLCanvas *win )
68{
69 wxPaintEvent event( win->GetId() );
70 event.SetEventObject( win );
71 win->HandleWindowEvent( event );
72
73 win->GetUpdateRegion().Clear();
74
75 return FALSE;
76}
77}
78
79//-----------------------------------------------------------------------------
80// "expose_event" of m_wxwindow
81//-----------------------------------------------------------------------------
82
83extern "C" {
84static void
85gtk_glwindow_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxGLCanvas *win )
86{
87 if (g_isIdle)
88 wxapp_install_idle_handler();
89
90 win->GetUpdateRegion().Union( gdk_event->area.x,
91 gdk_event->area.y,
92 gdk_event->area.width,
93 gdk_event->area.height );
94}
95}
96
97//-----------------------------------------------------------------------------
98// "draw" of m_wxwindow
99//-----------------------------------------------------------------------------
100
101extern "C" {
102static void
103gtk_glwindow_draw_callback( GtkWidget *WXUNUSED(widget), GdkRectangle *rect, wxGLCanvas *win )
104{
105 if (g_isIdle)
106 wxapp_install_idle_handler();
107
108 win->GetUpdateRegion().Union( rect->x, rect->y,
109 rect->width, rect->height );
110}
111}
112
113//-----------------------------------------------------------------------------
114// "size_allocate" of m_wxwindow
115//-----------------------------------------------------------------------------
116
117extern "C" {
118static void
119gtk_glcanvas_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxGLCanvas *win )
120{
121 if (g_isIdle)
122 wxapp_install_idle_handler();
123
124 if (!win->m_hasVMT)
125 return;
126
127 wxSizeEvent event( wxSize(win->m_width,win->m_height), win->GetId() );
128 event.SetEventObject( win );
129 win->HandleWindowEvent( event );
130}
131}
132
133//---------------------------------------------------------------------------
134// wxGlCanvas
135//---------------------------------------------------------------------------
136
137IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
138
139wxGLCanvas::wxGLCanvas(wxWindow *parent,
140 wxWindowID id,
141 const int *attribList,
142 const wxPoint& pos,
143 const wxSize& size,
144 long style,
145 const wxString& name,
146 const wxPalette& palette)
147#if WXWIN_COMPATIBILITY_2_8
148 : m_createImplicitContext(false)
149#endif
150{
151 Create(parent, id, pos, size, style, name, attribList, palette);
152}
153
154#if WXWIN_COMPATIBILITY_2_8
155
156wxGLCanvas::wxGLCanvas(wxWindow *parent,
157 wxWindowID id,
158 const wxPoint& pos,
159 const wxSize& size,
160 long style,
161 const wxString& name,
162 const int *attribList,
163 const wxPalette& palette)
164 : m_createImplicitContext(true)
165{
166 Create(parent, id, pos, size, style, name, attribList, palette);
167}
168
169wxGLCanvas::wxGLCanvas(wxWindow *parent,
170 const wxGLContext *shared,
171 wxWindowID id,
172 const wxPoint& pos,
173 const wxSize& size,
174 long style,
175 const wxString& name,
176 const int *attribList,
177 const wxPalette& palette)
178 : m_createImplicitContext(true)
179{
180 m_sharedContext = const_cast<wxGLContext *>(shared);
181
182 Create(parent, id, pos, size, style, name, attribList, palette);
183}
184
185wxGLCanvas::wxGLCanvas(wxWindow *parent,
186 const wxGLCanvas *shared,
187 wxWindowID id,
188 const wxPoint& pos, const wxSize& size,
189 long style, const wxString& name,
190 const int *attribList,
191 const wxPalette& palette )
192 : m_createImplicitContext(true)
193{
194 m_sharedContextOf = const_cast<wxGLCanvas *>(shared);
195
196 Create(parent, id, pos, size, style, name, attribList, palette);
197}
198
199#endif // WXWIN_COMPATIBILITY_2_8
200
201bool wxGLCanvas::Create(wxWindow *parent,
202 wxWindowID id,
203 const wxPoint& pos,
204 const wxSize& size,
205 long style,
206 const wxString& name,
207 const int *attribList,
208 const wxPalette& palette)
209{
210 m_noExpose = true;
211 m_nativeSizeEvent = true;
212
213 if ( !InitVisual(attribList) )
214 return false;
215
216 GdkVisual *visual = gdkx_visual_get( GetXVisualInfo()->visualid );
217 GdkColormap *colormap = gdk_colormap_new( visual, TRUE );
218
219 gtk_widget_push_colormap( colormap );
220 gtk_widget_push_visual( visual );
221
222 wxWindow::Create( parent, id, pos, size, style, name );
223 m_glWidget = m_wxwindow;
224
225 gtk_pizza_set_clear( GTK_PIZZA(m_wxwindow), FALSE );
226
227#if WXWIN_COMPATIBILITY_2_8
228 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "realize",
229 GTK_SIGNAL_FUNC(gtk_glwindow_realized_callback), (gpointer) this);
230#endif // WXWIN_COMPATIBILITY_2_8
231
232 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "map",
233 GTK_SIGNAL_FUNC(gtk_glwindow_map_callback), (gpointer) this);
234
235 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event",
236 GTK_SIGNAL_FUNC(gtk_glwindow_expose_callback), (gpointer) this);
237
238 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw",
239 GTK_SIGNAL_FUNC(gtk_glwindow_draw_callback), (gpointer) this);
240
241 gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
242 GTK_SIGNAL_FUNC(gtk_glcanvas_size_callback), (gpointer) this);
243
244 gtk_widget_pop_visual();
245
246 gtk_widget_pop_colormap();
247
248#if WXWIN_COMPATIBILITY_2_8
249 // if our parent window is already visible, we had been realized before we
250 // connected to the "realize" signal and hence our m_glContext hasn't been
251 // initialized yet and we have to do it now
252 if (GTK_WIDGET_REALIZED(m_wxwindow))
253 gtk_glwindow_realized_callback( m_wxwindow, this );
254#endif // WXWIN_COMPATIBILITY_2_8
255
256 if (GTK_WIDGET_MAPPED(m_wxwindow))
257 gtk_glwindow_map_callback( m_wxwindow, this );
258
259 return true;
260}
261
262Window wxGLCanvas::GetXWindow() const
263{
264 GdkWindow *window = GTK_PIZZA(m_wxwindow)->bin_window;
265 return window ? GDK_WINDOW_XWINDOW(window) : 0;
266}
267
268void wxGLCanvas::OnInternalIdle()
269{
270 if (!m_updateRegion.IsEmpty())
271 {
272 wxPaintEvent event( GetId() );
273 event.SetEventObject( this );
274 HandleWindowEvent( event );
275
276 GetUpdateRegion().Clear();
277 }
278
279 wxWindow::OnInternalIdle();
280}
281
282#if WXWIN_COMPATIBILITY_2_8
283
284void wxGLCanvas::GTKInitImplicitContext()
285{
286 if ( !m_glContext && m_createImplicitContext )
287 {
288 wxGLContext *share = m_sharedContext;
289 if ( !share && m_sharedContextOf )
290 share = m_sharedContextOf->m_glContext;
291
292 m_glContext = new wxGLContext(this, share);
293 }
294}
295
296#endif // WXWIN_COMPATIBILITY_2_8
297
298#endif // wxUSE_GLCANVAS