1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/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"
29 #include "wx/gtk/win_gtk.h"
31 #if WXWIN_COMPATIBILITY_2_8
33 //-----------------------------------------------------------------------------
34 // "realize" from m_wxwindow: used to create m_glContext implicitly
35 //-----------------------------------------------------------------------------
39 gtk_glwindow_realized_callback( GtkWidget
*WXUNUSED(widget
), wxGLCanvas
*win
)
41 win
->GTKInitImplicitContext();
47 #endif // WXWIN_COMPATIBILITY_2_8
49 //-----------------------------------------------------------------------------
50 // "map" from m_wxwindow
51 //-----------------------------------------------------------------------------
55 gtk_glwindow_map_callback( GtkWidget
* WXUNUSED(widget
), wxGLCanvas
*win
)
57 wxPaintEvent
event( win
->GetId() );
58 event
.SetEventObject( win
);
59 win
->GetEventHandler()->ProcessEvent( event
);
61 win
->m_exposed
= false;
62 win
->GetUpdateRegion().Clear();
68 //-----------------------------------------------------------------------------
69 // "expose_event" of m_wxwindow
70 //-----------------------------------------------------------------------------
74 gtk_glwindow_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxGLCanvas
*win
)
76 win
->m_exposed
= true;
78 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
80 gdk_event
->area
.width
,
81 gdk_event
->area
.height
);
86 //-----------------------------------------------------------------------------
87 // "size_allocate" of m_wxwindow
88 //-----------------------------------------------------------------------------
92 gtk_glcanvas_size_callback(GtkWidget
*WXUNUSED(widget
),
93 GtkAllocation
* WXUNUSED(alloc
),
99 wxSizeEvent
event( wxSize(win
->m_width
,win
->m_height
), win
->GetId() );
100 event
.SetEventObject( win
);
101 win
->GetEventHandler()->ProcessEvent( event
);
105 //---------------------------------------------------------------------------
107 //---------------------------------------------------------------------------
109 IMPLEMENT_CLASS(wxGLCanvas
, wxWindow
)
111 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
113 const int *attribList
,
117 const wxString
& name
,
118 const wxPalette
& palette
)
119 #if WXWIN_COMPATIBILITY_2_8
120 : m_createImplicitContext(false)
123 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
126 #if WXWIN_COMPATIBILITY_2_8
128 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
133 const wxString
& name
,
134 const int *attribList
,
135 const wxPalette
& palette
)
136 : m_createImplicitContext(true)
138 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
141 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
142 const wxGLContext
*shared
,
147 const wxString
& name
,
148 const int *attribList
,
149 const wxPalette
& palette
)
150 : m_createImplicitContext(true)
152 m_sharedContext
= wx_const_cast(wxGLContext
*, shared
);
154 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
157 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
158 const wxGLCanvas
*shared
,
160 const wxPoint
& pos
, const wxSize
& size
,
161 long style
, const wxString
& name
,
162 const int *attribList
,
163 const wxPalette
& palette
)
164 : m_createImplicitContext(true)
166 m_sharedContextOf
= wx_const_cast(wxGLCanvas
*, shared
);
168 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
171 #endif // WXWIN_COMPATIBILITY_2_8
173 bool wxGLCanvas::Create(wxWindow
*parent
,
178 const wxString
& name
,
179 const int *attribList
,
180 const wxPalette
& WXUNUSED_UNLESS_DEBUG(palette
))
182 wxASSERT_MSG( !palette
.IsOk(), _T("palettes not supported") );
186 m_nativeSizeEvent
= true;
188 if ( !InitVisual(attribList
) )
191 XVisualInfo
* const xvi
= GetXVisualInfo();
194 GdkColormap
*colormap
;
196 // MR: This needs a fix for lower gtk+ versions too. Might need to rethink logic (FIXME)
197 #if defined(__WXGTK20__) && GTK_CHECK_VERSION(2,2,0)
198 if (!gtk_check_version(2,2,0))
200 wxWindow::Create( parent
, id
, pos
, size
, style
, name
);
202 m_glWidget
= m_wxwindow
;
204 GdkScreen
*screen
= gtk_widget_get_screen( m_glWidget
);
205 colormap
= gdk_screen_get_default_colormap(screen
);
206 visual
= gdk_colormap_get_visual(colormap
);
208 if (GDK_VISUAL_XVISUAL(visual
)->visualid
!= xvi
->visualid
)
210 visual
= gdk_x11_screen_lookup_visual( screen
, xvi
->visualid
);
211 colormap
= gdk_colormap_new(visual
, FALSE
);
214 gtk_widget_set_colormap( m_glWidget
, colormap
);
217 #endif // GTK+ >= 2.2
219 visual
= gdkx_visual_get( xvi
->visualid
);
220 colormap
= gdk_colormap_new( visual
, TRUE
);
222 gtk_widget_push_colormap( colormap
);
224 wxWindow::Create( parent
, id
, pos
, size
, style
, name
);
225 m_glWidget
= m_wxwindow
;
228 gtk_widget_set_double_buffered( m_glWidget
, FALSE
);
230 #if WXWIN_COMPATIBILITY_2_8
231 g_signal_connect(m_wxwindow
, "realize", G_CALLBACK(gtk_glwindow_realized_callback
), this);
232 #endif // WXWIN_COMPATIBILITY_2_8
233 g_signal_connect(m_wxwindow
, "map", G_CALLBACK(gtk_glwindow_map_callback
), this);
234 g_signal_connect(m_wxwindow
, "expose_event", G_CALLBACK(gtk_glwindow_expose_callback
), this);
235 g_signal_connect(m_widget
, "size_allocate", G_CALLBACK(gtk_glcanvas_size_callback
), this);
237 if (gtk_check_version(2,2,0) != NULL
)
239 gtk_widget_pop_colormap();
242 #if WXWIN_COMPATIBILITY_2_8
243 // if our parent window is already visible, we had been realized before we
244 // connected to the "realize" signal and hence our m_glContext hasn't been
245 // initialized yet and we have to do it now
246 if (GTK_WIDGET_REALIZED(m_wxwindow
))
247 gtk_glwindow_realized_callback( m_wxwindow
, this );
248 #endif // WXWIN_COMPATIBILITY_2_8
250 if (GTK_WIDGET_MAPPED(m_wxwindow
))
251 gtk_glwindow_map_callback( m_wxwindow
, this );
256 Window
wxGLCanvas::GetXWindow() const
258 GdkWindow
*window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
259 return window
? GDK_WINDOW_XWINDOW(window
) : 0;
262 void wxGLCanvas::OnInternalIdle()
266 wxPaintEvent
event( GetId() );
267 event
.SetEventObject( this );
268 GetEventHandler()->ProcessEvent( event
);
271 GetUpdateRegion().Clear();
274 wxWindow::OnInternalIdle();
277 #if WXWIN_COMPATIBILITY_2_8
279 void wxGLCanvas::GTKInitImplicitContext()
281 if ( !m_glContext
&& m_createImplicitContext
)
283 wxGLContext
*share
= m_sharedContext
;
284 if ( !share
&& m_sharedContextOf
)
285 share
= m_sharedContextOf
->m_glContext
;
287 m_glContext
= new wxGLContext(this, share
);
291 #endif // WXWIN_COMPATIBILITY_2_8
293 #endif // wxUSE_GLCANVAS