mirror of
https://github.com/glfw/glfw.git
synced 2026-02-21 14:43:02 +01:00
Merge branch '3.3-stable' into new-cursors-on-3.3-stable
This commit is contained in:
@@ -92,7 +92,7 @@ typedef VkResult (APIENTRY *PFN_vkCreateMetalSurfaceEXT)(VkInstance,const VkMeta
|
||||
#define _glfw_dlclose(handle) dlclose(handle)
|
||||
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||
|
||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->ns.view)
|
||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->ns.layer)
|
||||
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
|
||||
|
||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns
|
||||
@@ -121,6 +121,7 @@ typedef struct _GLFWwindowNS
|
||||
id layer;
|
||||
|
||||
GLFWbool maximized;
|
||||
GLFWbool occluded;
|
||||
GLFWbool retina;
|
||||
|
||||
// Cached window properties to filter out duplicate events
|
||||
|
||||
@@ -322,6 +322,14 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||
}
|
||||
|
||||
- (void)windowDidChangeOcclusionState:(NSNotification* )notification
|
||||
{
|
||||
if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible)
|
||||
window->ns.occluded = GLFW_FALSE;
|
||||
else
|
||||
window->ns.occluded = GLFW_TRUE;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -901,6 +909,11 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
}
|
||||
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
|
||||
{
|
||||
// EGL implementation on macOS use CALayer* EGLNativeWindowType so we
|
||||
// need to get the layer for EGL window surface creation.
|
||||
[window->ns.view setWantsLayer:YES];
|
||||
window->ns.layer = [window->ns.view layer];
|
||||
|
||||
if (!_glfwInitEGL())
|
||||
return GLFW_FALSE;
|
||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||
|
||||
@@ -588,18 +588,16 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
// Set up attributes for surface creation
|
||||
index = 0;
|
||||
|
||||
if (fbconfig->sRGB)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
if (fbconfig->sRGB)
|
||||
{
|
||||
if (_glfw.egl.KHR_gl_colorspace)
|
||||
setAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
|
||||
}
|
||||
|
||||
setAttrib(EGL_NONE, EGL_NONE);
|
||||
if (_glfw.egl.KHR_gl_colorspace)
|
||||
setAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
|
||||
}
|
||||
|
||||
setAttrib(EGL_NONE, EGL_NONE);
|
||||
|
||||
window->context.egl.surface =
|
||||
eglCreateWindowSurface(_glfw.egl.display,
|
||||
config,
|
||||
|
||||
@@ -51,7 +51,7 @@ static void swapBuffersNSGL(_GLFWwindow* window)
|
||||
|
||||
// HACK: Simulate vsync with usleep as NSGL swap interval does not apply to
|
||||
// windows with a non-visible occlusion state
|
||||
if (!([window->ns.object occlusionState] & NSWindowOcclusionStateVisible))
|
||||
if (window->ns.occluded)
|
||||
{
|
||||
int interval = 0;
|
||||
[window->context.nsgl.object getValues:&interval
|
||||
|
||||
@@ -356,7 +356,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||
js = _glfw.joysticks + jid;
|
||||
if (js->present)
|
||||
{
|
||||
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
|
||||
@@ -672,11 +672,11 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
};
|
||||
|
||||
// Screams of horror are appropriate at this point
|
||||
int state = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES);
|
||||
if (state < 0 || state > 8)
|
||||
state = 8;
|
||||
int stateIndex = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES);
|
||||
if (stateIndex < 0 || stateIndex > 8)
|
||||
stateIndex = 8;
|
||||
|
||||
_glfwInputJoystickHat(js, pi, states[state]);
|
||||
_glfwInputJoystickHat(js, pi, states[stateIndex]);
|
||||
pi++;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -208,8 +208,8 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
||||
if (fd < 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Creating a buffer file for %d B failed: %m",
|
||||
length);
|
||||
"Wayland: Creating a buffer file for %d B failed: %s",
|
||||
length, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
||||
if (data == MAP_FAILED)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: mmap failed: %m");
|
||||
"Wayland: mmap failed: %s", strerror(errno));
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
336
src/x11_init.c
336
src/x11_init.c
@@ -38,24 +38,15 @@
|
||||
#include <locale.h>
|
||||
|
||||
|
||||
// Translate an X11 key code to a GLFW key code.
|
||||
// Translate the X11 KeySyms for a key to a GLFW key code
|
||||
// NOTE: This is only used as a fallback, in case the XKB method fails
|
||||
// It is layout-dependent and will fail partially on most non-US layouts
|
||||
//
|
||||
static int translateKeyCode(int scancode)
|
||||
static int translateKeySyms(const KeySym* keysyms, int width)
|
||||
{
|
||||
int keySym;
|
||||
|
||||
// Valid key code range is [8,255], according to the Xlib manual
|
||||
if (scancode < 8 || scancode > 255)
|
||||
return GLFW_KEY_UNKNOWN;
|
||||
|
||||
if (_glfw.x11.xkb.available)
|
||||
if (width > 1)
|
||||
{
|
||||
// Try secondary keysym, for numeric keypad keys
|
||||
// Note: This way we always force "NumLock = ON", which is intentional
|
||||
// since the returned key code should correspond to a physical
|
||||
// location.
|
||||
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 1);
|
||||
switch (keySym)
|
||||
switch (keysyms[1])
|
||||
{
|
||||
case XK_KP_0: return GLFW_KEY_KP_0;
|
||||
case XK_KP_1: return GLFW_KEY_KP_1;
|
||||
@@ -73,22 +64,9 @@ static int translateKeyCode(int scancode)
|
||||
case XK_KP_Enter: return GLFW_KEY_KP_ENTER;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Now try primary keysym for function keys (non-printable keys)
|
||||
// These should not depend on the current keyboard layout
|
||||
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, _glfw.x11.xkb.group, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int dummy;
|
||||
KeySym* keySyms;
|
||||
|
||||
keySyms = XGetKeyboardMapping(_glfw.x11.display, scancode, 1, &dummy);
|
||||
keySym = keySyms[0];
|
||||
XFree(keySyms);
|
||||
}
|
||||
|
||||
switch (keySym)
|
||||
switch (keysyms[0])
|
||||
{
|
||||
case XK_Escape: return GLFW_KEY_ESCAPE;
|
||||
case XK_Tab: return GLFW_KEY_TAB;
|
||||
@@ -232,7 +210,7 @@ static int translateKeyCode(int scancode)
|
||||
//
|
||||
static void createKeyTables(void)
|
||||
{
|
||||
int scancode, key;
|
||||
int scancode, scancodeMin, scancodeMax;
|
||||
|
||||
memset(_glfw.x11.keycodes, -1, sizeof(_glfw.x11.keycodes));
|
||||
memset(_glfw.x11.scancodes, -1, sizeof(_glfw.x11.scancodes));
|
||||
@@ -242,89 +220,217 @@ static void createKeyTables(void)
|
||||
// Use XKB to determine physical key locations independently of the
|
||||
// current keyboard layout
|
||||
|
||||
char name[XkbKeyNameLength + 1];
|
||||
XkbDescPtr desc = XkbGetMap(_glfw.x11.display, 0, XkbUseCoreKbd);
|
||||
XkbGetNames(_glfw.x11.display, XkbKeyNamesMask, desc);
|
||||
XkbGetNames(_glfw.x11.display, XkbKeyNamesMask | XkbKeyAliasesMask, desc);
|
||||
|
||||
scancodeMin = desc->min_key_code;
|
||||
scancodeMax = desc->max_key_code;
|
||||
|
||||
const struct
|
||||
{
|
||||
int key;
|
||||
char* name;
|
||||
} keymap[] =
|
||||
{
|
||||
{ GLFW_KEY_GRAVE_ACCENT, "TLDE" },
|
||||
{ GLFW_KEY_1, "AE01" },
|
||||
{ GLFW_KEY_2, "AE02" },
|
||||
{ GLFW_KEY_3, "AE03" },
|
||||
{ GLFW_KEY_4, "AE04" },
|
||||
{ GLFW_KEY_5, "AE05" },
|
||||
{ GLFW_KEY_6, "AE06" },
|
||||
{ GLFW_KEY_7, "AE07" },
|
||||
{ GLFW_KEY_8, "AE08" },
|
||||
{ GLFW_KEY_9, "AE09" },
|
||||
{ GLFW_KEY_0, "AE10" },
|
||||
{ GLFW_KEY_MINUS, "AE11" },
|
||||
{ GLFW_KEY_EQUAL, "AE12" },
|
||||
{ GLFW_KEY_Q, "AD01" },
|
||||
{ GLFW_KEY_W, "AD02" },
|
||||
{ GLFW_KEY_E, "AD03" },
|
||||
{ GLFW_KEY_R, "AD04" },
|
||||
{ GLFW_KEY_T, "AD05" },
|
||||
{ GLFW_KEY_Y, "AD06" },
|
||||
{ GLFW_KEY_U, "AD07" },
|
||||
{ GLFW_KEY_I, "AD08" },
|
||||
{ GLFW_KEY_O, "AD09" },
|
||||
{ GLFW_KEY_P, "AD10" },
|
||||
{ GLFW_KEY_LEFT_BRACKET, "AD11" },
|
||||
{ GLFW_KEY_RIGHT_BRACKET, "AD12" },
|
||||
{ GLFW_KEY_A, "AC01" },
|
||||
{ GLFW_KEY_S, "AC02" },
|
||||
{ GLFW_KEY_D, "AC03" },
|
||||
{ GLFW_KEY_F, "AC04" },
|
||||
{ GLFW_KEY_G, "AC05" },
|
||||
{ GLFW_KEY_H, "AC06" },
|
||||
{ GLFW_KEY_J, "AC07" },
|
||||
{ GLFW_KEY_K, "AC08" },
|
||||
{ GLFW_KEY_L, "AC09" },
|
||||
{ GLFW_KEY_SEMICOLON, "AC10" },
|
||||
{ GLFW_KEY_APOSTROPHE, "AC11" },
|
||||
{ GLFW_KEY_Z, "AB01" },
|
||||
{ GLFW_KEY_X, "AB02" },
|
||||
{ GLFW_KEY_C, "AB03" },
|
||||
{ GLFW_KEY_V, "AB04" },
|
||||
{ GLFW_KEY_B, "AB05" },
|
||||
{ GLFW_KEY_N, "AB06" },
|
||||
{ GLFW_KEY_M, "AB07" },
|
||||
{ GLFW_KEY_COMMA, "AB08" },
|
||||
{ GLFW_KEY_PERIOD, "AB09" },
|
||||
{ GLFW_KEY_SLASH, "AB10" },
|
||||
{ GLFW_KEY_BACKSLASH, "BKSL" },
|
||||
{ GLFW_KEY_WORLD_1, "LSGT" },
|
||||
{ GLFW_KEY_SPACE, "SPCE" },
|
||||
{ GLFW_KEY_ESCAPE, "ESC" },
|
||||
{ GLFW_KEY_ENTER, "RTRN" },
|
||||
{ GLFW_KEY_TAB, "TAB" },
|
||||
{ GLFW_KEY_BACKSPACE, "BKSP" },
|
||||
{ GLFW_KEY_INSERT, "INS" },
|
||||
{ GLFW_KEY_DELETE, "DELE" },
|
||||
{ GLFW_KEY_RIGHT, "RGHT" },
|
||||
{ GLFW_KEY_LEFT, "LEFT" },
|
||||
{ GLFW_KEY_DOWN, "DOWN" },
|
||||
{ GLFW_KEY_UP, "UP" },
|
||||
{ GLFW_KEY_PAGE_UP, "PGUP" },
|
||||
{ GLFW_KEY_PAGE_DOWN, "PGDN" },
|
||||
{ GLFW_KEY_HOME, "HOME" },
|
||||
{ GLFW_KEY_END, "END" },
|
||||
{ GLFW_KEY_CAPS_LOCK, "CAPS" },
|
||||
{ GLFW_KEY_SCROLL_LOCK, "SCLK" },
|
||||
{ GLFW_KEY_NUM_LOCK, "NMLK" },
|
||||
{ GLFW_KEY_PRINT_SCREEN, "PRSC" },
|
||||
{ GLFW_KEY_PAUSE, "PAUS" },
|
||||
{ GLFW_KEY_F1, "FK01" },
|
||||
{ GLFW_KEY_F2, "FK02" },
|
||||
{ GLFW_KEY_F3, "FK03" },
|
||||
{ GLFW_KEY_F4, "FK04" },
|
||||
{ GLFW_KEY_F5, "FK05" },
|
||||
{ GLFW_KEY_F6, "FK06" },
|
||||
{ GLFW_KEY_F7, "FK07" },
|
||||
{ GLFW_KEY_F8, "FK08" },
|
||||
{ GLFW_KEY_F9, "FK09" },
|
||||
{ GLFW_KEY_F10, "FK10" },
|
||||
{ GLFW_KEY_F11, "FK11" },
|
||||
{ GLFW_KEY_F12, "FK12" },
|
||||
{ GLFW_KEY_F13, "FK13" },
|
||||
{ GLFW_KEY_F14, "FK14" },
|
||||
{ GLFW_KEY_F15, "FK15" },
|
||||
{ GLFW_KEY_F16, "FK16" },
|
||||
{ GLFW_KEY_F17, "FK17" },
|
||||
{ GLFW_KEY_F18, "FK18" },
|
||||
{ GLFW_KEY_F19, "FK19" },
|
||||
{ GLFW_KEY_F20, "FK20" },
|
||||
{ GLFW_KEY_F21, "FK21" },
|
||||
{ GLFW_KEY_F22, "FK22" },
|
||||
{ GLFW_KEY_F23, "FK23" },
|
||||
{ GLFW_KEY_F24, "FK24" },
|
||||
{ GLFW_KEY_F25, "FK25" },
|
||||
{ GLFW_KEY_KP_0, "KP0" },
|
||||
{ GLFW_KEY_KP_1, "KP1" },
|
||||
{ GLFW_KEY_KP_2, "KP2" },
|
||||
{ GLFW_KEY_KP_3, "KP3" },
|
||||
{ GLFW_KEY_KP_4, "KP4" },
|
||||
{ GLFW_KEY_KP_5, "KP5" },
|
||||
{ GLFW_KEY_KP_6, "KP6" },
|
||||
{ GLFW_KEY_KP_7, "KP7" },
|
||||
{ GLFW_KEY_KP_8, "KP8" },
|
||||
{ GLFW_KEY_KP_9, "KP9" },
|
||||
{ GLFW_KEY_KP_DECIMAL, "KPDL" },
|
||||
{ GLFW_KEY_KP_DIVIDE, "KPDV" },
|
||||
{ GLFW_KEY_KP_MULTIPLY, "KPMU" },
|
||||
{ GLFW_KEY_KP_SUBTRACT, "KPSU" },
|
||||
{ GLFW_KEY_KP_ADD, "KPAD" },
|
||||
{ GLFW_KEY_KP_ENTER, "KPEN" },
|
||||
{ GLFW_KEY_KP_EQUAL, "KPEQ" },
|
||||
{ GLFW_KEY_LEFT_SHIFT, "LFSH" },
|
||||
{ GLFW_KEY_LEFT_CONTROL, "LCTL" },
|
||||
{ GLFW_KEY_LEFT_ALT, "LALT" },
|
||||
{ GLFW_KEY_LEFT_SUPER, "LWIN" },
|
||||
{ GLFW_KEY_RIGHT_SHIFT, "RTSH" },
|
||||
{ GLFW_KEY_RIGHT_CONTROL, "RCTL" },
|
||||
{ GLFW_KEY_RIGHT_ALT, "RALT" },
|
||||
{ GLFW_KEY_RIGHT_ALT, "LVL3" },
|
||||
{ GLFW_KEY_RIGHT_ALT, "MDSW" },
|
||||
{ GLFW_KEY_RIGHT_SUPER, "RWIN" },
|
||||
{ GLFW_KEY_MENU, "MENU" }
|
||||
};
|
||||
|
||||
// Find the X11 key code -> GLFW key code mapping
|
||||
for (scancode = desc->min_key_code; scancode <= desc->max_key_code; scancode++)
|
||||
for (scancode = scancodeMin; scancode <= scancodeMax; scancode++)
|
||||
{
|
||||
memcpy(name, desc->names->keys[scancode].name, XkbKeyNameLength);
|
||||
name[XkbKeyNameLength] = '\0';
|
||||
int key = GLFW_KEY_UNKNOWN;
|
||||
|
||||
// Map the key name to a GLFW key code. Note: We only map printable
|
||||
// keys here, and we use the US keyboard layout. The rest of the
|
||||
// keys (function keys) are mapped using traditional KeySym
|
||||
// translations.
|
||||
if (strcmp(name, "TLDE") == 0) key = GLFW_KEY_GRAVE_ACCENT;
|
||||
else if (strcmp(name, "AE01") == 0) key = GLFW_KEY_1;
|
||||
else if (strcmp(name, "AE02") == 0) key = GLFW_KEY_2;
|
||||
else if (strcmp(name, "AE03") == 0) key = GLFW_KEY_3;
|
||||
else if (strcmp(name, "AE04") == 0) key = GLFW_KEY_4;
|
||||
else if (strcmp(name, "AE05") == 0) key = GLFW_KEY_5;
|
||||
else if (strcmp(name, "AE06") == 0) key = GLFW_KEY_6;
|
||||
else if (strcmp(name, "AE07") == 0) key = GLFW_KEY_7;
|
||||
else if (strcmp(name, "AE08") == 0) key = GLFW_KEY_8;
|
||||
else if (strcmp(name, "AE09") == 0) key = GLFW_KEY_9;
|
||||
else if (strcmp(name, "AE10") == 0) key = GLFW_KEY_0;
|
||||
else if (strcmp(name, "AE11") == 0) key = GLFW_KEY_MINUS;
|
||||
else if (strcmp(name, "AE12") == 0) key = GLFW_KEY_EQUAL;
|
||||
else if (strcmp(name, "AD01") == 0) key = GLFW_KEY_Q;
|
||||
else if (strcmp(name, "AD02") == 0) key = GLFW_KEY_W;
|
||||
else if (strcmp(name, "AD03") == 0) key = GLFW_KEY_E;
|
||||
else if (strcmp(name, "AD04") == 0) key = GLFW_KEY_R;
|
||||
else if (strcmp(name, "AD05") == 0) key = GLFW_KEY_T;
|
||||
else if (strcmp(name, "AD06") == 0) key = GLFW_KEY_Y;
|
||||
else if (strcmp(name, "AD07") == 0) key = GLFW_KEY_U;
|
||||
else if (strcmp(name, "AD08") == 0) key = GLFW_KEY_I;
|
||||
else if (strcmp(name, "AD09") == 0) key = GLFW_KEY_O;
|
||||
else if (strcmp(name, "AD10") == 0) key = GLFW_KEY_P;
|
||||
else if (strcmp(name, "AD11") == 0) key = GLFW_KEY_LEFT_BRACKET;
|
||||
else if (strcmp(name, "AD12") == 0) key = GLFW_KEY_RIGHT_BRACKET;
|
||||
else if (strcmp(name, "AC01") == 0) key = GLFW_KEY_A;
|
||||
else if (strcmp(name, "AC02") == 0) key = GLFW_KEY_S;
|
||||
else if (strcmp(name, "AC03") == 0) key = GLFW_KEY_D;
|
||||
else if (strcmp(name, "AC04") == 0) key = GLFW_KEY_F;
|
||||
else if (strcmp(name, "AC05") == 0) key = GLFW_KEY_G;
|
||||
else if (strcmp(name, "AC06") == 0) key = GLFW_KEY_H;
|
||||
else if (strcmp(name, "AC07") == 0) key = GLFW_KEY_J;
|
||||
else if (strcmp(name, "AC08") == 0) key = GLFW_KEY_K;
|
||||
else if (strcmp(name, "AC09") == 0) key = GLFW_KEY_L;
|
||||
else if (strcmp(name, "AC10") == 0) key = GLFW_KEY_SEMICOLON;
|
||||
else if (strcmp(name, "AC11") == 0) key = GLFW_KEY_APOSTROPHE;
|
||||
else if (strcmp(name, "AB01") == 0) key = GLFW_KEY_Z;
|
||||
else if (strcmp(name, "AB02") == 0) key = GLFW_KEY_X;
|
||||
else if (strcmp(name, "AB03") == 0) key = GLFW_KEY_C;
|
||||
else if (strcmp(name, "AB04") == 0) key = GLFW_KEY_V;
|
||||
else if (strcmp(name, "AB05") == 0) key = GLFW_KEY_B;
|
||||
else if (strcmp(name, "AB06") == 0) key = GLFW_KEY_N;
|
||||
else if (strcmp(name, "AB07") == 0) key = GLFW_KEY_M;
|
||||
else if (strcmp(name, "AB08") == 0) key = GLFW_KEY_COMMA;
|
||||
else if (strcmp(name, "AB09") == 0) key = GLFW_KEY_PERIOD;
|
||||
else if (strcmp(name, "AB10") == 0) key = GLFW_KEY_SLASH;
|
||||
else if (strcmp(name, "BKSL") == 0) key = GLFW_KEY_BACKSLASH;
|
||||
else if (strcmp(name, "LSGT") == 0) key = GLFW_KEY_WORLD_1;
|
||||
else key = GLFW_KEY_UNKNOWN;
|
||||
// Map the key name to a GLFW key code. Note: We use the US
|
||||
// keyboard layout. Because function keys aren't mapped correctly
|
||||
// when using traditional KeySym translations, they are mapped
|
||||
// here instead.
|
||||
for (int i = 0; i < sizeof(keymap) / sizeof(keymap[0]); i++)
|
||||
{
|
||||
if (strncmp(desc->names->keys[scancode].name,
|
||||
keymap[i].name,
|
||||
XkbKeyNameLength) == 0)
|
||||
{
|
||||
key = keymap[i].key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((scancode >= 0) && (scancode < 256))
|
||||
_glfw.x11.keycodes[scancode] = key;
|
||||
// Fall back to key aliases in case the key name did not match
|
||||
for (int i = 0; i < desc->names->num_key_aliases; i++)
|
||||
{
|
||||
if (key != GLFW_KEY_UNKNOWN)
|
||||
break;
|
||||
|
||||
if (strncmp(desc->names->key_aliases[i].real,
|
||||
desc->names->keys[scancode].name,
|
||||
XkbKeyNameLength) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 0; j < sizeof(keymap) / sizeof(keymap[0]); j++)
|
||||
{
|
||||
if (strncmp(desc->names->key_aliases[i].alias,
|
||||
keymap[j].name,
|
||||
XkbKeyNameLength) == 0)
|
||||
{
|
||||
key = keymap[j].key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_glfw.x11.keycodes[scancode] = key;
|
||||
}
|
||||
|
||||
XkbFreeNames(desc, XkbKeyNamesMask, True);
|
||||
XkbFreeKeyboard(desc, 0, True);
|
||||
}
|
||||
else
|
||||
XDisplayKeycodes(_glfw.x11.display, &scancodeMin, &scancodeMax);
|
||||
|
||||
for (scancode = 0; scancode < 256; scancode++)
|
||||
int width;
|
||||
KeySym* keysyms = XGetKeyboardMapping(_glfw.x11.display,
|
||||
scancodeMin,
|
||||
scancodeMax - scancodeMin + 1,
|
||||
&width);
|
||||
|
||||
for (scancode = scancodeMin; scancode <= scancodeMax; scancode++)
|
||||
{
|
||||
// Translate the un-translated key codes using traditional X11 KeySym
|
||||
// lookups
|
||||
if (_glfw.x11.keycodes[scancode] < 0)
|
||||
_glfw.x11.keycodes[scancode] = translateKeyCode(scancode);
|
||||
{
|
||||
const size_t base = (scancode - scancodeMin) * width;
|
||||
_glfw.x11.keycodes[scancode] = translateKeySyms(&keysyms[base], width);
|
||||
}
|
||||
|
||||
// Store the reverse translation for faster key name lookup
|
||||
if (_glfw.x11.keycodes[scancode] > 0)
|
||||
_glfw.x11.scancodes[_glfw.x11.keycodes[scancode]] = scancode;
|
||||
}
|
||||
|
||||
XFree(keysyms);
|
||||
}
|
||||
|
||||
// Check whether the IM has a usable style
|
||||
@@ -352,13 +458,13 @@ static GLFWbool hasUsableInputMethodStyle(void)
|
||||
|
||||
// Check whether the specified atom is supported
|
||||
//
|
||||
static Atom getSupportedAtom(Atom* supportedAtoms,
|
||||
unsigned long atomCount,
|
||||
const char* atomName)
|
||||
static Atom getAtomIfSupported(Atom* supportedAtoms,
|
||||
unsigned long atomCount,
|
||||
const char* atomName)
|
||||
{
|
||||
const Atom atom = XInternAtom(_glfw.x11.display, atomName, False);
|
||||
|
||||
for (unsigned int i = 0; i < atomCount; i++)
|
||||
for (unsigned long i = 0; i < atomCount; i++)
|
||||
{
|
||||
if (supportedAtoms[i] == atom)
|
||||
return atom;
|
||||
@@ -426,33 +532,33 @@ static void detectEWMH(void)
|
||||
// See which of the atoms we support that are supported by the WM
|
||||
|
||||
_glfw.x11.NET_WM_STATE =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE");
|
||||
_glfw.x11.NET_WM_STATE_ABOVE =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_ABOVE");
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_ABOVE");
|
||||
_glfw.x11.NET_WM_STATE_FULLSCREEN =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");
|
||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_VERT");
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_VERT");
|
||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_HORZ");
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_HORZ");
|
||||
_glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_DEMANDS_ATTENTION");
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_STATE_DEMANDS_ATTENTION");
|
||||
_glfw.x11.NET_WM_FULLSCREEN_MONITORS =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS");
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS");
|
||||
_glfw.x11.NET_WM_WINDOW_TYPE =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE");
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE");
|
||||
_glfw.x11.NET_WM_WINDOW_TYPE_NORMAL =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL");
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL");
|
||||
_glfw.x11.NET_WORKAREA =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WORKAREA");
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_WORKAREA");
|
||||
_glfw.x11.NET_CURRENT_DESKTOP =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_CURRENT_DESKTOP");
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_CURRENT_DESKTOP");
|
||||
_glfw.x11.NET_ACTIVE_WINDOW =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
|
||||
_glfw.x11.NET_FRAME_EXTENTS =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_FRAME_EXTENTS");
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_FRAME_EXTENTS");
|
||||
_glfw.x11.NET_REQUEST_FRAME_EXTENTS =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS");
|
||||
getAtomIfSupported(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS");
|
||||
|
||||
if (supportedAtoms)
|
||||
XFree(supportedAtoms);
|
||||
@@ -666,13 +772,12 @@ static GLFWbool initExtensions(void)
|
||||
_glfw.x11.xkb.detectable = GLFW_TRUE;
|
||||
}
|
||||
|
||||
_glfw.x11.xkb.group = 0;
|
||||
XkbStateRec state;
|
||||
if (XkbGetState(_glfw.x11.display, XkbUseCoreKbd, &state) == Success)
|
||||
{
|
||||
XkbSelectEventDetails(_glfw.x11.display, XkbUseCoreKbd, XkbStateNotify, XkbAllStateComponentsMask, XkbGroupStateMask);
|
||||
_glfw.x11.xkb.group = (unsigned int)state.group;
|
||||
}
|
||||
|
||||
XkbSelectEventDetails(_glfw.x11.display, XkbUseCoreKbd, XkbStateNotify,
|
||||
XkbGroupStateMask, XkbGroupStateMask);
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
@@ -857,6 +962,9 @@ static Window createHelperWindow(void)
|
||||
//
|
||||
static int errorHandler(Display *display, XErrorEvent* event)
|
||||
{
|
||||
if (_glfw.x11.display != display)
|
||||
return 0;
|
||||
|
||||
_glfw.x11.errorCode = event->error_code;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1195,6 +1195,8 @@ static void processEvent(XEvent *event)
|
||||
{
|
||||
_glfw.x11.xkb.group = ((XkbEvent*) event)->state.group;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1557,6 +1559,8 @@ static void processEvent(XEvent *event)
|
||||
// the position into root (screen) coordinates
|
||||
if (!event->xany.send_event && window->x11.parent != _glfw.x11.root)
|
||||
{
|
||||
_glfwGrabErrorHandlerX11();
|
||||
|
||||
Window dummy;
|
||||
XTranslateCoordinates(_glfw.x11.display,
|
||||
window->x11.parent,
|
||||
@@ -1564,6 +1568,10 @@ static void processEvent(XEvent *event)
|
||||
xpos, ypos,
|
||||
&xpos, &ypos,
|
||||
&dummy);
|
||||
|
||||
_glfwReleaseErrorHandlerX11();
|
||||
if (_glfw.x11.errorCode == BadWindow)
|
||||
return;
|
||||
}
|
||||
|
||||
if (xpos != window->x11.xpos || ypos != window->x11.ypos)
|
||||
@@ -1971,7 +1979,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
Visual* visual;
|
||||
Visual* visual = NULL;
|
||||
int depth;
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
@@ -1997,8 +2005,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
}
|
||||
}
|
||||
|
||||
if (ctxconfig->client == GLFW_NO_API ||
|
||||
ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
||||
if (!visual)
|
||||
{
|
||||
visual = DefaultVisual(_glfw.x11.display, _glfw.x11.screen);
|
||||
depth = DefaultDepth(_glfw.x11.display, _glfw.x11.screen);
|
||||
|
||||
Reference in New Issue
Block a user