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(); 
  43 #endif // WXWIN_COMPATIBILITY_2_8 
  45 //----------------------------------------------------------------------------- 
  46 // "map" from m_wxwindow 
  47 //----------------------------------------------------------------------------- 
  51 gtk_glwindow_map_callback( GtkWidget 
* WXUNUSED(widget
), wxGLCanvas 
*win 
) 
  53     wxPaintEvent 
event( win
->GetId() ); 
  54     event
.SetEventObject( win 
); 
  55     win
->HandleWindowEvent( event 
); 
  57     win
->m_exposed 
= false; 
  58     win
->GetUpdateRegion().Clear(); 
  62 //----------------------------------------------------------------------------- 
  63 // "expose_event" of m_wxwindow 
  64 //----------------------------------------------------------------------------- 
  68 gtk_glwindow_expose_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventExpose 
*gdk_event
, wxGLCanvas 
*win 
) 
  70     win
->m_exposed 
= true; 
  72     win
->GetUpdateRegion().Union( gdk_event
->area
.x
, 
  74                                   gdk_event
->area
.width
, 
  75                                   gdk_event
->area
.height 
); 
  80 //----------------------------------------------------------------------------- 
  81 // "size_allocate" of m_wxwindow 
  82 //----------------------------------------------------------------------------- 
  86 gtk_glcanvas_size_callback(GtkWidget 
*WXUNUSED(widget
), 
  87                            GtkAllocation 
* WXUNUSED(alloc
), 
  93     wxSizeEvent 
event( wxSize(win
->m_width
,win
->m_height
), win
->GetId() ); 
  94     event
.SetEventObject( win 
); 
  95     win
->HandleWindowEvent( event 
); 
  99 //----------------------------------------------------------------------------- 
 100 // emission hook for "parent-set" 
 101 //----------------------------------------------------------------------------- 
 105 parent_set_hook(GSignalInvocationHint
*, guint
, const GValue
* param_values
, void* data
) 
 107     wxGLCanvas
* win 
= (wxGLCanvas
*)data
; 
 108     if (g_value_peek_pointer(¶m_values
[0]) == win
->m_wxwindow
) 
 110         const XVisualInfo
* xvi 
= win
->GetXVisualInfo(); 
 111         GdkVisual
* visual 
= gtk_widget_get_visual(win
->m_wxwindow
); 
 112         if (GDK_VISUAL_XVISUAL(visual
)->visualid 
!= xvi
->visualid
) 
 114             GdkScreen
* screen 
= gtk_widget_get_screen(win
->m_wxwindow
); 
 115             visual 
= gdk_x11_screen_lookup_visual(screen
, xvi
->visualid
); 
 116             GdkColormap
* colormap 
= gdk_colormap_new(visual
, false); 
 117             gtk_widget_set_colormap(win
->m_wxwindow
, colormap
); 
 118             g_object_unref(colormap
); 
 127 //--------------------------------------------------------------------------- 
 129 //--------------------------------------------------------------------------- 
 131 IMPLEMENT_CLASS(wxGLCanvas
, wxWindow
) 
 133 wxGLCanvas::wxGLCanvas(wxWindow 
*parent
, 
 135                        const int *attribList
, 
 139                        const wxString
& name
, 
 140                        const wxPalette
& palette
) 
 141 #if WXWIN_COMPATIBILITY_2_8 
 142     : m_createImplicitContext(false) 
 145     Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
); 
 148 #if WXWIN_COMPATIBILITY_2_8 
 150 wxGLCanvas::wxGLCanvas(wxWindow 
*parent
, 
 155                        const wxString
& name
, 
 156                        const int *attribList
, 
 157                        const wxPalette
& palette
) 
 158     : m_createImplicitContext(true) 
 160     m_sharedContext 
= NULL
; 
 161     m_sharedContextOf 
= NULL
; 
 163     Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
); 
 166 wxGLCanvas::wxGLCanvas(wxWindow 
*parent
, 
 167                        const wxGLContext 
*shared
, 
 172                        const wxString
& name
, 
 173                        const int *attribList
, 
 174                        const wxPalette
& palette
) 
 175     : m_createImplicitContext(true) 
 177     m_sharedContext 
= const_cast<wxGLContext 
*>(shared
); 
 179     Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
); 
 182 wxGLCanvas::wxGLCanvas(wxWindow 
*parent
, 
 183                        const wxGLCanvas 
*shared
, 
 185                        const wxPoint
& pos
, const wxSize
& size
, 
 186                        long style
, const wxString
& name
, 
 187                        const int *attribList
, 
 188                        const wxPalette
& palette 
) 
 189     : m_createImplicitContext(true) 
 191     m_sharedContext 
= NULL
; 
 192     m_sharedContextOf 
= const_cast<wxGLCanvas 
*>(shared
); 
 194     Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
); 
 197 #endif // WXWIN_COMPATIBILITY_2_8 
 199 bool wxGLCanvas::Create(wxWindow 
*parent
, 
 204                         const wxString
& name
, 
 205                         const int *attribList
, 
 206                         const wxPalette
& WXUNUSED_UNLESS_DEBUG(palette
)) 
 208     wxASSERT_MSG( !palette
.IsOk(), wxT("palettes not supported") ); 
 212     m_nativeSizeEvent 
= true; 
 214     if ( !InitVisual(attribList
) ) 
 217     // watch for the "parent-set" signal on m_wxwindow so we can set colormap 
 218     // before m_wxwindow is realized (which will occur before 
 219     // wxWindow::Create() returns if parent is already visible) 
 220     unsigned sig_id 
= g_signal_lookup("parent-set", GTK_TYPE_WIDGET
); 
 221     g_signal_add_emission_hook(sig_id
, 0, parent_set_hook
, this, NULL
); 
 223     wxWindow::Create( parent
, id
, pos
, size
, style
, name 
); 
 225     gtk_widget_set_double_buffered(m_wxwindow
, false); 
 227 #if WXWIN_COMPATIBILITY_2_8 
 228     g_signal_connect(m_wxwindow
, "realize",       G_CALLBACK(gtk_glwindow_realized_callback
), this); 
 229 #endif // WXWIN_COMPATIBILITY_2_8 
 230     g_signal_connect(m_wxwindow
, "map",           G_CALLBACK(gtk_glwindow_map_callback
),      this); 
 231     g_signal_connect(m_wxwindow
, "expose_event",  G_CALLBACK(gtk_glwindow_expose_callback
),   this); 
 232     g_signal_connect(m_widget
,   "size_allocate", G_CALLBACK(gtk_glcanvas_size_callback
),     this); 
 234 #if WXWIN_COMPATIBILITY_2_8 
 235     // if our parent window is already visible, we had been realized before we 
 236     // connected to the "realize" signal and hence our m_glContext hasn't been 
 237     // initialized yet and we have to do it now 
 238     if (GTK_WIDGET_REALIZED(m_wxwindow
)) 
 239         gtk_glwindow_realized_callback( m_wxwindow
, this ); 
 240 #endif // WXWIN_COMPATIBILITY_2_8 
 242     if (GTK_WIDGET_MAPPED(m_wxwindow
)) 
 243         gtk_glwindow_map_callback( m_wxwindow
, this ); 
 248 Window 
wxGLCanvas::GetXWindow() const 
 250     GdkWindow
* window 
= GTKGetDrawingWindow(); 
 251     return window 
? GDK_WINDOW_XWINDOW(window
) : 0; 
 254 void wxGLCanvas::OnInternalIdle() 
 258         wxPaintEvent 
event( GetId() ); 
 259         event
.SetEventObject( this ); 
 260         HandleWindowEvent( event 
); 
 263         GetUpdateRegion().Clear(); 
 266     wxWindow::OnInternalIdle(); 
 269 #if WXWIN_COMPATIBILITY_2_8 
 271 void wxGLCanvas::GTKInitImplicitContext() 
 273     if ( !m_glContext 
&& m_createImplicitContext 
) 
 275         wxGLContext 
*share 
= m_sharedContext
; 
 276         if ( !share 
&& m_sharedContextOf 
) 
 277             share 
= m_sharedContextOf
->m_glContext
; 
 279         m_glContext 
= new wxGLContext(this, share
); 
 283 #endif // WXWIN_COMPATIBILITY_2_8 
 285 #endif // wxUSE_GLCANVAS