]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/glcanvas.cpp
Fix link errors under Cygwin with wxUSE_GRAPHICS_CONTEXT==1.
[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
a1abca32
PC
19#include <gtk/gtk.h>
20#include <gdk/gdkx.h>
8b089c5e 21
dc3065a5
VZ
22#if WXWIN_COMPATIBILITY_2_8
23
8b089c5e 24//-----------------------------------------------------------------------------
dc3065a5 25// "realize" from m_wxwindow: used to create m_glContext implicitly
8b089c5e
JS
26//-----------------------------------------------------------------------------
27
865bb325 28extern "C" {
144ae5bb 29static void
34a34b02 30gtk_glwindow_realized_callback( GtkWidget *WXUNUSED(widget), wxGLCanvas *win )
8b089c5e 31{
dc3065a5 32 win->GTKInitImplicitContext();
8b089c5e 33}
865bb325 34}
8b089c5e 35
dc3065a5
VZ
36#endif // WXWIN_COMPATIBILITY_2_8
37
8b089c5e
JS
38//-----------------------------------------------------------------------------
39// "map" from m_wxwindow
40//-----------------------------------------------------------------------------
41
865bb325 42extern "C" {
144ae5bb 43static void
8b089c5e
JS
44gtk_glwindow_map_callback( GtkWidget * WXUNUSED(widget), wxGLCanvas *win )
45{
dc3065a5
VZ
46 wxPaintEvent event( win->GetId() );
47 event.SetEventObject( win );
937013e0 48 win->HandleWindowEvent( event );
8b089c5e 49
dc3065a5
VZ
50 win->m_exposed = false;
51 win->GetUpdateRegion().Clear();
8b089c5e 52}
865bb325 53}
8b089c5e
JS
54
55//-----------------------------------------------------------------------------
56// "expose_event" of m_wxwindow
57//-----------------------------------------------------------------------------
58
865bb325 59extern "C" {
6d727f6c 60static gboolean
8b089c5e
JS
61gtk_glwindow_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxGLCanvas *win )
62{
670f9935 63 win->m_exposed = true;
8b089c5e
JS
64
65 win->GetUpdateRegion().Union( gdk_event->area.x,
66 gdk_event->area.y,
67 gdk_event->area.width,
68 gdk_event->area.height );
6d727f6c 69 return false;
8b089c5e 70}
865bb325 71}
8b089c5e 72
8b089c5e
JS
73//-----------------------------------------------------------------------------
74// "size_allocate" of m_wxwindow
75//-----------------------------------------------------------------------------
76
865bb325 77extern "C" {
2b5f62a0 78static void
e0d1fd7f
VZ
79gtk_glcanvas_size_callback(GtkWidget *WXUNUSED(widget),
80 GtkAllocation * WXUNUSED(alloc),
81 wxGLCanvas *win)
8b089c5e 82{
8b089c5e
JS
83 if (!win->m_hasVMT)
84 return;
85
86 wxSizeEvent event( wxSize(win->m_width,win->m_height), win->GetId() );
87 event.SetEventObject( win );
937013e0 88 win->HandleWindowEvent( event );
8b089c5e 89}
865bb325 90}
8b089c5e 91
3780e252
PC
92//-----------------------------------------------------------------------------
93// emission hook for "parent-set"
94//-----------------------------------------------------------------------------
95
96extern "C" {
97static gboolean
98parent_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
8b089c5e
JS
120//---------------------------------------------------------------------------
121// wxGlCanvas
122//---------------------------------------------------------------------------
123
4660d7e5 124IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
8b089c5e 125
dc3065a5
VZ
126wxGLCanvas::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
b7ea712c 135 : m_createImplicitContext(false)
dc3065a5 136#endif
b7ea712c 137{
dc3065a5 138 Create(parent, id, pos, size, style, name, attribList, palette);
b7ea712c
RR
139}
140
dc3065a5
VZ
141#if WXWIN_COMPATIBILITY_2_8
142
143wxGLCanvas::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)
b7ea712c 151 : m_createImplicitContext(true)
8b089c5e 152{
21562ad2
VZ
153 m_sharedContext = NULL;
154 m_sharedContextOf = NULL;
155
dc3065a5 156 Create(parent, id, pos, size, style, name, attribList, palette);
8b089c5e
JS
157}
158
dc3065a5
VZ
159wxGLCanvas::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)
b7ea712c 168 : m_createImplicitContext(true)
2b5f62a0 169{
5c33522f 170 m_sharedContext = const_cast<wxGLContext *>(shared);
dc3065a5
VZ
171
172 Create(parent, id, pos, size, style, name, attribList, palette);
8b089c5e
JS
173}
174
dc3065a5
VZ
175wxGLCanvas::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 )
b7ea712c 182 : m_createImplicitContext(true)
2b5f62a0 183{
21562ad2 184 m_sharedContext = NULL;
5c33522f 185 m_sharedContextOf = const_cast<wxGLCanvas *>(shared);
dc3065a5
VZ
186
187 Create(parent, id, pos, size, style, name, attribList, palette);
8b089c5e
JS
188}
189
dc3065a5 190#endif // WXWIN_COMPATIBILITY_2_8
2b5f62a0 191
dc3065a5
VZ
192bool 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,
9ce5cf09 199 const wxPalette& palette)
dc3065a5 200{
9ce5cf09 201#if wxUSE_PALETTE
9a83f860 202 wxASSERT_MSG( !palette.IsOk(), wxT("palettes not supported") );
9ce5cf09
VZ
203#endif // wxUSE_PALETTE
204 wxUnusedVar(palette); // Unused when wxDEBUG_LEVEL==0
e0d1fd7f 205
670f9935
WS
206 m_exposed = false;
207 m_noExpose = true;
208 m_nativeSizeEvent = true;
34a34b02 209
498ace9e
VZ
210 if ( !InitVisual(attribList) )
211 return false;
2b5f62a0 212
3780e252
PC
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);
2b5f62a0 218
ff654490 219 wxWindow::Create( parent, id, pos, size, style, name );
fee7a683 220
144ae5bb 221 gtk_widget_set_double_buffered(m_wxwindow, false);
2b5b9325 222
dc3065a5 223#if WXWIN_COMPATIBILITY_2_8
b7ea712c 224 g_signal_connect(m_wxwindow, "realize", G_CALLBACK(gtk_glwindow_realized_callback), this);
dc3065a5 225#endif // WXWIN_COMPATIBILITY_2_8
b7ea712c
RR
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);
a6f5aa49 229
dc3065a5 230#if WXWIN_COMPATIBILITY_2_8
bc869971
VZ
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_REALIZED(m_wxwindow))
235 gtk_glwindow_realized_callback( m_wxwindow, this );
dc3065a5 236#endif // WXWIN_COMPATIBILITY_2_8
bc869971
VZ
237
238 if (GTK_WIDGET_MAPPED(m_wxwindow))
239 gtk_glwindow_map_callback( m_wxwindow, this );
240
670f9935 241 return true;
a6f5aa49
VZ
242}
243
498ace9e 244Window wxGLCanvas::GetXWindow() const
8b089c5e 245{
f089940f 246 GdkWindow* window = GTKGetDrawingWindow();
498ace9e 247 return window ? GDK_WINDOW_XWINDOW(window) : 0;
8b089c5e
JS
248}
249
8b089c5e
JS
250void wxGLCanvas::OnInternalIdle()
251{
dc3065a5 252 if (m_exposed)
8b089c5e
JS
253 {
254 wxPaintEvent event( GetId() );
255 event.SetEventObject( this );
937013e0 256 HandleWindowEvent( event );
8b089c5e 257
670f9935 258 m_exposed = false;
8b089c5e
JS
259 GetUpdateRegion().Clear();
260 }
2b5f62a0 261
8b089c5e
JS
262 wxWindow::OnInternalIdle();
263}
264
dc3065a5
VZ
265#if WXWIN_COMPATIBILITY_2_8
266
267void 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}
a6f5aa49 278
dc3065a5 279#endif // WXWIN_COMPATIBILITY_2_8
a6f5aa49 280
dc3065a5 281#endif // wxUSE_GLCANVAS