further robustness for WxPandaWindow on Linux

This commit is contained in:
David Rose 2012-01-14 19:20:56 +00:00
parent fdca621619
commit 1fd8a621ff
9 changed files with 220 additions and 68 deletions

View File

@ -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()

View File

@ -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 \

View File

@ -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(),

View File

@ -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);
}

View File

@ -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);
}
////////////////////////////////////////////////////////////////////

View File

@ -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();

View File

@ -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."
//
////////////////////////////////////////////////////////////////////

View File

@ -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 <dlfcn.h>
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);
}

View File

@ -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