mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
allow resizing subprocess buffer
This commit is contained in:
parent
961a754ec4
commit
6174ae7228
@ -221,14 +221,30 @@ set_wparams(const P3DWindowParams &wparams) {
|
||||
// to the browser. Set up this mechanism.
|
||||
int x_size = _wparams.get_win_width();
|
||||
int y_size = _wparams.get_win_height();
|
||||
if (_shared_fd == -1 && x_size != 0 && y_size != 0) {
|
||||
_swbuffer = SubprocessWindowBuffer::new_buffer
|
||||
(_shared_fd, _shared_mmap_size, _shared_filename, x_size, y_size);
|
||||
if (_swbuffer != NULL) {
|
||||
_reversed_buffer = new char[_swbuffer->get_framebuffer_size()];
|
||||
if (x_size != 0 && y_size != 0) {
|
||||
if (_swbuffer == NULL || _swbuffer->get_x_size() != x_size ||
|
||||
_swbuffer->get_y_size() != y_size) {
|
||||
// We need to open a new shared buffer.
|
||||
if (_swbuffer != NULL) {
|
||||
SubprocessWindowBuffer::destroy_buffer(_shared_fd, _shared_mmap_size,
|
||||
_shared_filename, _swbuffer);
|
||||
_swbuffer = NULL;
|
||||
}
|
||||
if (_reversed_buffer != NULL) {
|
||||
delete[] _reversed_buffer;
|
||||
_reversed_buffer = NULL;
|
||||
}
|
||||
|
||||
_swbuffer = SubprocessWindowBuffer::new_buffer
|
||||
(_shared_fd, _shared_mmap_size, _shared_filename, x_size, y_size);
|
||||
if (_swbuffer != NULL) {
|
||||
_reversed_buffer = new char[_swbuffer->get_framebuffer_size()];
|
||||
}
|
||||
}
|
||||
|
||||
xwparams->SetAttribute("subprocess_window", _shared_filename);
|
||||
if (_swbuffer != NULL) {
|
||||
xwparams->SetAttribute("subprocess_window", _shared_filename);
|
||||
}
|
||||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
@ -513,8 +529,6 @@ handle_event(P3D_event_data event) {
|
||||
swb_event._flags = 0;
|
||||
add_modifier_flags(swb_event._flags, er->modifiers);
|
||||
|
||||
bool keep_event = false;
|
||||
|
||||
switch (er->what) {
|
||||
case mouseDown:
|
||||
case mouseUp:
|
||||
@ -526,7 +540,6 @@ handle_event(P3D_event_data event) {
|
||||
} else {
|
||||
swb_event._type = SubprocessWindowBuffer::ET_button_down;
|
||||
}
|
||||
keep_event = true;
|
||||
retval = true;
|
||||
}
|
||||
break;
|
||||
@ -544,7 +557,6 @@ handle_event(P3D_event_data event) {
|
||||
} else {
|
||||
swb_event._type = SubprocessWindowBuffer::ET_button_again;
|
||||
}
|
||||
keep_event = true;
|
||||
retval = true;
|
||||
}
|
||||
break;
|
||||
@ -556,7 +568,6 @@ handle_event(P3D_event_data event) {
|
||||
|
||||
case activateEvt:
|
||||
_mouse_active = ((er->modifiers & 1) != 0);
|
||||
keep_event = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -569,12 +580,10 @@ handle_event(P3D_event_data event) {
|
||||
swb_event._flags |= SubprocessWindowBuffer::EF_mouse_position | SubprocessWindowBuffer::EF_has_mouse;
|
||||
}
|
||||
|
||||
if (keep_event && _swbuffer != NULL) {
|
||||
if (_swbuffer != NULL) {
|
||||
_swbuffer->add_event(swb_event);
|
||||
}
|
||||
|
||||
#elif defined(HAVE_X11)
|
||||
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
@ -785,6 +794,7 @@ void P3DInstance::
|
||||
handle_notify_request(const string &message) {
|
||||
// We look for certain notify events that have particular meaning
|
||||
// to this instance.
|
||||
nout << "Got notify: " << message << "\n" << flush;
|
||||
if (message == "onpythonload") {
|
||||
// Once Python is up and running, we can get the actual toplevel
|
||||
// object from the Python side, and merge it with our own.
|
||||
|
@ -134,6 +134,7 @@ def buildDmg(startDir):
|
||||
fstartDir = Filename.fromOsSpecific(startDir)
|
||||
rootFilename = Filename(fstartDir, 'bundle')
|
||||
output = Filename(fstartDir, 'nppanda3d.dmg')
|
||||
output.unlink()
|
||||
cmd = 'hdiutil create -fs HFS+ -srcfolder "%(dir)s" -volname "%(volname)s" "%(output)s"' % {
|
||||
'dir' : rootFilename.toOsSpecific(),
|
||||
'volname' : 'nppanda3d',
|
||||
|
@ -304,6 +304,8 @@ class AppRunner(DirectObject):
|
||||
wp.setOrigin(x, y)
|
||||
if width or height:
|
||||
wp.setSize(width, height)
|
||||
if subprocessWindow:
|
||||
wp.setSubprocessWindow(subprocessWindow)
|
||||
base.win.requestProperties(wp)
|
||||
return
|
||||
|
||||
|
@ -35,34 +35,24 @@ SubprocessWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host,
|
||||
const string &filename) :
|
||||
GraphicsOutput *host) :
|
||||
GraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
|
||||
{
|
||||
GraphicsWindowInputDevice device =
|
||||
GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard/mouse");
|
||||
_input_devices.push_back(device);
|
||||
|
||||
// Create a buffer with the same properties as the window.
|
||||
flags = ((flags & ~GraphicsPipe::BF_require_window) | GraphicsPipe::BF_refuse_window);
|
||||
// This will be an offscreen buffer that we use to render the actual
|
||||
// contents.
|
||||
_buffer = NULL;
|
||||
|
||||
GraphicsOutput *buffer =
|
||||
engine->make_output(pipe, name, 0,
|
||||
fb_prop, win_prop, flags, gsg, host);
|
||||
if (buffer != NULL) {
|
||||
_buffer = DCAST(GraphicsBuffer, buffer);
|
||||
// However, the buffer is not itself intended to be rendered. We
|
||||
// only render it indirectly, via callbacks in here.
|
||||
_buffer->set_active(false);
|
||||
}
|
||||
|
||||
// Now create a texture to receive the contents of the framebuffer
|
||||
// from the buffer.
|
||||
// Create a texture to receive the contents of the framebuffer from
|
||||
// the offscreen buffer.
|
||||
_texture = new Texture(name);
|
||||
|
||||
_fd = -1;
|
||||
_mmap_size = 0;
|
||||
_filename = filename;
|
||||
_filename = string();
|
||||
_swbuffer = NULL;
|
||||
_last_event_flags = 0;
|
||||
}
|
||||
@ -74,9 +64,7 @@ SubprocessWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
SubprocessWindow::
|
||||
~SubprocessWindow() {
|
||||
if (_buffer != NULL) {
|
||||
_engine->remove_window(_buffer);
|
||||
}
|
||||
nassertv(_buffer == NULL);
|
||||
nassertv(_swbuffer == NULL);
|
||||
}
|
||||
|
||||
@ -193,7 +181,9 @@ end_frame(FrameMode mode, Thread *current_thread) {
|
||||
void SubprocessWindow::
|
||||
begin_flip() {
|
||||
nassertv(_buffer != (GraphicsBuffer *)NULL);
|
||||
nassertv(_swbuffer != NULL);
|
||||
if (_swbuffer == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
RenderBuffer buffer(_gsg, DrawableRegion::get_renderbuffer_type(RTP_color));
|
||||
buffer = _gsg->get_render_buffer(_buffer->get_draw_buffer_type(),
|
||||
@ -233,6 +223,54 @@ begin_flip() {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SubprocessWindow::set_properties_now
|
||||
// Access: Public, Virtual
|
||||
// Description: Applies the requested set of properties to the
|
||||
// window, if possible, for instance to request a change
|
||||
// in size or minimization status.
|
||||
//
|
||||
// The window properties are applied immediately, rather
|
||||
// than waiting until the next frame. This implies that
|
||||
// this method may *only* be called from within the
|
||||
// window thread.
|
||||
//
|
||||
// The properties that have been applied are cleared
|
||||
// from the structure by this function; so on return,
|
||||
// whatever remains in the properties structure are
|
||||
// those that were unchanged for some reason (probably
|
||||
// because the underlying interface does not support
|
||||
// changing that property on an open window).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void SubprocessWindow::
|
||||
set_properties_now(WindowProperties &properties) {
|
||||
if (properties.has_subprocess_window() &&
|
||||
properties.get_subprocess_window() != _filename) {
|
||||
// We're changing the subprocess buffer filename; that means we
|
||||
// might as well completely close and re-open the window.
|
||||
internal_close_window();
|
||||
|
||||
_properties.add_properties(properties);
|
||||
properties.clear();
|
||||
|
||||
internal_open_window();
|
||||
set_size_and_recalc(_properties.get_x_size(), _properties.get_y_size());
|
||||
throw_event(get_window_event(), this);
|
||||
return;
|
||||
}
|
||||
|
||||
GraphicsWindow::set_properties_now(properties);
|
||||
if (!properties.is_any_specified()) {
|
||||
// The base class has already handled this case.
|
||||
return;
|
||||
}
|
||||
|
||||
if (properties.has_subprocess_window()) {
|
||||
// Redundant subprocess specification.
|
||||
properties.clear_subprocess_window();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SubprocessWindow::close_window
|
||||
// Access: Protected, Virtual
|
||||
@ -241,20 +279,7 @@ begin_flip() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void SubprocessWindow::
|
||||
close_window() {
|
||||
if (_swbuffer != NULL) {
|
||||
SubprocessWindowBuffer::close_buffer(_fd, _mmap_size, _filename, _swbuffer);
|
||||
_fd = -1;
|
||||
_filename = string();
|
||||
|
||||
_swbuffer = NULL;
|
||||
}
|
||||
|
||||
if (_buffer != NULL) {
|
||||
_buffer->request_close();
|
||||
_buffer->process_events();
|
||||
}
|
||||
|
||||
_is_valid = false;
|
||||
internal_close_window();
|
||||
|
||||
WindowProperties properties;
|
||||
properties.set_open(false);
|
||||
@ -271,28 +296,7 @@ close_window() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool SubprocessWindow::
|
||||
open_window() {
|
||||
nout << "open_window\n";
|
||||
|
||||
if (_buffer != NULL) {
|
||||
_buffer->request_open();
|
||||
_buffer->process_events();
|
||||
|
||||
_is_valid = _buffer->is_valid();
|
||||
}
|
||||
|
||||
if (!_is_valid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_gsg = _buffer->get_gsg();
|
||||
|
||||
_swbuffer = SubprocessWindowBuffer::open_buffer(_fd, _mmap_size, _filename);
|
||||
|
||||
if (_swbuffer == NULL) {
|
||||
close(_fd);
|
||||
_fd = -1;
|
||||
_filename = string();
|
||||
_is_valid = false;
|
||||
if (!internal_open_window()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -304,6 +308,88 @@ open_window() {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SubprocessWindow::internal_close_window
|
||||
// Access: Private
|
||||
// Description: Closes the "window" and resets the buffer, without
|
||||
// changing the WindowProperties.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void SubprocessWindow::
|
||||
internal_close_window() {
|
||||
if (_swbuffer != NULL) {
|
||||
SubprocessWindowBuffer::close_buffer
|
||||
(_fd, _mmap_size, _filename.to_os_specific(), _swbuffer);
|
||||
_fd = -1;
|
||||
_filename = string();
|
||||
|
||||
_swbuffer = NULL;
|
||||
}
|
||||
|
||||
if (_buffer != NULL) {
|
||||
_buffer->request_close();
|
||||
_buffer->process_events();
|
||||
_engine->remove_window(_buffer);
|
||||
_buffer = NULL;
|
||||
}
|
||||
|
||||
_is_valid = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SubprocessWindow::internal_open_window
|
||||
// Access: Private
|
||||
// Description: Opens the "window" and the associated offscreen
|
||||
// buffer, without changing the WindowProperties.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool SubprocessWindow::
|
||||
internal_open_window() {
|
||||
nassertr(_buffer == NULL, false);
|
||||
|
||||
// Create a buffer with the same properties as the window.
|
||||
int flags = _creation_flags;
|
||||
flags = ((flags & ~GraphicsPipe::BF_require_window) | GraphicsPipe::BF_refuse_window);
|
||||
|
||||
GraphicsOutput *buffer =
|
||||
_engine->make_output(_pipe, _name, 0, _fb_properties, _properties,
|
||||
flags, _gsg, _host);
|
||||
if (buffer != NULL) {
|
||||
_buffer = DCAST(GraphicsBuffer, buffer);
|
||||
// However, the buffer is not itself intended to be rendered. We
|
||||
// only render it indirectly, via callbacks in here.
|
||||
_buffer->set_active(false);
|
||||
|
||||
_buffer->request_open();
|
||||
_buffer->process_events();
|
||||
|
||||
_is_valid = _buffer->is_valid();
|
||||
}
|
||||
|
||||
if (!_is_valid) {
|
||||
display_cat.error()
|
||||
<< "Failed to open SubprocessWindowBuffer's internal offscreen buffer.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
_gsg = _buffer->get_gsg();
|
||||
_filename = _properties.get_subprocess_window();
|
||||
|
||||
_swbuffer = SubprocessWindowBuffer::open_buffer
|
||||
(_fd, _mmap_size, _filename.to_os_specific());
|
||||
|
||||
if (_swbuffer == NULL) {
|
||||
close(_fd);
|
||||
_fd = -1;
|
||||
_filename = string();
|
||||
_is_valid = false;
|
||||
display_cat.error()
|
||||
<< "Failed to open SubprocessWindowBuffer's shared-memory buffer "
|
||||
<< _filename << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SubprocessWindow::translate_key
|
||||
// Access: Private
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "graphicsBuffer.h"
|
||||
#include "texture.h"
|
||||
#include "subprocessWindowBuffer.h"
|
||||
#include "filename.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : SubprocessWindow
|
||||
@ -55,8 +56,7 @@ public:
|
||||
const WindowProperties &win_prop,
|
||||
int flags,
|
||||
GraphicsStateGuardian *gsg,
|
||||
GraphicsOutput *host,
|
||||
const string &filename);
|
||||
GraphicsOutput *host);
|
||||
virtual ~SubprocessWindow();
|
||||
|
||||
virtual void process_events();
|
||||
@ -65,11 +65,16 @@ public:
|
||||
virtual void end_frame(FrameMode mode, Thread *current_thread);
|
||||
virtual void begin_flip();
|
||||
|
||||
virtual void set_properties_now(WindowProperties &properties);
|
||||
|
||||
protected:
|
||||
virtual void close_window();
|
||||
virtual bool open_window();
|
||||
|
||||
private:
|
||||
void internal_close_window();
|
||||
bool internal_open_window();
|
||||
|
||||
ButtonHandle translate_key(int &keycode, int os_code, unsigned int flags) const;
|
||||
void transition_button(unsigned int flag, ButtonHandle button);
|
||||
|
||||
@ -79,7 +84,7 @@ private:
|
||||
|
||||
int _fd;
|
||||
size_t _mmap_size;
|
||||
string _filename;
|
||||
Filename _filename;
|
||||
SubprocessWindowBuffer *_swbuffer;
|
||||
|
||||
unsigned int _last_event_flags;
|
||||
|
@ -237,8 +237,7 @@ make_output(const string &name,
|
||||
#ifdef SUPPORT_SUBPROCESS_WINDOW
|
||||
if (win_prop.has_subprocess_window()) {
|
||||
return new SubprocessWindow(engine, this, name, fb_prop, win_prop,
|
||||
flags, gsg, host,
|
||||
win_prop.get_subprocess_window().to_os_specific());
|
||||
flags, gsg, host);
|
||||
}
|
||||
#endif // SUPPORT_SUBPROCESS_WINDOW
|
||||
return new osxGraphicsWindow(engine, this, name, fb_prop, win_prop,
|
||||
|
@ -238,8 +238,7 @@ make_output(const string &name,
|
||||
#ifdef SUPPORT_SUBPROCESS_WINDOW
|
||||
if (win_prop.has_subprocess_window()) {
|
||||
return new SubprocessWindow(engine, this, name, fb_prop, win_prop,
|
||||
flags, gsg, host,
|
||||
win_prop.get_subprocess_window().to_os_specific());
|
||||
flags, gsg, host);
|
||||
}
|
||||
#endif // SUPPORT_SUBPROCESS_WINDOW
|
||||
return new TinyOsxGraphicsWindow(engine, this, name, fb_prop, win_prop,
|
||||
|
Loading…
x
Reference in New Issue
Block a user