diff --git a/CMakeLists.txt b/CMakeLists.txt index fcd6da117..414162969 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project(GLFW C) set(CMAKE_LEGACY_CYGWIN_WIN32 OFF) -if (NOT CMAKE_VERSION VERSION_LESS "3.1") +if (POLICY CMP0054) cmake_policy(SET CMP0054 NEW) endif() @@ -14,7 +14,6 @@ set(GLFW_VERSION_PATCH "0") set(GLFW_VERSION_EXTRA "") set(GLFW_VERSION "${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}") set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA}") -set(LIB_SUFFIX "" CACHE STRING "Takes an empty string or 64. Directory where lib will be installed: lib or lib64") set_property(GLOBAL PROPERTY USE_FOLDERS ON) @@ -25,6 +24,8 @@ option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON) option(GLFW_INSTALL "Generate installation target" ON) option(GLFW_VULKAN_STATIC "Use the Vulkan loader statically linked into application" OFF) +include(GNUInstallDirs) + if (UNIX) option(GLFW_USE_OSMESA "Use OSMesa for offscreen context creation" OFF) endif() @@ -320,7 +321,7 @@ endforeach() #-------------------------------------------------------------------- include(CMakePackageConfigHelpers) -set(GLFW_CONFIG_PATH "lib${LIB_SUFFIX}/cmake/glfw3") +set(GLFW_CONFIG_PATH "${CMAKE_INSTALL_LIBDIR}/cmake/glfw3") configure_package_config_file(src/glfw3Config.cmake.in src/glfw3Config.cmake @@ -357,7 +358,7 @@ endif() # The library is installed by src/CMakeLists.txt #-------------------------------------------------------------------- if (GLFW_INSTALL) - install(DIRECTORY include/GLFW DESTINATION include + install(DIRECTORY include/GLFW DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN glfw3.h PATTERN glfw3native.h) install(FILES "${GLFW_BINARY_DIR}/src/glfw3Config.cmake" @@ -368,7 +369,7 @@ if (GLFW_INSTALL) EXPORT_LINK_INTERFACE_LIBRARIES DESTINATION "${GLFW_CONFIG_PATH}") install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc" - DESTINATION "lib${LIB_SUFFIX}/pkgconfig") + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") # Only generate this target if no higher-level project already has if (NOT TARGET uninstall) diff --git a/README.md b/README.md index 6d4e67846..6366a4f37 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,8 @@ information on what to include when reporting a bug. (#749,#842) - Added `GLFW_FOCUS_ON_SHOW` window hint and attribute to control input focus on calling show window (#1189) +- Added `GLFW_SCALE_TO_MONITOR` window hint for automatic window resizing + (#676,#1115) - Added `GLFW_JOYSTICK_HAT_BUTTONS` init hint (#889) - Added `GLFW_LOCK_KEY_MODS` input mode and `GLFW_MOD_*_LOCK` mod bits (#946) - Added macOS specific `GLFW_COCOA_RETINA_FRAMEBUFFER` window hint @@ -195,6 +197,8 @@ information on what to include when reporting a bug. - Bugfix: Invalid library paths were used in test and example CMake files (#930) - Bugfix: The scancode for synthetic key release events was always zero - Bugfix: The generated Doxyfile did not handle paths with spaces (#1081) +- Bugfix: The gamma ramp generated by `glfwSetGamma` did not use the monitor + ramp size (#1387,#1388) - [Win32] Added system error strings to relevant GLFW error descriptions (#733) - [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125) - [Win32] Removed XInput circular deadzone from joystick axis data (#1045) @@ -223,6 +227,8 @@ information on what to include when reporting a bug. hint set to false (#1179,#1180) - [Win32] Bugfix: The keypad equals key was reported as `GLFW_KEY_UNKNOWN` (#1315,#1316) +- [Win32] Bugfix: A title bar would be drawn over undecorated windows in some + circumstances (#1383) - [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125) - [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading - [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X @@ -237,6 +243,8 @@ information on what to include when reporting a bug. - [X11] Bugfix: Selection I/O reported but did not support `COMPOUND_TEXT` - [X11] Bugfix: Latin-1 text read from selections was not converted to UTF-8 - [X11] Bugfix: NVidia EGL would segfault if unloaded before closing the display +- [X11] Bugfix: Checking window maximized attrib could crash some WMs (#1356) +- [X11] Bugfix: Update cursor position on enter event (#1366) - [Linux] Added workaround for missing `SYN_DROPPED` in pre-2.6.39 kernel headers (#1196) - [Linux] Moved to evdev for joystick input (#906,#1005) @@ -269,6 +277,9 @@ information on what to include when reporting a bug. - [Cocoa] Bugfix: Window was resized twice when entering full screen (#1085) - [Cocoa] Bugfix: Duplicate size events were not filtered (#1085) - [Cocoa] Bugfix: Event polling did not initialize AppKit if necessary (#1218) +- [Cocoa] Bugfix: OpenGL rendering was not initially visible on 10.14 + (#1334,#1346) +- [Cocoa] Bugfix: Caps Lock did not generate any key events (#1368,#1373) - [WGL] Added support for `WGL_EXT_colorspace` for OpenGL ES contexts - [WGL] Added support for `WGL_ARB_create_context_no_error` - [GLX] Added support for `GLX_ARB_create_context_no_error` @@ -308,6 +319,7 @@ skills. - John Bartholomew - Coşku Baş - Niklas Behrens + - Andrew Belt - Niklas Bergström - Denis Bernard - Doug Binks @@ -374,6 +386,7 @@ skills. - Glenn Lewis - Shane Liesegang - Eyal Lotem + - Aaron Loucks - Tristam MacDonald - Hans Mackowiak - Дмитри Малышев @@ -390,6 +403,7 @@ skills. - Bruce Mitchener - Jack Moffitt - Jeff Molofee + - Alexander Monakov - Pierre Morel - Jon Morton - Pierre Moulon diff --git a/deps/nuklear.h b/deps/nuklear.h index 05b9b3df2..6c873535b 100644 --- a/deps/nuklear.h +++ b/deps/nuklear.h @@ -13644,7 +13644,7 @@ nk_font_atlas_bake(struct nk_font_atlas *atlas, int *width, int *height, #ifdef NK_INCLUDE_DEFAULT_FONT /* no font added so just use default font */ if (!atlas->font_num) - atlas->default_font = nk_font_atlas_add_default(atlas, 20.0f, 0); + atlas->default_font = nk_font_atlas_add_default(atlas, 13.0f, 0); #endif NK_ASSERT(atlas->font_num); if (!atlas->font_num) return 0; diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 6d85f5cd5..3bee43b95 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -35,7 +35,7 @@ questions without first checking with a maintainer. ## Reporting a bug If GLFW is behaving unexpectedly at run-time, start by setting an [error -callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling). +callback](https://www.glfw.org/docs/latest/intro_guide.html#error_handling). GLFW will often tell you the cause of an error via this callback. If it doesn't, that might be a separate bug. @@ -87,8 +87,8 @@ means linking to many system libraries. If you are using GLFW as a static library, that means your application needs to link to these in addition to GLFW. __Note:__ Check the [Compiling -GLFW](http://www.glfw.org/docs/latest/compile.html) guide and or [Building -applications](http://www.glfw.org/docs/latest/build.html) guide for before +GLFW](https://www.glfw.org/docs/latest/compile.html) guide and or [Building +applications](https://www.glfw.org/docs/latest/build.html) guide for before opening an issue of this kind. Most issues are caused by a missing package or linker flag. @@ -121,7 +121,7 @@ __GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git. Please also include any __error messages__ provided to your application via the [error -callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling) and +callback](https://www.glfw.org/docs/latest/intro_guide.html#error_handling) and the __full call stack__ of the crash, or if the crash does not occur in debug mode, mention that instead. @@ -141,13 +141,13 @@ Call stack: __Note:__ Windows ships with graphics drivers that do not support OpenGL. If GLFW says that your machine lacks support for OpenGL, it very likely does. Install drivers from the computer manufacturer or graphics card manufacturer -([Nvidia](http://www.geforce.com/drivers), -[AMD](http://support.amd.com/en-us/download), +([Nvidia](https://www.geforce.com/drivers), +[AMD](https://www.amd.com/en/support), [Intel](https://www-ssl.intel.com/content/www/us/en/support/detect.html)) to fix this. __Note:__ AMD only supports OpenGL ES on Windows via EGL. See the -[GLFW\_CONTEXT\_CREATION\_API](http://www.glfw.org/docs/latest/window_guide.html#window_hints_ctx) +[GLFW\_CONTEXT\_CREATION\_API](https://www.glfw.org/docs/latest/window_guide.html#window_hints_ctx) hint for how to select EGL. Please verify that context creation also fails with the `glfwinfo` tool before @@ -165,7 +165,7 @@ include the __VM name and version__ (e.g. `VirtualBox 5.1`). Please also include the __GLFW version string__ (`3.2.0 X11 EGL clock_gettime /dev/js`), as described -[here](http://www.glfw.org/docs/latest/intro.html#intro_version_string), the +[here](https://www.glfw.org/docs/latest/intro.html#intro_version_string), the __GPU model and driver version__ (e.g. `GeForce GTX660 with 352.79`), and the __output of `glfwinfo`__ (with switches matching any hints you set in your code) when reporting this kind of bug. If this tool doesn't run on the machine, @@ -207,7 +207,7 @@ include the __VM name and version__ (e.g. `VirtualBox 5.1`). Please also include any __error messages__ provided to your application via the [error -callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling) and +callback](https://www.glfw.org/docs/latest/intro_guide.html#error_handling) and the __output of `monitors`__ when reporting this kind of bug. If this tool doesn't run on the machine, mention this instead. @@ -228,7 +228,7 @@ __Note:__ The exact ordering of related window events will sometimes differ. __Note:__ Window moving and resizing (by the user) will block the main thread on some platforms. This is not a bug. Set a [refresh -callback](http://www.glfw.org/docs/latest/window.html#window_refresh) if you +callback](https://www.glfw.org/docs/latest/window.html#window_refresh) if you want to keep the window contents updated during a move or size operation. The `events` tool is included in the GLFW source tree as `tests/events.c` and is @@ -247,7 +247,7 @@ include the __VM name and version__ (e.g. `VirtualBox 5.1`). Please also include any __error messages__ provided to your application via the [error -callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling) and +callback](https://www.glfw.org/docs/latest/intro_guide.html#error_handling) and if relevant, the __output of `events`__ when reporting this kind of bug. If this tool doesn't run on the machine, mention this instead. @@ -276,7 +276,7 @@ __GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git. Please also include any __error messages__ provided to your application via the [error -callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling), if +callback](https://www.glfw.org/docs/latest/intro_guide.html#error_handling), if relevant. @@ -299,7 +299,7 @@ the source to the output or vice versa. ### Reporting a website bug If the bug is in the documentation (anything under `/docs/`) then please see the -section above. Bugs in the rest of the site are reported to to the [website +section above. Bugs in the rest of the site are reported to the [website source repository](https://github.com/glfw/website/issues). diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in index 51f2b093a..27ed92c4b 100644 --- a/docs/Doxyfile.in +++ b/docs/Doxyfile.in @@ -195,12 +195,12 @@ TAB_SIZE = 8 # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. -ALIASES = "thread_safety=@par Thread safety\n" \ - "pointer_lifetime=@par Pointer lifetime\n" \ - "analysis=@par Analysis\n" \ - "reentrancy=@par Reentrancy\n" \ - "errors=@par Errors\n" \ - "glfw3=@par\n__GLFW 3:__" \ +ALIASES = "thread_safety=@par Thread safety^^" \ + "pointer_lifetime=@par Pointer lifetime^^" \ + "analysis=@par Analysis^^" \ + "reentrancy=@par Reentrancy^^" \ + "errors=@par Errors^^" \ + "glfw3=__GLFW 3:__" \ "x11=__X11:__" \ "wayland=__Wayland:__" \ "win32=__Windows:__" \ @@ -264,7 +264,7 @@ MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented classes, # or namespaces to their corresponding documentation. Such a link can be -# prevented in individual cases by by putting a % sign in front of the word or +# prevented in individual cases by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. AUTOLINK_SUPPORT = YES @@ -589,7 +589,7 @@ FILE_VERSION_FILTER = # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. -LAYOUT_FILE = +LAYOUT_FILE = "@GLFW_SOURCE_DIR@/docs/DoxygenLayout.xml" # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The diff --git a/docs/DoxygenLayout.xml b/docs/DoxygenLayout.xml index a7e175306..ab9717218 100644 --- a/docs/DoxygenLayout.xml +++ b/docs/DoxygenLayout.xml @@ -1,115 +1,21 @@ - + + - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + @@ -117,9 +23,7 @@ - - @@ -131,46 +35,26 @@ - - - - - - - - - - - - - - - - - - - - @@ -178,7 +62,6 @@ - diff --git a/docs/build.dox b/docs/build.dox index 6304d4254..b4502c732 100644 --- a/docs/build.dox +++ b/docs/build.dox @@ -152,7 +152,7 @@ environment below. On Linux and other Unix-like operating systems, the list varies but can be retrieved in various ways as described below. A good general introduction to linking is -[Beginner's Guide to Linkers](http://www.lurklurk.org/linkers/linkers.html) by +[Beginner's Guide to Linkers](https://www.lurklurk.org/linkers/linkers.html) by David Drysdale. @@ -161,11 +161,12 @@ David Drysdale. The static version of the GLFW library is named `glfw3`. When using this version, it is also necessary to link with some libraries that GLFW uses. -When linking an application under Windows that uses the static version of GLFW, -you must link with `opengl32`. On some versions of MinGW, you must also -explicitly link with `gdi32`, while other versions of MinGW include it in the -set of default libraries along with other dependencies like `user32` and -`kernel32`. If you are using GLU, you must also link with `glu32`. +When using MinGW to link an application with the static version of GLFW, you +must also explicitly link with `gdi32`. Other toolchains including MinGW-w64 +include it in the set of default libraries along with other dependencies like +`user32` and `kernel32`. + +If you are using GLU, you must also link with `glu32`. The link library for the GLFW DLL is named `glfw3dll`. When compiling an application that uses the DLL version of GLFW, you need to define the @ref @@ -173,8 +174,7 @@ GLFW_DLL macro _before_ any inclusion of the GLFW header. This can be done either with a compiler switch or by defining it in your source code. An application using the GLFW DLL does not need to link against any of its -dependencies, but you still have to link against `opengl32` if your application -uses OpenGL and `glu32` if it uses GLU. +dependencies, but you still have to link against `glu32` if it uses GLU. @subsection build_link_cmake_source With CMake and GLFW source @@ -298,7 +298,7 @@ transition guide for suggested replacements. @subsection build_link_pkgconfig With makefiles and pkg-config on Unix -GLFW supports [pkg-config](http://www.freedesktop.org/wiki/Software/pkg-config/), +GLFW supports [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/), and the `glfw3.pc` pkg-config file is generated when the GLFW library is built and is installed along with it. A pkg-config file describes all necessary compile-time and link-time flags and dependencies needed to use a library. When diff --git a/docs/compat.dox b/docs/compat.dox index ade24ec8e..98e045cb6 100644 --- a/docs/compat.dox +++ b/docs/compat.dox @@ -23,9 +23,9 @@ varied window managers in use on Unix-like systems. In order for applications and window managers to work well together, a number of standards and conventions have been developed that regulate behavior outside the scope of the X11 API; most importantly the -[Inter-Client Communication Conventions Manual](http://www.tronche.com/gui/x/icccm/) +[Inter-Client Communication Conventions Manual](https://www.tronche.com/gui/x/icccm/) (ICCCM) and -[Extended Window Manager Hints](http://standards.freedesktop.org/wm-spec/wm-spec-latest.html) +[Extended Window Manager Hints](https://standards.freedesktop.org/wm-spec/wm-spec-latest.html) (EWMH) standards. GLFW uses the `_MOTIF_WM_HINTS` window property to support borderless windows. @@ -53,13 +53,13 @@ running window manager uses compositing but does not support this property then additional copying may be performed for each buffer swap of full screen windows. GLFW uses the -[clipboard manager protocol](http://www.freedesktop.org/wiki/ClipboardManager/) +[clipboard manager protocol](https://www.freedesktop.org/wiki/ClipboardManager/) to push a clipboard string (i.e. selection) owned by a GLFW window about to be destroyed to the clipboard manager. If there is no running clipboard manager, the clipboard string will be unavailable once the window has been destroyed. GLFW uses the -[X drag-and-drop protocol](http://www.freedesktop.org/wiki/Specifications/XDND/) +[X drag-and-drop protocol](https://www.freedesktop.org/wiki/Specifications/XDND/) to provide file drop events. If the application originating the drag does not support this protocol, drag and drop will not work. diff --git a/docs/compile.dox b/docs/compile.dox index 762143a20..e03b74aad 100644 --- a/docs/compile.dox +++ b/docs/compile.dox @@ -10,12 +10,12 @@ build applications that use GLFW, see @ref build_guide. @section compile_cmake Using CMake -GLFW uses [CMake](http://www.cmake.org/) to generate project files or makefiles +GLFW uses [CMake](https://cmake.org/) to generate project files or makefiles for a particular development environment. If you are on a Unix-like system such as Linux or FreeBSD or have a package system like Fink, MacPorts, Cygwin or Homebrew, you can install its CMake package. If not, you can download installers for Windows and macOS from the -[CMake website](http://www.cmake.org/). +[CMake website](https://cmake.org/). @note CMake only generates project files or makefiles. It does not compile the actual GLFW library. To compile GLFW, first generate these files for your @@ -71,7 +71,7 @@ cmake -DCMAKE_TOOLCHAIN_FILE=CMake/x86_64-w64-mingw32.cmake . @endcode For more details see the article -[CMake Cross Compiling](http://www.paraview.org/Wiki/CMake_Cross_Compiling) on +[CMake Cross Compiling](https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/CrossCompiling) on the CMake wiki. Once you have this set up, move on to @ref compile_generate. @@ -210,11 +210,6 @@ cmake -DBUILD_SHARED_LIBS=ON . __BUILD_SHARED_LIBS__ determines whether GLFW is built as a static library or as a DLL / shared library / dynamic library. -@anchor LIB_SUFFIX -__LIB_SUFFIX__ affects where the GLFW shared /dynamic library is installed. If -it is empty, it is installed to `${CMAKE_INSTALL_PREFIX}/lib`. If it is set to -`64`, it is installed to `${CMAKE_INSTALL_PREFIX}/lib64`. - @anchor GLFW_BUILD_EXAMPLES __GLFW_BUILD_EXAMPLES__ determines whether the GLFW examples are built along with the library. diff --git a/docs/context.dox b/docs/context.dox index 5e1eb25c1..69b8fa7fd 100644 --- a/docs/context.dox +++ b/docs/context.dox @@ -56,7 +56,7 @@ platforms where it is possible to choose which types of objects are shared, GLFW requests that all types are shared. See the relevant chapter of the [OpenGL](https://www.opengl.org/registry/) or -[OpenGL ES](http://www.khronos.org/opengles/) reference documents for more +[OpenGL ES](https://www.khronos.org/opengles/) reference documents for more information. The name and number of this chapter unfortunately varies between versions and APIs, but has at times been named _Shared Objects and Multiple Contexts_. @@ -151,7 +151,7 @@ for official extensions. The extension above was created by the ARB, but there are many different affixes, like `NV` for Nvidia and `AMD` for, well, AMD. Any group may also use the generic `EXT` affix. Lists of extensions, together with their specifications, can be found at the -[OpenGL Registry](http://www.opengl.org/registry/) and +[OpenGL Registry](https://www.opengl.org/registry/) and [OpenGL ES Registry](https://www.khronos.org/registry/gles/). @@ -255,7 +255,7 @@ of OpenGL ES extensions is identical except for the name of the extension header The `glext.h` extension header is a continually updated file that defines the interfaces for all OpenGL extensions. The latest version of this can always be -found at the [OpenGL Registry](http://www.opengl.org/registry/). There are also +found at the [OpenGL Registry](https://www.opengl.org/registry/). There are also extension headers for the various versions of OpenGL ES at the [OpenGL ES Registry](https://www.khronos.org/registry/gles/). It it strongly recommended that you use your own copy of the extension header, as the one diff --git a/docs/extra.css b/docs/extra.css index 42091cd10..032b7c2fa 100644 --- a/docs/extra.css +++ b/docs/extra.css @@ -1 +1 @@ -.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{background:none}#titlearea,.footer,.contents,div.header,.memdoc,table.doxtable td,table.doxtable 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{padding:0}#nav-path,.directory .levels,span.lineno{display:none}html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code{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;height:64px;max-width:920px;min-width:800px;padding:0 32px;margin:0 auto}#glfwhome{line-height:64px;padding-right:48px;color:#666;font-size:2.5em;background:url("http://www.glfw.org/css/arrow.png") no-repeat right}.glfwnavbar{list-style-type:none;margin:0 auto;float:right}#glfwhome,.glfwnavbar li{float:left}.glfwnavbar a,.glfwnavbar a:visited{line-height:64px;margin-left:2em;display:block;color:#666}#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;min-width:800px;margin:0 auto;font-size:13px}#main-menu{max-width:920px;min-width:800px;margin:0 auto;font-size:13px}.memtitle{display:none}.memproto,.memname{font-weight:bold;text-shadow:none}#main-menu{height:36px;display:block;position:relative}#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}.contents{min-height:590px}div.contents,div.header{max-width:920px;margin:0 auto;padding:0 32px;background:#fff none}table.doxtable 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: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{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 #afe599}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 #e5c499}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 #e599bb}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 #99cce5}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} +.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{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:0.5em;font-size:180%}h2{padding-top:0.5em;margin-bottom:0;font-size:140%}h3{padding-top:0.5em;margin-bottom:0;font-size:110%}.glfwheader{font-size:16px;height:64px;max-width:920px;min-width:800px;padding:0 32px;margin:0 auto}#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 auto;float:right}#glfwhome,.glfwnavbar li{float:left}.glfwnavbar a,.glfwnavbar a:visited{line-height:64px;margin-left:2em;display:block;color:#666}#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;min-width:800px;margin:0 auto;font-size:13px}#main-menu{max-width:920px;min-width:800px;margin:0 auto;font-size:13px}.memtitle{display:none}.memproto,.memname{font-weight:bold;text-shadow:none}#main-menu{height:36px;display:block;position:relative}#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}.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: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 #afe599}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 #e5c499}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 #e599bb}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 #99cce5}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} diff --git a/docs/extra.less b/docs/extra.less index 53e94f751..ff1dd69e3 100644 --- a/docs/extra.less +++ b/docs/extra.less @@ -103,11 +103,11 @@ 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 { +#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,hr,.memSeparator { +#titlearea,.footer,.contents,div.header,.memdoc,table.doxtable td,table.doxtable th,table.markdownTable td,table.markdownTable th,hr,.memSeparator { border:none; } @@ -119,7 +119,7 @@ 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 { +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; } @@ -127,7 +127,7 @@ div.headertitle,.note code,.pre code,.post code,.invariant code,.warning code,.a display:none; } -html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code { +html,#titlearea,.footer,tr.even,.directory tr.even,.doxtable tr:nth-child(even),tr.markdownTableBody:nth-child(even),.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,code { background:@header-footer-background-color; } @@ -171,7 +171,7 @@ h3 { padding-right:48px; color:@header-footer-link-color; font-size:2.5em; - background:url("http://www.glfw.org/css/arrow.png") no-repeat right; + background:url("https://www.glfw.org/css/arrow.png") no-repeat right; } .glfwnavbar { @@ -261,7 +261,7 @@ div.contents,div.header { background:@content-background-color none; } -table.doxtable th,dl.reflist dt { +table.doxtable th,table.markdownTable th,dl.reflist dt { background:linear-gradient(to bottom,@table-background-color2 0%,@table-background-color1 100%); box-shadow:inset 0 0 32px @table-background-color1; text-shadow:0 -1px 1px darken(@table-background-color1, 15%); @@ -322,7 +322,7 @@ dl.reflist dd { border-top:none; } -table.doxtable { +table.doxtable,table.markdownTable { border-collapse:inherit; border-spacing:0; border:2px solid @default-border-color; diff --git a/docs/header.html b/docs/header.html index 16b09a721..f42f49ee4 100644 --- a/docs/header.html +++ b/docs/header.html @@ -21,11 +21,11 @@ $extrastylesheet diff --git a/docs/input.dox b/docs/input.dox index 095481c36..84978bd09 100644 --- a/docs/input.dox +++ b/docs/input.dox @@ -162,7 +162,7 @@ missed the key press. The recommended solution for this is to use a key callback, but there is also the `GLFW_STICKY_KEYS` input mode. @code -glfwSetInputMode(window, GLFW_STICKY_KEYS, 1); +glfwSetInputMode(window, GLFW_STICKY_KEYS, GLFW_TRUE); @endcode When sticky keys mode is enabled, the pollable state of a key will remain @@ -175,7 +175,7 @@ If you wish to know what the state of the Caps Lock and Num Lock keys was when input events were generated, set the `GLFW_LOCK_KEY_MODS` input mode. @code -glfwSetInputMode(window, GLFW_LOCK_KEY_MODS, 1); +glfwSetInputMode(window, GLFW_LOCK_KEY_MODS, GLFW_TRUE); @endcode When this input mode is enabled, any callback that receives @@ -245,7 +245,7 @@ If you wish to be notified when the cursor moves over the window, set a cursor position callback. @code -glfwSetCursorPosCallback(window, cursor_pos_callback); +glfwSetCursorPosCallback(window, cursor_position_callback); @endcode The callback functions receives the cursor position, measured in screen @@ -475,7 +475,7 @@ mouse button callback, but there is also the `GLFW_STICKY_MOUSE_BUTTONS` input mode. @code -glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, 1); +glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, GLFW_TRUE); @endcode When sticky mouse buttons mode is enabled, the pollable state of a mouse button @@ -523,7 +523,7 @@ int present = glfwJoystickPresent(GLFW_JOYSTICK_1); Each joystick has zero or more axes, zero or more buttons, zero or more hats, a human-readable name, a user pointer and an SDL compatible GUID. -When GLFW is initialized, detected joysticks are added to to the beginning of +When GLFW is initialized, detected joysticks are added to the beginning of the array. Once a joystick is detected, it keeps its assigned ID until it is disconnected or the library is terminated, so as joysticks are connected and disconnected, there may appear gaps in the IDs. @@ -583,7 +583,7 @@ const unsigned char* hats = glfwGetJoystickHats(GLFW_JOYSTICK_7, &count); Each element in the returned array is one of the following: Name | Value ---------------------- | -------------------------------- +---- | ----- `GLFW_HAT_CENTERED` | 0 `GLFW_HAT_UP` | 1 `GLFW_HAT_RIGHT` | 2 diff --git a/docs/main.dox b/docs/main.dox index a1a093f56..9dcbcdc83 100644 --- a/docs/main.dox +++ b/docs/main.dox @@ -9,7 +9,7 @@ Vulkan application development. It provides a simple, platform-independent API for creating windows, contexts and surfaces, reading input, handling events, etc. See @ref news_33 for highlights or the -[version history](http://www.glfw.org/changelog.html) for details. +[version history](https://www.glfw.org/changelog.html) for details. @ref quick_guide is a guide for users new to GLFW. It takes you through how to write a small but complete program. @@ -34,14 +34,14 @@ use the new API. There is a section on @ref guarantees_limitations for pointer lifetimes, reentrancy, thread safety, event order and backward and forward compatibility. -The [FAQ](http://www.glfw.org/faq.html) answers many common questions about the +The [FAQ](https://www.glfw.org/faq.html) answers many common questions about the design, implementation and use of GLFW. Finally, @ref compat_guide explains what APIs, standards and protocols GLFW uses and what happens when they are not present on a given machine. This documentation was generated with Doxygen. The sources for it are available -in both the [source distribution](http://www.glfw.org/download.html) and +in both the [source distribution](https://www.glfw.org/download.html) and [GitHub repository](https://github.com/glfw/glfw). */ diff --git a/docs/monitor.dox b/docs/monitor.dox index 08c119336..b23482b6e 100644 --- a/docs/monitor.dox +++ b/docs/monitor.dox @@ -101,7 +101,7 @@ size and a gamma ramp. @subsection monitor_modes Video modes GLFW generally does a good job selecting a suitable video mode when you create -a full screen window, change its video mode or or make a windowed one full +a full screen window, change its video mode or make a windowed one full screen, but it is sometimes useful to know exactly which video modes are supported. diff --git a/docs/moving.dox b/docs/moving.dox index 08ef7f24c..85ba0a70c 100644 --- a/docs/moving.dox +++ b/docs/moving.dox @@ -38,8 +38,8 @@ The threading functions have been removed, including the per-thread sleep function. They were fairly primitive, under-used, poorly integrated and took time away from the focus of GLFW (i.e. context, input and window). There are better threading libraries available and native threading support is available -in both [C++11](http://en.cppreference.com/w/cpp/thread) and -[C11](http://en.cppreference.com/w/c/thread), both of which are gaining +in both [C++11](https://en.cppreference.com/w/cpp/thread) and +[C11](https://en.cppreference.com/w/c/thread), both of which are gaining traction. If you wish to use the C++11 or C11 facilities but your compiler doesn't yet @@ -87,7 +87,7 @@ platform-independent, as both OpenGL and stdio are available wherever GLFW is. @subsection moving_stdcall Removal of GLFWCALL macro The `GLFWCALL` macro, which made callback functions use -[__stdcall](http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx) on Windows, +[__stdcall](https://msdn.microsoft.com/en-us/library/zxk0tw93.aspx) on Windows, has been removed. GLFW is written in C, not Pascal. Removing this macro means there's one less thing for application programmers to remember, i.e. the requirement to mark all callback functions with `GLFWCALL`. It also simplifies @@ -379,7 +379,7 @@ glfwGetJoystickAxes and @ref glfwGetJoystickButtons functions. @subsection moving_mbcs Win32 MBCS support The Win32 port of GLFW 3 will not compile in -[MBCS mode](http://msdn.microsoft.com/en-us/library/5z097dxa.aspx). +[MBCS mode](https://msdn.microsoft.com/en-us/library/5z097dxa.aspx). However, because the use of the Unicode version of the Win32 API doesn't affect the process as a whole, but only those windows created using it, it's perfectly possible to call MBCS functions from other parts of the same application. diff --git a/docs/news.dox b/docs/news.dox index d751f13a6..0cdec0055 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -275,7 +275,7 @@ easy linking with the library and its dependencies. @section news_31 Release notes for 3.1 These are the release highlights. For a full list of changes see the -[version history](http://www.glfw.org/changelog.html). +[version history](https://www.glfw.org/changelog.html). @subsection news_31_cursor Custom mouse cursor images @@ -386,7 +386,7 @@ on Linux with a CMake option. @section news_30 Release notes for 3.0 These are the release highlights. For a full list of changes see the -[version history](http://www.glfw.org/changelog.html). +[version history](https://www.glfw.org/changelog.html). @subsection news_30_cmake CMake build system @@ -397,7 +397,7 @@ supported by GLFW, is present in most package systems and can generate makefiles and/or project files for most popular development environments. For more information on how to use CMake, see the -[CMake manual](http://cmake.org/cmake/help/documentation.html). +[CMake manual](https://cmake.org/cmake/help/documentation.html). @subsection news_30_multiwnd Multi-window support diff --git a/docs/quick.dox b/docs/quick.dox index d8c338220..b67ae3578 100644 --- a/docs/quick.dox +++ b/docs/quick.dox @@ -335,7 +335,7 @@ presses _Escape_ or closes the window. @snippet simple.c code The program above can be found in the -[source package](http://www.glfw.org/download.html) as `examples/simple.c` +[source package](https://www.glfw.org/download.html) as `examples/simple.c` and is compiled along with all other examples when you build GLFW. If you built GLFW from the source package then already have this as `simple.exe` on Windows, `simple` on Linux or `simple.app` on macOS. diff --git a/docs/window.dox b/docs/window.dox index 355a74e83..f30127847 100644 --- a/docs/window.dox +++ b/docs/window.dox @@ -68,7 +68,7 @@ set for the chosen monitor as long as the window has input focus. For more information about retrieving video modes, see @ref monitor_modes. Video mode field | Corresponds to ------------------------ | ------------------------ +---------------- | -------------- GLFWvidmode.width | `width` parameter GLFWvidmode.height | `height` parameter GLFWvidmode.redBits | @ref GLFW_RED_BITS hint diff --git a/examples/boing.c b/examples/boing.c index 45c867fd1..5b8e667e8 100644 --- a/examples/boing.c +++ b/examples/boing.c @@ -302,7 +302,7 @@ void cursor_position_callback( GLFWwindow* window, double x, double y ) * The Boing ball is sphere in which each facet is a rectangle. * Facet colors alternate between red and white. * The ball is built by stacking latitudinal circles. Each circle is composed - * of a widely-separated set of points, so that each facet is noticably large. + * of a widely-separated set of points, so that each facet is noticeably large. *****************************************************************************/ void DrawBoingBall( void ) { @@ -446,7 +446,7 @@ void DrawBoingBallBand( GLfloat long_lo, static int colorToggle = 0; /* - * Iterate thru the points of a latitude circle. + * Iterate through the points of a latitude circle. * A latitude circle is a 2D set of X,Z points. */ for ( lat_deg = 0; diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 1fc8fe556..099cd8e67 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -269,23 +269,22 @@ extern "C" { #define GLFW_VERSION_REVISION 0 /*! @} */ -/*! @name Boolean values - * @{ */ /*! @brief One. * - * One. Seriously. You don't _need_ to use this symbol in your code. It's - * semantic sugar for the number 1. You can also use `1` or `true` or `_True` - * or `GL_TRUE` or whatever you want. + * This is only semantic sugar for the number 1. You can instead use `1` or + * `true` or `_True` or `GL_TRUE` or anything else that is equal to one. + * + * @ingroup init */ #define GLFW_TRUE 1 /*! @brief Zero. * - * Zero. Seriously. You don't _need_ to use this symbol in your code. It's - * semantic sugar for the number 0. You can also use `0` or `false` or - * `_False` or `GL_FALSE` or whatever you want. + * This is only semantic sugar for the number 0. You can instead use `0` or + * `false` or `_False` or `GL_FALSE` or anything else that is equal to zero. + * + * @ingroup init */ #define GLFW_FALSE 0 -/*! @} */ /*! @name Key and button actions * @{ */ @@ -313,6 +312,7 @@ extern "C" { /*! @} */ /*! @defgroup hat_state Joystick hat states + * @brief Joystick hat states. * * See [joystick hat input](@ref joystick_hat) for how these are used. * @@ -1060,9 +1060,20 @@ extern "C" { /*! @addtogroup init * @{ */ +/*! @brief Joystick hat buttons init hint. + * + * Joystick hat buttons [init hint](@ref GLFW_JOYSTICK_HAT_BUTTONS) + */ #define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001 - +/*! @brief macOS specific init hint. + * + * macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES) + */ #define GLFW_COCOA_CHDIR_RESOURCES 0x00051001 +/*! @brief macOS specific init hint. + * + * macOS specific [init hint](@ref GLFW_COCOA_MENUBAR) + */ #define GLFW_COCOA_MENUBAR 0x00051002 /*! @} */ @@ -1133,7 +1144,7 @@ typedef struct GLFWwindow GLFWwindow; * * @since Added in version 3.1. * - * @ingroup cursor + * @ingroup input */ typedef struct GLFWcursor GLFWcursor; @@ -1571,6 +1582,8 @@ typedef struct GLFWgammaramp * * @since Added in version 2.1. * @glfw3 Removed format and bytes-per-pixel members. + * + * @ingroup window */ typedef struct GLFWimage { @@ -1593,6 +1606,8 @@ typedef struct GLFWimage * @sa @ref glfwGetGamepadState * * @since Added in version 3.3. + * + * @ingroup input */ typedef struct GLFWgamepadstate { @@ -2141,9 +2156,9 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); /*! @brief Generates a gamma ramp and sets it for the specified monitor. * - * This function generates a 256-element gamma ramp from the specified exponent - * and then calls @ref glfwSetGammaRamp with it. The value must be a finite - * number greater than zero. + * This function generates an appropriately sized gamma ramp from the specified + * exponent and then calls @ref glfwSetGammaRamp with it. The value must be + * a finite number greater than zero. * * The software controlled gamma ramp is applied _in addition_ to the hardware * gamma correction, which today is usually an approximation of sRGB gamma. @@ -2222,8 +2237,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * - * @remark Gamma ramp sizes other than 256 are not supported by all platforms - * or graphics hardware. + * @remark The size of the specified gamma ramp should match the size of the + * current ramp for that monitor. * * @remark @win32 The gamma ramp size must be 256. * @@ -3762,6 +3777,9 @@ GLFWAPI void glfwWaitEvents(void); * * @param[in] timeout The maximum amount of time, in seconds, to wait. * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref + * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. + * * @reentrancy This function must not be called from a callback. * * @thread_safety This function must only be called from the main thread. @@ -4287,9 +4305,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun); * The character callback behaves as system text input normally does and will * not be called if modifier keys are held down that would prevent normal text * input on that platform, for example a Super (Command) key on macOS or Alt key - * on Windows. There is a - * [character with modifiers callback](@ref glfwSetCharModsCallback) that - * receives these events. + * on Windows. * * @param[in] window The window whose callback to set. * @param[in] cbfun The new callback, or `NULL` to remove the currently set @@ -4585,7 +4601,7 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count); * Each element in the array is one of the following values: * * Name | Value - * --------------------- | -------------------------------- + * ---- | ----- * `GLFW_HAT_CENTERED` | 0 * `GLFW_HAT_UP` | 1 * `GLFW_HAT_RIGHT` | 2 @@ -4928,8 +4944,6 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * - * @remark @wayland Clipboard is currently unimplemented. - * * @pointer_lifetime The specified string is copied before this function * returns. * @@ -4958,8 +4972,6 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * - * @remark @wayland Clipboard is currently unimplemented. - * * @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 * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index 83d3ca44b..6bddc432f 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -81,7 +81,7 @@ extern "C" { * System headers and types *************************************************************************/ -#if defined(GLFW_EXPOSE_NATIVE_WIN32) +#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL) // This is a workaround for the fact that glfw3.h needs to export APIENTRY (for // example to allow applications to correctly declare a GL_ARB_debug_output // callback) but windows.h assumes no one will define APIENTRY before it does @@ -90,14 +90,14 @@ extern "C" { #undef GLFW_APIENTRY_DEFINED #endif #include -#elif defined(GLFW_EXPOSE_NATIVE_COCOA) - #include +#elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL) #if defined(__OBJC__) #import #else + #include typedef void* id; #endif -#elif defined(GLFW_EXPOSE_NATIVE_X11) +#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX) #include #include #elif defined(GLFW_EXPOSE_NATIVE_WAYLAND) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ecce17069..6bf4ff0d7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -100,7 +100,7 @@ set_target_properties(glfw PROPERTIES target_compile_definitions(glfw PRIVATE _GLFW_USE_CONFIG_H) target_include_directories(glfw PUBLIC "$" - "$/include>") + "$") target_include_directories(glfw PRIVATE "${GLFW_SOURCE_DIR}/src" "${GLFW_BINARY_DIR}/src" @@ -121,7 +121,7 @@ target_compile_options(glfw PRIVATE if (BUILD_SHARED_LIBS) if (WIN32) if (MINGW) - # Remove the lib prefix on the DLL (but not the import library + # Remove the lib prefix on the DLL (but not the import library) set_target_properties(glfw PROPERTIES PREFIX "") # Add a suffix to the import library to avoid naming conflicts @@ -135,7 +135,7 @@ if (BUILD_SHARED_LIBS) target_compile_options(glfw PRIVATE "-fno-common") set_target_properties(glfw PROPERTIES - INSTALL_NAME_DIR "lib${LIB_SUFFIX}") + INSTALL_NAME_DIR "${CMAKE_INSTALL_LIBDIR}") elseif (UNIX) # Hide symbols not explicitly tagged for export from the shared library target_compile_options(glfw PRIVATE "-fvisibility=hidden") @@ -155,7 +155,7 @@ if (GLFW_INSTALL) install(TARGETS glfw EXPORT glfwTargets RUNTIME DESTINATION "bin" - ARCHIVE DESTINATION "lib${LIB_SUFFIX}" - LIBRARY DESTINATION "lib${LIB_SUFFIX}") + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") endif() diff --git a/src/cocoa_init.m b/src/cocoa_init.m index 01a746bae..f3c479578 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -27,6 +27,10 @@ #include "internal.h" #include // For MAXPATHLEN +#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200 + #define NSEventMaskKeyUp NSKeyUpMask + #define NSEventModifierFlagCommand NSCommandKeyMask +#endif // Change to our application bundle's resources directory, if present // @@ -271,17 +275,21 @@ static GLFWbool initializeTIS(void) return updateUnicodeDataNS(); } -@interface GLFWLayoutListener : NSObject +@interface GLFWHelper : NSObject @end -@implementation GLFWLayoutListener +@implementation GLFWHelper - (void)selectedKeyboardInputSourceChanged:(NSObject* )object { updateUnicodeDataNS(); } -@end +- (void)doNothing:(id)object +{ +} + +@end // GLFWHelper ////////////////////////////////////////////////////////////////////////// @@ -291,13 +299,31 @@ static GLFWbool initializeTIS(void) int _glfwPlatformInit(void) { _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; + _glfw.ns.helper = [[GLFWHelper alloc] init]; + + [NSThread detachNewThreadSelector:@selector(doNothing:) + toTarget:_glfw.ns.helper + withObject:nil]; + + [NSApplication sharedApplication]; + + NSEvent* (^block)(NSEvent*) = ^ NSEvent* (NSEvent* event) + { + if ([event modifierFlags] & NSEventModifierFlagCommand) + [[NSApp keyWindow] sendEvent:event]; + + return event; + }; + + _glfw.ns.keyUpMonitor = + [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyUp + handler:block]; if (_glfw.hints.init.ns.chdir) changeToResourcesDirectory(); - _glfw.ns.listener = [[GLFWLayoutListener alloc] init]; [[NSNotificationCenter defaultCenter] - addObserver:_glfw.ns.listener + addObserver:_glfw.ns.helper selector:@selector(selectedKeyboardInputSourceChanged:) name:NSTextInputContextKeyboardSelectionDidChangeNotification object:nil]; @@ -342,18 +368,21 @@ void _glfwPlatformTerminate(void) _glfw.ns.delegate = nil; } - if (_glfw.ns.listener) + if (_glfw.ns.helper) { [[NSNotificationCenter defaultCenter] - removeObserver:_glfw.ns.listener + removeObserver:_glfw.ns.helper name:NSTextInputContextKeyboardSelectionDidChangeNotification object:nil]; [[NSNotificationCenter defaultCenter] - removeObserver:_glfw.ns.listener]; - [_glfw.ns.listener release]; - _glfw.ns.listener = nil; + removeObserver:_glfw.ns.helper]; + [_glfw.ns.helper release]; + _glfw.ns.helper = nil; } + if (_glfw.ns.keyUpMonitor) + [NSEvent removeMonitor:_glfw.ns.keyUpMonitor]; + free(_glfw.ns.clipboardString); _glfwTerminateNSGL(); diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 986d799e7..39fff6f7f 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -467,7 +467,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) CVDisplayLinkRelease(link); } -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID); CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue)); @@ -489,6 +489,7 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) } free(values); + return GLFW_TRUE; } void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index cf6ca9f5c..13adaa972 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -27,12 +27,10 @@ #include #include +#include #if defined(__OBJC__) -#import #import #else -#include -#include typedef void* id; #endif @@ -111,7 +109,9 @@ typedef struct _GLFWlibraryNS TISInputSourceRef inputSource; IOHIDManagerRef hidManager; id unicodeData; - id listener; + id helper; + id keyUpMonitor; + id nibObjects; char keyName[64]; short int keycodes[256]; diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 7cf4a593d..db9935ce8 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -32,7 +32,6 @@ // Needed for _NSGetProgname #include -// HACK: The 10.12 SDK adds new symbols and immediately deprecates the old ones #if MAC_OS_X_VERSION_MAX_ALLOWED < 101200 #define NSWindowStyleMaskBorderless NSBorderlessWindowMask #define NSWindowStyleMaskClosable NSClosableWindowMask @@ -47,10 +46,9 @@ #define NSEventModifierFlagDeviceIndependentFlagsMask NSDeviceIndependentModifierFlagsMask #define NSEventMaskAny NSAnyEventMask #define NSEventTypeApplicationDefined NSApplicationDefined - #define NSEventTypeKeyUp NSKeyUp + #define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat #endif - // Returns the style mask corresponding to the window settings // static NSUInteger getStyleMask(_GLFWwindow* window) @@ -237,6 +235,8 @@ static NSUInteger translateKeyToModifierFlag(int key) case GLFW_KEY_LEFT_SUPER: case GLFW_KEY_RIGHT_SUPER: return NSEventModifierFlagCommand; + case GLFW_KEY_CAPS_LOCK: + return NSEventModifierFlagCapsLock; } return 0; @@ -365,7 +365,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; // Delegate for application related notifications //------------------------------------------------------------------------ -@interface GLFWApplicationDelegate : NSObject +@interface GLFWApplicationDelegate : NSObject @end @implementation GLFWApplicationDelegate @@ -438,8 +438,9 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; markedText = [[NSMutableAttributedString alloc] init]; [self updateTrackingAreas]; - [self registerForDraggedTypes:[NSArray arrayWithObjects: - NSFilenamesPboardType, nil]]; + // NOTE: kUTTypeURL corresponds to NSPasteboardTypeURL but is available + // on 10.7 without having been deprecated yet + [self registerForDraggedTypes:@[(__bridge NSString*) kUTTypeURL]]; } return self; @@ -472,6 +473,14 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; return YES; } +- (void)updateLayer +{ + if (window->context.client != GLFW_NO_API) + [window->context.nsgl.object update]; + + _glfwInputWindowDamage(window); +} + - (id)makeBackingLayer { if (window->ns.layer) @@ -485,6 +494,11 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; updateCursorImage(window); } +- (BOOL)acceptsFirstMouse:(NSEvent *)event +{ + return YES; +} + - (void)mouseDown:(NSEvent *)event { _glfwInputMouseClick(window, @@ -650,7 +664,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; _glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods); - [self interpretKeyEvents:[NSArray arrayWithObject:event]]; + [self interpretKeyEvents:@[event]]; } - (void)flagsChanged:(NSEvent *)event @@ -701,45 +715,33 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (NSDragOperation)draggingEntered:(id )sender { - if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) - == NSDragOperationGeneric) - { - [self setNeedsDisplay:YES]; - return NSDragOperationGeneric; - } - - return NSDragOperationNone; -} - -- (BOOL)prepareForDragOperation:(id )sender -{ - [self setNeedsDisplay:YES]; - return YES; + // HACK: We don't know what to say here because we don't know what the + // application wants to do with the paths + return NSDragOperationGeneric; } - (BOOL)performDragOperation:(id )sender { - NSPasteboard* pasteboard = [sender draggingPasteboard]; - NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType]; - const NSRect contentRect = [window->ns.view frame]; _glfwInputCursorPos(window, [sender draggingLocation].x, contentRect.size.height - [sender draggingLocation].y); - const NSUInteger count = [files count]; + NSPasteboard* pasteboard = [sender draggingPasteboard]; + NSDictionary* options = @{NSPasteboardURLReadingFileURLsOnlyKey:@YES}; + NSArray* urls = [pasteboard readObjectsForClasses:@[[NSURL class]] + options:options]; + const NSUInteger count = [urls count]; if (count) { - NSEnumerator* e = [files objectEnumerator]; char** paths = calloc(count, sizeof(char*)); - NSUInteger i; - for (i = 0; i < count; i++) - paths[i] = _glfw_strdup([[e nextObject] UTF8String]); + for (NSUInteger i = 0; i < count; i++) + paths[i] = _glfw_strdup([[urls objectAtIndex:i] fileSystemRepresentation]); _glfwInputDrop(window, (int) count, (const char**) paths); - for (i = 0; i < count; i++) + for (NSUInteger i = 0; i < count; i++) free(paths[i]); free(paths); } @@ -747,11 +749,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; return YES; } -- (void)concludeDragOperation:(id )sender -{ - [self setNeedsDisplay:YES]; -} - - (BOOL)hasMarkedText { return [markedText length] > 0; @@ -865,52 +862,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; @end -//------------------------------------------------------------------------ -// GLFW application class -//------------------------------------------------------------------------ - -@interface GLFWApplication : NSApplication -{ - NSArray* nibObjects; -} - -@end - -@implementation GLFWApplication - -// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost -// This works around an AppKit bug, where key up events while holding -// down the command key don't get sent to the key window. -- (void)sendEvent:(NSEvent *)event -{ - if ([event type] == NSEventTypeKeyUp && - ([event modifierFlags] & NSEventModifierFlagCommand)) - { - [[self keyWindow] sendEvent:event]; - } - else - [super sendEvent:event]; -} - - -// No-op thread entry point -// -- (void)doNothing:(id)object -{ -} - -- (void)loadMainMenu -{ -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 - [[NSBundle mainBundle] loadNibNamed:@"MainMenu" - owner:NSApp - topLevelObjects:&nibObjects]; -#else - [[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:NSApp]; -#endif -} -@end - // Set up the menu bar (manually) // This is nasty, nasty stuff -- calls to undocumented semi-private APIs that // could go away at any moment, lots of stuff that really should be @@ -1020,32 +971,9 @@ static void createMenuBar(void) // static GLFWbool initializeAppKit(void) { - if (NSApp) + if (_glfw.ns.delegate) return GLFW_TRUE; - // Implicitly create shared NSApplication instance - [GLFWApplication sharedApplication]; - - // Make Cocoa enter multi-threaded mode - [NSThread detachNewThreadSelector:@selector(doNothing:) - toTarget:NSApp - withObject:nil]; - - if (_glfw.hints.init.ns.menubar) - { - // In case we are unbundled, make us a proper UI application - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - - // Menu bar setup must go between sharedApplication above and - // finishLaunching below, in order to properly emulate the behavior - // of NSApplicationMain - - if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"]) - [NSApp loadMainMenu]; - else - createMenuBar(); - } - // There can only be one application delegate, but we allocate it the // first time a window is created to keep all window code in this file _glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init]; @@ -1057,13 +985,34 @@ static GLFWbool initializeAppKit(void) } [NSApp setDelegate:_glfw.ns.delegate]; + + if (_glfw.hints.init.ns.menubar) + { + // In case we are unbundled, make us a proper UI application + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + + // Menu bar setup must go between sharedApplication above and + // finishLaunching below, in order to properly emulate the behavior + // of NSApplicationMain + + if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"]) + { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 + [[NSBundle mainBundle] loadNibNamed:@"MainMenu" + owner:NSApp + topLevelObjects:&_glfw.ns.nibObjects]; +#else + [[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:NSApp]; +#endif + } + else + createMenuBar(); + } + [NSApp run]; // Press and Hold prevents some keys from emitting repeated characters - NSDictionary* defaults = - [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO], - @"ApplePressAndHoldEnabled", - nil]; + NSDictionary* defaults = @{@"ApplePressAndHoldEnabled":@NO}; [[NSUserDefaults standardUserDefaults] registerDefaults:defaults]; return GLFW_TRUE; @@ -1563,9 +1512,6 @@ void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) void _glfwPlatformPollEvents(void) { - if (!initializeAppKit()) - return; - for (;;) { NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny @@ -1716,9 +1662,6 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, NSImage* native; NSBitmapImageRep* rep; - if (!initializeAppKit()) - return GLFW_FALSE; - rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:image->width @@ -1728,7 +1671,7 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, hasAlpha:YES isPlanar:NO colorSpaceName:NSCalibratedRGBColorSpace - bitmapFormat:NSAlphaNonpremultipliedBitmapFormat + bitmapFormat:NSBitmapFormatAlphaNonpremultiplied bytesPerRow:image->width * 4 bitsPerPixel:32]; @@ -1754,9 +1697,6 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) { - if (!initializeAppKit()) - return GLFW_FALSE; - if (shape == GLFW_ARROW_CURSOR) cursor->ns.object = [NSCursor arrowCursor]; else if (shape == GLFW_IBEAM_CURSOR) @@ -1795,26 +1735,24 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) void _glfwPlatformSetClipboardString(const char* string) { - NSArray* types = [NSArray arrayWithObjects:NSStringPboardType, nil]; - NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; - [pasteboard declareTypes:types owner:nil]; + [pasteboard declareTypes:@[NSPasteboardTypeString] owner:nil]; [pasteboard setString:[NSString stringWithUTF8String:string] - forType:NSStringPboardType]; + forType:NSPasteboardTypeString]; } const char* _glfwPlatformGetClipboardString(void) { NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; - if (![[pasteboard types] containsObject:NSStringPboardType]) + if (![[pasteboard types] containsObject:NSPasteboardTypeString]) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "Cocoa: Failed to retrieve string from pasteboard"); return NULL; } - NSString* object = [pasteboard stringForType:NSStringPboardType]; + NSString* object = [pasteboard stringForType:NSPasteboardTypeString]; if (!object) { _glfwInputError(GLFW_PLATFORM_ERROR, diff --git a/src/glfw3.pc.in b/src/glfw3.pc.in index f2e4d9769..87423e1a6 100644 --- a/src/glfw3.pc.in +++ b/src/glfw3.pc.in @@ -1,12 +1,12 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix} -includedir=${prefix}/include -libdir=${exec_prefix}/lib@LIB_SUFFIX@ +includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ Name: GLFW Description: A multi-platform library for OpenGL, window and input Version: @GLFW_VERSION_FULL@ -URL: http://www.glfw.org/ +URL: https://www.glfw.org/ Requires.private: @GLFW_PKG_DEPS@ Libs: -L${libdir} -l@GLFW_LIB_NAME@ Libs.private: @GLFW_PKG_LIBS@ diff --git a/src/init.c b/src/init.c index 9e670d423..4f424c4a9 100644 --- a/src/init.c +++ b/src/init.c @@ -119,6 +119,30 @@ char* _glfw_strdup(const char* source) return result; } +float _glfw_fminf(float a, float b) +{ + if (a != a) + return b; + else if (b != b) + return a; + else if (a < b) + return a; + else + return b; +} + +float _glfw_fmaxf(float a, float b) +{ + if (a != a) + return b; + else if (b != b) + return a; + else if (a > b) + return a; + else + return b; +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW event API ////// diff --git a/src/input.c b/src/input.c index b0bb3de47..460e9f31f 100644 --- a/src/input.c +++ b/src/input.c @@ -1242,7 +1242,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state) if (e->type == _GLFW_JOYSTICK_AXIS) { const float value = js->axes[e->index] * e->axisScale + e->axisOffset; - state->axes[i] = fminf(fmaxf(value, -1.f), 1.f); + state->axes[i] = _glfw_fminf(_glfw_fmaxf(value, -1.f), 1.f); } else if (e->type == _GLFW_JOYSTICK_HATBIT) { diff --git a/src/internal.h b/src/internal.h index 7be2b267c..c7c5bf8fd 100644 --- a/src/internal.h +++ b/src/internal.h @@ -611,7 +611,7 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, float* xscale, float* yscale); GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count); void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode); -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp); +GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp); void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp); void _glfwPlatformSetClipboardString(const char* string); @@ -766,4 +766,6 @@ void _glfwTerminateVulkan(void); const char* _glfwGetVulkanResultString(VkResult result); char* _glfw_strdup(const char* source); +float _glfw_fminf(float a, float b); +float _glfw_fmaxf(float a, float b); diff --git a/src/monitor.c b/src/monitor.c index f7de5500f..0ab865e3b 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -427,12 +427,12 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle) GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) { - int i; - unsigned short values[256]; + unsigned int i; + unsigned short* values; GLFWgammaramp ramp; + const GLFWgammaramp* original; assert(handle != NULL); - assert(gamma == gamma); - assert(gamma >= 0.f); + assert(gamma > 0.f); assert(gamma <= FLT_MAX); _GLFW_REQUIRE_INIT(); @@ -443,18 +443,22 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) return; } - for (i = 0; i < 256; i++) + original = glfwGetGammaRamp(handle); + if (!original) + return; + + values = calloc(original->size, sizeof(unsigned short)); + + for (i = 0; i < original->size; i++) { float value; // Calculate intensity - value = i / 255.f; + value = i / (float) (original->size - 1); // Apply gamma curve value = powf(value, 1.f / gamma) * 65535.f + 0.5f; - // Clamp to value range - if (value > 65535.f) - value = 65535.f; + value = _glfw_fminf(value, 65535.f); values[i] = (unsigned short) value; } @@ -462,9 +466,10 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) ramp.red = values; ramp.green = values; ramp.blue = values; - ramp.size = 256; + ramp.size = original->size; glfwSetGammaRamp(handle, &ramp); + free(values); } GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) @@ -475,7 +480,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) _GLFW_REQUIRE_INIT_OR_RETURN(NULL); _glfwFreeGammaArrays(&monitor->currentRamp); - _glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp); + if (!_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp)) + return NULL; return &monitor->currentRamp; } @@ -501,7 +507,10 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) _GLFW_REQUIRE_INIT(); if (!monitor->originalRamp.size) - _glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp); + { + if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp)) + return; + } _glfwPlatformSetGammaRamp(monitor, ramp); } diff --git a/src/nsgl_context.m b/src/nsgl_context.m index 82af90636..ec1012e9d 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -26,6 +26,10 @@ #include "internal.h" +#if MAC_OS_X_VERSION_MAX_ALLOWED < 101400 + #define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval + #define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity +#endif static void makeContextCurrentNSGL(_GLFWwindow* window) { @@ -49,7 +53,7 @@ static void swapIntervalNSGL(int interval) GLint sync = interval; [window->context.nsgl.object setValues:&sync - forParameter:NSOpenGLCPSwapInterval]; + forParameter:NSOpenGLContextParameterSwapInterval]; } static int extensionSupportedNSGL(const char* extension) @@ -299,7 +303,8 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, if (fbconfig->transparent) { GLint opaque = 0; - [window->context.nsgl.object setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity]; + [window->context.nsgl.object setValues:&opaque + forParameter:NSOpenGLContextParameterSurfaceOpacity]; } [window->context.nsgl.object setView:window->ns.view]; diff --git a/src/null_monitor.c b/src/null_monitor.c index 84b41c7e3..45c4a10f8 100644 --- a/src/null_monitor.c +++ b/src/null_monitor.c @@ -58,8 +58,9 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) { } -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { + return GLFW_FALSE; } void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) diff --git a/src/osmesa_context.c b/src/osmesa_context.c index a7de33f26..03651ebf4 100644 --- a/src/osmesa_context.c +++ b/src/osmesa_context.c @@ -240,7 +240,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window, if (ctxconfig->forward) { _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "OSMesa: Foward-compatible contexts not supported"); + "OSMesa: Forward-compatible contexts not supported"); return GLFW_FALSE; } diff --git a/src/wgl_context.c b/src/wgl_context.c index 02f84eae5..14e9d5cd5 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -413,29 +413,17 @@ static void swapIntervalWGL(int interval) static int extensionSupportedWGL(const char* extension) { - const char* extensions; - - if (_glfw.wgl.GetExtensionsStringEXT) - { - extensions = _glfw.wgl.GetExtensionsStringEXT(); - if (extensions) - { - if (_glfwStringInExtensionString(extension, extensions)) - return GLFW_TRUE; - } - } + const char* extensions = NULL; if (_glfw.wgl.GetExtensionsStringARB) - { extensions = _glfw.wgl.GetExtensionsStringARB(wglGetCurrentDC()); - if (extensions) - { - if (_glfwStringInExtensionString(extension, extensions)) - return GLFW_TRUE; - } - } + else if (_glfw.wgl.GetExtensionsStringEXT) + extensions = _glfw.wgl.GetExtensionsStringEXT(); - return GLFW_FALSE; + if (!extensions) + return GLFW_FALSE; + + return _glfwStringInExtensionString(extension, extensions); } static GLFWglproc getProcAddressWGL(const char* procname) diff --git a/src/win32_joystick.c b/src/win32_joystick.c index d9d341ff5..581239654 100644 --- a/src/win32_joystick.c +++ b/src/win32_joystick.c @@ -260,6 +260,8 @@ static void closeJoystick(_GLFWjoystick* js) IDirectInputDevice8_Release(js->win32.device); } + free(js->win32.objects); + _glfwFreeJoystick(js); _glfwInputJoystick(js, GLFW_DISCONNECTED); } diff --git a/src/win32_monitor.c b/src/win32_monitor.c index b7a24e615..07b3614bb 100644 --- a/src/win32_monitor.c +++ b/src/win32_monitor.c @@ -455,7 +455,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) &mode->blueBits); } -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { HDC dc; WORD values[768]; @@ -469,6 +469,8 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short)); memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short)); memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short)); + + return GLFW_TRUE; } void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) diff --git a/src/win32_platform.h b/src/win32_platform.h index fa9f041c6..712de7f1e 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -147,8 +147,7 @@ typedef enum #endif /*DPI_ENUMS_DECLARED*/ #ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 -DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); -#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT) -4) +#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((HANDLE) -4) #endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/ // HACK: Define versionhelpers.h functions manually as MinGW lacks the header @@ -225,7 +224,7 @@ typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID* typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void); typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,CHANGEFILTERSTRUCT*); typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND); -typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); +typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(HANDLE); typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND); typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT); #define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_ diff --git a/src/win32_window.c b/src/win32_window.c index 858931bca..a0abca060 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -209,11 +209,14 @@ static void getFullWindowSize(DWORD style, DWORD exStyle, static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area) { int xoff, yoff; + UINT dpi = USER_DEFAULT_SCREEN_DPI; const float ratio = (float) window->numer / (float) window->denom; + if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) + dpi = GetDpiForWindow(window->win32.handle); + getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), - 0, 0, &xoff, &yoff, - GetDpiForWindow(window->win32.handle)); + 0, 0, &xoff, &yoff, dpi); if (edge == WMSZ_LEFT || edge == WMSZ_BOTTOMLEFT || edge == WMSZ_RIGHT || edge == WMSZ_BOTTOMRIGHT) @@ -1001,14 +1004,17 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, case WM_GETMINMAXINFO: { int xoff, yoff; + UINT dpi = USER_DEFAULT_SCREEN_DPI; MINMAXINFO* mmi = (MINMAXINFO*) lParam; if (window->monitor) break; + if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) + dpi = GetDpiForWindow(window->win32.handle); + getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), - 0, 0, &xoff, &yoff, - GetDpiForWindow(window->win32.handle)); + 0, 0, &xoff, &yoff, dpi); if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE) @@ -1054,6 +1060,17 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, return TRUE; } + case WM_NCACTIVATE: + case WM_NCPAINT: + { + // Prevent title bar from being drawn after restoring a minimized + // undecorated window + if (!window->decorated) + return TRUE; + + break; + } + case WM_DWMCOMPOSITIONCHANGED: { if (window->win32.transparent) diff --git a/src/wl_init.c b/src/wl_init.c index 4a51f38cd..c6b209bc7 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -99,7 +99,7 @@ static void pointerHandleEnter(void* data, } window->wl.decorations.focus = focus; - _glfw.wl.pointerSerial = serial; + _glfw.wl.serial = serial; _glfw.wl.pointerFocus = window; window->wl.hovered = GLFW_TRUE; @@ -120,7 +120,7 @@ static void pointerHandleLeave(void* data, window->wl.hovered = GLFW_FALSE; - _glfw.wl.pointerSerial = serial; + _glfw.wl.serial = serial; _glfw.wl.pointerFocus = NULL; _glfwInputCursorEnter(window, GLFW_FALSE); } @@ -158,7 +158,7 @@ static void setCursor(_GLFWwindow* window, const char* name) buffer = wl_cursor_image_get_buffer(image); if (!buffer) return; - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial, surface, image->hotspot_x / scale, image->hotspot_y / scale); @@ -309,7 +309,7 @@ static void pointerHandleButton(void* data, if (window->wl.decorations.focus != mainWindow) return; - _glfw.wl.pointerSerial = serial; + _glfw.wl.serial = serial; /* Makes left, right and middle 0, 1 and 2. Overall order follows evdev * codes. */ @@ -478,6 +478,7 @@ static void keyboardHandleEnter(void* data, return; } + _glfw.wl.serial = serial; _glfw.wl.keyboardFocus = window; _glfwInputWindowFocus(window, GLFW_TRUE); } @@ -492,6 +493,7 @@ static void keyboardHandleLeave(void* data, if (!window) return; + _glfw.wl.serial = serial; _glfw.wl.keyboardFocus = NULL; _glfwInputWindowFocus(window, GLFW_FALSE); } @@ -575,6 +577,7 @@ static void keyboardHandleKey(void* data, action = state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE; + _glfw.wl.serial = serial; _glfwInputKey(window, keyCode, key, action, _glfw.wl.xkb.modifiers); @@ -606,6 +609,8 @@ static void keyboardHandleModifiers(void* data, xkb_mod_mask_t mask; unsigned int modifiers = 0; + _glfw.wl.serial = serial; + if (!_glfw.wl.xkb.keymap) return; @@ -700,6 +705,70 @@ static const struct wl_seat_listener seatListener = { seatHandleName, }; +static void dataOfferHandleOffer(void* data, + struct wl_data_offer* dataOffer, + const char* mimeType) +{ +} + +static const struct wl_data_offer_listener dataOfferListener = { + dataOfferHandleOffer, +}; + +static void dataDeviceHandleDataOffer(void* data, + struct wl_data_device* dataDevice, + struct wl_data_offer* id) +{ + if (_glfw.wl.dataOffer) + wl_data_offer_destroy(_glfw.wl.dataOffer); + + _glfw.wl.dataOffer = id; + wl_data_offer_add_listener(_glfw.wl.dataOffer, &dataOfferListener, NULL); +} + +static void dataDeviceHandleEnter(void* data, + struct wl_data_device* dataDevice, + uint32_t serial, + struct wl_surface *surface, + wl_fixed_t x, + wl_fixed_t y, + struct wl_data_offer *id) +{ +} + +static void dataDeviceHandleLeave(void* data, + struct wl_data_device* dataDevice) +{ +} + +static void dataDeviceHandleMotion(void* data, + struct wl_data_device* dataDevice, + uint32_t time, + wl_fixed_t x, + wl_fixed_t y) +{ +} + +static void dataDeviceHandleDrop(void* data, + struct wl_data_device* dataDevice) +{ +} + +static void dataDeviceHandleSelection(void* data, + struct wl_data_device* dataDevice, + struct wl_data_offer* id) +{ +} + +static const struct wl_data_device_listener dataDeviceListener = { + dataDeviceHandleDataOffer, + dataDeviceHandleEnter, + dataDeviceHandleLeave, + dataDeviceHandleMotion, + dataDeviceHandleDrop, + dataDeviceHandleSelection, +}; + static void wmBaseHandlePing(void* data, struct xdg_wm_base* wmBase, uint32_t serial) @@ -754,6 +823,15 @@ static void registryHandleGlobal(void* data, wl_seat_add_listener(_glfw.wl.seat, &seatListener, NULL); } } + else if (strcmp(interface, "wl_data_device_manager") == 0) + { + if (!_glfw.wl.dataDeviceManager) + { + _glfw.wl.dataDeviceManager = + wl_registry_bind(registry, name, + &wl_data_device_manager_interface, 1); + } + } else if (strcmp(interface, "xdg_wm_base") == 0) { _glfw.wl.wmBase = @@ -1112,6 +1190,22 @@ int _glfwPlatformInit(void) _glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); } + if (_glfw.wl.seat && _glfw.wl.dataDeviceManager) + { + _glfw.wl.dataDevice = + wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager, + _glfw.wl.seat); + wl_data_device_add_listener(_glfw.wl.dataDevice, &dataDeviceListener, NULL); + _glfw.wl.clipboardString = malloc(4096); + if (!_glfw.wl.clipboardString) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Unable to allocate clipboard memory"); + return GLFW_FALSE; + } + _glfw.wl.clipboardSize = 4096; + } + return GLFW_TRUE; } @@ -1169,6 +1263,14 @@ void _glfwPlatformTerminate(void) zxdg_decoration_manager_v1_destroy(_glfw.wl.decorationManager); if (_glfw.wl.wmBase) xdg_wm_base_destroy(_glfw.wl.wmBase); + if (_glfw.wl.dataSource) + wl_data_source_destroy(_glfw.wl.dataSource); + if (_glfw.wl.dataDevice) + wl_data_device_destroy(_glfw.wl.dataDevice); + if (_glfw.wl.dataOffer) + wl_data_offer_destroy(_glfw.wl.dataOffer); + if (_glfw.wl.dataDeviceManager) + wl_data_device_manager_destroy(_glfw.wl.dataDeviceManager); if (_glfw.wl.pointer) wl_pointer_destroy(_glfw.wl.pointer); if (_glfw.wl.keyboard) @@ -1193,6 +1295,11 @@ void _glfwPlatformTerminate(void) close(_glfw.wl.timerfd); if (_glfw.wl.cursorTimerfd >= 0) close(_glfw.wl.cursorTimerfd); + + if (_glfw.wl.clipboardString) + free(_glfw.wl.clipboardString); + if (_glfw.wl.clipboardSendString) + free(_glfw.wl.clipboardSendString); } const char* _glfwPlatformGetVersionString(void) diff --git a/src/wl_monitor.c b/src/wl_monitor.c index 7d8e23eb9..588f8b0de 100644 --- a/src/wl_monitor.c +++ b/src/wl_monitor.c @@ -180,19 +180,18 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) *mode = monitor->modes[monitor->wl.currentMode]; } -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { - // TODO _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Gamma ramp getting not supported yet"); + "Wayland: Gamma ramp access it not available"); + return GLFW_FALSE; } void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) { - // TODO _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Gamma ramp setting not supported yet"); + "Wayland: Gamma ramp access is not available"); } diff --git a/src/wl_platform.h b/src/wl_platform.h index 2cf649693..c17ebe88b 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -233,6 +233,10 @@ typedef struct _GLFWlibraryWayland struct wl_seat* seat; struct wl_pointer* pointer; struct wl_keyboard* keyboard; + struct wl_data_device_manager* dataDeviceManager; + struct wl_data_device* dataDevice; + struct wl_data_offer* dataOffer; + struct wl_data_source* dataSource; struct xdg_wm_base* wmBase; struct zxdg_decoration_manager_v1* decorationManager; struct wp_viewporter* viewporter; @@ -247,12 +251,16 @@ typedef struct _GLFWlibraryWayland struct wl_cursor_theme* cursorThemeHiDPI; struct wl_surface* cursorSurface; int cursorTimerfd; - uint32_t pointerSerial; + uint32_t serial; int32_t keyboardRepeatRate; int32_t keyboardRepeatDelay; int keyboardLastKey; int keyboardLastScancode; + char* clipboardString; + size_t clipboardSize; + char* clipboardSendString; + size_t clipboardSendSize; int timerfd; short int keycodes[256]; short int scancodes[GLFW_KEY_LAST + 1]; diff --git a/src/wl_window.c b/src/wl_window.c index c1d24f231..98a646590 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -779,7 +779,7 @@ static void setCursorImage(_GLFWwindow* window, cursorWayland->yhot = image->hotspot_y; } - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial, surface, cursorWayland->xhot / scale, cursorWayland->yhot / scale); @@ -1501,7 +1501,7 @@ static void lockPointer(_GLFWwindow* window) window->wl.pointerLock.relativePointer = relativePointer; window->wl.pointerLock.lockedPointer = lockedPointer; - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial, NULL, 0, 0); } @@ -1565,24 +1565,213 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) } else if (window->cursorMode == GLFW_CURSOR_HIDDEN) { - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerSerial, - NULL, 0, 0); + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial, NULL, 0, 0); } } +static void dataSourceHandleTarget(void* data, + struct wl_data_source* dataSource, + const char* mimeType) +{ + if (_glfw.wl.dataSource != dataSource) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Unknown clipboard data source"); + return; + } +} + +static void dataSourceHandleSend(void* data, + struct wl_data_source* dataSource, + const char* mimeType, + int fd) +{ + const char* string = _glfw.wl.clipboardSendString; + size_t len = _glfw.wl.clipboardSendSize; + int ret; + + if (_glfw.wl.dataSource != dataSource) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Unknown clipboard data source"); + return; + } + + if (!string) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Copy requested from an invalid string"); + return; + } + + if (strcmp(mimeType, "text/plain;charset=utf-8") != 0) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Wrong MIME type asked from clipboard"); + close(fd); + return; + } + + while (len > 0) + { + ret = write(fd, string, len); + if (ret == -1 && errno == EINTR) + continue; + if (ret == -1) + { + // TODO: also report errno maybe. + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Error while writing the clipboard"); + close(fd); + return; + } + len -= ret; + } + close(fd); +} + +static void dataSourceHandleCancelled(void* data, + struct wl_data_source* dataSource) +{ + wl_data_source_destroy(dataSource); + + if (_glfw.wl.dataSource != dataSource) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Unknown clipboard data source"); + return; + } + + _glfw.wl.dataSource = NULL; +} + +static const struct wl_data_source_listener dataSourceListener = { + dataSourceHandleTarget, + dataSourceHandleSend, + dataSourceHandleCancelled, +}; + void _glfwPlatformSetClipboardString(const char* string) { - // TODO - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Clipboard setting not implemented yet"); + if (_glfw.wl.dataSource) + { + wl_data_source_destroy(_glfw.wl.dataSource); + _glfw.wl.dataSource = NULL; + } + + if (_glfw.wl.clipboardSendString) + { + free(_glfw.wl.clipboardSendString); + _glfw.wl.clipboardSendString = NULL; + } + + _glfw.wl.clipboardSendString = strdup(string); + if (!_glfw.wl.clipboardSendString) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Impossible to allocate clipboard string"); + return; + } + _glfw.wl.clipboardSendSize = strlen(string); + _glfw.wl.dataSource = + wl_data_device_manager_create_data_source(_glfw.wl.dataDeviceManager); + if (!_glfw.wl.dataSource) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Impossible to create clipboard source"); + free(_glfw.wl.clipboardSendString); + return; + } + wl_data_source_add_listener(_glfw.wl.dataSource, + &dataSourceListener, + NULL); + wl_data_source_offer(_glfw.wl.dataSource, "text/plain;charset=utf-8"); + wl_data_device_set_selection(_glfw.wl.dataDevice, + _glfw.wl.dataSource, + _glfw.wl.serial); +} + +static GLFWbool growClipboardString(void) +{ + char* clipboard = _glfw.wl.clipboardString; + + clipboard = realloc(clipboard, _glfw.wl.clipboardSize * 2); + if (!clipboard) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Impossible to grow clipboard string"); + return GLFW_FALSE; + } + _glfw.wl.clipboardString = clipboard; + _glfw.wl.clipboardSize = _glfw.wl.clipboardSize * 2; + return GLFW_TRUE; } const char* _glfwPlatformGetClipboardString(void) { - // TODO - _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: Clipboard getting not implemented yet"); - return NULL; + int fds[2]; + int ret; + size_t len = 0; + + if (!_glfw.wl.dataOffer) + { + _glfwInputError(GLFW_FORMAT_UNAVAILABLE, + "No clipboard data has been sent yet"); + return NULL; + } + + ret = pipe2(fds, O_CLOEXEC); + if (ret < 0) + { + // TODO: also report errno maybe? + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Impossible to create clipboard pipe fds"); + return NULL; + } + + wl_data_offer_receive(_glfw.wl.dataOffer, "text/plain;charset=utf-8", fds[1]); + close(fds[1]); + + // XXX: this is a huge hack, this function shouldn’t be synchronous! + handleEvents(-1); + + while (1) + { + // Grow the clipboard if we need to paste something bigger, there is no + // shrink operation yet. + if (len + 4096 > _glfw.wl.clipboardSize) + { + if (!growClipboardString()) + { + close(fds[0]); + return NULL; + } + } + + // Then read from the fd to the clipboard, handling all known errors. + ret = read(fds[0], _glfw.wl.clipboardString + len, 4096); + if (ret == 0) + break; + if (ret == -1 && errno == EINTR) + continue; + if (ret == -1) + { + // TODO: also report errno maybe. + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Impossible to read from clipboard fd"); + close(fds[0]); + return NULL; + } + len += ret; + } + close(fds[0]); + if (len + 1 > _glfw.wl.clipboardSize) + { + if (!growClipboardString()) + return NULL; + } + _glfw.wl.clipboardString[len] = '\0'; + return _glfw.wl.clipboardString; } void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) diff --git a/src/x11_init.c b/src/x11_init.c index c949916d3..e3e3ad518 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -780,8 +780,9 @@ static GLFWbool initExtensions(void) // static void getSystemContentScale(float* xscale, float* yscale) { - // NOTE: Default to the display-wide DPI as we don't currently have a policy - // for which monitor a window is considered to be on + // NOTE: Fall back to the display-wide DPI instead of RandR monitor DPI if + // Xft.dpi retrieval below fails as we don't currently have an exact + // policy for which monitor a window is considered to "be on" float xdpi = DisplayWidth(_glfw.x11.display, _glfw.x11.screen) * 25.4f / DisplayWidthMM(_glfw.x11.display, _glfw.x11.screen); float ydpi = DisplayHeight(_glfw.x11.display, _glfw.x11.screen) * diff --git a/src/x11_monitor.c b/src/x11_monitor.c index f557fe472..df53041df 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c @@ -422,7 +422,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) } } -void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) { @@ -438,6 +438,7 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short)); XRRFreeGamma(gamma); + return GLFW_TRUE; } else if (_glfw.x11.vidmode.available) { @@ -449,6 +450,13 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) XF86VidModeGetGammaRamp(_glfw.x11.display, _glfw.x11.screen, ramp->size, ramp->red, ramp->green, ramp->blue); + return GLFW_TRUE; + } + else + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Gamma ramp access not supported by server"); + return GLFW_FALSE; } } @@ -481,6 +489,11 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) (unsigned short*) ramp->green, (unsigned short*) ramp->blue); } + else + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Gamma ramp access not supported by server"); + } } diff --git a/src/x11_window.c b/src/x11_window.c index c01cf17ec..5e9161072 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1455,12 +1455,20 @@ static void processEvent(XEvent *event) case EnterNotify: { + // XEnterWindowEvent is XCrossingEvent + const int x = event->xcrossing.x; + const int y = event->xcrossing.y; + // HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise // ignore the defined cursor for hidden cursor mode if (window->cursorMode == GLFW_CURSOR_HIDDEN) updateCursorImage(window); _glfwInputCursorEnter(window, GLFW_TRUE); + _glfwInputCursorPos(window, x, y); + + window->x11.lastCursorPosX = x; + window->x11.lastCursorPosY = y; return; } @@ -2450,6 +2458,14 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window) Atom* states; unsigned long i; GLFWbool maximized = GLFW_FALSE; + + if (!_glfw.x11.NET_WM_STATE || + !_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT || + !_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ) + { + return maximized; + } + const unsigned long count = _glfwGetWindowPropertyX11(window->x11.handle, _glfw.x11.NET_WM_STATE, diff --git a/tests/events.c b/tests/events.c index 9a0144d79..5c89beb5a 100644 --- a/tests/events.c +++ b/tests/events.c @@ -429,15 +429,6 @@ static void char_callback(GLFWwindow* window, unsigned int codepoint) get_character_string(codepoint)); } -static void char_mods_callback(GLFWwindow* window, unsigned int codepoint, int mods) -{ - Slot* slot = glfwGetWindowUserPointer(window); - printf("%08x to %i at %0.3f: Character 0x%08x (%s) with modifiers (with%s) input\n", - counter++, slot->number, glfwGetTime(), codepoint, - get_character_string(codepoint), - get_mods_name(mods)); -} - static void drop_callback(GLFWwindow* window, int count, const char** paths) { int i; @@ -616,7 +607,6 @@ int main(int argc, char** argv) glfwSetScrollCallback(slots[i].window, scroll_callback); glfwSetKeyCallback(slots[i].window, key_callback); glfwSetCharCallback(slots[i].window, char_callback); - glfwSetCharModsCallback(slots[i].window, char_mods_callback); glfwSetDropCallback(slots[i].window, drop_callback); glfwMakeContextCurrent(slots[i].window);