From 727db55c3a81951833c2adcd4d06d926185b4099 Mon Sep 17 00:00:00 2001 From: Ioannis Tsakpinis Date: Sat, 23 Oct 2021 16:17:33 +0300 Subject: [PATCH 01/71] Fix context API checks in native access functions --- src/egl_context.c | 4 ++-- src/glx_context.c | 4 ++-- src/nsgl_context.m | 2 +- src/osmesa_context.c | 6 +++--- src/wgl_context.c | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/egl_context.c b/src/egl_context.c index 593a153c..03c72d04 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -821,7 +821,7 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle) _GLFWwindow* window = (_GLFWwindow*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT); - if (window->context.client != GLFW_EGL_CONTEXT_API) + if (window->context.source != GLFW_EGL_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); return EGL_NO_CONTEXT; @@ -835,7 +835,7 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle) _GLFWwindow* window = (_GLFWwindow*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE); - if (window->context.client != GLFW_EGL_CONTEXT_API) + if (window->context.source != GLFW_EGL_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); return EGL_NO_SURFACE; diff --git a/src/glx_context.c b/src/glx_context.c index 4a92353c..bbe261a0 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -680,7 +680,7 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle) return NULL; } - if (window->context.client != GLFW_NATIVE_CONTEXT_API) + if (window->context.source != GLFW_NATIVE_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); return NULL; @@ -700,7 +700,7 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle) return None; } - if (window->context.client != GLFW_NATIVE_CONTEXT_API) + if (window->context.source != GLFW_NATIVE_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); return None; diff --git a/src/nsgl_context.m b/src/nsgl_context.m index 694937c6..f85ef67b 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -365,7 +365,7 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle) return nil; } - if (window->context.client != GLFW_NATIVE_CONTEXT_API) + if (window->context.source != GLFW_NATIVE_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); return nil; diff --git a/src/osmesa_context.c b/src/osmesa_context.c index cf742f89..1b28c517 100644 --- a/src/osmesa_context.c +++ b/src/osmesa_context.c @@ -302,7 +302,7 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width, _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); - if (window->context.client != GLFW_OSMESA_CONTEXT_API) + if (window->context.source != GLFW_OSMESA_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); return GLFW_FALSE; @@ -341,7 +341,7 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle, _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); - if (window->context.client != GLFW_OSMESA_CONTEXT_API) + if (window->context.source != GLFW_OSMESA_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); return GLFW_FALSE; @@ -373,7 +373,7 @@ GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle) _GLFWwindow* window = (_GLFWwindow*) handle; _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - if (window->context.client != GLFW_OSMESA_CONTEXT_API) + if (window->context.source != GLFW_OSMESA_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); return NULL; diff --git a/src/wgl_context.c b/src/wgl_context.c index 774f45bd..952d70de 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -783,7 +783,7 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle) return NULL; } - if (window->context.client != GLFW_NATIVE_CONTEXT_API) + if (window->context.source != GLFW_NATIVE_CONTEXT_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); return NULL; From 38dd51552429066e56ba7e69bff5b78d70f89f5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 29 Aug 2021 21:53:44 +0200 Subject: [PATCH 02/71] Use Win32 instead of Windows in Doxygen headings This was especially bad in the window guide, where the TOC ended up having "Window related hints" and "Windows specific window hints" close to one another. This commit only fixes headings. There are likely issues in the actual text as well. --- docs/compile.dox | 2 +- docs/window.dox | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/compile.dox b/docs/compile.dox index 8f99472e..20b33a91 100644 --- a/docs/compile.dox +++ b/docs/compile.dox @@ -278,7 +278,7 @@ __GLFW_VULKAN_STATIC__ determines whether to use the Vulkan loader linked directly with the application. This is disabled by default. -@subsection compile_options_win32 Windows specific CMake options +@subsection compile_options_win32 Win32 specific CMake options @anchor GLFW_BUILD_WIN32 __GLFW_BUILD_WIN32__ determines whether to include support for Win32 when compiling the diff --git a/docs/window.dox b/docs/window.dox index 5e482431..32271e3a 100644 --- a/docs/window.dox +++ b/docs/window.dox @@ -447,7 +447,7 @@ The no error mode for OpenGL and OpenGL ES is described in detail by the extension. -@subsubsection window_hints_win32 Windows specific window hints +@subsubsection window_hints_win32 Win32 specific hints @anchor GLFW_WIN32_KEYBOARD_MENU_hint __GLFW_WIN32_KEYBOARD_MENU__ specifies whether to allow access to the window @@ -455,7 +455,7 @@ menu via the Alt+Space and Alt-and-then-Space keyboard shortcuts. This is ignored on other platforms. -@subsubsection window_hints_osx macOS specific window hints +@subsubsection window_hints_osx macOS specific hints @anchor GLFW_COCOA_RETINA_FRAMEBUFFER_hint __GLFW_COCOA_RETINA_FRAMEBUFFER__ specifies whether to use full resolution From 6efaaec9ce9f90510ef6e6d5155abb619138344b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 29 Aug 2021 21:51:00 +0200 Subject: [PATCH 03/71] Improve headings and TOC layout in Doxygen docs This more or less restores the original custom layout where the TOC is on the right side, with a CSS workaround added for portrait orientation. The indentation of sub-lists in the TOC has been decreased. The sizes of HTML headings and the "h0" div generated for each Doxygen page have been adjusted to look better together now that they can meet. A few headings have been shortened to fit better in the narrower TOC. --- docs/compile.dox | 12 ++++++------ docs/extra.css | 3 ++- docs/extra.css.map | 8 +++++++- docs/extra.scss | 27 +++++++++++++++++++++++---- docs/vulkan.dox | 2 +- 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/docs/compile.dox b/docs/compile.dox index 20b33a91..63479516 100644 --- a/docs/compile.dox +++ b/docs/compile.dox @@ -10,8 +10,8 @@ build applications that use GLFW, see @ref build_guide. @section compile_cmake Using CMake -@note GLFW behaves like most other libraries that use CMake so this guide mostly -describes the basic configure/generate/compile sequence. If you are already +GLFW behaves like most other libraries that use CMake so this guide mostly +describes the standard configure, generate and compile sequence. If you are already familiar with this from other projects, you may want to focus on the @ref compile_deps and @ref compile_options sections for GLFW-specific information. @@ -40,7 +40,7 @@ all necessary dependencies for compiling GLFW, but on Unix-like systems like Linux and FreeBSD you will need a few extra packages. -@subsubsection compile_deps_x11 Dependencies for X11 on Unix-like systems +@subsubsection compile_deps_x11 Dependencies for X11 To compile GLFW for X11, you need to have the X11 development packages installed. They are not needed to build or run programs that use GLFW. @@ -74,7 +74,7 @@ install the headers and other development related files for all of X11. Once you have the required dependencies, move on to @ref compile_generate. -@subsubsection compile_deps_wayland Dependencies for Wayland and X11 on Unix-like systems +@subsubsection compile_deps_wayland Dependencies for Wayland and X11 To compile GLFW for both Wayland and X11, you need to have the X11, Wayland and xkbcommon development packages installed. They are not needed to build or run programs that use @@ -131,7 +131,7 @@ A common pattern when building a single configuration is to have a build directory named `build` in the root of the source tree. -@subsubsection compile_generate_gui Generating files with the CMake GUI +@subsubsection compile_generate_gui Generating with the CMake GUI Start the CMake GUI and set the paths to the source and build directories described above. Then press _Configure_ and _Generate_. @@ -148,7 +148,7 @@ Once you have generated the project files or makefiles for your chosen development environment, move on to @ref compile_compile. -@subsubsection compile_generate_cli Generating files with the CMake command-line tool +@subsubsection compile_generate_cli Generating with command-line CMake To make a build directory, pass the source and build directories to the `cmake` command. These can be relative or absolute paths. The build directory is diff --git a/docs/extra.css b/docs/extra.css index 05c1938c..1a287343 100644 --- a/docs/extra.css +++ b/docs/extra.css @@ -1 +1,2 @@ -.sm-dox,.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted,.sm-dox ul a:hover{background:none;text-shadow:none}.sm-dox a span.sub-arrow{border-color:#f2f2f2 transparent transparent transparent}.sm-dox a span.sub-arrow:active,.sm-dox a span.sub-arrow:focus,.sm-dox a span.sub-arrow:hover,.sm-dox a:hover span.sub-arrow{border-color:#f60 transparent transparent transparent}.sm-dox ul a span.sub-arrow:active,.sm-dox ul a span.sub-arrow:focus,.sm-dox ul a span.sub-arrow:hover,.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent #f60}.sm-dox ul a:hover{background:#666;text-shadow:none}.sm-dox ul.sm-nowrap a{color:#4d4d4d;text-shadow:none}#main-nav,#main-menu,#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li,.memdoc,dl.reflist dd,div.toc li,.ah,span.lineno,span.lineno a,span.lineno a:hover,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,.doxtable code,.markdownTable code{background:none}#titlearea,.footer,.contents,div.header,.memdoc,table.doxtable td,table.doxtable th,table.markdownTable td,table.markdownTable th,hr,.memSeparator{border:none}#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li,.reflist dt a.el,.levels span,.directory .levels span{text-shadow:none}.memdoc,dl.reflist dd{box-shadow:none}div.headertitle,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,table.doxtable code,table.markdownTable code{padding:0}#nav-path,.directory .levels,span.lineno{display:none}html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),tr.markdownTableBody:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code,.markdownTableRowEven{background:#f2f2f2}body{color:#4d4d4d}h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em{color:#1a1a1a;border-bottom:none}h1{padding-top:.5em;font-size:180%}h2{padding-top:.5em;margin-bottom:0;font-size:140%}h3{padding-top:.5em;margin-bottom:0;font-size:110%}.glfwheader{font-size:16px;min-height:64px;max-width:920px;padding:0 32px;margin:0 auto;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:flex-start;align-items:center;align-content:stretch}#glfwhome{line-height:64px;padding-right:48px;color:#666;font-size:2.5em;background:url("https://www.glfw.org/css/arrow.png") no-repeat right}.glfwnavbar{list-style-type:none;margin:0 0 0 auto;float:right}#glfwhome,.glfwnavbar li{float:left}.glfwnavbar a,.glfwnavbar a:visited{line-height:64px;margin-left:2em;display:block;color:#666}.glfwnavbar{padding-left:0}#glfwhome,.glfwnavbar a,.glfwnavbar a:visited{transition:.35s ease}#titlearea,.footer{color:#666}address.footer{text-align:center;padding:2em;margin-top:3em}#top{background:#666}#main-nav{max-width:960px;margin:0 auto;font-size:13px}#main-menu{max-width:920px;margin:0 auto;font-size:13px}.memtitle{display:none}.memproto,.memname{font-weight:bold;text-shadow:none}#main-menu{min-height:36px;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:flex-start;align-items:center;align-content:stretch}#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li{color:#f2f2f2}#main-menu li ul.sm-nowrap li a{color:#4d4d4d}#main-menu li ul.sm-nowrap li a:hover{color:#f60}#main-menu>li:last-child{margin:0 0 0 auto}.contents{min-height:590px}div.contents,div.header{max-width:920px;margin:0 auto;padding:0 32px;background:#fff none}table.doxtable th,table.markdownTable th,dl.reflist dt{background:linear-gradient(to bottom, #ffa733 0%, #ff6600 100%);box-shadow:inset 0 0 32px #f60;text-shadow:0 -1px 1px #b34700;text-align:left;color:#fff}dl.reflist dt a.el{color:#f60;padding:.2em;border-radius:4px;background-color:#ffe0cc}div.toc{float:none;width:auto}div.toc h3{font-size:1.17em}div.toc ul{padding-left:1.5em}div.toc li{font-size:1em;padding-left:0;list-style-type:disc}div.toc,.memproto,div.qindex,div.ah{background:linear-gradient(to bottom, #f2f2f2 0%, #e6e6e6 100%);box-shadow:inset 0 0 32px #e6e6e6;text-shadow:0 1px 1px #fff;color:#1a1a1a;border:2px solid #e6e6e6;border-radius:4px}.paramname{color:#803300}dl.reflist dt{border:2px solid #f60;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom:none}dl.reflist dd{border:2px solid #f60;border-bottom-right-radius:4px;border-bottom-left-radius:4px;border-top:none}table.doxtable,table.markdownTable{border-collapse:inherit;border-spacing:0;border:2px solid #f60;border-radius:4px}a,a:hover,a:visited,a:visited:hover,.contents a:visited,.el,a.el:visited,#glfwhome:hover,#main-menu a:hover,span.lineno a:hover{color:#f60;text-decoration:none}div.directory{border-collapse:inherit;border-spacing:0;border:2px solid #f60;border-radius:4px}hr,.memSeparator{height:2px;background:linear-gradient(to right, #f2f2f2 0%, #d9d9d9 50%, #f2f2f2 100%)}dl.note,dl.pre,dl.post,dl.invariant{background:linear-gradient(to bottom, #ddfad1 0%, #cbf7ba 100%);box-shadow:inset 0 0 32px #baf5a3;color:#1e5309;border:2px solid #afe699}dl.warning,dl.attention{background:linear-gradient(to bottom, #fae8d1 0%, #f7ddba 100%);box-shadow:inset 0 0 32px #f5d1a3;color:#533309;border:2px solid #e6c499}dl.deprecated,dl.bug{background:linear-gradient(to bottom, #fad1e3 0%, #f7bad6 100%);box-shadow:inset 0 0 32px #f5a3c8;color:#53092a;border:2px solid #e699bb}dl.todo,dl.test{background:linear-gradient(to bottom, #d1ecfa 0%, #bae3f7 100%);box-shadow:inset 0 0 32px #a3daf5;color:#093a53;border:2px solid #99cce6}dl.note,dl.pre,dl.post,dl.invariant,dl.warning,dl.attention,dl.deprecated,dl.bug,dl.todo,dl.test{border-radius:4px;padding:1em;text-shadow:0 1px 1px #fff;margin:1em 0}.note a,.pre a,.post a,.invariant a,.warning a,.attention a,.deprecated a,.bug a,.todo a,.test a,.note a:visited,.pre a:visited,.post a:visited,.invariant a:visited,.warning a:visited,.attention a:visited,.deprecated a:visited,.bug a:visited,.todo a:visited,.test a:visited{color:inherit}div.line{line-height:inherit}div.fragment,pre.fragment{background:#f2f2f2;border-radius:4px;border:none;padding:1em;overflow:auto;border-left:4px solid #ccc;margin:1em 0}.lineno a,.lineno a:visited,.line,pre.fragment{color:#4d4d4d}span.preprocessor,span.comment{color:#007899}a.code,a.code:visited{color:#e64500}span.keyword,span.keywordtype,span.keywordflow{color:#404040;font-weight:bold}span.stringliteral{color:#360099}code{padding:.1em;border-radius:4px}/*# sourceMappingURL=extra.css.map */ +.sm-dox,.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted,.sm-dox ul a:hover{background:none;text-shadow:none}.sm-dox a span.sub-arrow{border-color:#f2f2f2 transparent transparent transparent}.sm-dox a span.sub-arrow:active,.sm-dox a span.sub-arrow:focus,.sm-dox a span.sub-arrow:hover,.sm-dox a:hover span.sub-arrow{border-color:#f60 transparent transparent transparent}.sm-dox ul a span.sub-arrow:active,.sm-dox ul a span.sub-arrow:focus,.sm-dox ul a span.sub-arrow:hover,.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent #f60}.sm-dox ul a:hover{background:#666;text-shadow:none}.sm-dox ul.sm-nowrap a{color:#4d4d4d;text-shadow:none}#main-nav,#main-menu,#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li,.memdoc,dl.reflist dd,div.toc li,.ah,span.lineno,span.lineno a,span.lineno a:hover,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,.doxtable code,.markdownTable code{background:none}#titlearea,.footer,.contents,div.header,.memdoc,table.doxtable td,table.doxtable th,table.markdownTable td,table.markdownTable th,hr,.memSeparator{border:none}#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li,.reflist dt a.el,.levels span,.directory .levels span{text-shadow:none}.memdoc,dl.reflist dd{box-shadow:none}div.headertitle,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,table.doxtable code,table.markdownTable code{padding:0}#nav-path,.directory .levels,span.lineno{display:none}html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),tr.markdownTableBody:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code,.markdownTableRowEven{background:#f2f2f2}body{color:#4d4d4d}div.title{font-size:170%;margin:1em 0 0.5em 0}h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em{color:#1a1a1a;border-bottom:none}h1{padding-top:0.5em;font-size:150%}h2{padding-top:0.5em;margin-bottom:0;font-size:130%}h3{padding-top:0.5em;margin-bottom:0;font-size:110%}.glfwheader{font-size:16px;min-height:64px;max-width:920px;padding:0 32px;margin:0 auto;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:flex-start;align-items:center;align-content:stretch}#glfwhome{line-height:64px;padding-right:48px;color:#666;font-size:2.5em;background:url("https://www.glfw.org/css/arrow.png") no-repeat right}.glfwnavbar{list-style-type:none;margin:0 0 0 auto;float:right}#glfwhome,.glfwnavbar li{float:left}.glfwnavbar a,.glfwnavbar a:visited{line-height:64px;margin-left:2em;display:block;color:#666}.glfwnavbar{padding-left:0}#glfwhome,.glfwnavbar a,.glfwnavbar a:visited{transition:.35s ease}#titlearea,.footer{color:#666}address.footer{text-align:center;padding:2em;margin-top:3em}#top{background:#666}#main-nav{max-width:960px;margin:0 auto;font-size:13px}#main-menu{max-width:920px;margin:0 auto;font-size:13px}.memtitle{display:none}.memproto,.memname{font-weight:bold;text-shadow:none}#main-menu{min-height:36px;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:flex-start;align-items:center;align-content:stretch}#main-menu a,#main-menu a:visited,#main-menu a:hover,#main-menu li{color:#f2f2f2}#main-menu li ul.sm-nowrap li a{color:#4d4d4d}#main-menu li ul.sm-nowrap li a:hover{color:#f60}#main-menu>li:last-child{margin:0 0 0 auto}.contents{min-height:590px}div.contents,div.header{max-width:920px;margin:0 auto;padding:0 32px;background:#fff none}table.doxtable th,table.markdownTable th,dl.reflist dt{background:linear-gradient(to bottom, #ffa733 0%, #f60 100%);box-shadow:inset 0 0 32px #f60;text-shadow:0 -1px 1px #b34700;text-align:left;color:#fff}dl.reflist dt a.el{color:#f60;padding:.2em;border-radius:4px;background-color:#ffe0cc}div.toc{float:right;width:35%}@media screen and (max-width: 600px){div.toc{float:none;width:inherit;margin:0}}div.toc h3{font-size:1.17em}div.toc ul{padding-left:1.5em}div.toc li{font-size:1em;padding-left:0;list-style-type:disc}div.toc li.level2,div.toc li.level3{margin-left:0.5em}div.toc,.memproto,div.qindex,div.ah{background:linear-gradient(to bottom, #f2f2f2 0%, #e6e6e6 100%);box-shadow:inset 0 0 32px #e6e6e6;text-shadow:0 1px 1px #fff;color:#1a1a1a;border:2px solid #e6e6e6;border-radius:4px}.paramname{color:#803300}dl.reflist dt{border:2px solid #f60;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom:none}dl.reflist dd{border:2px solid #f60;border-bottom-right-radius:4px;border-bottom-left-radius:4px;border-top:none}table.doxtable,table.markdownTable{border-collapse:inherit;border-spacing:0;border:2px solid #f60;border-radius:4px}a,a:hover,a:visited,a:visited:hover,.contents a:visited,.el,a.el:visited,#glfwhome:hover,#main-menu a:hover,span.lineno a:hover{color:#f60;text-decoration:none}div.directory{border-collapse:inherit;border-spacing:0;border:2px solid #f60;border-radius:4px}hr,.memSeparator{height:2px;background:linear-gradient(to right, #f2f2f2 0%, #d9d9d9 50%, #f2f2f2 100%)}dl.note,dl.pre,dl.post,dl.invariant{background:linear-gradient(to bottom, #ddfad1 0%, #cbf7ba 100%);box-shadow:inset 0 0 32px #baf5a3;color:#1e5309;border:2px solid #afe699}dl.warning,dl.attention{background:linear-gradient(to bottom, #fae8d1 0%, #f7ddba 100%);box-shadow:inset 0 0 32px #f5d1a3;color:#533309;border:2px solid #e6c499}dl.deprecated,dl.bug{background:linear-gradient(to bottom, #fad1e3 0%, #f7bad6 100%);box-shadow:inset 0 0 32px #f5a3c8;color:#53092a;border:2px solid #e699bb}dl.todo,dl.test{background:linear-gradient(to bottom, #d1ecfa 0%, #bae3f7 100%);box-shadow:inset 0 0 32px #a3daf5;color:#093a53;border:2px solid #99cce6}dl.note,dl.pre,dl.post,dl.invariant,dl.warning,dl.attention,dl.deprecated,dl.bug,dl.todo,dl.test{border-radius:4px;padding:1em;text-shadow:0 1px 1px #fff;margin:1em 0}.note a,.pre a,.post a,.invariant a,.warning a,.attention a,.deprecated a,.bug a,.todo a,.test a,.note a:visited,.pre a:visited,.post a:visited,.invariant a:visited,.warning a:visited,.attention a:visited,.deprecated a:visited,.bug a:visited,.todo a:visited,.test a:visited{color:inherit}div.line{line-height:inherit}div.fragment,pre.fragment{background:#f2f2f2;border-radius:4px;border:none;padding:1em;overflow:auto;border-left:4px solid #ccc;margin:1em 0}.lineno a,.lineno a:visited,.line,pre.fragment{color:#4d4d4d}span.preprocessor,span.comment{color:#007899}a.code,a.code:visited{color:#e64500}span.keyword,span.keywordtype,span.keywordflow{color:#404040;font-weight:bold}span.stringliteral{color:#360099}code{padding:.1em;border-radius:4px} +/*# sourceMappingURL=extra.css.map */ diff --git a/docs/extra.css.map b/docs/extra.css.map index 7d10c5e2..4d9333c2 100644 --- a/docs/extra.css.map +++ b/docs/extra.css.map @@ -1 +1,7 @@ -{"version":3,"sourceRoot":"","sources":["extra.scss"],"names":[],"mappings":"AA8EA,4GACI,gBACA,iBAGJ,yBACC,yDAGD,6HACC,sDAGD,yIACC,sDAGD,mBACI,WA9EuB,KA+EvB,iBAGJ,uBACC,MAzFoB,QA0FjB,iBAGJ,6UACC,gBAGD,mJACC,YAGD,yHACC,iBAGD,sBACC,gBAGD,4LACC,UAGD,yCACC,aAGD,kMACC,WAnHgC,QAsHjC,KACC,MA1HoB,QA6HrB,sDACC,MA/Ge,QAgHf,mBAGD,GACE,iBACA,eAGF,GACE,iBACA,gBACA,eAGF,GACE,iBACA,gBACA,eAGF,YACC,eACA,gBACA,gBACA,eACA,cAEA,aACA,mBACA,eACA,2BACA,mBACA,sBAGD,UACC,iBACA,mBACA,MA/J0B,KAgK1B,gBACA,qEAGD,YACC,qBACA,kBACA,YAGD,yBACC,WAGD,oCACC,iBACA,gBACA,cACA,MAlL0B,KAqL3B,YACC,eAGD,8CACC,qBAGD,mBACC,MA9L0B,KAiM3B,eACC,kBACA,YACA,eAGD,KACC,WAxM0B,KA2M3B,UACC,gBACA,cACA,eAGD,WACC,gBACA,cACA,eAGD,UACI,aAGJ,mBACI,iBACA,iBAGJ,WACC,gBACA,aACA,mBACA,eACA,2BACA,mBACA,sBAGD,mEACC,MA9OgC,QAiPjC,gCACC,MArPoB,QAwPrB,sCACC,MAjOoB,KAoOrB,yBACC,kBAGD,UACC,iBAGD,wBACC,gBACA,cACA,eACA,qBAGD,uDACC,gEACA,+BACA,+BACA,gBACA,MArPgB,KAwPjB,mBACC,MA5PoB,KA6PpB,aACA,kBACA,yBAGD,QACC,WACA,WAGD,WACC,iBAGD,WACC,mBAGD,WACC,cACA,eACA,qBAGD,oCACC,gEACA,kCACA,2BACA,MAlSe,QAmSf,yBACA,kBAGD,WACC,MA3QuB,QA8QxB,cACC,sBACA,2BACA,4BACA,mBAGD,cACC,sBACA,+BACA,8BACA,gBAGD,mCACC,wBACA,iBACA,sBACA,kBAGD,gIACC,MAxToB,KAyTpB,qBAGD,cACC,wBACA,iBACA,sBACA,kBAGD,iBACC,WACA,4EAGD,oCApSC,gEACA,kCACA,cACA,yBAqSD,wBAxSC,gEACA,kCACA,cACA,yBAySD,qBA5SC,gEACA,kCACA,cACA,yBA6SD,gBAhTC,gEACA,kCACA,cACA,yBAiTD,iGACC,kBACA,YACA,2BACA,aAGD,kRACC,cAGD,SACC,oBAGD,0BACC,mBACA,kBACA,YACA,YACA,cACA,2BACA,aAGD,+CACC,MA1YoB,QA6YrB,+BACC,cAGD,sBACC,cAGD,+CACC,cACA,iBAGD,mBACC,cAGD,KACC,aACA","file":"extra.css"} \ No newline at end of file +{ +"version": 3, +"mappings": "AA8EA,2GAA4G,CAC3G,UAAU,CAAC,IAAI,CACf,WAAW,CAAC,IAAI,CAGjB,wBAAyB,CACxB,YAAY,CAAC,2CAAsD,CAGpE,4HAA6H,CAC5H,YAAY,CAAC,wCAAuD,CAGrE,wIAAyI,CACxI,YAAY,CAAC,wCAAuD,CAGrE,kBAAmB,CAClB,UAAU,CA9EgB,IAAa,CA+EvC,WAAW,CAAC,IAAI,CAGjB,sBAAuB,CACtB,KAAK,CAzFe,OAAa,CA0FjC,WAAW,CAAC,IAAI,CAGjB,4UAA6U,CAC5U,UAAU,CAAC,IAAI,CAGhB,kJAAmJ,CAClJ,MAAM,CAAC,IAAI,CAGZ,wHAAyH,CACxH,WAAW,CAAC,IAAI,CAGjB,qBAAsB,CACrB,UAAU,CAAC,IAAI,CAGhB,2LAA4L,CAC3L,OAAO,CAAC,CAAC,CAGV,wCAAyC,CACxC,OAAO,CAAC,IAAI,CAGb,iMAAkM,CACjM,UAAU,CApGW,OAA+B,CAuGrD,IAAK,CACJ,KAAK,CA1He,OAAa,CA6HlC,SAAU,CACN,SAAS,CAAE,IAAI,CACf,MAAM,CAAE,aAAa,CAGzB,qDAAsD,CACrD,KAAK,CApHU,OAAa,CAqH5B,aAAa,CAAC,IAAI,CAGnB,EAAG,CACF,WAAW,CAAC,KAAK,CACjB,SAAS,CAAC,IAAI,CAGf,EAAG,CACF,WAAW,CAAC,KAAK,CACjB,aAAa,CAAC,CAAC,CACf,SAAS,CAAC,IAAI,CAGf,EAAG,CACF,WAAW,CAAC,KAAK,CACjB,aAAa,CAAC,CAAC,CACf,SAAS,CAAC,IAAI,CAGf,WAAY,CACX,SAAS,CAAC,IAAI,CACd,UAAU,CAAC,IAAI,CACf,SAAS,CAAC,KAAK,CACf,OAAO,CAAC,MAAM,CACd,MAAM,CAAC,MAAM,CAEb,OAAO,CAAE,IAAI,CACb,cAAc,CAAE,GAAG,CACnB,SAAS,CAAE,IAAI,CACf,eAAe,CAAE,UAAU,CAC3B,WAAW,CAAE,MAAM,CACnB,aAAa,CAAE,OAAO,CAGvB,SAAU,CACT,WAAW,CAAC,IAAI,CAChB,aAAa,CAAC,IAAI,CAClB,KAAK,CApKqB,IAAa,CAqKvC,SAAS,CAAC,KAAK,CACf,UAAU,CAAC,yDAAyD,CAGrE,WAAY,CACX,eAAe,CAAC,IAAI,CACpB,MAAM,CAAC,UAAU,CACjB,KAAK,CAAC,KAAK,CAGZ,wBAAyB,CACxB,KAAK,CAAC,IAAI,CAGX,mCAAoC,CACnC,WAAW,CAAC,IAAI,CAChB,WAAW,CAAC,GAAG,CACf,OAAO,CAAC,KAAK,CACb,KAAK,CAvLqB,IAAa,CA0LxC,WAAY,CACX,YAAY,CAAE,CAAC,CAGhB,6CAA8C,CAC7C,UAAU,CAAC,SAAS,CAGrB,kBAAmB,CAClB,KAAK,CAnMqB,IAAa,CAsMxC,cAAe,CACd,UAAU,CAAC,MAAM,CACjB,OAAO,CAAC,GAAG,CACX,UAAU,CAAC,GAAG,CAGf,IAAK,CACJ,UAAU,CA7MgB,IAAa,CAgNxC,SAAU,CACT,SAAS,CAAC,KAAK,CACf,MAAM,CAAC,MAAM,CACb,SAAS,CAAC,IAAI,CAGf,UAAW,CACV,SAAS,CAAC,KAAK,CACf,MAAM,CAAC,MAAM,CACb,SAAS,CAAC,IAAI,CAGf,SAAU,CACT,OAAO,CAAC,IAAI,CAGb,kBAAmB,CAClB,WAAW,CAAC,IAAI,CAChB,WAAW,CAAC,IAAI,CAGjB,UAAW,CACV,UAAU,CAAC,IAAI,CACf,OAAO,CAAE,IAAI,CACb,cAAc,CAAE,GAAG,CACnB,SAAS,CAAE,IAAI,CACf,eAAe,CAAE,UAAU,CAC3B,WAAW,CAAE,MAAM,CACnB,aAAa,CAAE,OAAO,CAGvB,kEAAmE,CAClE,KAAK,CApOgB,OAA+B,CAuOrD,+BAAgC,CAC/B,KAAK,CA1Pe,OAAa,CA6PlC,qCAAsC,CACrC,KAAK,CA1NoB,IAAsB,CA6NhD,wBAA2B,CAC1B,MAAM,CAAE,UAAU,CAGnB,SAAU,CACT,UAAU,CAAC,KAAK,CAGjB,uBAAwB,CACvB,SAAS,CAAC,KAAK,CACf,MAAM,CAAC,MAAM,CACb,OAAO,CAAC,MAAM,CACd,UAAU,CAAC,SAA8B,CAG1C,sDAAuD,CACtD,UAAU,CAAC,iDAAoF,CAC/F,UAAU,CAAC,mBAAuC,CAClD,WAAW,CAAC,kBAAgD,CAC5D,UAAU,CAAC,IAAI,CACf,KAAK,CAlPa,IAAe,CAqPlC,kBAAmB,CAClB,KAAK,CArPoB,IAAsB,CAsP/C,OAAO,CAAC,IAAI,CACZ,aAAa,CAAC,GAAG,CACjB,gBAAgB,CAAC,OAAiC,CAGnD,OAAQ,CACP,KAAK,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAGV,oCAAoC,CACnC,OAAQ,CACP,KAAK,CAAC,IAAI,CACV,KAAK,CAAC,OAAO,CACb,MAAM,CAAC,CAAC,EAIV,UAAW,CACV,SAAS,CAAC,MAAM,CAGjB,UAAW,CACV,YAAY,CAAC,KAAK,CAGnB,UAAW,CACV,SAAS,CAAC,GAAG,CACb,YAAY,CAAC,CAAC,CACd,eAAe,CAAC,IAAI,CAIjB,mCAAqB,CACjB,WAAW,CAAC,KAAK,CAIzB,mCAAoC,CACnC,UAAU,CAAC,oDAAgF,CAC3F,UAAU,CAAC,sBAAqC,CAChD,WAAW,CAAC,cAA8C,CAC1D,KAAK,CArTU,OAAa,CAsT5B,MAAM,CAAC,iBAAgC,CACvC,aAAa,CAAC,GAAG,CAGlB,UAAW,CACV,KAAK,CA9RkB,OAAgC,CAiSxD,aAAc,CACb,MAAM,CAAC,cAA+B,CACtC,sBAAsB,CAAC,GAAG,CAC1B,uBAAuB,CAAC,GAAG,CAC3B,aAAa,CAAC,IAAI,CAGnB,aAAc,CACb,MAAM,CAAC,cAA+B,CACtC,0BAA0B,CAAC,GAAG,CAC9B,yBAAyB,CAAC,GAAG,CAC7B,UAAU,CAAC,IAAI,CAGhB,kCAAmC,CAClC,eAAe,CAAC,OAAO,CACvB,cAAc,CAAC,CAAC,CAChB,MAAM,CAAC,cAA+B,CACtC,aAAa,CAAC,GAAG,CAGlB,+HAAgI,CAC/H,KAAK,CA/ToB,IAAsB,CAgU/C,eAAe,CAAC,IAAI,CAGrB,aAAc,CACb,eAAe,CAAC,OAAO,CACvB,cAAc,CAAC,CAAC,CAChB,MAAM,CAAC,cAA+B,CACtC,aAAa,CAAC,GAAG,CAGlB,gBAAiB,CAChB,MAAM,CAAC,GAAG,CACV,UAAU,CAAC,gEAAiH,CAG7H,mCAAoC,CAvTnC,UAAU,CAAC,oDAAuE,CAClF,UAAU,CAAC,sBAAsC,CACjD,KAAK,CAAC,OAAwB,CAC9B,MAAM,CAAC,iBAAmD,CAwT3D,uBAAwB,CA3TvB,UAAU,CAAC,oDAAuE,CAClF,UAAU,CAAC,sBAAsC,CACjD,KAAK,CAAC,OAAwB,CAC9B,MAAM,CAAC,iBAAmD,CA4T3D,oBAAqB,CA/TpB,UAAU,CAAC,oDAAuE,CAClF,UAAU,CAAC,sBAAsC,CACjD,KAAK,CAAC,OAAwB,CAC9B,MAAM,CAAC,iBAAmD,CAgU3D,eAAgB,CAnUf,UAAU,CAAC,oDAAuE,CAClF,UAAU,CAAC,sBAAsC,CACjD,KAAK,CAAC,OAAwB,CAC9B,MAAM,CAAC,iBAAmD,CAoU3D,gGAAiG,CAChG,aAAa,CAAC,GAAG,CACjB,OAAO,CAAC,GAAG,CACX,WAAW,CAAC,cAAwB,CACpC,MAAM,CAAC,KAAK,CAGb,iRAAkR,CACjR,KAAK,CAAC,OAAO,CAGd,QAAS,CACR,WAAW,CAAC,OAAO,CAGpB,yBAA0B,CACzB,UAAU,CAAC,OAAa,CACxB,aAAa,CAAC,GAAG,CACjB,MAAM,CAAC,IAAI,CACX,OAAO,CAAC,GAAG,CACX,QAAQ,CAAC,IAAI,CACb,WAAW,CAAC,cAAuB,CACnC,MAAM,CAAC,KAAK,CAGb,8CAA+C,CAC9C,KAAK,CA7Ze,OAAa,CAgalC,8BAA+B,CAC9B,KAAK,CAAC,OAAiB,CAGxB,qBAAsB,CACrB,KAAK,CAAC,OAAgB,CAGvB,8CAA+C,CAC9C,KAAK,CAAC,OAA+B,CACrC,WAAW,CAAC,IAAI,CAGjB,kBAAmB,CAClB,KAAK,CAAC,OAAiB,CAGxB,IAAK,CACJ,OAAO,CAAC,IAAI,CACZ,aAAa,CAAC,GAAG", +"sources": ["extra.scss"], +"names": [], +"file": "extra.css" +} diff --git a/docs/extra.scss b/docs/extra.scss index 6c5f3c25..43fe9831 100644 --- a/docs/extra.scss +++ b/docs/extra.scss @@ -135,6 +135,11 @@ body { color:$default-text-color; } +div.title { + font-size: 170%; + margin: 1em 0 0.5em 0; +} + h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em { color:$heading-color; border-bottom:none; @@ -142,13 +147,13 @@ h1,h2,h2.groupheader,h3,div.toc h3,h4,h5,h6,strong,em { h1 { padding-top:0.5em; - font-size:180%; + font-size:150%; } h2 { padding-top:0.5em; margin-bottom:0; - font-size:140%; + font-size:130%; } h3 { @@ -293,8 +298,16 @@ dl.reflist dt a.el { } div.toc { - float:none; - width:auto; + float:right; + width:35%; +} + +@media screen and (max-width:600px) { + div.toc { + float:none; + width:inherit; + margin:0; + } } div.toc h3 { @@ -311,6 +324,12 @@ div.toc li { list-style-type:disc; } +div.toc { + li.level2, li.level3 { + margin-left:0.5em; + } +} + div.toc,.memproto,div.qindex,div.ah { background:linear-gradient(to bottom,$toc-background-color2 0%,$toc-background-color1 100%); box-shadow:inset 0 0 32px $toc-background-color1; diff --git a/docs/vulkan.dox b/docs/vulkan.dox index 68e3d5fe..a40f47a6 100644 --- a/docs/vulkan.dox +++ b/docs/vulkan.dox @@ -48,7 +48,7 @@ documentation. This is explained in more detail in the [SDK documentation for macOS](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html). -@section vulkan_include Including the Vulkan and GLFW header files +@section vulkan_include Including the Vulkan header file To include the Vulkan header, define @ref GLFW_INCLUDE_VULKAN before including the GLFW header. From 309d79376f31bddb75faed26efd1fe27b9365c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 26 Sep 2021 16:28:04 +0200 Subject: [PATCH 04/71] Fix GLFW_INCLUDE_GLEXT being ignored for glcorearb The GLFW_INCLUDE_GLCOREARB branch was left out when GLFW_INCLUDE_GLEXT was originally added, for reasons that are lost to history. The current versions of these headers seem to co-exist just fine. Issue reported on IRC. --- include/GLFW/glfw3.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index efd54e0c..b90f83a7 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -190,6 +190,9 @@ extern "C" { #else /*__APPLE__*/ #include + #if defined(GLFW_INCLUDE_GLEXT) + #include + #endif #endif /*__APPLE__*/ From f4d0365a5a389b8bb049e34c26b8771833bf7f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 19 Jul 2021 21:02:30 +0200 Subject: [PATCH 05/71] Use switch statement instead of if-else-chain Related to #1739 --- src/input.c | 142 ++++++++++++++++++++++++++++----------------------- src/window.c | 60 ++++++++++++---------- 2 files changed, 110 insertions(+), 92 deletions(-) diff --git a/src/input.c b/src/input.c index f2604c86..f6e03f23 100644 --- a/src/input.c +++ b/src/input.c @@ -522,90 +522,102 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) _GLFW_REQUIRE_INIT(); - if (mode == GLFW_CURSOR) + switch (mode) { - if (value != GLFW_CURSOR_NORMAL && - value != GLFW_CURSOR_HIDDEN && - value != GLFW_CURSOR_DISABLED) + case GLFW_CURSOR: { - _glfwInputError(GLFW_INVALID_ENUM, - "Invalid cursor mode 0x%08X", - value); - return; - } - - if (window->cursorMode == value) - return; - - window->cursorMode = value; - - _glfw.platform.getCursorPos(window, - &window->virtualCursorPosX, - &window->virtualCursorPosY); - _glfw.platform.setCursorMode(window, value); - } - else if (mode == GLFW_STICKY_KEYS) - { - value = value ? GLFW_TRUE : GLFW_FALSE; - if (window->stickyKeys == value) - return; - - if (!value) - { - int i; - - // Release all sticky keys - for (i = 0; i <= GLFW_KEY_LAST; i++) + if (value != GLFW_CURSOR_NORMAL && + value != GLFW_CURSOR_HIDDEN && + value != GLFW_CURSOR_DISABLED) { - if (window->keys[i] == _GLFW_STICK) - window->keys[i] = GLFW_RELEASE; + _glfwInputError(GLFW_INVALID_ENUM, + "Invalid cursor mode 0x%08X", + value); + return; } + + if (window->cursorMode == value) + return; + + window->cursorMode = value; + + _glfw.platform.getCursorPos(window, + &window->virtualCursorPosX, + &window->virtualCursorPosY); + _glfw.platform.setCursorMode(window, value); + return; } - window->stickyKeys = value; - } - else if (mode == GLFW_STICKY_MOUSE_BUTTONS) - { - value = value ? GLFW_TRUE : GLFW_FALSE; - if (window->stickyMouseButtons == value) - return; - - if (!value) + case GLFW_STICKY_KEYS: { - int i; + value = value ? GLFW_TRUE : GLFW_FALSE; + if (window->stickyKeys == value) + return; - // Release all sticky mouse buttons - for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++) + if (!value) { - if (window->mouseButtons[i] == _GLFW_STICK) - window->mouseButtons[i] = GLFW_RELEASE; + int i; + + // Release all sticky keys + for (i = 0; i <= GLFW_KEY_LAST; i++) + { + if (window->keys[i] == _GLFW_STICK) + window->keys[i] = GLFW_RELEASE; + } } + + window->stickyKeys = value; + return; } - window->stickyMouseButtons = value; - } - else if (mode == GLFW_LOCK_KEY_MODS) - { - window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE; - } - else if (mode == GLFW_RAW_MOUSE_MOTION) - { - if (!_glfw.platform.rawMouseMotionSupported()) + case GLFW_STICKY_MOUSE_BUTTONS: { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Raw mouse motion is not supported on this system"); + value = value ? GLFW_TRUE : GLFW_FALSE; + if (window->stickyMouseButtons == value) + return; + + if (!value) + { + int i; + + // Release all sticky mouse buttons + for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++) + { + if (window->mouseButtons[i] == _GLFW_STICK) + window->mouseButtons[i] = GLFW_RELEASE; + } + } + + window->stickyMouseButtons = value; return; } - value = value ? GLFW_TRUE : GLFW_FALSE; - if (window->rawMouseMotion == value) + case GLFW_LOCK_KEY_MODS: + { + window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE; return; + } - window->rawMouseMotion = value; - _glfw.platform.setRawMouseMotion(window, value); + case GLFW_RAW_MOUSE_MOTION: + { + if (!_glfw.platform.rawMouseMotionSupported()) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Raw mouse motion is not supported on this system"); + return; + } + + value = value ? GLFW_TRUE : GLFW_FALSE; + if (window->rawMouseMotion == value) + return; + + window->rawMouseMotion = value; + _glfw.platform.setRawMouseMotion(window, value); + return; + } } - else - _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); + + _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); } GLFWAPI int glfwRawMouseMotionSupported(void) diff --git a/src/window.c b/src/window.c index c9845eca..dda96ec8 100644 --- a/src/window.c +++ b/src/window.c @@ -882,35 +882,41 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value) value = value ? GLFW_TRUE : GLFW_FALSE; - if (attrib == GLFW_AUTO_ICONIFY) - window->autoIconify = value; - else if (attrib == GLFW_RESIZABLE) + switch (attrib) { - window->resizable = value; - if (!window->monitor) - _glfw.platform.setWindowResizable(window, value); + case GLFW_AUTO_ICONIFY: + window->autoIconify = value; + return; + + case GLFW_RESIZABLE: + window->resizable = value; + if (!window->monitor) + _glfw.platform.setWindowResizable(window, value); + return; + + case GLFW_DECORATED: + window->decorated = value; + if (!window->monitor) + _glfw.platform.setWindowDecorated(window, value); + return; + + case GLFW_FLOATING: + window->floating = value; + if (!window->monitor) + _glfw.platform.setWindowFloating(window, value); + return; + + case GLFW_FOCUS_ON_SHOW: + window->focusOnShow = value; + return; + + case GLFW_MOUSE_PASSTHROUGH: + window->mousePassthrough = value; + _glfw.platform.setWindowMousePassthrough(window, value); + return; } - else if (attrib == GLFW_DECORATED) - { - window->decorated = value; - if (!window->monitor) - _glfw.platform.setWindowDecorated(window, value); - } - else if (attrib == GLFW_FLOATING) - { - window->floating = value; - if (!window->monitor) - _glfw.platform.setWindowFloating(window, value); - } - else if (attrib == GLFW_FOCUS_ON_SHOW) - window->focusOnShow = value; - else if (attrib == GLFW_MOUSE_PASSTHROUGH) - { - window->mousePassthrough = value; - _glfw.platform.setWindowMousePassthrough(window, value); - } - else - _glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib); + + _glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib); } GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle) From 3d52f7e345ea480d15cc6f23bff7366fda9d2a6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 16 Feb 2021 20:12:19 +0100 Subject: [PATCH 06/71] Limit scope of some loop counters in C99 files --- src/cocoa_init.m | 19 ++++--------- src/cocoa_joystick.m | 29 ++++++------------- src/glx_context.c | 7 ++--- src/linux_joystick.c | 4 +-- src/wl_init.c | 7 ++--- src/wl_window.c | 17 +++++------- src/x11_init.c | 9 +++--- src/x11_window.c | 66 ++++++++++++++++++++------------------------ 8 files changed, 61 insertions(+), 97 deletions(-) diff --git a/src/cocoa_init.m b/src/cocoa_init.m index e97d9596..48bc2c29 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -75,7 +75,6 @@ static void changeToResourcesDirectory(void) // static void createMenuBar(void) { - size_t i; NSString* appName = nil; NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary]; NSString* nameKeys[] = @@ -87,7 +86,7 @@ static void createMenuBar(void) // Try to figure out what the calling application is called - for (i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++) + for (size_t i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++) { id name = bundleInfo[nameKeys[i]]; if (name && @@ -177,8 +176,6 @@ static void createMenuBar(void) // static void createKeyTables(void) { - int scancode; - memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes)); memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes)); @@ -297,7 +294,7 @@ static void createKeyTables(void) _glfw.ns.keycodes[0x43] = GLFW_KEY_KP_MULTIPLY; _glfw.ns.keycodes[0x4E] = GLFW_KEY_KP_SUBTRACT; - for (scancode = 0; scancode < 256; scancode++) + for (int scancode = 0; scancode < 256; scancode++) { // Store the reverse translation for faster key name lookup if (_glfw.ns.keycodes[scancode] >= 0) @@ -403,9 +400,7 @@ static GLFWbool initializeTIS(void) - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { - _GLFWwindow* window; - - for (window = _glfw.windowListHead; window; window = window->next) + for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next) _glfwInputWindowCloseRequest(window); return NSTerminateCancel; @@ -413,9 +408,7 @@ static GLFWbool initializeTIS(void) - (void)applicationDidChangeScreenParameters:(NSNotification *) notification { - _GLFWwindow* window; - - for (window = _glfw.windowListHead; window; window = window->next) + for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next) { if (window->context.client != GLFW_NO_API) [window->context.nsgl.object update]; @@ -450,9 +443,7 @@ static GLFWbool initializeTIS(void) - (void)applicationDidHide:(NSNotification *)notification { - int i; - - for (i = 0; i < _glfw.monitorCount; i++) + for (int i = 0; i < _glfw.monitorCount; i++) _glfwRestoreVideoModeCocoa(_glfw.monitors[i]); } diff --git a/src/cocoa_joystick.m b/src/cocoa_joystick.m index 74f20d02..e09e1efa 100644 --- a/src/cocoa_joystick.m +++ b/src/cocoa_joystick.m @@ -96,20 +96,18 @@ static CFComparisonResult compareElements(const void* fp, // static void closeJoystick(_GLFWjoystick* js) { - int i; - if (!js->present) return; - for (i = 0; i < CFArrayGetCount(js->ns.axes); i++) + for (int i = 0; i < CFArrayGetCount(js->ns.axes); i++) _glfw_free((void*) CFArrayGetValueAtIndex(js->ns.axes, i)); CFRelease(js->ns.axes); - for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++) + for (int i = 0; i < CFArrayGetCount(js->ns.buttons); i++) _glfw_free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i)); CFRelease(js->ns.buttons); - for (i = 0; i < CFArrayGetCount(js->ns.hats); i++) + for (int i = 0; i < CFArrayGetCount(js->ns.hats); i++) _glfw_free((void*) CFArrayGetValueAtIndex(js->ns.hats, i)); CFRelease(js->ns.hats); @@ -127,7 +125,6 @@ static void matchCallback(void* context, int jid; char name[256]; char guid[33]; - CFIndex i; CFTypeRef property; uint32_t vendor = 0, product = 0, version = 0; _GLFWjoystick* js; @@ -185,7 +182,7 @@ static void matchCallback(void* context, CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone); - for (i = 0; i < CFArrayGetCount(elements); i++) + for (CFIndex i = 0; i < CFArrayGetCount(elements); i++) { IOHIDElementRef native = (IOHIDElementRef) CFArrayGetValueAtIndex(elements, i); @@ -290,9 +287,7 @@ static void removeCallback(void* context, void* sender, IOHIDDeviceRef device) { - int jid; - - for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) + for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { if (_glfw.joysticks[jid].ns.device == device) { @@ -386,9 +381,7 @@ GLFWbool _glfwInitJoysticksCocoa(void) void _glfwTerminateJoysticksCocoa(void) { - int jid; - - for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) + for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) closeJoystick(_glfw.joysticks + jid); if (_glfw.ns.hidManager) @@ -403,9 +396,7 @@ int _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode) { if (mode & _GLFW_POLL_AXES) { - CFIndex i; - - for (i = 0; i < CFArrayGetCount(js->ns.axes); i++) + for (CFIndex i = 0; i < CFArrayGetCount(js->ns.axes); i++) { _GLFWjoyelementNS* axis = (_GLFWjoyelementNS*) CFArrayGetValueAtIndex(js->ns.axes, i); @@ -430,9 +421,7 @@ int _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode) if (mode & _GLFW_POLL_BUTTONS) { - CFIndex i; - - for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++) + for (CFIndex i = 0; i < CFArrayGetCount(js->ns.buttons); i++) { _GLFWjoyelementNS* button = (_GLFWjoyelementNS*) CFArrayGetValueAtIndex(js->ns.buttons, i); @@ -441,7 +430,7 @@ int _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode) _glfwInputJoystickButton(js, (int) i, state); } - for (i = 0; i < CFArrayGetCount(js->ns.hats); i++) + for (CFIndex i = 0; i < CFArrayGetCount(js->ns.hats); i++) { const int states[9] = { diff --git a/src/glx_context.c b/src/glx_context.c index bbe261a0..060e487d 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -55,7 +55,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* nativeConfigs; _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; - int i, nativeCount, usableCount; + int nativeCount, usableCount; const char* vendor; GLFWbool trustWindowBit = GLFW_TRUE; @@ -76,7 +76,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig)); usableCount = 0; - for (i = 0; i < nativeCount; i++) + for (int i = 0; i < nativeCount; i++) { const GLXFBConfig n = nativeConfigs[i]; _GLFWfbconfig* u = usableConfigs + usableCount; @@ -253,7 +253,6 @@ static void destroyContextGLX(_GLFWwindow* window) // GLFWbool _glfwInitGLX(void) { - int i; const char* sonames[] = { #if defined(_GLFW_GLX_LIBRARY) @@ -270,7 +269,7 @@ GLFWbool _glfwInitGLX(void) if (_glfw.glx.handle) return GLFW_TRUE; - for (i = 0; sonames[i]; i++) + for (int i = 0; sonames[i]; i++) { _glfw.glx.handle = _glfwPlatformLoadModule(sonames[i]); if (_glfw.glx.handle) diff --git a/src/linux_joystick.c b/src/linux_joystick.c index 6ea63942..da04e9c3 100644 --- a/src/linux_joystick.c +++ b/src/linux_joystick.c @@ -363,9 +363,7 @@ GLFWbool _glfwInitJoysticksLinux(void) void _glfwTerminateJoysticksLinux(void) { - int jid; - - for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) + for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { _GLFWjoystick* js = _glfw.joysticks + jid; if (js->present) diff --git a/src/wl_init.c b/src/wl_init.c index 031e5d52..acfe477d 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -886,10 +886,9 @@ static void registryHandleGlobalRemove(void *data, struct wl_registry *registry, uint32_t name) { - int i; _GLFWmonitor* monitor; - for (i = 0; i < _glfw.monitorCount; ++i) + for (int i = 0; i < _glfw.monitorCount; ++i) { monitor = _glfw.monitors[i]; if (monitor->wl.name == name) @@ -910,8 +909,6 @@ static const struct wl_registry_listener registryListener = { // static void createKeyTables(void) { - int scancode; - memset(_glfw.wl.keycodes, -1, sizeof(_glfw.wl.keycodes)); memset(_glfw.wl.scancodes, -1, sizeof(_glfw.wl.scancodes)); @@ -1033,7 +1030,7 @@ static void createKeyTables(void) _glfw.wl.keycodes[KEY_KPEQUAL] = GLFW_KEY_KP_EQUAL; _glfw.wl.keycodes[KEY_KPENTER] = GLFW_KEY_KP_ENTER; - for (scancode = 0; scancode < 256; scancode++) + for (int scancode = 0; scancode < 256; scancode++) { if (_glfw.wl.keycodes[scancode] > 0) _glfw.wl.scancodes[_glfw.wl.keycodes[scancode]] = scancode; diff --git a/src/wl_window.c b/src/wl_window.c index bf57ce53..b4c59d69 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -144,9 +144,8 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image) int stride = image->width * 4; int length = image->width * image->height * 4; void* data; - int fd, i; - fd = createAnonymousFile(length); + const int fd = createAnonymousFile(length); if (fd < 0) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -169,7 +168,7 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image) close(fd); unsigned char* source = (unsigned char*) image->pixels; unsigned char* target = data; - for (i = 0; i < image->width * image->height; i++, source += 4) + for (int i = 0; i < image->width * image->height; i++, source += 4) { unsigned int alpha = source[3]; @@ -347,7 +346,6 @@ static void resizeWindow(_GLFWwindow* window) static void checkScaleChange(_GLFWwindow* window) { int scale = 1; - int i; int monitorScale; // Check if we will be able to set the buffer scale or not. @@ -355,7 +353,7 @@ static void checkScaleChange(_GLFWwindow* window) return; // Get the scale factor from the highest scale monitor. - for (i = 0; i < window->wl.monitorsCount; ++i) + for (int i = 0; i < window->wl.monitorsCount; ++i) { monitorScale = window->wl.monitors[i]->wl.scale; if (scale < monitorScale) @@ -397,10 +395,9 @@ static void surfaceHandleLeave(void *data, { _GLFWwindow* window = data; _GLFWmonitor* monitor = wl_output_get_user_data(output); - GLFWbool found; - int i; + GLFWbool found = GLFW_FALSE; - for (i = 0, found = GLFW_FALSE; i < window->wl.monitorsCount - 1; ++i) + for (int i = 0; i < window->wl.monitorsCount - 1; ++i) { if (monitor == window->wl.monitors[i]) found = GLFW_TRUE; @@ -719,7 +716,7 @@ static void handleEvents(int timeout) { _glfw.wl.cursorTimerfd, POLLIN }, }; ssize_t read_ret; - uint64_t repeats, i; + uint64_t repeats; while (wl_display_prepare_read(display) != 0) wl_display_dispatch_pending(display); @@ -759,7 +756,7 @@ static void handleEvents(int timeout) if (_glfw.wl.keyboardFocus) { - for (i = 0; i < repeats; ++i) + for (uint64_t i = 0; i < repeats; ++i) { _glfwInputKey(_glfw.wl.keyboardFocus, _glfw.wl.keyboardLastKey, diff --git a/src/x11_init.c b/src/x11_init.c index bedd1bc9..68d6a6c4 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -209,7 +209,7 @@ static int translateKeySyms(const KeySym* keysyms, int width) // static void createKeyTables(void) { - int scancode, scancodeMin, scancodeMax; + int scancodeMin, scancodeMax; memset(_glfw.x11.keycodes, -1, sizeof(_glfw.x11.keycodes)); memset(_glfw.x11.scancodes, -1, sizeof(_glfw.x11.scancodes)); @@ -355,7 +355,7 @@ static void createKeyTables(void) }; // Find the X11 key code -> GLFW key code mapping - for (scancode = scancodeMin; scancode <= scancodeMax; scancode++) + for (int scancode = scancodeMin; scancode <= scancodeMax; scancode++) { int key = GLFW_KEY_UNKNOWN; @@ -414,7 +414,7 @@ static void createKeyTables(void) scancodeMax - scancodeMin + 1, &width); - for (scancode = scancodeMin; scancode <= scancodeMax; scancode++) + for (int scancode = scancodeMin; scancode <= scancodeMax; scancode++) { // Translate the un-translated key codes using traditional X11 KeySym // lookups @@ -1072,7 +1072,6 @@ void _glfwInputErrorX11(int error, const char* message) // Cursor _glfwCreateNativeCursorX11(const GLFWimage* image, int xhot, int yhot) { - int i; Cursor cursor; if (!_glfw.x11.xcursor.handle) @@ -1088,7 +1087,7 @@ Cursor _glfwCreateNativeCursorX11(const GLFWimage* image, int xhot, int yhot) unsigned char* source = (unsigned char*) image->pixels; XcursorPixel* target = native->pixels; - for (i = 0; i < image->width * image->height; i++, target++, source += 4) + for (int i = 0; i < image->width * image->height; i++, target++, source += 4) { unsigned int alpha = source[3]; diff --git a/src/x11_window.c b/src/x11_window.c index 3c74a813..616f9fd8 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -788,7 +788,6 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, // static Atom writeTargetToProperty(const XSelectionRequestEvent* request) { - int i; char* selectionString = NULL; const Atom formats[] = { _glfw.x11.UTF8_STRING, XA_STRING }; const int formatCount = sizeof(formats) / sizeof(formats[0]); @@ -831,14 +830,13 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request) // Multiple conversions were requested Atom* targets; - unsigned long i, count; + const unsigned long count = + _glfwGetWindowPropertyX11(request->requestor, + request->property, + _glfw.x11.ATOM_PAIR, + (unsigned char**) &targets); - count = _glfwGetWindowPropertyX11(request->requestor, - request->property, - _glfw.x11.ATOM_PAIR, - (unsigned char**) &targets); - - for (i = 0; i < count; i += 2) + for (unsigned long i = 0; i < count; i += 2) { int j; @@ -896,7 +894,7 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request) // Conversion to a data target was requested - for (i = 0; i < formatCount; i++) + for (int i = 0; i < formatCount; i++) { if (request->target == formats[i]) { @@ -1588,7 +1586,7 @@ static void processEvent(XEvent *event) else if (event->xclient.message_type == _glfw.x11.XdndEnter) { // A drag operation has entered the window - unsigned long i, count; + unsigned long count; Atom* formats = NULL; const GLFWbool list = event->xclient.data.l[1] & 1; @@ -1612,7 +1610,7 @@ static void processEvent(XEvent *event) formats = (Atom*) event->xclient.data.l + 2; } - for (i = 0; i < count; i++) + for (unsigned int i = 0; i < count; i++) { if (formats[i] == _glfw.x11.text_uri_list) { @@ -1718,12 +1716,12 @@ static void processEvent(XEvent *event) if (result) { - int i, count; + int count; char** paths = parseUriList(data, &count); _glfwInputDrop(window, count, (const char**) paths); - for (i = 0; i < count; i++) + for (int i = 0; i < count; i++) _glfw_free(paths[i]); _glfw_free(paths); } @@ -2102,20 +2100,20 @@ void _glfwSetWindowIconX11(_GLFWwindow* window, int count, const GLFWimage* imag { if (count) { - int i, j, longCount = 0; + int longCount = 0; - for (i = 0; i < count; i++) + for (int i = 0; i < count; i++) longCount += 2 + images[i].width * images[i].height; long* icon = _glfw_calloc(longCount, sizeof(long)); long* target = icon; - for (i = 0; i < count; i++) + for (int i = 0; i < count; i++) { *target++ = images[i].width; *target++ = images[i].height; - for (j = 0; j < images[i].width * images[i].height; j++) + for (int j = 0; j < images[i].width * images[i].height; j++) { *target++ = (images[i].pixels[j * 4 + 0] << 16) | (images[i].pixels[j * 4 + 1] << 8) | @@ -2537,7 +2535,6 @@ int _glfwWindowVisibleX11(_GLFWwindow* window) int _glfwWindowMaximizedX11(_GLFWwindow* window) { Atom* states; - unsigned long i; GLFWbool maximized = GLFW_FALSE; if (!_glfw.x11.NET_WM_STATE || @@ -2553,7 +2550,7 @@ int _glfwWindowMaximizedX11(_GLFWwindow* window) XA_ATOM, (unsigned char**) &states); - for (i = 0; i < count; i++) + for (unsigned long i = 0; i < count; i++) { if (states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT || states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ) @@ -2651,18 +2648,19 @@ void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled) else { Atom* states = NULL; - unsigned long i, count; - - count = _glfwGetWindowPropertyX11(window->x11.handle, - _glfw.x11.NET_WM_STATE, - XA_ATOM, - (unsigned char**) &states); + const unsigned long count = + _glfwGetWindowPropertyX11(window->x11.handle, + _glfw.x11.NET_WM_STATE, + XA_ATOM, + (unsigned char**) &states); // NOTE: We don't check for failure as this property may not exist yet // and that's fine (and we'll create it implicitly with append) if (enabled) { + unsigned long i; + for (i = 0; i < count; i++) { if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE) @@ -2680,20 +2678,16 @@ void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled) } else if (states) { - for (i = 0; i < count; i++) + for (unsigned long i = 0; i < count; i++) { if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE) + { + states[i] = states[count - 1]; + XChangeProperty(_glfw.x11.display, window->x11.handle, + _glfw.x11.NET_WM_STATE, XA_ATOM, 32, + PropModeReplace, (unsigned char*) states, count - 1); break; - } - - if (i < count) - { - states[i] = states[count - 1]; - count--; - - XChangeProperty(_glfw.x11.display, window->x11.handle, - _glfw.x11.NET_WM_STATE, XA_ATOM, 32, - PropModeReplace, (unsigned char*) states, count); + } } } From 0fe96ec2025557b37d4e2e003cb7115141db4d18 Mon Sep 17 00:00:00 2001 From: luz paz Date: Wed, 15 Sep 2021 08:20:56 -0400 Subject: [PATCH 07/71] Fix various typos Found via `codespell -q 3 -S ./deps -L fo,numer,te,uint,wille` Closes #1965 --- include/GLFW/glfw3.h | 2 +- src/win32_platform.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index b90f83a7..17cb66c2 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -375,7 +375,7 @@ extern "C" { * * The naming of the key codes follow these rules: * - The US keyboard layout is used - * - Names of printable alpha-numeric characters are used (e.g. "A", "R", + * - Names of printable alphanumeric characters are used (e.g. "A", "R", * "3", etc.) * - For non-alphanumeric characters, Unicode:ish names are used (e.g. * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not diff --git a/src/win32_platform.h b/src/win32_platform.h index 20e40d74..a7130377 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -428,7 +428,7 @@ typedef struct _GLFWwindowWin32 // The last received cursor position, regardless of source int lastCursorPosX, lastCursorPosY; - // The last recevied high surrogate when decoding pairs of UTF-16 messages + // The last received high surrogate when decoding pairs of UTF-16 messages WCHAR highSurrogate; } _GLFWwindowWin32; From 41ebcf1eed4f74028a218d7dd3c14c663464c030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 17 Oct 2021 20:52:31 +0200 Subject: [PATCH 08/71] Add credit Related to #1965 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d1396af4..bb24ebe9 100644 --- a/README.md +++ b/README.md @@ -433,6 +433,7 @@ skills. - Denis Ovod - Ozzy - Andri Pálsson + - luz paz - Peoro - Braden Pellett - Christopher Pelloux From 53d7622a3a78757d5297ecafa235fac64a62b0a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 19 Jul 2021 18:25:50 +0200 Subject: [PATCH 09/71] Move list of contributors to separate file Fixes #1839 --- CONTRIBUTORS.md | 226 +++++++++++++++++++++++++++++++++++++++++++++++ README.md | 230 ++---------------------------------------------- 2 files changed, 231 insertions(+), 225 deletions(-) create mode 100644 CONTRIBUTORS.md diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 00000000..7e79b955 --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,226 @@ +# Acknowledgements + +GLFW exists because people around the world donated their time and lent their +skills. This list only includes contributions to the main repository and +excludes other invaluable contributions like language bindings and text and +video tutorials. + + - Bobyshev Alexander + - Laurent Aphecetche + - Matt Arsenault + - ashishgamedev + - David Avedissian + - Keith Bauer + - John Bartholomew + - Coşku Baş + - Niklas Behrens + - Andrew Belt + - Nevyn Bengtsson + - Niklas Bergström + - Denis Bernard + - Doug Binks + - blanco + - Waris Boonyasiriwat + - Kyle Brenneman + - Rok Breulj + - Kai Burjack + - Martin Capitanio + - Nicolas Caramelli + - David Carlier + - Arturo Castro + - Chi-kwan Chan + - Joseph Chua + - Ian Clarkson + - Michał Cichoń + - Lambert Clara + - Anna Clarke + - Yaron Cohen-Tal + - Omar Cornut + - Andrew Corrigan + - Bailey Cosier + - Noel Cower + - CuriouserThing + - Jason Daly + - Jarrod Davis + - Olivier Delannoy + - Paul R. Deppe + - Michael Dickens + - Роман Донченко + - Mario Dorn + - Wolfgang Draxinger + - Jonathan Dummer + - Ralph Eastwood + - Fredrik Ehnbom + - Robin Eklind + - Siavash Eliasi + - Ahmad Fatoum + - Felipe Ferreira + - Michael Fogleman + - Gerald Franz + - Mário Freitas + - GeO4d + - Marcus Geelnard + - Charles Giessen + - Ryan C. Gordon + - Stephen Gowen + - Kovid Goyal + - Eloi Marín Gratacós + - Stefan Gustavson + - Jonathan Hale + - hdf89shfdfs + - Sylvain Hellegouarch + - Matthew Henry + - heromyth + - Lucas Hinderberger + - Paul Holden + - Warren Hu + - Charles Huber + - IntellectualKitty + - Aaron Jacobs + - Erik S. V. Jansson + - Toni Jovanoski + - Arseny Kapoulkine + - Cem Karan + - Osman Keskin + - Koray Kilinc + - Josh Kilmer + - Byunghoon Kim + - Cameron King + - Peter Knut + - Christoph Kubisch + - Yuri Kunde Schlesner + - Rokas Kupstys + - Konstantin Käfer + - Eric Larson + - Francis Lecavalier + - Jong Won Lee + - Robin Leffmann + - Glenn Lewis + - Shane Liesegang + - Anders Lindqvist + - Leon Linhart + - Marco Lizza + - Eyal Lotem + - Aaron Loucks + - Luflosi + - lukect + - Tristam MacDonald + - Hans Mackowiak + - Дмитри Малышев + - Zbigniew Mandziejewicz + - Adam Marcus + - Célestin Marot + - Kyle McDonald + - David V. McKay + - David Medlock + - Bryce Mehring + - Jonathan Mercier + - Marcel Metz + - Liam Middlebrook + - Ave Milia + - Jonathan Miller + - Kenneth Miller + - Bruce Mitchener + - Jack Moffitt + - Jeff Molofee + - Alexander Monakov + - Pierre Morel + - Jon Morton + - Pierre Moulon + - Martins Mozeiko + - Julian Møller + - ndogxj + - n3rdopolis + - Kristian Nielsen + - Kamil Nowakowski + - onox + - Denis Ovod + - Ozzy + - Andri Pálsson + - luz paz + - Peoro + - Braden Pellett + - Christopher Pelloux + - Arturo J. Pérez + - Vladimir Perminov + - Anthony Pesch + - Orson Peters + - Emmanuel Gil Peyrot + - Cyril Pichard + - Keith Pitt + - Stanislav Podgorskiy + - Konstantin Podsvirov + - Nathan Poirier + - Alexandre Pretyman + - Pablo Prietz + - przemekmirek + - pthom + - Guillaume Racicot + - Philip Rideout + - Eddie Ringle + - Max Risuhin + - Jorge Rodriguez + - Jari Ronkainen + - Luca Rood + - Ed Ropple + - Aleksey Rybalkin + - Mikko Rytkönen + - Riku Salminen + - Brandon Schaefer + - Sebastian Schuberth + - Christian Sdunek + - Matt Sealey + - Steve Sexton + - Arkady Shapkin + - Ali Sherief + - Yoshiki Shibukawa + - Dmitri Shuralyov + - Daniel Skorupski + - Anthony Smith + - Bradley Smith + - Cliff Smolinsky + - Patrick Snape + - Erlend Sogge Heggen + - Julian Squires + - Johannes Stein + - Pontus Stenetorp + - Michael Stocker + - Justin Stoecker + - Elviss Strazdins + - Paul Sultana + - Nathan Sweet + - TTK-Bandit + - Jared Tiala + - Sergey Tikhomirov + - Arthur Tombs + - Ioannis Tsakpinis + - Samuli Tuomola + - Matthew Turner + - urraka + - Elias Vanderstuyft + - Stef Velzel + - Jari Vetoniemi + - Ricardo Vieira + - Nicholas Vitovitch + - Simon Voordouw + - Corentin Wallez + - Torsten Walluhn + - Patrick Walton + - Xo Wang + - Jay Weisskopf + - Frank Wille + - Andy Williams + - Joel Winarske + - Richard A. Wilkes + - Tatsuya Yatagawa + - Ryogo Yoshimura + - Lukas Zanner + - Andrey Zholos + - Aihui Zhu + - Santi Zupancic + - Jonas Ådahl + - Lasse Öörni + - Leonard König + - All the unmentioned and anonymous contributors in the GLFW community, for bug + reports, patches, feedback, testing and encouragement + diff --git a/README.md b/README.md index bb24ebe9..d97f2e7e 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,11 @@ you have used GLFW 2 in the past, there is a [transition guide](https://www.glfw.org/docs/latest/moving.html) for moving to the GLFW 3 API. +GLFW exists because of the contributions of [many people](CONTRIBUTORS.md) +around the world, whether by reporting bugs, providing community support, adding +features, reviewing or testing code, debugging, proofreading docs, suggesting +features or fixing bugs. + ## Compiling GLFW @@ -295,228 +300,3 @@ request, please file it in the Finally, if you're interested in helping out with the development of GLFW or porting it to your favorite platform, join us on the forum, GitHub or IRC. - -## Acknowledgements - -GLFW exists because people around the world donated their time and lent their -skills. - - - Bobyshev Alexander - - Laurent Aphecetche - - Matt Arsenault - - ashishgamedev - - David Avedissian - - Keith Bauer - - John Bartholomew - - Coşku Baş - - Niklas Behrens - - Andrew Belt - - Nevyn Bengtsson - - Niklas Bergström - - Denis Bernard - - Doug Binks - - blanco - - Waris Boonyasiriwat - - Kyle Brenneman - - Rok Breulj - - Kai Burjack - - Martin Capitanio - - Nicolas Caramelli - - David Carlier - - Arturo Castro - - Chi-kwan Chan - - Joseph Chua - - Ian Clarkson - - Michał Cichoń - - Lambert Clara - - Anna Clarke - - Yaron Cohen-Tal - - Omar Cornut - - Andrew Corrigan - - Bailey Cosier - - Noel Cower - - CuriouserThing - - Jason Daly - - Jarrod Davis - - Olivier Delannoy - - Paul R. Deppe - - Michael Dickens - - Роман Донченко - - Mario Dorn - - Wolfgang Draxinger - - Jonathan Dummer - - Ralph Eastwood - - Fredrik Ehnbom - - Robin Eklind - - Siavash Eliasi - - Ahmad Fatoum - - Felipe Ferreira - - Michael Fogleman - - Gerald Franz - - Mário Freitas - - GeO4d - - Marcus Geelnard - - Charles Giessen - - Ryan C. Gordon - - Stephen Gowen - - Kovid Goyal - - Eloi Marín Gratacós - - Stefan Gustavson - - Jonathan Hale - - hdf89shfdfs - - Sylvain Hellegouarch - - Matthew Henry - - heromyth - - Lucas Hinderberger - - Paul Holden - - Warren Hu - - Charles Huber - - IntellectualKitty - - Aaron Jacobs - - Erik S. V. Jansson - - Toni Jovanoski - - Arseny Kapoulkine - - Cem Karan - - Osman Keskin - - Koray Kilinc - - Josh Kilmer - - Byunghoon Kim - - Cameron King - - Peter Knut - - Christoph Kubisch - - Yuri Kunde Schlesner - - Rokas Kupstys - - Konstantin Käfer - - Eric Larson - - Francis Lecavalier - - Jong Won Lee - - Robin Leffmann - - Glenn Lewis - - Shane Liesegang - - Anders Lindqvist - - Leon Linhart - - Marco Lizza - - Eyal Lotem - - Aaron Loucks - - Luflosi - - lukect - - Tristam MacDonald - - Hans Mackowiak - - Дмитри Малышев - - Zbigniew Mandziejewicz - - Adam Marcus - - Célestin Marot - - Kyle McDonald - - David V. McKay - - David Medlock - - Bryce Mehring - - Jonathan Mercier - - Marcel Metz - - Liam Middlebrook - - Ave Milia - - Jonathan Miller - - Kenneth Miller - - Bruce Mitchener - - Jack Moffitt - - Jeff Molofee - - Alexander Monakov - - Pierre Morel - - Jon Morton - - Pierre Moulon - - Martins Mozeiko - - Julian Møller - - ndogxj - - n3rdopolis - - Kristian Nielsen - - Kamil Nowakowski - - onox - - Denis Ovod - - Ozzy - - Andri Pálsson - - luz paz - - Peoro - - Braden Pellett - - Christopher Pelloux - - Arturo J. Pérez - - Vladimir Perminov - - Anthony Pesch - - Orson Peters - - Emmanuel Gil Peyrot - - Cyril Pichard - - Keith Pitt - - Stanislav Podgorskiy - - Konstantin Podsvirov - - Nathan Poirier - - Alexandre Pretyman - - Pablo Prietz - - przemekmirek - - pthom - - Guillaume Racicot - - Philip Rideout - - Eddie Ringle - - Max Risuhin - - Jorge Rodriguez - - Jari Ronkainen - - Luca Rood - - Ed Ropple - - Aleksey Rybalkin - - Mikko Rytkönen - - Riku Salminen - - Brandon Schaefer - - Sebastian Schuberth - - Christian Sdunek - - Matt Sealey - - Steve Sexton - - Arkady Shapkin - - Ali Sherief - - Yoshiki Shibukawa - - Dmitri Shuralyov - - Daniel Skorupski - - Anthony Smith - - Bradley Smith - - Cliff Smolinsky - - Patrick Snape - - Erlend Sogge Heggen - - Julian Squires - - Johannes Stein - - Pontus Stenetorp - - Michael Stocker - - Justin Stoecker - - Elviss Strazdins - - Paul Sultana - - Nathan Sweet - - TTK-Bandit - - Jared Tiala - - Sergey Tikhomirov - - Arthur Tombs - - Ioannis Tsakpinis - - Samuli Tuomola - - Matthew Turner - - urraka - - Elias Vanderstuyft - - Stef Velzel - - Jari Vetoniemi - - Ricardo Vieira - - Nicholas Vitovitch - - Simon Voordouw - - Corentin Wallez - - Torsten Walluhn - - Patrick Walton - - Xo Wang - - Jay Weisskopf - - Frank Wille - - Andy Williams - - Joel Winarske - - Richard A. Wilkes - - Tatsuya Yatagawa - - Ryogo Yoshimura - - Lukas Zanner - - Andrey Zholos - - Aihui Zhu - - Santi Zupancic - - Jonas Ådahl - - Lasse Öörni - - Leonard König - - All the unmentioned and anonymous contributors in the GLFW community, for bug - reports, patches, feedback, testing and encouragement - From 4005f70eef41a691b849cd06e085d9005df6b66b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 18 Oct 2021 01:05:09 +0200 Subject: [PATCH 10/71] WGL: Limit DWM swap interval hack to Vista and 7 This hack breaks when switching a window to fullscreen, if the OpenGL ICD detects this and switches its swapchain to exclusive mode. This limits the hack to Windows Vista and 7. This hack was added because of vsync jitter under DWM on Windows 7 and I have been unable to reproduce it on any later version. Is this change causing any problems on any version of Windows? Please open an issue! Fixes #1072 --- README.md | 1 + src/wgl_context.c | 22 +++++++++------------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index d97f2e7e..e6da3acd 100644 --- a/README.md +++ b/README.md @@ -271,6 +271,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Non-arrow cursors are offset from the hotspot (#1706,#1899) - [POSIX] Removed use of deprecated function `gettimeofday` - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled + - [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072) - [NSGL] Removed enforcement of forward-compatible flag for core contexts - [NSGL] Bugfix: `GLFW_COCOA_RETINA_FRAMEBUFFER` had no effect on newer macOS versions (#1442) diff --git a/src/wgl_context.c b/src/wgl_context.c index 952d70de..6586db10 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -322,14 +322,12 @@ static void swapBuffersWGL(_GLFWwindow* window) { if (!window->monitor) { - if (IsWindowsVistaOrGreater()) + // HACK: Use DwmFlush when desktop composition is enabled on Windows Vista and 7 + if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater()) { - // DWM Composition is always enabled on Win8+ - BOOL enabled = IsWindows8OrGreater(); + BOOL enabled = FALSE; - // HACK: Use DwmFlush when desktop composition is enabled - if (enabled || - (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)) + if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled) { int count = abs(window->context.wgl.interval); while (count--) @@ -349,15 +347,13 @@ static void swapIntervalWGL(int interval) if (!window->monitor) { - if (IsWindowsVistaOrGreater()) + // HACK: Disable WGL swap interval when desktop composition is enabled on Windows + // Vista and 7 to avoid interfering with DWM vsync + if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater()) { - // DWM Composition is always enabled on Win8+ - BOOL enabled = IsWindows8OrGreater(); + BOOL enabled = FALSE; - // HACK: Disable WGL swap interval when desktop composition is enabled to - // avoid interfering with DWM vsync - if (enabled || - (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)) + if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled) interval = 0; } } From 68534cc2ce43126b0451f7fc771d6c5a2e6e9981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 19 Oct 2021 15:32:40 +0200 Subject: [PATCH 11/71] Null: Remove unused function --- src/null_platform.h | 1 - src/null_window.c | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/null_platform.h b/src/null_platform.h index 30e50a85..fca7c11f 100644 --- a/src/null_platform.h +++ b/src/null_platform.h @@ -116,7 +116,6 @@ GLFWbool _glfwRawMouseMotionSupportedNull(void); void _glfwShowWindowNull(_GLFWwindow* window); void _glfwRequestWindowAttentionNull(_GLFWwindow* window); void _glfwRequestWindowAttentionNull(_GLFWwindow* window); -void _glfwUnhideWindowNull(_GLFWwindow* window); void _glfwHideWindowNull(_GLFWwindow* window); void _glfwFocusWindowNull(_GLFWwindow* window); int _glfwWindowFocusedNull(_GLFWwindow* window); diff --git a/src/null_window.c b/src/null_window.c index 10c5293f..710d4c9c 100644 --- a/src/null_window.c +++ b/src/null_window.c @@ -409,10 +409,6 @@ void _glfwRequestWindowAttentionNull(_GLFWwindow* window) { } -void _glfwUnhideWindowNull(_GLFWwindow* window) -{ -} - void _glfwHideWindowNull(_GLFWwindow* window) { if (_glfw.null.focusedWindow == window) From ee6ff939a540544494dc70f00a49af0561282dee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 21 Oct 2021 19:43:01 +0200 Subject: [PATCH 12/71] Fix invalid pointer conversions C does not allow conversions between data pointers and function pointers. Yes, the name of the macro is reserved. That's something for a future commit to fix. Fixes #1703 --- src/init.c | 2 +- src/input.c | 18 +++++++++--------- src/internal.h | 12 ++++++------ src/monitor.c | 2 +- src/window.c | 18 +++++++++--------- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/init.c b/src/init.c index cdb7ae41..65f5de31 100644 --- a/src/init.c +++ b/src/init.c @@ -440,7 +440,7 @@ GLFWAPI int glfwGetError(const char** description) GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun) { - _GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun); + _GLFW_SWAP(GLFWerrorfun, _glfwErrorCallback, cbfun); return cbfun; } diff --git a/src/input.c b/src/input.c index f6e03f23..11716bd5 100644 --- a/src/input.c +++ b/src/input.c @@ -868,7 +868,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.key, cbfun); + _GLFW_SWAP(GLFWkeyfun, window->callbacks.key, cbfun); return cbfun; } @@ -878,7 +878,7 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun) assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.character, cbfun); + _GLFW_SWAP(GLFWcharfun, window->callbacks.character, cbfun); return cbfun; } @@ -888,7 +888,7 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmods assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun); + _GLFW_SWAP(GLFWcharmodsfun, window->callbacks.charmods, cbfun); return cbfun; } @@ -899,7 +899,7 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun); + _GLFW_SWAP(GLFWmousebuttonfun, window->callbacks.mouseButton, cbfun); return cbfun; } @@ -910,7 +910,7 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun); + _GLFW_SWAP(GLFWcursorposfun, window->callbacks.cursorPos, cbfun); return cbfun; } @@ -921,7 +921,7 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun); + _GLFW_SWAP(GLFWcursorenterfun, window->callbacks.cursorEnter, cbfun); return cbfun; } @@ -932,7 +932,7 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun); + _GLFW_SWAP(GLFWscrollfun, window->callbacks.scroll, cbfun); return cbfun; } @@ -942,7 +942,7 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun) assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun); + _GLFW_SWAP(GLFWdropfun, window->callbacks.drop, cbfun); return cbfun; } @@ -1166,7 +1166,7 @@ GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun) if (!initJoysticks()) return NULL; - _GLFW_SWAP_POINTERS(_glfw.callbacks.joystick, cbfun); + _GLFW_SWAP(GLFWjoystickfun, _glfw.callbacks.joystick, cbfun); return cbfun; } diff --git a/src/internal.h b/src/internal.h index 45ae45ab..4d2a6805 100644 --- a/src/internal.h +++ b/src/internal.h @@ -357,12 +357,12 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void); } // Swaps the provided pointers -#define _GLFW_SWAP_POINTERS(x, y) \ - { \ - void* t; \ - t = x; \ - x = y; \ - y = t; \ +#define _GLFW_SWAP(type, x, y) \ + { \ + type t; \ + t = x; \ + x = y; \ + y = t; \ } // Per-thread error structure diff --git a/src/monitor.c b/src/monitor.c index 31921b46..e6f47d65 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -419,7 +419,7 @@ GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* handle) GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun) { _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(_glfw.callbacks.monitor, cbfun); + _GLFW_SWAP(GLFWmonitorfun, _glfw.callbacks.monitor, cbfun); return cbfun; } diff --git a/src/window.c b/src/window.c index dda96ec8..a65ed760 100644 --- a/src/window.c +++ b/src/window.c @@ -992,7 +992,7 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.pos, cbfun); + _GLFW_SWAP(GLFWwindowposfun, window->callbacks.pos, cbfun); return cbfun; } @@ -1003,7 +1003,7 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.size, cbfun); + _GLFW_SWAP(GLFWwindowsizefun, window->callbacks.size, cbfun); return cbfun; } @@ -1014,7 +1014,7 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.close, cbfun); + _GLFW_SWAP(GLFWwindowclosefun, window->callbacks.close, cbfun); return cbfun; } @@ -1025,7 +1025,7 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.refresh, cbfun); + _GLFW_SWAP(GLFWwindowrefreshfun, window->callbacks.refresh, cbfun); return cbfun; } @@ -1036,7 +1036,7 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.focus, cbfun); + _GLFW_SWAP(GLFWwindowfocusfun, window->callbacks.focus, cbfun); return cbfun; } @@ -1047,7 +1047,7 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.iconify, cbfun); + _GLFW_SWAP(GLFWwindowiconifyfun, window->callbacks.iconify, cbfun); return cbfun; } @@ -1058,7 +1058,7 @@ GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* handle, assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.maximize, cbfun); + _GLFW_SWAP(GLFWwindowmaximizefun, window->callbacks.maximize, cbfun); return cbfun; } @@ -1069,7 +1069,7 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.fbsize, cbfun); + _GLFW_SWAP(GLFWframebuffersizefun, window->callbacks.fbsize, cbfun); return cbfun; } @@ -1080,7 +1080,7 @@ GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - _GLFW_SWAP_POINTERS(window->callbacks.scale, cbfun); + _GLFW_SWAP(GLFWwindowcontentscalefun, window->callbacks.scale, cbfun); return cbfun; } From db91507956e2e925aa2027d82d2afee83093fdbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 21 Oct 2021 21:54:50 +0200 Subject: [PATCH 13/71] Remove saving a function pointer only used once This removes the global struct member for vkEnumerateInstanceExtensionProperties, which is only used in the same function that fetches the function from the loader. The pattern is now more in line with how other single uses of Vulkan functions are structures, such as window surface creation. --- src/internal.h | 2 -- src/vulkan.c | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/internal.h b/src/internal.h index 4d2a6805..1a38ba7e 100644 --- a/src/internal.h +++ b/src/internal.h @@ -329,7 +329,6 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void); #else typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*); typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*); - #define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties #define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr #endif @@ -855,7 +854,6 @@ struct _GLFWlibrary void* handle; char* extensions[2]; #if !defined(_GLFW_VULKAN_STATIC) - PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties; PFN_vkGetInstanceProcAddr GetInstanceProcAddr; #endif GLFWbool KHR_surface; diff --git a/src/vulkan.c b/src/vulkan.c index 51789249..b5ca25c0 100644 --- a/src/vulkan.c +++ b/src/vulkan.c @@ -45,6 +45,7 @@ GLFWbool _glfwInitVulkan(int mode) { VkResult err; VkExtensionProperties* ep; + PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties; uint32_t i, count; if (_glfw.vk.available) @@ -81,9 +82,9 @@ GLFWbool _glfwInitVulkan(int mode) return GLFW_FALSE; } - _glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) + vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties"); - if (!_glfw.vk.EnumerateInstanceExtensionProperties) + if (!vkEnumerateInstanceExtensionProperties) { _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties"); From 393eac458b749d9d4b8b9bb1bb5119705106c960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 21 Oct 2021 23:49:03 +0200 Subject: [PATCH 14/71] Improve Vulkan guide header section --- docs/vulkan.dox | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/vulkan.dox b/docs/vulkan.dox index a40f47a6..734c630b 100644 --- a/docs/vulkan.dox +++ b/docs/vulkan.dox @@ -50,7 +50,7 @@ documentation. This is explained in more detail in the @section vulkan_include Including the Vulkan header file -To include the Vulkan header, define @ref GLFW_INCLUDE_VULKAN before including +To have GLFW include the Vulkan header, define @ref GLFW_INCLUDE_VULKAN before including the GLFW header. @code @@ -66,8 +66,12 @@ your own custom Vulkan header then do this before the GLFW header. #include @endcode -Unless a Vulkan header is included, either by the GLFW header or above it, any -GLFW functions that take or return Vulkan types will not be declared. +Unless a Vulkan header is included, either by the GLFW header or above it, the following +GLFW functions will not be declared, as depend on Vulkan types. + + - @ref glfwGetInstanceProcAddress + - @ref glfwGetPhysicalDevicePresentationSupport + - @ref glfwCreateWindowSurface The `VK_USE_PLATFORM_*_KHR` macros do not need to be defined for the Vulkan part of GLFW to work. Define them only if you are using these extensions directly. From 76a5f781dbff5366271c021ee763da2a44fdcef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 21 Oct 2021 20:45:44 +0200 Subject: [PATCH 15/71] Add glfwInitVulkanLoader This removes the GLFW_VULKAN_STATIC CMake option and the _GLFW_VULKAN_STATIC configuration macro and replaces them with the glfwInitVulkanLoader function, allowing a single library binary to provide both behaviors. This is based on the design from PR #1374 by @pmuetschard. Closes #1374 Closes #1890 --- CMakeLists.txt | 1 - CONTRIBUTORS.md | 1 + README.md | 1 + docs/compile.dox | 8 ------ docs/intro.dox | 1 + docs/news.dox | 12 +++++++++ docs/vulkan.dox | 33 +++++++++++++---------- include/GLFW/glfw3.h | 48 ++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 5 ---- src/init.c | 6 +++++ src/internal.h | 14 +++------- src/vulkan.c | 62 ++++++++++++++++++++++---------------------- 12 files changed, 124 insertions(+), 68 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5042ab9c..f5e538bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,6 @@ option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ${GLFW_STANDALONE}) option(GLFW_BUILD_TESTS "Build the GLFW test programs" ${GLFW_STANDALONE}) option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON) option(GLFW_INSTALL "Generate installation target" ON) -option(GLFW_VULKAN_STATIC "Assume the Vulkan loader is linked with the application" OFF) include(GNUInstallDirs) include(CMakeDependentOption) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 7e79b955..84320b17 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -128,6 +128,7 @@ video tutorials. - Jon Morton - Pierre Moulon - Martins Mozeiko + - Pascal Muetschard - Julian Møller - ndogxj - n3rdopolis diff --git a/README.md b/README.md index e6da3acd..6cfb59a5 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,7 @@ information on what to include when reporting a bug. - Added `glfwInitAllocator` for setting a custom memory allocator (#544,#1628,#1947) - Added `GLFWallocator` struct and `GLFWallocatefun`, `GLFWreallocatefun` and `GLFWdeallocatefun` types (#544,#1628,#1947) + - Added `glfwInitVulkanLoader` for using a non-default Vulkan loader (#1374,#1890) - Added `GLFW_RESIZE_NWSE_CURSOR`, `GLFW_RESIZE_NESW_CURSOR`, `GLFW_RESIZE_ALL_CURSOR` and `GLFW_NOT_ALLOWED_CURSOR` cursor shapes (#427) - Added `GLFW_RESIZE_EW_CURSOR` alias for `GLFW_HRESIZE_CURSOR` (#427) diff --git a/docs/compile.dox b/docs/compile.dox index 63479516..05da99cf 100644 --- a/docs/compile.dox +++ b/docs/compile.dox @@ -273,10 +273,6 @@ __GLFW_BUILD_DOCS__ determines whether the GLFW documentation is built along with the library. This is enabled by default if [Doxygen](https://www.doxygen.nl/) is found by CMake during configuration. -@anchor GLFW_VULKAN_STATIC -__GLFW_VULKAN_STATIC__ determines whether to use the Vulkan loader linked -directly with the application. This is disabled by default. - @subsection compile_options_win32 Win32 specific CMake options @@ -383,10 +379,6 @@ attempts to detect the appropriate platform at initialization. If you are building GLFW as a shared library / dynamic library / DLL then you must also define @b _GLFW_BUILD_DLL. Otherwise, you must not define it. -If you are linking the Vulkan loader directly with your application then you -must also define @b _GLFW_VULKAN_STATIC. Otherwise, GLFW will attempt to use the -external version. - If you are using a custom name for the Vulkan, EGL, GLX, OSMesa, OpenGL, GLESv1 or GLESv2 library, you can override the default names by defining those you need of @b _GLFW_VULKAN_LIBRARY, @b _GLFW_EGL_LIBRARY, @b _GLFW_GLX_LIBRARY, @b diff --git a/docs/intro.dox b/docs/intro.dox index c50a3722..5cbd7eb0 100644 --- a/docs/intro.dox +++ b/docs/intro.dox @@ -35,6 +35,7 @@ successfully initialized, and only from the main thread. - @ref glfwSetErrorCallback - @ref glfwInitHint - @ref glfwInitAllocator + - @ref glfwInitVulkanLoader - @ref glfwInit - @ref glfwTerminate diff --git a/docs/news.dox b/docs/news.dox index 28affab0..6c55e65f 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -142,6 +142,17 @@ GLFW_TRANSPARENT_FRAMEBUFFER on Windows 7 if DWM transparency is off @subsection removals_34 Removals in 3.4 +@subsubsection vulkan_static_34 GLFW_VULKAN_STATIC CMake option has been removed + +This option was used to compile GLFW directly linked with the Vulkan loader, instead of +using dynamic loading to get hold of `vkGetInstanceProcAddr` at initialization. This is +now done by calling the @ref glfwInitVulkanLoader function before initialization. + +If you need backward compatibility, this macro can still be defined for GLFW 3.4 and will +have no effect. The call to @ref glfwInitVulkanLoader can be conditionally enabled in +your code by checking the @ref GLFW_VERSION_MAJOR and @ref GLFW_VERSION_MINOR macros. + + @subsubsection osmesa_option_34 GLFW_USE_OSMESA CMake option has been removed This option was used to compile GLFW for the Null platform. The Null platform is now @@ -168,6 +179,7 @@ then GLFW will fail to initialize. - @ref glfwInitAllocator - @ref glfwGetPlatform - @ref glfwPlatformSupported + - @ref glfwInitVulkanLoader @subsubsection types_34 New types in version 3.4 diff --git a/docs/vulkan.dox b/docs/vulkan.dox index 734c630b..31891036 100644 --- a/docs/vulkan.dox +++ b/docs/vulkan.dox @@ -29,22 +29,28 @@ are also guides for the other areas of the GLFW API. - @ref input_guide -@section vulkan_loader Linking against the Vulkan loader +@section vulkan_loader Finding the Vulkan loader -By default, GLFW will look for the Vulkan loader on demand at runtime via its -standard name (`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other -Unix-like systems and `libvulkan.1.dylib` on macOS). This means that GLFW does -not need to be linked against the loader. However, it also means that if you -are using the static library form of the Vulkan loader GLFW will either fail to -find it or (worse) use the wrong one. +GLFW itself does not ever need to be linked against the Vulkan loader. -The @ref GLFW_VULKAN_STATIC CMake option makes GLFW call the Vulkan loader -directly instead of dynamically loading it at runtime. Not linking against the -Vulkan loader will then be a compile-time error. +By default, GLFW will load the Vulkan loader dynamically at runtime via its standard name: +`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other Unix-like systems and +`libvulkan.1.dylib` on macOS. -@macos Because the Vulkan loader and ICD are not installed globally on macOS, -you need to set up the application bundle according to the LunarG SDK -documentation. This is explained in more detail in the +@macos GLFW will also look up and search the executable subdirectory of your application +bundle. + +If your code is using a Vulkan loader with a different name or in a non-standard location +you will need to direct GLFW to it. Pass your version of `vkGetInstanceProcAddr` to @ref +glfwInitVulkanLoader before initializing GLFW and it will use that function for all Vulkan +entry point retrieval. This prevents GLFW from dynamically loading the Vulkan loader. + +@code +glfwInitVulkanLoader(vkGetInstanceProcAddr); +@endcode + +@macos To make your application be redistributable you will need to set up the application +bundle according to the LunarG SDK documentation. This is explained in more detail in the [SDK documentation for macOS](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html). @@ -69,6 +75,7 @@ your own custom Vulkan header then do this before the GLFW header. Unless a Vulkan header is included, either by the GLFW header or above it, the following GLFW functions will not be declared, as depend on Vulkan types. + - @ref glfwInitVulkanLoader - @ref glfwGetInstanceProcAddress - @ref glfwGetPhysicalDevicePresentationSupport - @ref glfwCreateWindowSurface diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 17cb66c2..751615eb 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -2224,6 +2224,54 @@ GLFWAPI void glfwInitHint(int hint, int value); */ GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator); +#if defined(VK_VERSION_1_0) + +/*! @brief Sets the desired Vulkan `vkGetInstanceProcAddr` function. + * + * This function sets the `vkGetInstanceProcAddr` function that GLFW will use for all + * Vulkan related entry point queries. + * + * This feature is mostly useful on macOS, if your copy of the Vulkan loader is in + * a location where GLFW cannot find it through dynamic loading, or if you are still + * using the static library version of the loader. + * + * If set to `NULL`, GLFW will try to load the Vulkan loader dynamically by its standard + * name and get this function from there. This is the default behavior. + * + * The standard name of the loader is `vulkan-1.dll` on Windows, `libvulkan.so.1` on + * Linux and other Unix-like systems and `libvulkan.1.dylib` on macOS. If your code is + * also loading it via these names then you probably don't need to use this function. + * + * The function address you set is never reset by GLFW, but it only takes effect during + * initialization. Once GLFW has been initialized, any updates will be ignored until the + * library is terminated and initialized again. + * + * @param[in] loader The address of the function to use, or `NULL`. + * + * @par Loader function signature + * @code + * PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance instance, const char* name) + * @endcode + * For more information about this function, see the + * [Vulkan Registry](https://www.khronos.org/registry/vulkan/). + * + * @errors None. + * + * @remark This function may be called before @ref glfwInit. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref vulkan_loader + * @sa @ref glfwInit + * + * @since Added in version 3.4. + * + * @ingroup init + */ +GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader); + +#endif /*VK_VERSION_1_0*/ + /*! @brief Retrieves the version of the GLFW library. * * This function retrieves the major, minor and revision numbers of the GLFW diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0ab57255..a0be580e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -155,11 +155,6 @@ if (CMAKE_VERSION VERSION_LESS "3.16" AND APPLE) LANGUAGE C) endif() -if (GLFW_VULKAN_STATIC) - target_compile_definitions(glfw PRIVATE _GLFW_VULKAN_STATIC) - list(APPEND glfw_PKG_DEPS "vulkan") -endif() - if (GLFW_BUILD_WIN32) list(APPEND glfw_PKG_LIBS "-lgdi32") endif() diff --git a/src/init.c b/src/init.c index 65f5de31..c4c5e030 100644 --- a/src/init.c +++ b/src/init.c @@ -55,6 +55,7 @@ static _GLFWinitconfig _glfwInitHints = GLFW_TRUE, // hat buttons GLFW_ANGLE_PLATFORM_TYPE_NONE, // ANGLE backend GLFW_ANY_PLATFORM, // preferred platform + NULL, // vkGetInstanceProcAddr function { GLFW_TRUE, // macOS menu bar GLFW_TRUE // macOS bundle chdir @@ -404,6 +405,11 @@ GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator) memset(&_glfwInitAllocator, 0, sizeof(GLFWallocator)); } +GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader) +{ + _glfwInitHints.vulkanLoader = loader; +} + GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev) { if (major != NULL) diff --git a/src/internal.h b/src/internal.h index 1a38ba7e..c853ad9b 100644 --- a/src/internal.h +++ b/src/internal.h @@ -323,14 +323,9 @@ typedef struct VkExtensionProperties typedef void (APIENTRY * PFN_vkVoidFunction)(void); -#if defined(_GLFW_VULKAN_STATIC) - PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance,const char*); - VkResult vkEnumerateInstanceExtensionProperties(const char*,uint32_t*,VkExtensionProperties*); -#else - typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*); - typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*); - #define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr -#endif +typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*); +typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*); +#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr #include "platform.h" @@ -382,6 +377,7 @@ struct _GLFWinitconfig GLFWbool hatButtons; int angleType; int platformID; + PFN_vkGetInstanceProcAddr vulkanLoader; struct { GLFWbool menubar; GLFWbool chdir; @@ -853,9 +849,7 @@ struct _GLFWlibrary GLFWbool available; void* handle; char* extensions[2]; -#if !defined(_GLFW_VULKAN_STATIC) PFN_vkGetInstanceProcAddr GetInstanceProcAddr; -#endif GLFWbool KHR_surface; GLFWbool KHR_win32_surface; GLFWbool MVK_macos_surface; diff --git a/src/vulkan.c b/src/vulkan.c index b5ca25c0..2a64ecb4 100644 --- a/src/vulkan.c +++ b/src/vulkan.c @@ -51,35 +51,39 @@ GLFWbool _glfwInitVulkan(int mode) if (_glfw.vk.available) return GLFW_TRUE; -#if !defined(_GLFW_VULKAN_STATIC) + if (_glfw.hints.init.vulkanLoader) + _glfw.vk.GetInstanceProcAddr = _glfw.hints.init.vulkanLoader; + else + { #if defined(_GLFW_VULKAN_LIBRARY) - _glfw.vk.handle = _glfwPlatformLoadModule(_GLFW_VULKAN_LIBRARY); + _glfw.vk.handle = _glfwPlatformLoadModule(_GLFW_VULKAN_LIBRARY); #elif defined(_GLFW_WIN32) - _glfw.vk.handle = _glfwPlatformLoadModule("vulkan-1.dll"); + _glfw.vk.handle = _glfwPlatformLoadModule("vulkan-1.dll"); #elif defined(_GLFW_COCOA) - _glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.1.dylib"); - if (!_glfw.vk.handle) - _glfw.vk.handle = _glfwLoadLocalVulkanLoaderCocoa(); + _glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.1.dylib"); + if (!_glfw.vk.handle) + _glfw.vk.handle = _glfwLoadLocalVulkanLoaderCocoa(); #else - _glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so.1"); + _glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so.1"); #endif - if (!_glfw.vk.handle) - { - if (mode == _GLFW_REQUIRE_LOADER) - _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found"); + if (!_glfw.vk.handle) + { + if (mode == _GLFW_REQUIRE_LOADER) + _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found"); - return GLFW_FALSE; - } + return GLFW_FALSE; + } - _glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) - _glfwPlatformGetModuleSymbol(_glfw.vk.handle, "vkGetInstanceProcAddr"); - if (!_glfw.vk.GetInstanceProcAddr) - { - _glfwInputError(GLFW_API_UNAVAILABLE, - "Vulkan: Loader does not export vkGetInstanceProcAddr"); + _glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) + _glfwPlatformGetModuleSymbol(_glfw.vk.handle, "vkGetInstanceProcAddr"); + if (!_glfw.vk.GetInstanceProcAddr) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "Vulkan: Loader does not export vkGetInstanceProcAddr"); - _glfwTerminateVulkan(); - return GLFW_FALSE; + _glfwTerminateVulkan(); + return GLFW_FALSE; + } } vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) @@ -92,7 +96,6 @@ GLFWbool _glfwInitVulkan(int mode) _glfwTerminateVulkan(); return GLFW_FALSE; } -#endif // _GLFW_VULKAN_STATIC err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL); if (err) @@ -152,10 +155,8 @@ GLFWbool _glfwInitVulkan(int mode) void _glfwTerminateVulkan(void) { -#if !defined(_GLFW_VULKAN_STATIC) if (_glfw.vk.handle) _glfwPlatformFreeModule(_glfw.vk.handle); -#endif } const char* _glfwGetVulkanResultString(VkResult result) @@ -253,17 +254,16 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER)) return NULL; + // NOTE: Vulkan 1.0 and 1.1 vkGetInstanceProcAddr cannot return itself + if (strcmp(procname, "vkGetInstanceProcAddr") == 0) + return (GLFWvkproc) vkGetInstanceProcAddr; + proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname); -#if defined(_GLFW_VULKAN_STATIC) if (!proc) { - if (strcmp(procname, "vkGetInstanceProcAddr") == 0) - return (GLFWvkproc) vkGetInstanceProcAddr; + if (_glfw.vk.handle) + proc = (GLFWvkproc) _glfwPlatformGetModuleSymbol(_glfw.vk.handle, procname); } -#else - if (!proc) - proc = (GLFWvkproc) _glfwPlatformGetModuleSymbol(_glfw.vk.handle, procname); -#endif return proc; } From 2a78a2cf82a95e6d1f3bde0f33a6b8fb64b7be12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 25 Oct 2021 21:11:26 +0200 Subject: [PATCH 16/71] Refactor platform selection for clarity? --- src/platform.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/platform.c b/src/platform.c index 34fb7acd..a692432d 100644 --- a/src/platform.c +++ b/src/platform.c @@ -73,31 +73,34 @@ GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform) if (desiredID == GLFW_PLATFORM_NULL) return _glfwConnectNull(desiredID, platform); - // If there is only one platform available for auto-selection, let it emit the error - // on failure as the platform-specific error description may be more helpful - if (desiredID == GLFW_ANY_PLATFORM && count == 1) - return supportedPlatforms[0].connect(supportedPlatforms[0].ID, platform); - - for (i = 0; i < count; i++) + if (desiredID == GLFW_ANY_PLATFORM) { - if (desiredID == GLFW_ANY_PLATFORM || desiredID == supportedPlatforms[i].ID) + // If there is exactly one platform available for auto-selection, let it emit the + // error on failure as the platform-specific error description may be more helpful + if (count == 1) + return supportedPlatforms[0].connect(supportedPlatforms[0].ID, platform); + + for (i = 0; i < count; i++) { if (supportedPlatforms[i].connect(desiredID, platform)) return GLFW_TRUE; - else if (desiredID == supportedPlatforms[i].ID) - return GLFW_FALSE; } - } - if (desiredID == GLFW_ANY_PLATFORM) - { if (count) _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Failed to detect any supported platform"); else _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "This binary only supports the Null platform"); } else + { + for (i = 0; i < count; i++) + { + if (supportedPlatforms[i].ID == desiredID) + return supportedPlatforms[i].connect(desiredID, platform); + } + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "The requested platform is not supported"); + } return GLFW_FALSE; } From 575d2971d414ef9f7a47899f44664168537d26c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 25 Oct 2021 21:24:07 +0200 Subject: [PATCH 17/71] Fix glfwinfo not handling --platform=any --- tests/glfwinfo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index a76ca1c2..14347e4b 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -462,7 +462,9 @@ int main(int argc, char** argv) switch (ch) { case PLATFORM: - if (strcasecmp(optarg, PLATFORM_NAME_WIN32) == 0) + if (strcasecmp(optarg, PLATFORM_NAME_ANY) == 0) + platform = GLFW_ANY_PLATFORM; + else if (strcasecmp(optarg, PLATFORM_NAME_WIN32) == 0) platform = GLFW_PLATFORM_WIN32; else if (strcasecmp(optarg, PLATFORM_NAME_COCOA) == 0) platform = GLFW_PLATFORM_COCOA; From f75c251deccde745d3d3f313aa81955095369d6f Mon Sep 17 00:00:00 2001 From: Josh Codd Date: Tue, 26 Oct 2021 00:14:30 +0100 Subject: [PATCH 18/71] Cocoa: Fix deprecation of kIOMasterPortDefault This adds a workaround for kIOMasterPortDefault having been deprecated in favor of kIOMainPortDefault in macOS 12.0. Closes #1980 --- src/cocoa_monitor.m | 4 ++-- src/cocoa_platform.h | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 2109a7fe..89580bfa 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -58,7 +58,7 @@ static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen) io_service_t service; CFDictionaryRef info; - if (IOServiceGetMatchingServices(kIOMasterPortDefault, + if (IOServiceGetMatchingServices(kIOMainPortDefault, IOServiceMatching("IODisplayConnect"), &it) != 0) { @@ -231,7 +231,7 @@ static double getFallbackRefreshRate(CGDirectDisplayID displayID) io_iterator_t it; io_service_t service; - if (IOServiceGetMatchingServices(kIOMasterPortDefault, + if (IOServiceGetMatchingServices(kIOMainPortDefault, IOServiceMatching("IOFramebuffer"), &it) != 0) { diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 67c1a3cc..ed4ffc12 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -41,6 +41,13 @@ typedef void* id; #endif +// NOTE: Many Cocoa enum values have been renamed and we need to build across +// SDK versions where one is unavailable or the other deprecated +// We use the newer names in code and these macros to handle compatibility +#if MAC_OS_X_VERSION_MAX_ALLOWED < 120000 + #define kIOMainPortDefault kIOMasterPortDefault +#endif + // NOTE: Many Cocoa enum values have been renamed and we need to build across // SDK versions where one is unavailable or the other deprecated // We use the newer names in code and these macros to handle compatibility From 999962bd2f7e642a8f8ad94e643e53392945caa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 27 Oct 2021 23:14:19 +0200 Subject: [PATCH 19/71] Update changelog and add credit Related to #1980 --- CONTRIBUTORS.md | 1 + README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 84320b17..0fe9c8f7 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -34,6 +34,7 @@ video tutorials. - Michał Cichoń - Lambert Clara - Anna Clarke + - Josh Codd - Yaron Cohen-Tal - Omar Cornut - Andrew Corrigan diff --git a/README.md b/README.md index 6cfb59a5..b3c40688 100644 --- a/README.md +++ b/README.md @@ -229,6 +229,7 @@ information on what to include when reporting a bug. related events were emitted - [Cocoa] Bugfix: Moving the cursor programmatically would freeze it for a fraction of a second (#1962) + - [Cocoa] Bugfix: `kIOMasterPortDefault` was depreacted in macOS 12.0 (#1980) - [X11] Bugfix: The CMake files did not check for the XInput headers (#1480) - [X11] Bugfix: Key names were not updated when the keyboard layout changed (#1462,#1528) From 83d3fb08ec3d9048600b12bb6655973804dbb628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 27 Oct 2021 23:58:59 +0200 Subject: [PATCH 20/71] Fix some spelling errors in changelog --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b3c40688..a84f73ba 100644 --- a/README.md +++ b/README.md @@ -221,7 +221,7 @@ information on what to include when reporting a bug. could leak memory - [Cocoa] Bugfix: Objective-C files were compiled as C with CMake 3.19 (#1787) - [Cocoa] Bugfix: Duplicate video modes were not filtered out (#1830) - - [Cocoa] Bugfix: Menubar was not clickable on macOS 10.15+ until it lost and + - [Cocoa] Bugfix: Menu bar was not clickable on macOS 10.15+ until it lost and regained focus (#1648,#1802) - [Cocoa] Bugfix: Monitor name query could segfault on macOS 11 (#1809,#1833) - [Cocoa] Bugfix: The install name of the installed dylib was relative (#1504) @@ -229,7 +229,7 @@ information on what to include when reporting a bug. related events were emitted - [Cocoa] Bugfix: Moving the cursor programmatically would freeze it for a fraction of a second (#1962) - - [Cocoa] Bugfix: `kIOMasterPortDefault` was depreacted in macOS 12.0 (#1980) + - [Cocoa] Bugfix: `kIOMasterPortDefault` was deprecated in macOS 12.0 (#1980) - [X11] Bugfix: The CMake files did not check for the XInput headers (#1480) - [X11] Bugfix: Key names were not updated when the keyboard layout changed (#1462,#1528) @@ -252,7 +252,7 @@ information on what to include when reporting a bug. - [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) + combinations (#1598) - [X11] Bugfix: Keys pressed simultaneously with others were not always reported (#1112,#1415,#1472,#1616) - [X11] Bugfix: Some window attributes were not applied on leaving fullscreen @@ -266,7 +266,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Retrieving partial framebuffer size would segfault - [Wayland] Bugfix: Scrolling offsets were inverted compared to other platforms (#1463) - - [Wayland] Bugfix: Client-Side Decorations were destroyed in the wrong worder + - [Wayland] Bugfix: Client-Side Decorations were destroyed in the wrong order (#1798) - [Wayland] Bugfix: Monitors physical size could report zero (#1784,#1792) - [Wayland] Bugfix: Some keys were not repeating in Wayland (#1908) From fb0f2f92a38c1d6a776ffeb253329f8d1c65694c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 28 Oct 2021 11:48:34 +0200 Subject: [PATCH 21/71] Add missing changelog entries --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a84f73ba..d9257e58 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,7 @@ information on what to include when reporting a bug. - Made joystick subsystem initialize at first use (#1284,#1646) - Made `GLFW_DOUBLEBUFFER` a read-only window attribute - Updated the minimum required CMake version to 3.1 + - Updated gamepad mappings from upstream - Disabled tests and examples by default when built as a CMake subdirectory - Renamed `GLFW_USE_WAYLAND` CMake option to `GLFW_BUILD_WAYLAND` (#1958) - Removed `GLFW_USE_OSMESA` CMake option enabling the Null platform (#1958) @@ -271,6 +272,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Monitors physical size could report zero (#1784,#1792) - [Wayland] Bugfix: Some keys were not repeating in Wayland (#1908) - [Wayland] Bugfix: Non-arrow cursors are offset from the hotspot (#1706,#1899) + - [Wayland] Bugfix: The `O_CLOEXEC` flag was not defined on FreeBSD - [POSIX] Removed use of deprecated function `gettimeofday` - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled - [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072) From 544790666bb2a9a2dcd3ee6dc8c45716207e65d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ekstr=C3=B6m?= Date: Thu, 18 Nov 2021 22:59:52 +0200 Subject: [PATCH 22/71] Cocoa: Use MACH_PORT_NULL for default IOKit port Looking into the definition of kIOMainPortDefault, the following description can be found: When specifying a main port to IOKit functions, the NULL argument indicates "use the default". This is a synonym for NULL, if you'd rather use a named constant. Thus, we do not have to utilize an external symbol for the identifier of the default main IOKit port, but MACH_PORT_NULL suffice. This simplifies compatibility between macOS versions as the symbol was renamed with macOS 12.0. Fixes #1985 Closes #1994 --- src/cocoa_monitor.m | 4 ++-- src/cocoa_platform.h | 7 ------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 89580bfa..70c75aa3 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -58,7 +58,7 @@ static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen) io_service_t service; CFDictionaryRef info; - if (IOServiceGetMatchingServices(kIOMainPortDefault, + if (IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching("IODisplayConnect"), &it) != 0) { @@ -231,7 +231,7 @@ static double getFallbackRefreshRate(CGDirectDisplayID displayID) io_iterator_t it; io_service_t service; - if (IOServiceGetMatchingServices(kIOMainPortDefault, + if (IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching("IOFramebuffer"), &it) != 0) { diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index ed4ffc12..67c1a3cc 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -41,13 +41,6 @@ typedef void* id; #endif -// NOTE: Many Cocoa enum values have been renamed and we need to build across -// SDK versions where one is unavailable or the other deprecated -// We use the newer names in code and these macros to handle compatibility -#if MAC_OS_X_VERSION_MAX_ALLOWED < 120000 - #define kIOMainPortDefault kIOMasterPortDefault -#endif - // NOTE: Many Cocoa enum values have been renamed and we need to build across // SDK versions where one is unavailable or the other deprecated // We use the newer names in code and these macros to handle compatibility From b55a517ae0c7b5127dffa79a64f5406021bf9076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 22 Nov 2021 21:32:34 +0100 Subject: [PATCH 23/71] Add credit Related to #1994 --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 0fe9c8f7..4190b261 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -53,6 +53,7 @@ video tutorials. - Ralph Eastwood - Fredrik Ehnbom - Robin Eklind + - Jan Ekström - Siavash Eliasi - Ahmad Fatoum - Felipe Ferreira From bb193325cc4e5af7d4e715072a242c1d3cfce26e Mon Sep 17 00:00:00 2001 From: InKryption <59504965+InKryption@users.noreply.github.com> Date: Mon, 22 Nov 2021 23:32:29 +0000 Subject: [PATCH 24/71] Add missing error to glfwGetClipboardString docs Add GLFW_FORMAT_UNAVAILABLE to the list of possible errors in the reference documentation for glfwGetClipboardString. Slightly edited by @elmindreda. Closes #1998 --- include/GLFW/glfw3.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 751615eb..a1fa6f35 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -5792,8 +5792,8 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL` * if an [error](@ref error_handling) occurred. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_FORMAT_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the next call to @ref From a30cd6acef49a4527546fe15d490b705df959c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 25 Nov 2021 01:22:46 +0100 Subject: [PATCH 25/71] Add credit Related to #1998 --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 4190b261..d309e435 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -77,6 +77,7 @@ video tutorials. - Paul Holden - Warren Hu - Charles Huber + - InKryption - IntellectualKitty - Aaron Jacobs - Erik S. V. Jansson From eacc1cafba90fa7b52302841dd47f5f8b1bf777a Mon Sep 17 00:00:00 2001 From: luz paz Date: Thu, 28 Oct 2021 14:35:09 -0400 Subject: [PATCH 26/71] Fix source comment typo Closes #1982 --- examples/splitview.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/splitview.c b/examples/splitview.c index 4f0a8a98..990df12c 100644 --- a/examples/splitview.c +++ b/examples/splitview.c @@ -2,7 +2,7 @@ // This is an example program for the GLFW library // // The program uses a "split window" view, rendering four views of the -// same scene in one window (e.g. uesful for 3D modelling software). This +// same scene in one window (e.g. useful for 3D modelling software). This // demo uses scissors to separate the four different rendering areas from // each other. // From b3a98f855568b1a4f3961cfa30cb7a201fb91a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 9 Nov 2021 19:40:36 +0100 Subject: [PATCH 27/71] Update comments for global mutable data --- src/init.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/init.c b/src/init.c index c4c5e030..b5c5da9c 100644 --- a/src/init.c +++ b/src/init.c @@ -36,16 +36,15 @@ #include -// The global variables below comprise all mutable global data in GLFW -// -// Any other global variable is a bug +// NOTE: The global variables below comprise all mutable global data in GLFW +// Any other mutable global variable is a bug -// Global state shared between compilation units of GLFW +// This contains all mutable state shared between compilation units of GLFW // _GLFWlibrary _glfw = { GLFW_FALSE }; // These are outside of _glfw so they can be used before initialization and -// after termination +// after termination without special handling when _glfw is cleared to zero // static _GLFWerror _glfwMainThreadError; static GLFWerrorfun _glfwErrorCallback; From 706d1f16535747e7889df26f3d639e9212e9ad5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 16 Nov 2021 01:51:27 +0100 Subject: [PATCH 28/71] Gather Null specific platform selection logic The more specific error description is now used whatever the desired platform is, when a binary only supports the Null platform. --- src/platform.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/platform.c b/src/platform.c index a692432d..d0bbd06d 100644 --- a/src/platform.c +++ b/src/platform.c @@ -72,6 +72,11 @@ GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform) // Only allow the Null platform if specifically requested if (desiredID == GLFW_PLATFORM_NULL) return _glfwConnectNull(desiredID, platform); + else if (count == 0) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "This binary only supports the Null platform"); + return GLFW_FALSE; + } if (desiredID == GLFW_ANY_PLATFORM) { @@ -86,10 +91,7 @@ GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform) return GLFW_TRUE; } - if (count) - _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Failed to detect any supported platform"); - else - _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "This binary only supports the Null platform"); + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Failed to detect any supported platform"); } else { From 37fc28bff6cad7164aa67e828e9317596f8080da Mon Sep 17 00:00:00 2001 From: Stephen Gutekanst Date: Mon, 15 Nov 2021 15:50:37 -0700 Subject: [PATCH 29/71] Fix docs calling GLFW_CONTEXT_REVISION a hint This docstring previously indicated that GLFW_CONTEXT_REVISION was a window hint and attribute, but in fact it is only a window attribute (there is no code which uses this constant in any other context.) We noticed this in https://github.com/hexops/mach/pull/71/files#r749741814 Closes #1992 Signed-off-by: Stephen Gutekanst --- include/GLFW/glfw3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index a1fa6f35..d76f5c49 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1028,7 +1028,7 @@ extern "C" { * and [attribute](@ref GLFW_CONTEXT_VERSION_MINOR_attrib). */ #define GLFW_CONTEXT_VERSION_MINOR 0x00022003 -/*! @brief Context client API revision number hint and attribute. +/*! @brief Context client API revision number attribute. * * Context client API revision number * [attribute](@ref GLFW_CONTEXT_REVISION_attrib). From 9cd4d2fa204fc9fb884b9bb9096cedb7f1484cf7 Mon Sep 17 00:00:00 2001 From: Stephen Gutekanst Date: Sun, 31 Oct 2021 11:22:40 -0700 Subject: [PATCH 30/71] X11: Fix undefined behavior in glfwSetWindowIcon The conversion of window icon image data involves unsigned char color values being promoted to int and then shifted to the left by 24. For 32-bit ints this is just far enough to trigger undefined behavior. It worked by accident because of how current compilers translate this piece of code. This was caught by @slimsag while working on [Zig bindings for GLFW][1], and diagnosed together with @Andoryuuta, as described [in an article][2]. Zig has UBSan enabled by default, which caught this undefined behavior. [1]: https://github.com/hexops/mach-glfw [2]: https://devlog.hexops.com/2021/perfecting-glfw-for-zig-and-finding-undefined-behavior#finding-lurking-undefined-behavior-in-6-year-old-glfw-code Thanks to Maato, martinhath, dcousens, drfuchs and Validark for helping to refine the solution. This commit message was rewritten by @elmindreda to hopefully reflect the conclusions of the pull request thread. Related to hexops/mach#20 Closes #1986 --- src/x11_window.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/x11_window.c b/src/x11_window.c index 616f9fd8..ea775cd4 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -2105,8 +2105,8 @@ void _glfwSetWindowIconX11(_GLFWwindow* window, int count, const GLFWimage* imag for (int i = 0; i < count; i++) longCount += 2 + images[i].width * images[i].height; - long* icon = _glfw_calloc(longCount, sizeof(long)); - long* target = icon; + unsigned long* icon = _glfw_calloc(longCount, sizeof(unsigned long)); + unsigned long* target = icon; for (int i = 0; i < count; i++) { @@ -2115,13 +2115,20 @@ void _glfwSetWindowIconX11(_GLFWwindow* window, int count, const GLFWimage* imag for (int j = 0; j < images[i].width * images[i].height; j++) { - *target++ = (images[i].pixels[j * 4 + 0] << 16) | - (images[i].pixels[j * 4 + 1] << 8) | - (images[i].pixels[j * 4 + 2] << 0) | - (images[i].pixels[j * 4 + 3] << 24); + *target++ = (((unsigned long)images[i].pixels[j * 4 + 0]) << 16) | + (((unsigned long)images[i].pixels[j * 4 + 1]) << 8) | + (((unsigned long)images[i].pixels[j * 4 + 2]) << 0) | + (((unsigned long)images[i].pixels[j * 4 + 3]) << 24); } } + // Important: Despite XChangeProperty docs indicating that `icon` (unsigned char*) would be + // in the format of the icon image, e.g. 32-bit below, the function actually casts the ptr + // (unsigned char*) internally to (long*) and then if long is defined as 64-bits, as on IL64 + // platforms, extracts only 32 bits from the long leaving the other 32 unused. That is, on a + // 64-bit platform XChangeProperty expects 64-bit integers representing 32-bit pixels. + // + // See https://github.com/glfw/glfw/pull/1986#issuecomment-962445299 XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.NET_WM_ICON, XA_CARDINAL, 32, From e40fa3bb94a9277d7190ec49e197de663eb943bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 2 Nov 2021 23:15:05 +0100 Subject: [PATCH 31/71] Add credits and update changelog --- CONTRIBUTORS.md | 2 ++ README.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index d309e435..959b55eb 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -68,6 +68,8 @@ video tutorials. - Kovid Goyal - Eloi Marín Gratacós - Stefan Gustavson + - Andrew Gutekanst + - Stephen Gutekanst - Jonathan Hale - hdf89shfdfs - Sylvain Hellegouarch diff --git a/README.md b/README.md index d9257e58..b13739f1 100644 --- a/README.md +++ b/README.md @@ -259,6 +259,8 @@ information on what to include when reporting a bug. - [X11] Bugfix: Some window attributes were not applied on leaving fullscreen (#1863) - [X11] Bugfix: Changing `GLFW_FLOATING` could leak memory + - [X11] Bugfix: Icon pixel format conversion worked only by accident, relying on + undefined behavior (#1986) - [Wayland] Added dynamic loading of all Wayland libraries - [Wayland] Removed support for `wl_shell` (#1443) - [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432) From 79de08db06d358c4aae243532d2e530e62780687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 30 Nov 2021 20:34:47 +0100 Subject: [PATCH 32/71] Cleanup --- src/x11_window.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/x11_window.c b/src/x11_window.c index ea775cd4..a5255215 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -2115,20 +2115,19 @@ void _glfwSetWindowIconX11(_GLFWwindow* window, int count, const GLFWimage* imag for (int j = 0; j < images[i].width * images[i].height; j++) { - *target++ = (((unsigned long)images[i].pixels[j * 4 + 0]) << 16) | - (((unsigned long)images[i].pixels[j * 4 + 1]) << 8) | - (((unsigned long)images[i].pixels[j * 4 + 2]) << 0) | - (((unsigned long)images[i].pixels[j * 4 + 3]) << 24); + *target++ = (((unsigned long) images[i].pixels[j * 4 + 0]) << 16) | + (((unsigned long) images[i].pixels[j * 4 + 1]) << 8) | + (((unsigned long) images[i].pixels[j * 4 + 2]) << 0) | + (((unsigned long) images[i].pixels[j * 4 + 3]) << 24); } } - // Important: Despite XChangeProperty docs indicating that `icon` (unsigned char*) would be - // in the format of the icon image, e.g. 32-bit below, the function actually casts the ptr - // (unsigned char*) internally to (long*) and then if long is defined as 64-bits, as on IL64 - // platforms, extracts only 32 bits from the long leaving the other 32 unused. That is, on a - // 64-bit platform XChangeProperty expects 64-bit integers representing 32-bit pixels. - // - // See https://github.com/glfw/glfw/pull/1986#issuecomment-962445299 + // NOTE: XChangeProperty expects 32-bit values like the image data above to be + // placed in the 32 least significant bits of individual longs. This is + // true even if long is 64-bit and a WM protocol calls for "packed" data. + // This is because of a historical mistake that then became part of the Xlib + // ABI. Xlib will pack these values into a regular array of 32-bit values + // before sending it over the wire. XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.NET_WM_ICON, XA_CARDINAL, 32, From d1efa3298345a36a969f1fbbb2272d97ad5354af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 30 Nov 2021 21:14:44 +0100 Subject: [PATCH 33/71] Formatting --- src/win32_window.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index ae7710a2..9fb0baa1 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1645,8 +1645,7 @@ void _glfwGetWindowFrameSizeWin32(_GLFWwindow* window, *bottom = rect.bottom - height; } -void _glfwGetWindowContentScaleWin32(_GLFWwindow* window, - float* xscale, float* yscale) +void _glfwGetWindowContentScaleWin32(_GLFWwindow* window, float* xscale, float* yscale) { const HANDLE handle = MonitorFromWindow(window->win32.handle, MONITOR_DEFAULTTONEAREST); From fbfd7e65c842c7909b11747f0641364593304f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 1 Dec 2021 17:55:16 +0100 Subject: [PATCH 34/71] Win32: Fix bad content scale on monitor disconnect The monitor handle could have become invalid just before the call to GetDpiForMonitor. It was possible for both window and monitor content scale queries. This ensures both that an appropriate error is emitted and that the retrieved values are zero on error. Fixes #1615 --- CONTRIBUTORS.md | 1 + README.md | 3 +++ src/win32_monitor.c | 13 ++++++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 959b55eb..d86fe473 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -62,6 +62,7 @@ video tutorials. - Mário Freitas - GeO4d - Marcus Geelnard + - ghuser404 - Charles Giessen - Ryan C. Gordon - Stephen Gowen diff --git a/README.md b/README.md index b13739f1..e3f7d9e7 100644 --- a/README.md +++ b/README.md @@ -202,6 +202,9 @@ information on what to include when reporting a bug. later (#1783,#1796) - [Win32] Bugfix: Compilation with LLVM for Windows failed (#1807,#1824,#1874) - [Win32] Bugfix: The foreground lock timeout was overridden, ignoring the user + - [Win32] Bugfix: Content scale queries could fail silently (#1615) + - [Win32] Bugfix: Content scales could have garbage values if monitor was recently + disconnected (#1615) - [Cocoa] Added support for `VK_EXT_metal_surface` (#1619) - [Cocoa] Added locating the Vulkan loader at runtime in an application bundle - [Cocoa] Moved main menu creation to GLFW initialization time (#1649) diff --git a/src/win32_monitor.c b/src/win32_monitor.c index 17359a5f..cdee49a9 100644 --- a/src/win32_monitor.c +++ b/src/win32_monitor.c @@ -317,8 +317,19 @@ void _glfwGetHMONITORContentScaleWin32(HMONITOR handle, float* xscale, float* ys { UINT xdpi, ydpi; + if (xscale) + *xscale = 0.f; + if (yscale) + *yscale = 0.f; + if (IsWindows8Point1OrGreater()) - GetDpiForMonitor(handle, MDT_EFFECTIVE_DPI, &xdpi, &ydpi); + { + if (GetDpiForMonitor(handle, MDT_EFFECTIVE_DPI, &xdpi, &ydpi) != S_OK) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to query monitor DPI"); + return; + } + } else { const HDC dc = GetDC(NULL); From 53d86c64d709ff52886580d338d9b3b2b1f27266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 1 Dec 2021 18:09:56 +0100 Subject: [PATCH 35/71] Win32: Handle content scale error on creation Only apply the content scale to the initial size of the window if content scale retrieval succeeded. Related to #1615. --- src/win32_window.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index 9fb0baa1..e03b8564 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1304,8 +1304,12 @@ static int createNativeWindow(_GLFWwindow* window, { float xscale, yscale; _glfwGetWindowContentScaleWin32(window, &xscale, &yscale); - rect.right = (int) (rect.right * xscale); - rect.bottom = (int) (rect.bottom * yscale); + + if (xscale > 0.f && yscale > 0.f) + { + rect.right = (int) (rect.right * xscale); + rect.bottom = (int) (rect.bottom * yscale); + } } ClientToScreen(window->win32.handle, (POINT*) &rect.left); From c19f36b28d255d280d39446f09f36f441318138e Mon Sep 17 00:00:00 2001 From: InKryption <59504965+InKryption@users.noreply.github.com> Date: Sun, 5 Dec 2021 17:51:43 +0100 Subject: [PATCH 36/71] Add missing errors section for glfwGetGamepadName The reference documentation for glfwGetGamepadName lacked the possible errors section. Closes #2007 --- include/GLFW/glfw3.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index d76f5c49..f0b8d5ec 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -5703,6 +5703,8 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string); * joystick is not present, does not have a mapping or an * [error](@ref error_handling) occurred. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref GLFW_INVALID_ENUM. + * * @pointer_lifetime The returned string is allocated and freed by GLFW. You * should not free it yourself. It is valid until the specified joystick is * disconnected, the gamepad mappings are updated or the library is terminated. From cd01187b9d4145a3947f806f113bc777c3aa4c1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 8 Dec 2021 23:09:59 +0100 Subject: [PATCH 37/71] Fix initial windowed mode size for test --- tests/iconify.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/iconify.c b/tests/iconify.c index e5a428a0..32fd44f2 100644 --- a/tests/iconify.c +++ b/tests/iconify.c @@ -38,7 +38,7 @@ #include "getopt.h" -static int windowed_xpos, windowed_ypos, windowed_width, windowed_height; +static int windowed_xpos, windowed_ypos, windowed_width = 640, windowed_height = 480; static void usage(void) { @@ -181,8 +181,8 @@ static GLFWwindow* create_window(GLFWmonitor* monitor) } else { - width = 640; - height = 480; + width = windowed_width; + height = windowed_height; } window = glfwCreateWindow(width, height, "Iconify", monitor, NULL); From 900848ad0ce0c94a5d4cb8e0ac2489ff11973477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 9 Dec 2021 19:35:15 +0100 Subject: [PATCH 38/71] X11: Add extension header paths to CMake target The way the X11 find module is written, these paths can differ from the base X11 header path, even if they very rarely do. Fixes #1999 --- src/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a0be580e..16cb1749 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -194,31 +194,37 @@ if (GLFW_BUILD_X11) if (NOT X11_Xrandr_INCLUDE_PATH) message(FATAL_ERROR "RandR headers not found; install libxrandr development package") endif() + target_include_directories(glfw PRIVATE "${X11_Xrandr_INCLUDE_PATH}") # Check for Xinerama (legacy multi-monitor support) if (NOT X11_Xinerama_INCLUDE_PATH) message(FATAL_ERROR "Xinerama headers not found; install libxinerama development package") endif() + target_include_directories(glfw PRIVATE "${X11_Xinerama_INCLUDE_PATH}") # Check for Xkb (X keyboard extension) if (NOT X11_Xkb_INCLUDE_PATH) message(FATAL_ERROR "XKB headers not found; install X11 development package") endif() + target_include_directories(glfw PRIVATE "${X11_Xkb_INCLUDE_PATH}") # Check for Xcursor (cursor creation from RGBA images) if (NOT X11_Xcursor_INCLUDE_PATH) message(FATAL_ERROR "Xcursor headers not found; install libxcursor development package") endif() + target_include_directories(glfw PRIVATE "${X11_Xcursor_INCLUDE_PATH}") # Check for XInput (modern HID input) if (NOT X11_Xi_INCLUDE_PATH) message(FATAL_ERROR "XInput headers not found; install libxi development package") endif() + target_include_directories(glfw PRIVATE "${X11_Xi_INCLUDE_PATH}") # Check for X Shape (custom window input shape) if (NOT X11_Xshape_INCLUDE_PATH) message(FATAL_ERROR "X Shape headers not found; install libxext development package") endif() + target_include_directories(glfw PRIVATE "${X11_Xshape_INCLUDE_PATH}") endif() if (UNIX AND NOT APPLE) From 963e728881d7551aab0b843c79915f2419d4d36e Mon Sep 17 00:00:00 2001 From: Stone Tickle Date: Fri, 5 Jun 2020 12:51:25 +0900 Subject: [PATCH 39/71] Wayland: Set O_NONBLOCK on repeat timerfd Fixes #1710 Fixes #1711 --- src/wl_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index acfe477d..bba908fa 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -1336,7 +1336,7 @@ int _glfwInitWayland(void) _glfw.wl.timerfd = -1; if (_glfw.wl.seatVersion >= 4) - _glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); + _glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); if (!_glfw.wl.wmBase) { @@ -1370,7 +1370,7 @@ int _glfwInitWayland(void) wl_cursor_theme_load(cursorTheme, 2 * cursorSize, _glfw.wl.shm); _glfw.wl.cursorSurface = wl_compositor_create_surface(_glfw.wl.compositor); - _glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); + _glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); } if (_glfw.wl.seat && _glfw.wl.dataDeviceManager) From 68879081cb39f50bd65d12e0f1869f5970dc71b9 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Tue, 14 Dec 2021 09:29:01 +0100 Subject: [PATCH 40/71] =?UTF-8?q?Wayland:=20Continue=20poll()=20if=20timer?= =?UTF-8?q?fd=20can=E2=80=99t=20be=20read?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the case the key repeat timerfd was interrupted before read(), the cursor timerfd wasn’t read at all even when it could. Related to #1711 --- README.md | 1 + src/wl_window.c | 11 +++-------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index e3f7d9e7..57c43a4b 100644 --- a/README.md +++ b/README.md @@ -278,6 +278,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Some keys were not repeating in Wayland (#1908) - [Wayland] Bugfix: Non-arrow cursors are offset from the hotspot (#1706,#1899) - [Wayland] Bugfix: The `O_CLOEXEC` flag was not defined on FreeBSD + - [Wayland] Bugfix: Key repeat could lead to a race condition (#1710) - [POSIX] Removed use of deprecated function `gettimeofday` - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled - [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072) diff --git a/src/wl_window.c b/src/wl_window.c index b4c59d69..8ed803b4 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -751,10 +751,7 @@ static void handleEvents(int timeout) if (fds[1].revents & POLLIN) { read_ret = read(_glfw.wl.timerfd, &repeats, sizeof(repeats)); - if (read_ret != 8) - return; - - if (_glfw.wl.keyboardFocus) + if (read_ret == 8 && _glfw.wl.keyboardFocus) { for (uint64_t i = 0; i < repeats; ++i) { @@ -770,10 +767,8 @@ static void handleEvents(int timeout) if (fds[2].revents & POLLIN) { read_ret = read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)); - if (read_ret != 8) - return; - - incrementCursorImage(_glfw.wl.pointerFocus); + if (read_ret == 8) + incrementCursorImage(_glfw.wl.pointerFocus); } } else From 6281f498c875f49d8ac5c5a02d968fb1792fd9f5 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Tue, 14 Dec 2021 18:35:30 +0100 Subject: [PATCH 41/71] EGL: Use EGL_EXT_present_opaque when available This extensions allows GLFW to instruct the driver to ignore the alpha bits, even in formats which contain them. This makes it possible to use the alpha bits as extra storage, without it affecting the end result getting displayed to the user. Fixes #1434 Fixes #1803 --- src/egl_context.c | 5 +++++ src/internal.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/egl_context.c b/src/egl_context.c index 03c72d04..edb2fae2 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -472,6 +472,8 @@ GLFWbool _glfwInitEGL(void) extensionSupportedEGL("EGL_KHR_get_all_proc_addresses"); _glfw.egl.KHR_context_flush_control = extensionSupportedEGL("EGL_KHR_context_flush_control"); + _glfw.egl.EXT_present_opaque = + extensionSupportedEGL("EGL_EXT_present_opaque"); return GLFW_TRUE; } @@ -646,6 +648,9 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, if (!fbconfig->doublebuffer) setAttrib(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER); + if (_glfw.egl.EXT_present_opaque) + setAttrib(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent); + setAttrib(EGL_NONE, EGL_NONE); native = _glfw.platform.getEGLNativeWindow(window); diff --git a/src/internal.h b/src/internal.h index c853ad9b..2a8c8d6d 100644 --- a/src/internal.h +++ b/src/internal.h @@ -177,6 +177,7 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint); #define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098 #define EGL_PLATFORM_X11_EXT 0x31d5 #define EGL_PLATFORM_WAYLAND_EXT 0x31d8 +#define EGL_PRESENT_OPAQUE_EXT 0x31df #define EGL_PLATFORM_ANGLE_ANGLE 0x3202 #define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203 #define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320d @@ -803,6 +804,7 @@ struct _GLFWlibrary GLFWbool EXT_platform_base; GLFWbool EXT_platform_x11; GLFWbool EXT_platform_wayland; + GLFWbool EXT_present_opaque; GLFWbool ANGLE_platform_angle; GLFWbool ANGLE_platform_angle_opengl; GLFWbool ANGLE_platform_angle_d3d; From c2f0a0ae5990a23d84c3f4529771b1268a34f918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 22 Dec 2021 14:16:19 +0100 Subject: [PATCH 42/71] Wayland: Fix duplicate focus event on activation --- README.md | 1 + src/wl_window.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 57c43a4b..4a0faf35 100644 --- a/README.md +++ b/README.md @@ -279,6 +279,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Non-arrow cursors are offset from the hotspot (#1706,#1899) - [Wayland] Bugfix: The `O_CLOEXEC` flag was not defined on FreeBSD - [Wayland] Bugfix: Key repeat could lead to a race condition (#1710) + - [Wayland] Bugfix: Activating a window would emit two input focus events - [POSIX] Removed use of deprecated function `gettimeofday` - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled - [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072) diff --git a/src/wl_window.c b/src/wl_window.c index 8ed803b4..12af2701 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -537,7 +537,6 @@ static void xdgToplevelHandleConfigure(void* data, } if (fullscreen && activated) window->wl.wasFullscreen = GLFW_TRUE; - _glfwInputWindowFocus(window, activated); } static void xdgToplevelHandleClose(void* data, From e24fe4b189d2cf99e0374992e7fc6650f4c6cf01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 22 Dec 2021 14:19:55 +0100 Subject: [PATCH 43/71] Wayland: Fix key repeat continuing when refocused If a window lost input focus while a key was held down, the key repeat mechanism would resume once the window regained focus. --- README.md | 1 + src/wl_init.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 4a0faf35..2f505c00 100644 --- a/README.md +++ b/README.md @@ -280,6 +280,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: The `O_CLOEXEC` flag was not defined on FreeBSD - [Wayland] Bugfix: Key repeat could lead to a race condition (#1710) - [Wayland] Bugfix: Activating a window would emit two input focus events + - [Wayland] Bugfix: Disable key repeat mechanism when window loses input focus - [POSIX] Removed use of deprecated function `gettimeofday` - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled - [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072) diff --git a/src/wl_init.c b/src/wl_init.c index bba908fa..fd6efaa8 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -508,6 +508,9 @@ static void keyboardHandleLeave(void* data, _glfw.wl.serial = serial; _glfw.wl.keyboardFocus = NULL; _glfwInputWindowFocus(window, GLFW_FALSE); + + struct itimerspec timer = {}; + timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); } static int toGLFWKeyCode(uint32_t key) From 094aa6d3c721397825cb1095c156353463ecafb5 Mon Sep 17 00:00:00 2001 From: Jason Francis Date: Sun, 12 Jul 2020 20:47:50 -0400 Subject: [PATCH 44/71] Wayland: Fix window hiding Corrects the protocol violation when creating an xdg_surface from a wl_surface that already has a buffer due to EGL buffer swaps. This commit is based on PR #1731 by @ghost, but adapted and altered: - The XDG surface and role are now only created when a window is shown to prevent application lists from showing command-line applications with off-screen-only windows - The special case of Wayland+EGL buffer swap is now in the EGL code to mirror how X11 is handled - Adaption to run-time platform selection and separate credits file Fixes #1492 Closes #1731 --- CONTRIBUTORS.md | 1 + README.md | 1 + src/egl_context.c | 9 +++++++++ src/wl_window.c | 30 +++++++++--------------------- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index d86fe473..1bfc5bc5 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -58,6 +58,7 @@ video tutorials. - Ahmad Fatoum - Felipe Ferreira - Michael Fogleman + - Jason Francis - Gerald Franz - Mário Freitas - GeO4d diff --git a/README.md b/README.md index 2f505c00..63e9f6bd 100644 --- a/README.md +++ b/README.md @@ -281,6 +281,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Key repeat could lead to a race condition (#1710) - [Wayland] Bugfix: Activating a window would emit two input focus events - [Wayland] Bugfix: Disable key repeat mechanism when window loses input focus + - [Wayland] Bugfix: Window hiding and showing did not work (#1492,#1731) - [POSIX] Removed use of deprecated function `gettimeofday` - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled - [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072) diff --git a/src/egl_context.c b/src/egl_context.c index edb2fae2..319da273 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -231,6 +231,15 @@ static void swapBuffersEGL(_GLFWwindow* window) return; } +#if defined(_GLFW_WAYLAND) + if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND) + { + // NOTE: Swapping buffers on a hidden window on Wayland makes it visible + if (!window->wl.visible) + return; + } +#endif + eglSwapBuffers(_glfw.egl.display, window->context.egl.surface); } diff --git a/src/wl_window.c b/src/wl_window.c index 12af2701..10d0e25f 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -812,20 +812,6 @@ int _glfwCreateWindowWayland(_GLFWwindow* window, if (wndconfig->title) window->wl.title = _glfw_strdup(wndconfig->title); - if (wndconfig->visible) - { - if (!createXdgSurface(window)) - return GLFW_FALSE; - - window->wl.visible = GLFW_TRUE; - } - else - { - window->wl.xdg.surface = NULL; - window->wl.xdg.toplevel = NULL; - window->wl.visible = GLFW_FALSE; - } - window->wl.currentCursor = NULL; window->wl.monitors = _glfw_calloc(1, sizeof(_GLFWmonitor*)); @@ -1018,21 +1004,23 @@ void _glfwShowWindowWayland(_GLFWwindow* window) { if (!window->wl.visible) { - createXdgSurface(window); + // NOTE: The XDG surface and role are created here so command-line applications + // with off-screen windows do not appear in for example the Unity dock + if (!window->wl.xdg.toplevel) + createXdgSurface(window); + window->wl.visible = GLFW_TRUE; } } void _glfwHideWindowWayland(_GLFWwindow* window) { - if (window->wl.xdg.toplevel) + if (window->wl.visible) { - xdg_toplevel_destroy(window->wl.xdg.toplevel); - xdg_surface_destroy(window->wl.xdg.surface); - window->wl.xdg.toplevel = NULL; - window->wl.xdg.surface = NULL; + window->wl.visible = GLFW_FALSE; + wl_surface_attach(window->wl.surface, NULL, 0, 0); + wl_surface_commit(window->wl.surface); } - window->wl.visible = GLFW_FALSE; } void _glfwRequestWindowAttentionWayland(_GLFWwindow* window) From f8ef3ca719eba800232eff30f08885d69c564e86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 22 Dec 2021 18:52:30 +0100 Subject: [PATCH 45/71] Add hiding and showing to interactive window test --- tests/window.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/window.c b/tests/window.c index 3e2bc671..83baff46 100644 --- a/tests/window.c +++ b/tests/window.c @@ -121,7 +121,7 @@ int main(int argc, char** argv) nk_glfw3_new_frame(); if (nk_begin(nk, "main", area, 0)) { - nk_layout_row_dynamic(nk, 30, 4); + nk_layout_row_dynamic(nk, 30, 5); if (nk_button_label(nk, "Toggle Fullscreen")) { @@ -149,6 +149,16 @@ int main(int argc, char** argv) glfwIconifyWindow(window); if (nk_button_label(nk, "Restore")) glfwRestoreWindow(window); + if (nk_button_label(nk, "Hide (briefly)")) + { + glfwHideWindow(window); + + const double time = glfwGetTime() + 3.0; + while (glfwGetTime() < time) + glfwWaitEventsTimeout(1.0); + + glfwShowWindow(window); + } nk_layout_row_dynamic(nk, 30, 1); From 7d060ba4f1237c87ed53e007db619da8c25df282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 22 Dec 2021 22:19:25 +0100 Subject: [PATCH 46/71] X11: Fix sonames for loaded libraries on OpenBSD The OpenBSD ports tree assigns its own soname version numbers, so the hardcoded sonames GLFW uses to load libraries on non-macOS Unices are often incorrect. Instead OpenBSD recommends that run-time loading should leave out the version numbers entirely. The OpenBSD ld.so then finds the correct library. This upstreams the ports tree fixes for Xcursor and EGL, and adds the corresponding fix for all other run-time loaded library sonames. Tested on OpenBSD 7.0. This issue was initially reported on IRC. --- README.md | 1 + src/egl_context.c | 8 ++++++++ src/glx_context.c | 2 ++ src/osmesa_context.c | 2 ++ src/vulkan.c | 2 ++ src/x11_init.c | 20 ++++++++++++++++++++ 6 files changed, 35 insertions(+) diff --git a/README.md b/README.md index 63e9f6bd..9641fdf2 100644 --- a/README.md +++ b/README.md @@ -264,6 +264,7 @@ information on what to include when reporting a bug. - [X11] Bugfix: Changing `GLFW_FLOATING` could leak memory - [X11] Bugfix: Icon pixel format conversion worked only by accident, relying on undefined behavior (#1986) + - [X11] Bugfix: Dynamic loading on OpenBSD failed due to soname differences - [Wayland] Added dynamic loading of all Wayland libraries - [Wayland] Removed support for `wl_shell` (#1443) - [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432) diff --git a/src/egl_context.c b/src/egl_context.c index 319da273..89ea78fa 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -325,6 +325,8 @@ GLFWbool _glfwInitEGL(void) "libEGL.dylib", #elif defined(__CYGWIN__) "libEGL-1.so", +#elif defined(__OpenBSD__) + "libEGL.so", #else "libEGL.so.1", #endif @@ -700,6 +702,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, "libGLES_CM.dll", #elif defined(_GLFW_COCOA) "libGLESv1_CM.dylib", +#elif defined(__OpenBSD__) + "libGLESv1_CM.so", #else "libGLESv1_CM.so.1", "libGLES_CM.so.1", @@ -717,6 +721,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, "libGLESv2.dylib", #elif defined(__CYGWIN__) "libGLESv2-2.so", +#elif defined(__OpenBSD__) + "libGLESv2.so", #else "libGLESv2.so.2", #endif @@ -728,6 +734,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, _GLFW_OPENGL_LIBRARY, #elif defined(_GLFW_WIN32) #elif defined(_GLFW_COCOA) +#elif defined(__OpenBSD__) + "libGL.so", #else "libGL.so.1", #endif diff --git a/src/glx_context.c b/src/glx_context.c index 060e487d..31cd34dc 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -259,6 +259,8 @@ GLFWbool _glfwInitGLX(void) _GLFW_GLX_LIBRARY, #elif defined(__CYGWIN__) "libGL-1.so", +#elif defined(__OpenBSD__) + "libGL.so", #else "libGL.so.1", "libGL.so", diff --git a/src/osmesa_context.c b/src/osmesa_context.c index 1b28c517..161d9fd8 100644 --- a/src/osmesa_context.c +++ b/src/osmesa_context.c @@ -124,6 +124,8 @@ GLFWbool _glfwInitOSMesa(void) "libOSMesa.8.dylib", #elif defined(__CYGWIN__) "libOSMesa-8.so", +#elif defined(__OpenBSD__) + "libOSMesa.so", #else "libOSMesa.so.8", "libOSMesa.so.6", diff --git a/src/vulkan.c b/src/vulkan.c index 2a64ecb4..f02b1ede 100644 --- a/src/vulkan.c +++ b/src/vulkan.c @@ -63,6 +63,8 @@ GLFWbool _glfwInitVulkan(int mode) _glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.1.dylib"); if (!_glfw.vk.handle) _glfw.vk.handle = _glfwLoadLocalVulkanLoaderCocoa(); +#elif defined(__OpenBSD__) + _glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so"); #else _glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so.1"); #endif diff --git a/src/x11_init.c b/src/x11_init.c index 68d6a6c4..acfa7933 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -601,7 +601,11 @@ static void detectEWMH(void) // static GLFWbool initExtensions(void) { +#if defined(__OpenBSD__) + _glfw.x11.vidmode.handle = _glfwPlatformLoadModule("libXxf86vm.so"); +#else _glfw.x11.vidmode.handle = _glfwPlatformLoadModule("libXxf86vm.so.1"); +#endif if (_glfw.x11.vidmode.handle) { _glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension) @@ -621,6 +625,8 @@ static GLFWbool initExtensions(void) #if defined(__CYGWIN__) _glfw.x11.xi.handle = _glfwPlatformLoadModule("libXi-6.so"); +#elif defined(__OpenBSD__) + _glfw.x11.xi.handle = _glfwPlatformLoadModule("libXi.so"); #else _glfw.x11.xi.handle = _glfwPlatformLoadModule("libXi.so.6"); #endif @@ -651,6 +657,8 @@ static GLFWbool initExtensions(void) #if defined(__CYGWIN__) _glfw.x11.randr.handle = _glfwPlatformLoadModule("libXrandr-2.so"); +#elif defined(__OpenBSD__) + _glfw.x11.randr.handle = _glfwPlatformLoadModule("libXrandr.so"); #else _glfw.x11.randr.handle = _glfwPlatformLoadModule("libXrandr.so.2"); #endif @@ -743,6 +751,8 @@ static GLFWbool initExtensions(void) #if defined(__CYGWIN__) _glfw.x11.xcursor.handle = _glfwPlatformLoadModule("libXcursor-1.so"); +#elif defined(__OpenBSD__) + _glfw.x11.xcursor.handle = _glfwPlatformLoadModule("libXcursor.so"); #else _glfw.x11.xcursor.handle = _glfwPlatformLoadModule("libXcursor.so.1"); #endif @@ -764,6 +774,8 @@ static GLFWbool initExtensions(void) #if defined(__CYGWIN__) _glfw.x11.xinerama.handle = _glfwPlatformLoadModule("libXinerama-1.so"); +#elif defined(__OpenBSD__) + _glfw.x11.xinerama.handle = _glfwPlatformLoadModule("libXinerama.so"); #else _glfw.x11.xinerama.handle = _glfwPlatformLoadModule("libXinerama.so.1"); #endif @@ -817,6 +829,8 @@ static GLFWbool initExtensions(void) { #if defined(__CYGWIN__) _glfw.x11.x11xcb.handle = _glfwPlatformLoadModule("libX11-xcb-1.so"); +#elif defined(__OpenBSD__) + _glfw.x11.x11xcb.handle = _glfwPlatformLoadModule("libX11-xcb.so"); #else _glfw.x11.x11xcb.handle = _glfwPlatformLoadModule("libX11-xcb.so.1"); #endif @@ -830,6 +844,8 @@ static GLFWbool initExtensions(void) #if defined(__CYGWIN__) _glfw.x11.xrender.handle = _glfwPlatformLoadModule("libXrender-1.so"); +#elif defined(__OpenBSD__) + _glfw.x11.xrender.handle = _glfwPlatformLoadModule("libXrender.so"); #else _glfw.x11.xrender.handle = _glfwPlatformLoadModule("libXrender.so.1"); #endif @@ -857,6 +873,8 @@ static GLFWbool initExtensions(void) #if defined(__CYGWIN__) _glfw.x11.xshape.handle = _glfwPlatformLoadModule("libXext-6.so"); +#elif defined(__OpenBSD__) + _glfw.x11.xshape.handle = _glfwPlatformLoadModule("libXext.so"); #else _glfw.x11.xshape.handle = _glfwPlatformLoadModule("libXext.so.6"); #endif @@ -1203,6 +1221,8 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform) #if defined(__CYGWIN__) void* module = _glfwPlatformLoadModule("libX11-6.so"); +#elif defined(__OpenBSD__) + void* module = _glfwPlatformLoadModule("libX11.so"); #else void* module = _glfwPlatformLoadModule("libX11.so.6"); #endif From 05b0e2fab2be38e0c937bf2ba09f6dc892160616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 26 Dec 2021 18:02:00 +0100 Subject: [PATCH 47/71] Update docs for specific Vulkan surface extensions Related to #2014 --- include/GLFW/glfw3.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index f0b8d5ec..520dc1df 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -6189,9 +6189,6 @@ GLFWAPI int glfwVulkanSupported(void); * returned array, as it is an error to specify an extension more than once in * the `VkInstanceCreateInfo` struct. * - * @remark @macos GLFW currently supports both the `VK_MVK_macos_surface` and - * the newer `VK_EXT_metal_surface` extensions. - * * @pointer_lifetime The returned array is allocated and freed by GLFW. You * should not free it yourself. It is guaranteed to be valid only until the * library is terminated. @@ -6330,17 +6327,20 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhys * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should * eliminate almost all occurrences of these errors. * - * @remark @macos This function currently only supports the - * `VK_MVK_macos_surface` extension from MoltenVK. + * @remark @macos GLFW prefers the `VK_EXT_metal_surface` extension, with the + * `VK_MVK_macos_surface` extension as a fallback. The name of the selected + * extension, if any, is included in the array returned by @ref + * glfwGetRequiredInstanceExtensions. * * @remark @macos This function creates and sets a `CAMetalLayer` instance for * the window content view, which is required for MoltenVK to function. * - * @remark @x11 GLFW by default attempts to use the `VK_KHR_xcb_surface` - * extension, if available. You can make it prefer the `VK_KHR_xlib_surface` - * extension by setting the + * @remark @x11 By default GLFW prefers the `VK_KHR_xcb_surface` extension, + * with the `VK_KHR_xlib_surface` extension as a fallback. You can make + * `VK_KHR_xlib_surface` the preferred extension by setting the * [GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init - * hint. + * hint. The name of the selected extension, if any, is included in the array + * returned by @ref glfwGetRequiredInstanceExtensions. * * @thread_safety This function may be called from any thread. For * synchronization details of Vulkan objects, see the Vulkan specification. From 8edbc4971d6c994d84f12f349afdeef41fae527f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 27 Dec 2021 01:31:38 +0100 Subject: [PATCH 48/71] Wayland: Document delayed window showing --- include/GLFW/glfw3.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 520dc1df..72d5fa71 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -3764,6 +3764,11 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* window); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * + * @remark @wayland Because Wayland wants every frame of the desktop to be + * complete, this function does not immediately make the window visible. + * Instead it will become visible the next time the window framebuffer is + * updated after this call. + * * @thread_safety This function must only be called from the main thread. * * @sa @ref window_hide From 855d338a6596cef6b88b298ad00b6f2658019877 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Thu, 30 Dec 2021 19:04:10 +0100 Subject: [PATCH 49/71] Wayland: Use correct action on fallback decoration We were previously storing the pointer position only when on the main window, so when the user clicked on a fallback decoration it would use the last position of the cursor on the main window, instead of the position in the decoration surface. Fixes part of #1991. --- src/wl_init.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index fd6efaa8..d26e5f6c 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -207,12 +207,12 @@ static void pointerHandleMotion(void* data, return; x = wl_fixed_to_double(sx); y = wl_fixed_to_double(sy); + window->wl.cursorPosX = x; + window->wl.cursorPosY = y; switch (window->wl.decorations.focus) { case mainWindow: - window->wl.cursorPosX = x; - window->wl.cursorPosY = y; _glfwInputCursorPos(window, x, y); _glfw.wl.cursorPreviousName = NULL; return; @@ -272,9 +272,7 @@ static void pointerHandleButton(void* data, if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH) edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP; else - { xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial); - } break; case leftDecoration: if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH) @@ -303,6 +301,7 @@ static void pointerHandleButton(void* data, { xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat, serial, edges); + return; } } else if (button == BTN_RIGHT) From 79e7e65c9d6145ded05baf54f82b53f5df451ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 26 Dec 2021 22:01:32 +0100 Subject: [PATCH 50/71] Wayland: Clean up event pump Adapt style to the rest of the project. --- src/wl_window.c | 59 ++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 10d0e25f..d51c9309 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -708,22 +708,19 @@ static void incrementCursorImage(_GLFWwindow* window) static void handleEvents(int timeout) { - struct wl_display* display = _glfw.wl.display; - struct pollfd fds[] = { - { wl_display_get_fd(display), POLLIN }, + struct pollfd fds[] = + { + { wl_display_get_fd(_glfw.wl.display), POLLIN }, { _glfw.wl.timerfd, POLLIN }, { _glfw.wl.cursorTimerfd, POLLIN }, }; - ssize_t read_ret; - uint64_t repeats; - while (wl_display_prepare_read(display) != 0) - wl_display_dispatch_pending(display); + while (wl_display_prepare_read(_glfw.wl.display) != 0) + wl_display_dispatch_pending(_glfw.wl.display); - // If an error different from EAGAIN happens, we have likely been - // disconnected from the Wayland session, try to handle that the best we - // can. - if (wl_display_flush(display) < 0 && errno != EAGAIN) + // If an error other than EAGAIN happens, we have likely been disconnected + // from the Wayland session; try to handle that the best we can. + if (wl_display_flush(_glfw.wl.display) < 0 && errno != EAGAIN) { _GLFWwindow* window = _glfw.windowListHead; while (window) @@ -731,7 +728,8 @@ static void handleEvents(int timeout) _glfwInputWindowCloseRequest(window); window = window->next; } - wl_display_cancel_read(display); + + wl_display_cancel_read(_glfw.wl.display); return; } @@ -739,41 +737,42 @@ static void handleEvents(int timeout) { if (fds[0].revents & POLLIN) { - wl_display_read_events(display); - wl_display_dispatch_pending(display); + wl_display_read_events(_glfw.wl.display); + wl_display_dispatch_pending(_glfw.wl.display); } else - { - wl_display_cancel_read(display); - } + wl_display_cancel_read(_glfw.wl.display); if (fds[1].revents & POLLIN) { - read_ret = read(_glfw.wl.timerfd, &repeats, sizeof(repeats)); - if (read_ret == 8 && _glfw.wl.keyboardFocus) + uint64_t repeats; + + if (read(_glfw.wl.timerfd, &repeats, sizeof(repeats)) == 8) { - for (uint64_t i = 0; i < repeats; ++i) + if (_glfw.wl.keyboardFocus) { - _glfwInputKey(_glfw.wl.keyboardFocus, - _glfw.wl.keyboardLastKey, - _glfw.wl.keyboardLastScancode, - GLFW_REPEAT, - _glfw.wl.xkb.modifiers); + for (uint64_t i = 0; i < repeats; i++) + { + _glfwInputKey(_glfw.wl.keyboardFocus, + _glfw.wl.keyboardLastKey, + _glfw.wl.keyboardLastScancode, + GLFW_REPEAT, + _glfw.wl.xkb.modifiers); + } } } } if (fds[2].revents & POLLIN) { - read_ret = read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)); - if (read_ret == 8) + uint64_t repeats; + + if (read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)) == 8) incrementCursorImage(_glfw.wl.pointerFocus); } } else - { - wl_display_cancel_read(display); - } + wl_display_cancel_read(_glfw.wl.display); } ////////////////////////////////////////////////////////////////////////// From 850893a39f1e58ba5d6ff891ee18ca39037f921a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 27 Dec 2021 00:52:24 +0100 Subject: [PATCH 51/71] Wayland: Control key repeat via timerfd state The key repeat logic is now controlled only via the key repeat timerfd. --- src/wl_init.c | 6 +++--- src/wl_window.c | 15 ++++++--------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index d26e5f6c..9ccd3530 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -504,12 +504,12 @@ static void keyboardHandleLeave(void* data, if (!window) return; + struct itimerspec timer = {}; + timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); + _glfw.wl.serial = serial; _glfw.wl.keyboardFocus = NULL; _glfwInputWindowFocus(window, GLFW_FALSE); - - struct itimerspec timer = {}; - timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); } static int toGLFWKeyCode(uint32_t key) diff --git a/src/wl_window.c b/src/wl_window.c index d51c9309..f2e268db 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -749,16 +749,13 @@ static void handleEvents(int timeout) if (read(_glfw.wl.timerfd, &repeats, sizeof(repeats)) == 8) { - if (_glfw.wl.keyboardFocus) + for (uint64_t i = 0; i < repeats; i++) { - for (uint64_t i = 0; i < repeats; i++) - { - _glfwInputKey(_glfw.wl.keyboardFocus, - _glfw.wl.keyboardLastKey, - _glfw.wl.keyboardLastScancode, - GLFW_REPEAT, - _glfw.wl.xkb.modifiers); - } + _glfwInputKey(_glfw.wl.keyboardFocus, + _glfw.wl.keyboardLastKey, + _glfw.wl.keyboardLastScancode, + GLFW_REPEAT, + _glfw.wl.xkb.modifiers); } } } From 3f5dfeaf295f69af006458f589e45c991d460fde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Sun, 26 Dec 2021 22:51:20 +0100 Subject: [PATCH 52/71] Wayland: Fix repeated key not released on defocus Platform code should not generate key events with GLFW_REPEAT. GLFW_PRESS is translated into GLFW_REPEAT by shared code based on the key state cache. This confused the automatic key release logic into not generating an event with GLFW_RELEASE for a key being repeated when the window lost input focus. --- README.md | 1 + src/wl_window.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9641fdf2..393a383d 100644 --- a/README.md +++ b/README.md @@ -283,6 +283,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Activating a window would emit two input focus events - [Wayland] Bugfix: Disable key repeat mechanism when window loses input focus - [Wayland] Bugfix: Window hiding and showing did not work (#1492,#1731) + - [Wayland] Bugfix: A key being repeated was not released when window lost focus - [POSIX] Removed use of deprecated function `gettimeofday` - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled - [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072) diff --git a/src/wl_window.c b/src/wl_window.c index f2e268db..26200363 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -754,7 +754,7 @@ static void handleEvents(int timeout) _glfwInputKey(_glfw.wl.keyboardFocus, _glfw.wl.keyboardLastKey, _glfw.wl.keyboardLastScancode, - GLFW_REPEAT, + GLFW_PRESS, _glfw.wl.xkb.modifiers); } } From a3d1633e1d48c2283da139116d70d5223642a804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 27 Dec 2021 18:10:52 +0100 Subject: [PATCH 53/71] Wayland: Move surface creation function This needs to be after createXdgSurface, which it will soon be calling. --- src/wl_window.c | 58 ++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 26200363..e1fd96cb 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -432,35 +432,6 @@ static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable) } } -static GLFWbool createSurface(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig) -{ - window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor); - if (!window->wl.surface) - return GLFW_FALSE; - - wl_surface_add_listener(window->wl.surface, - &surfaceListener, - window); - - wl_surface_set_user_data(window->wl.surface, window); - - window->wl.native = wl_egl_window_create(window->wl.surface, - wndconfig->width, - wndconfig->height); - if (!window->wl.native) - return GLFW_FALSE; - - window->wl.width = wndconfig->width; - window->wl.height = wndconfig->height; - window->wl.scale = 1; - - if (!window->wl.transparent) - setOpaqueRegion(window); - - return GLFW_TRUE; -} - static void setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor, int refreshRate) { @@ -644,6 +615,35 @@ static GLFWbool createXdgSurface(_GLFWwindow* window) return GLFW_TRUE; } +static GLFWbool createSurface(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig) +{ + window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor); + if (!window->wl.surface) + return GLFW_FALSE; + + wl_surface_add_listener(window->wl.surface, + &surfaceListener, + window); + + wl_surface_set_user_data(window->wl.surface, window); + + window->wl.native = wl_egl_window_create(window->wl.surface, + wndconfig->width, + wndconfig->height); + if (!window->wl.native) + return GLFW_FALSE; + + window->wl.width = wndconfig->width; + window->wl.height = wndconfig->height; + window->wl.scale = 1; + + if (!window->wl.transparent) + setOpaqueRegion(window); + + return GLFW_TRUE; +} + static void setCursorImage(_GLFWwindow* window, _GLFWcursorWayland* cursorWayland) { From 7bede13b1dacb2ccf4d9492d0ec6bc0f7879222e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 27 Dec 2021 18:13:51 +0100 Subject: [PATCH 54/71] Wayland: Gather framebuffer transparency logic --- src/wl_window.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index e1fd96cb..28fdcb3d 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -616,7 +616,8 @@ static GLFWbool createXdgSurface(_GLFWwindow* window) } static GLFWbool createSurface(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig) + const _GLFWwndconfig* wndconfig, + const _GLFWfbconfig* fbconfig) { window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor); if (!window->wl.surface) @@ -638,6 +639,7 @@ static GLFWbool createSurface(_GLFWwindow* window, window->wl.height = wndconfig->height; window->wl.scale = 1; + window->wl.transparent = fbconfig->transparent; if (!window->wl.transparent) setOpaqueRegion(window); @@ -781,9 +783,7 @@ int _glfwCreateWindowWayland(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig) { - window->wl.transparent = fbconfig->transparent; - - if (!createSurface(window, wndconfig)) + if (!createSurface(window, wndconfig, fbconfig)) return GLFW_FALSE; if (ctxconfig->client != GLFW_NO_API) From c1ecd4673eae76d65a8a5e4222c46e20693f4e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 27 Dec 2021 18:16:37 +0100 Subject: [PATCH 55/71] Wayland: Move window title cloning to creation --- src/wl_window.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 28fdcb3d..2cfdee47 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -638,6 +638,7 @@ static GLFWbool createSurface(_GLFWwindow* window, window->wl.width = wndconfig->width; window->wl.height = wndconfig->height; window->wl.scale = 1; + window->wl.title = _glfw_strdup(wndconfig->title); window->wl.transparent = fbconfig->transparent; if (!window->wl.transparent) @@ -805,9 +806,6 @@ int _glfwCreateWindowWayland(_GLFWwindow* window, } } - if (wndconfig->title) - window->wl.title = _glfw_strdup(wndconfig->title); - window->wl.currentCursor = NULL; window->wl.monitors = _glfw_calloc(1, sizeof(_GLFWmonitor*)); From 216ea3d735e44691a5d06ee5654cd1ca14f685f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 27 Dec 2021 18:20:30 +0100 Subject: [PATCH 56/71] Wayland: Remove superfluous initialize to NULL The whole window struct has already been cleared to zero. --- src/wl_window.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 2cfdee47..dfee3f34 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -806,8 +806,6 @@ int _glfwCreateWindowWayland(_GLFWwindow* window, } } - window->wl.currentCursor = NULL; - window->wl.monitors = _glfw_calloc(1, sizeof(_GLFWmonitor*)); window->wl.monitorsCount = 0; window->wl.monitorsSize = 1; From 12c2ccd609442f835e8f68b27bd903ab716f2531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 27 Dec 2021 18:22:15 +0100 Subject: [PATCH 57/71] Wayland: Remove window monitor array pre-alloc The array will be allocated by surfaceHandleEnter when needed. --- src/wl_window.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index dfee3f34..6ad95f31 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -806,10 +806,6 @@ int _glfwCreateWindowWayland(_GLFWwindow* window, } } - window->wl.monitors = _glfw_calloc(1, sizeof(_GLFWmonitor*)); - window->wl.monitorsCount = 0; - window->wl.monitorsSize = 1; - return GLFW_TRUE; } From c05acf6246eefb08533dc3955db7eac9d2d1c0ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 28 Dec 2021 01:20:19 +0100 Subject: [PATCH 58/71] Wayland: Fix window not visible after initial swap A window created with GLFW_VISIBLE set was not made visible by the initial buffer swap during context attribute refresh. Regression introduced by @elmindreda in 094aa6d3c721397825cb1095c156353463ecafb5. --- src/wl_window.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/wl_window.c b/src/wl_window.c index 6ad95f31..b01d01f0 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -644,6 +644,14 @@ static GLFWbool createSurface(_GLFWwindow* window, if (!window->wl.transparent) setOpaqueRegion(window); + if (wndconfig->visible) + { + if (!createXdgSurface(window)) + return GLFW_FALSE; + + window->wl.visible = GLFW_TRUE; + } + return GLFW_TRUE; } From 25c521cbe5acd58641740db5063d33fb51eeb882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 28 Dec 2021 01:39:06 +0100 Subject: [PATCH 59/71] Wayland: Fix missing damage event on window show By definition a hidden window on Wayland does not have valid framebuffer contents. This adds a window damage (refresh) event when a window is shown, to request an initial frame for the now visible window. --- README.md | 1 + src/wl_window.c | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 393a383d..f2769580 100644 --- a/README.md +++ b/README.md @@ -284,6 +284,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Disable key repeat mechanism when window loses input focus - [Wayland] Bugfix: Window hiding and showing did not work (#1492,#1731) - [Wayland] Bugfix: A key being repeated was not released when window lost focus + - [Wayland] Bugfix: Showing a hidden window did not emit a window refresh event - [POSIX] Removed use of deprecated function `gettimeofday` - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled - [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072) diff --git a/src/wl_window.c b/src/wl_window.c index b01d01f0..a3190592 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1006,6 +1006,7 @@ void _glfwShowWindowWayland(_GLFWwindow* window) createXdgSurface(window); window->wl.visible = GLFW_TRUE; + _glfwInputWindowDamage(window); } } From 8aaea57421cd4e37b439fbce7482a5f351c0c31f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 28 Dec 2021 04:01:32 +0100 Subject: [PATCH 60/71] Fix gamma test not checking for NULL return value --- tests/gamma.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/gamma.c b/tests/gamma.c index 734955cd..d1f6dc27 100644 --- a/tests/gamma.c +++ b/tests/gamma.c @@ -113,6 +113,12 @@ int main(int argc, char** argv) { const GLFWgammaramp* ramp = glfwGetGammaRamp(monitor); + if (!ramp) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + const size_t array_size = ramp->size * sizeof(short); orig_ramp.size = ramp->size; orig_ramp.red = malloc(array_size); From 715b874db341d7f696a8244e4f3d5d14d07894bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 28 Dec 2021 15:33:58 +0100 Subject: [PATCH 61/71] Wayland: Fix GLFW_VISIBLE affecting full screen Full screen window creation was not ignoring the GLFW_VISIBLE hint. --- README.md | 1 + src/wl_window.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f2769580..abe5ed29 100644 --- a/README.md +++ b/README.md @@ -285,6 +285,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Window hiding and showing did not work (#1492,#1731) - [Wayland] Bugfix: A key being repeated was not released when window lost focus - [Wayland] Bugfix: Showing a hidden window did not emit a window refresh event + - [Wayland] Bugfix: Full screen window creation did not ignore `GLFW_VISIBLE` - [POSIX] Removed use of deprecated function `gettimeofday` - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled - [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072) diff --git a/src/wl_window.c b/src/wl_window.c index a3190592..eab108ee 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -644,7 +644,7 @@ static GLFWbool createSurface(_GLFWwindow* window, if (!window->wl.transparent) setOpaqueRegion(window); - if (wndconfig->visible) + if (window->monitor || wndconfig->visible) { if (!createXdgSurface(window)) return GLFW_FALSE; From 37b7540db9d850e9318fd1948dfb714f75306d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 30 Dec 2021 02:59:15 +0100 Subject: [PATCH 62/71] Wayland: Fix keys reported as wrong or unknown key --- README.md | 1 + src/wl_init.c | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index abe5ed29..ae36e304 100644 --- a/README.md +++ b/README.md @@ -286,6 +286,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: A key being repeated was not released when window lost focus - [Wayland] Bugfix: Showing a hidden window did not emit a window refresh event - [Wayland] Bugfix: Full screen window creation did not ignore `GLFW_VISIBLE` + - [Wayland] Bugfix: Some keys were reported as wrong key or `GLFW_KEY_UNKNOWN` - [POSIX] Removed use of deprecated function `gettimeofday` - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled - [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072) diff --git a/src/wl_init.c b/src/wl_init.c index 9ccd3530..3d28bddc 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -972,7 +972,7 @@ static void createKeyTables(void) _glfw.wl.keycodes[KEY_RIGHTALT] = GLFW_KEY_RIGHT_ALT; _glfw.wl.keycodes[KEY_LEFTMETA] = GLFW_KEY_LEFT_SUPER; _glfw.wl.keycodes[KEY_RIGHTMETA] = GLFW_KEY_RIGHT_SUPER; - _glfw.wl.keycodes[KEY_MENU] = GLFW_KEY_MENU; + _glfw.wl.keycodes[KEY_COMPOSE] = GLFW_KEY_MENU; _glfw.wl.keycodes[KEY_NUMLOCK] = GLFW_KEY_NUM_LOCK; _glfw.wl.keycodes[KEY_CAPSLOCK] = GLFW_KEY_CAPS_LOCK; _glfw.wl.keycodes[KEY_PRINT] = GLFW_KEY_PRINT_SCREEN; @@ -1015,7 +1015,7 @@ static void createKeyTables(void) _glfw.wl.keycodes[KEY_F23] = GLFW_KEY_F23; _glfw.wl.keycodes[KEY_F24] = GLFW_KEY_F24; _glfw.wl.keycodes[KEY_KPSLASH] = GLFW_KEY_KP_DIVIDE; - _glfw.wl.keycodes[KEY_KPDOT] = GLFW_KEY_KP_MULTIPLY; + _glfw.wl.keycodes[KEY_KPASTERISK] = GLFW_KEY_KP_MULTIPLY; _glfw.wl.keycodes[KEY_KPMINUS] = GLFW_KEY_KP_SUBTRACT; _glfw.wl.keycodes[KEY_KPPLUS] = GLFW_KEY_KP_ADD; _glfw.wl.keycodes[KEY_KP0] = GLFW_KEY_KP_0; @@ -1028,9 +1028,10 @@ static void createKeyTables(void) _glfw.wl.keycodes[KEY_KP7] = GLFW_KEY_KP_7; _glfw.wl.keycodes[KEY_KP8] = GLFW_KEY_KP_8; _glfw.wl.keycodes[KEY_KP9] = GLFW_KEY_KP_9; - _glfw.wl.keycodes[KEY_KPCOMMA] = GLFW_KEY_KP_DECIMAL; + _glfw.wl.keycodes[KEY_KPDOT] = GLFW_KEY_KP_DECIMAL; _glfw.wl.keycodes[KEY_KPEQUAL] = GLFW_KEY_KP_EQUAL; _glfw.wl.keycodes[KEY_KPENTER] = GLFW_KEY_KP_ENTER; + _glfw.wl.keycodes[KEY_102ND] = GLFW_KEY_WORLD_2; for (int scancode = 0; scancode < 256; scancode++) { From cb22c5411938c14a3ddef6f0fb4f338a6b4b99a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 30 Dec 2021 18:22:16 +0100 Subject: [PATCH 63/71] Move UTF-8 encoding to shared code This will be used by the Wayland code too. --- src/init.c | 31 +++++++++++++++++++++++++++++++ src/internal.h | 2 ++ src/x11_window.c | 35 ++--------------------------------- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/init.c b/src/init.c index b5c5da9c..1d4e7804 100644 --- a/src/init.c +++ b/src/init.c @@ -140,6 +140,37 @@ static void terminate(void) ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// +// Encode a Unicode code point to a UTF-8 stream +// Based on cutef8 by Jeff Bezanson (Public Domain) +// +size_t _glfwEncodeUTF8(char* s, unsigned int ch) +{ + size_t count = 0; + + if (ch < 0x80) + s[count++] = (char) ch; + else if (ch < 0x800) + { + s[count++] = (ch >> 6) | 0xc0; + s[count++] = (ch & 0x3f) | 0x80; + } + else if (ch < 0x10000) + { + s[count++] = (ch >> 12) | 0xe0; + s[count++] = ((ch >> 6) & 0x3f) | 0x80; + s[count++] = (ch & 0x3f) | 0x80; + } + else if (ch < 0x110000) + { + s[count++] = (ch >> 18) | 0xf0; + s[count++] = ((ch >> 12) & 0x3f) | 0x80; + s[count++] = ((ch >> 6) & 0x3f) | 0x80; + s[count++] = (ch & 0x3f) | 0x80; + } + + return count; +} + char* _glfw_strdup(const char* source) { const size_t length = strlen(source); diff --git a/src/internal.h b/src/internal.h index 2a8c8d6d..b28d41ab 100644 --- a/src/internal.h +++ b/src/internal.h @@ -995,6 +995,8 @@ GLFWbool _glfwInitVulkan(int mode); void _glfwTerminateVulkan(void); const char* _glfwGetVulkanResultString(VkResult result); +size_t _glfwEncodeUTF8(char* s, unsigned int ch); + char* _glfw_strdup(const char* source); float _glfw_fminf(float a, float b); float _glfw_fmaxf(float a, float b); diff --git a/src/x11_window.c b/src/x11_window.c index a5255215..96514c18 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -429,37 +429,6 @@ static char** parseUriList(char* text, int* count) return paths; } -// Encode a Unicode code point to a UTF-8 stream -// Based on cutef8 by Jeff Bezanson (Public Domain) -// -static size_t encodeUTF8(char* s, unsigned int ch) -{ - size_t count = 0; - - if (ch < 0x80) - s[count++] = (char) ch; - else if (ch < 0x800) - { - s[count++] = (ch >> 6) | 0xc0; - s[count++] = (ch & 0x3f) | 0x80; - } - else if (ch < 0x10000) - { - s[count++] = (ch >> 12) | 0xe0; - s[count++] = ((ch >> 6) & 0x3f) | 0x80; - s[count++] = (ch & 0x3f) | 0x80; - } - else if (ch < 0x110000) - { - s[count++] = (ch >> 18) | 0xf0; - s[count++] = ((ch >> 12) & 0x3f) | 0x80; - s[count++] = ((ch >> 6) & 0x3f) | 0x80; - s[count++] = (ch & 0x3f) | 0x80; - } - - return count; -} - // Decode a Unicode code point from a UTF-8 stream // Based on cutef8 by Jeff Bezanson (Public Domain) // @@ -497,7 +466,7 @@ static char* convertLatin1toUTF8(const char* source) char* tp = target; for (sp = source; *sp; sp++) - tp += encodeUTF8(tp, *sp); + tp += _glfwEncodeUTF8(tp, *sp); return target; } @@ -2903,7 +2872,7 @@ const char* _glfwGetScancodeNameX11(int scancode) if (ch == -1) return NULL; - const size_t count = encodeUTF8(_glfw.x11.keynames[key], (unsigned int) ch); + const size_t count = _glfwEncodeUTF8(_glfw.x11.keynames[key], (unsigned int) ch); if (count == 0) return NULL; From 17a9e34fbc179373dc9bc370164fa4690870b295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Wed, 29 Dec 2021 23:45:06 +0100 Subject: [PATCH 64/71] Wayland: Implement key name support --- README.md | 1 + src/wl_init.c | 4 ++++ src/wl_platform.h | 7 ++++++ src/wl_window.c | 55 +++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ae36e304..06108a86 100644 --- a/README.md +++ b/README.md @@ -266,6 +266,7 @@ information on what to include when reporting a bug. undefined behavior (#1986) - [X11] Bugfix: Dynamic loading on OpenBSD failed due to soname differences - [Wayland] Added dynamic loading of all Wayland libraries + - [Wayland] Added support for key names via xkbcommon - [Wayland] Removed support for `wl_shell` (#1443) - [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432) - [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled diff --git a/src/wl_init.c b/src/wl_init.c index 3d28bddc..bd365fdf 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -1290,6 +1290,8 @@ int _glfwInitWayland(void) _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_mod_get_index"); _glfw.wl.xkb.keymap_key_repeats = (PFN_xkb_keymap_key_repeats) _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_key_repeats"); + _glfw.wl.xkb.keymap_key_get_syms_by_level = (PFN_xkb_keymap_key_get_syms_by_level) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_key_get_syms_by_level"); _glfw.wl.xkb.state_new = (PFN_xkb_state_new) _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_new"); _glfw.wl.xkb.state_unref = (PFN_xkb_state_unref) @@ -1300,6 +1302,8 @@ int _glfwInitWayland(void) _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_update_mask"); _glfw.wl.xkb.state_serialize_mods = (PFN_xkb_state_serialize_mods) _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_serialize_mods"); + _glfw.wl.xkb.state_key_get_layout = (PFN_xkb_state_key_get_layout) + _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_key_get_layout"); #ifdef HAVE_XKBCOMMON_COMPOSE_H _glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale) diff --git a/src/wl_platform.h b/src/wl_platform.h index 1e36a794..e29f41b4 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -163,22 +163,26 @@ typedef struct xkb_keymap* (* PFN_xkb_keymap_new_from_string)(struct xkb_context typedef void (* PFN_xkb_keymap_unref)(struct xkb_keymap*); typedef xkb_mod_index_t (* PFN_xkb_keymap_mod_get_index)(struct xkb_keymap*, const char*); typedef int (* PFN_xkb_keymap_key_repeats)(struct xkb_keymap*, xkb_keycode_t); +typedef int (* PFN_xkb_keymap_key_get_syms_by_level)(struct xkb_keymap*,xkb_keycode_t,xkb_layout_index_t,xkb_level_index_t,const xkb_keysym_t**); typedef struct xkb_state* (* PFN_xkb_state_new)(struct xkb_keymap*); typedef void (* PFN_xkb_state_unref)(struct xkb_state*); typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**); typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t); typedef xkb_mod_mask_t (* PFN_xkb_state_serialize_mods)(struct xkb_state*, enum xkb_state_component); +typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xkb_keycode_t); #define xkb_context_new _glfw.wl.xkb.context_new #define xkb_context_unref _glfw.wl.xkb.context_unref #define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string #define xkb_keymap_unref _glfw.wl.xkb.keymap_unref #define xkb_keymap_mod_get_index _glfw.wl.xkb.keymap_mod_get_index #define xkb_keymap_key_repeats _glfw.wl.xkb.keymap_key_repeats +#define xkb_keymap_key_get_syms_by_level _glfw.wl.xkb.keymap_key_get_syms_by_level #define xkb_state_new _glfw.wl.xkb.state_new #define xkb_state_unref _glfw.wl.xkb.state_unref #define xkb_state_key_get_syms _glfw.wl.xkb.state_key_get_syms #define xkb_state_update_mask _glfw.wl.xkb.state_update_mask #define xkb_state_serialize_mods _glfw.wl.xkb.state_serialize_mods +#define xkb_state_key_get_layout _glfw.wl.xkb.state_key_get_layout #ifdef HAVE_XKBCOMMON_COMPOSE_H typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags); @@ -311,6 +315,7 @@ typedef struct _GLFWlibraryWayland int timerfd; short int keycodes[256]; short int scancodes[GLFW_KEY_LAST + 1]; + char keynames[GLFW_KEY_LAST + 1][5]; struct { void* handle; @@ -336,11 +341,13 @@ typedef struct _GLFWlibraryWayland PFN_xkb_keymap_unref keymap_unref; PFN_xkb_keymap_mod_get_index keymap_mod_get_index; PFN_xkb_keymap_key_repeats keymap_key_repeats; + PFN_xkb_keymap_key_get_syms_by_level keymap_key_get_syms_by_level; PFN_xkb_state_new state_new; PFN_xkb_state_unref state_unref; PFN_xkb_state_key_get_syms state_key_get_syms; PFN_xkb_state_update_mask state_update_mask; PFN_xkb_state_serialize_mods state_serialize_mods; + PFN_xkb_state_key_get_layout state_key_get_layout; #ifdef HAVE_XKBCOMMON_COMPOSE_H PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale; diff --git a/src/wl_window.c b/src/wl_window.c index eab108ee..1ed4b079 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1193,10 +1193,57 @@ void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode) const char* _glfwGetScancodeNameWayland(int scancode) { - // TODO - _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, - "Wayland: Key names not yet implemented"); - return NULL; + if (scancode < 0 || scancode > 255 || + _glfw.wl.keycodes[scancode] == GLFW_KEY_UNKNOWN) + { + _glfwInputError(GLFW_INVALID_VALUE, + "Wayland: Invalid scancode %i", + scancode); + return NULL; + } + + const int key = _glfw.wl.keycodes[scancode]; + const xkb_keycode_t keycode = scancode + 8; + const xkb_layout_index_t layout = + xkb_state_key_get_layout(_glfw.wl.xkb.state, keycode); + if (layout == XKB_LAYOUT_INVALID) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to retrieve layout for key name"); + return NULL; + } + + const xkb_keysym_t* keysyms = NULL; + xkb_keymap_key_get_syms_by_level(_glfw.wl.xkb.keymap, + keycode, + layout, + 0, + &keysyms); + if (keysyms == NULL) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to retrieve keysym for key name"); + return NULL; + } + + const long codepoint = _glfwKeySym2Unicode(keysyms[0]); + if (codepoint == -1) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to retrieve codepoint for key name"); + return NULL; + } + + const size_t count = _glfwEncodeUTF8(_glfw.wl.keynames[key], (unsigned int) codepoint); + if (count == 0) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Failed to encode codepoint for key name"); + return NULL; + } + + _glfw.wl.keynames[key][count] = '\0'; + return _glfw.wl.keynames[key]; } int _glfwGetKeyScancodeWayland(int key) From fe7be39793f993f9bf7480f2389bffad676199f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 30 Dec 2021 19:09:53 +0100 Subject: [PATCH 65/71] Clean up internal Unicode code point handling Call code points by their name and store them as uint32_t. --- src/init.c | 30 +++++++++++++++--------------- src/input.c | 2 +- src/internal.h | 4 ++-- src/win32_window.c | 4 ++-- src/wl_init.c | 9 ++++----- src/wl_window.c | 6 +++--- src/x11_window.c | 22 +++++++++++----------- src/xkb_unicode.c | 4 ++-- src/xkb_unicode.h | 4 +++- 9 files changed, 43 insertions(+), 42 deletions(-) diff --git a/src/init.c b/src/init.c index 1d4e7804..80f424a8 100644 --- a/src/init.c +++ b/src/init.c @@ -143,29 +143,29 @@ static void terminate(void) // Encode a Unicode code point to a UTF-8 stream // Based on cutef8 by Jeff Bezanson (Public Domain) // -size_t _glfwEncodeUTF8(char* s, unsigned int ch) +size_t _glfwEncodeUTF8(char* s, uint32_t codepoint) { size_t count = 0; - if (ch < 0x80) - s[count++] = (char) ch; - else if (ch < 0x800) + if (codepoint < 0x80) + s[count++] = (char) codepoint; + else if (codepoint < 0x800) { - s[count++] = (ch >> 6) | 0xc0; - s[count++] = (ch & 0x3f) | 0x80; + s[count++] = (codepoint >> 6) | 0xc0; + s[count++] = (codepoint & 0x3f) | 0x80; } - else if (ch < 0x10000) + else if (codepoint < 0x10000) { - s[count++] = (ch >> 12) | 0xe0; - s[count++] = ((ch >> 6) & 0x3f) | 0x80; - s[count++] = (ch & 0x3f) | 0x80; + s[count++] = (codepoint >> 12) | 0xe0; + s[count++] = ((codepoint >> 6) & 0x3f) | 0x80; + s[count++] = (codepoint & 0x3f) | 0x80; } - else if (ch < 0x110000) + else if (codepoint < 0x110000) { - s[count++] = (ch >> 18) | 0xf0; - s[count++] = ((ch >> 12) & 0x3f) | 0x80; - s[count++] = ((ch >> 6) & 0x3f) | 0x80; - s[count++] = (ch & 0x3f) | 0x80; + s[count++] = (codepoint >> 18) | 0xf0; + s[count++] = ((codepoint >> 12) & 0x3f) | 0x80; + s[count++] = ((codepoint >> 6) & 0x3f) | 0x80; + s[count++] = (codepoint & 0x3f) | 0x80; } return count; diff --git a/src/input.c b/src/input.c index 11716bd5..6a2c3e1d 100644 --- a/src/input.c +++ b/src/input.c @@ -295,7 +295,7 @@ void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int m // Notifies shared code of a Unicode codepoint input event // The 'plain' parameter determines whether to emit a regular character event // -void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWbool plain) +void _glfwInputChar(_GLFWwindow* window, uint32_t codepoint, int mods, GLFWbool plain) { if (codepoint < 32 || (codepoint > 126 && codepoint < 160)) return; diff --git a/src/internal.h b/src/internal.h index b28d41ab..f8548fa3 100644 --- a/src/internal.h +++ b/src/internal.h @@ -919,7 +919,7 @@ void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor); void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int mods); void _glfwInputChar(_GLFWwindow* window, - unsigned int codepoint, int mods, GLFWbool plain); + uint32_t codepoint, int mods, GLFWbool plain); void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset); void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods); void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos); @@ -995,7 +995,7 @@ GLFWbool _glfwInitVulkan(int mode); void _glfwTerminateVulkan(void); const char* _glfwGetVulkanResultString(VkResult result); -size_t _glfwEncodeUTF8(char* s, unsigned int ch); +size_t _glfwEncodeUTF8(char* s, uint32_t codepoint); char* _glfw_strdup(const char* source); float _glfw_fminf(float a, float b); diff --git a/src/win32_window.c b/src/win32_window.c index e03b8564..b3da6b2a 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -649,7 +649,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, window->win32.highSurrogate = (WCHAR) wParam; else { - unsigned int codepoint = 0; + uint32_t codepoint = 0; if (wParam >= 0xdc00 && wParam <= 0xdfff) { @@ -683,7 +683,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, return TRUE; } - _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GLFW_TRUE); + _glfwInputChar(window, (uint32_t) wParam, getKeyMods(), GLFW_TRUE); return 0; } diff --git a/src/wl_init.c b/src/wl_init.c index bd365fdf..e2bd2921 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -544,8 +544,7 @@ static xkb_keysym_t composeSymbol(xkb_keysym_t sym) static GLFWbool inputChar(_GLFWwindow* window, uint32_t key) { - uint32_t code, numSyms; - long cp; + uint32_t code, numSyms, codepoint; const xkb_keysym_t *syms; xkb_keysym_t sym; @@ -559,12 +558,12 @@ static GLFWbool inputChar(_GLFWwindow* window, uint32_t key) #else sym = syms[0]; #endif - cp = _glfwKeySym2Unicode(sym); - if (cp != -1) + codepoint = _glfwKeySym2Unicode(sym); + if (codepoint != GLFW_INVALID_CODEPOINT) { const int mods = _glfw.wl.xkb.modifiers; const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT)); - _glfwInputChar(window, cp, mods, plain); + _glfwInputChar(window, codepoint, mods, plain); } } diff --git a/src/wl_window.c b/src/wl_window.c index 1ed4b079..48ffb7c2 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1226,15 +1226,15 @@ const char* _glfwGetScancodeNameWayland(int scancode) return NULL; } - const long codepoint = _glfwKeySym2Unicode(keysyms[0]); - if (codepoint == -1) + const uint32_t codepoint = _glfwKeySym2Unicode(keysyms[0]); + if (codepoint == GLFW_INVALID_CODEPOINT) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to retrieve codepoint for key name"); return NULL; } - const size_t count = _glfwEncodeUTF8(_glfw.wl.keynames[key], (unsigned int) codepoint); + const size_t count = _glfwEncodeUTF8(_glfw.wl.keynames[key], codepoint); if (count == 0) { _glfwInputError(GLFW_PLATFORM_ERROR, diff --git a/src/x11_window.c b/src/x11_window.c index 96514c18..61e4fd6d 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -432,10 +432,10 @@ static char** parseUriList(char* text, int* count) // Decode a Unicode code point from a UTF-8 stream // Based on cutef8 by Jeff Bezanson (Public Domain) // -static unsigned int decodeUTF8(const char** s) +static uint32_t decodeUTF8(const char** s) { - unsigned int ch = 0, count = 0; - static const unsigned int offsets[] = + uint32_t codepoint = 0, count = 0; + static const uint32_t offsets[] = { 0x00000000u, 0x00003080u, 0x000e2080u, 0x03c82080u, 0xfa082080u, 0x82082080u @@ -443,13 +443,13 @@ static unsigned int decodeUTF8(const char** s) do { - ch = (ch << 6) + (unsigned char) **s; + codepoint = (codepoint << 6) + (unsigned char) **s; (*s)++; count++; } while ((**s & 0xc0) == 0x80); assert(count <= 6); - return ch - offsets[count - 1]; + return codepoint - offsets[count - 1]; } // Convert the specified Latin-1 string to UTF-8 @@ -1286,9 +1286,9 @@ static void processEvent(XEvent *event) _glfwInputKey(window, key, keycode, GLFW_PRESS, mods); - const long character = _glfwKeySym2Unicode(keysym); - if (character != -1) - _glfwInputChar(window, character, mods, plain); + const uint32_t codepoint = _glfwKeySym2Unicode(keysym); + if (codepoint != GLFW_INVALID_CODEPOINT) + _glfwInputChar(window, codepoint, mods, plain); } return; @@ -2868,11 +2868,11 @@ const char* _glfwGetScancodeNameX11(int scancode) if (keysym == NoSymbol) return NULL; - const long ch = _glfwKeySym2Unicode(keysym); - if (ch == -1) + const uint32_t codepoint = _glfwKeySym2Unicode(keysym); + if (codepoint == GLFW_INVALID_CODEPOINT) return NULL; - const size_t count = _glfwEncodeUTF8(_glfw.x11.keynames[key], (unsigned int) ch); + const size_t count = _glfwEncodeUTF8(_glfw.x11.keynames[key], codepoint); if (count == 0) return NULL; diff --git a/src/xkb_unicode.c b/src/xkb_unicode.c index 2772ea09..1b2482cd 100644 --- a/src/xkb_unicode.c +++ b/src/xkb_unicode.c @@ -907,7 +907,7 @@ static const struct codepair { // Convert XKB KeySym to Unicode // -long _glfwKeySym2Unicode(unsigned int keysym) +uint32_t _glfwKeySym2Unicode(unsigned int keysym) { int min = 0; int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; @@ -937,6 +937,6 @@ long _glfwKeySym2Unicode(unsigned int keysym) } // No matching Unicode value found - return -1; + return GLFW_INVALID_CODEPOINT; } diff --git a/src/xkb_unicode.h b/src/xkb_unicode.h index 76d83ffd..b07408f6 100644 --- a/src/xkb_unicode.h +++ b/src/xkb_unicode.h @@ -24,5 +24,7 @@ // //======================================================================== -long _glfwKeySym2Unicode(unsigned int keysym); +#define GLFW_INVALID_CODEPOINT 0xffffffffu + +uint32_t _glfwKeySym2Unicode(unsigned int keysym); From b70259e52df8cf5b1773ae7f0b575a0d6107454e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 30 Dec 2021 19:49:06 +0100 Subject: [PATCH 66/71] Wayland: Clean up text input Adapt style and naming to match the rest of the project. --- src/wl_init.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index e2bd2921..b1f98733 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -542,23 +542,19 @@ static xkb_keysym_t composeSymbol(xkb_keysym_t sym) } #endif -static GLFWbool inputChar(_GLFWwindow* window, uint32_t key) +static GLFWbool inputChar(_GLFWwindow* window, uint32_t scancode) { - uint32_t code, numSyms, codepoint; - const xkb_keysym_t *syms; - xkb_keysym_t sym; + const xkb_keysym_t* keysyms; + const xkb_keycode_t keycode = scancode + 8; - code = key + 8; - numSyms = xkb_state_key_get_syms(_glfw.wl.xkb.state, code, &syms); - - if (numSyms == 1) + if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1) { #ifdef HAVE_XKBCOMMON_COMPOSE_H - sym = composeSymbol(syms[0]); + const xkb_keysym_t keysym = composeSymbol(keysyms[0]); #else - sym = syms[0]; + const xkb_keysym_t keysym = keysyms[0]; #endif - codepoint = _glfwKeySym2Unicode(sym); + const uint32_t codepoint = _glfwKeySym2Unicode(keysym); if (codepoint != GLFW_INVALID_CODEPOINT) { const int mods = _glfw.wl.xkb.modifiers; @@ -567,7 +563,7 @@ static GLFWbool inputChar(_GLFWwindow* window, uint32_t key) } } - return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, code); + return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode); } static void keyboardHandleKey(void* data, From 293d19a1537e25d6a47c0e8fb080f94061f8d131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 30 Dec 2021 20:02:45 +0100 Subject: [PATCH 67/71] Wayland: Require xkbcommon 0.5.0 or greater The Wayland backend now requires xkbcommon-compose, which was added in version 0.5.0. xkbcommon 0.5.0 was released in 2014. This removes the non-composing fallback path for text input. --- docs/compat.dox | 5 ++--- src/CMakeLists.txt | 6 +----- src/wl_init.c | 16 ---------------- src/wl_platform.h | 8 -------- 4 files changed, 3 insertions(+), 32 deletions(-) diff --git a/docs/compat.dox b/docs/compat.dox index 5b264b3f..989c4c19 100644 --- a/docs/compat.dox +++ b/docs/compat.dox @@ -104,9 +104,8 @@ integration by libwayland-egl, and keyboard handling by from wayland-protocols to provide additional features if the compositor supports them. -GLFW uses xkbcommon 0.5.0 to provide compose key support. When it has been -built against an older xkbcommon, the compose key will be disabled even if it -has been configured in the compositor. +GLFW uses xkbcommon 0.5.0 to provide key and text input support. Earlier +versions are not supported. GLFW uses the [xdg-shell protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/xdg-shell/xdg-shell.xml) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 16cb1749..a07ca931 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -65,10 +65,6 @@ endif() if (GLFW_BUILD_WAYLAND) include(CheckIncludeFiles) include(CheckFunctionExists) - check_include_files(xkbcommon/xkbcommon-compose.h HAVE_XKBCOMMON_COMPOSE_H) - if (HAVE_XKBCOMMON_COMPOSE_H) - target_compile_definitions(glfw PRIVATE HAVE_XKBCOMMON_COMPOSE_H) - endif() check_function_exists(memfd_create HAVE_MEMFD_CREATE) if (HAVE_MEMFD_CREATE) target_compile_definitions(glfw PRIVATE HAVE_MEMFD_CREATE) @@ -173,7 +169,7 @@ if (GLFW_BUILD_WAYLAND) wayland-client>=0.2.7 wayland-cursor>=0.2.7 wayland-egl>=0.2.7 - xkbcommon) + xkbcommon>=0.5.0) target_include_directories(glfw PRIVATE ${Wayland_INCLUDE_DIRS}) diff --git a/src/wl_init.c b/src/wl_init.c index b1f98733..d9a70287 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -377,11 +377,8 @@ static void keyboardHandleKeymap(void* data, { struct xkb_keymap* keymap; struct xkb_state* state; - -#ifdef HAVE_XKBCOMMON_COMPOSE_H struct xkb_compose_table* composeTable; struct xkb_compose_state* composeState; -#endif char* mapStr; const char* locale; @@ -430,7 +427,6 @@ static void keyboardHandleKeymap(void* data, if (!locale) locale = "C"; -#ifdef HAVE_XKBCOMMON_COMPOSE_H composeTable = xkb_compose_table_new_from_locale(_glfw.wl.xkb.context, locale, XKB_COMPOSE_COMPILE_NO_FLAGS); @@ -450,7 +446,6 @@ static void keyboardHandleKeymap(void* data, _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to create XKB compose table"); } -#endif xkb_keymap_unref(_glfw.wl.xkb.keymap); xkb_state_unref(_glfw.wl.xkb.state); @@ -520,7 +515,6 @@ static int toGLFWKeyCode(uint32_t key) return GLFW_KEY_UNKNOWN; } -#ifdef HAVE_XKBCOMMON_COMPOSE_H static xkb_keysym_t composeSymbol(xkb_keysym_t sym) { if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState) @@ -540,7 +534,6 @@ static xkb_keysym_t composeSymbol(xkb_keysym_t sym) return sym; } } -#endif static GLFWbool inputChar(_GLFWwindow* window, uint32_t scancode) { @@ -549,11 +542,7 @@ static GLFWbool inputChar(_GLFWwindow* window, uint32_t scancode) if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1) { -#ifdef HAVE_XKBCOMMON_COMPOSE_H const xkb_keysym_t keysym = composeSymbol(keysyms[0]); -#else - const xkb_keysym_t keysym = keysyms[0]; -#endif const uint32_t codepoint = _glfwKeySym2Unicode(keysym); if (codepoint != GLFW_INVALID_CODEPOINT) { @@ -1299,8 +1288,6 @@ int _glfwInitWayland(void) _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_serialize_mods"); _glfw.wl.xkb.state_key_get_layout = (PFN_xkb_state_key_get_layout) _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_key_get_layout"); - -#ifdef HAVE_XKBCOMMON_COMPOSE_H _glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale) _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_table_new_from_locale"); _glfw.wl.xkb.compose_table_unref = (PFN_xkb_compose_table_unref) @@ -1315,7 +1302,6 @@ int _glfwInitWayland(void) _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_status"); _glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym) _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym"); -#endif _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display); wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL); @@ -1403,10 +1389,8 @@ void _glfwTerminateWayland(void) _glfw.wl.egl.handle = NULL; } -#ifdef HAVE_XKBCOMMON_COMPOSE_H if (_glfw.wl.xkb.composeState) xkb_compose_state_unref(_glfw.wl.xkb.composeState); -#endif if (_glfw.wl.xkb.keymap) xkb_keymap_unref(_glfw.wl.xkb.keymap); if (_glfw.wl.xkb.state) diff --git a/src/wl_platform.h b/src/wl_platform.h index e29f41b4..a26bd23e 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -26,9 +26,7 @@ #include #include -#ifdef HAVE_XKBCOMMON_COMPOSE_H #include -#endif typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; @@ -184,7 +182,6 @@ typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xk #define xkb_state_serialize_mods _glfw.wl.xkb.state_serialize_mods #define xkb_state_key_get_layout _glfw.wl.xkb.state_key_get_layout -#ifdef HAVE_XKBCOMMON_COMPOSE_H typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags); typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*); typedef struct xkb_compose_state* (* PFN_xkb_compose_state_new)(struct xkb_compose_table*, enum xkb_compose_state_flags); @@ -199,7 +196,6 @@ typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_st #define xkb_compose_state_feed _glfw.wl.xkb.compose_state_feed #define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status #define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym -#endif #define _GLFW_DECORATION_WIDTH 4 #define _GLFW_DECORATION_TOP 24 @@ -323,9 +319,7 @@ typedef struct _GLFWlibraryWayland struct xkb_keymap* keymap; struct xkb_state* state; -#ifdef HAVE_XKBCOMMON_COMPOSE_H struct xkb_compose_state* composeState; -#endif xkb_mod_mask_t controlMask; xkb_mod_mask_t altMask; @@ -349,7 +343,6 @@ typedef struct _GLFWlibraryWayland PFN_xkb_state_serialize_mods state_serialize_mods; PFN_xkb_state_key_get_layout state_key_get_layout; -#ifdef HAVE_XKBCOMMON_COMPOSE_H PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale; PFN_xkb_compose_table_unref compose_table_unref; PFN_xkb_compose_state_new compose_state_new; @@ -357,7 +350,6 @@ typedef struct _GLFWlibraryWayland PFN_xkb_compose_state_feed compose_state_feed; PFN_xkb_compose_state_get_status compose_state_get_status; PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym; -#endif } xkb; _GLFWwindow* pointerFocus; From bf995870052d5076ce80c4728eb6fd4054dd9742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 30 Dec 2021 21:06:22 +0100 Subject: [PATCH 68/71] Wayland: Clean up key event handler Adapt style and naming to match the rest of the project. --- src/wl_init.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index d9a70287..c57a7e73 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -559,42 +559,40 @@ static void keyboardHandleKey(void* data, struct wl_keyboard* keyboard, uint32_t serial, uint32_t time, - uint32_t key, + uint32_t scancode, uint32_t state) { - int keyCode; - int action; _GLFWwindow* window = _glfw.wl.keyboardFocus; - GLFWbool shouldRepeat; - struct itimerspec timer = {}; - if (!window) return; - keyCode = toGLFWKeyCode(key); - action = state == WL_KEYBOARD_KEY_STATE_PRESSED - ? GLFW_PRESS : GLFW_RELEASE; + const int key = toGLFWKeyCode(scancode); + const int action = + state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE; _glfw.wl.serial = serial; - _glfwInputKey(window, keyCode, key, action, - _glfw.wl.xkb.modifiers); + _glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers); + + struct itimerspec timer = {}; if (action == GLFW_PRESS) { - shouldRepeat = inputChar(window, key); + const GLFWbool shouldRepeat = inputChar(window, scancode); if (shouldRepeat && _glfw.wl.keyboardRepeatRate > 0) { - _glfw.wl.keyboardLastKey = keyCode; - _glfw.wl.keyboardLastScancode = key; + _glfw.wl.keyboardLastKey = key; + _glfw.wl.keyboardLastScancode = scancode; if (_glfw.wl.keyboardRepeatRate > 1) timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyboardRepeatRate; else timer.it_interval.tv_sec = 1; + timer.it_value.tv_sec = _glfw.wl.keyboardRepeatDelay / 1000; timer.it_value.tv_nsec = (_glfw.wl.keyboardRepeatDelay % 1000) * 1000000; } } + timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL); } From 1a7da42e6ebaa4e8eeffb693c32c8d36d54ddf6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Thu, 30 Dec 2021 21:09:23 +0100 Subject: [PATCH 69/71] Wayland: Fix text input not following key repeat The manual key repeat implementation did not call text input. --- README.md | 1 + src/wl_init.c | 4 ++-- src/wl_platform.h | 1 + src/wl_window.c | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 06108a86..4a3fb85c 100644 --- a/README.md +++ b/README.md @@ -288,6 +288,7 @@ information on what to include when reporting a bug. - [Wayland] Bugfix: Showing a hidden window did not emit a window refresh event - [Wayland] Bugfix: Full screen window creation did not ignore `GLFW_VISIBLE` - [Wayland] Bugfix: Some keys were reported as wrong key or `GLFW_KEY_UNKNOWN` + - [Wayland] Bugfix: Text input did not repeat along with key repeat - [POSIX] Removed use of deprecated function `gettimeofday` - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled - [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072) diff --git a/src/wl_init.c b/src/wl_init.c index c57a7e73..83cd7aca 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -535,7 +535,7 @@ static xkb_keysym_t composeSymbol(xkb_keysym_t sym) } } -static GLFWbool inputChar(_GLFWwindow* window, uint32_t scancode) +GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode) { const xkb_keysym_t* keysyms; const xkb_keycode_t keycode = scancode + 8; @@ -577,7 +577,7 @@ static void keyboardHandleKey(void* data, if (action == GLFW_PRESS) { - const GLFWbool shouldRepeat = inputChar(window, scancode); + const GLFWbool shouldRepeat = _glfwInputTextWayland(window, scancode); if (shouldRepeat && _glfw.wl.keyboardRepeatRate > 0) { diff --git a/src/wl_platform.h b/src/wl_platform.h index a26bd23e..7565411b 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -495,4 +495,5 @@ GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp); void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); void _glfwAddOutputWayland(uint32_t name, uint32_t version); +GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode); diff --git a/src/wl_window.c b/src/wl_window.c index 48ffb7c2..b2aa1800 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -767,6 +767,8 @@ static void handleEvents(int timeout) _glfw.wl.keyboardLastScancode, GLFW_PRESS, _glfw.wl.xkb.modifiers); + _glfwInputTextWayland(_glfw.wl.keyboardFocus, + _glfw.wl.keyboardLastScancode); } } } From 0ce611958ee6fe9ddbd799986711759c9156566a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 31 Dec 2021 00:19:08 +0100 Subject: [PATCH 70/71] Wayland: Clean up key translation Adapt style and naming to match the rest of the project. --- src/wl_init.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index 83cd7aca..2f138578 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -507,10 +507,10 @@ static void keyboardHandleLeave(void* data, _glfwInputWindowFocus(window, GLFW_FALSE); } -static int toGLFWKeyCode(uint32_t key) +static int translateKey(uint32_t scancode) { - if (key < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0])) - return _glfw.wl.keycodes[key]; + if (scancode < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0])) + return _glfw.wl.keycodes[scancode]; return GLFW_KEY_UNKNOWN; } @@ -566,7 +566,7 @@ static void keyboardHandleKey(void* data, if (!window) return; - const int key = toGLFWKeyCode(scancode); + const int key = translateKey(scancode); const int action = state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE; From df8d7bc892937a8b0f7c604c92a9f64f383cf48c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Fri, 31 Dec 2021 00:19:58 +0100 Subject: [PATCH 71/71] Wayland: Clean up modifier key event handler Adapt style and naming to match the rest of the project. --- src/wl_init.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/wl_init.c b/src/wl_init.c index 2f138578..e7756385 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -604,9 +604,6 @@ static void keyboardHandleModifiers(void* data, uint32_t modsLocked, uint32_t group) { - xkb_mod_mask_t mask; - unsigned int modifiers = 0; - _glfw.wl.serial = serial; if (!_glfw.wl.xkb.keymap) @@ -620,24 +617,29 @@ static void keyboardHandleModifiers(void* data, 0, group); - mask = xkb_state_serialize_mods(_glfw.wl.xkb.state, - XKB_STATE_MODS_DEPRESSED | - XKB_STATE_LAYOUT_DEPRESSED | - XKB_STATE_MODS_LATCHED | - XKB_STATE_LAYOUT_LATCHED); + const xkb_mod_mask_t mask = + xkb_state_serialize_mods(_glfw.wl.xkb.state, + XKB_STATE_MODS_DEPRESSED | + XKB_STATE_LAYOUT_DEPRESSED | + XKB_STATE_MODS_LATCHED | + XKB_STATE_LAYOUT_LATCHED); + + unsigned int mods = 0; + if (mask & _glfw.wl.xkb.controlMask) - modifiers |= GLFW_MOD_CONTROL; + mods |= GLFW_MOD_CONTROL; if (mask & _glfw.wl.xkb.altMask) - modifiers |= GLFW_MOD_ALT; + mods |= GLFW_MOD_ALT; if (mask & _glfw.wl.xkb.shiftMask) - modifiers |= GLFW_MOD_SHIFT; + mods |= GLFW_MOD_SHIFT; if (mask & _glfw.wl.xkb.superMask) - modifiers |= GLFW_MOD_SUPER; + mods |= GLFW_MOD_SUPER; if (mask & _glfw.wl.xkb.capsLockMask) - modifiers |= GLFW_MOD_CAPS_LOCK; + mods |= GLFW_MOD_CAPS_LOCK; if (mask & _glfw.wl.xkb.numLockMask) - modifiers |= GLFW_MOD_NUM_LOCK; - _glfw.wl.xkb.modifiers = modifiers; + mods |= GLFW_MOD_NUM_LOCK; + + _glfw.wl.xkb.modifiers = mods; } #ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION