15 #include "subprocessWindow.h"
17 #ifdef SUPPORT_SUBPROCESS_WINDOW
19 #include "graphicsEngine.h"
20 #include "config_display.h"
21 #include "nativeWindowHandle.h"
40 GraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
44 _input_devices.push_back(device);
58 _last_event_flags = 0;
68 nassertv(_buffer == NULL);
69 nassertv(_swbuffer == NULL);
82 void SubprocessWindow::
86 if (_swbuffer != NULL) {
88 while (_swbuffer->get_event(swb_event)) {
90 if (swb_event._flags & SubprocessWindowBuffer::EF_mouse_position) {
91 _input_devices[0].set_pointer_in_window(swb_event._x, swb_event._y);
92 }
else if ((swb_event._flags & SubprocessWindowBuffer::EF_has_mouse) == 0) {
93 _input_devices[0].set_pointer_out_of_window();
96 unsigned int diff = swb_event._flags ^ _last_event_flags;
97 _last_event_flags = swb_event._flags;
99 if (diff & SubprocessWindowBuffer::EF_shift_held) {
100 transition_button(swb_event._flags & SubprocessWindowBuffer::EF_shift_held, KeyboardButton::shift());
102 if (diff & SubprocessWindowBuffer::EF_control_held) {
103 transition_button(swb_event._flags & SubprocessWindowBuffer::EF_control_held, KeyboardButton::control());
105 if (diff & SubprocessWindowBuffer::EF_alt_held) {
106 transition_button(swb_event._flags & SubprocessWindowBuffer::EF_alt_held, KeyboardButton::alt());
108 if (diff & SubprocessWindowBuffer::EF_meta_held) {
109 transition_button(swb_event._flags & SubprocessWindowBuffer::EF_meta_held, KeyboardButton::meta());
113 if (swb_event._source == SubprocessWindowBuffer::ES_mouse) {
116 }
else if (swb_event._source == SubprocessWindowBuffer::ES_keyboard) {
118 button = translate_key(keycode, swb_event._code, swb_event._flags);
119 if (keycode != 0 && swb_event._type != SubprocessWindowBuffer::ET_button_up) {
120 _input_devices[0].keystroke(keycode);
124 if (swb_event._type == SubprocessWindowBuffer::ET_button_up) {
125 _input_devices[0].button_up(button);
126 }
else if (swb_event._type == SubprocessWindowBuffer::ET_button_down) {
127 _input_devices[0].button_down(button);
142 bool SubprocessWindow::
143 begin_frame(FrameMode mode,
Thread *current_thread) {
144 if (_swbuffer == NULL || _buffer == NULL) {
148 bool result = _buffer->begin_frame(mode, current_thread);
159 void SubprocessWindow::
160 end_frame(FrameMode mode,
Thread *current_thread) {
161 _buffer->end_frame(mode, current_thread);
163 if (mode == FM_render) {
182 void SubprocessWindow::
185 if (_swbuffer == NULL) {
190 buffer = _gsg->get_render_buffer(_buffer->get_draw_buffer_type(),
191 _buffer->get_fb_properties());
194 _gsg->framebuffer_copy_to_ram(_texture, 0, -1,
195 _overlay_display_region, buffer);
199 size_t framebuffer_size = _swbuffer->get_framebuffer_size();
200 nassertv(image.size() == framebuffer_size);
202 if (!_swbuffer->ready_for_write()) {
210 while (!_swbuffer->ready_for_write()) {
213 if (now - start > subprocess_window_max_wait) {
221 void *target = _swbuffer->open_write_framebuffer();
222 memcpy(target, image.
p(), framebuffer_size);
223 _swbuffer->close_write_framebuffer();
246 void SubprocessWindow::
250 if (window_handle != NULL) {
252 if (os_handle != NULL) {
253 if (os_handle->
is_of_type(NativeWindowHandle::SubprocessHandle::get_class_type())) {
255 filename = subprocess_handle->get_filename();
260 if (!filename.empty() && filename != _filename) {
263 display_cat.info() <<
"Re-opening SubprocessWindow\n";
264 internal_close_window();
266 _properties.add_properties(properties);
269 internal_open_window();
270 set_size_and_recalc(_properties.get_x_size(), _properties.get_y_size());
271 throw_event(get_window_event(),
this);
293 void SubprocessWindow::
295 internal_close_window();
300 system_changed_properties(properties);
310 bool SubprocessWindow::
312 if (!internal_open_window()) {
319 system_changed_properties(properties);
330 void SubprocessWindow::
331 internal_close_window() {
332 if (_swbuffer != NULL) {
334 (_fd, _mmap_size, _filename.to_os_specific(), _swbuffer);
336 _filename = string();
341 if (_buffer != NULL) {
342 _buffer->request_close();
343 _buffer->process_events();
344 _engine->remove_window(_buffer);
351 _parent_window_handle->detach_child(_window_handle);
354 _window_handle = NULL;
355 _parent_window_handle = NULL;
365 bool SubprocessWindow::
366 internal_open_window() {
367 nassertr(_buffer == NULL,
false);
370 int flags = _creation_flags;
371 flags = ((flags & ~
GraphicsPipe::BF_require_window) | GraphicsPipe::BF_refuse_window);
375 _engine->make_output(_pipe, _name, 0, _fb_properties, win_props,
377 if (buffer != NULL) {
381 _buffer->set_active(
false);
383 _buffer->request_open();
384 _buffer->process_events();
386 _is_valid = _buffer->is_valid();
391 <<
"Failed to open SubprocessWindowBuffer's internal offscreen buffer.\n";
395 _gsg = _buffer->get_gsg();
397 WindowHandle *window_handle = _properties.get_parent_window();
398 if (window_handle != NULL) {
400 if (os_handle != NULL) {
401 if (os_handle->
is_of_type(NativeWindowHandle::SubprocessHandle::get_class_type())) {
403 _filename = subprocess_handle->get_filename();
407 _parent_window_handle = window_handle;
409 if (_filename.empty()) {
412 <<
"No filename given to SubprocessWindow.\n";
417 (_fd, _mmap_size, _filename.to_os_specific());
419 if (_swbuffer == NULL) {
422 _filename = string();
425 <<
"Failed to open SubprocessWindowBuffer's shared-memory buffer "
426 << _filename <<
"\n";
430 if (display_cat.is_debug()) {
432 <<
"SubprocessWindow reading " << _filename <<
"\n";
436 _window_handle = NativeWindowHandle::make_subprocess(_filename);
440 _parent_window_handle->attach_child(_window_handle);
454 translate_key(
int &keycode,
int os_code,
unsigned int flags)
const {
459 switch ((os_code >> 8) & 0xff) {
512 case 49: nk = KeyboardButton::space();
break;
513 case 51: nk = KeyboardButton::backspace();
break;
514 case 48: nk = KeyboardButton::tab();
break;
515 case 53: nk = KeyboardButton::escape();
break;
516 case 76: nk = KeyboardButton::enter();
break;
517 case 36: nk = KeyboardButton::enter();
break;
519 case 123: nk = KeyboardButton::left();
break;
520 case 124: nk = KeyboardButton::right();
break;
521 case 125: nk = KeyboardButton::down();
break;
522 case 126: nk = KeyboardButton::up();
break;
523 case 116: nk = KeyboardButton::page_up();
break;
524 case 121: nk = KeyboardButton::page_down();
break;
525 case 115: nk = KeyboardButton::home();
break;
526 case 119: nk = KeyboardButton::end();
break;
527 case 114: nk = KeyboardButton::help();
break;
528 case 117: nk = KeyboardButton::del();
break;
532 case 122: nk = KeyboardButton::f1();
break;
533 case 120: nk = KeyboardButton::f2();
break;
534 case 99: nk = KeyboardButton::f3();
break;
535 case 118: nk = KeyboardButton::f4();
break;
536 case 96: nk = KeyboardButton::f5();
break;
537 case 97: nk = KeyboardButton::f6();
break;
538 case 98: nk = KeyboardButton::f7();
break;
539 case 100: nk = KeyboardButton::f8();
break;
540 case 101: nk = KeyboardButton::f9();
break;
541 case 109: nk = KeyboardButton::f10();
break;
542 case 103: nk = KeyboardButton::f11();
break;
543 case 111: nk = KeyboardButton::f12();
break;
545 case 105: nk = KeyboardButton::f13();
break;
546 case 107: nk = KeyboardButton::f14();
break;
547 case 113: nk = KeyboardButton::f15();
break;
548 case 106: nk = KeyboardButton::f16();
break;
574 keycode = os_code & 0xff;
589 void SubprocessWindow::
590 transition_button(
unsigned int flags,
ButtonHandle button) {
592 _input_devices[0].button_down(button);
594 _input_devices[0].button_up(button);
599 #endif // SUPPORT_SUBPROCESS_WINDOW
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
virtual void process_events()
Do whatever processing is necessary to ensure that the window responds to user events.
static int get_renderbuffer_type(int plane)
Returns the RenderBuffer::Type that corresponds to a RenderTexturePlane.
const Element * p() const
Function p() is similar to the function from ConstPointerTo.
void clear()
Unsets all properties that have been specified so far, and resets the WindowProperties structure to i...
This object represents a window on the desktop, not necessarily a Panda window.
static WindowProperties size(int x_size, int y_size)
Returns a WindowProperties structure with only the size specified.
virtual void set_properties_now(WindowProperties &properties)
Applies the requested set of properties to the window, if possible, for instance to request a change ...
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
void clear_parent_window()
Removes the S_parent_window specification from the properties.
static void force_yield()
Suspends the current thread for the rest of the current epoch.
A window, fullscreen or on a desktop, into which a graphics device sends its output for interactive d...
bool has_parent_window() const
Checks the S_parent_window specification from the properties.
static void close_buffer(int fd, size_t mmap_size, const string &filename, SubprocessWindowBuffer *buffer)
Closes a buffer object created via a previous call to open_buffer().
A container for the various kinds of properties we might ask to have on a graphics window before we o...
An offscreen buffer for rendering into.
The name of a file, such as a texture file or an Egg file.
A ClockObject keeps track of elapsed real time and discrete time.
An object to create GraphicsOutputs that share a particular 3-D API.
WindowHandle * get_parent_window() const
Returns the parent window specification, or NULL if there is no parent window specified.
This is a base class for the various different classes that represent the result of a frame of render...
bool is_any_specified() const
Returns true if any properties have been specified, false otherwise.
void set_foreground(bool foreground)
Specifies whether the window should be opened in the foreground (true), or left in the background (fa...
A thread; that is, a lightweight process.
Encapsulates all the communication with a particular instance of a given rendering backend...
This class is the main interface to controlling the render process.
double get_real_time() const
Returns the actual number of seconds elapsed since the ClockObject was created, or since it was last ...
TypeHandle is the identifier used to differentiate C++ class types.
OSHandle * get_os_handle() const
Returns the OS-specific handle stored internally to the WindowHandle wrapper.
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
void set_open(bool open)
Specifies whether the window should be open.
static SubprocessWindowBuffer * open_buffer(int &fd, size_t &mmap_size, const string &filename)
Call this method to open a reference to an existing buffer in shared memory space.
A RenderBuffer is an arbitrary subset of the various layers (depth buffer, color buffer, etc.) of a drawing region.