From c4b4476d78fae0acdd4d904f0a3729e6cc925581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 12 Feb 2020 14:53:18 +0100 Subject: [PATCH 01/30] Wayland: Remove unused link-time dependency The wayland-egl library is now loaded dynamically at init. This narrows the pkgconfig dependencies to the link-time depdendencies. (cherry picked from commit 6aca3e99f03617df1dd9081f20bd5408baf2a5d6) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 593f5cb3..be2eaf96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -244,7 +244,7 @@ if (_GLFW_WAYLAND) find_package(WaylandScanner REQUIRED) find_package(WaylandProtocols 1.15 REQUIRED) - list(APPEND glfw_PKG_DEPS "wayland-egl") + list(APPEND glfw_PKG_DEPS "wayland-client") list(APPEND glfw_INCLUDE_DIRS "${Wayland_INCLUDE_DIRS}") list(APPEND glfw_LIBRARIES "${Wayland_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}") From aee62d3c16196163c26322dea8364bd72f84fad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 12 Mar 2020 01:57:10 +0100 Subject: [PATCH 02/30] Fix unclear language in build guide Fixes #1658. (cherry picked from commit 9516df52a4745a67f4e1d58d3de32c74b8c33ecf) --- docs/build.dox | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/build.dox b/docs/build.dox index 5aeb136a..8ef3543a 100644 --- a/docs/build.dox +++ b/docs/build.dox @@ -219,7 +219,7 @@ find_package(OpenGL REQUIRED) @endcode If OpenGL is found, the `OpenGL::GL` target is added to your project, containing -library and include directory paths. Link against this like above. +library and include directory paths. Link against this like any other library. @code{.cmake} target_link_libraries(myapp OpenGL::GL) @@ -258,7 +258,7 @@ find_package(OpenGL REQUIRED) @endcode If OpenGL is found, the `OpenGL::GL` target is added to your project, containing -library and include directory paths. Link against this like above. +library and include directory paths. Link against this like any other library. @code{.cmake} target_link_libraries(myapp OpenGL::GL) From 2d4c4b7949563ce303dd44dd45295dfe7d443804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 16 Mar 2020 17:13:59 +0100 Subject: [PATCH 03/30] X11: Filter out Xlib errors from other connections (cherry picked from commit 2c8e0512ddb1e8baa73c5b8a03a79aedb4e5939d) --- README.md | 2 ++ src/x11_init.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/README.md b/README.md index a9f0d935..e08d56c9 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,8 @@ information on what to include when reporting a bug. ## Changelog - [X11] Bugfix: IME input of CJK was broken for "C" locale (#1587,#1636) + - [X11] Bugfix: Xlib errors caused by other parts of the application could be + reported as GLFW errors ## Contact diff --git a/src/x11_init.c b/src/x11_init.c index ee6c8720..a34bd591 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -851,6 +851,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; } From a6d022c257a3f2e0b626fd2d0fd3fca71ba84e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 19 Mar 2020 23:28:21 +0100 Subject: [PATCH 04/30] X11: Improve window handle race condition The non-root parent window owned by the WM could be destroyed before we process the ConfigureNotify event using the cached parent handle. Bug was found by unmapping a decorated window. This like all uses of the Xlib error handler is not thread safe and there is nothing we can do about that short of moving to XCB. Fixes #1633. (cherry picked from commit e65de2941c056ee5833b4dab3db36b297b53aa14) --- README.md | 1 + src/x11_window.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/README.md b/README.md index e08d56c9..b4d4163c 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,7 @@ information on what to include when reporting a bug. - [X11] Bugfix: IME input of CJK was broken for "C" locale (#1587,#1636) - [X11] Bugfix: Xlib errors caused by other parts of the application could be reported as GLFW errors + - [X11] Bugfix: A handle race condition could cause a `BadWindow` error (#1633) ## Contact diff --git a/src/x11_window.c b/src/x11_window.c index 3c03ccda..df622147 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1557,6 +1557,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 +1566,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) From b25ee390c13fe180fbb38585bcff3eea02add092 Mon Sep 17 00:00:00 2001 From: Ali Sherief <42585895+ZenulAbidin@users.noreply.github.com> Date: Thu, 21 Nov 2019 16:49:44 +0200 Subject: [PATCH 05/30] X11: Fix function keys mapped to GLFW_KEY_UNKNOWN This fixes the issue where function keys would be reported as GLFW_KEY_UNKNOWN if XKB was available and one of the configured keyboard layouts was Arabic. This is only part of #1598, because the full patch removed parts of the fallback path for when XKB is unavailable. Closes #1598. (cherry picked from commit a41a58a95e2ba8c2db8a2438aaa14b09f118e099) --- src/x11_init.c | 110 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 75 insertions(+), 35 deletions(-) diff --git a/src/x11_init.c b/src/x11_init.c index a34bd591..ab4a099d 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -48,37 +48,6 @@ static int translateKeyCode(int scancode) if (scancode < 8 || scancode > 255) return GLFW_KEY_UNKNOWN; - if (_glfw.x11.xkb.available) - { - // 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) - { - case XK_KP_0: return GLFW_KEY_KP_0; - case XK_KP_1: return GLFW_KEY_KP_1; - case XK_KP_2: return GLFW_KEY_KP_2; - case XK_KP_3: return GLFW_KEY_KP_3; - case XK_KP_4: return GLFW_KEY_KP_4; - case XK_KP_5: return GLFW_KEY_KP_5; - case XK_KP_6: return GLFW_KEY_KP_6; - case XK_KP_7: return GLFW_KEY_KP_7; - case XK_KP_8: return GLFW_KEY_KP_8; - case XK_KP_9: return GLFW_KEY_KP_9; - case XK_KP_Separator: - case XK_KP_Decimal: return GLFW_KEY_KP_DECIMAL; - case XK_KP_Equal: return GLFW_KEY_KP_EQUAL; - 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; @@ -252,10 +221,10 @@ static void createKeyTables(void) memcpy(name, desc->names->keys[scancode].name, XkbKeyNameLength); name[XkbKeyNameLength] = '\0'; - // 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. + // 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. 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; @@ -304,6 +273,77 @@ static void createKeyTables(void) 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 if (strcmp(name, "SPCE") == 0) key = GLFW_KEY_SPACE; + else if (strcmp(name, "ESC") == 0) key = GLFW_KEY_ESCAPE; + else if (strcmp(name, "RTRN") == 0) key = GLFW_KEY_ENTER; + else if (strcmp(name, "TAB") == 0) key = GLFW_KEY_TAB; + else if (strcmp(name, "BKSP") == 0) key = GLFW_KEY_BACKSPACE; + else if (strcmp(name, "INS") == 0) key = GLFW_KEY_INSERT; + else if (strcmp(name, "DELE") == 0) key = GLFW_KEY_DELETE; + else if (strcmp(name, "RGHT") == 0) key = GLFW_KEY_RIGHT; + else if (strcmp(name, "LEFT") == 0) key = GLFW_KEY_LEFT; + else if (strcmp(name, "DOWN") == 0) key = GLFW_KEY_DOWN; + else if (strcmp(name, "UP") == 0) key = GLFW_KEY_UP; + else if (strcmp(name, "PGUP") == 0) key = GLFW_KEY_PAGE_UP; + else if (strcmp(name, "PGDN") == 0) key = GLFW_KEY_PAGE_DOWN; + else if (strcmp(name, "HOME") == 0) key = GLFW_KEY_HOME; + else if (strcmp(name, "END") == 0) key = GLFW_KEY_END; + else if (strcmp(name, "CAPS") == 0) key = GLFW_KEY_CAPS_LOCK; + else if (strcmp(name, "SCLK") == 0) key = GLFW_KEY_SCROLL_LOCK; + else if (strcmp(name, "NMLK") == 0) key = GLFW_KEY_NUM_LOCK; + else if (strcmp(name, "PRSC") == 0) key = GLFW_KEY_PRINT_SCREEN; + else if (strcmp(name, "PAUS") == 0) key = GLFW_KEY_PAUSE; + else if (strcmp(name, "FK01") == 0) key = GLFW_KEY_F1; + else if (strcmp(name, "FK02") == 0) key = GLFW_KEY_F2; + else if (strcmp(name, "FK03") == 0) key = GLFW_KEY_F3; + else if (strcmp(name, "FK04") == 0) key = GLFW_KEY_F4; + else if (strcmp(name, "FK05") == 0) key = GLFW_KEY_F5; + else if (strcmp(name, "FK06") == 0) key = GLFW_KEY_F6; + else if (strcmp(name, "FK07") == 0) key = GLFW_KEY_F7; + else if (strcmp(name, "FK08") == 0) key = GLFW_KEY_F8; + else if (strcmp(name, "FK09") == 0) key = GLFW_KEY_F9; + else if (strcmp(name, "FK10") == 0) key = GLFW_KEY_F10; + else if (strcmp(name, "FK11") == 0) key = GLFW_KEY_F11; + else if (strcmp(name, "FK12") == 0) key = GLFW_KEY_F12; + else if (strcmp(name, "FK13") == 0) key = GLFW_KEY_F13; + else if (strcmp(name, "FK14") == 0) key = GLFW_KEY_F14; + else if (strcmp(name, "FK15") == 0) key = GLFW_KEY_F15; + else if (strcmp(name, "FK16") == 0) key = GLFW_KEY_F16; + else if (strcmp(name, "FK17") == 0) key = GLFW_KEY_F17; + else if (strcmp(name, "FK18") == 0) key = GLFW_KEY_F18; + else if (strcmp(name, "FK19") == 0) key = GLFW_KEY_F19; + else if (strcmp(name, "FK20") == 0) key = GLFW_KEY_F20; + else if (strcmp(name, "FK21") == 0) key = GLFW_KEY_F21; + else if (strcmp(name, "FK22") == 0) key = GLFW_KEY_F22; + else if (strcmp(name, "FK23") == 0) key = GLFW_KEY_F23; + else if (strcmp(name, "FK24") == 0) key = GLFW_KEY_F24; + else if (strcmp(name, "FK25") == 0) key = GLFW_KEY_F25; + else if (strcmp(name, "KP0") == 0) key = GLFW_KEY_KP_0; + else if (strcmp(name, "KP1") == 0) key = GLFW_KEY_KP_1; + else if (strcmp(name, "KP2") == 0) key = GLFW_KEY_KP_2; + else if (strcmp(name, "KP3") == 0) key = GLFW_KEY_KP_3; + else if (strcmp(name, "KP4") == 0) key = GLFW_KEY_KP_4; + else if (strcmp(name, "KP5") == 0) key = GLFW_KEY_KP_5; + else if (strcmp(name, "KP6") == 0) key = GLFW_KEY_KP_6; + else if (strcmp(name, "KP7") == 0) key = GLFW_KEY_KP_7; + else if (strcmp(name, "KP8") == 0) key = GLFW_KEY_KP_8; + else if (strcmp(name, "KP9") == 0) key = GLFW_KEY_KP_9; + else if (strcmp(name, "KPDL") == 0) key = GLFW_KEY_KP_DECIMAL; + else if (strcmp(name, "KPDV") == 0) key = GLFW_KEY_KP_DIVIDE; + else if (strcmp(name, "KPMU") == 0) key = GLFW_KEY_KP_MULTIPLY; + else if (strcmp(name, "KPSU") == 0) key = GLFW_KEY_KP_SUBTRACT; + else if (strcmp(name, "KPAD") == 0) key = GLFW_KEY_KP_ADD; + else if (strcmp(name, "KPEN") == 0) key = GLFW_KEY_KP_ENTER; + else if (strcmp(name, "KPEQ") == 0) key = GLFW_KEY_KP_EQUAL; + else if (strcmp(name, "LFSH") == 0) key = GLFW_KEY_LEFT_SHIFT; + else if (strcmp(name, "LCTL") == 0) key = GLFW_KEY_LEFT_CONTROL; + else if (strcmp(name, "LALT") == 0) key = GLFW_KEY_LEFT_ALT; + else if (strcmp(name, "LWIN") == 0) key = GLFW_KEY_LEFT_SUPER; + else if (strcmp(name, "RTSH") == 0) key = GLFW_KEY_RIGHT_SHIFT; + else if (strcmp(name, "RCTL") == 0) key = GLFW_KEY_RIGHT_CONTROL; + else if (strcmp(name, "RALT") == 0) key = GLFW_KEY_RIGHT_ALT; + else if (strcmp(name, "RWIN") == 0) key = GLFW_KEY_RIGHT_SUPER; + else if (strcmp(name, "COMP") == 0) key = GLFW_KEY_MENU; else key = GLFW_KEY_UNKNOWN; if ((scancode >= 0) && (scancode < 256)) From ec5610dedaf6ae703f513404727817902425d034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 31 Mar 2020 17:30:22 +0200 Subject: [PATCH 06/30] Update changelog and add credit Related to #1598. (cherry picked from commit 215a05af3d76f58391f5b1e533630fb84f7478cd) --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index b4d4163c..3238eb02 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,10 @@ information on what to include when reporting a bug. - [X11] Bugfix: Xlib errors caused by other parts of the application could be reported as GLFW errors - [X11] Bugfix: A handle race condition could cause a `BadWindow` error (#1633) + - [X11] Bugfix: XKB path used keysyms instead of physical locations for + non-printable keys (#1598) + - [X11] Bugfix: Function keys were mapped to `GLFW_KEY_UNKNOWN` for some layout + combinaitons (#1598) ## Contact @@ -293,6 +297,7 @@ skills. - Matt Sealey - Steve Sexton - Arkady Shapkin + - Ali Sherief - Yoshiki Shibukawa - Dmitri Shuralyov - Daniel Skorupski From 27d7fc098d6b33c71ce0cfa3b9c991ed71020d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 17 Mar 2020 00:04:48 +0100 Subject: [PATCH 07/30] X11: Fix X keycode ranges for XKB and core This replaces the hardcoded keycode ranges and various kludgy range checks with the actual ranges reported by Xlib and XKB. (cherry picked from commit ee45b58647475ceec10255d12f2c9986d259599a) --- src/x11_init.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/x11_init.c b/src/x11_init.c index ab4a099d..fca0b9c9 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -44,10 +44,6 @@ static int translateKeyCode(int scancode) { int keySym; - // Valid key code range is [8,255], according to the Xlib manual - if (scancode < 8 || scancode > 255) - return GLFW_KEY_UNKNOWN; - { int dummy; KeySym* keySyms; @@ -201,7 +197,7 @@ static int translateKeyCode(int scancode) // static void createKeyTables(void) { - int scancode, key; + int scancode, key, scancodeMin, scancodeMax; memset(_glfw.x11.keycodes, -1, sizeof(_glfw.x11.keycodes)); memset(_glfw.x11.scancodes, -1, sizeof(_glfw.x11.scancodes)); @@ -215,8 +211,11 @@ static void createKeyTables(void) XkbDescPtr desc = XkbGetMap(_glfw.x11.display, 0, XkbUseCoreKbd); XkbGetNames(_glfw.x11.display, XkbKeyNamesMask, desc); + scancodeMin = desc->min_key_code; + scancodeMax = desc->max_key_code; + // 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'; @@ -346,15 +345,16 @@ static void createKeyTables(void) else if (strcmp(name, "COMP") == 0) key = GLFW_KEY_MENU; else key = GLFW_KEY_UNKNOWN; - if ((scancode >= 0) && (scancode < 256)) - _glfw.x11.keycodes[scancode] = key; + _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++) + for (scancode = scancodeMin; scancode <= scancodeMax; scancode++) { // Translate the un-translated key codes using traditional X11 KeySym // lookups From cf87e6549c98a1a8bfe42f5791a9dc515a7ac088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 25 Mar 2020 18:16:15 +0100 Subject: [PATCH 08/30] X11: Check XKB key aliases in addition to names (cherry picked from commit 9ecacf1d7fb782c326bc3c47c25b44fecd6c6677) --- src/x11_init.c | 290 ++++++++++++++++++++++++++++--------------------- 1 file changed, 165 insertions(+), 125 deletions(-) diff --git a/src/x11_init.c b/src/x11_init.c index fca0b9c9..ffa6fc8f 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -197,7 +197,7 @@ static int translateKeyCode(int scancode) // static void createKeyTables(void) { - int scancode, key, scancodeMin, scancodeMax; + int scancode, scancodeMin, scancodeMax; memset(_glfw.x11.keycodes, -1, sizeof(_glfw.x11.keycodes)); memset(_glfw.x11.scancodes, -1, sizeof(_glfw.x11.scancodes)); @@ -207,143 +207,183 @@ 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_SUPER, "RWIN" }, + { GLFW_KEY_MENU, "COMP" } + }; + // Find the X11 key code -> GLFW key code mapping 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 use the US // keyboard layout. Because function keys aren't mapped correctly // when using traditional KeySym translations, they are mapped // here instead. - 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 if (strcmp(name, "SPCE") == 0) key = GLFW_KEY_SPACE; - else if (strcmp(name, "ESC") == 0) key = GLFW_KEY_ESCAPE; - else if (strcmp(name, "RTRN") == 0) key = GLFW_KEY_ENTER; - else if (strcmp(name, "TAB") == 0) key = GLFW_KEY_TAB; - else if (strcmp(name, "BKSP") == 0) key = GLFW_KEY_BACKSPACE; - else if (strcmp(name, "INS") == 0) key = GLFW_KEY_INSERT; - else if (strcmp(name, "DELE") == 0) key = GLFW_KEY_DELETE; - else if (strcmp(name, "RGHT") == 0) key = GLFW_KEY_RIGHT; - else if (strcmp(name, "LEFT") == 0) key = GLFW_KEY_LEFT; - else if (strcmp(name, "DOWN") == 0) key = GLFW_KEY_DOWN; - else if (strcmp(name, "UP") == 0) key = GLFW_KEY_UP; - else if (strcmp(name, "PGUP") == 0) key = GLFW_KEY_PAGE_UP; - else if (strcmp(name, "PGDN") == 0) key = GLFW_KEY_PAGE_DOWN; - else if (strcmp(name, "HOME") == 0) key = GLFW_KEY_HOME; - else if (strcmp(name, "END") == 0) key = GLFW_KEY_END; - else if (strcmp(name, "CAPS") == 0) key = GLFW_KEY_CAPS_LOCK; - else if (strcmp(name, "SCLK") == 0) key = GLFW_KEY_SCROLL_LOCK; - else if (strcmp(name, "NMLK") == 0) key = GLFW_KEY_NUM_LOCK; - else if (strcmp(name, "PRSC") == 0) key = GLFW_KEY_PRINT_SCREEN; - else if (strcmp(name, "PAUS") == 0) key = GLFW_KEY_PAUSE; - else if (strcmp(name, "FK01") == 0) key = GLFW_KEY_F1; - else if (strcmp(name, "FK02") == 0) key = GLFW_KEY_F2; - else if (strcmp(name, "FK03") == 0) key = GLFW_KEY_F3; - else if (strcmp(name, "FK04") == 0) key = GLFW_KEY_F4; - else if (strcmp(name, "FK05") == 0) key = GLFW_KEY_F5; - else if (strcmp(name, "FK06") == 0) key = GLFW_KEY_F6; - else if (strcmp(name, "FK07") == 0) key = GLFW_KEY_F7; - else if (strcmp(name, "FK08") == 0) key = GLFW_KEY_F8; - else if (strcmp(name, "FK09") == 0) key = GLFW_KEY_F9; - else if (strcmp(name, "FK10") == 0) key = GLFW_KEY_F10; - else if (strcmp(name, "FK11") == 0) key = GLFW_KEY_F11; - else if (strcmp(name, "FK12") == 0) key = GLFW_KEY_F12; - else if (strcmp(name, "FK13") == 0) key = GLFW_KEY_F13; - else if (strcmp(name, "FK14") == 0) key = GLFW_KEY_F14; - else if (strcmp(name, "FK15") == 0) key = GLFW_KEY_F15; - else if (strcmp(name, "FK16") == 0) key = GLFW_KEY_F16; - else if (strcmp(name, "FK17") == 0) key = GLFW_KEY_F17; - else if (strcmp(name, "FK18") == 0) key = GLFW_KEY_F18; - else if (strcmp(name, "FK19") == 0) key = GLFW_KEY_F19; - else if (strcmp(name, "FK20") == 0) key = GLFW_KEY_F20; - else if (strcmp(name, "FK21") == 0) key = GLFW_KEY_F21; - else if (strcmp(name, "FK22") == 0) key = GLFW_KEY_F22; - else if (strcmp(name, "FK23") == 0) key = GLFW_KEY_F23; - else if (strcmp(name, "FK24") == 0) key = GLFW_KEY_F24; - else if (strcmp(name, "FK25") == 0) key = GLFW_KEY_F25; - else if (strcmp(name, "KP0") == 0) key = GLFW_KEY_KP_0; - else if (strcmp(name, "KP1") == 0) key = GLFW_KEY_KP_1; - else if (strcmp(name, "KP2") == 0) key = GLFW_KEY_KP_2; - else if (strcmp(name, "KP3") == 0) key = GLFW_KEY_KP_3; - else if (strcmp(name, "KP4") == 0) key = GLFW_KEY_KP_4; - else if (strcmp(name, "KP5") == 0) key = GLFW_KEY_KP_5; - else if (strcmp(name, "KP6") == 0) key = GLFW_KEY_KP_6; - else if (strcmp(name, "KP7") == 0) key = GLFW_KEY_KP_7; - else if (strcmp(name, "KP8") == 0) key = GLFW_KEY_KP_8; - else if (strcmp(name, "KP9") == 0) key = GLFW_KEY_KP_9; - else if (strcmp(name, "KPDL") == 0) key = GLFW_KEY_KP_DECIMAL; - else if (strcmp(name, "KPDV") == 0) key = GLFW_KEY_KP_DIVIDE; - else if (strcmp(name, "KPMU") == 0) key = GLFW_KEY_KP_MULTIPLY; - else if (strcmp(name, "KPSU") == 0) key = GLFW_KEY_KP_SUBTRACT; - else if (strcmp(name, "KPAD") == 0) key = GLFW_KEY_KP_ADD; - else if (strcmp(name, "KPEN") == 0) key = GLFW_KEY_KP_ENTER; - else if (strcmp(name, "KPEQ") == 0) key = GLFW_KEY_KP_EQUAL; - else if (strcmp(name, "LFSH") == 0) key = GLFW_KEY_LEFT_SHIFT; - else if (strcmp(name, "LCTL") == 0) key = GLFW_KEY_LEFT_CONTROL; - else if (strcmp(name, "LALT") == 0) key = GLFW_KEY_LEFT_ALT; - else if (strcmp(name, "LWIN") == 0) key = GLFW_KEY_LEFT_SUPER; - else if (strcmp(name, "RTSH") == 0) key = GLFW_KEY_RIGHT_SHIFT; - else if (strcmp(name, "RCTL") == 0) key = GLFW_KEY_RIGHT_CONTROL; - else if (strcmp(name, "RALT") == 0) key = GLFW_KEY_RIGHT_ALT; - else if (strcmp(name, "RWIN") == 0) key = GLFW_KEY_RIGHT_SUPER; - else if (strcmp(name, "COMP") == 0) key = GLFW_KEY_MENU; - else key = GLFW_KEY_UNKNOWN; + 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; + } + } + + // 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; } From 4aaf8ba1d2332ca04217a2df64901945ea9683a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 31 Mar 2020 17:00:43 +0200 Subject: [PATCH 09/30] X11: Use XKB key name MENU for Menu key (cherry picked from commit 560304e0f4250fb979e65de00b6c8ce3b9fd6b71) --- src/x11_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x11_init.c b/src/x11_init.c index ffa6fc8f..0cbefd21 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -337,7 +337,7 @@ static void createKeyTables(void) { GLFW_KEY_RIGHT_CONTROL, "RCTL" }, { GLFW_KEY_RIGHT_ALT, "RALT" }, { GLFW_KEY_RIGHT_SUPER, "RWIN" }, - { GLFW_KEY_MENU, "COMP" } + { GLFW_KEY_MENU, "MENU" } }; // Find the X11 key code -> GLFW key code mapping From b0c79896a3a3841315c41fc17e43e00669fa1d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 23 Apr 2020 17:42:36 +0200 Subject: [PATCH 10/30] X11: Add additional XKB key names for Right Alt (cherry picked from commit 318e08d914e7e1893800d7d61a7188697b13bce2) --- src/x11_init.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/x11_init.c b/src/x11_init.c index 0cbefd21..674f587e 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -336,6 +336,8 @@ static void createKeyTables(void) { 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" } }; From 404c28df3d05b5579e5a1bd6656b610751a1c764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 23 Apr 2020 21:27:28 +0200 Subject: [PATCH 11/30] X11: Improve non-XKB fallback for key mapping A regression introduced by b889aa784129b3e7d1219a55a1008bd6518183db broke the special handling of numpad keys for the non-XKB fallback path. The non-functional remains were later removed. This restores the original behavior. (cherry picked from commit cab41529da42f46dc6d6aec159a9b8d1d1331652) --- src/x11_init.c | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/x11_init.c b/src/x11_init.c index 674f587e..b6399c56 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -38,22 +38,35 @@ #include -// 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; - + if (width > 1) { - int dummy; - KeySym* keySyms; - - keySyms = XGetKeyboardMapping(_glfw.x11.display, scancode, 1, &dummy); - keySym = keySyms[0]; - XFree(keySyms); + switch (keysyms[1]) + { + case XK_KP_0: return GLFW_KEY_KP_0; + case XK_KP_1: return GLFW_KEY_KP_1; + case XK_KP_2: return GLFW_KEY_KP_2; + case XK_KP_3: return GLFW_KEY_KP_3; + case XK_KP_4: return GLFW_KEY_KP_4; + case XK_KP_5: return GLFW_KEY_KP_5; + case XK_KP_6: return GLFW_KEY_KP_6; + case XK_KP_7: return GLFW_KEY_KP_7; + case XK_KP_8: return GLFW_KEY_KP_8; + case XK_KP_9: return GLFW_KEY_KP_9; + case XK_KP_Separator: + case XK_KP_Decimal: return GLFW_KEY_KP_DECIMAL; + case XK_KP_Equal: return GLFW_KEY_KP_EQUAL; + case XK_KP_Enter: return GLFW_KEY_KP_ENTER; + default: break; + } } - switch (keySym) + switch (keysyms[0]) { case XK_Escape: return GLFW_KEY_ESCAPE; case XK_Tab: return GLFW_KEY_TAB; @@ -396,17 +409,28 @@ static void createKeyTables(void) else XDisplayKeycodes(_glfw.x11.display, &scancodeMin, &scancodeMax); + 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 From 6e01359e3683f2a8ae336c98e617426f74527e52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 30 Apr 2020 22:12:21 +0200 Subject: [PATCH 12/30] Cocoa: Fix call to NSWindow from non-main threads glfwSwapBuffers may be called by any thread but NSWindow may not. Bug introduced by c3ca88055f7c2c8b02b38cb90fc1989990552977 and reported by @crujose. (cherry picked from commit 949275bbedaa58a5399c6ce5276adc190ae6a16b) --- src/cocoa_platform.h | 1 + src/cocoa_window.m | 8 ++++++++ src/nsgl_context.m | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 15c21696..e979396c 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -121,6 +121,7 @@ typedef struct _GLFWwindowNS id layer; GLFWbool maximized; + GLFWbool occluded; GLFWbool retina; // Cached window properties to filter out duplicate events diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 129e975e..17f34733 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -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 diff --git a/src/nsgl_context.m b/src/nsgl_context.m index 3bcfafcc..10286849 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -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 From 8216a148cf85e94fa99a10acc81d39893932fbf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 4 May 2020 23:18:48 +0200 Subject: [PATCH 13/30] Disambiguate Vulkan support reference link (cherry picked from commit 41a19ed49c5ace44949f58b157714d59c2aebf2f) --- docs/vulkan.dox | 2 +- include/GLFW/glfw3.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/vulkan.dox b/docs/vulkan.dox index dc158d6d..767cb9ff 100644 --- a/docs/vulkan.dox +++ b/docs/vulkan.dox @@ -14,7 +14,7 @@ To develop for Vulkan you should download the [LunarG Vulkan SDK](https://vulkan.lunarg.com/) for your platform. Apart from headers and link libraries, they also provide the validation layers necessary for development. -For details on a specific function in this category, see the @ref vulkan. There +For details on a specific Vulkan support function, see the @ref vulkan. There are also guides for the other areas of the GLFW API. - @ref intro_guide diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 255b5279..88364263 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -52,7 +52,7 @@ extern "C" { * This is the reference documentation for OpenGL and OpenGL ES context related * functions. For more task-oriented information, see the @ref context_guide. */ -/*! @defgroup vulkan Vulkan reference +/*! @defgroup vulkan Vulkan support reference * @brief Functions and types related to Vulkan. * * This is the reference documentation for Vulkan related functions and types. From 10c01512f263c6b63735b1ea8e4867d7c1710d52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 30 Apr 2020 21:21:40 +0200 Subject: [PATCH 14/30] Update community resource links (cherry picked from commit d7ae90a790416f150a39e8f42f8278598bafae29) --- docs/build.dox | 3 +++ docs/quick.dox | 16 ++++++++++------ docs/vulkan.dox | 9 +++++++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/docs/build.dox b/docs/build.dox index 8ef3543a..ed79075a 100644 --- a/docs/build.dox +++ b/docs/build.dox @@ -225,6 +225,9 @@ library and include directory paths. Link against this like any other library. target_link_libraries(myapp OpenGL::GL) @endcode +For a minimal example of a program and GLFW sources built with CMake, see the +[GLFW CMake Starter](https://github.com/juliettef/GLFW-CMake-starter) on GitHub. + @subsection build_link_cmake_package With CMake and installed GLFW binaries diff --git a/docs/quick.dox b/docs/quick.dox index 73070f4a..2c6fcb9d 100644 --- a/docs/quick.dox +++ b/docs/quick.dox @@ -246,12 +246,16 @@ glViewport(0, 0, width, height); You can also set a framebuffer size callback using @ref glfwSetFramebufferSizeCallback and be notified when the size changes. -Actual rendering with OpenGL is outside the scope of this tutorial, but there -are [many](https://open.gl/) [excellent](https://learnopengl.com/) -[tutorial](http://openglbook.com/) [sites](http://ogldev.atspace.co.uk/) that -teach modern OpenGL. Some of them use GLFW to create the context and window -while others use GLUT or SDL, but remember that OpenGL itself always works the -same. +The details of how to render with OpenGL is outside the scope of this tutorial, +but there are many excellent resources for learning modern OpenGL. Here are +a few of them: + + - [Anton's OpenGL 4 Tutorials](https://antongerdelan.net/opengl/) + - [Learn OpenGL](https://learnopengl.com/) + - [Open.GL](https://open.gl/) + +These all happen to use GLFW, but OpenGL itself works the same whatever API you +use to create the window and context. @subsection quick_timer Reading the timer diff --git a/docs/vulkan.dox b/docs/vulkan.dox index 767cb9ff..2585c2bb 100644 --- a/docs/vulkan.dox +++ b/docs/vulkan.dox @@ -4,8 +4,8 @@ @tableofcontents -This guide is intended to fill the gaps between the [Vulkan -documentation](https://www.khronos.org/vulkan/) and the rest of the GLFW +This guide is intended to fill the gaps between the official [Vulkan +resources](https://www.khronos.org/vulkan/) and the rest of the GLFW documentation and is not a replacement for either. It assumes some familiarity with Vulkan concepts like loaders, devices, queues and surfaces and leaves it to the Vulkan documentation to explain the details of Vulkan functions. @@ -14,6 +14,11 @@ To develop for Vulkan you should download the [LunarG Vulkan SDK](https://vulkan.lunarg.com/) for your platform. Apart from headers and link libraries, they also provide the validation layers necessary for development. +The [Vulkan Tutorial](https://vulkan-tutorial.com/) has more information on how +to use GLFW and Vulkan. The [Khronos Vulkan +Samples](https://github.com/KhronosGroup/Vulkan-Samples) also use GLFW, although +with a small framework in between. + For details on a specific Vulkan support function, see the @ref vulkan. There are also guides for the other areas of the GLFW API. From e145d89a96b0027325b70eef3cac75ef3ac3210b Mon Sep 17 00:00:00 2001 From: gre-42 <63736956+gre-42@users.noreply.github.com> Date: Wed, 15 Apr 2020 18:00:11 +0200 Subject: [PATCH 15/30] Correct sign in mat4x4_rotate_Y Signs were incorrect in mat4x4_rotate_Y. Closes #1673. (cherry picked from commit 67c720d117673f0e2d4625ba8463d7472bf9a71a) --- deps/linmath.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/linmath.h b/deps/linmath.h index 9c2e2a0a..0ab7a414 100644 --- a/deps/linmath.h +++ b/deps/linmath.h @@ -237,9 +237,9 @@ static inline void mat4x4_rotate_Y(mat4x4 Q, mat4x4 M, float angle) float s = sinf(angle); float c = cosf(angle); mat4x4 R = { - { c, 0.f, s, 0.f}, + { c, 0.f, -s, 0.f}, { 0.f, 1.f, 0.f, 0.f}, - { -s, 0.f, c, 0.f}, + { s, 0.f, c, 0.f}, { 0.f, 0.f, 0.f, 1.f} }; mat4x4_mul(Q, M, R); From d0c0997528bc8f64c65550dba924694f3a5ab3ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 19 May 2020 13:24:49 +0200 Subject: [PATCH 16/30] Add null platform to Travis CI (cherry picked from commit 844bc8031c63284ba324217b39b663a104fc4d35) --- .travis.yml | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5f3b7393..0b6392bd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -69,6 +69,28 @@ matrix: - USE_WAYLAND=ON - BUILD_SHARED_LIBS=OFF - CFLAGS=-Werror + - os: linux + dist: bionic + name: "Null shared library" + addons: + apt: + packages: + - libosmesa6-dev + env: + - BUILD_SHARED_LIBS=ON + - USE_OSMESA=ON + - CFLAGS=-Werror + - os: linux + dist: bionic + name: "Null static library" + addons: + apt: + packages: + - libosmesa6-dev + env: + - BUILD_SHARED_LIBS=OFF + - USE_OSMESA=ON + - CFLAGS=-Werror - os: osx sudo: false name: "Cocoa shared library" @@ -96,7 +118,7 @@ script: git checkout 1.15 && ./autogen.sh --prefix=/usr && make && sudo make install; popd; fi - - cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -DGLFW_USE_WAYLAND=${USE_WAYLAND} .. + - cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -DGLFW_USE_WAYLAND=${USE_WAYLAND} -DGLFW_USE_OSMESA=${USE_OSMESA} .. - cmake --build . notifications: email: From 117f7694b2d8b2341145746679953198b98d6bb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 19 May 2020 17:44:59 +0200 Subject: [PATCH 17/30] X11: Fix XKB group event depending on state query This fixes XKB group change events not being enabled if the initial XKB keyboard state query fails. (cherry picked from commit 0c403c8ca678208d5770211257d20581730d78b3) --- src/x11_init.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/x11_init.c b/src/x11_init.c index b6399c56..ad083f87 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -769,10 +769,9 @@ static GLFWbool initExtensions(void) _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, XkbAllStateComponentsMask, XkbGroupStateMask); } #if defined(__CYGWIN__) From dff64496d6bfd4b0e71dd289da136f3cfe0a52f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 19 May 2020 17:47:58 +0200 Subject: [PATCH 18/30] X11: Remove duplicate XKB group initialization The XKB group is already set to zero during initialization. (cherry picked from commit cf3a03a85d4ea031f231ca72d66228757778cc8e) --- src/x11_init.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/x11_init.c b/src/x11_init.c index ad083f87..bba68400 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -766,7 +766,6 @@ 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) _glfw.x11.xkb.group = (unsigned int)state.group; From 3df4ebeaacee35bb3d441e101f8f9d2fcf586745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 19 May 2020 17:49:02 +0200 Subject: [PATCH 19/30] X11: Fix XKB state event bits being overwritten This limits the update to the XKB group state event bit without clearing all other state event bits. (cherry picked from commit e07925c4047c4c5401369e0c6fe70bcab61e30c6) --- src/x11_init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/x11_init.c b/src/x11_init.c index bba68400..a3aacef5 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -770,7 +770,8 @@ static GLFWbool initExtensions(void) if (XkbGetState(_glfw.x11.display, XkbUseCoreKbd, &state) == Success) _glfw.x11.xkb.group = (unsigned int)state.group; - XkbSelectEventDetails(_glfw.x11.display, XkbUseCoreKbd, XkbStateNotify, XkbAllStateComponentsMask, XkbGroupStateMask); + XkbSelectEventDetails(_glfw.x11.display, XkbUseCoreKbd, XkbStateNotify, + XkbGroupStateMask, XkbGroupStateMask); } #if defined(__CYGWIN__) From 48bc089e9ea6ca821cf68b1d2f99c6f6e8e669e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 19 May 2020 17:55:28 +0200 Subject: [PATCH 20/30] X11: Fix XKB events being passed on to core path (cherry picked from commit a17a1b20115ef7c86ac1667532b67788ec8631df) --- src/x11_window.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/x11_window.c b/src/x11_window.c index df622147..c3cc82b0 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1195,6 +1195,8 @@ static void processEvent(XEvent *event) { _glfw.x11.xkb.group = ((XkbEvent*) event)->state.group; } + + return; } } From 0a7c24e48c00b36dc82a206c4f2e88e4eab60379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 19 May 2020 17:59:18 +0200 Subject: [PATCH 21/30] X11: Clarify code flow for Clang static analysis (cherry picked from commit ef5220d6b10174d0f7cce965475e34527afcfbcf) --- src/x11_window.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/x11_window.c b/src/x11_window.c index c3cc82b0..37c34fae 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1979,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) @@ -2005,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); From ca2cd2f796a7fc27e95efbe7325eafefc47d8a03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 19 May 2020 19:03:02 +0200 Subject: [PATCH 22/30] X11: Clarify function name and comment (cherry picked from commit 5f9dfe3d83af4d6b95c2e4f19adadc334eb314ae) --- src/x11_init.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/x11_init.c b/src/x11_init.c index a3aacef5..ac5a7b39 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -458,9 +458,9 @@ 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); @@ -532,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); From 8b63ca53dec5e074160eaf211581a4123cdd0def Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Sun, 19 Apr 2020 14:10:52 +0200 Subject: [PATCH 23/30] Use CALayer instead of NSView for EGLNativeWindowType The only two EGL implementations on macOS are Swiftshader and ANGLE. While Swiftshader supports both `NSView` and `CALayer` as `EGLNativeWindowType`, ANGLE supports only `CALayer`. Furthermore Swiftshader's OpenGL ES frontend is deprecated in favor of using ANGLE's Vulkan backend on top of Swiftshader's Vulkan frontend. This means that on macOS `EGLNativeWindowType` should be a `CALayer` for compatibility with ANGLE. Fixes #1169. Closes #1680. (cherry picked from commit 91eebe922de06a3ed4ba6622686c436c7941aa63) --- README.md | 1 + src/cocoa_platform.h | 2 +- src/cocoa_window.m | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3238eb02..6300f26c 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,7 @@ information on what to include when reporting a bug. ## Changelog + - [Cocoa] Use `CALayer` instead of `NSView` for `EGLNativeWindowType` (#1169) - [X11] Bugfix: IME input of CJK was broken for "C" locale (#1587,#1636) - [X11] Bugfix: Xlib errors caused by other parts of the application could be reported as GLFW errors diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index e979396c..05c23b70 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -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 diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 17f34733..ddd6e909 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -909,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)) From a8e5c530ee08851ef5675bfe28e1158a75e0e59d Mon Sep 17 00:00:00 2001 From: Luflosi Date: Mon, 25 May 2020 15:42:52 +0200 Subject: [PATCH 24/30] Replace %m conversion specifier with %s and strerror() When compiling with `-Wall` and `-pedantic-errors`, gcc complains with ``` warning: ISO C does not support the '%m' gnu_printf format [-Wformat=] ``` because the `%m` conversion specifier is a GNU extension. Closes #1702. (cherry picked from commit d4f50745356fd38e30100d50418b83db24755994) --- src/wl_window.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index a9025718..61785fe7 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -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; } From 11e5102d8342b4e1a690606876192a9f54de5f22 Mon Sep 17 00:00:00 2001 From: Luflosi Date: Mon, 25 May 2020 15:03:23 +0200 Subject: [PATCH 25/30] Use the correct type in a for loop The `atomCount` variable has the type `unsigned long`, so the `for` loop iterating over it should use the same type. Closes #1701. (cherry picked from commit 250b94cd03e6f947ba516869c7f3b277f8d0cacc) --- src/x11_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x11_init.c b/src/x11_init.c index ac5a7b39..87b3eb78 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -464,7 +464,7 @@ static Atom getAtomIfSupported(Atom* supportedAtoms, { 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; From 37a86f24f0aed0aea81c87a0c655ade64fce7394 Mon Sep 17 00:00:00 2001 From: ben1 Date: Mon, 25 May 2020 15:22:25 +1000 Subject: [PATCH 26/30] Win32: Fix VS /W4 compile warnings These are harmless errors but the code was worth fixing just to reduce confusion and be more explicit. E.g. using a different variable name for a new variable of a different type in win32_joystick.c. Closes #1700. (cherry picked from commit a84a30ab6399eedd4606da226fe4f02eab3c2d2e) --- src/egl_context.c | 16 +++++++--------- src/win32_joystick.c | 10 +++++----- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/egl_context.c b/src/egl_context.c index e458bfb8..6288fb7c 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -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, diff --git a/src/win32_joystick.c b/src/win32_joystick.c index 4ffc9fbf..62ad7a53 100644 --- a/src/win32_joystick.c +++ b/src/win32_joystick.c @@ -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; } From 78ad4e8f3652b5483c5de868a4ce581ac534d80e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 26 May 2020 23:35:40 +0200 Subject: [PATCH 27/30] Fix desktop GL header not always being suppressed If an OpenGL ES header or the glcorearb header is included before the GLFW header (with no options defined), the legacy OpenGL header will be implicitly included and the compilation will fail. This disables the default behavior if we detect any known OpenGL, OpenGL ES or extension loader inclusion guard macro. Sources: - Khronos headers - Windows SDK - MinGW - MinGW-w64 - flextGL - glad - glad2 - GLEW - Galogen - gl3w - GLXW - glbinding - Epoxy - Glatter - glLoadGen - Regal - GLee - OpenGL.framework - Debian - FreeBSD - ANGLE - SwiftShader Related to #1695. (cherry picked from commit 105cf32e0b05e207d4cd5efa462887569ca2116a) --- include/GLFW/glfw3.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 88364263..bf854b07 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -193,7 +193,22 @@ extern "C" { #endif /*__APPLE__*/ -#elif !defined(GLFW_INCLUDE_NONE) +#elif !defined(GLFW_INCLUDE_NONE) && \ + !defined(__gl_h_) && \ + !defined(__gles1_gl_h_) && \ + !defined(__gles2_gl2_h_) && \ + !defined(__gles2_gl3_h_) && \ + !defined(__gles2_gl31_h_) && \ + !defined(__gles2_gl32_h_) && \ + !defined(__gl_glcorearb_h_) && \ + !defined(__gl2_h_) /*legacy*/ && \ + !defined(__gl3_h_) /*legacy*/ && \ + !defined(__gl31_h_) /*legacy*/ && \ + !defined(__gl32_h_) /*legacy*/ && \ + !defined(__glcorearb_h_) /*legacy*/ && \ + !defined(__GL_H__) /*non-standard*/ && \ + !defined(__gltypes_h_) /*non-standard*/ && \ + !defined(__glee_h_) /*non-standard*/ #if defined(__APPLE__) From fb0c8d4662e47f6ea8b6acef615f0ef04646dfc3 Mon Sep 17 00:00:00 2001 From: "A. Tombs" Date: Fri, 22 May 2020 14:37:58 +0100 Subject: [PATCH 28/30] Add statement to docs for glfwTerminate It is safe to call glfwTerminate both before initialization and after termination. Closes #1698. (cherry picked from commit 7486e12f88b2a9039b805356bcbe259c0fca5c2d) --- include/GLFW/glfw3.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index bf854b07..85f2cfda 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1795,6 +1795,8 @@ GLFWAPI int glfwInit(void); * call this function, as it is called by @ref glfwInit before it returns * failure. * + * This function has no effect if GLFW is not initialized. + * * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. * * @remark This function may be called before @ref glfwInit. From e336288eebec74a1c6065cff7aab0a6c8983b78d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 28 May 2020 18:07:57 +0200 Subject: [PATCH 29/30] Fix typo in header option macro docs (cherry picked from commit fbf8aae44f4e37dc32747dacec86c255aad228c4) --- docs/build.dox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build.dox b/docs/build.dox index ed79075a..04fb4cc9 100644 --- a/docs/build.dox +++ b/docs/build.dox @@ -105,7 +105,7 @@ __GLFW_INCLUDE_ES31__ makes the GLFW header include the OpenGL ES 3.1 `GLES3/gl31.h` header instead of the regular OpenGL header. @anchor GLFW_INCLUDE_ES32 -__GLFW_INCLUDE_ES31__ makes the GLFW header include the OpenGL ES 3.2 +__GLFW_INCLUDE_ES32__ makes the GLFW header include the OpenGL ES 3.2 `GLES3/gl32.h` header instead of the regular OpenGL header. @anchor GLFW_INCLUDE_NONE From 63af05c41961c238c2f891e2c923e1b89c1271b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 28 May 2020 17:38:21 +0200 Subject: [PATCH 30/30] Clarify docs on default GL header inclusion The documentation claims that any extension loader library header included before the GLFW one will prevent the inclusion of the default OpenGL header. In reality this only worked if the loader defined the canonical desktop OpenGL __gl_h_ inclusion guard and even then relied on the OpenGL header to detect this. This is the companion to 105cf32e0b05e207d4cd5efa462887569ca2116a, which added the preprocessor logic to check for many known OpenGL and OpenGL ES inclusion guards and not even attempt to include the default header if any are present. Some clarification of the language around header inclusion has also been attempted, including making GLFW_INCLUDE_NONE more prominent. Fixes #1695. (cherry picked from commit 399c2a1fadbe6a1019c54f63d3839ef97a77d783) --- README.md | 2 ++ docs/build.dox | 41 ++++++++++++++++++++++------------------- docs/quick.dox | 47 +++++++++++++++++++++++------------------------ 3 files changed, 47 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 6300f26c..9fc19451 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,8 @@ information on what to include when reporting a bug. ## Changelog + - Bugfix: Some extension loader headers did not prevent default OpenGL header + inclusion (#1695) - [Cocoa] Use `CALayer` instead of `NSView` for `EGLNativeWindowType` (#1169) - [X11] Bugfix: IME input of CJK was broken for "C" locale (#1587,#1636) - [X11] Bugfix: Xlib errors caused by other parts of the application could be diff --git a/docs/build.dox b/docs/build.dox index 04fb4cc9..cb4d0f30 100644 --- a/docs/build.dox +++ b/docs/build.dox @@ -25,39 +25,41 @@ GLFW. #include @endcode -This header declares the GLFW API and by default also includes the OpenGL header -from your development environment. See below for how to control this. +This header defines all the constants and declares all the types and function +prototypes of the GLFW API. By default it also includes the OpenGL header from +your development environment. See [option macros](@ref build_macros) below for +how to select OpenGL ES headers and more. The GLFW header also defines any platform-specific macros needed by your OpenGL -header, so it can be included without needing any window system headers. +header, so that it can be included without needing any window system headers. -For example, under Windows you are normally required to include `windows.h` -before the OpenGL header, which would bring in the whole Win32 API. The GLFW -header duplicates the small number of macros needed. - -It does this only when needed, so if `windows.h` _is_ included, the GLFW header -does not try to redefine those symbols. The reverse is not true, i.e. -`windows.h` cannot cope if any of its symbols have already been defined. +It does this only when needed, so if window system headers are included, the +GLFW header does not try to redefine those symbols. The reverse is not true, +i.e. `windows.h` cannot cope if any Win32 symbols have already been defined. In other words: - - Do _not_ include the OpenGL headers yourself, as GLFW does this for you - - Do _not_ include `windows.h` or other platform-specific headers unless you - plan on using those APIs directly - - If you _do_ need to include such headers, do it _before_ including - the GLFW header and it will handle this + - Use the GLFW header to include OpenGL or OpenGL ES headers portably + - Do not include window system headers unless you will use those APIs directly + - If you do need such headers, include them before the GLFW header If you are using an OpenGL extension loading library such as [glad](https://github.com/Dav1dde/glad), the extension loader header should -be included _before_ the GLFW one. +be included before the GLFW one. GLFW attempts to detect any OpenGL or OpenGL +ES header or extension loader header included before it and will then disable +the inclusion of the default OpenGL header. Most extension loaders also define +macros that disable similar headers below it. @code #include #include @endcode -Alternatively the @ref GLFW_INCLUDE_NONE macro (described below) can be used to -prevent the GLFW header from including the OpenGL header. +Both of these mechanisms depend on the extension loader header defining a known +macro. If yours doesn't or you don't know which one your users will pick, the +@ref GLFW_INCLUDE_NONE macro will explicitly to prevent the GLFW header from +including the OpenGL header. This will also allow you to include the two +headers in any order. @code #define GLFW_INCLUDE_NONE @@ -113,7 +115,8 @@ __GLFW_INCLUDE_NONE__ makes the GLFW header not include any OpenGL or OpenGL ES API header. This is useful in combination with an extension loading library. If none of the above inclusion macros are defined, the standard OpenGL `GL/gl.h` -header (`OpenGL/gl.h` on macOS) is included. +header (`OpenGL/gl.h` on macOS) is included, unless GLFW detects the inclusion +guards of any OpenGL, OpenGL ES or extension loader header it knows about. The following macros control the inclusion of additional API headers. Any number of these may be defined simultaneously, and/or together with one of the diff --git a/docs/quick.dox b/docs/quick.dox index 2c6fcb9d..3645fc05 100644 --- a/docs/quick.dox +++ b/docs/quick.dox @@ -18,43 +18,42 @@ behave differently in GLFW 3. @subsection quick_include Including the GLFW header -In the source files of your application where you use OpenGL or GLFW, you need -to include the GLFW 3 header file. +In the source files of your application where you use GLFW, you need to include +its header file. @code #include @endcode -This defines all the constants, types and function prototypes of the GLFW API. -It also includes the OpenGL header from your development environment and -defines all the constants and types necessary for it to work on your platform -without including any platform-specific headers. +This header provides all the constants, types and function prototypes of the +GLFW API. -In other words: +By default it also includes the OpenGL header from your development environment. +On some platforms this header only supports older versions of OpenGL. The most +extreme case is Windows, where it typically only supports OpenGL 1.2. -- Do _not_ include the OpenGL header yourself, as GLFW does this for you in - a platform-independent way -- Do _not_ include `windows.h` or other platform-specific headers unless - you plan on using those APIs yourself -- If you _do_ need to include such headers, include them _before_ the GLFW - header and it will detect this - -On some platforms supported by GLFW the OpenGL header and link library only -expose older versions of OpenGL. The most extreme case is Windows, which only -exposes OpenGL 1.2. The easiest way to work around this is to use an -[extension loader library](@ref context_glext_auto). - -If you are using such a library then you should include its header _before_ the -GLFW header. This lets it replace the OpenGL header included by GLFW without -conflicts. This example uses -[glad2](https://github.com/Dav1dde/glad), but the same rule applies to all such -libraries. +Most programs will instead use an +[extension loader library](@ref context_glext_auto) and include its header. +This example uses files generated by [glad](https://gen.glad.sh/). The GLFW +header can detect most such headers if they are included first and will then not +include the one from your development environment. @code #include #include @endcode +To make sure there will be no header conflicts, you can define @ref +GLFW_INCLUDE_NONE before the GLFW header to explicitly disable inclusion of the +development environment header. This also allows the two headers to be included +in any order. + +@code +#define GLFW_INCLUDE_NONE +#include +#include +@endcode + @subsection quick_init_term Initializing and terminating GLFW