mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
WindowHandle
This commit is contained in:
parent
5b96fb9cdf
commit
f46981eec9
@ -9,7 +9,7 @@
|
||||
#define BUILD_DIRECTORY $[HAVE_GL]
|
||||
|
||||
#define COMPONENT_LIBS \
|
||||
glgsg glxdisplay \
|
||||
glgsg x11display glxdisplay \
|
||||
wgldisplay osxdisplay
|
||||
|
||||
#define LOCAL_LIBS gsgbase display express
|
||||
|
@ -32,6 +32,7 @@
|
||||
graphicsDevice.h graphicsDevice.I \
|
||||
lru.h \
|
||||
parasiteBuffer.I parasiteBuffer.h \
|
||||
windowHandle.I windowHandle.h \
|
||||
windowProperties.I windowProperties.h \
|
||||
renderBuffer.h \
|
||||
stencilRenderStates.h \
|
||||
@ -59,6 +60,7 @@
|
||||
graphicsWindow.cxx graphicsWindowInputDevice.cxx \
|
||||
graphicsDevice.cxx \
|
||||
parasiteBuffer.cxx \
|
||||
windowHandle.cxx \
|
||||
windowProperties.cxx \
|
||||
lru.cxx \
|
||||
stencilRenderStates.cxx \
|
||||
@ -88,6 +90,7 @@
|
||||
graphicsDevice.I graphicsDevice.h \
|
||||
lru.h \
|
||||
parasiteBuffer.I parasiteBuffer.h \
|
||||
windowHandle.I windowHandle.h \
|
||||
windowProperties.I windowProperties.h \
|
||||
renderBuffer.h \
|
||||
stencilRenderStates.h \
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "pandaSystem.h"
|
||||
#include "stereoDisplayRegion.h"
|
||||
#include "subprocessWindow.h"
|
||||
#include "windowHandle.h"
|
||||
|
||||
ConfigureDef(config_display);
|
||||
NotifyCategoryDef(display, "");
|
||||
@ -421,6 +422,9 @@ init_libdisplay() {
|
||||
#ifdef SUPPORT_SUBPROCESS_WINDOW
|
||||
SubprocessWindow::init_type();
|
||||
#endif
|
||||
WindowHandle::init_type();
|
||||
WindowHandle::OSHandle::init_type();
|
||||
WindowHandle::IntHandle::init_type();
|
||||
|
||||
#if defined(HAVE_THREADS) && defined(DO_PIPELINING)
|
||||
PandaSystem *ps = PandaSystem::get_global_ptr();
|
||||
|
@ -1,10 +1,13 @@
|
||||
#include "standardMunger.cxx"
|
||||
#include "drawableRegion.cxx"
|
||||
#include "config_display.cxx"
|
||||
#include "displayInformation.cxx"
|
||||
#include "displayRegion.cxx"
|
||||
#include "displayRegionCullCallbackData.cxx"
|
||||
#include "displayRegionDrawCallbackData.cxx"
|
||||
#include "displaySearchParameters.cxx"
|
||||
#include "drawableRegion.cxx"
|
||||
#include "frameBufferProperties.cxx"
|
||||
#include "graphicsBuffer.cxx"
|
||||
#include "graphicsDevice.cxx"
|
||||
#include "graphicsEngine.cxx"
|
||||
#include "graphicsOutput.cxx"
|
||||
#include "graphicsPipe.cxx"
|
||||
#include "graphicsStateGuardian.cxx"
|
||||
#include "graphicsWindowInputDevice.cxx"
|
||||
|
||||
|
@ -1,16 +1,13 @@
|
||||
#include "config_display.cxx"
|
||||
#include "frameBufferProperties.cxx"
|
||||
#include "graphicsPipeSelection.cxx"
|
||||
#include "graphicsStateGuardian.cxx"
|
||||
#include "graphicsThreadingModel.cxx"
|
||||
#include "graphicsDevice.cxx"
|
||||
#include "windowProperties.cxx"
|
||||
#include "graphicsWindow.cxx"
|
||||
#include "graphicsBuffer.cxx"
|
||||
#include "graphicsOutput.cxx"
|
||||
#include "parasiteBuffer.cxx"
|
||||
#include "graphicsWindowInputDevice.cxx"
|
||||
#include "lru.cxx"
|
||||
#include "parasiteBuffer.cxx"
|
||||
#include "standardMunger.cxx"
|
||||
#include "stencilRenderStates.cxx"
|
||||
#include "displaySearchParameters.cxx"
|
||||
#include "displayInformation.cxx"
|
||||
#include "stereoDisplayRegion.cxx"
|
||||
#include "subprocessWindow.cxx"
|
||||
#include "windowHandle.cxx"
|
||||
#include "windowProperties.cxx"
|
||||
|
@ -143,11 +143,33 @@ make_output(const string &name,
|
||||
// Access: Published
|
||||
// Description: Gets the pipe's DisplayInformation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DisplayInformation * GraphicsPipe::
|
||||
DisplayInformation *GraphicsPipe::
|
||||
get_display_information() {
|
||||
return _display_information;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsPipe::make_int_window_handle
|
||||
// Access: Published
|
||||
// Description: Creates a WindowHandle by interpreting the indicated
|
||||
// integer value as an OS-specific pointer, e.g. to a
|
||||
// HWND or a Window object, if this makes sense for the
|
||||
// current OS. Returns the WindowHandle if successful,
|
||||
// or NULL if not.
|
||||
//
|
||||
// This method exists primarily for the benefit of
|
||||
// Python, which likes to pass around pointers as
|
||||
// integers. For other languages, see the OS-specific
|
||||
// make_window_handle() method, which is defined for
|
||||
// each particular OS-specific GraphicsPipe type. It is
|
||||
// preferable to use make_window_handle() instead of
|
||||
// make_int_window_handle().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WindowHandle *GraphicsPipe::
|
||||
make_int_window_handle(size_t window) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsPipe::lookup_cpu_data
|
||||
// Access: Public, Virtual
|
||||
|
@ -31,6 +31,7 @@ class GraphicsStateGuardian;
|
||||
class FrameBufferProperties;
|
||||
class WindowProperties;
|
||||
class Texture;
|
||||
class WindowHandle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GraphicsPipe
|
||||
@ -100,6 +101,7 @@ PUBLISHED:
|
||||
virtual void lookup_cpu_data();
|
||||
|
||||
virtual string get_interface_name() const=0;
|
||||
virtual WindowHandle *make_int_window_handle(size_t window);
|
||||
|
||||
public:
|
||||
enum PreferredWindowThread {
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "config_display.h"
|
||||
#include "typeRegistry.h"
|
||||
#include "pset.h"
|
||||
#include "config_util.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -48,6 +48,8 @@
|
||||
#include "texGenAttrib.h"
|
||||
#include "shaderGenerator.h"
|
||||
#include "lightLensNode.h"
|
||||
#include "colorAttrib.h"
|
||||
#include "colorScaleAttrib.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits.h>
|
||||
|
@ -40,6 +40,22 @@ is_fullscreen() const {
|
||||
return _properties.get_fullscreen();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::get_window_handle
|
||||
// Access: Published
|
||||
// Description: Returns the WindowHandle corresponding to this window
|
||||
// on the desktop. This is mainly useful for
|
||||
// communicating with external libraries. Use
|
||||
// window_handle->get_os_handle()->get_handle(), or
|
||||
// window_handle->get_string_handle(), to get the actual
|
||||
// OS-specific window handle object, whatever type that
|
||||
// might be.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE WindowHandle *GraphicsWindow::
|
||||
get_window_handle() const {
|
||||
return _window_handle;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::add_input_device
|
||||
// Access: Protected
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "lightMutex.h"
|
||||
#include "lightReMutex.h"
|
||||
#include "pvector.h"
|
||||
#include "windowHandle.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GraphicsWindow
|
||||
@ -64,6 +65,8 @@ PUBLISHED:
|
||||
void set_close_request_event(const string &close_request_event);
|
||||
string get_close_request_event() const;
|
||||
|
||||
INLINE WindowHandle *get_window_handle() const;
|
||||
|
||||
// Mouse and keyboard routines
|
||||
int get_num_input_devices() const;
|
||||
string get_input_device_name(int device) const;
|
||||
@ -128,6 +131,7 @@ protected:
|
||||
|
||||
protected:
|
||||
WindowProperties _properties;
|
||||
PT(WindowHandle) _window_handle;
|
||||
|
||||
private:
|
||||
LightReMutex _properties_lock;
|
||||
|
87
panda/src/display/windowHandle.I
Normal file
87
panda/src/display/windowHandle.I
Normal file
@ -0,0 +1,87 @@
|
||||
// Filename: windowHandle.I
|
||||
// Created by: drose (30Sep09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE WindowHandle::
|
||||
WindowHandle(OSHandle *os_handle) : _os_handle(os_handle) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE WindowHandle::
|
||||
WindowHandle(const WindowHandle ©) : _os_handle(copy._os_handle) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::get_os_handle
|
||||
// Access: Published
|
||||
// Description: Returns the OS-specific handle stored internally to
|
||||
// the WindowHandle wrapper.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE WindowHandle::OSHandle *WindowHandle::
|
||||
get_os_handle() const {
|
||||
return _os_handle;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::set_os_handle
|
||||
// Access: Published
|
||||
// Description: Changes the OS-specific handle stored internally to
|
||||
// the WindowHandle wrapper.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void WindowHandle::
|
||||
set_os_handle(OSHandle *os_handle) {
|
||||
_os_handle = os_handle;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::OSHandle::Constructor
|
||||
// Access: Protected
|
||||
// Description: The base class of OSHandle doesn't have a usable
|
||||
// constructor. Always construct an instance of some
|
||||
// specialized type, that stores the appropriate kind of
|
||||
// window handle for each OS.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE WindowHandle::OSHandle::
|
||||
OSHandle() {
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::IntHandle::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE WindowHandle::IntHandle::
|
||||
IntHandle(size_t handle) : _handle(handle) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::IntHandle::get_handle
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE size_t WindowHandle::IntHandle::
|
||||
get_handle() const {
|
||||
return _handle;
|
||||
}
|
145
panda/src/display/windowHandle.cxx
Normal file
145
panda/src/display/windowHandle.cxx
Normal file
@ -0,0 +1,145 @@
|
||||
// Filename: windowHandle.cxx
|
||||
// Created by: drose (30Sep09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "windowHandle.h"
|
||||
|
||||
TypeHandle WindowHandle::_type_handle;
|
||||
TypeHandle WindowHandle::OSHandle::_type_handle;
|
||||
TypeHandle WindowHandle::IntHandle::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WindowHandle::
|
||||
~WindowHandle() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::get_string_handle
|
||||
// Access: Published
|
||||
// Description: Returns the OS-specific handle in a string
|
||||
// representation, whatever that means for a particular
|
||||
// OS. Typically this is a pointer value, represented
|
||||
// as a decimal integer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string WindowHandle::
|
||||
get_string_handle() const {
|
||||
ostringstream strm;
|
||||
if (_os_handle != NULL) {
|
||||
_os_handle->format_string_handle(strm);
|
||||
}
|
||||
return strm.str();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowHandle::
|
||||
output(ostream &out) const {
|
||||
if (_os_handle == NULL) {
|
||||
out << "(null)";
|
||||
} else {
|
||||
out << *_os_handle;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::attach_child
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called on a parent handle to indicate a child
|
||||
// window's intention to attach itself.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowHandle::
|
||||
attach_child(WindowHandle *child) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::detach_child
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called on a parent handle to indicate a child
|
||||
// window's intention to detach itself.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowHandle::
|
||||
detach_child(WindowHandle *child) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::set_keyboard_focus
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called on a parent handle to indicate a child
|
||||
// window's intention to set itself as the recipient of
|
||||
// keyboard events.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowHandle::
|
||||
set_keyboard_focus(WindowHandle *child) {
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::OSHandle::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WindowHandle::OSHandle::
|
||||
~OSHandle() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::OSHandle::format_string_handle
|
||||
// Access: Published, Virtual
|
||||
// Description: Writes the OS-specific value to the indicated stream
|
||||
// in whatever representation makes sense, but it should
|
||||
// format it as a decimal integer if possible, for
|
||||
// consistency between platforms.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowHandle::OSHandle::
|
||||
format_string_handle(ostream &out) const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::OSHandle::output
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowHandle::OSHandle::
|
||||
output(ostream &out) const {
|
||||
out << "(no type)";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::IntHandle::format_string_handle
|
||||
// Access: Published, Virtual
|
||||
// Description: Writes the OS-specific value to the indicated stream
|
||||
// in whatever representation makes sense, but it should
|
||||
// format it as a decimal integer if possible, for
|
||||
// consistency between platforms.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowHandle::IntHandle::
|
||||
format_string_handle(ostream &out) const {
|
||||
out << _handle;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowHandle::IntHandle::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WindowHandle::IntHandle::
|
||||
output(ostream &out) const {
|
||||
out << _handle;
|
||||
}
|
163
panda/src/display/windowHandle.h
Normal file
163
panda/src/display/windowHandle.h
Normal file
@ -0,0 +1,163 @@
|
||||
// Filename: windowHandle.h
|
||||
// Created by: drose (30Sep09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 WINDOWHANDLE_H
|
||||
#define WINDOWHANDLE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "typedReferenceCount.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : WindowHandle
|
||||
// Description : This object represents a window on the desktop, not
|
||||
// necessarily a Panda window. This structure can be
|
||||
// assigned to a WindowProperties to indicate a parent
|
||||
// window.
|
||||
//
|
||||
// It also has callbacks so the Panda window can
|
||||
// communicate with its parent window, which is
|
||||
// particularly important when running embedded in a
|
||||
// browser.
|
||||
//
|
||||
// To create a WindowHandle, you would typically call
|
||||
// GraphicsPipe::make_window_handle, for the particular
|
||||
// GraphicsPipe that you have constructed. (Each
|
||||
// OS-specific GraphicsPipe has a make_window_handle()
|
||||
// method that receives an OS-specific window handle,
|
||||
// whatever that means for a particular OS, and creates
|
||||
// a WindowHandle object wrapping it.)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_DISPLAY WindowHandle : public TypedReferenceCount {
|
||||
PUBLISHED:
|
||||
class OSHandle;
|
||||
|
||||
INLINE WindowHandle(OSHandle *os_handle);
|
||||
INLINE WindowHandle(const WindowHandle ©);
|
||||
virtual ~WindowHandle();
|
||||
|
||||
INLINE OSHandle *get_os_handle() const;
|
||||
INLINE void set_os_handle(OSHandle *os_handle);
|
||||
|
||||
string get_string_handle() const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
||||
// This internal pointer within WindowHandle stores the actual
|
||||
// OS-specific window handle type, whatever type that is. It is
|
||||
// subclassed for each OS.
|
||||
class OSHandle : public TypedReferenceCount {
|
||||
protected:
|
||||
INLINE OSHandle();
|
||||
|
||||
PUBLISHED:
|
||||
virtual ~OSHandle();
|
||||
virtual void format_string_handle(ostream &out) const;
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedReferenceCount::init_type();
|
||||
register_type(_type_handle, "WindowHandle::OSHandle",
|
||||
TypedReferenceCount::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;
|
||||
};
|
||||
|
||||
// This class only exists for backward compatibility; it stores the
|
||||
// OS handle as a size_t object, as the WindowProperties object did
|
||||
// historically. New code should use
|
||||
// GraphicsPipe::make_window_handle() instead of this.
|
||||
class IntHandle : public OSHandle {
|
||||
PUBLISHED:
|
||||
INLINE IntHandle(size_t handle);
|
||||
virtual void format_string_handle(ostream &out) const;
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
INLINE size_t get_handle() const;
|
||||
|
||||
private:
|
||||
size_t _handle;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
OSHandle::init_type();
|
||||
register_type(_type_handle, "WindowHandle::IntHandle",
|
||||
OSHandle::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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
// Callbacks for communication with the parent window.
|
||||
virtual void attach_child(WindowHandle *child);
|
||||
virtual void detach_child(WindowHandle *child);
|
||||
|
||||
virtual void set_keyboard_focus(WindowHandle *child);
|
||||
|
||||
protected:
|
||||
PT(OSHandle) _os_handle;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedReferenceCount::init_type();
|
||||
register_type(_type_handle, "WindowHandle",
|
||||
TypedReferenceCount::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 "windowHandle.I"
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const WindowHandle &handle) {
|
||||
handle.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const WindowHandle::OSHandle &handle) {
|
||||
handle.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif
|
@ -803,34 +803,59 @@ clear_mouse_mode() {
|
||||
// Function: WindowProperties::set_parent_window
|
||||
// Access: Published
|
||||
// Description: Specifies the window that this window should be
|
||||
// attached to. If this is zero or unspecified, the
|
||||
// window will be created as a toplevel window on the
|
||||
// desktop; if this is nonzero, the window will be bound
|
||||
// as a child window to the indicated parent window.
|
||||
// attached to.
|
||||
//
|
||||
// The actual value for "parent" is platform-specific.
|
||||
// On Windows, it is the HWND of the parent window, cast
|
||||
// to an unsigned integer. On X11, it is the Window
|
||||
// pointer of the parent window, similarly cast (yes,
|
||||
// it's a portability issue).
|
||||
// This is a deprecated variant on this method, and
|
||||
// exists only for backward compatibility. Future code
|
||||
// should use the version of set_parent_window() below
|
||||
// that receives a WindowHandle object; that interface
|
||||
// is much more robust.
|
||||
//
|
||||
// On OSX, this is the NSWindow pointer, though there
|
||||
// appear to be some compatibility issues (OSX doesn't
|
||||
// easily support the parent-window model). On OSX,
|
||||
// consider using subprocess_window instead.
|
||||
// In this deprecated variant, the actual value for
|
||||
// "parent" is platform-specific. On Windows, it is the
|
||||
// HWND of the parent window, cast to an unsigned
|
||||
// integer. On X11, it is the Window pointer of the
|
||||
// parent window, similarly cast. On OSX, this is the
|
||||
// NSWindow pointer, which doesn't appear to work at
|
||||
// all.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void WindowProperties::
|
||||
set_parent_window(size_t parent) {
|
||||
_parent_window=parent;
|
||||
PT(WindowHandle) handle = new WindowHandle(new WindowHandle::IntHandle(parent));
|
||||
set_parent_window(handle);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowProperties::set_parent_window
|
||||
// Access: Published
|
||||
// Description: Specifies the window that this window should be
|
||||
// attached to. If this is NULL or unspecified, the
|
||||
// window will be created as a toplevel window on the
|
||||
// desktop; if this is non-NULL, the window will be
|
||||
// bound as a child window to the indicated parent
|
||||
// window.
|
||||
//
|
||||
// You should use GraphicsPipe::make_window_handle() to
|
||||
// create an instance of a WindowHandle object given an
|
||||
// appropriate OS-specific window handle representation.
|
||||
// Each OS-specific GraphicsPipe class defines a
|
||||
// make_window_handle() method that returns an
|
||||
// appropriate WindowHandle object to wrap the
|
||||
// particular OS-specific representation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void WindowProperties::
|
||||
set_parent_window(WindowHandle *parent_window) {
|
||||
_parent_window = parent_window;
|
||||
_specified |= S_parent_window;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WindowProperties::get_parent_window
|
||||
// Access: Published
|
||||
// Description: Returns the parent window specification.
|
||||
// Description: Returns the parent window specification, or NULL if
|
||||
// there is no parent window specified.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE size_t WindowProperties::
|
||||
INLINE WindowHandle *WindowProperties::
|
||||
get_parent_window() const {
|
||||
return _parent_window;
|
||||
}
|
||||
@ -853,7 +878,7 @@ has_parent_window() const {
|
||||
INLINE void WindowProperties::
|
||||
clear_parent_window() {
|
||||
_specified &= ~S_parent_window;
|
||||
_parent_window = (size_t)NULL;
|
||||
_parent_window = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "pandabase.h"
|
||||
#include "filename.h"
|
||||
#include "pnotify.h"
|
||||
#include "windowHandle.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : WindowProperties
|
||||
@ -131,7 +132,8 @@ PUBLISHED:
|
||||
INLINE void clear_z_order();
|
||||
|
||||
INLINE void set_parent_window(size_t parent);
|
||||
INLINE size_t get_parent_window() const;
|
||||
INLINE void set_parent_window(WindowHandle *parent_window);
|
||||
INLINE WindowHandle *get_parent_window() const;
|
||||
INLINE bool has_parent_window() const;
|
||||
INLINE void clear_parent_window();
|
||||
|
||||
@ -193,7 +195,7 @@ private:
|
||||
Filename _icon_filename;
|
||||
ZOrder _z_order;
|
||||
unsigned int _flags;
|
||||
size_t _parent_window; // a HWND or WindowRef or ..
|
||||
PT(WindowHandle) _parent_window;
|
||||
Filename _subprocess_window;
|
||||
};
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#define USE_PACKAGES gles egl x11
|
||||
#define EXTRA_CDEFS OPENGLES_1
|
||||
#define LOCAL_LIBS \
|
||||
glesgsg
|
||||
glesgsg x11display
|
||||
|
||||
#define SOURCES \
|
||||
config_egldisplay.cxx config_egldisplay.h \
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "textEncoder.h"
|
||||
#include "throw_event.h"
|
||||
#include "lightReMutexHolder.h"
|
||||
#include "x11GraphicsPipe.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
@ -664,12 +665,25 @@ open_window() {
|
||||
if (!_properties.has_size()) {
|
||||
_properties.set_size(100, 100);
|
||||
}
|
||||
|
||||
Window root_window;
|
||||
if (!_properties.has_parent_window()) {
|
||||
root_window = egl_pipe->get_root();
|
||||
} else {
|
||||
root_window = (Window) _properties.get_parent_window();
|
||||
|
||||
Window parent_window = egl_pipe->get_root();
|
||||
WindowHandle *window_handle = _properties.get_parent_window();
|
||||
if (window_handle != NULL) {
|
||||
egldisplay_cat.info()
|
||||
<< "Got parent_window " << *window_handle << "\n";
|
||||
WindowHandle::OSHandle *os_handle = window_handle->get_os_handle();
|
||||
if (os_handle != NULL) {
|
||||
egldisplay_cat.info()
|
||||
<< "os_handle type " << os_handle->get_type() << "\n";
|
||||
|
||||
if (os_handle->is_of_type(x11GraphicsPipe::x11Handle::get_class_type())) {
|
||||
x11GraphicsPipe::x11Handle *x11_handle = DCAST(x11GraphicsPipe::x11Handle, os_handle);
|
||||
parent_window = x11_handle->get_handle();
|
||||
} else if (os_handle->is_of_type(WindowHandle::IntHandle::get_class_type())) {
|
||||
WindowHandle::IntHandle *int_handle = DCAST(WindowHandle::IntHandle, os_handle);
|
||||
parent_window = (Window)int_handle->get_handle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setup_colormap(visual_info);
|
||||
@ -693,7 +707,7 @@ open_window() {
|
||||
CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
|
||||
|
||||
_xwindow = XCreateWindow
|
||||
(_display, root_window,
|
||||
(_display, parent_window,
|
||||
_properties.get_x_origin(), _properties.get_y_origin(),
|
||||
_properties.get_x_size(), _properties.get_y_size(),
|
||||
0, depth, InputOutput, visual, attrib_mask, &wa);
|
||||
|
@ -196,11 +196,24 @@ open_window() {
|
||||
_properties.set_size(100, 100);
|
||||
}
|
||||
|
||||
Window root_window;
|
||||
if (!_properties.has_parent_window()) {
|
||||
root_window = glx_pipe->get_root();
|
||||
} else {
|
||||
root_window = (Window)_properties.get_parent_window();
|
||||
Window parent_window = glx_pipe->get_root();
|
||||
WindowHandle *window_handle = _properties.get_parent_window();
|
||||
if (window_handle != NULL) {
|
||||
glxdisplay_cat.info()
|
||||
<< "Got parent_window " << *window_handle << "\n";
|
||||
WindowHandle::OSHandle *os_handle = window_handle->get_os_handle();
|
||||
if (os_handle != NULL) {
|
||||
glxdisplay_cat.info()
|
||||
<< "os_handle type " << os_handle->get_type() << "\n";
|
||||
|
||||
if (os_handle->is_of_type(x11GraphicsPipe::x11Handle::get_class_type())) {
|
||||
x11GraphicsPipe::x11Handle *x11_handle = DCAST(x11GraphicsPipe::x11Handle, os_handle);
|
||||
parent_window = x11_handle->get_handle();
|
||||
} else if (os_handle->is_of_type(WindowHandle::IntHandle::get_class_type())) {
|
||||
WindowHandle::IntHandle *int_handle = DCAST(WindowHandle::IntHandle, os_handle);
|
||||
parent_window = (Window)int_handle->get_handle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_GLXFBCONFIG
|
||||
@ -232,7 +245,7 @@ open_window() {
|
||||
CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
|
||||
|
||||
_xwindow = XCreateWindow
|
||||
(_display, root_window,
|
||||
(_display, parent_window,
|
||||
_properties.get_x_origin(), _properties.get_y_origin(),
|
||||
_properties.get_x_size(), _properties.get_y_size(),
|
||||
0, depth, InputOutput, visual, attrib_mask, &wa);
|
||||
|
@ -36,7 +36,7 @@ ThreadSimpleImpl(Thread *parent_obj) :
|
||||
_unique_id = _next_unique_id;
|
||||
++_next_unique_id;
|
||||
|
||||
_status = S_new;
|
||||
_status = TS_new;
|
||||
_joinable = false;
|
||||
_priority = TP_normal;
|
||||
_priority_weight = 1.0;
|
||||
@ -63,7 +63,7 @@ ThreadSimpleImpl::
|
||||
thread_cat.debug()
|
||||
<< "Deleting thread " << _parent_obj->get_name() << "\n";
|
||||
}
|
||||
nassertv(_status != S_running);
|
||||
nassertv(_status != TS_running);
|
||||
|
||||
if (_stack != (void *)NULL) {
|
||||
memory_hook->mmap_free(_stack, _stack_size);
|
||||
@ -80,7 +80,7 @@ ThreadSimpleImpl::
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ThreadSimpleImpl::
|
||||
setup_main_thread() {
|
||||
_status = S_running;
|
||||
_status = TS_running;
|
||||
_priority = TP_normal;
|
||||
_priority_weight = _manager->_simple_thread_normal_weight;
|
||||
|
||||
@ -98,14 +98,14 @@ start(ThreadPriority priority, bool joinable) {
|
||||
thread_cat.debug() << "Starting " << *_parent_obj << "\n";
|
||||
}
|
||||
|
||||
nassertr(_status == S_new, false);
|
||||
nassertr(_status == TS_new, false);
|
||||
|
||||
nassertr(_stack == NULL, false);
|
||||
_stack_size = memory_hook->round_up_to_page_size((size_t)thread_stack_size);
|
||||
_stack = (unsigned char *)memory_hook->mmap_alloc(_stack_size, true);
|
||||
|
||||
_joinable = joinable;
|
||||
_status = S_running;
|
||||
_status = TS_running;
|
||||
_priority = priority;
|
||||
|
||||
switch (priority) {
|
||||
@ -152,7 +152,7 @@ start(ThreadPriority priority, bool joinable) {
|
||||
void ThreadSimpleImpl::
|
||||
join() {
|
||||
nassertv(_joinable);
|
||||
if (_status == S_running) {
|
||||
if (_status == TS_running) {
|
||||
ThreadSimpleImpl *thread = _manager->get_current_thread();
|
||||
if (thread != this) {
|
||||
_joining_threads.push_back(thread);
|
||||
@ -256,7 +256,7 @@ begin_thread() {
|
||||
_parent_obj->thread_main();
|
||||
|
||||
// Now we have completed the thread.
|
||||
_status = S_finished;
|
||||
_status = TS_finished;
|
||||
|
||||
// Any threads that were waiting to join with this thread now become ready.
|
||||
JoiningThreads::iterator jti;
|
||||
|
@ -93,18 +93,18 @@ private:
|
||||
void begin_thread();
|
||||
|
||||
private:
|
||||
enum Status {
|
||||
S_new,
|
||||
S_running,
|
||||
S_finished,
|
||||
S_killed,
|
||||
enum ThreadStatus {
|
||||
TS_new,
|
||||
TS_running,
|
||||
TS_finished,
|
||||
TS_killed,
|
||||
};
|
||||
|
||||
static int _next_unique_id;
|
||||
int _unique_id;
|
||||
Thread *_parent_obj;
|
||||
bool _joinable;
|
||||
Status _status;
|
||||
ThreadStatus _status;
|
||||
ThreadPriority _priority;
|
||||
|
||||
// The relative weight of this thread, relative to other threads, in
|
||||
|
@ -855,7 +855,7 @@ kill_non_joinable(ThreadSimpleManager::FifoThreads &threads) {
|
||||
thread_cat.debug()
|
||||
<< "Killing " << *thread->_parent_obj << "\n";
|
||||
}
|
||||
thread->_status = ThreadSimpleImpl::S_killed;
|
||||
thread->_status = ThreadSimpleImpl::TS_killed;
|
||||
enqueue_finished(thread);
|
||||
}
|
||||
}
|
||||
@ -882,7 +882,7 @@ kill_non_joinable(ThreadSimpleManager::Sleeping &threads) {
|
||||
thread_cat.debug()
|
||||
<< "Killing " << *thread->_parent_obj << "\n";
|
||||
}
|
||||
thread->_status = ThreadSimpleImpl::S_killed;
|
||||
thread->_status = ThreadSimpleImpl::TS_killed;
|
||||
enqueue_finished(thread);
|
||||
}
|
||||
}
|
||||
|
@ -510,13 +510,27 @@ open_window() {
|
||||
if (!_properties.has_size()) {
|
||||
_properties.set_size(100, 100);
|
||||
}
|
||||
|
||||
Window root_window;
|
||||
if (!_properties.has_parent_window()) {
|
||||
root_window = tinyx_pipe->get_root();
|
||||
} else {
|
||||
root_window = (Window)_properties.get_parent_window();
|
||||
|
||||
Window parent_window = tinyx_pipe->get_root();
|
||||
WindowHandle *window_handle = _properties.get_parent_window();
|
||||
if (window_handle != NULL) {
|
||||
tinydisplay_cat.info()
|
||||
<< "Got parent_window " << *window_handle << "\n";
|
||||
WindowHandle::OSHandle *os_handle = window_handle->get_os_handle();
|
||||
if (os_handle != NULL) {
|
||||
tinydisplay_cat.info()
|
||||
<< "os_handle type " << os_handle->get_type() << "\n";
|
||||
|
||||
if (os_handle->is_of_type(x11GraphicsPipe::x11Handle::get_class_type())) {
|
||||
x11GraphicsPipe::x11Handle *x11_handle = DCAST(x11GraphicsPipe::x11Handle, os_handle);
|
||||
parent_window = x11_handle->get_handle();
|
||||
} else if (os_handle->is_of_type(WindowHandle::IntHandle::get_class_type())) {
|
||||
WindowHandle::IntHandle *int_handle = DCAST(WindowHandle::IntHandle, os_handle);
|
||||
parent_window = (Window)int_handle->get_handle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setup_colormap(visual_info);
|
||||
|
||||
_event_mask =
|
||||
@ -538,7 +552,7 @@ open_window() {
|
||||
CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
|
||||
|
||||
_xwindow = XCreateWindow
|
||||
(_display, root_window,
|
||||
(_display, parent_window,
|
||||
_properties.get_x_origin(), _properties.get_y_origin(),
|
||||
_properties.get_x_size(), _properties.get_y_size(),
|
||||
0, _depth, InputOutput, _visual, attrib_mask, &wa);
|
||||
|
@ -78,5 +78,6 @@ init_libx11display() {
|
||||
initialized = true;
|
||||
|
||||
x11GraphicsPipe::init_type();
|
||||
x11GraphicsPipe::x11Handle::init_type();
|
||||
x11GraphicsWindow::init_type();
|
||||
}
|
||||
|
@ -70,3 +70,22 @@ get_hidden_cursor() {
|
||||
}
|
||||
return _hidden_cursor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: x11GraphicsPipe::x11Handle::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE x11GraphicsPipe::x11Handle::
|
||||
x11Handle(Window handle) : _handle(handle) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: x11GraphicsPipe::x11Handle::get_handle
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Window x11GraphicsPipe::x11Handle::
|
||||
get_handle() const {
|
||||
return _handle;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "frameBufferProperties.h"
|
||||
|
||||
TypeHandle x11GraphicsPipe::_type_handle;
|
||||
TypeHandle x11GraphicsPipe::x11Handle::_type_handle;
|
||||
|
||||
bool x11GraphicsPipe::_error_handlers_installed = false;
|
||||
x11GraphicsPipe::ErrorHandlerFunc *x11GraphicsPipe::_prev_error_handler;
|
||||
@ -131,6 +132,40 @@ x11GraphicsPipe::
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: x11GraphicsPipe::make_window_handle
|
||||
// Access: Public
|
||||
// Description: Constructs a new WindowHandle object that
|
||||
// encapsulates a window with the indicated Window
|
||||
// handle.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WindowHandle *x11GraphicsPipe::
|
||||
make_window_handle(Window window) {
|
||||
return new WindowHandle(new x11Handle(window));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: x11GraphicsPipe::make_int_window_handle
|
||||
// Access: Public, Virtual
|
||||
// Description: Creates a WindowHandle by interpreting the indicated
|
||||
// integer value as an OS-specific pointer, e.g. to a
|
||||
// HWND or a Window object, if this makes sense for the
|
||||
// current OS. Returns the WindowHandle if successful,
|
||||
// or NULL if not.
|
||||
//
|
||||
// This method exists primarily for the benefit of
|
||||
// Python, which likes to pass around pointers as
|
||||
// integers. For other languages, see the OS-specific
|
||||
// make_window_handle() method, which is defined for
|
||||
// each particular OS-specific GraphicsPipe type. It is
|
||||
// preferable to use make_window_handle() instead of
|
||||
// make_int_window_handle().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WindowHandle *x11GraphicsPipe::
|
||||
make_int_window_handle(size_t window) {
|
||||
return make_window_handle((Window)window);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: x11GraphicsPipe::get_preferred_window_thread
|
||||
// Access: Public, Virtual
|
||||
@ -254,3 +289,26 @@ io_error_handler(Display *display) {
|
||||
// anyway. Sigh. Very poor design on X's part.
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: x11GraphicsPipe::x11Handle::format_string_handle
|
||||
// Access: Published, Virtual
|
||||
// Description: Writes the OS-specific value to the indicated stream
|
||||
// in whatever representation makes sense, but it should
|
||||
// format it as a decimal integer if possible, for
|
||||
// consistency between platforms.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void x11GraphicsPipe::x11Handle::
|
||||
format_string_handle(ostream &out) const {
|
||||
out << (size_t)_handle;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: x11GraphicsPipe::x11Handle::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void x11GraphicsPipe::x11Handle::
|
||||
output(ostream &out) const {
|
||||
out << (void *)_handle;
|
||||
}
|
||||
|
@ -20,23 +20,12 @@
|
||||
#include "graphicsPipe.h"
|
||||
#include "lightMutex.h"
|
||||
#include "lightReMutex.h"
|
||||
#include "windowHandle.h"
|
||||
|
||||
class FrameBufferProperties;
|
||||
|
||||
#ifdef CPPPARSER
|
||||
// A simple hack so interrogate can parse this file.
|
||||
typedef int Display;
|
||||
typedef int Window;
|
||||
typedef int XErrorEvent;
|
||||
typedef int XVisualInfo;
|
||||
typedef int Atom;
|
||||
typedef int Cursor;
|
||||
typedef int XIM;
|
||||
typedef int XIC;
|
||||
#else
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : x11GraphicsPipe
|
||||
@ -55,6 +44,40 @@ public:
|
||||
|
||||
INLINE Cursor get_hidden_cursor();
|
||||
|
||||
WindowHandle *make_window_handle(Window window);
|
||||
virtual WindowHandle *make_int_window_handle(size_t window);
|
||||
|
||||
public:
|
||||
// Wraps a WindowHandle type for X11.
|
||||
class x11Handle : public WindowHandle::OSHandle {
|
||||
PUBLISHED:
|
||||
INLINE x11Handle(Window handle);
|
||||
virtual void format_string_handle(ostream &out) const;
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
INLINE Window get_handle() const;
|
||||
|
||||
private:
|
||||
Window _handle;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
OSHandle::init_type();
|
||||
register_type(_type_handle, "x11GraphicsPipe::x11Handle",
|
||||
OSHandle::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;
|
||||
};
|
||||
|
||||
public:
|
||||
virtual PreferredWindowThread get_preferred_window_thread() const;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user