26 #include <X11/XKBlib.h>
27 #include <X11/Xatom.h>
28 #include <X11/Xutil.h>
29 #include <X11/keysym.h>
41 #ifdef WITH_INPUT_NDOF
51 #if defined(WITH_GL_EGL)
53 # include <EGL/eglext.h>
58 #ifdef WITH_XF86KEYSYM
59 # include <X11/XF86keysym.h>
62 #ifdef WITH_X11_XFIXES
63 # include <X11/extensions/Xfixes.h>
65 # define WITH_XWAYLAND_HACK
69 #ifdef WITH_X11_XINPUT
70 # include <X11/extensions/XInput2.h>
85 #ifdef WITH_X11_XINPUT
86 # define USE_XINPUT_HOTPLUG
90 #define USE_UNITY_WORKAROUND
94 #define USE_NON_LATIN_KB_WORKAROUND
98 return ptr[bit >> 3] & (1 << (bit & 7));
104 const XkbDescPtr xkb_descr,
105 const KeyCode keycode);
111 #ifdef WITH_XWAYLAND_HACK
112 static bool use_xwayland_hack =
false;
120 m_display = XOpenDisplay(
NULL);
123 std::cerr <<
"Unable to open a display" << std::endl;
127 #ifdef USE_X11_ERROR_HANDLERS
132 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
139 #define GHOST_INTERN_ATOM_IF_EXISTS(atom) \
141 m_atom.atom = XInternAtom(m_display, #atom, True); \
144 #define GHOST_INTERN_ATOM(atom) \
146 m_atom.atom = XInternAtom(m_display, #atom, False); \
170 #ifdef WITH_X11_XINPUT
171 m_atom.TABLET = XInternAtom(m_display, XI_TABLET, False);
174 #undef GHOST_INTERN_ATOM_IF_EXISTS
175 #undef GHOST_INTERN_ATOM
179 m_last_release_keycode = 0;
180 m_last_release_time = 0;
184 if (gettimeofday(&tv,
NULL) == -1) {
189 m_start_time =
GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000;
193 int xkb_opcode, xkb_event, xkb_error;
194 int xkb_major = XkbMajorVersion, xkb_minor = XkbMinorVersion;
196 use_xkb = XkbQueryExtension(
197 m_display, &xkb_opcode, &xkb_event, &xkb_error, &xkb_major, &xkb_minor);
199 XkbSetDetectableAutoRepeat(m_display,
true,
NULL);
201 m_xkb_descr = XkbGetMap(m_display, 0, XkbUseCoreKbd);
203 XkbGetNames(m_display, XkbKeyNamesMask, m_xkb_descr);
204 XkbGetControls(m_display, XkbPerKeyRepeatMask | XkbRepeatKeysMask, m_xkb_descr);
208 #ifdef WITH_XWAYLAND_HACK
209 use_xwayland_hack = getenv(
"WAYLAND_DISPLAY") !=
NULL;
212 #ifdef WITH_X11_XINPUT
215 memset(&m_xinput_version, 0,
sizeof(m_xinput_version));
216 XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);
217 if (version && (version != (XExtensionVersion *)NoSuchExtension)) {
218 if (version->present) {
219 m_xinput_version = *version;
225 # ifdef USE_XINPUT_HOTPLUG
226 if (m_xinput_version.present) {
227 XEventClass class_presence;
229 DevicePresence(m_display, xi_presence, class_presence);
230 XSelectExtensionEvent(
231 m_display, RootWindow(m_display, DefaultScreen(m_display)), &class_presence, 1);
236 refreshXInputDevices();
242 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
248 #ifdef WITH_X11_XINPUT
250 clearXInputDevices();
254 ::eglTerminate(::eglGetDisplay(m_display));
258 XkbFreeKeyboard(m_xkb_descr, XkbAllComponentsMask,
true);
261 XCloseDisplay(m_display);
269 #ifdef WITH_INPUT_NDOF
285 if (gettimeofday(&tv,
NULL) == -1) {
290 return GHOST_TUns64(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time;
319 width = DisplayWidth(m_display, DefaultScreen(m_display));
320 height = DisplayHeight(m_display, DefaultScreen(m_display));
349 const bool exclusive,
350 const bool is_dialog,
411 #if defined(WITH_GL_PROFILE_CORE)
413 const char *version_major = (
char *)glewGetString(GLEW_VERSION_MAJOR);
414 if (version_major !=
NULL && version_major[0] ==
'1') {
415 fprintf(stderr,
"Error: GLEW version 2.0 and above is required.\n");
421 const int profile_mask =
423 # if defined(WITH_GL_PROFILE_CORE)
424 EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT;
425 # elif defined(WITH_GL_PROFILE_COMPAT)
426 EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT;
431 # if defined(WITH_GL_PROFILE_CORE)
432 GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
433 # elif defined(WITH_GL_PROFILE_COMPAT)
434 GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
442 for (
int minor = 5; minor >= 0; --minor) {
443 #if defined(WITH_GL_EGL)
445 EGLNativeWindowType(
nullptr),
446 EGLNativeDisplayType(m_display),
451 (debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0),
463 (debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
467 if (
context->initializeDrawingContext())
473 #if defined(WITH_GL_EGL)
475 EGLNativeWindowType(
nullptr),
476 EGLNativeDisplayType(m_display),
481 (debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0),
493 (debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
497 if (
context->initializeDrawingContext())
517 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
518 static void destroyIMCallback(XIM , XPointer
ptr, XPointer )
526 bool GHOST_SystemX11::openX11_IM()
532 XSetLocaleModifiers(
"");
534 m_xim = XOpenIM(m_display,
NULL, (
char *)GHOST_X11_RES_NAME, (
char *)GHOST_X11_RES_CLASS);
539 destroy.callback = (XIMProc)destroyIMCallback;
540 destroy.client_data = (XPointer)&m_xim;
541 XSetIMValues(m_xim, XNDestroyCallback, &destroy,
NULL);
559 vector<GHOST_IWindow *>::const_iterator win_it = win_vec.begin();
560 vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end();
562 for (; win_it != win_end; ++win_it) {
573 int fd = ConnectionNumber(display);
579 if (maxSleep == -1) {
585 tv.tv_sec = maxSleep / 1000;
586 tv.tv_usec = (maxSleep - tv.tv_sec * 1000) * 1000;
602 switch (event->type) {
605 data->timestamp =
event->xbutton.time;
608 data->timestamp =
event->xmotion.time;
612 data->timestamp =
event->xkey.time;
615 data->timestamp =
event->xproperty.time;
619 data->timestamp =
event->xcrossing.time;
622 data->timestamp =
event->xselectionclear.time;
631 Time GHOST_SystemX11::lastEventTime(
Time default_time)
634 data.timestamp = default_time;
638 return data.timestamp;
646 bool anyProcessed =
false;
651 if (waitForEvent && m_dirty_windows.empty() && !XPending(m_display)) {
669 while (XPending(m_display)) {
671 XNextEvent(m_display, &xevent);
673 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
677 if (xevent.type == FocusIn || xevent.type == KeyPress) {
678 if (!m_xim && openX11_IM()) {
684 if (window && !window->getX11_XIC() && window->createX11_XIC()) {
686 if (xevent.type == KeyPress)
690 XSetICFocus(window->getX11_XIC());
696 if ((XFilterEvent(&xevent, (Window)
NULL) == True)) {
703 if (xevent.type == KeyRelease) {
704 m_last_release_keycode = xevent.xkey.keycode;
705 m_last_release_time = xevent.xkey.time;
707 else if (xevent.type == KeyPress) {
708 if ((xevent.xkey.keycode == m_last_release_keycode) &&
709 ((xevent.xkey.time <= m_last_release_time)))
713 processEvent(&xevent);
716 #ifdef USE_UNITY_WORKAROUND
723 if (xevent.type == FocusIn) {
727 if (window && XPending(m_display) >= 2) {
728 XNextEvent(m_display, &xevent);
730 if (xevent.type == KeymapNotify) {
735 XPeekEvent(m_display, &xev_next);
737 if (xev_next.type == KeyPress || xev_next.type == KeyRelease) {
739 const static KeySym modifiers[8] = {
750 for (
int i = 0; i < (
sizeof(modifiers) /
sizeof(*modifiers)); i++) {
751 KeyCode kc = XKeysymToKeycode(m_display, modifiers[i]);
752 if (kc != 0 && ((xevent.xkeymap.key_vector[kc >> 3] >> (kc & 7)) & 1) != 0) {
769 if (generateWindowExposeEvents()) {
773 #ifdef WITH_INPUT_NDOF
779 }
while (waitForEvent && !anyProcessed);
784 #ifdef WITH_X11_XINPUT
785 static bool checkTabletProximity(Display *display, XDevice *device)
792 if (device ==
NULL) {
799 state = XQueryDeviceState(display, device);
804 XInputClass *cls =
state->data;
807 for (
int loop = 0; loop <
state->num_classes; loop++) {
808 switch (cls->c_class) {
810 XValuatorState *val_state = (XValuatorState *)cls;
815 if ((val_state->mode & 2) == 0) {
816 XFreeDeviceState(
state);
821 cls = (XInputClass *)((
char *)cls + cls->length);
823 XFreeDeviceState(
state);
829 void GHOST_SystemX11::processEvent(XEvent *xe)
835 bool is_repeat =
false;
836 if (xe->type == KeyPress || xe->type == KeyRelease) {
837 XKeyEvent *xke = &(xe->xkey);
840 bool is_repeat_keycode =
false;
842 if (m_xkb_descr !=
NULL) {
844 is_repeat_keycode = (
846 (xke->keycode < (XkbPerKeyBitArraySize << 3)) &&
847 bit_is_on(m_xkb_descr->ctrls->per_key_repeat, xke->keycode));
851 switch (XLookupKeysym(xke, 0)) {
868 is_repeat_keycode =
true;
873 if (is_repeat_keycode) {
874 if (xe->type == KeyPress) {
875 if (m_keycode_last_repeat_key == xke->keycode) {
878 m_keycode_last_repeat_key = xke->keycode;
881 if (m_keycode_last_repeat_key == xke->keycode) {
882 m_keycode_last_repeat_key = (
uint)-1;
887 else if (xe->type == EnterNotify) {
889 m_keycode_last_repeat_key = (
uint)-1;
892 #ifdef USE_XINPUT_HOTPLUG
894 if (m_xinput_version.present) {
895 XEventClass class_presence;
898 DevicePresence(m_display, xi_presence, class_presence);
899 (void)class_presence;
901 if (xe->type == xi_presence) {
902 XDevicePresenceNotifyEvent *notify_event = (XDevicePresenceNotifyEvent *)xe;
903 if ((notify_event->devchange == DeviceEnabled) ||
904 (notify_event->devchange == DeviceDisabled) ||
906 refreshXInputDevices();
911 vector<GHOST_IWindow *>::const_iterator win_it = win_vec.begin();
912 vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end();
914 for (; win_it != win_end; ++win_it) {
916 window_xinput->refreshXInputDevices();
928 #ifdef WITH_X11_XINPUT
935 bool any_proximity =
false;
937 for (GHOST_TabletX11 &xtablet : m_xtablets) {
938 if (checkTabletProximity(xe->xany.display, xtablet.Device)) {
939 any_proximity =
true;
943 if (!any_proximity) {
951 XExposeEvent &xee = xe->xexpose;
953 if (xee.count == 0) {
963 XMotionEvent &xme = xe->xmotion;
983 if (x_new != xme.x_root || y_new != xme.y_root) {
990 if (x_new != xme.x_root && xme.time > m_last_warp_x) {
991 x_accum += (xme.x_root - x_new);
992 m_last_warp_x = lastEventTime(xme.time) + 25;
994 if (y_new != xme.y_root && xme.time > m_last_warp_y) {
995 y_accum += (xme.y_root - y_new);
996 m_last_warp_y = lastEventTime(xme.time) + 25;
1007 xme.x_root + x_accum,
1008 xme.y_root + y_accum,
1025 XKeyEvent *xke = &(xe->xkey);
1028 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
1035 char utf8_array[16 * 6 + 5];
1036 char *utf8_buf = utf8_array;
1039 char *utf8_buf =
NULL;
1046 #ifdef USE_NON_LATIN_KB_WORKAROUND
1075 const unsigned int mode_switch_mask = XkbKeysymToModifiers(xke->display, XK_Mode_switch);
1076 const unsigned int number_hack_forbidden_kmods_mask = mode_switch_mask | ShiftMask;
1077 if ((xke->keycode >= 10 && xke->keycode < 20) &&
1078 ((xke->state & number_hack_forbidden_kmods_mask) == 0)) {
1079 key_sym = XLookupKeysym(xke, ShiftMask);
1080 if (!((key_sym >= XK_0) && (key_sym <= XK_9))) {
1081 key_sym = XLookupKeysym(xke, 0);
1085 key_sym = XLookupKeysym(xke, 0);
1088 if (!XLookupString(xke, &ascii, 1, &key_sym_str,
NULL)) {
1147 if ((xke->keycode >= 10 && xke->keycode < 20) &&
1148 ((key_sym = XLookupKeysym(xke, ShiftMask)) >= XK_0) && (key_sym <= XK_9)) {
1153 key_sym = XLookupKeysym(xke, 0);
1158 if (!XLookupString(xke, &ascii, 1,
NULL,
NULL)) {
1163 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
1165 XIC xic = window->getX11_XIC();
1166 if (xic && xke->type == KeyPress) {
1170 if (!(
len = Xutf8LookupString(
1171 xic, xke, utf8_buf,
sizeof(utf8_array) - 5, &key_sym, &status))) {
1175 if (status == XBufferOverflow) {
1176 utf8_buf = (
char *)malloc(
len + 5);
1177 len = Xutf8LookupString(xic, xke, utf8_buf,
len, &key_sym, &status);
1180 if ((status == XLookupChars || status == XLookupBoth)) {
1181 if ((
unsigned char)utf8_buf[0] >= 32) {
1188 else if (status == XLookupKeySym) {
1193 printf(
"Bad keycode lookup. Keysym 0x%x Status: %s\n",
1194 (
unsigned int)key_sym,
1195 (status == XLookupNone ?
1197 status == XLookupKeySym ?
"XLookupKeySym" :
"Unknown status"));
1199 printf(
"'%.*s' %p %p\n",
len, utf8_buf, xic, m_xim);
1210 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
1213 if (xic && xke->type == KeyPress) {
1218 if ((
unsigned char)utf8_buf[i++] > 0x7f) {
1219 for (; i <
len; ++i) {
1221 if (c < 0x80 || c > 0xbf)
1237 if (utf8_buf != utf8_array)
1245 case ButtonRelease: {
1246 XButtonEvent &xbe = xe->xbutton;
1252 if (xbe.button == Button4) {
1253 if (xbe.type == ButtonPress)
1257 else if (xbe.button == Button5) {
1258 if (xbe.type == ButtonPress)
1264 if (xbe.button == Button1)
1266 else if (xbe.button == Button2)
1268 else if (xbe.button == Button3)
1273 else if (xbe.button == 6)
1275 else if (xbe.button == 7)
1277 else if (xbe.button == 8)
1279 else if (xbe.button == 9)
1290 case ConfigureNotify: {
1298 XFocusChangeEvent &xfe = xe->xfocus;
1309 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
1310 XIC xic = window->getX11_XIC();
1312 if (xe->type == FocusIn)
1322 case ClientMessage: {
1323 XClientMessageEvent &xcme = xe->xclient;
1325 if (((Atom)xcme.data.l[0]) ==
m_atom.WM_DELETE_WINDOW) {
1328 else if (((Atom)xcme.data.l[0]) ==
m_atom.WM_TAKE_FOCUS) {
1329 XWindowAttributes attr;
1343 if (XGetWindowAttributes(m_display, xcme.window, &attr) == True) {
1344 if (XGetInputFocus(m_display, &fwin, &revert_to) == True) {
1345 if (attr.map_state == IsViewable) {
1346 if (fwin != xcme.window)
1347 XSetInputFocus(m_display, xcme.window, RevertToParent, xcme.data.l[1]);
1356 if (window->getDropTarget()->GHOST_HandleClientMessage(xe) ==
false) {
1371 case GraphicsExpose:
1383 XCrossingEvent &xce = xe->xcrossing;
1384 if (xce.mode == NotifyNormal) {
1396 if (xce.type == EnterNotify)
1425 case ReparentNotify:
1427 case SelectionRequest: {
1429 Atom target, utf8_string, string, compound_text, c_string;
1430 XSelectionRequestEvent *xse = &xe->xselectionrequest;
1432 target = XInternAtom(m_display,
"TARGETS", False);
1433 utf8_string = XInternAtom(m_display,
"UTF8_STRING", False);
1434 string = XInternAtom(m_display,
"STRING", False);
1435 compound_text = XInternAtom(m_display,
"COMPOUND_TEXT", False);
1436 c_string = XInternAtom(m_display,
"C_STRING", False);
1439 if (xse->property == None) {
1440 xse->property = xse->target;
1443 nxe.xselection.type = SelectionNotify;
1444 nxe.xselection.requestor = xse->requestor;
1445 nxe.xselection.property = xse->property;
1446 nxe.xselection.display = xse->display;
1447 nxe.xselection.selection = xse->selection;
1448 nxe.xselection.target = xse->target;
1449 nxe.xselection.time = xse->time;
1452 if (xse->target == utf8_string || xse->target ==
string || xse->target == compound_text ||
1453 xse->target == c_string) {
1454 if (xse->selection == XInternAtom(m_display,
"PRIMARY", False)) {
1455 XChangeProperty(m_display,
1464 else if (xse->selection == XInternAtom(m_display,
"CLIPBOARD", False)) {
1465 XChangeProperty(m_display,
1475 else if (xse->target == target) {
1478 alist[1] = utf8_string;
1480 alist[3] = compound_text;
1481 alist[4] = c_string;
1482 XChangeProperty(m_display,
1488 (
unsigned char *)alist,
1494 nxe.xselection.property =
None;
1498 XSendEvent(m_display, xse->requestor, 0, 0, &nxe);
1504 #ifdef WITH_X11_XINPUT
1505 for (GHOST_TabletX11 &xtablet : m_xtablets) {
1506 if (xe->type == xtablet.MotionEvent || xe->type == xtablet.PressEvent) {
1507 XDeviceMotionEvent *
data = (XDeviceMotionEvent *)xe;
1508 if (
data->deviceid != xtablet.ID) {
1512 const unsigned char axis_first =
data->first_axis;
1513 const unsigned char axes_end = axis_first +
data->axes_count;
1527 # define AXIS_VALUE_GET(axis, val) \
1528 ((axis_first <= axis && axes_end > axis) && \
1529 ((void)(val = data->axis_data[axis - axis_first]), true))
1531 if (AXIS_VALUE_GET(2, axis_value)) {
1543 if (AXIS_VALUE_GET(3, axis_value)) {
1545 ((
float)xtablet.XtiltLevels);
1547 if (AXIS_VALUE_GET(4, axis_value)) {
1549 ((
float)xtablet.YtiltLevels);
1552 # undef AXIS_VALUE_GET
1554 else if (xe->type == xtablet.ProxInEvent) {
1555 XProximityNotifyEvent *
data = (XProximityNotifyEvent *)xe;
1556 if (
data->deviceid != xtablet.ID) {
1562 else if (xe->type == xtablet.ProxOutEvent) {
1581 memset((
void *)m_keyboard_vector, 0,
sizeof(m_keyboard_vector));
1583 XQueryKeymap(m_display, (
char *)m_keyboard_vector);
1587 const static KeyCode shift_l = XKeysymToKeycode(m_display, XK_Shift_L);
1588 const static KeyCode shift_r = XKeysymToKeycode(m_display, XK_Shift_R);
1589 const static KeyCode control_l = XKeysymToKeycode(m_display, XK_Control_L);
1590 const static KeyCode control_r = XKeysymToKeycode(m_display, XK_Control_R);
1591 const static KeyCode alt_l = XKeysymToKeycode(m_display, XK_Alt_L);
1592 const static KeyCode alt_r = XKeysymToKeycode(m_display, XK_Alt_R);
1593 const static KeyCode super_l = XKeysymToKeycode(m_display, XK_Super_L);
1594 const static KeyCode super_r = XKeysymToKeycode(m_display, XK_Super_R);
1598 ((m_keyboard_vector[shift_l >> 3] >> (shift_l & 7)) & 1) != 0);
1600 ((m_keyboard_vector[shift_r >> 3] >> (shift_r & 7)) & 1) != 0);
1603 ((m_keyboard_vector[control_l >> 3] >> (control_l & 7)) & 1) != 0);
1605 ((m_keyboard_vector[control_r >> 3] >> (control_r & 7)) & 1) != 0);
1611 (((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) ||
1612 ((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1)) != 0);
1619 Window root_return, child_return;
1621 unsigned int mask_return;
1623 if (XQueryPointer(m_display,
1624 RootWindow(m_display, DefaultScreen(m_display)),
1631 &mask_return) == True) {
1646 Window *child_return)
1649 unsigned int mask_return;
1652 if (XQueryPointer(display,
1653 RootWindow(display, DefaultScreen(display)),
1660 &mask_return) == False) {
1672 Window child_return;
1685 #ifdef WITH_XWAYLAND_HACK
1686 Window child_return = None;
1699 #ifdef WITH_XWAYLAND_HACK
1700 if (use_xwayland_hack) {
1701 if (child_return != None) {
1702 XFixesHideCursor(m_display, child_return);
1707 #if defined(WITH_X11_XINPUT) && defined(USE_X11_XINPUT_WARP)
1708 if ((m_xinput_version.present) && (m_xinput_version.major_version >= 2)) {
1711 if (XIGetClientPointer(m_display, None, &device_id) != False) {
1712 XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, relx, rely);
1718 XWarpPointer(m_display, None, None, 0, 0, 0, 0, relx, rely);
1721 #ifdef WITH_XWAYLAND_HACK
1722 if (use_xwayland_hack) {
1723 if (child_return != None) {
1724 XFixesShowCursor(m_display, child_return);
1729 XSync(m_display, 0);
1736 GHOST_ASSERT((bad_wind !=
NULL),
"addDirtyWindow() NULL ptr trapped (window)");
1738 m_dirty_windows.push_back(bad_wind);
1741 bool GHOST_SystemX11::generateWindowExposeEvents()
1743 vector<GHOST_WindowX11 *>::const_iterator w_start = m_dirty_windows.begin();
1744 vector<GHOST_WindowX11 *>::const_iterator w_end = m_dirty_windows.end();
1745 bool anyProcessed =
false;
1747 for (; w_start != w_end; ++w_start) {
1750 (*w_start)->validate();
1754 anyProcessed =
true;
1758 m_dirty_windows.clear();
1759 return anyProcessed;
1763 XkbDescPtr xkb_descr,
1764 const KeyCode keycode)
1775 #define GXMAP(k, x, y) \
1784 if ((key >= XK_A) && (key <= XK_Z)) {
1787 else if ((key >= XK_a) && (key <= XK_z)) {
1790 else if ((key >= XK_0) && (key <= XK_9)) {
1793 else if ((key >= XK_F1) && (key <= XK_F24)) {
1879 #ifdef WITH_XF86KEYSYM
1885 # ifdef XF86XK_AudioForward
1890 #ifdef WITH_GHOST_DEBUG
1891 printf(
"%s: unknown key: %lu / 0x%lx\n", __func__, key, key);
1903 #define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))
1907 GHOST_ASSERT(XkbKeyNameLength == 4,
"Name length is invalid!");
1908 if (keycode >= xkb_descr->min_key_code && keycode <= xkb_descr->max_key_code) {
1909 const char *id_str = xkb_descr->names->keys[keycode].name;
1910 const uint32_t id =
MAKE_ID(id_str[0], id_str[1], id_str[2], id_str[3]);
1912 case MAKE_ID(
'T',
'L',
'D',
'E'):
1914 #ifdef WITH_GHOST_DEBUG
1916 printf(
"%s unhandled keycode: %.*s\n", __func__, XkbKeyNameLength, id_str);
1921 else if (keycode != 0) {
1931 #define XCLIB_XCOUT_NONE 0
1932 #define XCLIB_XCOUT_SENTCONVSEL 1
1933 #define XCLIB_XCOUT_INCR 2
1934 #define XCLIB_XCOUT_FALLBACK 3
1935 #define XCLIB_XCOUT_FALLBACK_UTF8 4
1936 #define XCLIB_XCOUT_FALLBACK_COMP 5
1937 #define XCLIB_XCOUT_FALLBACK_TEXT 6
1943 unsigned char **txt,
1950 unsigned long pty_size, pty_items;
1951 unsigned char *ltxt = *txt;
1954 vector<GHOST_IWindow *>::const_iterator win_it = win_vec.begin();
1968 XConvertSelection(m_display, sel, target,
m_atom.XCLIP_OUT, win, CurrentTime);
1973 if (evt->type != SelectionNotify)
1976 if (target ==
m_atom.UTF8_STRING && evt->xselection.property == None) {
1980 else if (target ==
m_atom.COMPOUND_TEXT && evt->xselection.property == None) {
1984 else if (target ==
m_atom.TEXT && evt->xselection.property == None) {
1990 XGetWindowProperty(m_display,
2004 if (pty_type ==
m_atom.INCR) {
2006 XDeleteProperty(m_display, win,
m_atom.XCLIP_OUT);
2015 if (pty_format != 8) {
2021 XGetWindowProperty(m_display,
2035 XDeleteProperty(m_display, win,
m_atom.XCLIP_OUT);
2038 ltxt = (
unsigned char *)malloc(pty_items);
2039 memcpy(ltxt,
buffer, pty_items);
2060 if (evt->type != PropertyNotify)
2064 if (evt->xproperty.state != PropertyNewValue)
2068 XGetWindowProperty(m_display,
2081 if (pty_format != 8) {
2086 XDeleteProperty(m_display, win,
m_atom.XCLIP_OUT);
2090 if (pty_size == 0) {
2093 XDeleteProperty(m_display, win,
m_atom.XCLIP_OUT);
2105 XGetWindowProperty(m_display,
2121 ltxt = (
unsigned char *)malloc(*
len);
2125 ltxt = (
unsigned char *)realloc(ltxt, *
len);
2129 memcpy(<xt[*
len - pty_items],
buffer, pty_items);
2135 XDeleteProperty(m_display, win,
m_atom.XCLIP_OUT);
2145 Atom target =
m_atom.UTF8_STRING;
2149 unsigned char *sel_buf;
2150 unsigned long sel_len = 0;
2154 if (selection == True)
2157 sseln =
m_atom.CLIPBOARD;
2160 vector<GHOST_IWindow *>::const_iterator win_it = win_vec.begin();
2165 owner = XGetSelectionOwner(m_display, sseln);
2167 if (sseln ==
m_atom.CLIPBOARD) {
2178 else if (owner == None)
2182 vector<XEvent> restore_events;
2186 bool restore_this_event =
false;
2188 XNextEvent(m_display, &evt);
2189 restore_this_event = (evt.type != SelectionNotify);
2195 if (restore_this_event) {
2196 restore_events.push_back(evt);
2208 target =
m_atom.COMPOUND_TEXT;
2227 while (!restore_events.empty()) {
2228 XPutBackEvent(m_display, &restore_events.back());
2229 restore_events.pop_back();
2234 unsigned char *tmp_data = (
unsigned char *)malloc(sel_len + 1);
2235 memcpy((
char *)tmp_data, (
char *)sel_buf, sel_len);
2236 tmp_data[sel_len] =
'\0';
2238 if (sseln ==
m_atom.STRING)
2250 Window m_window, owner;
2253 vector<GHOST_IWindow *>::const_iterator win_it = win_vec.begin();
2258 if (selection == False) {
2259 XSetSelectionOwner(m_display,
m_atom.CLIPBOARD, m_window, CurrentTime);
2260 owner = XGetSelectionOwner(m_display,
m_atom.CLIPBOARD);
2268 XSetSelectionOwner(m_display,
m_atom.PRIMARY, m_window, CurrentTime);
2269 owner = XGetSelectionOwner(m_display,
m_atom.PRIMARY);
2277 if (owner != m_window)
2278 fprintf(stderr,
"failed to own primary\n");
2330 XFillRectangle(display,
2338 XFillRectangle(display,
2346 XDrawString(display,
2371 data = strdup(text);
2372 for (tok = strtok(
data, seps); tok !=
NULL; tok = strtok(
NULL, seps))
2376 data = strdup(text);
2377 *
str = (
char **)malloc((
size_t)(*count) *
sizeof(
char *));
2378 for (i = 0, tok = strtok(
data, seps); tok !=
NULL; tok = strtok(
NULL, seps), i++)
2379 (*
str)[i] = strdup(tok);
2384 const char *message,
2385 const char *help_label,
2386 const char *continue_label,
2390 char **text_splitted =
NULL;
2392 split(message,
"\n", &text_splitted, &textLines);
2399 int screen = DefaultScreen(m_display);
2400 window = XCreateSimpleWindow(m_display,
2401 RootWindow(m_display, screen),
2407 BlackPixel(m_display, screen),
2408 WhitePixel(m_display, screen));
2412 hints.flags = PSize | PMinSize | PMaxSize;
2413 hints.min_width = hints.max_width = hints.base_width = dialog_data.
width;
2414 hints.min_height = hints.max_height = hints.base_height = dialog_data.
height;
2415 XSetWMNormalHints(m_display, window, &hints);
2420 Atom wm_Name = XInternAtom(m_display,
"_NET_WM_NAME", False);
2421 Atom utf8Str = XInternAtom(m_display,
"UTF8_STRING", False);
2423 Atom winType = XInternAtom(m_display,
"_NET_WM_WINDOW_TYPE", False);
2424 Atom typeDialog = XInternAtom(m_display,
"_NET_WM_WINDOW_TYPE_DIALOG", False);
2426 XChangeProperty(m_display,
2432 (
const unsigned char *)title,
2433 (
int)strlen(title));
2436 m_display, window, winType, XA_ATOM, 32, PropModeReplace, (
unsigned char *)&typeDialog, 1);
2440 XGCValues buttonBorderGCValues;
2441 buttonBorderGCValues.foreground = BlackPixel(m_display, screen);
2442 buttonBorderGCValues.background = WhitePixel(m_display, screen);
2443 XGCValues buttonGCValues;
2444 buttonGCValues.foreground = WhitePixel(m_display, screen);
2445 buttonGCValues.background = BlackPixel(m_display, screen);
2447 GC buttonBorderGC = XCreateGC(m_display, window, GCForeground, &buttonBorderGCValues);
2448 GC buttonGC = XCreateGC(m_display, window, GCForeground, &buttonGCValues);
2450 XSelectInput(m_display, window, ExposureMask | ButtonPressMask | ButtonReleaseMask);
2451 XMapWindow(m_display, window);
2454 XNextEvent(m_display, &
e);
2455 if (
e.type == Expose) {
2456 for (
int i = 0; i < textLines; i++) {
2457 XDrawString(m_display,
2459 DefaultGC(m_display, screen),
2463 (
int)strlen(text_splitted[i]));
2465 dialog_data.
drawButton(m_display, window, buttonBorderGC, buttonGC, 1, continue_label);
2467 dialog_data.
drawButton(m_display, window, buttonBorderGC, buttonGC, 2, help_label);
2470 else if (
e.type == ButtonRelease) {
2476 string cmd =
"xdg-open \"" + string(link) +
"\"";
2477 if (system(cmd.c_str()) != 0) {
2478 GHOST_PRINTF(
"GHOST_SystemX11::showMessageBox: Unable to run system command [%s]",
2487 for (
int i = 0; i < textLines; i++) {
2488 free(text_splitted[i]);
2490 free(text_splitted);
2492 XDestroyWindow(m_display, window);
2493 XFreeGC(m_display, buttonBorderGC);
2494 XFreeGC(m_display, buttonGC);
2527 char error_code_str[512];
2529 XGetErrorText(display, event->error_code, error_code_str,
sizeof(error_code_str));
2532 "Received X11 Error:\n"
2533 "\terror code: %d\n"
2534 "\trequest code: %d\n"
2535 "\tminor code: %d\n"
2536 "\terror text: %s\n",
2538 event->request_code,
2553 fprintf(stderr,
"Ignoring Xlib error: error IO\n");
2559 #ifdef WITH_X11_XINPUT
2561 static bool is_filler_char(
char c)
2563 return isspace(
c) ||
c ==
'_' ||
c ==
'-' ||
c ==
';' ||
c ==
':';
2567 static bool match_token(
const char *haystack,
const char *needle)
2570 for (h = haystack; *h;) {
2571 while (*h && is_filler_char(*h))
2576 for (n = needle; *n && *h && tolower(*h) == tolower(*n); n++)
2578 if (!*n && (is_filler_char(*h) || !*h))
2581 while (*h && !is_filler_char(*h))
2600 static const char *tablet_stylus_whitelist[] = {
"stylus",
"wizardpen",
"acecad",
"pen",
NULL};
2602 static const char *type_blacklist[] = {
"pad",
"cursor",
"touch",
NULL};
2605 for (i = 0; type_blacklist[i] !=
NULL; i++) {
2606 if (
type && (strcasecmp(
type, type_blacklist[i]) == 0)) {
2612 for (i = 0; tablet_stylus_whitelist[i] !=
NULL; i++) {
2613 if (
type && match_token(
type, tablet_stylus_whitelist[i])) {
2617 if (
type && match_token(
type,
"eraser")) {
2620 for (i = 0; tablet_stylus_whitelist[i] !=
NULL; i++) {
2621 if (name && match_token(name, tablet_stylus_whitelist[i])) {
2625 if (name && match_token(name,
"eraser")) {
2634 void GHOST_SystemX11::refreshXInputDevices()
2636 if (m_xinput_version.present) {
2638 clearXInputDevices();
2645 XDeviceInfo *device_info = XListInputDevices(m_display, &device_count);
2647 for (
int i = 0; i < device_count; ++i) {
2648 char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].
type) :
2650 GHOST_TTabletMode tablet_mode = tablet_mode_from_name(device_info[i].name, device_type);
2655 XFree((
void *)device_type);
2662 GHOST_TabletX11 xtablet = {tablet_mode};
2663 xtablet.ID = device_info[i].id;
2664 xtablet.Device = XOpenDevice(m_display, xtablet.ID);
2666 if (xtablet.Device !=
NULL) {
2668 XAnyClassPtr ici = device_info[i].inputclassinfo;
2671 for (
int j = 0; j < device_info[i].num_classes; ++j) {
2672 if (ici->c_class == ValuatorClass) {
2673 XValuatorInfo *xvi = (XValuatorInfo *)ici;
2674 if (xvi->axes !=
NULL) {
2675 xtablet.PressureLevels = xvi->axes[2].max_value;
2677 if (xvi->num_axes > 3) {
2680 xtablet.XtiltLevels = xvi->axes[3].max_value;
2681 xtablet.YtiltLevels = xvi->axes[4].max_value;
2684 xtablet.XtiltLevels = 0;
2685 xtablet.YtiltLevels = 0;
2692 ici = (XAnyClassPtr)(((
char *)ici) + ici->length);
2696 m_xtablets.push_back(xtablet);
2700 XFreeDeviceList(device_info);
2707 void GHOST_SystemX11::clearXInputDevices()
2709 for (GHOST_TabletX11 &xtablet : m_xtablets) {
2711 XCloseDevice(m_display, xtablet.Device);
typedef float(TangentPoint)[2]
void BLI_kdtree_nd_() free(KDTree *tree)
#define GHOST_OPENGL_EGL_CONTEXT_FLAGS
#define GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY
#define GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY
#define GHOST_OPENGL_GLX_CONTEXT_FLAGS
#define GHOST_PRINTF(x,...)
#define GHOST_ASSERT(x, info)
static void DeviceAdded(uint32_t unused)
static void DeviceRemoved(uint32_t unused)
static char * txt_select_buffer
static Bool init_timestamp_scanner(Display *, XEvent *event, XPointer arg)
static void split(const char *text, const char *seps, char ***str, int *count)
int GHOST_X11_ApplicationErrorHandler(Display *display, XErrorEvent *event)
#define XCLIB_XCOUT_FALLBACK_UTF8
static char * txt_cut_buffer
#define XCLIB_XCOUT_FALLBACK
#define GHOST_INTERN_ATOM(atom)
#define XCLIB_XCOUT_FALLBACK_COMP
static GHOST_TKey ghost_key_from_keysym_or_keycode(const KeySym key, const XkbDescPtr xkb_descr, const KeyCode keycode)
#define MAKE_ID(a, b, c, d)
static uchar bit_is_on(const uchar *ptr, int bit)
#define XCLIB_XCOUT_SENTCONVSEL
#define XCLIB_XCOUT_FALLBACK_TEXT
static GHOST_TKey ghost_key_from_keycode(const XkbDescPtr xkb_descr, const KeyCode keycode)
int GHOST_X11_ApplicationIOErrorHandler(Display *)
static void SleepTillEvent(Display *display, GHOST_TInt64 maxSleep)
static GHOST_TSuccess getCursorPosition_impl(Display *display, GHOST_TInt32 &x, GHOST_TInt32 &y, Window *child_return)
#define GHOST_INTERN_ATOM_IF_EXISTS(atom)
static GHOST_TKey ghost_key_from_keysym(const KeySym key)
#define GHOST_X11_ERROR_HANDLERS_OVERRIDE(var)
#define GHOST_X11_ERROR_HANDLERS_RESTORE(var)
unsigned int GHOST_TUns32
unsigned long long GHOST_TUns64
@ GHOST_kEventWindowClose
@ GHOST_kEventButtonUp
Mouse button event.
@ GHOST_kEventWindowActivate
@ GHOST_kEventWindowUpdate
@ GHOST_kEventWindowDeactivate
@ GHOST_kEventButtonDown
Mouse move event.
@ GHOST_kEventKeyDown
Trackpad event.
@ GHOST_kTabletModeEraser
@ GHOST_kTabletModeStylus
@ GHOST_glAlphaBackground
@ GHOST_kKeyNumpadAsterisk
GHOST_TDrawingContextType
@ GHOST_kButtonMaskButton4
@ GHOST_kButtonMaskButton7
@ GHOST_kButtonMaskButton6
@ GHOST_kButtonMaskButton5
@ GHOST_kButtonMaskMiddle
@ GHOST_kModifierKeyRightControl
@ GHOST_kModifierKeyLeftControl
@ GHOST_kModifierKeyRightAlt
@ GHOST_kModifierKeyRightShift
@ GHOST_kModifierKeyLeftAlt
@ GHOST_kModifierKeyLeftShift
unsigned char GHOST_TUns8
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble top
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Time
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
bool isInsideButton(XEvent &e, uint button_num)
void drawButton(Display *display, Window &window, GC &borderGC, GC &buttonGC, uint button_num, const char *label)
uint button_text_offset_y
static GHOST_ISystem * getSystem()
virtual bool isDebugEnabled()=0
GHOST_TSuccess disposeContext(GHOST_IContext *context)
GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
void getClipboard_xcout(const XEvent *evt, Atom sel, Atom target, unsigned char **txt, unsigned long *len, unsigned int *context) const
GHOST_IContext * createOffscreenContext(GHOST_GLSettings glSettings)
void addDirtyWindow(GHOST_WindowX11 *bad_wind)
void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
Atom _NET_WM_STATE_MAXIMIZED_VERT
GHOST_IWindow * createWindow(const char *title, GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height, GHOST_TWindowState state, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings, const bool exclusive=false, const bool is_dialog=false, const GHOST_IWindow *parentWindow=0)
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const
GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const
Atom _NET_WM_STATE_FULLSCREEN
GHOST_TUns64 getMilliSeconds() const
bool processEvents(bool waitForEvent)
GHOST_TUns8 getNumDisplays() const
struct GHOST_SystemX11::@1233 m_atom
GHOST_TUns8 * getClipboard(bool selection) const
GHOST_TSuccess showMessageBox(const char *title, const char *message, const char *help_label, const char *continue_label, const char *link, GHOST_DialogOptions dialog_options) const
Atom _NET_WM_STATE_MAXIMIZED_HORZ
GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const
void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
void putClipboard(GHOST_TInt8 *buffer, bool selection) const
virtual GHOST_TSuccess exit()
virtual GHOST_TSuccess init()
GHOST_TimerManager * getTimerManager() const
GHOST_WindowManager * m_windowManager
GHOST_TSuccess pushEvent(GHOST_IEvent *event)
GHOST_DisplayManager * m_displayManager
GHOST_TUns64 nextFireTime()
bool fireTimers(GHOST_TUns64 time)
GHOST_TSuccess addWindow(GHOST_IWindow *window)
const std::vector< GHOST_IWindow * > & getWindows() const
GHOST_TSuccess setActiveWindow(GHOST_IWindow *window)
void setWindowInactive(const GHOST_IWindow *window)
GHOST_TWindowState m_post_state
void getClientBounds(GHOST_Rect &bounds) const
GHOST_TSuccess setState(GHOST_TWindowState state)
GHOST_TabletData & GetTabletData()
GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds)
GHOST_TAxisFlag getCursorGrabAxis() const
void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y)
void getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const
bool getCursorGrabModeIsWarp() const
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
struct SELECTID_Context context
void set(GHOST_TModifierKeyMask mask, bool down)
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)