]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/glcanvas.cpp
fixed compilation of STL non-UTF8 builds
[wxWidgets.git] / src / gtk / glcanvas.cpp
CommitLineData
8b089c5e 1/////////////////////////////////////////////////////////////////////////////
9b5f1895 2// Name: src/gtk/glcanvas.cpp
77ffb593 3// Purpose: wxGLCanvas, for using OpenGL/Mesa with wxWidgets and GTK
8b089c5e
JS
4// Author: Robert Roebling
5// Modified by:
6// Created: 17/08/98
7// RCS-ID: $Id$
8// Copyright: (c) Robert Roebling
65571936 9// Licence: wxWindows licence
8b089c5e
JS
10/////////////////////////////////////////////////////////////////////////////
11
14f355c2
VS
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
8b089c5e
JS
15#if wxUSE_GLCANVAS
16
17#include "wx/glcanvas.h"
18
670f9935
WS
19#ifndef WX_PRECOMP
20 #include "wx/app.h"
76b49cf4 21 #include "wx/frame.h"
7cf41a5d 22 #include "wx/colour.h"
02761f6c 23 #include "wx/module.h"
670f9935
WS
24#endif // WX_PRECOMP
25
2b5f62a0
VZ
26extern "C"
27{
8b089c5e
JS
28#include "gtk/gtk.h"
29#include "gdk/gdk.h"
30#include "gdk/gdkx.h"
31}
32
33#include "wx/gtk/win_gtk.h"
f938068e 34#include "wx/gtk/private.h"
8b089c5e 35
dc3065a5
VZ
36#if WXWIN_COMPATIBILITY_2_8
37
8b089c5e 38//-----------------------------------------------------------------------------
dc3065a5 39// "realize" from m_wxwindow: used to create m_glContext implicitly
8b089c5e
JS
40//-----------------------------------------------------------------------------
41
865bb325 42extern "C" {
8b089c5e 43static gint
34a34b02 44gtk_glwindow_realized_callback( GtkWidget *WXUNUSED(widget), wxGLCanvas *win )
8b089c5e 45{
dc3065a5 46 win->GTKInitImplicitContext();
8b089c5e
JS
47
48 return FALSE;
49}
865bb325 50}
8b089c5e 51
dc3065a5
VZ
52#endif // WXWIN_COMPATIBILITY_2_8
53
8b089c5e
JS
54//-----------------------------------------------------------------------------
55// "map" from m_wxwindow
56//-----------------------------------------------------------------------------
57
865bb325 58extern "C" {
8b089c5e
JS
59static gint
60gtk_glwindow_map_callback( GtkWidget * WXUNUSED(widget), wxGLCanvas *win )
61{
dc3065a5
VZ
62 wxPaintEvent event( win->GetId() );
63 event.SetEventObject( win );
64 win->GetEventHandler()->ProcessEvent( event );
8b089c5e 65
dc3065a5
VZ
66 win->m_exposed = false;
67 win->GetUpdateRegion().Clear();
8b089c5e
JS
68
69 return FALSE;
70}
865bb325 71}
8b089c5e
JS
72
73//-----------------------------------------------------------------------------
74// "expose_event" of m_wxwindow
75//-----------------------------------------------------------------------------
76
865bb325 77extern "C" {
6d727f6c 78static gboolean
8b089c5e
JS
79gtk_glwindow_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxGLCanvas *win )
80{
14819684 81 // don't need to install idle handler, its done from "event" signal
8b089c5e 82
670f9935 83 win->m_exposed = true;
8b089c5e
JS
84
85 win->GetUpdateRegion().Union( gdk_event->area.x,
86 gdk_event->area.y,
87 gdk_event->area.width,
88 gdk_event->area.height );
6d727f6c 89 return false;
8b089c5e 90}
865bb325 91}
8b089c5e 92
8b089c5e
JS
93//-----------------------------------------------------------------------------
94// "size_allocate" of m_wxwindow
95//-----------------------------------------------------------------------------
96
865bb325 97extern "C" {
2b5f62a0 98static void
8b089c5e
JS
99gtk_glcanvas_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxGLCanvas *win )
100{
101 if (g_isIdle)
102 wxapp_install_idle_handler();
103
104 if (!win->m_hasVMT)
105 return;
106
107 wxSizeEvent event( wxSize(win->m_width,win->m_height), win->GetId() );
108 event.SetEventObject( win );
109 win->GetEventHandler()->ProcessEvent( event );
110}
865bb325 111}
8b089c5e
JS
112
113//---------------------------------------------------------------------------
114// wxGlCanvas
115//---------------------------------------------------------------------------
116
4660d7e5 117IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
8b089c5e 118
dc3065a5
VZ
119wxGLCanvas::wxGLCanvas(wxWindow *parent,
120 wxWindowID id,
121 const int *attribList,
122 const wxPoint& pos,
123 const wxSize& size,
124 long style,
125 const wxString& name,
126 const wxPalette& palette)
127#if WXWIN_COMPATIBILITY_2_8
b7ea712c 128 : m_createImplicitContext(false)
dc3065a5 129#endif
b7ea712c 130{
dc3065a5 131 Create(parent, id, pos, size, style, name, attribList, palette);
b7ea712c
RR
132}
133
dc3065a5
VZ
134#if WXWIN_COMPATIBILITY_2_8
135
136wxGLCanvas::wxGLCanvas(wxWindow *parent,
137 wxWindowID id,
138 const wxPoint& pos,
139 const wxSize& size,
140 long style,
141 const wxString& name,
142 const int *attribList,
143 const wxPalette& palette)
b7ea712c 144 : m_createImplicitContext(true)
8b089c5e 145{
dc3065a5 146 Create(parent, id, pos, size, style, name, attribList, palette);
8b089c5e
JS
147}
148
dc3065a5
VZ
149wxGLCanvas::wxGLCanvas(wxWindow *parent,
150 const wxGLContext *shared,
151 wxWindowID id,
152 const wxPoint& pos,
153 const wxSize& size,
154 long style,
155 const wxString& name,
156 const int *attribList,
157 const wxPalette& palette)
b7ea712c 158 : m_createImplicitContext(true)
2b5f62a0 159{
dc3065a5
VZ
160 m_sharedContext = wx_const_cast(wxGLContext *, shared);
161
162 Create(parent, id, pos, size, style, name, attribList, palette);
8b089c5e
JS
163}
164
dc3065a5
VZ
165wxGLCanvas::wxGLCanvas(wxWindow *parent,
166 const wxGLCanvas *shared,
167 wxWindowID id,
168 const wxPoint& pos, const wxSize& size,
169 long style, const wxString& name,
170 const int *attribList,
171 const wxPalette& palette )
b7ea712c 172 : m_createImplicitContext(true)
2b5f62a0 173{
dc3065a5
VZ
174 m_sharedContextOf = wx_const_cast(wxGLCanvas *, shared);
175
176 Create(parent, id, pos, size, style, name, attribList, palette);
8b089c5e
JS
177}
178
dc3065a5 179#endif // WXWIN_COMPATIBILITY_2_8
2b5f62a0 180
dc3065a5
VZ
181bool wxGLCanvas::Create(wxWindow *parent,
182 wxWindowID id,
183 const wxPoint& pos,
184 const wxSize& size,
185 long style,
186 const wxString& name,
187 const int *attribList,
188 const wxPalette& palette)
189{
670f9935
WS
190 m_exposed = false;
191 m_noExpose = true;
192 m_nativeSizeEvent = true;
34a34b02 193
498ace9e
VZ
194 if ( !InitVisual(attribList) )
195 return false;
2b5f62a0 196
498ace9e 197 XVisualInfo * const xvi = GetXVisualInfo();
b4d06fb7 198
fee7a683
MR
199 GdkVisual *visual;
200 GdkColormap *colormap;
2b5f62a0 201
fee7a683 202 // MR: This needs a fix for lower gtk+ versions too. Might need to rethink logic (FIXME)
b3f4c570 203#if defined(__WXGTK20__) && GTK_CHECK_VERSION(2,2,0)
fee7a683
MR
204 if (!gtk_check_version(2,2,0))
205 {
206 wxWindow::Create( parent, id, pos, size, style, name );
207
208 m_glWidget = m_wxwindow;
209
210 GdkScreen *screen = gtk_widget_get_screen( m_glWidget );
211 colormap = gdk_screen_get_default_colormap(screen);
212 visual = gdk_colormap_get_visual(colormap);
213
498ace9e 214 if (GDK_VISUAL_XVISUAL(visual)->visualid != xvi->visualid)
fee7a683 215 {
498ace9e 216 visual = gdk_x11_screen_lookup_visual( screen, xvi->visualid );
fee7a683
MR
217 colormap = gdk_colormap_new(visual, FALSE);
218 }
219
220 gtk_widget_set_colormap( m_glWidget, colormap );
221 }
222 else
dc3065a5 223#endif // GTK+ >= 2.2
fee7a683 224 {
498ace9e 225 visual = gdkx_visual_get( xvi->visualid );
fee7a683 226 colormap = gdk_colormap_new( visual, TRUE );
a6f5aa49 227
fee7a683 228 gtk_widget_push_colormap( colormap );
a6f5aa49 229
fee7a683
MR
230 wxWindow::Create( parent, id, pos, size, style, name );
231 m_glWidget = m_wxwindow;
232 }
2b5f62a0 233
2b5b9325 234 gtk_widget_set_double_buffered( m_glWidget, FALSE );
2b5b9325 235
dc3065a5 236#if WXWIN_COMPATIBILITY_2_8
b7ea712c 237 g_signal_connect(m_wxwindow, "realize", G_CALLBACK(gtk_glwindow_realized_callback), this);
dc3065a5 238#endif // WXWIN_COMPATIBILITY_2_8
b7ea712c
RR
239 g_signal_connect(m_wxwindow, "map", G_CALLBACK(gtk_glwindow_map_callback), this);
240 g_signal_connect(m_wxwindow, "expose_event", G_CALLBACK(gtk_glwindow_expose_callback), this);
241 g_signal_connect(m_widget, "size_allocate", G_CALLBACK(gtk_glcanvas_size_callback), this);
a6f5aa49 242
fee7a683
MR
243 if (gtk_check_version(2,2,0) != NULL)
244 {
fee7a683
MR
245 gtk_widget_pop_colormap();
246 }
2b5f62a0 247
dc3065a5 248#if WXWIN_COMPATIBILITY_2_8
bc869971
VZ
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 );
dc3065a5 254#endif // WXWIN_COMPATIBILITY_2_8
bc869971
VZ
255
256 if (GTK_WIDGET_MAPPED(m_wxwindow))
257 gtk_glwindow_map_callback( m_wxwindow, this );
258
670f9935 259 return true;
a6f5aa49
VZ
260}
261
498ace9e 262Window wxGLCanvas::GetXWindow() const
8b089c5e 263{
b7ea712c 264 GdkWindow *window = GTK_PIZZA(m_wxwindow)->bin_window;
498ace9e 265 return window ? GDK_WINDOW_XWINDOW(window) : 0;
8b089c5e
JS
266}
267
8b089c5e
JS
268void wxGLCanvas::OnInternalIdle()
269{
dc3065a5 270 if (m_exposed)
8b089c5e
JS
271 {
272 wxPaintEvent event( GetId() );
273 event.SetEventObject( this );
274 GetEventHandler()->ProcessEvent( event );
275
670f9935 276 m_exposed = false;
8b089c5e
JS
277 GetUpdateRegion().Clear();
278 }
2b5f62a0 279
8b089c5e
JS
280 wxWindow::OnInternalIdle();
281}
282
dc3065a5
VZ
283#if WXWIN_COMPATIBILITY_2_8
284
285void wxGLCanvas::GTKInitImplicitContext()
286{
287 if ( !m_glContext && m_createImplicitContext )
288 {
289 wxGLContext *share = m_sharedContext;
290 if ( !share && m_sharedContextOf )
291 share = m_sharedContextOf->m_glContext;
292
293 m_glContext = new wxGLContext(this, share);
294 }
295}
a6f5aa49 296
dc3065a5 297#endif // WXWIN_COMPATIBILITY_2_8
a6f5aa49 298
dc3065a5 299#endif // wxUSE_GLCANVAS