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);
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
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.
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 has_parent_window() const
Checks the S_parent_window specification from the properties.
virtual void detach_child(WindowHandle *child)
Called on a parent handle to indicate a child window's intention to detach itself.
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...
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.
OSHandle * get_os_handle() const
Returns the OS-specific handle stored internally to the WindowHandle wrapper.
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.
double get_real_time() const
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...
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...
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.
WindowHandle * get_parent_window() const
Returns the parent window specification, or NULL if there is no parent window specified.
TypeHandle is the identifier used to differentiate C++ class types.
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.