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