diff --git a/direct/src/wxwidgets/WxPandaWindow.py b/direct/src/wxwidgets/WxPandaWindow.py index c136691d52..f808adb51c 100644 --- a/direct/src/wxwidgets/WxPandaWindow.py +++ b/direct/src/wxwidgets/WxPandaWindow.py @@ -146,6 +146,7 @@ else: base.startWx() wxgl.GLCanvas.__init__(self, *args, **kw) + self.visible = False # Can't share the GSG when a new wxgl.GLContext is created # automatically. @@ -170,23 +171,27 @@ else: if pipe.getInterfaceName() != 'OpenGL': raise StandardError, "Couldn't get an OpenGL pipe." - self.win = base.openWindow(callbackWindowDict = callbackWindowDict, pipe = pipe, gsg = gsg, type = 'onscreen') - self.inputDevice = self.win.getInputDevice(0) + self.inputDevice = None + if hasattr(self.win, 'getInputDevice'): + self.inputDevice = self.win.getInputDevice(0) self.Bind(wx.EVT_SIZE, self.onSize) + self.Bind(wx.EVT_PAINT, self.onPaint) self.Bind(wx.EVT_IDLE, self.onIdle) - self.Bind(wx.EVT_LEFT_DOWN, lambda event: self.__buttonDown(MouseButton.one())) - self.Bind(wx.EVT_LEFT_UP, lambda event: self.__buttonUp(MouseButton.one())) - self.Bind(wx.EVT_MIDDLE_DOWN, lambda event: self.__buttonDown(MouseButton.two())) - self.Bind(wx.EVT_MIDDLE_UP, lambda event: self.__buttonUp(MouseButton.two())) - self.Bind(wx.EVT_RIGHT_DOWN, lambda event: self.__buttonDown(MouseButton.three())) - self.Bind(wx.EVT_RIGHT_UP, lambda event: self.__buttonUp(MouseButton.three())) - self.Bind(wx.EVT_MOTION, self.__mouseMotion) - self.Bind(wx.EVT_LEAVE_WINDOW, self.__mouseLeaveWindow) - self.Bind(wx.EVT_KEY_DOWN, self.__keyDown) - self.Bind(wx.EVT_KEY_UP, self.__keyUp) - self.Bind(wx.EVT_CHAR, self.__keystroke) + + if self.inputDevice: + self.Bind(wx.EVT_LEFT_DOWN, lambda event: self.__buttonDown(MouseButton.one())) + self.Bind(wx.EVT_LEFT_UP, lambda event: self.__buttonUp(MouseButton.one())) + self.Bind(wx.EVT_MIDDLE_DOWN, lambda event: self.__buttonDown(MouseButton.two())) + self.Bind(wx.EVT_MIDDLE_UP, lambda event: self.__buttonUp(MouseButton.two())) + self.Bind(wx.EVT_RIGHT_DOWN, lambda event: self.__buttonDown(MouseButton.three())) + self.Bind(wx.EVT_RIGHT_UP, lambda event: self.__buttonUp(MouseButton.three())) + self.Bind(wx.EVT_MOTION, self.__mouseMotion) + self.Bind(wx.EVT_LEAVE_WINDOW, self.__mouseLeaveWindow) + self.Bind(wx.EVT_KEY_DOWN, self.__keyDown) + self.Bind(wx.EVT_KEY_UP, self.__keyUp) + self.Bind(wx.EVT_CHAR, self.__keystroke) # This doesn't actually do anything, since wx won't call # EVT_CLOSE on a child window, only on the toplevel window @@ -263,7 +268,7 @@ else: def __renderCallback(self, data): cbType = data.getCallbackType() if cbType == CallbackGraphicsWindow.RCTBeginFrame: - if not self.IsShownOnScreen(): + if not self.visible or not self.IsShownOnScreen(): data.setRenderFlag(False) return self.SetCurrent() @@ -291,6 +296,14 @@ else: event.Skip() + def onPaint(self, event): + """ This is called whenever we get the fisrt paint event, + at which point we can conclude that the window has + actually been manifested onscreen. (In X11, there appears + to be no way to know this otherwise.) """ + self.visible = True + event.Skip() + def onIdle(self, event): size = None properties = self.win.getProperties() diff --git a/panda/src/glxdisplay/Sources.pp b/panda/src/glxdisplay/Sources.pp index 5382d24061..3f1fa32329 100644 --- a/panda/src/glxdisplay/Sources.pp +++ b/panda/src/glxdisplay/Sources.pp @@ -20,6 +20,8 @@ glxGraphicsWindow.h glxGraphicsWindow.cxx \ glxGraphicsStateGuardian.h glxGraphicsStateGuardian.I \ glxGraphicsStateGuardian.cxx \ + posixGraphicsStateGuardian.h posixGraphicsStateGuardian.I \ + posixGraphicsStateGuardian.cxx \ panda_glxext.h #define INSTALL_HEADERS \ diff --git a/panda/src/glxdisplay/config_glxdisplay.cxx b/panda/src/glxdisplay/config_glxdisplay.cxx index fc99763ab4..33028d2e9d 100644 --- a/panda/src/glxdisplay/config_glxdisplay.cxx +++ b/panda/src/glxdisplay/config_glxdisplay.cxx @@ -19,6 +19,7 @@ #include "glxGraphicsBuffer.h" #include "glxGraphicsWindow.h" #include "glxGraphicsStateGuardian.h" +#include "posixGraphicsStateGuardian.h" #include "graphicsPipeSelection.h" #include "dconfig.h" #include "pandaSystem.h" @@ -94,6 +95,7 @@ init_libglxdisplay() { glxGraphicsBuffer::init_type(); glxGraphicsWindow::init_type(); glxGraphicsStateGuardian::init_type(); + PosixGraphicsStateGuardian::init_type(); GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr(); selection->add_pipe_type(glxGraphicsPipe::get_class_type(), diff --git a/panda/src/glxdisplay/glxGraphicsPipe.cxx b/panda/src/glxdisplay/glxGraphicsPipe.cxx index 8ebb460df7..f745a66274 100644 --- a/panda/src/glxdisplay/glxGraphicsPipe.cxx +++ b/panda/src/glxdisplay/glxGraphicsPipe.cxx @@ -17,6 +17,7 @@ #include "glxGraphicsBuffer.h" #include "glxGraphicsPixmap.h" #include "glxGraphicsStateGuardian.h" +#include "posixGraphicsStateGuardian.h" #include "config_glxdisplay.h" #include "frameBufferProperties.h" @@ -217,5 +218,8 @@ make_output(const string &name, //////////////////////////////////////////////////////////////////// PT(GraphicsStateGuardian) glxGraphicsPipe:: make_callback_gsg(GraphicsEngine *engine) { - return new glxGraphicsStateGuardian(engine, this, NULL); + // We create a PosixGraphicsStateGuardian instead of a + // glxGraphicsStateGuardian, because the externally-created context + // might not have anything to do with the glx interface. + return new PosixGraphicsStateGuardian(engine, this); } diff --git a/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx b/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx index f1d2406fda..8470fe8d57 100644 --- a/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx +++ b/panda/src/glxdisplay/glxGraphicsStateGuardian.cxx @@ -30,7 +30,7 @@ TypeHandle glxGraphicsStateGuardian::_type_handle; glxGraphicsStateGuardian:: glxGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe, glxGraphicsStateGuardian *share_with) : - GLGraphicsStateGuardian(engine, pipe) + PosixGraphicsStateGuardian(engine, pipe) { _share_context=0; _context=0; @@ -53,7 +53,6 @@ glxGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe, _share_context = share_with->_context; } - _libgl_handle = NULL; _checked_get_proc_address = false; _glXGetProcAddress = NULL; _temp_context = (GLXContext)NULL; @@ -76,9 +75,6 @@ glxGraphicsStateGuardian:: glXDestroyContext(_display, _context); _context = (GLXContext)NULL; } - if (_libgl_handle != (void *)NULL) { - dlclose(_libgl_handle); - } } //////////////////////////////////////////////////////////////////// @@ -399,7 +395,7 @@ choose_pixel_format(const FrameBufferProperties &properties, //////////////////////////////////////////////////////////////////// void glxGraphicsStateGuardian:: reset() { - GLGraphicsStateGuardian::reset(); + PosixGraphicsStateGuardian::reset(); _supports_swap_control = has_extension("GLX_SGI_swap_control"); @@ -564,7 +560,7 @@ void glxGraphicsStateGuardian:: gl_flush() const { // This call requires synchronization with X. LightReMutexHolder holder(glxGraphicsPipe::_x_mutex); - GLGraphicsStateGuardian::gl_flush(); + PosixGraphicsStateGuardian::gl_flush(); } //////////////////////////////////////////////////////////////////// @@ -576,7 +572,7 @@ GLenum glxGraphicsStateGuardian:: gl_get_error() const { // This call requires synchronization with X. LightReMutexHolder holder(glxGraphicsPipe::_x_mutex); - return GLGraphicsStateGuardian::gl_get_error(); + return PosixGraphicsStateGuardian::gl_get_error(); } //////////////////////////////////////////////////////////////////// @@ -586,7 +582,7 @@ gl_get_error() const { //////////////////////////////////////////////////////////////////// void glxGraphicsStateGuardian:: query_gl_version() { - GLGraphicsStateGuardian::query_gl_version(); + PosixGraphicsStateGuardian::query_gl_version(); show_glx_client_string("GLX_VENDOR", GLX_VENDOR); show_glx_client_string("GLX_VERSION", GLX_VERSION); @@ -683,45 +679,8 @@ do_get_extension_func(const char *prefix, const char *name) { #endif // HAVE_GLXGETPROCADDRESS } - if (glx_get_os_address) { - // Otherwise, fall back to the OS-provided calls. - return get_system_func(fullname.c_str()); - } - - return NULL; -} - -//////////////////////////////////////////////////////////////////// -// Function: glxGraphicsStateGuardian::get_system_func -// Access: Private -// Description: Support for get_extension_func(), above, that uses -// system calls to find a GL or GLX function (in the -// absence of a working glxGetProcAddress() function to -// call). -//////////////////////////////////////////////////////////////////// -void *glxGraphicsStateGuardian:: -get_system_func(const char *name) { - if (_libgl_handle == (void *)NULL) { - // We open the current executable, rather than naming a particular - // library. Presumably libGL.so (or whatever the library should - // be called) is already available in the current executable - // address space, so this is more portable than insisting on a - // particular shared library name. - _libgl_handle = dlopen(NULL, RTLD_LAZY); - nassertr(_libgl_handle != (void *)NULL, NULL); - - // If that doesn't locate the symbol we expected, then fall back - // to loading the GL library by its usual name. - if (dlsym(_libgl_handle, name) == NULL) { - dlclose(_libgl_handle); - glxdisplay_cat.warning() - << name << " not found in executable; looking in libGL.so instead.\n"; - _libgl_handle = dlopen("libGL.so", RTLD_LAZY); - nassertr(_libgl_handle != (void *)NULL, NULL); - } - } - - return dlsym(_libgl_handle, name); + // Otherwise, fall back to the OS-provided calls. + return PosixGraphicsStateGuardian::do_get_extension_func(prefix, name); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/glxdisplay/glxGraphicsStateGuardian.h b/panda/src/glxdisplay/glxGraphicsStateGuardian.h index 220381a61d..f3f72f5b91 100644 --- a/panda/src/glxdisplay/glxGraphicsStateGuardian.h +++ b/panda/src/glxdisplay/glxGraphicsStateGuardian.h @@ -19,6 +19,7 @@ #include "glgsg.h" #include "glxGraphicsPipe.h" +#include "posixGraphicsStateGuardian.h" #if defined(GLX_VERSION_1_4) // If the system header files give us version 1.4, we can assume it's @@ -74,7 +75,7 @@ typedef void (* PFNGLXDESTROYPBUFFERPROC) (X11_Display *dpy, GLXPbuffer pbuf); // Description : A tiny specialization on GLGraphicsStateGuardian to // add some glx-specific information. //////////////////////////////////////////////////////////////////// -class glxGraphicsStateGuardian : public GLGraphicsStateGuardian { +class glxGraphicsStateGuardian : public PosixGraphicsStateGuardian { public: INLINE const FrameBufferProperties &get_fb_properties() const; void get_properties(FrameBufferProperties &properties, XVisualInfo *visual); @@ -134,7 +135,6 @@ protected: virtual void *do_get_extension_func(const char *prefix, const char *name); private: - void *get_system_func(const char *name); void show_glx_client_string(const string &name, int id); void show_glx_server_string(const string &name, int id); void choose_temp_visual(const FrameBufferProperties &properties); @@ -143,7 +143,6 @@ private: int _glx_version_major, _glx_version_minor; - void *_libgl_handle; bool _checked_get_proc_address; PFNGLXGETPROCADDRESSPROC _glXGetProcAddress; @@ -156,9 +155,9 @@ public: return _type_handle; } static void init_type() { - GLGraphicsStateGuardian::init_type(); + PosixGraphicsStateGuardian::init_type(); register_type(_type_handle, "glxGraphicsStateGuardian", - GLGraphicsStateGuardian::get_class_type()); + PosixGraphicsStateGuardian::get_class_type()); } virtual TypeHandle get_type() const { return get_class_type(); diff --git a/panda/src/glxdisplay/posixGraphicsStateGuardian.I b/panda/src/glxdisplay/posixGraphicsStateGuardian.I new file mode 100644 index 0000000000..52682680f0 --- /dev/null +++ b/panda/src/glxdisplay/posixGraphicsStateGuardian.I @@ -0,0 +1,13 @@ +// Filename: posixGraphicsStateGuardian.I +// Created by: drose (14Jan12) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// diff --git a/panda/src/glxdisplay/posixGraphicsStateGuardian.cxx b/panda/src/glxdisplay/posixGraphicsStateGuardian.cxx new file mode 100644 index 0000000000..cdba89853d --- /dev/null +++ b/panda/src/glxdisplay/posixGraphicsStateGuardian.cxx @@ -0,0 +1,99 @@ +// Filename: posixGraphicsStateGuardian.cxx +// Created by: drose (14Jan12) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "posixGraphicsStateGuardian.h" +#include "config_glxdisplay.h" +#include + +TypeHandle PosixGraphicsStateGuardian::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: PosixGraphicsStateGuardian::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +PosixGraphicsStateGuardian:: +PosixGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe) : + GLGraphicsStateGuardian(engine, pipe) +{ + _libgl_handle = NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: PosixGraphicsStateGuardian::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +PosixGraphicsStateGuardian:: +~PosixGraphicsStateGuardian() { + if (_libgl_handle != (void *)NULL) { + dlclose(_libgl_handle); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PosixGraphicsStateGuardian::do_get_extension_func +// Access: Public, Virtual +// Description: Returns the pointer to the GL extension function with +// the indicated name. It is the responsibility of the +// caller to ensure that the required extension is +// defined in the OpenGL runtime prior to calling this; +// it is an error to call this for a function that is +// not defined. +//////////////////////////////////////////////////////////////////// +void *PosixGraphicsStateGuardian:: +do_get_extension_func(const char *prefix, const char *name) { + nassertr(prefix != NULL, NULL); + nassertr(name != NULL, NULL); + string fullname = string(prefix) + string(name); + + if (glx_get_os_address) { + return get_system_func(fullname.c_str()); + } + + return NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: PosixGraphicsStateGuardian::get_system_func +// Access: Protected +// Description: Support for get_extension_func(), above, that uses +// system calls to find a GL or GLX function (in the +// absence of a working glxGetProcAddress() function to +// call). +//////////////////////////////////////////////////////////////////// +void *PosixGraphicsStateGuardian:: +get_system_func(const char *name) { + if (_libgl_handle == (void *)NULL) { + // We open the current executable, rather than naming a particular + // library. Presumably libGL.so (or whatever the library should + // be called) is already available in the current executable + // address space, so this is more portable than insisting on a + // particular shared library name. + _libgl_handle = dlopen(NULL, RTLD_LAZY); + nassertr(_libgl_handle != (void *)NULL, NULL); + + // If that doesn't locate the symbol we expected, then fall back + // to loading the GL library by its usual name. + if (dlsym(_libgl_handle, name) == NULL) { + dlclose(_libgl_handle); + glxdisplay_cat.warning() + << name << " not found in executable; looking in libGL.so instead.\n"; + _libgl_handle = dlopen("libGL.so", RTLD_LAZY); + nassertr(_libgl_handle != (void *)NULL, NULL); + } + } + + return dlsym(_libgl_handle, name); +} diff --git a/panda/src/glxdisplay/posixGraphicsStateGuardian.h b/panda/src/glxdisplay/posixGraphicsStateGuardian.h new file mode 100644 index 0000000000..950844951c --- /dev/null +++ b/panda/src/glxdisplay/posixGraphicsStateGuardian.h @@ -0,0 +1,61 @@ +// Filename: posixGraphicsStateGuardian.h +// Created by: drose (14Jan12) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#ifndef POSIXGRAPHICSSTATEGUARDIAN_H +#define POSIXGRAPHICSSTATEGUARDIAN_H + +#include "pandabase.h" + +#include "glgsg.h" + +//////////////////////////////////////////////////////////////////// +// Class : PosixGraphicsStateGuardian +// Description : This GSG is used only for CallbackGraphicsWindow +// (which might not be using the glx interfaces), to add +// the ability to peek in libGL.so to find the extension +// functions. +//////////////////////////////////////////////////////////////////// +class PosixGraphicsStateGuardian : public GLGraphicsStateGuardian { +public: + PosixGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe); + ~PosixGraphicsStateGuardian(); + +protected: + virtual void *do_get_extension_func(const char *prefix, const char *name); + void *get_system_func(const char *name); + +private: + void *_libgl_handle; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + GLGraphicsStateGuardian::init_type(); + register_type(_type_handle, "PosixGraphicsStateGuardian", + GLGraphicsStateGuardian::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +#include "posixGraphicsStateGuardian.I" + +#endif