16 #ifdef SUPPORT_SUBPROCESS_WINDOW 40 GraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
42 _input = GraphicsWindowInputDevice::pointer_and_keyboard(
this,
"keyboard/mouse");
43 _input_devices.push_back(_input.p());
57 _last_event_flags = 0;
65 nassertv(_buffer ==
nullptr);
66 nassertv(_swbuffer ==
nullptr);
76 void SubprocessWindow::
80 if (_swbuffer !=
nullptr) {
82 while (_swbuffer->get_event(swb_event)) {
84 if (swb_event._flags & SubprocessWindowBuffer::EF_mouse_position) {
85 _input->set_pointer_in_window(swb_event._x, swb_event._y);
86 }
else if ((swb_event._flags & SubprocessWindowBuffer::EF_has_mouse) == 0) {
87 _input->set_pointer_out_of_window();
90 unsigned int diff = swb_event._flags ^ _last_event_flags;
91 _last_event_flags = swb_event._flags;
93 if (diff & SubprocessWindowBuffer::EF_shift_held) {
94 transition_button(swb_event._flags & SubprocessWindowBuffer::EF_shift_held, KeyboardButton::shift());
96 if (diff & SubprocessWindowBuffer::EF_control_held) {
97 transition_button(swb_event._flags & SubprocessWindowBuffer::EF_control_held, KeyboardButton::control());
99 if (diff & SubprocessWindowBuffer::EF_alt_held) {
100 transition_button(swb_event._flags & SubprocessWindowBuffer::EF_alt_held, KeyboardButton::alt());
102 if (diff & SubprocessWindowBuffer::EF_meta_held) {
103 transition_button(swb_event._flags & SubprocessWindowBuffer::EF_meta_held, KeyboardButton::meta());
107 if (swb_event._source == SubprocessWindowBuffer::ES_mouse) {
110 }
else if (swb_event._source == SubprocessWindowBuffer::ES_keyboard) {
112 button = translate_key(keycode, swb_event._code, swb_event._flags);
113 if (keycode != 0 && swb_event._type != SubprocessWindowBuffer::ET_button_up) {
114 _input->keystroke(keycode);
118 if (swb_event._type == SubprocessWindowBuffer::ET_button_up) {
119 _input->button_up(button);
120 }
else if (swb_event._type == SubprocessWindowBuffer::ET_button_down) {
121 _input->button_down(button);
133 bool SubprocessWindow::
134 begin_frame(FrameMode mode,
Thread *current_thread) {
135 if (_swbuffer ==
nullptr || _buffer ==
nullptr) {
139 bool result = _buffer->begin_frame(mode, current_thread);
148 void SubprocessWindow::
149 end_frame(FrameMode mode,
Thread *current_thread) {
150 _buffer->end_frame(mode, current_thread);
152 if (mode == FM_render) {
168 void SubprocessWindow::
170 nassertv(_buffer !=
nullptr);
171 if (_swbuffer ==
nullptr) {
176 buffer = _gsg->get_render_buffer(_buffer->get_draw_buffer_type(),
177 _buffer->get_fb_properties());
180 _gsg->framebuffer_copy_to_ram(_texture, 0, -1,
181 _overlay_display_region, buffer);
185 size_t framebuffer_size = _swbuffer->get_framebuffer_size();
186 nassertv(image.size() == framebuffer_size);
188 if (!_swbuffer->ready_for_write()) {
196 while (!_swbuffer->ready_for_write()) {
199 if (now - start > subprocess_window_max_wait) {
207 void *target = _swbuffer->open_write_framebuffer();
208 memcpy(target, image.
p(), framebuffer_size);
209 _swbuffer->close_write_framebuffer();
227 void SubprocessWindow::
231 if (window_handle !=
nullptr) {
233 if (os_handle !=
nullptr) {
234 if (os_handle->
is_of_type(NativeWindowHandle::SubprocessHandle::get_class_type())) {
236 filename = subprocess_handle->get_filename();
241 if (!filename.empty() && filename != _filename) {
244 display_cat.info() <<
"Re-opening SubprocessWindow\n";
245 internal_close_window();
247 _properties.add_properties(properties);
250 internal_open_window();
251 set_size_and_recalc(_properties.get_x_size(), _properties.get_y_size());
252 throw_event(get_window_event(),
this);
271 void SubprocessWindow::
273 internal_close_window();
278 system_changed_properties(properties);
285 bool SubprocessWindow::
287 if (!internal_open_window()) {
294 system_changed_properties(properties);
303 void SubprocessWindow::
304 internal_close_window() {
305 if (_swbuffer !=
nullptr) {
307 (_fd, _mmap_size, _filename.to_os_specific(), _swbuffer);
309 _filename = string();
314 if (_buffer !=
nullptr) {
315 _buffer->request_close();
316 _buffer->process_events();
317 _engine->remove_window(_buffer);
322 if (_window_handle !=
nullptr &&
323 _parent_window_handle !=
nullptr) {
324 _parent_window_handle->detach_child(_window_handle);
327 _window_handle =
nullptr;
328 _parent_window_handle =
nullptr;
336 bool SubprocessWindow::
337 internal_open_window() {
338 nassertr(_buffer ==
nullptr,
false);
341 int flags = _creation_flags;
342 flags = ((flags & ~
GraphicsPipe::BF_require_window) | GraphicsPipe::BF_refuse_window);
346 _engine->make_output(_pipe, _name, 0, _fb_properties, win_props,
348 if (buffer !=
nullptr) {
352 _buffer->set_active(
false);
354 _buffer->request_open();
355 _buffer->process_events();
357 _is_valid = _buffer->is_valid();
362 <<
"Failed to open SubprocessWindowBuffer's internal offscreen buffer.\n";
366 _gsg = _buffer->get_gsg();
368 WindowHandle *window_handle = _properties.get_parent_window();
369 if (window_handle !=
nullptr) {
371 if (os_handle !=
nullptr) {
372 if (os_handle->
is_of_type(NativeWindowHandle::SubprocessHandle::get_class_type())) {
374 _filename = subprocess_handle->get_filename();
378 _parent_window_handle = window_handle;
380 if (_filename.empty()) {
383 <<
"No filename given to SubprocessWindow.\n";
388 (_fd, _mmap_size, _filename.to_os_specific());
390 if (_swbuffer ==
nullptr) {
393 _filename = string();
396 <<
"Failed to open SubprocessWindowBuffer's shared-memory buffer " 397 << _filename <<
"\n";
401 if (display_cat.is_debug()) {
403 <<
"SubprocessWindow reading " << _filename <<
"\n";
407 _window_handle = NativeWindowHandle::make_subprocess(_filename);
410 if (_parent_window_handle !=
nullptr) {
411 _parent_window_handle->attach_child(_window_handle);
423 translate_key(
int &keycode,
int os_code,
unsigned int flags)
const {
428 switch ((os_code >> 8) & 0xff) {
481 case 49: nk = KeyboardButton::space();
break;
482 case 51: nk = KeyboardButton::backspace();
break;
483 case 48: nk = KeyboardButton::tab();
break;
484 case 53: nk = KeyboardButton::escape();
break;
485 case 76: nk = KeyboardButton::enter();
break;
486 case 36: nk = KeyboardButton::enter();
break;
488 case 123: nk = KeyboardButton::left();
break;
489 case 124: nk = KeyboardButton::right();
break;
490 case 125: nk = KeyboardButton::down();
break;
491 case 126: nk = KeyboardButton::up();
break;
492 case 116: nk = KeyboardButton::page_up();
break;
493 case 121: nk = KeyboardButton::page_down();
break;
494 case 115: nk = KeyboardButton::home();
break;
495 case 119: nk = KeyboardButton::end();
break;
496 case 114: nk = KeyboardButton::help();
break;
497 case 117: nk = KeyboardButton::del();
break;
501 case 122: nk = KeyboardButton::f1();
break;
502 case 120: nk = KeyboardButton::f2();
break;
503 case 99: nk = KeyboardButton::f3();
break;
504 case 118: nk = KeyboardButton::f4();
break;
505 case 96: nk = KeyboardButton::f5();
break;
506 case 97: nk = KeyboardButton::f6();
break;
507 case 98: nk = KeyboardButton::f7();
break;
508 case 100: nk = KeyboardButton::f8();
break;
509 case 101: nk = KeyboardButton::f9();
break;
510 case 109: nk = KeyboardButton::f10();
break;
511 case 103: nk = KeyboardButton::f11();
break;
512 case 111: nk = KeyboardButton::f12();
break;
514 case 105: nk = KeyboardButton::f13();
break;
515 case 107: nk = KeyboardButton::f14();
break;
516 case 113: nk = KeyboardButton::f15();
break;
517 case 106: nk = KeyboardButton::f16();
break;
543 keycode = os_code & 0xff;
555 void SubprocessWindow::
556 transition_button(
unsigned int flags,
ButtonHandle button) {
558 _input->button_down(button);
560 _input->button_up(button);
565 #endif // SUPPORT_SUBPROCESS_WINDOW bool is_any_specified() const
Returns true if any properties have been specified, false otherwise.
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.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_parent_window
Returns the parent window specification, or NULL if there is no parent window 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-...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
has_parent_window
Checks the S_parent_window specification from the properties.
get_os_handle
Returns the OS-specific handle stored internally to the WindowHandle wrapper.
static WindowProperties size(const LVecBase2i &size)
Returns a WindowProperties structure with only the size specified.
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...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for the various kinds of properties we might ask to have on a graphics window before we o...
static void close_buffer(int fd, size_t mmap_size, const std::string &filename, SubprocessWindowBuffer *buffer)
Closes a buffer object created via a previous call to open_buffer().
An offscreen buffer for rendering into.
The name of a file, such as a texture file or an Egg file.
const Element * p() const
Function p() is similar to the function from ConstPointerTo.
A ClockObject keeps track of elapsed real time and discrete time.
An object to create GraphicsOutputs that share a particular 3-D API.
get_real_time
Returns the actual number of seconds elapsed since the ClockObject was created, or since it was last ...
This is a base class for the various different classes that represent the result of a frame of render...
A thread; that is, a lightweight process.
Encapsulates all the communication with a particular instance of a given rendering backend.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
This class is the main interface to controlling the render process.
TypeHandle is the identifier used to differentiate C++ class types.
clear_parent_window
Removes the S_parent_window specification from the properties.
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
set_open
Specifies whether the window should be open.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A RenderBuffer is an arbitrary subset of the various layers (depth buffer, color buffer,...
Similar to PointerToArray, except that its contents may not be modified.
set_foreground
Specifies whether the window should be opened in the foreground (true), or left in the background (fa...
static SubprocessWindowBuffer * open_buffer(int &fd, size_t &mmap_size, const std::string &filename)
Call this method to open a reference to an existing buffer in shared memory space.