From a6f5aa49cf93fc19c776bcce0a7872bdc9707afb Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 28 Sep 2001 13:53:55 +0000 Subject: [PATCH] applied wxGLApp patch (#464500) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11716 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gtk/app.h | 6 +- include/wx/gtk/glcanvas.h | 43 ++++++++++-- include/wx/gtk1/app.h | 6 +- include/wx/gtk1/glcanvas.h | 43 ++++++++++-- src/gtk/app.cpp | 24 ++++++- src/gtk/glcanvas.cpp | 135 +++++++++++++++++++++++-------------- src/gtk1/app.cpp | 24 ++++++- src/gtk1/glcanvas.cpp | 135 +++++++++++++++++++++++-------------- 8 files changed, 294 insertions(+), 122 deletions(-) diff --git a/include/wx/gtk/app.h b/include/wx/gtk/app.h index 6014589623..2681dea253 100644 --- a/include/wx/gtk/app.h +++ b/include/wx/gtk/app.h @@ -32,7 +32,7 @@ class wxApp: public wxAppBase { public: wxApp(); - ~wxApp(); + virtual ~wxApp(); /* override for altering the way wxGTK intializes the GUI * (palette/visual/colorcube). under wxMSW, OnInitGui() does nothing by @@ -75,6 +75,10 @@ public: #endif unsigned char *m_colorCube; + // used by the the wxGLApp and wxGLCanvas class for GL-based X visual + // selection; this is actually an XVisualInfo* + void *m_glVisualInfo; + private: // true if we're inside an assert modal dialog #ifdef __WXDEBUG__ diff --git a/include/wx/gtk/glcanvas.h b/include/wx/gtk/glcanvas.h index 813e314738..3eec4ab6ad 100644 --- a/include/wx/gtk/glcanvas.h +++ b/include/wx/gtk/glcanvas.h @@ -16,16 +16,17 @@ #ifndef _WX_GLCANVAS_H_ #define _WX_GLCANVAS_H_ -#include +#include "wx/defs.h" #if wxUSE_GLCANVAS -#include +#include "wx/scrolwin.h" +#include "wx/app.h" extern "C" { -#include "GL/gl.h" -#include "GL/glx.h" -#include "GL/glu.h" +#include +#include +#include } //--------------------------------------------------------------------------- @@ -100,7 +101,7 @@ private: }; //--------------------------------------------------------------------------- -// wxGLContext +// wxGLCanvas //--------------------------------------------------------------------------- class WXDLLEXPORT wxGLCanvas: public wxScrolledWindow @@ -161,15 +162,43 @@ public: wxGLContext *m_glContext, *m_sharedContext; wxGLCanvas *m_sharedContextOf; - void *m_vi; + void *m_vi; // actually an XVisualInfo* + bool m_canFreeVi; GtkWidget *m_glWidget; bool m_exposed; + + // returns an XVisualInfo* based on desired GL attributes; + // returns NULL if an appropriate visual is not found. The + // caller is reponsible for using XFree() to deallocate + // the returned structure. + static void* ChooseGLVisual(int *attribList); private: DECLARE_EVENT_TABLE() DECLARE_CLASS(wxGLCanvas) }; + +//--------------------------------------------------------------------------- +// wxGLApp +//--------------------------------------------------------------------------- + +class WXDLLEXPORT wxGLApp: public wxApp +{ +public: + wxGLApp() : wxApp() { } + ~wxGLApp(); + + // use this in the constructor of the user-derived wxGLApp class to select + // an appropriate X visual for GL. Returns TRUE if an appropriate visual + // is found - and sets m_glVisualInfo; FALSE otherwise. + bool InitGLVisual(int *attribList); + +private: + DECLARE_DYNAMIC_CLASS(wxGLApp) +}; + + #endif // wxUSE_GLCANVAS diff --git a/include/wx/gtk1/app.h b/include/wx/gtk1/app.h index 6014589623..2681dea253 100644 --- a/include/wx/gtk1/app.h +++ b/include/wx/gtk1/app.h @@ -32,7 +32,7 @@ class wxApp: public wxAppBase { public: wxApp(); - ~wxApp(); + virtual ~wxApp(); /* override for altering the way wxGTK intializes the GUI * (palette/visual/colorcube). under wxMSW, OnInitGui() does nothing by @@ -75,6 +75,10 @@ public: #endif unsigned char *m_colorCube; + // used by the the wxGLApp and wxGLCanvas class for GL-based X visual + // selection; this is actually an XVisualInfo* + void *m_glVisualInfo; + private: // true if we're inside an assert modal dialog #ifdef __WXDEBUG__ diff --git a/include/wx/gtk1/glcanvas.h b/include/wx/gtk1/glcanvas.h index 813e314738..3eec4ab6ad 100644 --- a/include/wx/gtk1/glcanvas.h +++ b/include/wx/gtk1/glcanvas.h @@ -16,16 +16,17 @@ #ifndef _WX_GLCANVAS_H_ #define _WX_GLCANVAS_H_ -#include +#include "wx/defs.h" #if wxUSE_GLCANVAS -#include +#include "wx/scrolwin.h" +#include "wx/app.h" extern "C" { -#include "GL/gl.h" -#include "GL/glx.h" -#include "GL/glu.h" +#include +#include +#include } //--------------------------------------------------------------------------- @@ -100,7 +101,7 @@ private: }; //--------------------------------------------------------------------------- -// wxGLContext +// wxGLCanvas //--------------------------------------------------------------------------- class WXDLLEXPORT wxGLCanvas: public wxScrolledWindow @@ -161,15 +162,43 @@ public: wxGLContext *m_glContext, *m_sharedContext; wxGLCanvas *m_sharedContextOf; - void *m_vi; + void *m_vi; // actually an XVisualInfo* + bool m_canFreeVi; GtkWidget *m_glWidget; bool m_exposed; + + // returns an XVisualInfo* based on desired GL attributes; + // returns NULL if an appropriate visual is not found. The + // caller is reponsible for using XFree() to deallocate + // the returned structure. + static void* ChooseGLVisual(int *attribList); private: DECLARE_EVENT_TABLE() DECLARE_CLASS(wxGLCanvas) }; + +//--------------------------------------------------------------------------- +// wxGLApp +//--------------------------------------------------------------------------- + +class WXDLLEXPORT wxGLApp: public wxApp +{ +public: + wxGLApp() : wxApp() { } + ~wxGLApp(); + + // use this in the constructor of the user-derived wxGLApp class to select + // an appropriate X visual for GL. Returns TRUE if an appropriate visual + // is found - and sets m_glVisualInfo; FALSE otherwise. + bool InitGLVisual(int *attribList); + +private: + DECLARE_DYNAMIC_CLASS(wxGLApp) +}; + + #endif // wxUSE_GLCANVAS diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp index 8502f2a279..38d4d1e75f 100644 --- a/src/gtk/app.cpp +++ b/src/gtk/app.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include "wx/gtk/win_gtk.h" @@ -335,6 +336,9 @@ wxApp::wxApp() #endif m_colorCube = (unsigned char*) NULL; + + // this is NULL for a "regular" wxApp, but is set (and freed) by a wxGLApp + m_glVisualInfo = (void *) NULL; } wxApp::~wxApp() @@ -355,11 +359,29 @@ bool wxApp::OnInitGui() GdkVisual *visual = gdk_visual_get_system(); + // if this is a wxGLApp (derived from wxApp), and we've already + // chosen a specific visual, then derive the GdkVisual from that + if (m_glVisualInfo != NULL) { +#ifdef __WXGTK20__ + /* seems gtk_widget_set_default_visual no longer exists? */ + GdkVisual* vis = gtk_widget_get_default_visual(); +#else + GdkVisual* vis = gdkx_visual_get( + ((XVisualInfo *) m_glVisualInfo) ->visualid ); + gtk_widget_set_default_visual( vis ); +#endif + + GdkColormap *colormap = gdk_colormap_new( vis, FALSE ); + gtk_widget_set_default_colormap( colormap ); + + visual = vis; + } + /* on some machines, the default visual is just 256 colours, so we make sure we get the best. this can sometimes be wasteful, of course, but what do these guys pay $30.000 for? */ - if ((gdk_visual_get_best() != gdk_visual_get_system()) && + else if ((gdk_visual_get_best() != gdk_visual_get_system()) && (m_useBestVisual)) { #ifdef __WXGTK20__ diff --git a/src/gtk/glcanvas.cpp b/src/gtk/glcanvas.cpp index a5ee3aa6bd..c15057112d 100644 --- a/src/gtk/glcanvas.cpp +++ b/src/gtk/glcanvas.cpp @@ -283,7 +283,6 @@ bool wxGLCanvas::Create( wxWindow *parent, int *attribList, const wxPalette& palette) { - int data[512]; m_sharedContext = (wxGLContext*)shared; // const_cast m_sharedContextOf = (wxGLCanvas*)shared_context_of; // const_cast m_glContext = (wxGLContext*) NULL; @@ -292,6 +291,68 @@ bool wxGLCanvas::Create( wxWindow *parent, m_noExpose = TRUE; m_nativeSizeEvent = TRUE; + XVisualInfo *vi = NULL; + if (wxTheApp->m_glVisualInfo != NULL) { + vi = (XVisualInfo *) wxTheApp->m_glVisualInfo; + m_canFreeVi = FALSE; // owned by wxTheApp - don't free upon destruction + } else { + vi = (XVisualInfo *) ChooseGLVisual(attribList); + m_canFreeVi = TRUE; + } + m_vi = vi; // save for later use + + wxCHECK_MSG( m_vi, FALSE, "required visual couldn't be found" ); + + GdkVisual *visual = gdkx_visual_get( vi->visualid ); + GdkColormap *colormap = gdk_colormap_new( gdkx_visual_get(vi->visualid), TRUE ); + + gtk_widget_push_colormap( colormap ); + gtk_widget_push_visual( visual ); + + wxScrolledWindow::Create( parent, id, pos, size, style, name ); + + m_glWidget = m_wxwindow; + + gtk_pizza_set_clear( GTK_PIZZA(m_wxwindow), FALSE ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "realize", + GTK_SIGNAL_FUNC(gtk_glwindow_realized_callback), (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "map", + GTK_SIGNAL_FUNC(gtk_glwindow_map_callback), (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", + GTK_SIGNAL_FUNC(gtk_glwindow_expose_callback), (gpointer)this ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw", + GTK_SIGNAL_FUNC(gtk_glwindow_draw_callback), (gpointer)this ); + + gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", + GTK_SIGNAL_FUNC(gtk_glcanvas_size_callback), (gpointer)this ); + + gtk_widget_pop_visual(); + gtk_widget_pop_colormap(); + + if (GTK_WIDGET_REALIZED(m_wxwindow)) + gtk_glwindow_realized_callback( m_wxwindow, this ); + + if (GTK_WIDGET_MAPPED(m_wxwindow)) + gtk_glwindow_map_callback( m_wxwindow, this ); + + return TRUE; +} + +wxGLCanvas::~wxGLCanvas() +{ + XVisualInfo *vi = (XVisualInfo *) m_vi; + + if (vi && m_canFreeVi) XFree( vi ); + if (m_glContext) delete m_glContext; +} + +void* wxGLCanvas::ChooseGLVisual(int *attribList) +{ + int data[512]; if (!attribList) { // default settings if attriblist = 0 @@ -355,57 +416,7 @@ bool wxGLCanvas::Create( wxWindow *parent, Display *dpy = GDK_DISPLAY(); - XVisualInfo *vi = glXChooseVisual( dpy, DefaultScreen(dpy), attribList ); - - m_vi = vi; // safe for later use - - wxCHECK_MSG( m_vi, FALSE, "required visual couldn't be found" ); - - GdkVisual *visual = gdkx_visual_get( vi->visualid ); - GdkColormap *colormap = gdk_colormap_new( gdkx_visual_get(vi->visualid), TRUE ); - - gtk_widget_push_colormap( colormap ); - gtk_widget_push_visual( visual ); - - wxScrolledWindow::Create( parent, id, pos, size, style, name ); - - m_glWidget = m_wxwindow; - - gtk_pizza_set_clear( GTK_PIZZA(m_wxwindow), FALSE ); - - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "realize", - GTK_SIGNAL_FUNC(gtk_glwindow_realized_callback), (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "map", - GTK_SIGNAL_FUNC(gtk_glwindow_map_callback), (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", - GTK_SIGNAL_FUNC(gtk_glwindow_expose_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw", - GTK_SIGNAL_FUNC(gtk_glwindow_draw_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", - GTK_SIGNAL_FUNC(gtk_glcanvas_size_callback), (gpointer)this ); - - gtk_widget_pop_visual(); - gtk_widget_pop_colormap(); - - if (GTK_WIDGET_REALIZED(m_wxwindow)) - gtk_glwindow_realized_callback( m_wxwindow, this ); - - if (GTK_WIDGET_MAPPED(m_wxwindow)) - gtk_glwindow_map_callback( m_wxwindow, this ); - - return TRUE; -} - -wxGLCanvas::~wxGLCanvas() -{ - XVisualInfo *vi = (XVisualInfo *) m_vi; - - if (vi) XFree( vi ); - if (m_glContext) delete m_glContext; + return glXChooseVisual( dpy, DefaultScreen(dpy), attribList ); } void wxGLCanvas::SwapBuffers() @@ -455,6 +466,26 @@ void wxGLCanvas::OnInternalIdle() wxWindow::OnInternalIdle(); } + + +//--------------------------------------------------------------------------- +// wxGLApp +//--------------------------------------------------------------------------- + +IMPLEMENT_CLASS(wxGLApp, wxApp) + +wxGLApp::~wxGLApp() +{ + if (m_glVisualInfo) XFree(m_glVisualInfo); +} + +bool wxGLApp::InitGLVisual(int *attribList) +{ + if (m_glVisualInfo) XFree(m_glVisualInfo); + m_glVisualInfo = wxGLCanvas::ChooseGLVisual(attribList); + return (m_glVisualInfo != NULL); +} + #endif // wxUSE_GLCANVAS diff --git a/src/gtk1/app.cpp b/src/gtk1/app.cpp index 8502f2a279..38d4d1e75f 100644 --- a/src/gtk1/app.cpp +++ b/src/gtk1/app.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include "wx/gtk/win_gtk.h" @@ -335,6 +336,9 @@ wxApp::wxApp() #endif m_colorCube = (unsigned char*) NULL; + + // this is NULL for a "regular" wxApp, but is set (and freed) by a wxGLApp + m_glVisualInfo = (void *) NULL; } wxApp::~wxApp() @@ -355,11 +359,29 @@ bool wxApp::OnInitGui() GdkVisual *visual = gdk_visual_get_system(); + // if this is a wxGLApp (derived from wxApp), and we've already + // chosen a specific visual, then derive the GdkVisual from that + if (m_glVisualInfo != NULL) { +#ifdef __WXGTK20__ + /* seems gtk_widget_set_default_visual no longer exists? */ + GdkVisual* vis = gtk_widget_get_default_visual(); +#else + GdkVisual* vis = gdkx_visual_get( + ((XVisualInfo *) m_glVisualInfo) ->visualid ); + gtk_widget_set_default_visual( vis ); +#endif + + GdkColormap *colormap = gdk_colormap_new( vis, FALSE ); + gtk_widget_set_default_colormap( colormap ); + + visual = vis; + } + /* on some machines, the default visual is just 256 colours, so we make sure we get the best. this can sometimes be wasteful, of course, but what do these guys pay $30.000 for? */ - if ((gdk_visual_get_best() != gdk_visual_get_system()) && + else if ((gdk_visual_get_best() != gdk_visual_get_system()) && (m_useBestVisual)) { #ifdef __WXGTK20__ diff --git a/src/gtk1/glcanvas.cpp b/src/gtk1/glcanvas.cpp index a5ee3aa6bd..c15057112d 100644 --- a/src/gtk1/glcanvas.cpp +++ b/src/gtk1/glcanvas.cpp @@ -283,7 +283,6 @@ bool wxGLCanvas::Create( wxWindow *parent, int *attribList, const wxPalette& palette) { - int data[512]; m_sharedContext = (wxGLContext*)shared; // const_cast m_sharedContextOf = (wxGLCanvas*)shared_context_of; // const_cast m_glContext = (wxGLContext*) NULL; @@ -292,6 +291,68 @@ bool wxGLCanvas::Create( wxWindow *parent, m_noExpose = TRUE; m_nativeSizeEvent = TRUE; + XVisualInfo *vi = NULL; + if (wxTheApp->m_glVisualInfo != NULL) { + vi = (XVisualInfo *) wxTheApp->m_glVisualInfo; + m_canFreeVi = FALSE; // owned by wxTheApp - don't free upon destruction + } else { + vi = (XVisualInfo *) ChooseGLVisual(attribList); + m_canFreeVi = TRUE; + } + m_vi = vi; // save for later use + + wxCHECK_MSG( m_vi, FALSE, "required visual couldn't be found" ); + + GdkVisual *visual = gdkx_visual_get( vi->visualid ); + GdkColormap *colormap = gdk_colormap_new( gdkx_visual_get(vi->visualid), TRUE ); + + gtk_widget_push_colormap( colormap ); + gtk_widget_push_visual( visual ); + + wxScrolledWindow::Create( parent, id, pos, size, style, name ); + + m_glWidget = m_wxwindow; + + gtk_pizza_set_clear( GTK_PIZZA(m_wxwindow), FALSE ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "realize", + GTK_SIGNAL_FUNC(gtk_glwindow_realized_callback), (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "map", + GTK_SIGNAL_FUNC(gtk_glwindow_map_callback), (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", + GTK_SIGNAL_FUNC(gtk_glwindow_expose_callback), (gpointer)this ); + + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw", + GTK_SIGNAL_FUNC(gtk_glwindow_draw_callback), (gpointer)this ); + + gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", + GTK_SIGNAL_FUNC(gtk_glcanvas_size_callback), (gpointer)this ); + + gtk_widget_pop_visual(); + gtk_widget_pop_colormap(); + + if (GTK_WIDGET_REALIZED(m_wxwindow)) + gtk_glwindow_realized_callback( m_wxwindow, this ); + + if (GTK_WIDGET_MAPPED(m_wxwindow)) + gtk_glwindow_map_callback( m_wxwindow, this ); + + return TRUE; +} + +wxGLCanvas::~wxGLCanvas() +{ + XVisualInfo *vi = (XVisualInfo *) m_vi; + + if (vi && m_canFreeVi) XFree( vi ); + if (m_glContext) delete m_glContext; +} + +void* wxGLCanvas::ChooseGLVisual(int *attribList) +{ + int data[512]; if (!attribList) { // default settings if attriblist = 0 @@ -355,57 +416,7 @@ bool wxGLCanvas::Create( wxWindow *parent, Display *dpy = GDK_DISPLAY(); - XVisualInfo *vi = glXChooseVisual( dpy, DefaultScreen(dpy), attribList ); - - m_vi = vi; // safe for later use - - wxCHECK_MSG( m_vi, FALSE, "required visual couldn't be found" ); - - GdkVisual *visual = gdkx_visual_get( vi->visualid ); - GdkColormap *colormap = gdk_colormap_new( gdkx_visual_get(vi->visualid), TRUE ); - - gtk_widget_push_colormap( colormap ); - gtk_widget_push_visual( visual ); - - wxScrolledWindow::Create( parent, id, pos, size, style, name ); - - m_glWidget = m_wxwindow; - - gtk_pizza_set_clear( GTK_PIZZA(m_wxwindow), FALSE ); - - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "realize", - GTK_SIGNAL_FUNC(gtk_glwindow_realized_callback), (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "map", - GTK_SIGNAL_FUNC(gtk_glwindow_map_callback), (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", - GTK_SIGNAL_FUNC(gtk_glwindow_expose_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw", - GTK_SIGNAL_FUNC(gtk_glwindow_draw_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", - GTK_SIGNAL_FUNC(gtk_glcanvas_size_callback), (gpointer)this ); - - gtk_widget_pop_visual(); - gtk_widget_pop_colormap(); - - if (GTK_WIDGET_REALIZED(m_wxwindow)) - gtk_glwindow_realized_callback( m_wxwindow, this ); - - if (GTK_WIDGET_MAPPED(m_wxwindow)) - gtk_glwindow_map_callback( m_wxwindow, this ); - - return TRUE; -} - -wxGLCanvas::~wxGLCanvas() -{ - XVisualInfo *vi = (XVisualInfo *) m_vi; - - if (vi) XFree( vi ); - if (m_glContext) delete m_glContext; + return glXChooseVisual( dpy, DefaultScreen(dpy), attribList ); } void wxGLCanvas::SwapBuffers() @@ -455,6 +466,26 @@ void wxGLCanvas::OnInternalIdle() wxWindow::OnInternalIdle(); } + + +//--------------------------------------------------------------------------- +// wxGLApp +//--------------------------------------------------------------------------- + +IMPLEMENT_CLASS(wxGLApp, wxApp) + +wxGLApp::~wxGLApp() +{ + if (m_glVisualInfo) XFree(m_glVisualInfo); +} + +bool wxGLApp::InitGLVisual(int *attribList) +{ + if (m_glVisualInfo) XFree(m_glVisualInfo); + m_glVisualInfo = wxGLCanvas::ChooseGLVisual(attribList); + return (m_glVisualInfo != NULL); +} + #endif // wxUSE_GLCANVAS -- 2.47.2