30 #include <X11/Xresource.h> 46 if (scancode < 8 || scancode > 255)
55 keySym = XkbKeycodeToKeysym(
_glfw.x11.display, scancode, 0, 1);
77 keySym = XkbKeycodeToKeysym(
_glfw.x11.display, scancode, 0, 0);
84 keySyms = XGetKeyboardMapping(
_glfw.x11.display, scancode, 1, &dummy);
100 case XK_ISO_Level3_Shift:
235 memset(
_glfw.x11.keycodes, -1,
sizeof(
_glfw.x11.keycodes));
236 memset(
_glfw.x11.scancodes, -1,
sizeof(
_glfw.x11.scancodes));
243 char name[XkbKeyNameLength + 1];
244 XkbDescPtr desc = XkbGetMap(
_glfw.x11.display, 0, XkbUseCoreKbd);
245 XkbGetNames(
_glfw.x11.display, XkbKeyNamesMask, desc);
248 for (scancode = desc->min_key_code; scancode <= desc->max_key_code; scancode++)
250 memcpy(name, desc->names->keys[scancode].name, XkbKeyNameLength);
251 name[XkbKeyNameLength] =
'\0';
258 else if (strcmp(name,
"AE01") == 0) key =
GLFW_KEY_1;
259 else if (strcmp(name,
"AE02") == 0) key =
GLFW_KEY_2;
260 else if (strcmp(name,
"AE03") == 0) key =
GLFW_KEY_3;
261 else if (strcmp(name,
"AE04") == 0) key =
GLFW_KEY_4;
262 else if (strcmp(name,
"AE05") == 0) key =
GLFW_KEY_5;
263 else if (strcmp(name,
"AE06") == 0) key =
GLFW_KEY_6;
264 else if (strcmp(name,
"AE07") == 0) key =
GLFW_KEY_7;
265 else if (strcmp(name,
"AE08") == 0) key =
GLFW_KEY_8;
266 else if (strcmp(name,
"AE09") == 0) key =
GLFW_KEY_9;
267 else if (strcmp(name,
"AE10") == 0) key =
GLFW_KEY_0;
270 else if (strcmp(name,
"AD01") == 0) key =
GLFW_KEY_Q;
271 else if (strcmp(name,
"AD02") == 0) key =
GLFW_KEY_W;
272 else if (strcmp(name,
"AD03") == 0) key =
GLFW_KEY_E;
273 else if (strcmp(name,
"AD04") == 0) key =
GLFW_KEY_R;
274 else if (strcmp(name,
"AD05") == 0) key =
GLFW_KEY_T;
275 else if (strcmp(name,
"AD06") == 0) key =
GLFW_KEY_Y;
276 else if (strcmp(name,
"AD07") == 0) key =
GLFW_KEY_U;
277 else if (strcmp(name,
"AD08") == 0) key =
GLFW_KEY_I;
278 else if (strcmp(name,
"AD09") == 0) key =
GLFW_KEY_O;
279 else if (strcmp(name,
"AD10") == 0) key =
GLFW_KEY_P;
282 else if (strcmp(name,
"AC01") == 0) key =
GLFW_KEY_A;
283 else if (strcmp(name,
"AC02") == 0) key =
GLFW_KEY_S;
284 else if (strcmp(name,
"AC03") == 0) key =
GLFW_KEY_D;
285 else if (strcmp(name,
"AC04") == 0) key =
GLFW_KEY_F;
286 else if (strcmp(name,
"AC05") == 0) key =
GLFW_KEY_G;
287 else if (strcmp(name,
"AC06") == 0) key =
GLFW_KEY_H;
288 else if (strcmp(name,
"AC07") == 0) key =
GLFW_KEY_J;
289 else if (strcmp(name,
"AC08") == 0) key =
GLFW_KEY_K;
290 else if (strcmp(name,
"AC09") == 0) key =
GLFW_KEY_L;
293 else if (strcmp(name,
"AB01") == 0) key =
GLFW_KEY_Z;
294 else if (strcmp(name,
"AB02") == 0) key =
GLFW_KEY_X;
295 else if (strcmp(name,
"AB03") == 0) key =
GLFW_KEY_C;
296 else if (strcmp(name,
"AB04") == 0) key =
GLFW_KEY_V;
297 else if (strcmp(name,
"AB05") == 0) key =
GLFW_KEY_B;
298 else if (strcmp(name,
"AB06") == 0) key =
GLFW_KEY_N;
299 else if (strcmp(name,
"AB07") == 0) key =
GLFW_KEY_M;
307 if ((scancode >= 0) && (scancode < 256))
311 XkbFreeNames(desc, XkbKeyNamesMask, True);
312 XkbFreeKeyboard(desc, 0, True);
315 for (scancode = 0; scancode < 256; scancode++)
319 if (
_glfw.x11.keycodes[scancode] < 0)
323 if (
_glfw.x11.keycodes[scancode] > 0)
324 _glfw.x11.scancodes[
_glfw.x11.keycodes[scancode]] = scancode;
334 XIMStyles* styles =
NULL;
336 if (XGetIMValues(
_glfw.x11.im, XNQueryInputStyle, &styles,
NULL) !=
NULL)
339 for (i = 0; i < styles->count_styles; i++)
341 if (styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing))
355 unsigned long atomCount,
356 const char* atomName)
359 const Atom atom = XInternAtom(
_glfw.x11.display, atomName, False);
361 for (i = 0; i < atomCount; i++)
363 if (supportedAtoms[i] == atom)
374 Window* windowFromRoot =
NULL;
375 Window* windowFromChild =
NULL;
378 const Atom supportingWmCheck =
379 XInternAtom(
_glfw.x11.display,
"_NET_SUPPORTING_WM_CHECK", False);
380 const Atom wmSupported =
381 XInternAtom(
_glfw.x11.display,
"_NET_SUPPORTED", False);
387 (
unsigned char**) &windowFromRoot))
399 (
unsigned char**) &windowFromChild))
401 XFree(windowFromRoot);
408 if (*windowFromRoot != *windowFromChild)
410 XFree(windowFromRoot);
411 XFree(windowFromChild);
415 XFree(windowFromRoot);
416 XFree(windowFromChild);
420 Atom* supportedAtoms;
421 unsigned long atomCount;
428 (
unsigned char**) &supportedAtoms);
431 _glfw.x11.NET_WM_STATE =
433 _glfw.x11.NET_WM_STATE_ABOVE =
435 _glfw.x11.NET_WM_STATE_FULLSCREEN =
437 _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT =
438 getSupportedAtom(supportedAtoms, atomCount,
"_NET_WM_STATE_MAXIMIZED_VERT");
439 _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ =
440 getSupportedAtom(supportedAtoms, atomCount,
"_NET_WM_STATE_MAXIMIZED_HORZ");
441 _glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION =
442 getSupportedAtom(supportedAtoms, atomCount,
"_NET_WM_STATE_DEMANDS_ATTENTION");
443 _glfw.x11.NET_WM_FULLSCREEN_MONITORS =
445 _glfw.x11.NET_WM_WINDOW_TYPE =
447 _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL =
449 _glfw.x11.NET_ACTIVE_WINDOW =
451 _glfw.x11.NET_FRAME_EXTENTS =
453 _glfw.x11.NET_REQUEST_FRAME_EXTENTS =
457 XFree(supportedAtoms);
478 &
_glfw.x11.vidmode.eventBase,
479 &
_glfw.x11.vidmode.errorBase);
482 #if defined(__CYGWIN__) 494 if (XQueryExtension(
_glfw.x11.display,
496 &
_glfw.x11.xi.majorOpcode,
497 &
_glfw.x11.xi.eventBase,
498 &
_glfw.x11.xi.errorBase))
500 _glfw.x11.xi.major = 2;
501 _glfw.x11.xi.minor = 0;
505 &
_glfw.x11.xi.minor) == Success)
512 #if defined(__CYGWIN__) 557 &
_glfw.x11.randr.eventBase,
558 &
_glfw.x11.randr.errorBase))
561 &
_glfw.x11.randr.major,
562 &
_glfw.x11.randr.minor))
565 if (
_glfw.x11.randr.major > 1 ||
_glfw.x11.randr.minor >= 3)
571 "X11: Failed to query RandR version");
601 RROutputChangeNotifyMask);
604 #if defined(__CYGWIN__) 619 #if defined(__CYGWIN__) 634 &
_glfw.x11.xinerama.major,
635 &
_glfw.x11.xinerama.minor))
642 _glfw.x11.xkb.major = 1;
643 _glfw.x11.xkb.minor = 0;
645 XkbQueryExtension(
_glfw.x11.display,
646 &
_glfw.x11.xkb.majorOpcode,
647 &
_glfw.x11.xkb.eventBase,
648 &
_glfw.x11.xkb.errorBase,
649 &
_glfw.x11.xkb.major,
650 &
_glfw.x11.xkb.minor);
656 if (XkbSetDetectableAutoRepeat(
_glfw.x11.display, True, &supported))
663 #if defined(__CYGWIN__) 674 #if defined(__CYGWIN__) 689 &
_glfw.x11.xrender.errorBase,
690 &
_glfw.x11.xrender.eventBase))
693 &
_glfw.x11.xrender.major,
694 &
_glfw.x11.xrender.minor))
710 _glfw.x11.NULL_ = XInternAtom(
_glfw.x11.display,
"NULL", False);
711 _glfw.x11.UTF8_STRING = XInternAtom(
_glfw.x11.display,
"UTF8_STRING", False);
712 _glfw.x11.ATOM_PAIR = XInternAtom(
_glfw.x11.display,
"ATOM_PAIR", False);
715 _glfw.x11.GLFW_SELECTION =
716 XInternAtom(
_glfw.x11.display,
"GLFW_SELECTION", False);
719 _glfw.x11.TARGETS = XInternAtom(
_glfw.x11.display,
"TARGETS", False);
720 _glfw.x11.MULTIPLE = XInternAtom(
_glfw.x11.display,
"MULTIPLE", False);
721 _glfw.x11.PRIMARY = XInternAtom(
_glfw.x11.display,
"PRIMARY", False);
722 _glfw.x11.INCR = XInternAtom(
_glfw.x11.display,
"INCR", False);
723 _glfw.x11.CLIPBOARD = XInternAtom(
_glfw.x11.display,
"CLIPBOARD", False);
726 _glfw.x11.CLIPBOARD_MANAGER =
727 XInternAtom(
_glfw.x11.display,
"CLIPBOARD_MANAGER", False);
728 _glfw.x11.SAVE_TARGETS =
729 XInternAtom(
_glfw.x11.display,
"SAVE_TARGETS", False);
732 _glfw.x11.XdndAware = XInternAtom(
_glfw.x11.display,
"XdndAware", False);
733 _glfw.x11.XdndEnter = XInternAtom(
_glfw.x11.display,
"XdndEnter", False);
734 _glfw.x11.XdndPosition = XInternAtom(
_glfw.x11.display,
"XdndPosition", False);
735 _glfw.x11.XdndStatus = XInternAtom(
_glfw.x11.display,
"XdndStatus", False);
736 _glfw.x11.XdndActionCopy = XInternAtom(
_glfw.x11.display,
"XdndActionCopy", False);
737 _glfw.x11.XdndDrop = XInternAtom(
_glfw.x11.display,
"XdndDrop", False);
738 _glfw.x11.XdndFinished = XInternAtom(
_glfw.x11.display,
"XdndFinished", False);
739 _glfw.x11.XdndSelection = XInternAtom(
_glfw.x11.display,
"XdndSelection", False);
740 _glfw.x11.XdndTypeList = XInternAtom(
_glfw.x11.display,
"XdndTypeList", False);
741 _glfw.x11.text_uri_list = XInternAtom(
_glfw.x11.display,
"text/uri-list", False);
746 _glfw.x11.WM_PROTOCOLS =
747 XInternAtom(
_glfw.x11.display,
"WM_PROTOCOLS", False);
749 XInternAtom(
_glfw.x11.display,
"WM_STATE", False);
750 _glfw.x11.WM_DELETE_WINDOW =
751 XInternAtom(
_glfw.x11.display,
"WM_DELETE_WINDOW", False);
752 _glfw.x11.NET_WM_ICON =
753 XInternAtom(
_glfw.x11.display,
"_NET_WM_ICON", False);
754 _glfw.x11.NET_WM_PING =
755 XInternAtom(
_glfw.x11.display,
"_NET_WM_PING", False);
756 _glfw.x11.NET_WM_PID =
757 XInternAtom(
_glfw.x11.display,
"_NET_WM_PID", False);
758 _glfw.x11.NET_WM_NAME =
759 XInternAtom(
_glfw.x11.display,
"_NET_WM_NAME", False);
760 _glfw.x11.NET_WM_ICON_NAME =
761 XInternAtom(
_glfw.x11.display,
"_NET_WM_ICON_NAME", False);
762 _glfw.x11.NET_WM_BYPASS_COMPOSITOR =
763 XInternAtom(
_glfw.x11.display,
"_NET_WM_BYPASS_COMPOSITOR", False);
764 _glfw.x11.NET_WM_WINDOW_OPACITY =
765 XInternAtom(
_glfw.x11.display,
"_NET_WM_WINDOW_OPACITY", False);
766 _glfw.x11.MOTIF_WM_HINTS =
767 XInternAtom(
_glfw.x11.display,
"_MOTIF_WM_HINTS", False);
772 snprintf(name,
sizeof(name),
"_NET_WM_CM_S%u",
_glfw.x11.screen);
773 _glfw.x11.NET_WM_CM_Sx = XInternAtom(
_glfw.x11.display, name, False);
786 float xdpi = DisplayWidth(
_glfw.x11.display,
_glfw.x11.screen) *
787 25.4f / DisplayWidthMM(
_glfw.x11.display,
_glfw.x11.screen);
788 float ydpi = DisplayHeight(
_glfw.x11.display,
_glfw.x11.screen) *
789 25.4f / DisplayHeightMM(
_glfw.x11.display,
_glfw.x11.screen);
794 char* rms = XResourceManagerString(
_glfw.x11.display);
797 XrmDatabase db = XrmGetStringDatabase(rms);
803 if (XrmGetResource(db,
"Xft.dpi",
"Xft.Dpi", &type, &value))
805 if (type && strcmp(type,
"String") == 0)
806 xdpi = ydpi = atof(value.addr);
809 XrmDestroyDatabase(db);
813 *xscale = xdpi / 96.f;
814 *yscale = ydpi / 96.f;
821 unsigned char pixels[16 * 16 * 4] = { 0 };
830 XSetWindowAttributes wa;
831 wa.event_mask = PropertyChangeMask;
833 return XCreateWindow(
_glfw.x11.display,
_glfw.x11.root,
836 DefaultVisual(
_glfw.x11.display,
_glfw.x11.screen),
844 _glfw.x11.errorCode =
event->error_code;
857 _glfw.x11.errorCode = Success;
866 XSync(
_glfw.x11.display, False);
867 XSetErrorHandler(
NULL);
875 XGetErrorText(
_glfw.x11.display,
_glfw.x11.errorCode,
876 buffer,
sizeof(buffer));
899 XcursorPixel*
target = native->pixels;
903 unsigned int alpha = source[3];
905 *target = (alpha << 24) |
906 ((
unsigned char) ((source[0] *
alpha) / 255) << 16) |
907 ((
unsigned char) ((source[1] *
alpha) / 255) << 8) |
908 ((
unsigned char) ((source[2] *
alpha) / 255) << 0);
924 #if !defined(X_HAVE_UTF8_STRING) 930 if (strcmp(setlocale(LC_CTYPE,
NULL),
"C") == 0)
931 setlocale(LC_CTYPE,
"");
938 if (!
_glfw.x11.display)
940 const char*
display = getenv(
"DISPLAY");
944 "X11: Failed to open display %s", display);
949 "X11: The DISPLAY environment variable is missing");
955 _glfw.x11.screen = DefaultScreen(
_glfw.x11.display);
967 if (XSupportsLocale())
969 XSetLocaleModifiers(
"");
976 XCloseIM(
_glfw.x11.im);
982 #if defined(__linux__) 995 if (
_glfw.x11.helperWindowHandle)
997 if (XGetSelectionOwner(
_glfw.x11.display,
_glfw.x11.CLIPBOARD) ==
998 _glfw.x11.helperWindowHandle)
1003 XDestroyWindow(
_glfw.x11.display,
_glfw.x11.helperWindowHandle);
1004 _glfw.x11.helperWindowHandle = None;
1007 if (
_glfw.x11.hiddenCursorHandle)
1009 XFreeCursor(
_glfw.x11.display,
_glfw.x11.hiddenCursorHandle);
1010 _glfw.x11.hiddenCursorHandle = (Cursor) 0;
1013 free(
_glfw.x11.primarySelectionString);
1014 free(
_glfw.x11.clipboardString);
1018 XCloseIM(
_glfw.x11.im);
1022 if (
_glfw.x11.display)
1024 XCloseDisplay(
_glfw.x11.display);
1075 #if defined(__linux__) 1083 #if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) 1088 #if defined(__linux__) 1091 #if defined(_GLFW_BUILD_DLL) #define GLFW_KEY_SCROLL_LOCK
GLenum GLuint GLenum GLsizei const GLchar * message
#define GLFW_KEY_RIGHT_CONTROL
#define GLFW_KEY_KP_DIVIDE
GLuint const GLchar * name
static void createKeyTables(void)
#define _GLFW_VERSION_NUMBER
#define GLFW_KEY_SEMICOLON
#define GLFW_KEY_GRAVE_ACCENT
static Cursor createHiddenCursor(void)
static Window createHelperWindow(void)
void _glfwInitTimerPOSIX(void)
#define GLFW_KEY_LEFT_SHIFT
static GLFWbool hasUsableInputMethodStyle(void)
#define GLFW_KEY_PAGE_DOWN
#define GLFW_KEY_LEFT_BRACKET
int _glfwPlatformInit(void)
#define GLFW_KEY_BACKSPACE
GLenum GLenum GLsizei void * image
void _glfwGrabErrorHandlerX11(void)
static int translateKeyCode(int scancode)
#define GLFW_KEY_KP_DECIMAL
static int errorHandler(Display *display, XErrorEvent *event)
GLfloat GLfloat GLfloat alpha
#define GLFW_KEY_RIGHT_SUPER
const char * _glfwPlatformGetVersionString(void)
#define GLFW_PLATFORM_ERROR
A platform-specific error occurred that does not match any of the more specific categories.
void _glfwInputErrorX11(int error, const char *message)
static Atom getSupportedAtom(Atom *supportedAtoms, unsigned long atomCount, const char *atomName)
#define GLFW_KEY_CAPS_LOCK
#define GLFW_KEY_KP_MULTIPLY
void _glfwTerminateEGL(void)
#define GLFW_KEY_NUM_LOCK
void _glfwPlatformTerminate(void)
void _glfwInputError(int code, const char *format,...)
GLint GLint GLsizei GLint GLenum GLenum const void * pixels
void _glfwPollMonitorsX11(void)
static void detectEWMH(void)
static GLFWbool initExtensions(void)
void _glfwTerminateGLX(void)
#define GLFW_KEY_RIGHT_BRACKET
Cursor _glfwCreateCursorX11(const GLFWimage *image, int xhot, int yhot)
#define GLFW_KEY_KP_ENTER
#define GLFW_KEY_KP_SUBTRACT
void _glfwReleaseErrorHandlerX11(void)
#define GLFW_KEY_RIGHT_ALT
#define GLFW_KEY_PRINT_SCREEN
static void getSystemContentScale(float *xscale, float *yscale)
#define GLFW_KEY_LEFT_CONTROL
void _glfwTerminateJoysticksLinux(void)
#define GLFW_KEY_KP_EQUAL
GLsizei GLsizei GLchar * source
#define GLFW_KEY_LEFT_ALT
#define _GLFW_MESSAGE_SIZE
#define GLFW_KEY_RIGHT_SHIFT
GLFWbool _glfwInitJoysticksLinux(void)
#define GLFW_KEY_BACKSLASH
#define GLFW_KEY_APOSTROPHE
#define GLFW_KEY_LEFT_SUPER