15 #include "eglGraphicsWindow.h" 16 #include "eglGraphicsStateGuardian.h" 17 #include "config_egldisplay.h" 18 #include "eglGraphicsPipe.h" 20 #include "graphicsPipe.h" 21 #include "keyboardButton.h" 22 #include "mouseButton.h" 23 #include "clockObject.h" 24 #include "pStatTimer.h" 25 #include "textEncoder.h" 26 #include "throw_event.h" 27 #include "lightReMutexHolder.h" 28 #include "nativeWindowHandle.h" 34 #ifdef HAVE_LINUX_INPUT_H 35 #include <linux/input.h> 40 #define test_bit(bit, array) ((array)[(bit)/8] & (1<<((bit)&7))) 55 GraphicsWindow(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
58 DCAST_INTO_V(egl_pipe, _pipe);
61 _xwindow = (X11_Window)NULL;
63 _egl_display = egl_pipe->_egl_display;
65 _awaiting_configure =
false;
66 _wm_delete_window = egl_pipe->_wm_delete_window;
67 _net_wm_window_type = egl_pipe->_net_wm_window_type;
68 _net_wm_window_type_splash = egl_pipe->_net_wm_window_type_splash;
69 _net_wm_window_type_fullscreen = egl_pipe->_net_wm_window_type_fullscreen;
70 _net_wm_state = egl_pipe->_net_wm_state;
71 _net_wm_state_fullscreen = egl_pipe->_net_wm_state_fullscreen;
72 _net_wm_state_above = egl_pipe->_net_wm_state_above;
73 _net_wm_state_below = egl_pipe->_net_wm_state_below;
74 _net_wm_state_add = egl_pipe->_net_wm_state_add;
75 _net_wm_state_remove = egl_pipe->_net_wm_state_remove;
79 add_input_device(device);
88 ~eglGraphicsWindow() {
107 if (!_properties.get_foreground() ||
108 !_input_devices[0].get_pointer().get_in_window()) {
114 const MouseData &md = _input_devices[0].get_pointer();
115 if (!md.get_in_window() || md.get_x() != x || md.get_y() != y) {
116 XWarpPointer(_display, None, _xwindow, 0, 0, 0, 0, x, y);
117 _input_devices[0].set_pointer_in_window(x, y);
122 if ((device < 1)||(device >= _input_devices.size())) {
125 _input_devices[device].set_pointer_in_window(x, y);
142 PStatTimer timer(_make_current_pcollector, current_thread);
144 begin_frame_spam(mode);
148 if (_awaiting_configure) {
155 DCAST_INTO_R(eglgsg, _gsg,
false);
159 if (eglGetCurrentDisplay() == _egl_display &&
160 eglGetCurrentSurface(EGL_READ) == _egl_surface &&
161 eglGetCurrentSurface(EGL_DRAW) == _egl_surface &&
162 eglGetCurrentContext() == eglgsg->_context) {
167 if (!eglMakeCurrent(_egl_display, _egl_surface, _egl_surface, eglgsg->_context)) {
168 egldisplay_cat.error() <<
"Failed to call eglMakeCurrent: " 169 << get_egl_error_string(eglGetError()) <<
"\n";
178 eglgsg->reset_if_new();
180 if (mode == FM_render) {
182 clear_cube_map_selection();
186 return _gsg->begin_frame(current_thread);
198 end_frame_spam(mode);
201 if (mode == FM_render) {
206 _gsg->end_frame(current_thread);
208 if (mode == FM_render) {
210 clear_cube_map_selection();
235 eglSwapBuffers(_egl_display, _egl_surface);
256 if (_xwindow == (X11_Window)0) {
263 XKeyEvent keyrelease_event;
264 bool got_keyrelease_event =
false;
266 while (XCheckIfEvent(_display, &event, check_event, (
char *)
this)) {
267 if (XFilterEvent(&event, None)) {
271 if (got_keyrelease_event) {
277 got_keyrelease_event =
false;
279 if (event.type == KeyPress &&
280 event.xkey.keycode == keyrelease_event.keycode &&
281 (event.xkey.time - keyrelease_event.time <= 1)) {
284 handle_keystroke(event.xkey);
288 handle_keypress(event.xkey);
294 handle_keyrelease(keyrelease_event);
301 switch (event.type) {
305 case ConfigureNotify:
306 _awaiting_configure =
false;
307 if (_properties.get_fixed_size()) {
315 if (event.xconfigure.width != current_props.
get_x_size() ||
316 event.xconfigure.height != current_props.
get_y_size()) {
317 XWindowChanges changes;
320 int value_mask = (CWWidth | CWHeight);
321 XConfigureWindow(_display, _xwindow, value_mask, &changes);
326 properties.
set_size(event.xconfigure.width, event.xconfigure.height);
327 system_changed_properties(properties);
333 button = get_mouse_button(event.xbutton);
334 _input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y);
335 _input_devices[0].button_down(button);
339 button = get_mouse_button(event.xbutton);
340 _input_devices[0].set_pointer_in_window(event.xbutton.x, event.xbutton.y);
341 _input_devices[0].button_up(button);
345 _input_devices[0].set_pointer_in_window(event.xmotion.x, event.xmotion.y);
349 handle_keystroke(event.xkey);
350 handle_keypress(event.xkey);
357 keyrelease_event =
event.xkey;
358 got_keyrelease_event =
true;
362 _input_devices[0].set_pointer_in_window(event.xcrossing.x, event.xcrossing.y);
366 _input_devices[0].set_pointer_out_of_window();
371 system_changed_properties(properties);
376 system_changed_properties(properties);
381 system_changed_properties(properties);
386 system_changed_properties(properties);
389 XSetInputFocus(_display, _xwindow, RevertToPointerRoot, CurrentTime);
393 if ((Atom)(event.xclient.data.l[0]) == _wm_delete_window) {
397 if (!close_request_event.empty()) {
400 throw_event(close_request_event);
409 system_changed_properties(properties);
418 egldisplay_cat.info()
419 <<
"DestroyNotify\n";
423 egldisplay_cat.error()
424 <<
"unhandled X event type " <<
event.type <<
"\n";
428 if (got_keyrelease_event) {
431 handle_keyrelease(keyrelease_event);
461 DCAST_INTO_V(egl_pipe, _pipe);
491 _properties.set_title(properties.
get_title());
505 XWindowChanges changes;
511 value_mask |= (CWX | CWY);
517 value_mask |= (CWWidth | CWHeight);
527 case WindowProperties::Z_bottom:
528 changes.stack_mode = Below;
531 case WindowProperties::Z_normal:
532 changes.stack_mode = TopIf;
535 case WindowProperties::Z_top:
536 changes.stack_mode = Above;
540 value_mask |= (CWStackMode);
544 if (value_mask != 0) {
545 XReconfigureWMWindow(_display, _xwindow, _screen, value_mask, &changes);
548 _awaiting_configure =
true;
557 XDefineCursor(_display, _xwindow, None);
564 XSetInputFocus(_display, _xwindow, RevertToPointerRoot, CurrentTime);
566 XSetInputFocus(_display, PointerRoot, RevertToPointerRoot, CurrentTime);
571 set_wm_properties(wm_properties,
true);
580 void eglGraphicsWindow::
583 if (!eglMakeCurrent(_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
584 egldisplay_cat.error() <<
"Failed to call eglMakeCurrent: " 585 << get_egl_error_string(eglGetError()) <<
"\n";
590 if (_ic != (XIC)NULL) {
595 if (_egl_surface != 0) {
596 if (!eglDestroySurface(_egl_display, _egl_surface)) {
597 egldisplay_cat.error() <<
"Failed to destroy surface: " 598 << get_egl_error_string(eglGetError()) <<
"\n";
602 if (_xwindow != (X11_Window)NULL) {
603 XDestroyWindow(_display, _xwindow);
604 _xwindow = (X11_Window)NULL;
610 GraphicsWindow::close_window();
620 bool eglGraphicsWindow::
623 DCAST_INTO_R(egl_pipe, _pipe,
false);
635 DCAST_INTO_R(eglgsg, _gsg,
false);
643 XVisualInfo *visual_info = eglgsg->_visual;
644 if (visual_info == NULL) {
646 egldisplay_cat.error()
647 <<
"No X visual: cannot open window.\n";
650 Visual *visual = visual_info->visual;
651 int depth = visual_info->depth;
653 if (!_properties.has_origin()) {
654 _properties.set_origin(0, 0);
656 if (!_properties.has_size()) {
657 _properties.set_size(100, 100);
660 X11_Window parent_window = egl_pipe->
get_root();
661 WindowHandle *window_handle = _properties.get_parent_window();
662 if (window_handle != NULL) {
663 egldisplay_cat.info()
664 <<
"Got parent_window " << *window_handle <<
"\n";
666 if (os_handle != NULL) {
667 egldisplay_cat.info()
668 <<
"os_handle type " << os_handle->get_type() <<
"\n";
670 if (os_handle->
is_of_type(NativeWindowHandle::X11Handle::get_class_type())) {
671 NativeWindowHandle::X11Handle *x11_handle = DCAST(NativeWindowHandle::X11Handle, os_handle);
672 parent_window = x11_handle->get_handle();
673 }
else if (os_handle->
is_of_type(NativeWindowHandle::IntHandle::get_class_type())) {
675 parent_window = (X11_Window)int_handle->get_handle();
679 _parent_window_handle = window_handle;
681 setup_colormap(visual_info);
684 ButtonPressMask | ButtonReleaseMask |
685 KeyPressMask | KeyReleaseMask |
686 EnterWindowMask | LeaveWindowMask |
692 XSetWindowAttributes wa;
693 wa.background_pixel = XBlackPixel(_display, _screen);
695 wa.colormap = _colormap;
696 wa.event_mask = _event_mask;
698 unsigned long attrib_mask =
699 CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
701 _xwindow = XCreateWindow
702 (_display, parent_window,
703 _properties.get_x_origin(), _properties.get_y_origin(),
704 _properties.get_x_size(), _properties.get_y_size(),
705 0, depth, InputOutput, visual, attrib_mask, &wa);
707 if (_xwindow == (X11_Window)0) {
708 egldisplay_cat.error()
709 <<
"failed to create X window.\n";
712 set_wm_properties(_properties,
false);
718 XIM im = egl_pipe->
get_im();
723 XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
725 if (_ic == (XIC)NULL) {
726 egldisplay_cat.warning()
727 <<
"Couldn't create input context.\n";
731 if (_properties.get_cursor_hidden()) {
735 _egl_surface = eglCreateWindowSurface(_egl_display, eglgsg->_fbconfig, (NativeWindowType) _xwindow, NULL);
736 if (eglGetError() != EGL_SUCCESS) {
737 egldisplay_cat.error()
738 <<
"Failed to create window surface.\n";
742 if (!eglMakeCurrent(_egl_display, _egl_surface, _egl_surface, eglgsg->_context)) {
743 egldisplay_cat.error() <<
"Failed to call eglMakeCurrent: " 744 << get_egl_error_string(eglGetError()) <<
"\n";
746 eglgsg->reset_if_new();
747 if (!eglgsg->is_valid()) {
752 (_fb_properties, eglgsg->get_gl_renderer())) {
758 XMapWindow(_display, _xwindow);
760 if (_properties.get_raw_mice()) {
763 if (egldisplay_cat.is_debug()) {
764 egldisplay_cat.debug()
765 <<
"Raw mice not requested.\n";
770 _window_handle = NativeWindowHandle::make_x11(_xwindow);
774 _parent_window_handle->attach_child(_window_handle);
793 void eglGraphicsWindow::
794 set_wm_properties(
const WindowProperties &properties,
bool already_mapped) {
796 XTextProperty window_name;
797 XTextProperty *window_name_p = (XTextProperty *)NULL;
799 char *name = (
char *)properties.
get_title().c_str();
800 if (XStringListToTextProperty(&name, 1, &window_name) != 0) {
801 window_name_p = &window_name;
807 XSizeHints *size_hints_p = NULL;
809 size_hints_p = XAllocSizeHints();
810 if (size_hints_p != (XSizeHints *)NULL) {
814 size_hints_p->flags |= USPosition;
817 size_hints_p->width = properties.
get_x_size();
818 size_hints_p->height = properties.
get_y_size();
819 size_hints_p->flags |= USSize;
822 size_hints_p->min_width = properties.
get_x_size();
823 size_hints_p->min_height = properties.
get_y_size();
824 size_hints_p->max_width = properties.
get_x_size();
825 size_hints_p->max_height = properties.
get_y_size();
826 size_hints_p->flags |= (PMinSize | PMaxSize);
834 XWMHints *wm_hints_p = NULL;
835 wm_hints_p = XAllocWMHints();
836 if (wm_hints_p != (XWMHints *)NULL) {
838 wm_hints_p->initial_state = IconicState;
840 wm_hints_p->initial_state = NormalState;
842 wm_hints_p->flags = StateHint;
848 static const int max_type_data = 32;
849 PN_int32 type_data[max_type_data];
850 int next_type_data = 0;
852 static const int max_state_data = 32;
853 PN_int32 state_data[max_state_data];
854 int next_state_data = 0;
856 static const int max_set_data = 32;
859 inline SetAction() { }
860 inline SetAction(Atom state, Atom action) : _state(state), _action(action) { }
864 SetAction set_data[max_set_data];
865 int next_set_data = 0;
870 type_data[next_type_data++] = _net_wm_window_type_fullscreen;
873 state_data[next_state_data++] = _net_wm_state_fullscreen;
874 set_data[next_set_data++] = SetAction(_net_wm_state_fullscreen, _net_wm_state_add);
876 set_data[next_set_data++] = SetAction(_net_wm_state_fullscreen, _net_wm_state_remove);
888 XClassHint *class_hints_p = NULL;
890 class_hints_p = XAllocClassHint();
891 class_hints_p->res_class = (
char*)
"Undecorated";
894 type_data[next_type_data++] = _net_wm_window_type_splash;
900 case WindowProperties::Z_bottom:
901 state_data[next_state_data++] = _net_wm_state_below;
902 set_data[next_set_data++] = SetAction(_net_wm_state_below, _net_wm_state_add);
903 set_data[next_set_data++] = SetAction(_net_wm_state_above, _net_wm_state_remove);
906 case WindowProperties::Z_normal:
907 set_data[next_set_data++] = SetAction(_net_wm_state_below, _net_wm_state_remove);
908 set_data[next_set_data++] = SetAction(_net_wm_state_above, _net_wm_state_remove);
911 case WindowProperties::Z_top:
912 state_data[next_state_data++] = _net_wm_state_above;
913 set_data[next_set_data++] = SetAction(_net_wm_state_below, _net_wm_state_remove);
914 set_data[next_set_data++] = SetAction(_net_wm_state_above, _net_wm_state_add);
919 nassertv(next_type_data < max_type_data);
920 nassertv(next_state_data < max_state_data);
921 nassertv(next_set_data < max_set_data);
923 XChangeProperty(_display, _xwindow, _net_wm_window_type,
924 XA_ATOM, 32, PropModeReplace,
925 (
unsigned char *)type_data, next_type_data);
928 XChangeProperty(_display, _xwindow, _net_wm_state,
929 XA_ATOM, 32, PropModeReplace,
930 (
unsigned char *)state_data, next_state_data);
932 if (already_mapped) {
938 DCAST_INTO_V(egl_pipe, _pipe);
940 for (
int i = 0; i < next_set_data; ++i) {
941 XClientMessageEvent event;
942 memset(&event, 0,
sizeof(event));
944 event.type = ClientMessage;
945 event.send_event = True;
946 event.display = _display;
947 event.window = _xwindow;
948 event.message_type = _net_wm_state;
950 event.data.l[0] = set_data[i]._action;
951 event.data.l[1] = set_data[i]._state;
955 XSendEvent(_display, egl_pipe->
get_root(), True, 0, (XEvent *)&event);
959 XSetWMProperties(_display, _xwindow, window_name_p, window_name_p,
960 NULL, 0, size_hints_p, wm_hints_p, class_hints_p);
962 if (size_hints_p != (XSizeHints *)NULL) {
965 if (wm_hints_p != (XWMHints *)NULL) {
968 if (class_hints_p != (XClassHint *)NULL) {
969 XFree(class_hints_p);
980 XSetWMProtocols(_display, _xwindow, protocols,
981 sizeof(protocols) /
sizeof(Atom));
990 void eglGraphicsWindow::
991 setup_colormap(XVisualInfo *visual) {
993 DCAST_INTO_V(egl_pipe, _pipe);
994 X11_Window root_window = egl_pipe->
get_root();
996 int visual_class = visual->c_class;
999 switch (visual_class) {
1001 _colormap = XCreateColormap(_display, root_window,
1002 visual->visual, AllocAll);
1006 _colormap = XCreateColormap(_display, root_window,
1007 visual->visual, AllocNone);
1012 _colormap = XCreateColormap(_display, root_window,
1013 visual->visual, AllocNone);
1016 egldisplay_cat.error()
1017 <<
"Could not allocate a colormap for visual class " 1018 << visual_class <<
".\n";
1028 void eglGraphicsWindow::
1031 #ifdef HAVE_LINUX_INPUT_H 1032 bool any_present =
false;
1033 bool any_mice =
false;
1035 for (
int i=0; i<64; i++) {
1036 uint8_t evtypes[EV_MAX/8 + 1];
1038 fnb <<
"/dev/input/event" << i;
1039 string fn = fnb.str();
1040 int fd = open(fn.c_str(), O_RDONLY | O_NONBLOCK, 0);
1046 if ((ioctl(fd, EVIOCGNAME(
sizeof(name)), name) < 0)||
1047 (ioctl(fd, EVIOCGPHYS(
sizeof(phys)), phys) < 0)||
1048 (ioctl(fd, EVIOCGPHYS(
sizeof(uniq)), uniq) < 0)||
1049 (ioctl(fd, EVIOCGBIT(0, EV_MAX), &evtypes) < 0)) {
1051 egldisplay_cat.error() <<
1052 "Opening raw mice: ioctl failed on " << fn <<
"\n";
1054 if (test_bit(EV_REL, evtypes) || test_bit(EV_ABS, evtypes)) {
1055 for (
char *p=name; *p; p++) {
1056 if (((*p<
'a')||(*p>
'z')) && ((*p<
'A')||(*p>
'Z')) && ((*p<
'0')||(*p>
'9'))) {
1060 for (
char *p=uniq; *p; p++) {
1061 if (((*p<
'a')||(*p>
'z')) && ((*p<
'A')||(*p>
'Z')) && ((*p<
'0')||(*p>
'9'))) {
1065 string full_id = ((string)name) +
"." + uniq;
1066 MouseDeviceInfo inf;
1068 inf._input_device_index = _input_devices.size();
1069 inf._io_buffer =
"";
1070 _mouse_device_info.push_back(inf);
1073 add_input_device(device);
1074 egldisplay_cat.info() <<
"Raw mouse " <<
1075 inf._input_device_index <<
" detected: " << full_id <<
"\n";
1082 if ((errno == ENOENT)||(errno == ENOTDIR)) {
1086 egldisplay_cat.error() <<
1087 "Opening raw mice: " << strerror(errno) <<
" " << fn <<
"\n";
1093 egldisplay_cat.error() <<
1094 "Opening raw mice: files not found: /dev/input/event*\n";
1095 }
else if (!any_mice) {
1096 egldisplay_cat.error() <<
1097 "Opening raw mice: no mouse devices detected in /dev/input/event*\n";
1100 egldisplay_cat.error() <<
1101 "Opening raw mice: panda not compiled with raw mouse support.\n";
1110 void eglGraphicsWindow::
1113 #ifdef HAVE_LINUX_INPUT_H 1114 for (
int dev=0; dev<_mouse_device_info.size(); dev++) {
1115 MouseDeviceInfo &inf = _mouse_device_info[dev];
1121 int nread = read(inf._fd, tbuf,
sizeof(tbuf));
1123 inf._io_buffer += string(tbuf, nread);
1125 if ((nread < 0)&&((errno == EWOULDBLOCK) || (errno==EAGAIN))) {
1136 int nevents = inf._io_buffer.size() /
sizeof(
struct input_event);
1140 const input_event *events = (
const input_event *)(inf._io_buffer.c_str());
1144 for (
int i=0; i<nevents; i++) {
1145 if (events[i].type == EV_REL) {
1146 if (events[i].code == REL_X) x += events[i].value;
1147 if (events[i].code == REL_Y) y += events[i].value;
1148 }
else if (events[i].type == EV_ABS) {
1149 if (events[i].code == ABS_X) x = events[i].value;
1150 if (events[i].code == ABS_Y) y = events[i].value;
1151 }
else if (events[i].type == EV_KEY) {
1152 if ((events[i].code >= BTN_MOUSE)&&(events[i].code < BTN_MOUSE+8)) {
1153 int btn = events[i].code - BTN_MOUSE;
1155 if (events[i].value) {
1163 inf._io_buffer.erase(0,nevents*
sizeof(
struct input_event));
1175 void eglGraphicsWindow::
1176 handle_keystroke(XKeyEvent &event) {
1177 _input_devices[0].set_pointer_in_window(event.x, event.y);
1181 static const int buffer_size = 256;
1182 wchar_t buffer[buffer_size];
1184 int len = XwcLookupString(_ic, &event, buffer, buffer_size, NULL,
1186 if (status == XBufferOverflow) {
1187 egldisplay_cat.error()
1188 <<
"Overflowed input buffer.\n";
1193 for (
int i = 0; i < len; i++) {
1194 _input_devices[0].keystroke(buffer[i]);
1212 void eglGraphicsWindow::
1213 handle_keypress(XKeyEvent &event) {
1214 _input_devices[0].set_pointer_in_window(event.x, event.y);
1219 if (button == KeyboardButton::lcontrol() || button == KeyboardButton::rcontrol()) {
1220 _input_devices[0].button_down(KeyboardButton::control());
1222 if (button == KeyboardButton::lshift() || button == KeyboardButton::rshift()) {
1223 _input_devices[0].button_down(KeyboardButton::shift());
1225 if (button == KeyboardButton::lalt() || button == KeyboardButton::ralt()) {
1226 _input_devices[0].button_down(KeyboardButton::alt());
1228 if (button == KeyboardButton::lmeta() || button == KeyboardButton::rmeta()) {
1229 _input_devices[0].button_down(KeyboardButton::meta());
1231 _input_devices[0].button_down(button);
1241 void eglGraphicsWindow::
1242 handle_keyrelease(XKeyEvent &event) {
1243 _input_devices[0].set_pointer_in_window(event.x, event.y);
1248 if (button == KeyboardButton::lcontrol() || button == KeyboardButton::rcontrol()) {
1249 _input_devices[0].button_up(KeyboardButton::control());
1251 if (button == KeyboardButton::lshift() || button == KeyboardButton::rshift()) {
1252 _input_devices[0].button_up(KeyboardButton::shift());
1254 if (button == KeyboardButton::lalt() || button == KeyboardButton::ralt()) {
1255 _input_devices[0].button_up(KeyboardButton::alt());
1257 if (button == KeyboardButton::lmeta() || button == KeyboardButton::rmeta()) {
1258 _input_devices[0].button_up(KeyboardButton::meta());
1260 _input_devices[0].button_up(button);
1271 get_button(XKeyEvent &key_event,
bool allow_shift) {
1272 KeySym key = XLookupKeysym(&key_event, 0);
1274 if ((key_event.state & Mod2Mask) != 0) {
1289 case XK_KP_Multiply:
1291 case XK_KP_Separator:
1292 case XK_KP_Subtract:
1315 k2 = XLookupKeysym(&key_event, 1);
1316 button = map_button(k2);
1331 if ((key_event.state & ShiftMask) != 0) {
1332 KeySym k2 = XLookupKeysym(&key_event, 1);
1342 if ((key_event.state & (ShiftMask | LockMask)) != 0) {
1343 if (key >= XK_a and key <= XK_z) {
1344 key += (XK_A - XK_a);
1349 return map_button(key);
1359 map_button(KeySym key) {
1362 return KeyboardButton::backspace();
1365 return KeyboardButton::tab();
1368 return KeyboardButton::enter();
1370 return KeyboardButton::escape();
1373 return KeyboardButton::space();
1393 case XK_KP_Multiply:
1399 case XK_KP_Separator:
1402 case XK_KP_Subtract:
1507 case XK_bracketleft:
1511 case XK_bracketright:
1513 case XK_asciicircum:
1581 return KeyboardButton::f1();
1584 return KeyboardButton::f2();
1587 return KeyboardButton::f3();
1590 return KeyboardButton::f4();
1592 return KeyboardButton::f5();
1594 return KeyboardButton::f6();
1596 return KeyboardButton::f7();
1598 return KeyboardButton::f8();
1600 return KeyboardButton::f9();
1602 return KeyboardButton::f10();
1604 return KeyboardButton::f11();
1606 return KeyboardButton::f12();
1609 return KeyboardButton::left();
1612 return KeyboardButton::up();
1615 return KeyboardButton::right();
1618 return KeyboardButton::down();
1621 return KeyboardButton::page_up();
1624 return KeyboardButton::page_down();
1627 return KeyboardButton::home();
1630 return KeyboardButton::end();
1633 return KeyboardButton::insert();
1636 return KeyboardButton::del();
1638 return KeyboardButton::num_lock();
1639 case XK_Scroll_Lock:
1640 return KeyboardButton::scroll_lock();
1642 return KeyboardButton::print_screen();
1644 return KeyboardButton::pause();
1646 return KeyboardButton::menu();
1648 return KeyboardButton::lshift();
1650 return KeyboardButton::rshift();
1652 return KeyboardButton::lcontrol();
1654 return KeyboardButton::rcontrol();
1656 return KeyboardButton::lalt();
1658 return KeyboardButton::ralt();
1660 return KeyboardButton::lmeta();
1662 return KeyboardButton::rmeta();
1664 return KeyboardButton::caps_lock();
1666 return KeyboardButton::shift_lock();
1679 get_mouse_button(XButtonEvent &button_event) {
1680 int index = button_event.button;
1681 if (index == x_wheel_up_button) {
1683 }
else if (index == x_wheel_down_button) {
1685 }
else if (index == x_wheel_left_button) {
1687 }
else if (index == x_wheel_right_button) {
1701 Bool eglGraphicsWindow::
1702 check_event(X11_Display *display, XEvent *event,
char *arg) {
1706 return (event->xany.window == self->_xwindow);
bool is_any_specified() const
Returns true if any properties have been specified, false otherwise.
virtual void process_events()
Do whatever processing is necessary to ensure that the window responds to user events.
int get_display_width() const
Returns the width of the entire display, if it is known.
This object represents a window on the desktop, not necessarily a Panda window.
bool get_foreground() const
Returns true if the window is in the foreground.
virtual void set_properties_now(WindowProperties &properties)
Applies the requested set of properties to the window, if possible, for instance to request a change ...
virtual void end_flip()
This function will be called within the draw thread after begin_flip() has been called on all windows...
void clear_foreground()
Removes the foreground specification from the properties.
bool get_fixed_size() const
Returns true if the window cannot be resized by the user, false otherwise.
virtual void end_frame(FrameMode mode, Thread *current_thread)
This function will be called within the draw thread after rendering is completed for a given frame...
void clear_origin()
Removes the origin specification from the properties.
ZOrder get_z_order() const
Returns the window's z_order.
bool get_undecorated() const
Returns true if the window has no border.
virtual void set_properties_now(WindowProperties &properties)
Applies the requested set of properties to the window, if possible, for instance to request a change ...
bool get_minimized() const
Returns true if the window is minimized.
An interface to the egl system for managing GLES windows under X.
void set_size(const LVector2i &size)
Specifies the requested size of the window, in pixels.
X11_Window get_root() const
Returns the handle to the root window on the pipe's display.
bool has_origin() const
Returns true if the window origin has been specified, false otherwise.
int get_display_height() const
Returns the height of the entire display, if it is known.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
void clear_title()
Removes the title specification from the properties.
const string & get_title() const
Returns the window's title.
int get_y_origin() const
Returns the y coordinate of the window's top-left corner, not including decorations.
string get_close_request_event() const
Returns the name of the event set via set_close_request_event().
This graphics pipe represents the interface for creating OpenGL ES graphics windows on an X-based (e...
int get_screen() const
Returns the X screen number associated with the pipe.
const WindowProperties get_properties() const
Returns the current properties of the window.
A window, fullscreen or on a desktop, into which a graphics device sends its output for interactive d...
const FrameBufferProperties & get_fb_properties() const
Gets the FrameBufferProperties for all windows and buffers that use this GSG.
XIM get_im() const
Returns the input method opened for the pipe, or NULL if the input method could not be opened for som...
bool has_fullscreen() const
Returns true if set_fullscreen() has been specified.
void set_undecorated(bool undecorated)
Specifies whether the window should be created with a visible title and border (false, the default) or not (true).
X11_Display * get_display() const
Returns a pointer to the X display associated with the pipe: the display on which to create the windo...
A container for the various kinds of properties we might ask to have on a graphics window before we o...
OSHandle * get_os_handle() const
Returns the OS-specific handle stored internally to the WindowHandle wrapper.
bool get_fullscreen() const
Returns true if the window is in fullscreen mode.
void clear_size()
Removes the size specification from the properties.
An object to create GraphicsOutputs that share a particular 3-D API.
bool verify_hardware_software(const FrameBufferProperties &props, const string &renderer) const
Validates that the properties represent the desired kind of renderer (hardware or software)...
void set_origin(const LPoint2i &origin)
Specifies the origin on the screen (in pixels, relative to the top-left corner) at which the window s...
bool has_foreground() const
Returns true if set_foreground() has been specified.
bool has_cursor_hidden() const
Returns true if set_cursor_hidden() has been specified.
X11_Cursor get_hidden_cursor()
Returns an invisible Cursor suitable for assigning to windows that have the cursor_hidden property se...
This is a base class for the various different classes that represent the result of a frame of render...
Similar to MutexHolder, but for a light reentrant mutex.
void choose_pixel_format(const FrameBufferProperties &properties, X11_Display *_display, int _screen, bool need_pbuffer, bool need_pixmap)
Selects a visual or fbconfig for all the windows and buffers that use this gsg.
bool has_z_order() const
Returns true if the window z_order has been specified, false otherwise.
virtual void process_events()
Do whatever processing is necessary to ensure that the window responds to user events.
bool get_cursor_hidden() const
Returns true if the mouse cursor is invisible.
Holds the data that might be generated by a 2-d pointer input device, such as the mouse in the Graphi...
void set_foreground(bool foreground)
Specifies whether the window should be opened in the foreground (true), or left in the background (fa...
void clear_z_order()
Removes the z_order specification from the properties.
void add_properties(const WindowProperties &other)
Sets any properties that are explicitly specified in other on this object.
A thread; that is, a lightweight process.
void clear_cursor_hidden()
Removes the cursor_hidden specification from the properties.
void set_minimized(bool minimized)
Specifies whether the window should be created minimized (true), or normal (false).
bool has_minimized() const
Returns true if set_minimized() has been specified.
Encapsulates all the communication with a particular instance of a given rendering backend...
virtual bool move_pointer(int device, int x, int y)
Forces the pointer to the indicated position within the window, if possible.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
A tiny specialization on GLESGraphicsStateGuardian to add some egl-specific information.
bool subsumes(const FrameBufferProperties &other) const
Returns true if this set of properties makes strictly greater or equal demands of the framebuffer tha...
This class is the main interface to controlling the render process.
int get_y_size() const
Returns size in pixels in the y dimension of the useful part of the window, not including decorations...
virtual void end_flip()
This function will be called within the draw thread after begin_flip() has been called on all windows...
int get_x_size() const
Returns size in pixels in the x dimension of the useful part of the window, not including decorations...
bool has_title() const
Returns true if the window title has been specified, false otherwise.
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...
bool has_size() const
Returns true if the window size has been specified, false otherwise.
virtual bool begin_frame(FrameMode mode, Thread *current_thread)
This function will be called within the draw thread before beginning rendering for a given frame...
void set_open(bool open)
Specifies whether the window should be open.
int get_x_origin() const
Returns the x coordinate of the window's top-left corner, not including decorations.
void clear_fullscreen()
Removes the fullscreen specification from the properties.
const FrameBufferProperties & get_fb_properties() const
Returns the framebuffer properties of the window.