1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk1/glcanvas.cpp
3 // Purpose: wxGLCanvas, for using OpenGL/Mesa with wxWidgets and GTK
4 // Author: Robert Roebling
7 // Copyright: (c) Robert Roebling
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
16 #include "wx/glcanvas.h"
21 #include "wx/colour.h"
22 #include "wx/module.h"
32 #include "wx/gtk1/win_gtk.h"
33 #include "wx/gtk1/private.h"
35 //-----------------------------------------------------------------------------
37 //-----------------------------------------------------------------------------
39 extern void wxapp_install_idle_handler();
42 #if WXWIN_COMPATIBILITY_2_8
44 //-----------------------------------------------------------------------------
45 // "realize" from m_wxwindow: used to create m_glContext implicitly
46 //-----------------------------------------------------------------------------
50 gtk_glwindow_realized_callback( GtkWidget
*WXUNUSED(widget
), wxGLCanvas
*win
)
52 win
->GTKInitImplicitContext();
58 #endif // WXWIN_COMPATIBILITY_2_8
60 //-----------------------------------------------------------------------------
61 // "map" from m_wxwindow
62 //-----------------------------------------------------------------------------
66 gtk_glwindow_map_callback( GtkWidget
* WXUNUSED(widget
), wxGLCanvas
*win
)
68 wxPaintEvent
event( win
->GetId() );
69 event
.SetEventObject( win
);
70 win
->HandleWindowEvent( event
);
72 win
->GetUpdateRegion().Clear();
78 //-----------------------------------------------------------------------------
79 // "expose_event" of m_wxwindow
80 //-----------------------------------------------------------------------------
84 gtk_glwindow_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxGLCanvas
*win
)
87 wxapp_install_idle_handler();
89 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
91 gdk_event
->area
.width
,
92 gdk_event
->area
.height
);
96 //-----------------------------------------------------------------------------
97 // "draw" of m_wxwindow
98 //-----------------------------------------------------------------------------
102 gtk_glwindow_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxGLCanvas
*win
)
105 wxapp_install_idle_handler();
107 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
108 rect
->width
, rect
->height
);
112 //-----------------------------------------------------------------------------
113 // "size_allocate" of m_wxwindow
114 //-----------------------------------------------------------------------------
118 gtk_glcanvas_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxGLCanvas
*win
)
121 wxapp_install_idle_handler();
126 wxSizeEvent
event( wxSize(win
->m_width
,win
->m_height
), win
->GetId() );
127 event
.SetEventObject( win
);
128 win
->HandleWindowEvent( event
);
132 //---------------------------------------------------------------------------
134 //---------------------------------------------------------------------------
136 IMPLEMENT_CLASS(wxGLCanvas
, wxWindow
)
138 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
140 const int *attribList
,
144 const wxString
& name
,
145 const wxPalette
& palette
)
146 #if WXWIN_COMPATIBILITY_2_8
147 : m_createImplicitContext(false)
150 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
153 #if WXWIN_COMPATIBILITY_2_8
155 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
160 const wxString
& name
,
161 const int *attribList
,
162 const wxPalette
& palette
)
163 : m_createImplicitContext(true)
165 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
168 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
169 const wxGLContext
*shared
,
174 const wxString
& name
,
175 const int *attribList
,
176 const wxPalette
& palette
)
177 : m_createImplicitContext(true)
179 m_sharedContext
= const_cast<wxGLContext
*>(shared
);
181 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
184 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
185 const wxGLCanvas
*shared
,
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)
193 m_sharedContextOf
= const_cast<wxGLCanvas
*>(shared
);
195 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
198 #endif // WXWIN_COMPATIBILITY_2_8
200 bool wxGLCanvas::Create(wxWindow
*parent
,
205 const wxString
& name
,
206 const int *attribList
,
207 const wxPalette
& palette
)
210 m_nativeSizeEvent
= true;
212 if ( !InitVisual(attribList
) )
215 GdkVisual
*visual
= gdkx_visual_get( GetXVisualInfo()->visualid
);
216 GdkColormap
*colormap
= gdk_colormap_new( visual
, TRUE
);
218 gtk_widget_push_colormap( colormap
);
219 gtk_widget_push_visual( visual
);
221 wxWindow::Create( parent
, id
, pos
, size
, style
, name
);
222 m_glWidget
= m_wxwindow
;
224 gtk_pizza_set_clear( GTK_PIZZA(m_wxwindow
), FALSE
);
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
231 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "map",
232 GTK_SIGNAL_FUNC(gtk_glwindow_map_callback
), (gpointer
) this);
234 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
235 GTK_SIGNAL_FUNC(gtk_glwindow_expose_callback
), (gpointer
) this);
237 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
238 GTK_SIGNAL_FUNC(gtk_glwindow_draw_callback
), (gpointer
) this);
240 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
241 GTK_SIGNAL_FUNC(gtk_glcanvas_size_callback
), (gpointer
) this);
243 gtk_widget_pop_visual();
245 gtk_widget_pop_colormap();
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
255 if (GTK_WIDGET_MAPPED(m_wxwindow
))
256 gtk_glwindow_map_callback( m_wxwindow
, this );
261 Window
wxGLCanvas::GetXWindow() const
263 GdkWindow
*window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
264 return window
? GDK_WINDOW_XWINDOW(window
) : 0;
267 void wxGLCanvas::OnInternalIdle()
269 if (!m_updateRegion
.IsEmpty())
271 wxPaintEvent
event( GetId() );
272 event
.SetEventObject( this );
273 HandleWindowEvent( event
);
275 GetUpdateRegion().Clear();
278 wxWindow::OnInternalIdle();
281 #if WXWIN_COMPATIBILITY_2_8
283 void wxGLCanvas::GTKInitImplicitContext()
285 if ( !m_glContext
&& m_createImplicitContext
)
287 wxGLContext
*share
= m_sharedContext
;
288 if ( !share
&& m_sharedContextOf
)
289 share
= m_sharedContextOf
->m_glContext
;
291 m_glContext
= new wxGLContext(this, share
);
295 #endif // WXWIN_COMPATIBILITY_2_8
297 #endif // wxUSE_GLCANVAS