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 #if WXWIN_COMPATIBILITY_2_8
31 //-----------------------------------------------------------------------------
32 // "realize" from m_wxwindow: used to create m_glContext implicitly
33 //-----------------------------------------------------------------------------
37 gtk_glwindow_realized_callback( GtkWidget
*WXUNUSED(widget
), wxGLCanvas
*win
)
39 win
->GTKInitImplicitContext();
45 #endif // WXWIN_COMPATIBILITY_2_8
47 //-----------------------------------------------------------------------------
48 // "map" from m_wxwindow
49 //-----------------------------------------------------------------------------
53 gtk_glwindow_map_callback( GtkWidget
* WXUNUSED(widget
), wxGLCanvas
*win
)
55 wxPaintEvent
event( win
->GetId() );
56 event
.SetEventObject( win
);
57 win
->GetEventHandler()->ProcessEvent( event
);
59 win
->m_exposed
= false;
60 win
->GetUpdateRegion().Clear();
66 //-----------------------------------------------------------------------------
67 // "expose_event" of m_wxwindow
68 //-----------------------------------------------------------------------------
72 gtk_glwindow_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxGLCanvas
*win
)
74 win
->m_exposed
= true;
76 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
78 gdk_event
->area
.width
,
79 gdk_event
->area
.height
);
84 //-----------------------------------------------------------------------------
85 // "size_allocate" of m_wxwindow
86 //-----------------------------------------------------------------------------
90 gtk_glcanvas_size_callback(GtkWidget
*WXUNUSED(widget
),
91 GtkAllocation
* WXUNUSED(alloc
),
97 wxSizeEvent
event( wxSize(win
->m_width
,win
->m_height
), win
->GetId() );
98 event
.SetEventObject( win
);
99 win
->GetEventHandler()->ProcessEvent( event
);
103 //---------------------------------------------------------------------------
105 //---------------------------------------------------------------------------
107 IMPLEMENT_CLASS(wxGLCanvas
, wxWindow
)
109 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
111 const int *attribList
,
115 const wxString
& name
,
116 const wxPalette
& palette
)
117 #if WXWIN_COMPATIBILITY_2_8
118 : m_createImplicitContext(false)
121 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
124 #if WXWIN_COMPATIBILITY_2_8
126 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
131 const wxString
& name
,
132 const int *attribList
,
133 const wxPalette
& palette
)
134 : m_createImplicitContext(true)
136 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
139 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
140 const wxGLContext
*shared
,
145 const wxString
& name
,
146 const int *attribList
,
147 const wxPalette
& palette
)
148 : m_createImplicitContext(true)
150 m_sharedContext
= wx_const_cast(wxGLContext
*, shared
);
152 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
155 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
156 const wxGLCanvas
*shared
,
158 const wxPoint
& pos
, const wxSize
& size
,
159 long style
, const wxString
& name
,
160 const int *attribList
,
161 const wxPalette
& palette
)
162 : m_createImplicitContext(true)
164 m_sharedContextOf
= wx_const_cast(wxGLCanvas
*, shared
);
166 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
169 #endif // WXWIN_COMPATIBILITY_2_8
171 bool wxGLCanvas::Create(wxWindow
*parent
,
176 const wxString
& name
,
177 const int *attribList
,
178 const wxPalette
& WXUNUSED_UNLESS_DEBUG(palette
))
180 wxASSERT_MSG( !palette
.IsOk(), _T("palettes not supported") );
184 m_nativeSizeEvent
= true;
186 if ( !InitVisual(attribList
) )
189 XVisualInfo
* const xvi
= GetXVisualInfo();
192 GdkColormap
*colormap
;
194 wxWindow::Create( parent
, id
, pos
, size
, style
, name
);
196 m_glWidget
= m_wxwindow
;
198 GdkScreen
*screen
= gtk_widget_get_screen( m_glWidget
);
199 colormap
= gdk_screen_get_default_colormap(screen
);
200 visual
= gdk_colormap_get_visual(colormap
);
202 if (GDK_VISUAL_XVISUAL(visual
)->visualid
!= xvi
->visualid
)
204 visual
= gdk_x11_screen_lookup_visual( screen
, xvi
->visualid
);
205 colormap
= gdk_colormap_new(visual
, FALSE
);
208 gtk_widget_set_colormap( m_glWidget
, colormap
);
210 gtk_widget_set_double_buffered( m_glWidget
, FALSE
);
212 #if WXWIN_COMPATIBILITY_2_8
213 g_signal_connect(m_wxwindow
, "realize", G_CALLBACK(gtk_glwindow_realized_callback
), this);
214 #endif // WXWIN_COMPATIBILITY_2_8
215 g_signal_connect(m_wxwindow
, "map", G_CALLBACK(gtk_glwindow_map_callback
), this);
216 g_signal_connect(m_wxwindow
, "expose_event", G_CALLBACK(gtk_glwindow_expose_callback
), this);
217 g_signal_connect(m_widget
, "size_allocate", G_CALLBACK(gtk_glcanvas_size_callback
), this);
219 #if WXWIN_COMPATIBILITY_2_8
220 // if our parent window is already visible, we had been realized before we
221 // connected to the "realize" signal and hence our m_glContext hasn't been
222 // initialized yet and we have to do it now
223 if (GTK_WIDGET_REALIZED(m_wxwindow
))
224 gtk_glwindow_realized_callback( m_wxwindow
, this );
225 #endif // WXWIN_COMPATIBILITY_2_8
227 if (GTK_WIDGET_MAPPED(m_wxwindow
))
228 gtk_glwindow_map_callback( m_wxwindow
, this );
233 Window
wxGLCanvas::GetXWindow() const
235 GdkWindow
*window
= m_wxwindow
->window
;
236 return window
? GDK_WINDOW_XWINDOW(window
) : 0;
239 void wxGLCanvas::OnInternalIdle()
243 wxPaintEvent
event( GetId() );
244 event
.SetEventObject( this );
245 GetEventHandler()->ProcessEvent( event
);
248 GetUpdateRegion().Clear();
251 wxWindow::OnInternalIdle();
254 #if WXWIN_COMPATIBILITY_2_8
256 void wxGLCanvas::GTKInitImplicitContext()
258 if ( !m_glContext
&& m_createImplicitContext
)
260 wxGLContext
*share
= m_sharedContext
;
261 if ( !share
&& m_sharedContextOf
)
262 share
= m_sharedContextOf
->m_glContext
;
264 m_glContext
= new wxGLContext(this, share
);
268 #endif // WXWIN_COMPATIBILITY_2_8
270 #endif // wxUSE_GLCANVAS