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