1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk1/glcanvas.cpp
3 // Purpose: wxGLCanvas, for using OpenGL/Mesa with wxWidgets and GTK
4 // Author: Robert Roebling
8 // Copyright: (c) Robert Roebling
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
17 #include "wx/glcanvas.h"
22 #include "wx/colour.h"
23 #include "wx/module.h"
33 #include "wx/gtk1/win_gtk.h"
34 #include "wx/gtk1/private.h"
36 //-----------------------------------------------------------------------------
38 //-----------------------------------------------------------------------------
40 extern void wxapp_install_idle_handler();
43 #if WXWIN_COMPATIBILITY_2_8
45 //-----------------------------------------------------------------------------
46 // "realize" from m_wxwindow: used to create m_glContext implicitly
47 //-----------------------------------------------------------------------------
51 gtk_glwindow_realized_callback( GtkWidget
*WXUNUSED(widget
), wxGLCanvas
*win
)
53 win
->GTKInitImplicitContext();
59 #endif // WXWIN_COMPATIBILITY_2_8
61 //-----------------------------------------------------------------------------
62 // "map" from m_wxwindow
63 //-----------------------------------------------------------------------------
67 gtk_glwindow_map_callback( GtkWidget
* WXUNUSED(widget
), wxGLCanvas
*win
)
69 wxPaintEvent
event( win
->GetId() );
70 event
.SetEventObject( win
);
71 win
->GetEventHandler()->ProcessEvent( event
);
73 win
->GetUpdateRegion().Clear();
79 //-----------------------------------------------------------------------------
80 // "expose_event" of m_wxwindow
81 //-----------------------------------------------------------------------------
85 gtk_glwindow_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxGLCanvas
*win
)
88 wxapp_install_idle_handler();
90 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
92 gdk_event
->area
.width
,
93 gdk_event
->area
.height
);
97 //-----------------------------------------------------------------------------
98 // "draw" of m_wxwindow
99 //-----------------------------------------------------------------------------
103 gtk_glwindow_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxGLCanvas
*win
)
106 wxapp_install_idle_handler();
108 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
109 rect
->width
, rect
->height
);
113 //-----------------------------------------------------------------------------
114 // "size_allocate" of m_wxwindow
115 //-----------------------------------------------------------------------------
119 gtk_glcanvas_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxGLCanvas
*win
)
122 wxapp_install_idle_handler();
127 wxSizeEvent
event( wxSize(win
->m_width
,win
->m_height
), win
->GetId() );
128 event
.SetEventObject( win
);
129 win
->GetEventHandler()->ProcessEvent( event
);
133 //---------------------------------------------------------------------------
135 //---------------------------------------------------------------------------
137 IMPLEMENT_CLASS(wxGLCanvas
, wxWindow
)
139 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
141 const int *attribList
,
145 const wxString
& name
,
146 const wxPalette
& palette
)
147 #if WXWIN_COMPATIBILITY_2_8
148 : m_createImplicitContext(false)
151 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
154 #if WXWIN_COMPATIBILITY_2_8
156 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
161 const wxString
& name
,
162 const int *attribList
,
163 const wxPalette
& palette
)
164 : m_createImplicitContext(true)
166 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
169 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
170 const wxGLContext
*shared
,
175 const wxString
& name
,
176 const int *attribList
,
177 const wxPalette
& palette
)
178 : m_createImplicitContext(true)
180 m_sharedContext
= wx_const_cast(wxGLContext
*, shared
);
182 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
185 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
186 const wxGLCanvas
*shared
,
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)
194 m_sharedContextOf
= wx_const_cast(wxGLCanvas
*, shared
);
196 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
199 #endif // WXWIN_COMPATIBILITY_2_8
201 bool wxGLCanvas::Create(wxWindow
*parent
,
206 const wxString
& name
,
207 const int *attribList
,
208 const wxPalette
& palette
)
211 m_nativeSizeEvent
= true;
213 if ( !InitVisual(attribList
) )
216 GdkVisual
*visual
= gdkx_visual_get( GetXVisualInfo()->visualid
);
217 GdkColormap
*colormap
= gdk_colormap_new( visual
, TRUE
);
219 gtk_widget_push_colormap( colormap
);
220 gtk_widget_push_visual( visual
);
222 wxWindow::Create( parent
, id
, pos
, size
, style
, name
);
223 m_glWidget
= m_wxwindow
;
225 gtk_pizza_set_clear( GTK_PIZZA(m_wxwindow
), FALSE
);
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
232 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "map",
233 GTK_SIGNAL_FUNC(gtk_glwindow_map_callback
), (gpointer
) this);
235 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
236 GTK_SIGNAL_FUNC(gtk_glwindow_expose_callback
), (gpointer
) this);
238 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
239 GTK_SIGNAL_FUNC(gtk_glwindow_draw_callback
), (gpointer
) this);
241 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
242 GTK_SIGNAL_FUNC(gtk_glcanvas_size_callback
), (gpointer
) this);
244 gtk_widget_pop_visual();
246 gtk_widget_pop_colormap();
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
256 if (GTK_WIDGET_MAPPED(m_wxwindow
))
257 gtk_glwindow_map_callback( m_wxwindow
, this );
262 Window
wxGLCanvas::GetXWindow() const
264 GdkWindow
*window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
265 return window
? GDK_WINDOW_XWINDOW(window
) : 0;
268 void wxGLCanvas::OnInternalIdle()
270 if (!m_updateRegion
.IsEmpty())
272 wxPaintEvent
event( GetId() );
273 event
.SetEventObject( this );
274 GetEventHandler()->ProcessEvent( event
);
276 GetUpdateRegion().Clear();
279 wxWindow::OnInternalIdle();
282 #if WXWIN_COMPATIBILITY_2_8
284 void wxGLCanvas::GTKInitImplicitContext()
286 if ( !m_glContext
&& m_createImplicitContext
)
288 wxGLContext
*share
= m_sharedContext
;
289 if ( !share
&& m_sharedContextOf
)
290 share
= m_sharedContextOf
->m_glContext
;
292 m_glContext
= new wxGLContext(this, share
);
296 #endif // WXWIN_COMPATIBILITY_2_8
298 #endif // wxUSE_GLCANVAS