X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/bbe0af5b15f8b8e95ed45abc2140fb3a1fac3c87..ba681060f36767a2682b8547871af2c6f8159955:/utils/glcanvas/src/glcanvas.cpp?ds=inline diff --git a/utils/glcanvas/src/glcanvas.cpp b/utils/glcanvas/src/glcanvas.cpp index a668badcab..9e16370d1e 100644 --- a/utils/glcanvas/src/glcanvas.cpp +++ b/utils/glcanvas/src/glcanvas.cpp @@ -20,17 +20,19 @@ #include "wx/module.h" #include "wx/app.h" +extern "C" { #include "gtk/gtk.h" #include "gdk/gdk.h" -extern "C" { #include "gdk/gdkx.h" } +#include "wx/gtk/win_gtk.h" + //--------------------------------------------------------------------------- -// global variables +// global data //--------------------------------------------------------------------------- -XVisualInfo *g_visual_info = (XVisualInfo*) NULL; +XVisualInfo *g_vi = (XVisualInfo*) NULL; //--------------------------------------------------------------------------- // wxGLContext @@ -41,25 +43,25 @@ IMPLEMENT_CLASS(wxGLContext,wxObject) wxGLContext::wxGLContext( bool WXUNUSED(isRGB), wxWindow *win, const wxPalette& WXUNUSED(palette) ) { m_window = win; - m_widget = win->m_wxwindow; + m_widget = ((wxGLCanvas*)win)->m_glWidget; - wxCHECK_RET( g_visual_info != NULL, "invalid visual for OpenGl" ); + wxCHECK_RET( g_vi, "invalid visual for OpenGl" ); - m_glContext = glXCreateContext( GDK_DISPLAY(), g_visual_info, None, GL_TRUE ); + m_glContext = glXCreateContext( GDK_DISPLAY(), g_vi, None, GL_TRUE ); - wxCHECK_RET( m_glContext != NULL, "Couldn't create OpenGl context" ); - - glXMakeCurrent( GDK_DISPLAY(), GDK_WINDOW_XWINDOW(m_widget->window), m_glContext ); + wxCHECK_RET( m_glContext, "Couldn't create OpenGl context" ); } wxGLContext::~wxGLContext() { - if (m_glContext) - { - glXMakeCurrent( GDK_DISPLAY(), GDK_WINDOW_XWINDOW(m_widget->window), m_glContext ); + if (!m_glContext) return; - glXDestroyContext( GDK_DISPLAY(), m_glContext ); + if (m_glContext == glXGetCurrentContext()) + { + glXMakeCurrent( GDK_DISPLAY(), None, NULL); } + + glXDestroyContext( GDK_DISPLAY(), m_glContext ); } void wxGLContext::SwapBuffers() @@ -116,12 +118,71 @@ BEGIN_EVENT_TABLE(wxGLCanvas, wxScrolledWindow) EVT_SIZE(wxGLCanvas::OnSize) END_EVENT_TABLE() -wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id, - const wxPoint& pos, const wxSize& size, long style, const wxString& name, - int *WXUNUSED(attribList), const wxPalette& palette): - wxScrolledWindow(parent, id, pos, size, style, name) +wxGLCanvas::wxGLCanvas( wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, + long style, const wxString& name, + int *attribList, + const wxPalette& palette ) +{ + Create( parent, id, pos, size, style, name, attribList, palette ); +} + +bool wxGLCanvas::Create( wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, + long style, const wxString& name, + int *attribList, + const wxPalette& palette ) { + if (!attribList) + { + int data[] = { GLX_RGBA, + GLX_DOUBLEBUFFER, + GLX_DEPTH_SIZE, 1, + None }; + attribList = (int*) data; + } + + Display *dpy = GDK_DISPLAY(); + + g_vi = glXChooseVisual( dpy, DefaultScreen(dpy), attribList ); + + GdkVisual *visual = gdkx_visual_get( g_vi->visualid ); + GdkColormap *colormap = gdk_colormap_new( gdkx_visual_get(g_vi->visualid), TRUE ); + + gtk_widget_push_colormap( colormap ); + gtk_widget_push_visual( visual ); + + m_glWidget = gtk_drawing_area_new(); + gtk_widget_set_events( m_glWidget, + GDK_EXPOSURE_MASK | + GDK_POINTER_MOTION_HINT_MASK | + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_MOTION_MASK | + GDK_BUTTON1_MOTION_MASK | + GDK_BUTTON2_MOTION_MASK | + GDK_BUTTON3_MOTION_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_KEY_PRESS_MASK | + GDK_KEY_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK ); + + gtk_widget_pop_visual(); + gtk_widget_pop_colormap(); + + wxScrolledWindow::Create( parent, id, pos, size, style, name ); + + gtk_myfixed_put( GTK_MYFIXED(m_wxwindow), m_glWidget, 0, 0 ); + + gtk_widget_show( m_glWidget ); + m_glContext = new wxGLContext( TRUE, this, palette ); + + XFree( g_vi ); + g_vi = (XVisualInfo*) NULL; + + return TRUE; } wxGLCanvas::~wxGLCanvas() @@ -137,13 +198,12 @@ void wxGLCanvas::SwapBuffers() void wxGLCanvas::OnSize(wxSizeEvent& WXUNUSED(event)) { int width, height; - GetClientSize(& width, & height); - - if (m_glContext) + GetClientSize( &width, &height ); + if (m_glContext && GTK_WIDGET_REALIZED(m_glWidget) ) { - m_glContext->SetCurrent(); - - glViewport(0, 0, (GLint)width, (GLint)height); + SetCurrent(); + + glViewport(0, 0, (GLint)width, (GLint)height ); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 ); @@ -161,39 +221,92 @@ void wxGLCanvas::SetColour( const char *colour ) if (m_glContext) m_glContext->SetColour( colour ); } -//-------------------------------------------------------------------- -// wxGLModule -//-------------------------------------------------------------------- - -class wxGLModule : public wxModule +void wxGLCanvas::SetSize( int x, int y, int width, int height, int sizeFlags ) { -public: - virtual bool OnInit(); - virtual void OnExit(); + if (m_resizing) return; // I don't like recursions + m_resizing = TRUE; + + if (m_parent->m_wxwindow == NULL) // i.e. wxNotebook + { + // don't set the size for children of wxNotebook, just take the values. + m_x = x; + m_y = y; + m_width = width; + m_height = height; + } + else + { + int old_width = m_width; + int old_height = m_height; + + if ((sizeFlags & wxSIZE_USE_EXISTING) == wxSIZE_USE_EXISTING) + { + if (x != -1) m_x = x; + if (y != -1) m_y = y; + if (width != -1) m_width = width; + if (height != -1) m_height = height; + } + else + { + m_x = x; + m_y = y; + m_width = width; + m_height = height; + } + + if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH) + { + if (width == -1) m_width = 80; + } + + if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT) + { + if (height == -1) m_height = 26; + } + + if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth; + if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight; + if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth; + if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight; + + wxPoint pt( m_parent->GetClientAreaOrigin() ); + gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x+pt.x, m_y+pt.y ); + + if ((old_width != m_width) || (old_height != m_height)) + { + gtk_widget_set_usize( m_widget, m_width, m_height ); + + gtk_drawing_area_size( GTK_DRAWING_AREA(m_glWidget), m_width, m_height ); + + GtkAllocation allo; + allo.x = 0; + allo.y = 0; + allo.width = m_width; + allo.height = m_height; + gtk_widget_size_allocate( m_glWidget, &allo ); + } + } -private: - DECLARE_DYNAMIC_CLASS(wxGLModule) -}; + m_sizeSet = TRUE; -IMPLEMENT_DYNAMIC_CLASS(wxGLModule, wxModule) + wxSizeEvent event( wxSize(m_width,m_height), GetId() ); + event.SetEventObject( this ); + GetEventHandler()->ProcessEvent( event ); -bool wxGLModule::OnInit() -{ - int data[] = { GLX_RGBA,GLX_RED_SIZE,1,GLX_GREEN_SIZE,1, - GLX_BLUE_SIZE,1,GLX_DOUBLEBUFFER,None}; + m_resizing = FALSE; +} - g_visual_info = glXChooseVisual( GDK_DISPLAY(), DefaultScreen(GDK_DISPLAY()), data ); - - wxCHECK_MSG( g_visual_info != NULL, FALSE, "Couldn't choose visual for OpenGl" ); - - wxVisualSetByExternal = gdkx_visual_get(g_visual_info->visualid); - - wxColormapSetByExternal = gdk_colormap_new( gdkx_visual_get(g_visual_info->visualid), TRUE ); - - return TRUE; +void wxGLCanvas::SetSize( int width, int height ) +{ + SetSize( -1, -1, width, height, wxSIZE_USE_EXISTING ); } -void wxGLModule::OnExit() +GtkWidget *wxGLCanvas::GetConnectWidget() { + return m_glWidget; } +bool wxGLCanvas::IsOwnGtkWindow( GdkWindow *window ) +{ + return (window == m_glWidget->window); +}