{
public:
wxApp();
- ~wxApp();
+ virtual ~wxApp();
/* override for altering the way wxGTK intializes the GUI
* (palette/visual/colorcube). under wxMSW, OnInitGui() does nothing by
#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__
#ifndef _WX_GLCANVAS_H_
#define _WX_GLCANVAS_H_
-#include <wx/defs.h>
+#include "wx/defs.h"
#if wxUSE_GLCANVAS
-#include <wx/scrolwin.h>
+#include "wx/scrolwin.h"
+#include "wx/app.h"
extern "C" {
-#include "GL/gl.h"
-#include "GL/glx.h"
-#include "GL/glu.h"
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <GL/glu.h>
}
//---------------------------------------------------------------------------
};
//---------------------------------------------------------------------------
-// wxGLContext
+// wxGLCanvas
//---------------------------------------------------------------------------
class WXDLLEXPORT wxGLCanvas: public wxScrolledWindow
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
{
public:
wxApp();
- ~wxApp();
+ virtual ~wxApp();
/* override for altering the way wxGTK intializes the GUI
* (palette/visual/colorcube). under wxMSW, OnInitGui() does nothing by
#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__
#ifndef _WX_GLCANVAS_H_
#define _WX_GLCANVAS_H_
-#include <wx/defs.h>
+#include "wx/defs.h"
#if wxUSE_GLCANVAS
-#include <wx/scrolwin.h>
+#include "wx/scrolwin.h"
+#include "wx/app.h"
extern "C" {
-#include "GL/gl.h"
-#include "GL/glx.h"
-#include "GL/glu.h"
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <GL/glu.h>
}
//---------------------------------------------------------------------------
};
//---------------------------------------------------------------------------
-// wxGLContext
+// wxGLCanvas
//---------------------------------------------------------------------------
class WXDLLEXPORT wxGLCanvas: public wxScrolledWindow
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
#include <glib.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
#include "wx/gtk/win_gtk.h"
#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()
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__
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;
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
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()
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
#include <glib.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
#include "wx/gtk/win_gtk.h"
#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()
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__
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;
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
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()
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