Use accessor functions instead of deprecated GTK+ macros.
[wxWidgets.git] / src / gtk / glcanvas.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/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 // RCS-ID: $Id$
8 // Copyright: (c) Robert Roebling
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #if wxUSE_GLCANVAS
16
17 #include "wx/glcanvas.h"
18
19 #include <gtk/gtk.h>
20 #include <gdk/gdkx.h>
21
22 #if WXWIN_COMPATIBILITY_2_8
23
24 //-----------------------------------------------------------------------------
25 // "realize" from m_wxwindow: used to create m_glContext implicitly
26 //-----------------------------------------------------------------------------
27
28 extern "C" {
29 static void
30 gtk_glwindow_realized_callback( GtkWidget *WXUNUSED(widget), wxGLCanvas *win )
31 {
32 win->GTKInitImplicitContext();
33 }
34 }
35
36 #endif // WXWIN_COMPATIBILITY_2_8
37
38 //-----------------------------------------------------------------------------
39 // "map" from m_wxwindow
40 //-----------------------------------------------------------------------------
41
42 extern "C" {
43 static void
44 gtk_glwindow_map_callback( GtkWidget * WXUNUSED(widget), wxGLCanvas *win )
45 {
46 wxPaintEvent event( win->GetId() );
47 event.SetEventObject( win );
48 win->HandleWindowEvent( event );
49
50 win->m_exposed = false;
51 win->GetUpdateRegion().Clear();
52 }
53 }
54
55 //-----------------------------------------------------------------------------
56 // "expose_event" of m_wxwindow
57 //-----------------------------------------------------------------------------
58
59 extern "C" {
60 static gboolean
61 gtk_glwindow_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxGLCanvas *win )
62 {
63 win->m_exposed = true;
64
65 win->GetUpdateRegion().Union( gdk_event->area.x,
66 gdk_event->area.y,
67 gdk_event->area.width,
68 gdk_event->area.height );
69 return false;
70 }
71 }
72
73 //-----------------------------------------------------------------------------
74 // "size_allocate" of m_wxwindow
75 //-----------------------------------------------------------------------------
76
77 extern "C" {
78 static void
79 gtk_glcanvas_size_callback(GtkWidget *WXUNUSED(widget),
80 GtkAllocation * WXUNUSED(alloc),
81 wxGLCanvas *win)
82 {
83 if (!win->m_hasVMT)
84 return;
85
86 wxSizeEvent event( wxSize(win->m_width,win->m_height), win->GetId() );
87 event.SetEventObject( win );
88 win->HandleWindowEvent( event );
89 }
90 }
91
92 //-----------------------------------------------------------------------------
93 // emission hook for "parent-set"
94 //-----------------------------------------------------------------------------
95
96 extern "C" {
97 static gboolean
98 parent_set_hook(GSignalInvocationHint*, guint, const GValue* param_values, void* data)
99 {
100 wxGLCanvas* win = (wxGLCanvas*)data;
101 if (g_value_peek_pointer(&param_values[0]) == win->m_wxwindow)
102 {
103 const XVisualInfo* xvi = win->GetXVisualInfo();
104 GdkVisual* visual = gtk_widget_get_visual(win->m_wxwindow);
105 if (GDK_VISUAL_XVISUAL(visual)->visualid != xvi->visualid)
106 {
107 GdkScreen* screen = gtk_widget_get_screen(win->m_wxwindow);
108 visual = gdk_x11_screen_lookup_visual(screen, xvi->visualid);
109 GdkColormap* colormap = gdk_colormap_new(visual, false);
110 gtk_widget_set_colormap(win->m_wxwindow, colormap);
111 g_object_unref(colormap);
112 }
113 // remove hook
114 return false;
115 }
116 return true;
117 }
118 }
119
120 //---------------------------------------------------------------------------
121 // wxGlCanvas
122 //---------------------------------------------------------------------------
123
124 IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
125
126 wxGLCanvas::wxGLCanvas(wxWindow *parent,
127 wxWindowID id,
128 const int *attribList,
129 const wxPoint& pos,
130 const wxSize& size,
131 long style,
132 const wxString& name,
133 const wxPalette& palette)
134 #if WXWIN_COMPATIBILITY_2_8
135 : m_createImplicitContext(false)
136 #endif
137 {
138 Create(parent, id, pos, size, style, name, attribList, palette);
139 }
140
141 #if WXWIN_COMPATIBILITY_2_8
142
143 wxGLCanvas::wxGLCanvas(wxWindow *parent,
144 wxWindowID id,
145 const wxPoint& pos,
146 const wxSize& size,
147 long style,
148 const wxString& name,
149 const int *attribList,
150 const wxPalette& palette)
151 : m_createImplicitContext(true)
152 {
153 m_sharedContext = NULL;
154 m_sharedContextOf = NULL;
155
156 Create(parent, id, pos, size, style, name, attribList, palette);
157 }
158
159 wxGLCanvas::wxGLCanvas(wxWindow *parent,
160 const wxGLContext *shared,
161 wxWindowID id,
162 const wxPoint& pos,
163 const wxSize& size,
164 long style,
165 const wxString& name,
166 const int *attribList,
167 const wxPalette& palette)
168 : m_createImplicitContext(true)
169 {
170 m_sharedContext = const_cast<wxGLContext *>(shared);
171
172 Create(parent, id, pos, size, style, name, attribList, palette);
173 }
174
175 wxGLCanvas::wxGLCanvas(wxWindow *parent,
176 const wxGLCanvas *shared,
177 wxWindowID id,
178 const wxPoint& pos, const wxSize& size,
179 long style, const wxString& name,
180 const int *attribList,
181 const wxPalette& palette )
182 : m_createImplicitContext(true)
183 {
184 m_sharedContext = NULL;
185 m_sharedContextOf = const_cast<wxGLCanvas *>(shared);
186
187 Create(parent, id, pos, size, style, name, attribList, palette);
188 }
189
190 #endif // WXWIN_COMPATIBILITY_2_8
191
192 bool wxGLCanvas::Create(wxWindow *parent,
193 wxWindowID id,
194 const wxPoint& pos,
195 const wxSize& size,
196 long style,
197 const wxString& name,
198 const int *attribList,
199 const wxPalette& palette)
200 {
201 #if wxUSE_PALETTE
202 wxASSERT_MSG( !palette.IsOk(), wxT("palettes not supported") );
203 #endif // wxUSE_PALETTE
204 wxUnusedVar(palette); // Unused when wxDEBUG_LEVEL==0
205
206 m_exposed = false;
207 m_noExpose = true;
208 m_nativeSizeEvent = true;
209
210 if ( !InitVisual(attribList) )
211 return false;
212
213 // watch for the "parent-set" signal on m_wxwindow so we can set colormap
214 // before m_wxwindow is realized (which will occur before
215 // wxWindow::Create() returns if parent is already visible)
216 unsigned sig_id = g_signal_lookup("parent-set", GTK_TYPE_WIDGET);
217 g_signal_add_emission_hook(sig_id, 0, parent_set_hook, this, NULL);
218
219 wxWindow::Create( parent, id, pos, size, style, name );
220
221 gtk_widget_set_double_buffered(m_wxwindow, false);
222
223 #if WXWIN_COMPATIBILITY_2_8
224 g_signal_connect(m_wxwindow, "realize", G_CALLBACK(gtk_glwindow_realized_callback), this);
225 #endif // WXWIN_COMPATIBILITY_2_8
226 g_signal_connect(m_wxwindow, "map", G_CALLBACK(gtk_glwindow_map_callback), this);
227 g_signal_connect(m_wxwindow, "expose_event", G_CALLBACK(gtk_glwindow_expose_callback), this);
228 g_signal_connect(m_widget, "size_allocate", G_CALLBACK(gtk_glcanvas_size_callback), this);
229
230 #if WXWIN_COMPATIBILITY_2_8
231 // if our parent window is already visible, we had been realized before we
232 // connected to the "realize" signal and hence our m_glContext hasn't been
233 // initialized yet and we have to do it now
234 if (gtk_widget_get_realized(m_wxwindow))
235 gtk_glwindow_realized_callback( m_wxwindow, this );
236 #endif // WXWIN_COMPATIBILITY_2_8
237
238 if (gtk_widget_get_mapped(m_wxwindow))
239 gtk_glwindow_map_callback( m_wxwindow, this );
240
241 return true;
242 }
243
244 Window wxGLCanvas::GetXWindow() const
245 {
246 GdkWindow* window = GTKGetDrawingWindow();
247 return window ? GDK_WINDOW_XWINDOW(window) : 0;
248 }
249
250 void wxGLCanvas::OnInternalIdle()
251 {
252 if (m_exposed)
253 {
254 wxPaintEvent event( GetId() );
255 event.SetEventObject( this );
256 HandleWindowEvent( event );
257
258 m_exposed = false;
259 GetUpdateRegion().Clear();
260 }
261
262 wxWindow::OnInternalIdle();
263 }
264
265 #if WXWIN_COMPATIBILITY_2_8
266
267 void wxGLCanvas::GTKInitImplicitContext()
268 {
269 if ( !m_glContext && m_createImplicitContext )
270 {
271 wxGLContext *share = m_sharedContext;
272 if ( !share && m_sharedContextOf )
273 share = m_sharedContextOf->m_glContext;
274
275 m_glContext = new wxGLContext(this, share);
276 }
277 }
278
279 #endif // WXWIN_COMPATIBILITY_2_8
280
281 #endif // wxUSE_GLCANVAS