~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to src/gtk1/glcanvas.cpp

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/////////////////////////////////////////////////////////////////////////////
 
2
// Name:        src/gtk1/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: glcanvas.cpp 56644 2008-11-02 02:39:52Z VZ $
 
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
#ifndef WX_PRECOMP
 
20
    #include "wx/app.h"
 
21
    #include "wx/frame.h"
 
22
    #include "wx/colour.h"
 
23
    #include "wx/module.h"
 
24
#endif // WX_PRECOMP
 
25
 
 
26
extern "C"
 
27
{
 
28
#include "gtk/gtk.h"
 
29
#include "gdk/gdk.h"
 
30
#include "gdk/gdkx.h"
 
31
}
 
32
 
 
33
#include "wx/gtk1/win_gtk.h"
 
34
#include "wx/gtk1/private.h"
 
35
 
 
36
//-----------------------------------------------------------------------------
 
37
// idle system
 
38
//-----------------------------------------------------------------------------
 
39
 
 
40
extern void wxapp_install_idle_handler();
 
41
extern bool g_isIdle;
 
42
 
 
43
#if WXWIN_COMPATIBILITY_2_8
 
44
 
 
45
//-----------------------------------------------------------------------------
 
46
// "realize" from m_wxwindow: used to create m_glContext implicitly
 
47
//-----------------------------------------------------------------------------
 
48
 
 
49
extern "C" {
 
50
static gint
 
51
gtk_glwindow_realized_callback( GtkWidget *WXUNUSED(widget), wxGLCanvas *win )
 
52
{
 
53
    win->GTKInitImplicitContext();
 
54
 
 
55
    return FALSE;
 
56
}
 
57
}
 
58
 
 
59
#endif // WXWIN_COMPATIBILITY_2_8
 
60
 
 
61
//-----------------------------------------------------------------------------
 
62
// "map" from m_wxwindow
 
63
//-----------------------------------------------------------------------------
 
64
 
 
65
extern "C" {
 
66
static gint
 
67
gtk_glwindow_map_callback( GtkWidget * WXUNUSED(widget), wxGLCanvas *win )
 
68
{
 
69
    wxPaintEvent event( win->GetId() );
 
70
    event.SetEventObject( win );
 
71
    win->HandleWindowEvent( event );
 
72
 
 
73
    win->GetUpdateRegion().Clear();
 
74
 
 
75
    return FALSE;
 
76
}
 
77
}
 
78
 
 
79
//-----------------------------------------------------------------------------
 
80
// "expose_event" of m_wxwindow
 
81
//-----------------------------------------------------------------------------
 
82
 
 
83
extern "C" {
 
84
static void
 
85
gtk_glwindow_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxGLCanvas *win )
 
86
{
 
87
    if (g_isIdle)
 
88
        wxapp_install_idle_handler();
 
89
 
 
90
    win->GetUpdateRegion().Union( gdk_event->area.x,
 
91
                                  gdk_event->area.y,
 
92
                                  gdk_event->area.width,
 
93
                                  gdk_event->area.height );
 
94
}
 
95
}
 
96
 
 
97
//-----------------------------------------------------------------------------
 
98
// "draw" of m_wxwindow
 
99
//-----------------------------------------------------------------------------
 
100
 
 
101
extern "C" {
 
102
static void
 
103
gtk_glwindow_draw_callback( GtkWidget *WXUNUSED(widget), GdkRectangle *rect, wxGLCanvas *win )
 
104
{
 
105
    if (g_isIdle)
 
106
        wxapp_install_idle_handler();
 
107
 
 
108
    win->GetUpdateRegion().Union( rect->x, rect->y,
 
109
                                  rect->width, rect->height );
 
110
}
 
111
}
 
112
 
 
113
//-----------------------------------------------------------------------------
 
114
// "size_allocate" of m_wxwindow
 
115
//-----------------------------------------------------------------------------
 
116
 
 
117
extern "C" {
 
118
static void
 
119
gtk_glcanvas_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxGLCanvas *win )
 
120
{
 
121
    if (g_isIdle)
 
122
        wxapp_install_idle_handler();
 
123
 
 
124
    if (!win->m_hasVMT)
 
125
        return;
 
126
 
 
127
    wxSizeEvent event( wxSize(win->m_width,win->m_height), win->GetId() );
 
128
    event.SetEventObject( win );
 
129
    win->HandleWindowEvent( event );
 
130
}
 
131
}
 
132
 
 
133
//---------------------------------------------------------------------------
 
134
// wxGlCanvas
 
135
//---------------------------------------------------------------------------
 
136
 
 
137
IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
 
138
 
 
139
wxGLCanvas::wxGLCanvas(wxWindow *parent,
 
140
                       wxWindowID id,
 
141
                       const int *attribList,
 
142
                       const wxPoint& pos,
 
143
                       const wxSize& size,
 
144
                       long style,
 
145
                       const wxString& name,
 
146
                       const wxPalette& palette)
 
147
#if WXWIN_COMPATIBILITY_2_8
 
148
    : m_createImplicitContext(false)
 
149
#endif
 
150
{
 
151
    Create(parent, id, pos, size, style, name, attribList, palette);
 
152
}
 
153
 
 
154
#if WXWIN_COMPATIBILITY_2_8
 
155
 
 
156
wxGLCanvas::wxGLCanvas(wxWindow *parent,
 
157
                       wxWindowID id,
 
158
                       const wxPoint& pos,
 
159
                       const wxSize& size,
 
160
                       long style,
 
161
                       const wxString& name,
 
162
                       const int *attribList,
 
163
                       const wxPalette& palette)
 
164
    : m_createImplicitContext(true)
 
165
{
 
166
    Create(parent, id, pos, size, style, name, attribList, palette);
 
167
}
 
168
 
 
169
wxGLCanvas::wxGLCanvas(wxWindow *parent,
 
170
                       const wxGLContext *shared,
 
171
                       wxWindowID id,
 
172
                       const wxPoint& pos,
 
173
                       const wxSize& size,
 
174
                       long style,
 
175
                       const wxString& name,
 
176
                       const int *attribList,
 
177
                       const wxPalette& palette)
 
178
    : m_createImplicitContext(true)
 
179
{
 
180
    m_sharedContext = const_cast<wxGLContext *>(shared);
 
181
 
 
182
    Create(parent, id, pos, size, style, name, attribList, palette);
 
183
}
 
184
 
 
185
wxGLCanvas::wxGLCanvas(wxWindow *parent,
 
186
                       const wxGLCanvas *shared,
 
187
                       wxWindowID id,
 
188
                       const wxPoint& pos, const wxSize& size,
 
189
                       long style, const wxString& name,
 
190
                       const int *attribList,
 
191
                       const wxPalette& palette )
 
192
    : m_createImplicitContext(true)
 
193
{
 
194
    m_sharedContextOf = const_cast<wxGLCanvas *>(shared);
 
195
 
 
196
    Create(parent, id, pos, size, style, name, attribList, palette);
 
197
}
 
198
 
 
199
#endif // WXWIN_COMPATIBILITY_2_8
 
200
 
 
201
bool wxGLCanvas::Create(wxWindow *parent,
 
202
                        wxWindowID id,
 
203
                        const wxPoint& pos,
 
204
                        const wxSize& size,
 
205
                        long style,
 
206
                        const wxString& name,
 
207
                        const int *attribList,
 
208
                        const wxPalette& palette)
 
209
{
 
210
    m_noExpose = true;
 
211
    m_nativeSizeEvent = true;
 
212
 
 
213
    if ( !InitVisual(attribList) )
 
214
        return false;
 
215
 
 
216
    GdkVisual *visual = gdkx_visual_get( GetXVisualInfo()->visualid );
 
217
    GdkColormap *colormap = gdk_colormap_new( visual, TRUE );
 
218
 
 
219
    gtk_widget_push_colormap( colormap );
 
220
    gtk_widget_push_visual( visual );
 
221
 
 
222
    wxWindow::Create( parent, id, pos, size, style, name );
 
223
    m_glWidget = m_wxwindow;
 
224
 
 
225
    gtk_pizza_set_clear( GTK_PIZZA(m_wxwindow), FALSE );
 
226
 
 
227
#if WXWIN_COMPATIBILITY_2_8
 
228
    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "realize",
 
229
                            GTK_SIGNAL_FUNC(gtk_glwindow_realized_callback), (gpointer) this);
 
230
#endif // WXWIN_COMPATIBILITY_2_8
 
231
 
 
232
    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "map",
 
233
                            GTK_SIGNAL_FUNC(gtk_glwindow_map_callback), (gpointer) this);
 
234
 
 
235
    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event",
 
236
                            GTK_SIGNAL_FUNC(gtk_glwindow_expose_callback), (gpointer) this);
 
237
 
 
238
    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw",
 
239
                            GTK_SIGNAL_FUNC(gtk_glwindow_draw_callback), (gpointer) this);
 
240
 
 
241
    gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
 
242
                            GTK_SIGNAL_FUNC(gtk_glcanvas_size_callback), (gpointer) this);
 
243
 
 
244
    gtk_widget_pop_visual();
 
245
 
 
246
    gtk_widget_pop_colormap();
 
247
 
 
248
#if WXWIN_COMPATIBILITY_2_8
 
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 );
 
254
#endif // WXWIN_COMPATIBILITY_2_8
 
255
 
 
256
    if (GTK_WIDGET_MAPPED(m_wxwindow))
 
257
        gtk_glwindow_map_callback( m_wxwindow, this );
 
258
 
 
259
    return true;
 
260
}
 
261
 
 
262
Window wxGLCanvas::GetXWindow() const
 
263
{
 
264
    GdkWindow *window = GTK_PIZZA(m_wxwindow)->bin_window;
 
265
    return window ? GDK_WINDOW_XWINDOW(window) : 0;
 
266
}
 
267
 
 
268
void wxGLCanvas::OnInternalIdle()
 
269
{
 
270
    if (!m_updateRegion.IsEmpty())
 
271
    {
 
272
        wxPaintEvent event( GetId() );
 
273
        event.SetEventObject( this );
 
274
        HandleWindowEvent( event );
 
275
 
 
276
        GetUpdateRegion().Clear();
 
277
    }
 
278
 
 
279
    wxWindow::OnInternalIdle();
 
280
}
 
281
 
 
282
#if WXWIN_COMPATIBILITY_2_8
 
283
 
 
284
void wxGLCanvas::GTKInitImplicitContext()
 
285
{
 
286
    if ( !m_glContext && m_createImplicitContext )
 
287
    {
 
288
        wxGLContext *share = m_sharedContext;
 
289
        if ( !share && m_sharedContextOf )
 
290
            share = m_sharedContextOf->m_glContext;
 
291
 
 
292
        m_glContext = new wxGLContext(this, share);
 
293
    }
 
294
}
 
295
 
 
296
#endif // WXWIN_COMPATIBILITY_2_8
 
297
 
 
298
#endif // wxUSE_GLCANVAS