mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 17:35:34 -04:00
More Linux work - the plugin now really works on Linux.
This commit is contained in:
parent
d02b9bd34b
commit
474b738f8b
@ -3,9 +3,15 @@
|
||||
#define BUILD_DIRECTORY $[and $[HAVE_P3D_PLUGIN],$[HAVE_TINYXML],$[HAVE_OPENSSL],$[HAVE_ZLIB]]
|
||||
|
||||
#begin lib_target
|
||||
#define USE_PACKAGES tinyxml openssl zlib jpeg
|
||||
#define USE_PACKAGES tinyxml openssl zlib jpeg x11
|
||||
#define TARGET p3d_plugin
|
||||
#define LIB_PREFIX
|
||||
|
||||
// We need this because we don't
|
||||
// include dtool_config.h.
|
||||
#if $[HAVE_X11]
|
||||
#define EXTRA_CDEFS HAVE_X11
|
||||
#endif
|
||||
|
||||
#define COMBINED_SOURCES \
|
||||
$[TARGET]_composite1.cxx
|
||||
@ -39,6 +45,7 @@
|
||||
p3dStringObject.h \
|
||||
p3dUndefinedObject.h \
|
||||
p3dWinSplashWindow.h p3dWinSplashWindow.I \
|
||||
p3dX11SplashWindow.h \
|
||||
p3dWindowParams.h p3dWindowParams.I
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
@ -62,6 +69,7 @@
|
||||
p3dStringObject.cxx \
|
||||
p3dUndefinedObject.cxx \
|
||||
p3dWinSplashWindow.cxx \
|
||||
p3dX11SplashWindow.cxx \
|
||||
p3dWindowParams.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "p3dPackage.h"
|
||||
#include "p3dSplashWindow.h"
|
||||
#include "p3dWinSplashWindow.h"
|
||||
#include "p3dX11SplashWindow.h"
|
||||
#include "p3dObject.h"
|
||||
#include "p3dUndefinedObject.h"
|
||||
|
||||
@ -28,8 +29,12 @@
|
||||
#ifdef _WIN32
|
||||
typedef P3DWinSplashWindow SplashWindowType;
|
||||
#else
|
||||
#ifdef HAVE_X11
|
||||
typedef P3DX11SplashWindow SplashWindowType;
|
||||
#else
|
||||
typedef P3DSplashWindow SplashWindowType;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int P3DInstance::_next_instance_id = 0;
|
||||
|
||||
|
@ -368,8 +368,9 @@ nt_thread_run() {
|
||||
for (ni = instances.begin(); ni != instances.end(); ++ni) {
|
||||
// TODO: a race condition here when instances are deleted.
|
||||
P3DInstance *inst = (*ni);
|
||||
P3D_request_ready_func *func = inst->get_request_ready_func();
|
||||
assert(inst != NULL);
|
||||
P3D_request_ready_func *func = inst->get_request_ready_func();
|
||||
assert(func != NULL);
|
||||
(*func)(inst);
|
||||
}
|
||||
_notify_ready.acquire();
|
||||
|
@ -851,6 +851,13 @@ setup_window(P3DCInstance *inst, TiXmlElement *xwparams) {
|
||||
parent_window_handle = (long)hwnd;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_X11
|
||||
// Bad! Casting to int loses precision.
|
||||
int xwindow;
|
||||
if (xwparams->Attribute("parent_xwindow", &xwindow)) {
|
||||
parent_window_handle = (unsigned long)xwindow;
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: direct this into the particular instance. This will
|
||||
// require a specialized ShowBase replacement.
|
||||
|
@ -79,6 +79,9 @@ make_xml() {
|
||||
xwparams->SetAttribute("win_height", _win_height);
|
||||
#ifdef _WIN32
|
||||
xwparams->SetAttribute("parent_hwnd", (int)_parent_window._hwnd);
|
||||
#endif
|
||||
#ifdef HAVE_X11
|
||||
xwparams->SetAttribute("parent_xwindow", (unsigned long)_parent_window._xwindow);
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
301
direct/src/plugin/p3dX11SplashWindow.cxx
Executable file
301
direct/src/plugin/p3dX11SplashWindow.cxx
Executable file
@ -0,0 +1,301 @@
|
||||
// Filename: p3dX11SplashWindow.cxx
|
||||
// Created by: pro-rsoft (08Jul09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "p3dX11SplashWindow.h"
|
||||
|
||||
#ifdef HAVE_X11
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3DX11SplashWindow::
|
||||
P3DX11SplashWindow(P3DInstance *inst) :
|
||||
P3DSplashWindow(inst)
|
||||
{
|
||||
INIT_THREAD(_thread);
|
||||
_display = None;
|
||||
_window = None;
|
||||
_screen = 0;
|
||||
_graphics_context = None;
|
||||
_thread_running = false;
|
||||
_got_install = false;
|
||||
_image_filename_changed = false;
|
||||
_image_filename_temp = false;
|
||||
_install_label_changed = false;
|
||||
_install_progress = 0.0;
|
||||
|
||||
INIT_LOCK(_install_lock);
|
||||
|
||||
start_thread();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3DX11SplashWindow::
|
||||
~P3DX11SplashWindow() {
|
||||
stop_thread();
|
||||
|
||||
DESTROY_LOCK(_install_lock);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::set_image_filename
|
||||
// Access: Public, Virtual
|
||||
// displayed in the center of the splash window. If
|
||||
// image_filename_temp is true, the file is immediately
|
||||
// deleted after it has been read.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DX11SplashWindow::
|
||||
set_image_filename(const string &image_filename,
|
||||
bool image_filename_temp) {
|
||||
ACQUIRE_LOCK(_install_lock);
|
||||
if (_image_filename != image_filename) {
|
||||
_image_filename = image_filename;
|
||||
_image_filename_temp = image_filename_temp;
|
||||
_image_filename_changed = true;
|
||||
}
|
||||
RELEASE_LOCK(_install_lock);
|
||||
|
||||
// Post a silly message to spin the message loop.
|
||||
//PostThreadMessage(_thread_id, WM_USER, 0, 0);
|
||||
|
||||
if (!_thread_running && _thread_continue) {
|
||||
// The user must have closed the window. Let's shut down the
|
||||
// instance, too.
|
||||
_inst->request_stop();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::set_install_label
|
||||
// Access: Public, Virtual
|
||||
// Description: Specifies the text that is displayed above the
|
||||
// install progress bar.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DX11SplashWindow::
|
||||
set_install_label(const string &install_label) {
|
||||
ACQUIRE_LOCK(_install_lock);
|
||||
if (_install_label != install_label) {
|
||||
_install_label = install_label;
|
||||
_install_label_changed = true;
|
||||
}
|
||||
RELEASE_LOCK(_install_lock);
|
||||
|
||||
// Post a silly message to spin the message loop.
|
||||
//PostThreadMessage(_thread_id, WM_USER, 0, 0);
|
||||
|
||||
if (!_thread_running && _thread_continue) {
|
||||
// The user must have closed the window. Let's shut down the
|
||||
// instance, too.
|
||||
_inst->request_stop();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::set_install_progress
|
||||
// Access: Public, Virtual
|
||||
// Description: Moves the install progress bar from 0.0 to 1.0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DX11SplashWindow::
|
||||
set_install_progress(double install_progress) {
|
||||
_got_install = true;
|
||||
|
||||
ACQUIRE_LOCK(_install_lock);
|
||||
_install_progress = install_progress;
|
||||
RELEASE_LOCK(_install_lock);
|
||||
|
||||
// Post a silly message to spin the message loop.
|
||||
//PostThreadMessage(_thread_id, WM_USER, 0, 0);
|
||||
|
||||
if (!_thread_running && _thread_continue) {
|
||||
// The user must have closed the window. Let's shut down the
|
||||
// instance, too.
|
||||
_inst->request_stop();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::start_thread
|
||||
// Access: Private
|
||||
// Description: Spawns the sub-thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DX11SplashWindow::
|
||||
start_thread() {
|
||||
_thread_continue = true;
|
||||
INIT_THREAD(_thread);
|
||||
SPAWN_THREAD(_thread, thread_run, this);
|
||||
if (_thread != 0) {
|
||||
_thread_running = true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::stop_thread
|
||||
// Access: Private
|
||||
// Description: Terminates and joins the sub-thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DX11SplashWindow::
|
||||
stop_thread() {
|
||||
_thread_continue = false;
|
||||
// Post a silly message to spin the message loop.
|
||||
//PostThreadMessage(_thread_id, WM_USER, 0, 0);
|
||||
|
||||
JOIN_THREAD(_thread);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::thread_run
|
||||
// Access: Private
|
||||
// Description: The sub-thread's main run method.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DX11SplashWindow::
|
||||
thread_run() {
|
||||
make_window();
|
||||
setup_gc();
|
||||
|
||||
XEvent event;
|
||||
XSelectInput(_display, _window, ExposureMask);
|
||||
|
||||
bool override = true, have_event = false;
|
||||
string prev_label;
|
||||
|
||||
while (_thread_continue) {
|
||||
have_event = XCheckTypedWindowEvent(_display, _window, Expose, &event);
|
||||
|
||||
ACQUIRE_LOCK(_install_lock);
|
||||
double install_progress = _install_progress;
|
||||
|
||||
if (have_event || _install_label != prev_label) {
|
||||
redraw(_install_label, install_progress);
|
||||
override = false;
|
||||
}
|
||||
prev_label = _install_label;
|
||||
|
||||
RELEASE_LOCK(_install_lock);
|
||||
}
|
||||
|
||||
close_window();
|
||||
_thread_running = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::redraw
|
||||
// Access: Private
|
||||
// Description: Redraws the window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DX11SplashWindow::
|
||||
redraw(string label, double progress) {
|
||||
if (_graphics_context == NULL) return;
|
||||
|
||||
XClearWindow(_display, _window);
|
||||
XDrawString(_display, _window, _graphics_context, 10, 20, label.c_str(), label.size());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::make_window
|
||||
// Access: Private
|
||||
// Description: Creates the window for displaying progress. Runs
|
||||
// within the sub-thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DX11SplashWindow::
|
||||
make_window() {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
if (_wparams.get_win_x() != 0 && _wparams.get_win_y() != 0) {
|
||||
x = _wparams.get_win_x();
|
||||
y = _wparams.get_win_y();
|
||||
}
|
||||
|
||||
int width = 320;
|
||||
int height = 240;
|
||||
if (_wparams.get_win_width() != 0 && _wparams.get_win_height() != 0) {
|
||||
width = _wparams.get_win_width();
|
||||
height = _wparams.get_win_height();
|
||||
}
|
||||
|
||||
Window parent = 0;
|
||||
_display = (Display*) _wparams.get_parent_window()._xdisplay;
|
||||
if (_display == 0) {
|
||||
_display = XOpenDisplay(NULL);
|
||||
}
|
||||
_screen = DefaultScreen(_display);
|
||||
|
||||
if (_wparams.get_window_type() == P3D_WT_embedded) {
|
||||
// Create an embedded window.
|
||||
parent = _wparams.get_parent_window()._xwindow;
|
||||
} else {
|
||||
// Create a toplevel window.
|
||||
parent = XRootWindow(_display, _screen);
|
||||
}
|
||||
|
||||
assert(_display != NULL);
|
||||
assert(parent != None);
|
||||
_window = XCreateSimpleWindow(_display, parent, x, y, width, height, 0, 0, -1);
|
||||
XMapWindow(_display, _window);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::setup_gc
|
||||
// Access: Private
|
||||
// Description: Sets up the graphics context for drawing the text.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DX11SplashWindow::
|
||||
setup_gc() {
|
||||
if (_graphics_context != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ACQUIRE_LOCK(_install_lock);
|
||||
string install_label = _install_label;
|
||||
double install_progress = _install_progress;
|
||||
_install_label_changed = false;
|
||||
RELEASE_LOCK(_install_lock);
|
||||
|
||||
|
||||
XFontStruct* fs = XLoadQueryFont(_display, "6x13");
|
||||
XGCValues gcval;
|
||||
gcval.font = fs->fid;
|
||||
gcval.function = GXcopy;
|
||||
gcval.plane_mask = AllPlanes;
|
||||
gcval.foreground = BlackPixel(_display, _screen);
|
||||
gcval.background = WhitePixel(_display, _screen);
|
||||
_graphics_context = XCreateGC(_display, _window,
|
||||
GCFont | GCFunction | GCPlaneMask | GCForeground | GCBackground, &gcval);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DX11SplashWindow::close_window
|
||||
// Access: Private
|
||||
// Description: Closes the window created above.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DX11SplashWindow::
|
||||
close_window() {
|
||||
if (_window != None) {
|
||||
XDestroyWindow(_display, _window);
|
||||
_window = None;
|
||||
}
|
||||
|
||||
if (_display != None) {
|
||||
XCloseDisplay(_display);
|
||||
_display = None;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAVE_X11
|
82
direct/src/plugin/p3dX11SplashWindow.h
Executable file
82
direct/src/plugin/p3dX11SplashWindow.h
Executable file
@ -0,0 +1,82 @@
|
||||
// Filename: p3dX11SplashWindow.h
|
||||
// Created by: pro-rsoft (08Jul09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 P3DX11SPLASHWINDOW_H
|
||||
#define P3DX11SPLASHWINDOW_H
|
||||
|
||||
#include "p3d_plugin_common.h"
|
||||
|
||||
#ifdef HAVE_X11
|
||||
|
||||
#include "p3dSplashWindow.h"
|
||||
#include "p3d_lock.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : P3DX11SplashWindow
|
||||
// Description : This is the Windows implementation of the
|
||||
// initial-download window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class P3DX11SplashWindow : public P3DSplashWindow {
|
||||
public:
|
||||
P3DX11SplashWindow(P3DInstance *inst);
|
||||
virtual ~P3DX11SplashWindow();
|
||||
|
||||
virtual void set_image_filename(const string &image_filename,
|
||||
bool image_filename_temp);
|
||||
virtual void set_install_label(const string &install_label);
|
||||
virtual void set_install_progress(double install_progress);
|
||||
|
||||
private:
|
||||
void start_thread();
|
||||
void stop_thread();
|
||||
|
||||
private:
|
||||
// These methods run only within the window thread.
|
||||
void thread_run();
|
||||
THREAD_CALLBACK_DECLARATION(P3DX11SplashWindow, thread_run);
|
||||
|
||||
void redraw(string label, double progress);
|
||||
void make_window();
|
||||
void setup_gc();
|
||||
void close_window();
|
||||
|
||||
private:
|
||||
bool _got_install;
|
||||
bool _image_filename_changed;
|
||||
string _image_filename;
|
||||
bool _image_filename_temp;
|
||||
bool _install_label_changed;
|
||||
string _install_label;
|
||||
double _install_progress;
|
||||
LOCK _install_lock;
|
||||
|
||||
string _label_text;
|
||||
|
||||
bool _thread_continue;
|
||||
bool _thread_running;
|
||||
Display *_display;
|
||||
int _screen;
|
||||
GC _graphics_context;
|
||||
|
||||
THREAD _thread;
|
||||
Window _window;
|
||||
int _bitmap_width, _bitmap_height;
|
||||
};
|
||||
|
||||
#endif // HAVE_X11
|
||||
|
||||
#endif
|
@ -131,6 +131,10 @@ typedef struct {
|
||||
#ifdef _WIN32
|
||||
HWND _hwnd;
|
||||
#endif
|
||||
#ifdef HAVE_X11
|
||||
unsigned long _xwindow;
|
||||
void *_xdisplay;
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
void *_nswindow;
|
||||
#endif
|
||||
|
@ -18,4 +18,5 @@
|
||||
#include "p3dStringObject.cxx"
|
||||
#include "p3dUndefinedObject.cxx"
|
||||
#include "p3dWinSplashWindow.cxx"
|
||||
#include "p3dX11SplashWindow.cxx"
|
||||
#include "p3dWindowParams.cxx"
|
||||
|
@ -12,6 +12,12 @@
|
||||
|
||||
#define LOCAL_LIBS plugin_common
|
||||
|
||||
// We need this because we don't
|
||||
// include dtool_config.h.
|
||||
#if $[HAVE_X11]
|
||||
#define EXTRA_CDEFS HAVE_X11
|
||||
#endif
|
||||
|
||||
#define COMBINED_SOURCES \
|
||||
$[TARGET]_composite1.cxx
|
||||
|
||||
|
@ -923,24 +923,49 @@ send_window() {
|
||||
int y = _window.y;
|
||||
|
||||
P3D_window_handle parent_window;
|
||||
#ifdef _WIN32
|
||||
if (_window.type == NPWindowTypeWindow) {
|
||||
// We have a "windowed" plugin. Parent our window to the one we
|
||||
// were given. In this case, we should also reset the offset to
|
||||
// (0, 0), since the window we were given is already placed in the
|
||||
// right spot.
|
||||
#ifdef _WIN32
|
||||
parent_window._hwnd = (HWND)(_window.window);
|
||||
#endif
|
||||
#ifdef HAVE_X11
|
||||
// We make it an 'unsigned long' instead of 'Window'
|
||||
// to avoid nppanda3d.so getting a dependency on X11.
|
||||
parent_window._xwindow = (unsigned long)(_window.window);
|
||||
#endif
|
||||
x = 0;
|
||||
y = 0;
|
||||
} else {
|
||||
// We have a "windowless" plugin. Parent our window directly to
|
||||
// the browser window.
|
||||
#ifdef _WIN32
|
||||
parent_window._hwnd = 0;
|
||||
HWND hwnd;
|
||||
if (browser->getvalue(_npp_instance, NPNVnetscapeWindow,
|
||||
&hwnd) == NPERR_NO_ERROR) {
|
||||
parent_window._hwnd = hwnd;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_X11
|
||||
parent_window._xwindow = 0;
|
||||
unsigned long win;
|
||||
if (browser->getvalue(_npp_instance, NPNVnetscapeWindow,
|
||||
&win) == NPERR_NO_ERROR) {
|
||||
parent_window._xwindow = win;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_X11
|
||||
// In the case of X11, grab the display as well.
|
||||
parent_window._xdisplay = 0;
|
||||
void* disp;
|
||||
if (browser->getvalue(_npp_instance, NPNVxDisplay,
|
||||
&disp) == NPERR_NO_ERROR) {
|
||||
parent_window._xdisplay = disp;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -66,7 +66,13 @@ request_ready(P3D_instance *instance) {
|
||||
// it within HandleEvent(). TODO: enable a timer to ensure we get
|
||||
// HandleEvent callbacks in a timely manner? Or maybe we should
|
||||
// enable a one-shot timer in response to this asynchronous event?
|
||||
#endif
|
||||
|
||||
#ifndef __APPLE__
|
||||
// On Unix, HandleEvent isn't called, so we will do what it does
|
||||
// right here. Not sure if this is right.
|
||||
PPInstance::handle_request_loop();
|
||||
#endif // __APPLE__
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -98,7 +104,11 @@ NP_GetValue(void*, NPPVariable variable, void* value) {
|
||||
case NPPVpluginDescriptionString:
|
||||
*(const char **)value = "Runs 3-D games and interactive applets";
|
||||
break;
|
||||
case NPPVpluginNeedsXEmbed:
|
||||
*((PRBool *)value) = PR_FALSE;
|
||||
break;
|
||||
default:
|
||||
logfile << "Ignoring GetValue request " << variable << "\n" << flush;
|
||||
return NPERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user