Updated glfw
parent
48c8cde66b
commit
cf59f6b6ae
|
@ -1,35 +1,118 @@
|
|||
# Contribution Guide
|
||||
|
||||
This file is a work in progress and you can report errors or submit patches for
|
||||
it the same as any other file.
|
||||
## Contents
|
||||
|
||||
- [Asking a question](#asking-a-question)
|
||||
- [Reporting a bug](#reporting-a-bug)
|
||||
- [Reporting a compile or link bug](#reporting-a-compile-or-link-bug)
|
||||
- [Reporting a segfault or other crash bug](#reporting-a-segfault-or-other-crash-bug)
|
||||
- [Reporting a context creation bug](#reporting-a-context-creation-bug)
|
||||
- [Reporting a monitor or video mode bug](#reporting-a-monitor-or-video-mode-bug)
|
||||
- [Reporting an input or event bug](#reporting-an-input-or-event-bug)
|
||||
- [Reporting some other library bug](#reporting-some-other-library-bug)
|
||||
- [Reporting a documentation bug](#reporting-a-documentation-bug)
|
||||
- [Reporting a website bug](#reporting-a-website-bug)
|
||||
- [Requesting a feature](#requesting-a-feature)
|
||||
- [Contributing a bug fix](#contributing-a-bug-fix)
|
||||
- [Contributing a feature](#contributing-a-feature)
|
||||
|
||||
|
||||
## Asking a question
|
||||
|
||||
Questions about how to use GLFW should be asked either in the [support
|
||||
section](http://discourse.glfw.org/c/support) of the forum, under the [Stack
|
||||
Overflow tag](https://stackoverflow.com/questions/tagged/glfw) or [Game
|
||||
Development tag](https://gamedev.stackexchange.com/questions/tagged/glfw) on
|
||||
Stack Exchange or in the IRC channel `#glfw` on
|
||||
[Freenode](http://freenode.net/).
|
||||
|
||||
Questions about the design or implementation of GLFW or about future plans
|
||||
should be asked in the [dev section](http://discourse.glfw.org/c/dev) of the
|
||||
forum or in the IRC channel. Please don't open a GitHub issue to discuss design
|
||||
questions without first checking with a maintainer.
|
||||
|
||||
|
||||
## Reporting a bug
|
||||
|
||||
If GLFW is behaving unexpectedly, make sure you have set an error callback.
|
||||
GLFW will often tell you the cause of an issue via this callback.
|
||||
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).
|
||||
GLFW will often tell you the cause of an error via this callback. If it
|
||||
doesn't, that might be a separate bug.
|
||||
|
||||
If GLFW is crashing or triggering asserts, make sure that all your object
|
||||
handles and other pointers are valid.
|
||||
|
||||
Always include the __operating system name and version__ (i.e. `Windows
|
||||
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW,
|
||||
include the __GLFW release version__ (i.e. `3.1.2`), otherwise include the
|
||||
__GLFW commit ID__ (i.e. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
|
||||
If possible, please also include the __GLFW version string__ (`3.2.0 X11 EGL
|
||||
clock_gettime /dev/js XI Xf86vm`), as described
|
||||
[here](http://www.glfw.org/docs/latest/intro.html#intro_version_string).
|
||||
For bugs where it makes sense, a [Short, Self Contained, Correct (Compilable),
|
||||
Example](http://www.sscce.org/) is absolutely invaluable. Just put it inline in
|
||||
the body text. Note that if the bug is reproducible with one of the test
|
||||
programs that come with GLFW, just mention that instead.
|
||||
|
||||
__Don't worry about adding too much information__. Unimportant information can
|
||||
be abbreviated or removed later, but missing information can stall bug fixing,
|
||||
especially when your schedule doesn't align with that of the maintainer.
|
||||
|
||||
There are issue labels for both platforms and GPU manufacturers, so there is no
|
||||
need to mention these in the subject line. If you do, it will be removed when
|
||||
the issue is labeled.
|
||||
|
||||
If your bug is already reported, please add any new information you have, or if
|
||||
it already has everything, give it a :+1:.
|
||||
|
||||
|
||||
### Reporting a compile or link bug
|
||||
|
||||
__Note:__ GLFW needs many system APIs to do its job. See the [Building
|
||||
applications](http://www.glfw.org/docs/latest/build.html) guide for more
|
||||
information.
|
||||
__Note:__ GLFW needs many system APIs to do its job, which on some platforms
|
||||
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.
|
||||
|
||||
In addition to the information above, always include the complete build log from
|
||||
your compiler and linker. Issue posts are editable so it can always be
|
||||
shortened later.
|
||||
__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
|
||||
opening an issue of this kind. Most issues are caused by a missing package or
|
||||
linker flag.
|
||||
|
||||
Always include the __operating system name and version__ (e.g. `Windows
|
||||
7 64-bit` or `Ubuntu 15.10`) and the __compiler name and version__ (e.g. `Visual
|
||||
C++ 2015 Update 2`). If you are using an official release of GLFW,
|
||||
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
|
||||
__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
|
||||
|
||||
Please also include the __complete build log__ from your compiler and linker,
|
||||
even if it's long. It can always be shortened later, if necessary.
|
||||
|
||||
|
||||
#### Quick template
|
||||
|
||||
```
|
||||
OS and version:
|
||||
Compiler version:
|
||||
Release or commit:
|
||||
Build log:
|
||||
```
|
||||
|
||||
|
||||
### Reporting a segfault or other crash bug
|
||||
|
||||
Always include the __operating system name and version__ (e.g. `Windows
|
||||
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW,
|
||||
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
|
||||
__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
|
||||
the __full call stack__ of the crash, or if the crash does not occur in debug
|
||||
mode, mention that instead.
|
||||
|
||||
|
||||
#### Quick template
|
||||
|
||||
```
|
||||
OS and version:
|
||||
Release or commit:
|
||||
Error messages:
|
||||
Call stack:
|
||||
```
|
||||
|
||||
|
||||
### Reporting a context creation bug
|
||||
|
@ -38,23 +121,42 @@ __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),
|
||||
[Intel](https://www-ssl.intel.com/content/www/us/en/support/detect.html)) to
|
||||
[AMD](http://support.amd.com/en-us/download),
|
||||
[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. EGL support is not
|
||||
enabled in GLFW by default. You need to [enable EGL when
|
||||
compiling](http://www.glfw.org/docs/latest/compile.html) GLFW to use 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)
|
||||
hint for how to select EGL.
|
||||
|
||||
The `glfwinfo` tool is included in the GLFW source tree as `tests/glfwinfo.c`
|
||||
and is built along with the library. It lets you request any kind of context
|
||||
and framebuffer format supported by the GLFW API without having to recompile.
|
||||
If context creation fails in your application, please verify that it also fails
|
||||
with this tool before reporting it as a bug.
|
||||
Please verify that context creation also fails with the `glfwinfo` tool before
|
||||
reporting it as a bug. This tool is included in the GLFW source tree as
|
||||
`tests/glfwinfo.c` and is built along with the library. It has switches for all
|
||||
GLFW context and framebuffer hints. Run `glfwinfo -h` for a complete list.
|
||||
|
||||
In addition to the information above (OS and GLFW version), always include the
|
||||
__GPU model and driver version__ (i.e. `GeForce GTX660 with 352.79`) when
|
||||
reporting this kind of bug.
|
||||
Always include the __operating system name and version__ (e.g. `Windows
|
||||
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW,
|
||||
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
|
||||
__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
|
||||
|
||||
Please also include the __GLFW version string__ (`3.2.0 X11 EGL clock_gettime
|
||||
/dev/js XI Xf86vm`), as described
|
||||
[here](http://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,
|
||||
mention that instead.
|
||||
|
||||
|
||||
#### Quick template
|
||||
|
||||
```
|
||||
OS and version:
|
||||
GPU and driver:
|
||||
Release or commit:
|
||||
Version string:
|
||||
glfwinfo output:
|
||||
```
|
||||
|
||||
|
||||
### Reporting a monitor or video mode bug
|
||||
|
@ -63,23 +165,44 @@ __Note:__ On headless systems on some platforms, no monitors are reported. This
|
|||
causes glfwGetPrimaryMonitor to return `NULL`, which not all applications are
|
||||
prepared for.
|
||||
|
||||
__Note:__ Some third-party tools report more video modes than those approved of
|
||||
by the OS. For safety and compatbility, GLFW only reports video modes the OS
|
||||
__Note:__ Some third-party tools report more video modes than are approved of
|
||||
by the OS. For safety and compatibility, GLFW only reports video modes the OS
|
||||
wants programs to use. This is not a bug.
|
||||
|
||||
The `monitors` tool is included in the GLFW source tree as `tests/monitors.c`
|
||||
and is built along with the library. lists all information about connected
|
||||
monitors made available by GLFW.
|
||||
and is built along with the library. It lists all information GLFW provides
|
||||
about monitors it detects.
|
||||
|
||||
In addition to the information above (OS and GLFW version), please also include
|
||||
the output of the `monitors` tool when reporting this kind of bug. If it
|
||||
doesn't work at all, please mention this.
|
||||
Always include the __operating system name and version__ (e.g. `Windows
|
||||
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW,
|
||||
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
|
||||
__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
|
||||
the __output of `monitors`__ when reporting this kind of bug. If this tool
|
||||
doesn't run on the machine, mention this instead.
|
||||
|
||||
|
||||
### Reporting a window event bug
|
||||
#### Quick template
|
||||
|
||||
__Note:__ While GLFW tries to provide the exact same behavior between platforms,
|
||||
the exact ordering of related window events will sometimes differ.
|
||||
```
|
||||
OS and version:
|
||||
Release or commit:
|
||||
Error messages:
|
||||
monitors output:
|
||||
```
|
||||
|
||||
|
||||
### Reporting an input or event bug
|
||||
|
||||
__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
|
||||
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
|
||||
built along with the library. It prints all information provided to every
|
||||
|
@ -87,20 +210,137 @@ callback supported by GLFW as events occur. Each event is listed with the time
|
|||
and a unique number to make discussions about event logs easier. The tool has
|
||||
command-line options for creating multiple windows and full screen windows.
|
||||
|
||||
Always include the __operating system name and version__ (e.g. `Windows
|
||||
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW,
|
||||
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
|
||||
__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
|
||||
if relevant, the __output of `events`__ when reporting this kind of bug. If
|
||||
this tool doesn't run on the machine, mention this instead.
|
||||
|
||||
|
||||
#### Quick template
|
||||
|
||||
```
|
||||
OS and version:
|
||||
Release or commit:
|
||||
Error messages:
|
||||
events output:
|
||||
```
|
||||
|
||||
|
||||
### Reporting some other library bug
|
||||
|
||||
Always include the __operating system name and version__ (e.g. `Windows
|
||||
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW,
|
||||
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
|
||||
__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
|
||||
relevant.
|
||||
|
||||
|
||||
#### Quick template
|
||||
|
||||
```
|
||||
OS and version:
|
||||
Release or commit:
|
||||
Error messages:
|
||||
```
|
||||
|
||||
|
||||
### Reporting a documentation bug
|
||||
|
||||
If you found the error in the generated documentation then it's fine to just
|
||||
link to that webpage. You don't need to figure out which documentation source
|
||||
file the text comes from.
|
||||
If you found a bug in the documentation, including this file, then it's fine to
|
||||
just link to that web page or mention that source file. You don't need to match
|
||||
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
|
||||
source repository](https://github.com/glfw/website/issues).
|
||||
|
||||
|
||||
## Requesting a feature
|
||||
|
||||
Please explain why you need the feature and how you intend to use it. If you
|
||||
have a specific API design in mind, please add that as well. If you have or are
|
||||
planning to write code for the feature, see the section below.
|
||||
|
||||
If there already is a request for the feature you need, add your specific use
|
||||
case unless it is already mentioned. If it is, give it a :+1:.
|
||||
|
||||
|
||||
## Contributing a bug fix
|
||||
|
||||
There should be text here, but there isn't.
|
||||
__Note:__ You must have all necessary [intellectual
|
||||
property rights](https://en.wikipedia.org/wiki/Intellectual_property) to any
|
||||
code you contribute. If you did not write the code yourself, you must explain
|
||||
where it came from and under what license you received it. Even code using the
|
||||
same license as GLFW may not be copied without attribution.
|
||||
|
||||
__There is no preferred patch size__. A one character fix is just as welcome as
|
||||
a thousand line one, if that is the appropriate size for the fix.
|
||||
|
||||
In addition to the code, a complete bug fix includes:
|
||||
|
||||
- Change log entry in `README.md`, describing the incorrect behavior
|
||||
- Credits entries for all authors of the bug fix
|
||||
|
||||
Bug fixes will not be rejected because they don't include all the above parts,
|
||||
but please keep in mind that maintainer time is finite and that there are many
|
||||
other bugs and features to work on.
|
||||
|
||||
If the patch fixes a bug introduced after the last release, it should not get
|
||||
a change log entry.
|
||||
|
||||
|
||||
## Contributing a feature
|
||||
|
||||
This is not (yet) the text you are looking for.
|
||||
__Note:__ You must have all necessary rights to any code you contribute. If you
|
||||
did not write the code yourself, you must explain where it came from and under
|
||||
what license. Even code using the same license as GLFW may not be copied
|
||||
without attribution.
|
||||
|
||||
__There is no preferred patch size__. A one character change is just as welcome
|
||||
as one adding a thousand line one, if that is the appropriate size for the
|
||||
feature.
|
||||
|
||||
In addition to the code, a complete feature includes:
|
||||
|
||||
- Change log entry in `README.md`, listing all new symbols
|
||||
- News page entry, briefly describing the feature
|
||||
- Guide documentation, with minimal examples, in the relevant guide
|
||||
- Reference documentation, with all applicable tags
|
||||
- Cross-references and mentions in appropriate places
|
||||
- Credits entries for all authors of the feature
|
||||
|
||||
If the feature requires platform-specific code, at minimum stubs must be added
|
||||
for the new platform function to all supported and experimental platforms.
|
||||
|
||||
If it adds a new callback, support for it must be added to `tests/event.c`.
|
||||
|
||||
If it adds a new monitor property, support for it must be added to
|
||||
`tests/monitor.c`.
|
||||
|
||||
If it adds a new OpenGL, OpenGL ES or Vulkan option or extension, support
|
||||
for it must be added to `tests/glfwinfo.c` and the behavior of the library when
|
||||
the extension is missing documented in `docs/compat.dox`.
|
||||
|
||||
Features will not be rejected because they don't include all the above parts,
|
||||
but please keep in mind that maintainer time is finite and that there are many
|
||||
other features and bugs to work on.
|
||||
|
||||
Please also keep in mind that any part of the public API that has been included
|
||||
in a release cannot be changed until the next _major_ version. Features can be
|
||||
added and existing parts can sometimes be overloaded (in the general sense of
|
||||
doing more things, not in the C++ sense), but code written to the API of one
|
||||
minor release should both compile and run on subsequent minor releases.
|
||||
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
# External junk
|
||||
.DS_Store
|
||||
_ReSharper*
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.suo
|
||||
*.dir
|
||||
*.vcxproj*
|
||||
*.sln
|
||||
Win32
|
||||
x64
|
||||
Debug
|
||||
Release
|
||||
MinSizeRel
|
||||
RelWithDebInfo
|
||||
*.xcodeproj
|
||||
|
||||
# CMake files
|
||||
Makefile
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
cmake_install.cmake
|
||||
cmake_uninstall.cmake
|
||||
|
||||
# Generated files
|
||||
docs/Doxyfile
|
||||
docs/html
|
||||
docs/warnings.txt
|
||||
docs/doxygen_sqlite3.db
|
||||
src/glfw_config.h
|
||||
src/glfw3.pc
|
||||
src/glfw3Config.cmake
|
||||
src/glfw3ConfigVersion.cmake
|
||||
src/wayland-pointer-constraints-unstable-v1-client-protocol.h
|
||||
src/wayland-pointer-constraints-unstable-v1-protocol.c
|
||||
src/wayland-relative-pointer-unstable-v1-client-protocol.h
|
||||
src/wayland-relative-pointer-unstable-v1-protocol.c
|
||||
|
||||
# Compiled binaries
|
||||
src/libglfw.so
|
||||
src/libglfw.so.3
|
||||
src/libglfw.so.3.2
|
||||
src/libglfw.dylib
|
||||
src/libglfw.dylib
|
||||
src/libglfw.3.dylib
|
||||
src/libglfw.3.2.dylib
|
||||
src/libglfw3.a
|
||||
src/glfw3.lib
|
||||
src/glfw3.dll
|
||||
src/glfw3dll.lib
|
||||
src/libglfw3dll.a
|
||||
examples/*.app
|
||||
examples/*.exe
|
||||
examples/boing
|
||||
examples/gears
|
||||
examples/heightmap
|
||||
examples/particles
|
||||
examples/splitview
|
||||
examples/simple
|
||||
examples/wave
|
||||
tests/*.app
|
||||
tests/*.exe
|
||||
tests/clipboard
|
||||
tests/cursor
|
||||
tests/empty
|
||||
tests/events
|
||||
tests/gamma
|
||||
tests/glfwinfo
|
||||
tests/iconify
|
||||
tests/joysticks
|
||||
tests/monitors
|
||||
tests/msaa
|
||||
tests/reopen
|
||||
tests/sharing
|
||||
tests/tearing
|
||||
tests/threads
|
||||
tests/title
|
||||
tests/version
|
||||
tests/vulkan
|
||||
tests/windows
|
||||
|
|
@ -12,6 +12,9 @@ if (WIN32)
|
|||
find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS
|
||||
"$ENV{VULKAN_SDK}/Bin"
|
||||
"$ENV{VK_SDK_PATH}/Bin")
|
||||
find_library(VULKAN_STATIC_LIBRARY NAMES vkstatic.1 HINTS
|
||||
"$ENV{VULKAN_SDK}/Bin"
|
||||
"$ENV{VK_SDK_PATH}/Bin")
|
||||
else()
|
||||
find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS
|
||||
"$ENV{VULKAN_SDK}/Bin32"
|
||||
|
@ -27,5 +30,5 @@ endif()
|
|||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Vulkan DEFAULT_MSG VULKAN_LIBRARY VULKAN_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(VULKAN_INCLUDE_DIR VULKAN_LIBRARY)
|
||||
mark_as_advanced(VULKAN_INCLUDE_DIR VULKAN_LIBRARY VULKAN_STATIC_LIBRARY)
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ON)
|
|||
option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON)
|
||||
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)
|
||||
option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF)
|
||||
|
||||
if (WIN32)
|
||||
|
@ -57,7 +58,11 @@ else()
|
|||
set(GLFW_LIB_NAME glfw3)
|
||||
endif()
|
||||
|
||||
set(CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
|
||||
if (GLFW_VULKAN_STATIC)
|
||||
set(_GLFW_VULKAN_STATIC 1)
|
||||
endif()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(Vulkan)
|
||||
|
@ -148,6 +153,21 @@ else()
|
|||
message(FATAL_ERROR "No supported platform was detected")
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Add Vulkan static library if requested
|
||||
#--------------------------------------------------------------------
|
||||
if (GLFW_VULKAN_STATIC)
|
||||
if (VULKAN_FOUND AND VULKAN_STATIC_LIBRARY)
|
||||
list(APPEND glfw_LIBRARIES ${VULKAN_STATIC_LIBRARY})
|
||||
else()
|
||||
if (BUILD_SHARED_LIBS OR GLFW_BUILD_EXAMPLES OR GLFW_BUILD_TESTS)
|
||||
message(FATAL_ERROR "Vulkan loader static library not found")
|
||||
else()
|
||||
message(WARNING "Vulkan loader static library not found")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Find and add Unix math and time libraries
|
||||
#--------------------------------------------------------------------
|
||||
|
@ -253,7 +273,7 @@ endif()
|
|||
#--------------------------------------------------------------------
|
||||
if (_GLFW_WAYLAND)
|
||||
find_package(ECM REQUIRED NO_MODULE)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH})
|
||||
list(APPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
|
||||
|
||||
find_package(Wayland REQUIRED)
|
||||
find_package(WaylandScanner REQUIRED)
|
||||
|
|
|
@ -2,19 +2,25 @@
|
|||
|
||||
[![Build status](https://travis-ci.org/glfw/glfw.svg?branch=master)](https://travis-ci.org/glfw/glfw)
|
||||
[![Build status](https://ci.appveyor.com/api/projects/status/0kf0ct9831i5l6sp/branch/master?svg=true)](https://ci.appveyor.com/project/elmindreda/glfw)
|
||||
[![Coverity Scan](https://scan.coverity.com/projects/4884/badge.svg)](https://scan.coverity.com/projects/glfw-glfw)
|
||||
|
||||
## Introduction
|
||||
|
||||
GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and
|
||||
Vulkan application development. It provides a simple, platform-independent API
|
||||
for creating windows, contexts and surfaces, reading input, handling events, etc.
|
||||
GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan
|
||||
application development. It provides a simple, platform-independent API for
|
||||
creating windows, contexts and surfaces, reading input, handling events, etc.
|
||||
|
||||
The current stable release is version 3.2. See the
|
||||
[downloads](http://www.glfw.org/download.html) page for details and files, or
|
||||
fetch the `latest` branch, which always points to the latest stable release.
|
||||
Each release starting with 3.0 also has a corresponding annotated tag.
|
||||
GLFW is licensed under the [zlib/libpng
|
||||
license](https://opensource.org/licenses/Zlib).
|
||||
|
||||
This is version 3.2.1, which is _not yet described_.
|
||||
This is version 3.2.1, which adds support for statically linking the Vulkan
|
||||
loader and fixes for a number of bugs that together affect all supported
|
||||
platforms.
|
||||
|
||||
See the [downloads](http://www.glfw.org/download.html) page for details and
|
||||
files, or fetch the `latest` branch, which always points to the latest stable
|
||||
release. Each release starting with 3.0 also has a corresponding [annotated
|
||||
tag](https://github.com/glfw/glfw/releases) with source and binary archives.
|
||||
|
||||
If you are new to GLFW, you may find the
|
||||
[tutorial](http://www.glfw.org/docs/latest/quick.html) for GLFW
|
||||
|
@ -25,37 +31,43 @@ the GLFW 3 API.
|
|||
|
||||
## Compiling GLFW
|
||||
|
||||
See the [Compiling GLFW](http://www.glfw.org/docs/latest/compile.html) guide in
|
||||
the GLFW documentation.
|
||||
GLFW itself requires only the headers and libraries for your window system. It
|
||||
does not need the headers for any context creation API (WGL, GLX, EGL, NSGL) or
|
||||
rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
|
||||
|
||||
GLFW supports compilation on Windows with Visual C++ 2010 and later, MinGW and
|
||||
MinGW-w64, on OS X with Clang and on Linux and other Unix-like systems with GCC
|
||||
and Clang. It will likely compile in other environments as well, but this is
|
||||
not regularly tested.
|
||||
|
||||
There are also [pre-compiled Windows
|
||||
binaries](http://www.glfw.org/download.html) available for all compilers
|
||||
supported on that platform.
|
||||
|
||||
See the [compilation guide](http://www.glfw.org/docs/latest/compile.html) in the
|
||||
documentation for more information.
|
||||
|
||||
|
||||
## Using GLFW
|
||||
|
||||
See the
|
||||
[Building programs that use GLFW](http://www.glfw.org/docs/latest/build.html)
|
||||
guide in the GLFW documentation.
|
||||
See the [building application guide](http://www.glfw.org/docs/latest/build.html)
|
||||
guide in the documentation for more information.
|
||||
|
||||
|
||||
## Reporting bugs
|
||||
## System requirements
|
||||
|
||||
Bugs are reported to our [issue tracker](https://github.com/glfw/glfw/issues).
|
||||
Please always include the name and version of the OS where the bug occurs and
|
||||
the version of GLFW used. If you have cloned it, include the commit ID used.
|
||||
GLFW supports Windows XP and later, OS X 10.7 Lion and later, and Linux and
|
||||
other Unix-like systems with the X Window System. Experimental implementations
|
||||
for the Wayland protocol and the Mir display server are available but not yet
|
||||
officially supported.
|
||||
|
||||
If it's a build issue, please also include the build log and the name and
|
||||
version of your development environment.
|
||||
|
||||
If it's a context creation issue, please also include the make and model of your
|
||||
graphics card and the version of your driver.
|
||||
|
||||
This will help both us and other people experiencing the same bug.
|
||||
See the [compatibility guide](http://www.glfw.org/docs/latest/compat.html)
|
||||
in the documentation for more information.
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
GLFW itself needs only the headers and libraries for your window system. It
|
||||
does not need the headers for any context creation API (WGL, GLX, EGL, NSGL) or
|
||||
rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
|
||||
GLFW itself depends only on the headers and libraries for your window system.
|
||||
|
||||
The examples and test programs depend on a number of tiny libraries. These are
|
||||
located in the `deps/` directory.
|
||||
|
@ -74,30 +86,64 @@ The Vulkan example additionally requires the Vulkan SDK to be installed, or it
|
|||
will not be included in the build.
|
||||
|
||||
The documentation is generated with [Doxygen](http://doxygen.org/). If CMake
|
||||
does not find Doxygen, the documentation will not be generated.
|
||||
does not find Doxygen, the documentation will not be generated when you build.
|
||||
|
||||
|
||||
## Reporting bugs
|
||||
|
||||
Bugs are reported to our [issue tracker](https://github.com/glfw/glfw/issues).
|
||||
Please check the [contribution
|
||||
guide](https://github.com/glfw/glfw/blob/master/.github/CONTRIBUTING.md) for
|
||||
information on what to include when reporting a bug.
|
||||
|
||||
|
||||
## Changelog
|
||||
|
||||
- Bugfix: The range checks for `glfwSetCursorPos` used the wrong minimum
|
||||
- Added on-demand loading of Vulkan and context creation API libraries
|
||||
- Added `_GLFW_VULKAN_STATIC` build macro to make the library use the Vulkan
|
||||
loader linked statically into the application (#820)
|
||||
- Bugfix: Single compilation unit builds failed due to naming conflicts (#783)
|
||||
- Bugfix: The range checks for `glfwSetCursorPos` used the wrong minimum (#773)
|
||||
- Bugfix: Defining `GLFW_INCLUDE_VULKAN` when compiling the library did not
|
||||
fail with the expected error message (#823)
|
||||
- Bugfix: Inherited value of `CMAKE_MODULE_PATH` was clobbered (#822)
|
||||
- [Win32] Bugfix: `glfwSetClipboardString` created an unnecessary intermediate
|
||||
copy of the string
|
||||
- [Win32] Bugfix: Examples failed to build on Visual C++ 2010 due to C99 in
|
||||
`linmath.h` (#785)
|
||||
- [Win32] Bugfix: The first shown window ignored the `GLFW_MAXIMIZED` hint
|
||||
when the process was provided a `STARTUPINFO` (#780)
|
||||
- [Cocoa] Bugfix: Event processing would segfault on some machines due to
|
||||
a previous distributed notification listener not being fully
|
||||
removed (#817,#826)
|
||||
- [Cocoa] Bugfix: Some include statements were duplicated (#838)
|
||||
- [X11] Bugfix: Window size limits were ignored if the minimum or maximum size
|
||||
was set to `GLFW_DONT_CARE` (#805)
|
||||
- [X11] Bugfix: Input focus was set before window was visible, causing
|
||||
`BadMatch` on some non-reparenting WMs (#789,#798)
|
||||
- [X11] Bugfix: `glfwGetWindowPos` and `glfwSetWindowPos` operated on the
|
||||
window frame instead of the client area (#800)
|
||||
- [WGL] Added reporting of errors from `WGL_ARB_create_context` extension
|
||||
- [GLX] Bugfix: Dynamically loaded entry points were not verified
|
||||
- [EGL] Added `lib` prefix matching between EGL and OpenGL ES library binaries
|
||||
- [EGL] Bugfix: Dynamically loaded entry points were not verified
|
||||
|
||||
|
||||
## Contact
|
||||
|
||||
The official website for GLFW is [glfw.org](http://www.glfw.org/). There you
|
||||
can find the latest version of GLFW, as well as news, documentation and other
|
||||
information about the project.
|
||||
On [glfw.org](http://www.glfw.org/) you can find the latest version of GLFW, as
|
||||
well as news, documentation and other information about the project.
|
||||
|
||||
If you have questions related to the use of GLFW, we have a
|
||||
[support forum](http://discourse.glfw.org/), and the IRC
|
||||
channel `#glfw` on [Freenode](http://freenode.net/).
|
||||
[forum](http://discourse.glfw.org/), and the `#glfw` IRC channel on
|
||||
[Freenode](http://freenode.net/).
|
||||
|
||||
If you have a bug to report, a patch to submit or a feature you'd like to
|
||||
request, please file it in the
|
||||
[issue tracker](https://github.com/glfw/glfw/issues) on GitHub.
|
||||
|
||||
Finally, if you're interested in helping out with the development of GLFW or
|
||||
porting it to your favorite platform, join us on GitHub or IRC.
|
||||
porting it to your favorite platform, join us on the forum, GitHub or IRC.
|
||||
|
||||
|
||||
## Acknowledgements
|
||||
|
@ -140,8 +186,10 @@ skills.
|
|||
- heromyth
|
||||
- Lucas Hinderberger
|
||||
- Paul Holden
|
||||
- Warren Hu
|
||||
- IntellectualKitty
|
||||
- Aaron Jacobs
|
||||
- Erik S. V. Jansson
|
||||
- Toni Jovanoski
|
||||
- Arseny Kapoulkine
|
||||
- Osman Keskin
|
||||
|
@ -181,6 +229,7 @@ skills.
|
|||
- Emmanuel Gil Peyrot
|
||||
- Cyril Pichard
|
||||
- Pieroman
|
||||
- Philip Rideout
|
||||
- Jorge Rodriguez
|
||||
- Ed Ropple
|
||||
- Aleksey Rybalkin
|
||||
|
@ -195,6 +244,7 @@ skills.
|
|||
- Dmitri Shuralyov
|
||||
- Daniel Skorupski
|
||||
- Bradley Smith
|
||||
- Patrick Snape
|
||||
- Julian Squires
|
||||
- Johannes Stein
|
||||
- Justin Stoecker
|
||||
|
@ -202,7 +252,7 @@ skills.
|
|||
- Nathan Sweet
|
||||
- TTK-Bandit
|
||||
- Sergey Tikhomirov
|
||||
- A. Tombs
|
||||
- Arthur Tombs
|
||||
- Ioannis Tsakpinis
|
||||
- Samuli Tuomola
|
||||
- urraka
|
||||
|
|
|
@ -192,19 +192,20 @@ static inline void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z,
|
|||
vec3 u = {x, y, z};
|
||||
|
||||
if(vec3_len(u) > 1e-4) {
|
||||
mat4x4 T, C, S;
|
||||
|
||||
vec3_norm(u, u);
|
||||
mat4x4 T;
|
||||
mat4x4_from_vec3_mul_outer(T, u, u);
|
||||
|
||||
mat4x4 S = {
|
||||
{ 0, u[2], -u[1], 0},
|
||||
{-u[2], 0, u[0], 0},
|
||||
{ u[1], -u[0], 0, 0},
|
||||
{ 0, 0, 0, 0}
|
||||
};
|
||||
S[1][2] = u[0];
|
||||
S[2][1] = -u[0];
|
||||
S[2][0] = u[1];
|
||||
S[0][2] = -u[1];
|
||||
S[0][1] = u[2];
|
||||
S[1][0] = -u[2];
|
||||
|
||||
mat4x4_scale(S, S, s);
|
||||
|
||||
mat4x4 C;
|
||||
mat4x4_identity(C);
|
||||
mat4x4_sub(C, C, T);
|
||||
|
||||
|
@ -257,6 +258,7 @@ static inline void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle)
|
|||
}
|
||||
static inline void mat4x4_invert(mat4x4 T, mat4x4 M)
|
||||
{
|
||||
float idet;
|
||||
float s[6];
|
||||
float c[6];
|
||||
s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1];
|
||||
|
@ -274,7 +276,7 @@ static inline void mat4x4_invert(mat4x4 T, mat4x4 M)
|
|||
c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3];
|
||||
|
||||
/* Assumes it is invertible */
|
||||
float idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] );
|
||||
idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] );
|
||||
|
||||
T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet;
|
||||
T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet;
|
||||
|
@ -298,10 +300,10 @@ static inline void mat4x4_invert(mat4x4 T, mat4x4 M)
|
|||
}
|
||||
static inline void mat4x4_orthonormalize(mat4x4 R, mat4x4 M)
|
||||
{
|
||||
mat4x4_dup(R, M);
|
||||
float s = 1.;
|
||||
vec3 h;
|
||||
|
||||
mat4x4_dup(R, M);
|
||||
vec3_norm(R[2], R[2]);
|
||||
|
||||
s = vec3_mul_inner(R[1], R[2]);
|
||||
|
@ -387,14 +389,15 @@ static inline void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up)
|
|||
/* TODO: The negation of of can be spared by swapping the order of
|
||||
* operands in the following cross products in the right way. */
|
||||
vec3 f;
|
||||
vec3 s;
|
||||
vec3 t;
|
||||
|
||||
vec3_sub(f, center, eye);
|
||||
vec3_norm(f, f);
|
||||
|
||||
vec3 s;
|
||||
vec3_mul_cross(s, f, up);
|
||||
vec3_norm(s, s);
|
||||
|
||||
vec3 t;
|
||||
vec3_mul_cross(t, s, f);
|
||||
|
||||
m[0][0] = s[0];
|
||||
|
@ -470,9 +473,9 @@ static inline void quat_conj(quat r, quat q)
|
|||
r[3] = q[3];
|
||||
}
|
||||
static inline void quat_rotate(quat r, float angle, vec3 axis) {
|
||||
int i;
|
||||
vec3 v;
|
||||
vec3_scale(v, axis, sinf(angle / 2));
|
||||
int i;
|
||||
for(i=0; i<3; ++i)
|
||||
r[i] = v[i];
|
||||
r[3] = cosf(angle / 2);
|
||||
|
|
|
@ -115,11 +115,14 @@ extern "C" {
|
|||
#define GLFW_CALLBACK_DEFINED
|
||||
#endif /* CALLBACK */
|
||||
|
||||
/* Most Windows GLU headers need wchar_t.
|
||||
* The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h.
|
||||
/* Include because most Windows GLU headers need wchar_t and
|
||||
* the OS X OpenGL header blocks the definition of ptrdiff_t by glext.h.
|
||||
* Include it unconditionally to avoid surprising side-effects.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
|
||||
/* Include because it is needed by Vulkan and related functions.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
/* Include the chosen client API headers.
|
||||
|
@ -1182,6 +1185,7 @@ typedef struct GLFWgammaramp
|
|||
/*! @brief Image data.
|
||||
*
|
||||
* @sa @ref cursor_custom
|
||||
* @sa @ref window_icon
|
||||
*
|
||||
* @since Added in version 2.1.
|
||||
* @glfw3 Removed format and bytes-per-pixel members.
|
||||
|
@ -1739,6 +1743,10 @@ GLFWAPI void glfwWindowHint(int hint, int value);
|
|||
* screen windows, including the creation of so called _windowed full screen_
|
||||
* or _borderless full screen_ windows, see @ref window_windowed_full_screen.
|
||||
*
|
||||
* Once you have created the window, you can switch it between windowed and
|
||||
* full screen mode with @ref glfwSetWindowMonitor. If the window has an
|
||||
* OpenGL or OpenGL ES context, it will be unaffected.
|
||||
*
|
||||
* By default, newly created windows use the placement recommended by the
|
||||
* window system. To create the window at a specific position, make it
|
||||
* initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window
|
||||
|
@ -2390,8 +2398,8 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* window);
|
|||
* in full screen on.
|
||||
*
|
||||
* @param[in] window The window to query.
|
||||
* @return The monitor, or `NULL` if the window is in windowed mode or an error
|
||||
* occurred.
|
||||
* @return The monitor, or `NULL` if the window is in windowed mode or an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
|
@ -2846,7 +2854,7 @@ GLFWAPI void glfwWaitEventsTimeout(double timeout);
|
|||
/*! @brief Posts an empty event to the event queue.
|
||||
*
|
||||
* This function posts an empty event from the current thread to the event
|
||||
* queue, causing @ref glfwWaitEvents to return.
|
||||
* queue, causing @ref glfwWaitEvents or @ref glfwWaitEventsTimeout to return.
|
||||
*
|
||||
* If no windows exist, this function returns immediately. For synchronization
|
||||
* of threads in applications that do not create windows, use your threading
|
||||
|
@ -2859,6 +2867,7 @@ GLFWAPI void glfwWaitEventsTimeout(double timeout);
|
|||
*
|
||||
* @sa @ref events
|
||||
* @sa glfwWaitEvents
|
||||
* @sa glfwWaitEventsTimeout
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
|
@ -3354,7 +3363,7 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun);
|
|||
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
|
||||
* callback.
|
||||
* @return The previously set callback, or `NULL` if no callback was set or an
|
||||
* error occurred.
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
|
@ -3533,8 +3542,10 @@ GLFWAPI int glfwJoystickPresent(int joy);
|
|||
*
|
||||
* @param[in] joy The [joystick](@ref joysticks) to query.
|
||||
* @param[out] count Where to store the number of axis values in the returned
|
||||
* array. This is set to zero if an error occurred.
|
||||
* @return An array of axis values, or `NULL` if the joystick is not present.
|
||||
* array. This is set to zero if the joystick is not present or an error
|
||||
* occurred.
|
||||
* @return An array of axis values, or `NULL` if the joystick is not present or
|
||||
* an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
||||
|
@ -3565,8 +3576,10 @@ GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count);
|
|||
*
|
||||
* @param[in] joy The [joystick](@ref joysticks) to query.
|
||||
* @param[out] count Where to store the number of button states in the returned
|
||||
* array. This is set to zero if an error occurred.
|
||||
* @return An array of button states, or `NULL` if the joystick is not present.
|
||||
* array. This is set to zero if the joystick is not present or an error
|
||||
* occurred.
|
||||
* @return An array of button states, or `NULL` if the joystick is not present
|
||||
* or an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
||||
|
@ -3599,7 +3612,7 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count);
|
|||
*
|
||||
* @param[in] joy The [joystick](@ref joysticks) to query.
|
||||
* @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick
|
||||
* is not present.
|
||||
* is not present or an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
||||
|
|
|
@ -325,9 +325,6 @@ int _glfwPlatformInit(void)
|
|||
if (!_glfwInitThreadLocalStoragePOSIX())
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!_glfwInitNSGL())
|
||||
return GLFW_FALSE;
|
||||
|
||||
_glfwInitTimerNS();
|
||||
_glfwInitJoysticksNS();
|
||||
|
||||
|
@ -362,6 +359,8 @@ void _glfwPlatformTerminate(void)
|
|||
removeObserver:_glfw.ns.listener
|
||||
name:(__bridge NSString*)kTISNotifySelectedKeyboardInputSourceChanged
|
||||
object:nil];
|
||||
[[NSDistributedNotificationCenter defaultCenter]
|
||||
removeObserver:_glfw.ns.listener];
|
||||
[_glfw.ns.listener release];
|
||||
_glfw.ns.listener = nil;
|
||||
}
|
||||
|
|
|
@ -27,11 +27,9 @@
|
|||
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||
#include <CoreVideo/CVBase.h>
|
||||
#include <CoreVideo/CVDisplayLink.h>
|
||||
|
@ -66,7 +64,7 @@ static char* getDisplayName(CGDirectDisplayID displayID)
|
|||
|
||||
size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value),
|
||||
kCFStringEncodingUTF8);
|
||||
name = calloc(size + 1, sizeof(char));
|
||||
name = calloc(size + 1, 1);
|
||||
CFStringGetCString(value, name, size, kCFStringEncodingUTF8);
|
||||
|
||||
CFRelease(info);
|
||||
|
|
|
@ -944,7 +944,7 @@ static GLFWbool initializeAppKit(void)
|
|||
|
||||
// Create the Cocoa window
|
||||
//
|
||||
static GLFWbool createWindow(_GLFWwindow* window,
|
||||
static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig)
|
||||
{
|
||||
window->ns.delegate = [[GLFWWindowDelegate alloc] initWithGlfwWindow:window];
|
||||
|
@ -1027,13 +1027,15 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||
if (!initializeAppKit())
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!createWindow(window, wndconfig))
|
||||
if (!createNativeWindow(window, wndconfig))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwInitNSGL())
|
||||
return GLFW_FALSE;
|
||||
if (!_glfwCreateContextNSGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
@ -1067,7 +1069,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||
if (window->monitor)
|
||||
releaseMonitor(window);
|
||||
|
||||
if (window->context.client != GLFW_NO_API)
|
||||
if (window->context.destroy)
|
||||
window->context.destroy(window);
|
||||
|
||||
[window->ns.object setDelegate:nil];
|
||||
|
@ -1538,7 +1540,7 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||
memcpy([rep bitmapData], image->pixels, image->width * image->height * 4);
|
||||
|
||||
native = [[NSImage alloc] initWithSize:NSMakeSize(image->width, image->height)];
|
||||
[native addRepresentation: rep];
|
||||
[native addRepresentation:rep];
|
||||
|
||||
cursor->ns.object = [[NSCursor alloc] initWithImage:native
|
||||
hotSpot:NSMakePoint(xhot, yhot)];
|
||||
|
|
|
@ -34,56 +34,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
|
||||
// Parses the client API version string and extracts the version number
|
||||
//
|
||||
static GLFWbool parseVersionString(int* api, int* major, int* minor, int* rev)
|
||||
{
|
||||
int i;
|
||||
_GLFWwindow* window;
|
||||
const char* version;
|
||||
const char* prefixes[] =
|
||||
{
|
||||
"OpenGL ES-CM ",
|
||||
"OpenGL ES-CL ",
|
||||
"OpenGL ES ",
|
||||
NULL
|
||||
};
|
||||
|
||||
*api = GLFW_OPENGL_API;
|
||||
|
||||
window = _glfwPlatformGetCurrentContext();
|
||||
|
||||
version = (const char*) window->context.GetString(GL_VERSION);
|
||||
if (!version)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Client API version string retrieval is broken");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; prefixes[i]; i++)
|
||||
{
|
||||
const size_t length = strlen(prefixes[i]);
|
||||
|
||||
if (strncmp(version, prefixes[i], length) == 0)
|
||||
{
|
||||
version += length;
|
||||
*api = GLFW_OPENGL_ES_API;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sscanf(version, "%d.%d.%d", major, minor, rev))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"No version found in client API version string");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -369,27 +319,79 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
|
|||
|
||||
GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
|
||||
{
|
||||
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
|
||||
int i;
|
||||
_GLFWwindow* window;
|
||||
const char* version;
|
||||
const char* prefixes[] =
|
||||
{
|
||||
"OpenGL ES-CM ",
|
||||
"OpenGL ES-CL ",
|
||||
"OpenGL ES ",
|
||||
NULL
|
||||
};
|
||||
|
||||
window = _glfwPlatformGetCurrentContext();
|
||||
|
||||
window->context.source = ctxconfig->source;
|
||||
window->context.client = GLFW_OPENGL_API;
|
||||
|
||||
window->context.GetIntegerv = (PFNGLGETINTEGERVPROC)
|
||||
glfwGetProcAddress("glGetIntegerv");
|
||||
window->context.getProcAddress("glGetIntegerv");
|
||||
window->context.GetString = (PFNGLGETSTRINGPROC)
|
||||
glfwGetProcAddress("glGetString");
|
||||
window->context.getProcAddress("glGetString");
|
||||
if (!window->context.GetIntegerv || !window->context.GetString)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!parseVersionString(&window->context.client,
|
||||
version = (const char*) window->context.GetString(GL_VERSION);
|
||||
if (!version)
|
||||
{
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"OpenGL version string retrieval is broken");
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"OpenGL ES version string retrieval is broken");
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; prefixes[i]; i++)
|
||||
{
|
||||
const size_t length = strlen(prefixes[i]);
|
||||
|
||||
if (strncmp(version, prefixes[i], length) == 0)
|
||||
{
|
||||
version += length;
|
||||
window->context.client = GLFW_OPENGL_ES_API;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sscanf(version, "%d.%d.%d",
|
||||
&window->context.major,
|
||||
&window->context.minor,
|
||||
&window->context.revision))
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
if (window->context.client == GLFW_OPENGL_API)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"No version found in OpenGL version string");
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"No version found in OpenGL ES version string");
|
||||
}
|
||||
|
||||
window->context.source = ctxconfig->source;
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (window->context.major < ctxconfig->major ||
|
||||
(window->context.major == ctxconfig->major &&
|
||||
|
@ -402,10 +404,21 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
|
|||
// For API consistency, we emulate the behavior of the
|
||||
// {GLX|WGL}_ARB_create_context extension and fail here
|
||||
|
||||
if (window->context.client == GLFW_OPENGL_API)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"Requested client API version %i.%i, got version %i.%i",
|
||||
"Requested OpenGL version %i.%i, got version %i.%i",
|
||||
ctxconfig->major, ctxconfig->minor,
|
||||
window->context.major, window->context.minor);
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"Requested OpenGL ES version %i.%i, got version %i.%i",
|
||||
ctxconfig->major, ctxconfig->minor,
|
||||
window->context.major, window->context.minor);
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
|
@ -416,7 +429,7 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
|
|||
// users as early as possible that their build may be broken
|
||||
|
||||
window->context.GetStringi = (PFNGLGETSTRINGIPROC)
|
||||
glfwGetProcAddress("glGetStringi");
|
||||
window->context.getProcAddress("glGetStringi");
|
||||
if (!window->context.GetStringi)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
|
@ -521,7 +534,8 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
|
|||
// Clearing the front buffer to black to avoid garbage pixels left over from
|
||||
// previous uses of our bit of VRAM
|
||||
{
|
||||
PFNGLCLEARPROC glClear = (PFNGLCLEARPROC) glfwGetProcAddress("glClear");
|
||||
PFNGLCLEARPROC glClear = (PFNGLCLEARPROC)
|
||||
window->context.getProcAddress("glClear");
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
window->context.swapBuffers(window);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "internal.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
@ -296,6 +297,9 @@ GLFWbool _glfwInitEGL(void)
|
|||
NULL
|
||||
};
|
||||
|
||||
if (_glfw.egl.handle)
|
||||
return GLFW_TRUE;
|
||||
|
||||
for (i = 0; sonames[i]; i++)
|
||||
{
|
||||
_glfw.egl.handle = _glfw_dlopen(sonames[i]);
|
||||
|
@ -304,7 +308,12 @@ GLFWbool _glfwInitEGL(void)
|
|||
}
|
||||
|
||||
if (!_glfw.egl.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Library not found");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0);
|
||||
|
||||
_glfw.egl.GetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib");
|
||||
|
@ -339,6 +348,30 @@ GLFWbool _glfwInitEGL(void)
|
|||
_glfw.egl.GetProcAddress = (PFNEGLGETPROCADDRESSPROC)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress");
|
||||
|
||||
if (!_glfw.egl.GetConfigAttrib ||
|
||||
!_glfw.egl.GetConfigs ||
|
||||
!_glfw.egl.GetDisplay ||
|
||||
!_glfw.egl.GetError ||
|
||||
!_glfw.egl.Initialize ||
|
||||
!_glfw.egl.Terminate ||
|
||||
!_glfw.egl.BindAPI ||
|
||||
!_glfw.egl.CreateContext ||
|
||||
!_glfw.egl.DestroySurface ||
|
||||
!_glfw.egl.DestroyContext ||
|
||||
!_glfw.egl.CreateWindowSurface ||
|
||||
!_glfw.egl.MakeCurrent ||
|
||||
!_glfw.egl.SwapBuffers ||
|
||||
!_glfw.egl.SwapInterval ||
|
||||
!_glfw.egl.QueryString ||
|
||||
!_glfw.egl.GetProcAddress)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: Failed to load required entry points");
|
||||
|
||||
_glfwTerminateEGL();
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY);
|
||||
if (_glfw.egl.display == EGL_NO_DISPLAY)
|
||||
{
|
||||
|
@ -600,6 +633,11 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||
|
||||
for (i = 0; sonames[i]; i++)
|
||||
{
|
||||
// HACK: Match presence of lib prefix to increase chance of finding
|
||||
// a matching pair in the jungle that is Win32 EGL/GLES
|
||||
if (_glfw.egl.prefix != (strncmp(sonames[i], "lib", 3) == 0))
|
||||
continue;
|
||||
|
||||
window->context.egl.client = _glfw_dlopen(sonames[i]);
|
||||
if (window->context.egl.client)
|
||||
break;
|
||||
|
|
|
@ -171,6 +171,7 @@ typedef struct _GLFWlibraryEGL
|
|||
{
|
||||
EGLDisplay display;
|
||||
EGLint major, minor;
|
||||
GLFWbool prefix;
|
||||
|
||||
GLFWbool KHR_create_context;
|
||||
GLFWbool KHR_create_context_no_error;
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
|
||||
// Define this to 1 if building as a shared library / dynamic library / DLL
|
||||
#cmakedefine _GLFW_BUILD_DLL
|
||||
// Define this to 1 to use Vulkan loader linked statically into application
|
||||
#cmakedefine _GLFW_VULKAN_STATIC
|
||||
|
||||
// Define this to 1 to force use of high-performance GPU on hybrid systems
|
||||
#cmakedefine _GLFW_USE_HYBRID_HPG
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef GLXBadProfileARB
|
||||
#define GLXBadProfileARB 13
|
||||
|
@ -180,19 +179,14 @@ static void swapIntervalGLX(int interval)
|
|||
|
||||
if (_glfw.glx.EXT_swap_control)
|
||||
{
|
||||
fprintf (stderr, "swapping with glXSwapIntervalEXT\n");
|
||||
_glfw.glx.SwapIntervalEXT(_glfw.x11.display,
|
||||
window->context.glx.window,
|
||||
interval);
|
||||
}
|
||||
else if (_glfw.glx.MESA_swap_control)
|
||||
{
|
||||
fprintf (stderr, "swapping with glXSwapIntervalMESA %d %p\n", interval, _glfw.glx.SwapIntervalMESA);
|
||||
_glfw.glx.SwapIntervalMESA(interval);
|
||||
}
|
||||
else if (_glfw.glx.SGI_swap_control)
|
||||
{
|
||||
fprintf (stderr, "swapping with glXSwapIntervalSGI\n");
|
||||
if (interval > 0)
|
||||
_glfw.glx.SwapIntervalSGI(interval);
|
||||
}
|
||||
|
@ -259,6 +253,9 @@ GLFWbool _glfwInitGLX(void)
|
|||
NULL
|
||||
};
|
||||
|
||||
if (_glfw.glx.handle)
|
||||
return GLFW_TRUE;
|
||||
|
||||
for (i = 0; sonames[i]; i++)
|
||||
{
|
||||
_glfw.glx.handle = dlopen(sonames[i], RTLD_LAZY | RTLD_GLOBAL);
|
||||
|
@ -303,6 +300,27 @@ GLFWbool _glfwInitGLX(void)
|
|||
_glfw.glx.GetVisualFromFBConfig =
|
||||
dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig");
|
||||
|
||||
if (!_glfw.glx.GetFBConfigs ||
|
||||
!_glfw.glx.GetFBConfigAttrib ||
|
||||
!_glfw.glx.GetClientString ||
|
||||
!_glfw.glx.QueryExtension ||
|
||||
!_glfw.glx.QueryVersion ||
|
||||
!_glfw.glx.DestroyContext ||
|
||||
!_glfw.glx.MakeCurrent ||
|
||||
!_glfw.glx.SwapBuffers ||
|
||||
!_glfw.glx.QueryExtensionsString ||
|
||||
!_glfw.glx.CreateNewContext ||
|
||||
!_glfw.glx.CreateWindow ||
|
||||
!_glfw.glx.DestroyWindow ||
|
||||
!_glfw.glx.GetProcAddress ||
|
||||
!_glfw.glx.GetProcAddressARB ||
|
||||
!_glfw.glx.GetVisualFromFBConfig)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"GLX: Failed to load required entry points");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!glXQueryExtension(_glfw.x11.display,
|
||||
&_glfw.glx.errorBase,
|
||||
&_glfw.glx.eventBase))
|
||||
|
@ -330,8 +348,6 @@ GLFWbool _glfwInitGLX(void)
|
|||
_glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)
|
||||
getProcAddressGLX("glXSwapIntervalEXT");
|
||||
|
||||
fprintf (stderr, "using glXSwapIntervalEXT\n");
|
||||
|
||||
if (_glfw.glx.SwapIntervalEXT)
|
||||
_glfw.glx.EXT_swap_control = GLFW_TRUE;
|
||||
}
|
||||
|
@ -341,9 +357,6 @@ GLFWbool _glfwInitGLX(void)
|
|||
_glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)
|
||||
getProcAddressGLX("glXSwapIntervalSGI");
|
||||
|
||||
fprintf (stderr, "using glXSwapIntervalSGI\n");
|
||||
|
||||
|
||||
if (_glfw.glx.SwapIntervalSGI)
|
||||
_glfw.glx.SGI_swap_control = GLFW_TRUE;
|
||||
}
|
||||
|
@ -353,8 +366,6 @@ GLFWbool _glfwInitGLX(void)
|
|||
_glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)
|
||||
getProcAddressGLX("glXSwapIntervalMESA");
|
||||
|
||||
fprintf (stderr, "using glXSwapIntervalMESA\n");
|
||||
|
||||
if (_glfw.glx.SwapIntervalMESA)
|
||||
_glfw.glx.MESA_swap_control = GLFW_TRUE;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ typedef void (*PFNGLXSWAPBUFFERSPROC)(Display*,GLXDrawable);
|
|||
typedef const char* (*PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display*,int);
|
||||
typedef GLXFBConfig* (*PFNGLXGETFBCONFIGSPROC)(Display*,int,int*);
|
||||
typedef GLXContext (*PFNGLXCREATENEWCONTEXTPROC)(Display*,GLXFBConfig,int,GLXContext,Bool);
|
||||
typedef __GLXextproc (* PFNGLXGETPROCADDRESSPROC) (const GLubyte *procName);
|
||||
typedef __GLXextproc (* PFNGLXGETPROCADDRESSPROC)(const GLubyte *procName);
|
||||
typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int);
|
||||
typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int);
|
||||
typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*,GLXDrawable,int);
|
||||
|
|
|
@ -65,9 +65,9 @@ static const char* getErrorString(int error)
|
|||
case GLFW_OUT_OF_MEMORY:
|
||||
return "Out of memory";
|
||||
case GLFW_API_UNAVAILABLE:
|
||||
return "The requested client API is unavailable";
|
||||
return "The requested API is unavailable";
|
||||
case GLFW_VERSION_UNAVAILABLE:
|
||||
return "The requested client API version is unavailable";
|
||||
return "The requested API version is unavailable";
|
||||
case GLFW_PLATFORM_ERROR:
|
||||
return "A platform-specific error occurred";
|
||||
case GLFW_FORMAT_UNAVAILABLE:
|
||||
|
@ -130,8 +130,6 @@ GLFWAPI int glfwInit(void)
|
|||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfwInitVulkan();
|
||||
|
||||
_glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
|
||||
_glfwInitialized = GLFW_TRUE;
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
defined(GLFW_INCLUDE_NONE) || \
|
||||
defined(GLFW_INCLUDE_GLEXT) || \
|
||||
defined(GLFW_INCLUDE_GLU) || \
|
||||
defined(GLFW_INCLUDE_VULKAN) || \
|
||||
defined(GLFW_DLL)
|
||||
#error "You must not define any header option macros when compiling GLFW"
|
||||
#endif
|
||||
|
@ -149,11 +150,16 @@ typedef struct VkExtensionProperties
|
|||
} VkExtensionProperties;
|
||||
|
||||
typedef void (APIENTRY * PFN_vkVoidFunction)(void);
|
||||
typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*);
|
||||
typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*);
|
||||
|
||||
#define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties
|
||||
#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
|
||||
#if defined(_GLFW_VULKAN_STATIC)
|
||||
PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance,const char*);
|
||||
VkResult vkEnumerateInstanceExtensionProperties(const char*,uint32_t*,VkExtensionProperties*);
|
||||
#else
|
||||
typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*);
|
||||
typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*);
|
||||
#define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties
|
||||
#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
|
||||
#endif
|
||||
|
||||
#if defined(_GLFW_COCOA)
|
||||
#include "cocoa_platform.h"
|
||||
|
@ -445,8 +451,10 @@ struct _GLFWlibrary
|
|||
void* handle;
|
||||
char** extensions;
|
||||
uint32_t extensionCount;
|
||||
#if !defined(_GLFW_VULKAN_STATIC)
|
||||
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
|
||||
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
|
||||
#endif
|
||||
GLFWbool KHR_surface;
|
||||
GLFWbool KHR_win32_surface;
|
||||
GLFWbool KHR_xlib_surface;
|
||||
|
@ -1034,7 +1042,7 @@ GLFWbool _glfwIsPrintable(int key);
|
|||
|
||||
/*! @ingroup utility
|
||||
*/
|
||||
void _glfwInitVulkan(void);
|
||||
GLFWbool _glfwInitVulkan(void);
|
||||
|
||||
/*! @ingroup utility
|
||||
*/
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
static GLFWbool openJoystickDevice(const char* path)
|
||||
{
|
||||
char axisCount, buttonCount;
|
||||
char name[256];
|
||||
char name[256] = "";
|
||||
int joy, fd, version;
|
||||
_GLFWjoystickLinux* js;
|
||||
|
||||
|
@ -153,7 +153,7 @@ static GLFWbool pollJoystickEvents(_GLFWjoystickLinux* js)
|
|||
return js->present;
|
||||
}
|
||||
|
||||
// Lexically compare joysticks, used by quicksort
|
||||
// Lexically compare joysticks by name; used by qsort
|
||||
//
|
||||
#if defined(__linux__)
|
||||
static int compareJoysticks(const void* fp, const void* sp)
|
||||
|
|
|
@ -183,9 +183,6 @@ int _glfwPlatformInit(void)
|
|||
if (!_glfwInitThreadLocalStoragePOSIX())
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!_glfwInitEGL())
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!_glfwInitJoysticksLinux())
|
||||
return GLFW_FALSE;
|
||||
|
||||
|
|
|
@ -379,6 +379,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
if (!_glfwInitEGL())
|
||||
return GLFW_FALSE;
|
||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
@ -394,7 +396,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||
window->mir.surface = NULL;
|
||||
}
|
||||
|
||||
if (window->context.client != GLFW_NO_API)
|
||||
if (window->context.destroy)
|
||||
window->context.destroy(window);
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,9 @@ static void destroyContextNSGL(_GLFWwindow* window)
|
|||
//
|
||||
GLFWbool _glfwInitNSGL(void)
|
||||
{
|
||||
if (_glfw.nsgl.framework)
|
||||
return GLFW_TRUE;
|
||||
|
||||
_glfw.nsgl.framework =
|
||||
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
|
||||
if (_glfw.nsgl.framework == NULL)
|
||||
|
|
|
@ -36,20 +36,25 @@
|
|||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwInitVulkan(void)
|
||||
GLFWbool _glfwInitVulkan(void)
|
||||
{
|
||||
VkResult err;
|
||||
VkExtensionProperties* ep;
|
||||
uint32_t i, count;
|
||||
|
||||
#if !defined(_GLFW_VULKAN_STATIC)
|
||||
#if defined(_GLFW_WIN32)
|
||||
const char* name = "vulkan-1.dll";
|
||||
#else
|
||||
const char* name = "libvulkan.so.1";
|
||||
#endif
|
||||
|
||||
if (_glfw.vk.available)
|
||||
return GLFW_TRUE;
|
||||
|
||||
_glfw.vk.handle = _glfw_dlopen(name);
|
||||
if (!_glfw.vk.handle)
|
||||
return;
|
||||
return GLFW_FALSE;
|
||||
|
||||
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
|
||||
_glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
|
||||
|
@ -57,7 +62,9 @@ void _glfwInitVulkan(void)
|
|||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"Vulkan: Loader does not export vkGetInstanceProcAddr");
|
||||
return;
|
||||
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
|
||||
|
@ -66,8 +73,11 @@ void _glfwInitVulkan(void)
|
|||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
|
||||
return;
|
||||
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
#endif // _GLFW_VULKAN_STATIC
|
||||
|
||||
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
|
||||
if (err)
|
||||
|
@ -75,7 +85,9 @@ void _glfwInitVulkan(void)
|
|||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Vulkan: Failed to query instance extension count: %s",
|
||||
_glfwGetVulkanResultString(err));
|
||||
return;
|
||||
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
ep = calloc(count, sizeof(VkExtensionProperties));
|
||||
|
@ -88,7 +100,8 @@ void _glfwInitVulkan(void)
|
|||
_glfwGetVulkanResultString(err));
|
||||
|
||||
free(ep);
|
||||
return;
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
|
@ -111,11 +124,13 @@ void _glfwInitVulkan(void)
|
|||
|
||||
_glfw.vk.available = GLFW_TRUE;
|
||||
|
||||
if (!_glfw.vk.KHR_surface)
|
||||
return;
|
||||
|
||||
if (_glfw.vk.KHR_surface)
|
||||
{
|
||||
_glfw.vk.extensions =
|
||||
_glfwPlatformGetRequiredInstanceExtensions(&_glfw.vk.extensionCount);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwTerminateVulkan(void)
|
||||
|
@ -193,7 +208,7 @@ const char* _glfwGetVulkanResultString(VkResult result)
|
|||
GLFWAPI int glfwVulkanSupported(void)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
return _glfw.vk.available;
|
||||
return _glfwInitVulkan();
|
||||
}
|
||||
|
||||
GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
|
||||
|
@ -202,9 +217,9 @@ GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
|
|||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (!_glfw.vk.available)
|
||||
if (!_glfwInitVulkan())
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -219,9 +234,9 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
|
|||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (!_glfw.vk.available)
|
||||
if (!_glfwInitVulkan())
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -238,9 +253,9 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
|
|||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
|
||||
if (!_glfw.vk.available)
|
||||
if (!_glfwInitVulkan())
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
|
@ -263,15 +278,15 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
|
|||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
assert(surface != NULL);
|
||||
|
||||
*surface = VK_NULL_HANDLE;
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED);
|
||||
|
||||
if (!_glfw.vk.available)
|
||||
if (!_glfwInitVulkan())
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available");
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,13 +55,11 @@ static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib
|
|||
|
||||
// Return a list of available and usable framebuffer configs
|
||||
//
|
||||
static GLFWbool choosePixelFormat(_GLFWwindow* window,
|
||||
const _GLFWfbconfig* desired,
|
||||
int* result)
|
||||
static int choosePixelFormat(_GLFWwindow* window, const _GLFWfbconfig* desired)
|
||||
{
|
||||
_GLFWfbconfig* usableConfigs;
|
||||
const _GLFWfbconfig* closest;
|
||||
int i, nativeCount, usableCount;
|
||||
int i, pixelFormat, nativeCount, usableCount;
|
||||
|
||||
if (_glfw.wgl.ARB_pixel_format)
|
||||
{
|
||||
|
@ -197,7 +195,7 @@ static GLFWbool choosePixelFormat(_GLFWwindow* window,
|
|||
"WGL: The driver does not appear to support OpenGL");
|
||||
|
||||
free(usableConfigs);
|
||||
return GLFW_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
|
||||
|
@ -207,13 +205,13 @@ static GLFWbool choosePixelFormat(_GLFWwindow* window,
|
|||
"WGL: Failed to find a suitable pixel format");
|
||||
|
||||
free(usableConfigs);
|
||||
return GLFW_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*result = (int) closest->handle;
|
||||
pixelFormat = (int) closest->handle;
|
||||
free(usableConfigs);
|
||||
|
||||
return GLFW_TRUE;
|
||||
return pixelFormat;
|
||||
}
|
||||
|
||||
// Returns whether desktop compositing is enabled
|
||||
|
@ -288,8 +286,6 @@ static int extensionSupportedWGL(const char* extension)
|
|||
{
|
||||
const char* extensions;
|
||||
|
||||
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
|
||||
|
||||
if (_glfw.wgl.GetExtensionsStringEXT)
|
||||
{
|
||||
extensions = _glfw.wgl.GetExtensionsStringEXT();
|
||||
|
@ -302,7 +298,7 @@ static int extensionSupportedWGL(const char* extension)
|
|||
|
||||
if (_glfw.wgl.GetExtensionsStringARB)
|
||||
{
|
||||
extensions = _glfw.wgl.GetExtensionsStringARB(window->context.wgl.dc);
|
||||
extensions = _glfw.wgl.GetExtensionsStringARB(wglGetCurrentDC());
|
||||
if (extensions)
|
||||
{
|
||||
if (_glfwStringInExtensionString(extension, extensions))
|
||||
|
@ -335,29 +331,65 @@ static void destroyContextWGL(_GLFWwindow* window)
|
|||
|
||||
// Initialize WGL-specific extensions
|
||||
//
|
||||
static void loadExtensions(void)
|
||||
static void loadWGLExtensions(void)
|
||||
{
|
||||
// Functions for WGL_EXT_extension_string
|
||||
// NOTE: These are needed by extensionSupported
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
HGLRC rc;
|
||||
HDC dc = GetDC(_glfw.win32.helperWindowHandle);;
|
||||
|
||||
_glfw.wgl.extensionsLoaded = GLFW_TRUE;
|
||||
|
||||
// NOTE: A dummy context has to be created for opengl32.dll to load the
|
||||
// OpenGL ICD, from which we can then query WGL extensions
|
||||
// NOTE: This code will accept the Microsoft GDI ICD; accelerated context
|
||||
// creation failure occurs during manual pixel format enumeration
|
||||
|
||||
ZeroMemory(&pfd, sizeof(pfd));
|
||||
pfd.nSize = sizeof(pfd);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = 24;
|
||||
|
||||
if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to set pixel format for dummy context");
|
||||
return;
|
||||
}
|
||||
|
||||
rc = wglCreateContext(dc);
|
||||
if (!rc)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to create dummy context");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wglMakeCurrent(dc, rc))
|
||||
{
|
||||
wglDeleteContext(rc);
|
||||
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to make dummy context current");
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: Functions must be loaded first as they're needed to retrieve the
|
||||
// extension string that tells us whether the functions are supported
|
||||
_glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
|
||||
wglGetProcAddress("wglGetExtensionsStringEXT");
|
||||
_glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
|
||||
wglGetProcAddress("wglGetExtensionsStringARB");
|
||||
|
||||
// Functions for WGL_ARB_create_context
|
||||
_glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
|
||||
wglGetProcAddress("wglCreateContextAttribsARB");
|
||||
|
||||
// Functions for WGL_EXT_swap_control
|
||||
_glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
|
||||
wglGetProcAddress("wglSwapIntervalEXT");
|
||||
|
||||
// Functions for WGL_ARB_pixel_format
|
||||
_glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
|
||||
wglGetProcAddress("wglGetPixelFormatAttribivARB");
|
||||
|
||||
// This needs to include every extension used below except for
|
||||
// WGL_ARB_extensions_string and WGL_EXT_extensions_string
|
||||
// NOTE: WGL_ARB_extensions_string and WGL_EXT_extensions_string are not
|
||||
// checked below as we are already using them
|
||||
_glfw.wgl.ARB_multisample =
|
||||
extensionSupportedWGL("WGL_ARB_multisample");
|
||||
_glfw.wgl.ARB_framebuffer_sRGB =
|
||||
|
@ -379,7 +411,8 @@ static void loadExtensions(void)
|
|||
_glfw.wgl.ARB_context_flush_control =
|
||||
extensionSupportedWGL("WGL_ARB_context_flush_control");
|
||||
|
||||
_glfw.wgl.extensionsLoaded = GLFW_TRUE;
|
||||
wglMakeCurrent(dc, NULL);
|
||||
wglDeleteContext(rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -391,6 +424,9 @@ static void loadExtensions(void)
|
|||
//
|
||||
GLFWbool _glfwInitWGL(void)
|
||||
{
|
||||
if (_glfw.wgl.instance)
|
||||
return GLFW_TRUE;
|
||||
|
||||
_glfw.wgl.instance = LoadLibraryA("opengl32.dll");
|
||||
if (!_glfw.wgl.instance)
|
||||
{
|
||||
|
@ -404,6 +440,8 @@ GLFWbool _glfwInitWGL(void)
|
|||
GetProcAddress(_glfw.wgl.instance, "wglDeleteContext");
|
||||
_glfw.wgl.GetProcAddress = (WGLGETPROCADDRESS_T)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress");
|
||||
_glfw.wgl.GetCurrentDC = (WGLGETCURRENTDC_T)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC");
|
||||
_glfw.wgl.MakeCurrent = (WGLMAKECURRENT_T)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent");
|
||||
_glfw.wgl.ShareLists = (WGLSHARELISTS_T)
|
||||
|
@ -434,12 +472,12 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
int attribs[40];
|
||||
int pixelFormat = 0;
|
||||
int pixelFormat;
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
HGLRC share = NULL;
|
||||
|
||||
if (ctxconfig->client == GLFW_NO_API)
|
||||
return GLFW_TRUE;
|
||||
if (!_glfw.wgl.extensionsLoaded)
|
||||
loadWGLExtensions();
|
||||
|
||||
if (ctxconfig->share)
|
||||
share = ctxconfig->share->context.wgl.handle;
|
||||
|
@ -452,7 +490,8 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!choosePixelFormat(window, fbconfig, &pixelFormat))
|
||||
pixelFormat = choosePixelFormat(window, fbconfig);
|
||||
if (!pixelFormat)
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!DescribePixelFormat(window->context.wgl.dc,
|
||||
|
@ -470,6 +509,40 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
if (ctxconfig->forward)
|
||||
{
|
||||
if (!_glfw.wgl.ARB_create_context)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctxconfig->profile)
|
||||
{
|
||||
if (!_glfw.wgl.ARB_create_context_profile)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_glfw.wgl.ARB_create_context ||
|
||||
!_glfw.wgl.ARB_create_context_profile ||
|
||||
!_glfw.wgl.EXT_create_context_es2_profile)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (_glfw.wgl.ARB_create_context)
|
||||
{
|
||||
int index = 0, mask = 0, flags = 0;
|
||||
|
@ -549,9 +622,45 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||
_glfw.wgl.CreateContextAttribsARB(window->context.wgl.dc,
|
||||
share, attribs);
|
||||
if (!window->context.wgl.handle)
|
||||
{
|
||||
const DWORD error = GetLastError();
|
||||
|
||||
if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB))
|
||||
{
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Driver does not support OpenGL version %i.%i",
|
||||
ctxconfig->major,
|
||||
ctxconfig->minor);
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Driver does not support OpenGL ES version %i.%i",
|
||||
ctxconfig->major,
|
||||
ctxconfig->minor);
|
||||
}
|
||||
}
|
||||
else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB))
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Driver does not support the requested OpenGL profile");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Failed to create OpenGL context");
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Failed to create OpenGL ES context");
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -588,102 +697,6 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||
|
||||
#undef setWGLattrib
|
||||
|
||||
// Analyzes the specified context for possible recreation
|
||||
//
|
||||
int _glfwAnalyzeContextWGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
GLFWbool required = GLFW_FALSE;
|
||||
|
||||
if (_glfw.wgl.extensionsLoaded)
|
||||
return _GLFW_RECREATION_NOT_NEEDED;
|
||||
|
||||
makeContextCurrentWGL(window);
|
||||
loadExtensions();
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
if (ctxconfig->forward)
|
||||
{
|
||||
if (!_glfw.wgl.ARB_create_context)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable");
|
||||
return _GLFW_RECREATION_IMPOSSIBLE;
|
||||
}
|
||||
|
||||
required = GLFW_TRUE;
|
||||
}
|
||||
|
||||
if (ctxconfig->profile)
|
||||
{
|
||||
if (!_glfw.wgl.ARB_create_context_profile)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
|
||||
return _GLFW_RECREATION_IMPOSSIBLE;
|
||||
}
|
||||
|
||||
required = GLFW_TRUE;
|
||||
}
|
||||
|
||||
if (ctxconfig->release)
|
||||
{
|
||||
if (_glfw.wgl.ARB_context_flush_control)
|
||||
required = GLFW_TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_glfw.wgl.ARB_create_context ||
|
||||
!_glfw.wgl.ARB_create_context_profile ||
|
||||
!_glfw.wgl.EXT_create_context_es2_profile)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable");
|
||||
return _GLFW_RECREATION_IMPOSSIBLE;
|
||||
}
|
||||
|
||||
required = GLFW_TRUE;
|
||||
}
|
||||
|
||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||
{
|
||||
if (_glfw.wgl.ARB_create_context)
|
||||
required = GLFW_TRUE;
|
||||
}
|
||||
|
||||
if (ctxconfig->debug)
|
||||
{
|
||||
if (_glfw.wgl.ARB_create_context)
|
||||
required = GLFW_TRUE;
|
||||
}
|
||||
|
||||
if (fbconfig->samples > 0)
|
||||
{
|
||||
// MSAA is not a hard constraint, so do nothing if it's not supported
|
||||
if (_glfw.wgl.ARB_multisample && _glfw.wgl.ARB_pixel_format)
|
||||
required = GLFW_TRUE;
|
||||
}
|
||||
|
||||
if (fbconfig->sRGB)
|
||||
{
|
||||
// sRGB is not a hard constraint, so do nothing if it's not supported
|
||||
if ((_glfw.wgl.ARB_framebuffer_sRGB ||
|
||||
_glfw.wgl.EXT_framebuffer_sRGB) &&
|
||||
_glfw.wgl.ARB_pixel_format)
|
||||
{
|
||||
required = GLFW_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (required)
|
||||
return _GLFW_RECREATION_REQUIRED;
|
||||
|
||||
return _GLFW_RECREATION_NOT_NEEDED;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
|
|
|
@ -73,6 +73,9 @@
|
|||
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
|
||||
#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
|
||||
|
||||
#define ERROR_INVALID_VERSION_ARB 0x2095
|
||||
#define ERROR_INVALID_PROFILE_ARB 0x2096
|
||||
|
||||
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int);
|
||||
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*);
|
||||
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void);
|
||||
|
@ -82,6 +85,7 @@ typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC,HGLRC,const int*)
|
|||
typedef HGLRC (WINAPI * WGLCREATECONTEXT_T)(HDC);
|
||||
typedef BOOL (WINAPI * WGLDELETECONTEXT_T)(HGLRC);
|
||||
typedef PROC (WINAPI * WGLGETPROCADDRESS_T)(LPCSTR);
|
||||
typedef HDC (WINAPI * WGLGETCURRENTDC_T)(void);
|
||||
typedef BOOL (WINAPI * WGLMAKECURRENT_T)(HDC,HGLRC);
|
||||
typedef BOOL (WINAPI * WGLSHARELISTS_T)(HGLRC,HGLRC);
|
||||
|
||||
|
@ -89,6 +93,7 @@ typedef BOOL (WINAPI * WGLSHARELISTS_T)(HGLRC,HGLRC);
|
|||
#define wglCreateContext _glfw.wgl.CreateContext
|
||||
#define wglDeleteContext _glfw.wgl.DeleteContext
|
||||
#define wglGetProcAddress _glfw.wgl.GetProcAddress
|
||||
#define wglGetCurrentDC _glfw.wgl.GetCurrentDC
|
||||
#define wglMakeCurrent _glfw.wgl.MakeCurrent
|
||||
#define wglShareLists _glfw.wgl.ShareLists
|
||||
|
||||
|
@ -118,6 +123,7 @@ typedef struct _GLFWlibraryWGL
|
|||
WGLCREATECONTEXT_T CreateContext;
|
||||
WGLDELETECONTEXT_T DeleteContext;
|
||||
WGLGETPROCADDRESS_T GetProcAddress;
|
||||
WGLGETCURRENTDC_T GetCurrentDC;
|
||||
WGLMAKECURRENT_T MakeCurrent;
|
||||
WGLSHARELISTS_T ShareLists;
|
||||
|
||||
|
@ -147,8 +153,5 @@ void _glfwTerminateWGL(void);
|
|||
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
int _glfwAnalyzeContextWGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
|
||||
#endif // _glfw3_wgl_context_h_
|
||||
|
|
|
@ -319,6 +319,10 @@ static HWND createHelperWindow(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// HACK: The first call to ShowWindow is ignored if the parent process
|
||||
// passed along a STARTUPINFO, so clear that flag with a no-op call
|
||||
ShowWindow(window, SW_HIDE);
|
||||
|
||||
// Register for HID device notifications
|
||||
{
|
||||
DEV_BROADCAST_DEVICEINTERFACE_W dbi;
|
||||
|
@ -373,7 +377,7 @@ char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
|
|||
if (!length)
|
||||
return NULL;
|
||||
|
||||
target = calloc(length, sizeof(char));
|
||||
target = calloc(length, 1);
|
||||
|
||||
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, length, NULL, NULL))
|
||||
{
|
||||
|
@ -421,10 +425,6 @@ int _glfwPlatformInit(void)
|
|||
|
||||
_glfwPlatformPollEvents();
|
||||
|
||||
if (!_glfwInitWGL())
|
||||
return GLFW_FALSE;
|
||||
|
||||
_glfwInitEGL();
|
||||
_glfwInitTimerWin32();
|
||||
_glfwInitJoysticksWin32();
|
||||
|
||||
|
|
|
@ -176,7 +176,7 @@ static int compareJoystickObjects(const void* first, const void* second)
|
|||
//
|
||||
static GLFWbool supportsXInput(const GUID* guid)
|
||||
{
|
||||
UINT i, count;
|
||||
UINT i, count = 0;
|
||||
RAWINPUTDEVICELIST* ridl;
|
||||
GLFWbool result = GLFW_FALSE;
|
||||
|
||||
|
@ -185,7 +185,7 @@ static GLFWbool supportsXInput(const GUID* guid)
|
|||
|
||||
ridl = calloc(count, sizeof(RAWINPUTDEVICELIST));
|
||||
|
||||
if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == -1)
|
||||
if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1)
|
||||
{
|
||||
free(ridl);
|
||||
return GLFW_FALSE;
|
||||
|
@ -211,7 +211,7 @@ static GLFWbool supportsXInput(const GUID* guid)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != guid->Data1)
|
||||
if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != (LONG) guid->Data1)
|
||||
continue;
|
||||
|
||||
memset(name, 0, sizeof(name));
|
||||
|
|
|
@ -850,9 +850,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
// Creates the GLFW window and rendering context
|
||||
// Creates the GLFW window
|
||||
//
|
||||
static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig)
|
||||
static int createNativeWindow(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig)
|
||||
{
|
||||
int xpos, ypos, fullWidth, fullHeight;
|
||||
WCHAR* wideTitle;
|
||||
|
@ -928,21 +929,6 @@ static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig)
|
|||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Destroys the GLFW window and rendering context
|
||||
//
|
||||
static void destroyWindow(_GLFWwindow* window)
|
||||
{
|
||||
if (_glfw.win32.disabledCursorWindow == window)
|
||||
_glfw.win32.disabledCursorWindow = NULL;
|
||||
|
||||
if (window->win32.handle)
|
||||
{
|
||||
RemovePropW(window->win32.handle, L"GLFW");
|
||||
DestroyWindow(window->win32.handle);
|
||||
window->win32.handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
|
@ -1001,60 +987,22 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (!createWindow(window, wndconfig))
|
||||
if (!createNativeWindow(window, wndconfig))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
|
||||
status = _glfwAnalyzeContextWGL(window, ctxconfig, fbconfig);
|
||||
|
||||
if (status == _GLFW_RECREATION_IMPOSSIBLE)
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (status == _GLFW_RECREATION_REQUIRED)
|
||||
{
|
||||
// Some window hints require us to re-create the context using WGL
|
||||
// extensions retrieved through the current context, as we cannot
|
||||
// check for WGL extensions or retrieve WGL entry points before we
|
||||
// have a current context (actually until we have implicitly loaded
|
||||
// the vendor ICD)
|
||||
|
||||
// Yes, this is strange, and yes, this is the proper way on WGL
|
||||
|
||||
// As Windows only allows you to set the pixel format once for
|
||||
// a window, we need to destroy the current window and create a new
|
||||
// one to be able to use the new pixel format
|
||||
|
||||
// Technically, it may be possible to keep the old window around if
|
||||
// we're just creating an OpenGL 3.0+ context with the same pixel
|
||||
// format, but it's not worth the added code complexity
|
||||
|
||||
// First we clear the current context (the one we just created)
|
||||
// This is usually done by glfwDestroyWindow, but as we're not doing
|
||||
// full GLFW window destruction, it's duplicated here
|
||||
window->context.makeCurrent(NULL);
|
||||
|
||||
// Next destroy the Win32 window and WGL context (without resetting
|
||||
// or destroying the GLFW window object)
|
||||
window->context.destroy(window);
|
||||
destroyWindow(window);
|
||||
|
||||
// ...and then create them again, this time with better APIs
|
||||
if (!createWindow(window, wndconfig))
|
||||
if (!_glfwInitWGL())
|
||||
return GLFW_FALSE;
|
||||
if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_glfwInitEGL())
|
||||
return GLFW_FALSE;
|
||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
@ -1078,10 +1026,18 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||
if (window->monitor)
|
||||
releaseMonitor(window);
|
||||
|
||||
if (window->context.client != GLFW_NO_API)
|
||||
if (window->context.destroy)
|
||||
window->context.destroy(window);
|
||||
|
||||
destroyWindow(window);
|
||||
if (_glfw.win32.disabledCursorWindow == window)
|
||||
_glfw.win32.disabledCursorWindow = NULL;
|
||||
|
||||
if (window->win32.handle)
|
||||
{
|
||||
RemovePropW(window->win32.handle, L"GLFW");
|
||||
DestroyWindow(window->win32.handle);
|
||||
window->win32.handle = NULL;
|
||||
}
|
||||
|
||||
if (window->win32.bigIcon)
|
||||
DestroyIcon(window->win32.bigIcon);
|
||||
|
@ -1594,52 +1550,55 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
|||
|
||||
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
|
||||
{
|
||||
WCHAR* wideString;
|
||||
HANDLE stringHandle;
|
||||
size_t wideSize;
|
||||
int characterCount;
|
||||
HANDLE object;
|
||||
WCHAR* buffer;
|
||||
|
||||
wideString = _glfwCreateWideStringFromUTF8Win32(string);
|
||||
if (!wideString)
|
||||
characterCount = MultiByteToWideChar(CP_UTF8, 0, string, -1, NULL, 0);
|
||||
if (!characterCount)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to convert string to UTF-16");
|
||||
"Win32: Failed to convert clipboard string to UTF-16");
|
||||
return;
|
||||
}
|
||||
|
||||
wideSize = (wcslen(wideString) + 1) * sizeof(WCHAR);
|
||||
|
||||
stringHandle = GlobalAlloc(GMEM_MOVEABLE, wideSize);
|
||||
if (!stringHandle)
|
||||
object = GlobalAlloc(GMEM_MOVEABLE, characterCount * sizeof(WCHAR));
|
||||
if (!object)
|
||||
{
|
||||
free(wideString);
|
||||
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to allocate global handle for clipboard");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(GlobalLock(stringHandle), wideString, wideSize);
|
||||
GlobalUnlock(stringHandle);
|
||||
buffer = GlobalLock(object);
|
||||
if (!buffer)
|
||||
{
|
||||
GlobalFree(object);
|
||||
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to lock global handle");
|
||||
return;
|
||||
}
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, 0, string, -1, buffer, characterCount);
|
||||
GlobalUnlock(object);
|
||||
|
||||
if (!OpenClipboard(_glfw.win32.helperWindowHandle))
|
||||
{
|
||||
GlobalFree(stringHandle);
|
||||
free(wideString);
|
||||
GlobalFree(object);
|
||||
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard");
|
||||
return;
|
||||
}
|
||||
|
||||
EmptyClipboard();
|
||||
SetClipboardData(CF_UNICODETEXT, stringHandle);
|
||||
SetClipboardData(CF_UNICODETEXT, object);
|
||||
CloseClipboard();
|
||||
|
||||
free(wideString);
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
||||
{
|
||||
HANDLE stringHandle;
|
||||
HANDLE object;
|
||||
WCHAR* buffer;
|
||||
|
||||
if (!OpenClipboard(_glfw.win32.helperWindowHandle))
|
||||
{
|
||||
|
@ -1647,8 +1606,8 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
stringHandle = GetClipboardData(CF_UNICODETEXT);
|
||||
if (!stringHandle)
|
||||
object = GetClipboardData(CF_UNICODETEXT);
|
||||
if (!object)
|
||||
{
|
||||
CloseClipboard();
|
||||
|
||||
|
@ -1657,11 +1616,20 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
buffer = GlobalLock(object);
|
||||
if (!buffer)
|
||||
{
|
||||
CloseClipboard();
|
||||
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to lock global handle");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(_glfw.win32.clipboardString);
|
||||
_glfw.win32.clipboardString =
|
||||
_glfwCreateUTF8FromWideStringWin32(GlobalLock(stringHandle));
|
||||
_glfwCreateUTF8FromWideStringWin32(buffer);
|
||||
|
||||
GlobalUnlock(stringHandle);
|
||||
GlobalUnlock(object);
|
||||
CloseClipboard();
|
||||
|
||||
if (!_glfw.win32.clipboardString)
|
||||
|
|
|
@ -151,7 +151,8 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
|||
|
||||
if (ctxconfig.share)
|
||||
{
|
||||
if (ctxconfig.share->context.client == GLFW_NO_API)
|
||||
if (ctxconfig.client == GLFW_NO_API ||
|
||||
ctxconfig.share->context.client == GLFW_NO_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return NULL;
|
||||
|
@ -627,6 +628,8 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* handle)
|
|||
GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
_glfwPlatformMaximizeWindow(window);
|
||||
}
|
||||
|
|
|
@ -600,9 +600,6 @@ int _glfwPlatformInit(void)
|
|||
if (!_glfwInitThreadLocalStoragePOSIX())
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!_glfwInitEGL())
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!_glfwInitJoysticksLinux())
|
||||
return GLFW_FALSE;
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
|
|||
struct wl_output *output;
|
||||
char name_str[80];
|
||||
|
||||
memset(name_str, 0, 80 * sizeof(char));
|
||||
memset(name_str, 0, sizeof(name_str));
|
||||
snprintf(name_str, 79, "wl_output@%u", name);
|
||||
|
||||
if (version < 2)
|
||||
|
|
|
@ -393,6 +393,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
if (!_glfwInitEGL())
|
||||
return GLFW_FALSE;
|
||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
@ -435,7 +437,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||
}
|
||||
|
||||
if (window->context.client != GLFW_NO_API)
|
||||
if (window->context.destroy)
|
||||
window->context.destroy(window);
|
||||
|
||||
if (window->wl.native)
|
||||
|
|
|
@ -72,9 +72,8 @@ static int translateKeyCode(int scancode)
|
|||
default: break;
|
||||
}
|
||||
|
||||
// Now try primary keysym for function keys (non-printable keys). These
|
||||
// should not be layout dependent (i.e. US layout and international
|
||||
// layouts should give the same result).
|
||||
// Now try primary keysym for function keys (non-printable keys)
|
||||
// These should not depend on the current keyboard layout
|
||||
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0);
|
||||
}
|
||||
else
|
||||
|
@ -766,13 +765,9 @@ int _glfwPlatformInit(void)
|
|||
if (!_glfwInitThreadLocalStoragePOSIX())
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!_glfwInitGLX())
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!_glfwInitJoysticksLinux())
|
||||
return GLFW_FALSE;
|
||||
|
||||
_glfwInitEGL();
|
||||
_glfwInitTimerPOSIX();
|
||||
|
||||
return GLFW_TRUE;
|
||||
|
|
|
@ -123,10 +123,8 @@ typedef struct _GLFWwindowX11
|
|||
int warpCursorPosX, warpCursorPosY;
|
||||
|
||||
// The information from the last KeyPress event
|
||||
struct {
|
||||
unsigned int keycode;
|
||||
Time time;
|
||||
} last;
|
||||
unsigned int lastKeyCode;
|
||||
Time lastKeyTime;
|
||||
|
||||
} _GLFWwindowX11;
|
||||
|
||||
|
|
|
@ -49,15 +49,15 @@
|
|||
#define Button7 7
|
||||
|
||||
|
||||
// Wait for data to arrive
|
||||
// Wait for data to arrive using select
|
||||
// This avoids blocking other threads via the per-display Xlib lock that also
|
||||
// covers GLX functions
|
||||
//
|
||||
void selectDisplayConnection(struct timeval* timeout)
|
||||
static GLFWbool waitForEvent(double* timeout)
|
||||
{
|
||||
fd_set fds;
|
||||
int result, count;
|
||||
const int fd = ConnectionNumber(_glfw.x11.display);
|
||||
|
||||
count = fd + 1;
|
||||
int count = fd + 1;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
|
@ -67,18 +67,49 @@ void selectDisplayConnection(struct timeval* timeout)
|
|||
if (fd < _glfw.linux_js.inotify)
|
||||
count = _glfw.linux_js.inotify + 1;
|
||||
#endif
|
||||
|
||||
// NOTE: We use select instead of an X function like XNextEvent, as the
|
||||
// wait inside those are guarded by the mutex protecting the display
|
||||
// struct, locking out other threads from using X (including GLX)
|
||||
// NOTE: Only retry on EINTR if there is no timeout, as select is not
|
||||
// required to update it for the time elapsed
|
||||
// TODO: Update timeout value manually
|
||||
do
|
||||
for (;;)
|
||||
{
|
||||
result = select(count, &fds, NULL, NULL, timeout);
|
||||
if (timeout)
|
||||
{
|
||||
const long seconds = (long) *timeout;
|
||||
const long microseconds = (long) ((*timeout - seconds) * 1e6);
|
||||
struct timeval tv = { seconds, microseconds };
|
||||
const uint64_t base = _glfwPlatformGetTimerValue();
|
||||
|
||||
const int result = select(count, &fds, NULL, NULL, &tv);
|
||||
const int error = errno;
|
||||
|
||||
*timeout -= (_glfwPlatformGetTimerValue() - base) /
|
||||
(double) _glfwPlatformGetTimerFrequency();
|
||||
|
||||
if (result > 0)
|
||||
return GLFW_TRUE;
|
||||
if ((result == -1 && error == EINTR) || *timeout <= 0.0)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
while (result == -1 && errno == EINTR && timeout == NULL);
|
||||
else if (select(count, &fds, NULL, NULL, NULL) != -1 || errno != EINTR)
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Waits until a VisibilityNotify event arrives for the specified window or the
|
||||
// timeout period elapses (ICCCM section 4.2.2)
|
||||
//
|
||||
static GLFWbool waitForVisibilityNotify(_GLFWwindow* window)
|
||||
{
|
||||
XEvent dummy;
|
||||
double timeout = 0.1;
|
||||
|
||||
while (!XCheckTypedWindowEvent(_glfw.x11.display,
|
||||
window->x11.handle,
|
||||
VisibilityNotify,
|
||||
&dummy))
|
||||
{
|
||||
if (!waitForEvent(&timeout))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Returns whether the window is iconified
|
||||
|
@ -105,6 +136,15 @@ static int getWindowState(_GLFWwindow* window)
|
|||
|
||||
// Returns whether the event is a selection event
|
||||
//
|
||||
static Bool isSelectionEvent(Display* display, XEvent* event, XPointer pointer)
|
||||
{
|
||||
return event->type == SelectionRequest ||
|
||||
event->type == SelectionNotify ||
|
||||
event->type == SelectionClear;
|
||||
}
|
||||
|
||||
// Returns whether it is a _NET_FRAME_EXTENTS event for the specified window
|
||||
//
|
||||
static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointer)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) pointer;
|
||||
|
@ -218,13 +258,17 @@ static void updateNormalHints(_GLFWwindow* window, int width, int height)
|
|||
if (window->resizable)
|
||||
{
|
||||
if (window->minwidth != GLFW_DONT_CARE &&
|
||||
window->minheight != GLFW_DONT_CARE &&
|
||||
window->maxwidth != GLFW_DONT_CARE &&
|
||||
window->maxheight != GLFW_DONT_CARE)
|
||||
window->minheight != GLFW_DONT_CARE)
|
||||
{
|
||||
hints->flags |= (PMinSize | PMaxSize);
|
||||
hints->flags |= PMinSize;
|
||||
hints->min_width = window->minwidth;
|
||||
hints->min_height = window->minheight;
|
||||
}
|
||||
|
||||
if (window->maxwidth != GLFW_DONT_CARE &&
|
||||
window->maxheight != GLFW_DONT_CARE)
|
||||
{
|
||||
hints->flags |= PMaxSize;
|
||||
hints->max_width = window->maxwidth;
|
||||
hints->max_height = window->maxheight;
|
||||
}
|
||||
|
@ -245,6 +289,9 @@ static void updateNormalHints(_GLFWwindow* window, int width, int height)
|
|||
}
|
||||
}
|
||||
|
||||
hints->flags |= PWinGravity;
|
||||
hints->win_gravity = StaticGravity;
|
||||
|
||||
XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);
|
||||
XFree(hints);
|
||||
}
|
||||
|
@ -416,7 +463,7 @@ static void updateCursorImage(_GLFWwindow* window)
|
|||
|
||||
// Create the X11 window (and its colormap)
|
||||
//
|
||||
static GLFWbool createWindow(_GLFWwindow* window,
|
||||
static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
Visual* visual, int depth)
|
||||
{
|
||||
|
@ -608,15 +655,6 @@ static GLFWbool createWindow(_GLFWwindow* window,
|
|||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Returns whether the event is a selection event
|
||||
//
|
||||
static Bool isSelectionEvent(Display* display, XEvent* event, XPointer pointer)
|
||||
{
|
||||
return event->type == SelectionRequest ||
|
||||
event->type == SelectionNotify ||
|
||||
event->type == SelectionClear;
|
||||
}
|
||||
|
||||
// Set the specified property to the selection converted to the requested target
|
||||
//
|
||||
static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
|
||||
|
@ -815,7 +853,7 @@ static void pushSelectionToManager(_GLFWwindow* window)
|
|||
}
|
||||
}
|
||||
|
||||
selectDisplayConnection(NULL);
|
||||
waitForEvent(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -957,15 +995,15 @@ static void processEvent(XEvent *event)
|
|||
// HACK: Ignore duplicate key press events generated by ibus
|
||||
// Corresponding release events are filtered out by the
|
||||
// GLFW key repeat logic
|
||||
if (window->x11.last.keycode != keycode ||
|
||||
window->x11.last.time != event->xkey.time)
|
||||
if (window->x11.lastKeyCode != keycode ||
|
||||
window->x11.lastKeyTime != event->xkey.time)
|
||||
{
|
||||
if (keycode)
|
||||
_glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
|
||||
}
|
||||
|
||||
window->x11.last.keycode = keycode;
|
||||
window->x11.last.time = event->xkey.time;
|
||||
window->x11.lastKeyCode = keycode;
|
||||
window->x11.lastKeyTime = event->xkey.time;
|
||||
|
||||
if (!filtered)
|
||||
{
|
||||
|
@ -1514,17 +1552,21 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||
{
|
||||
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwInitGLX())
|
||||
return GLFW_FALSE;
|
||||
if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_glfwInitEGL())
|
||||
return GLFW_FALSE;
|
||||
if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!createWindow(window, wndconfig, visual, depth))
|
||||
if (!createNativeWindow(window, wndconfig, visual, depth))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
|
@ -1569,7 +1611,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||
window->x11.ic = NULL;
|
||||
}
|
||||
|
||||
if (window->context.client != GLFW_NO_API)
|
||||
if (window->context.destroy)
|
||||
window->context.destroy(window);
|
||||
|
||||
if (window->x11.handle)
|
||||
|
@ -1673,21 +1715,11 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
|||
|
||||
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
||||
{
|
||||
Window child;
|
||||
Window dummy;
|
||||
int x, y;
|
||||
|
||||
XTranslateCoordinates(_glfw.x11.display, window->x11.handle, _glfw.x11.root,
|
||||
0, 0, &x, &y, &child);
|
||||
|
||||
if (child)
|
||||
{
|
||||
int left, top;
|
||||
XTranslateCoordinates(_glfw.x11.display, window->x11.handle, child,
|
||||
0, 0, &left, &top, &child);
|
||||
|
||||
x -= left;
|
||||
y -= top;
|
||||
}
|
||||
0, 0, &x, &y, &dummy);
|
||||
|
||||
if (xpos)
|
||||
*xpos = x;
|
||||
|
@ -1786,19 +1818,16 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
|||
if (!_glfwPlatformWindowVisible(window) &&
|
||||
_glfw.x11.NET_REQUEST_FRAME_EXTENTS)
|
||||
{
|
||||
uint64_t base;
|
||||
XEvent event;
|
||||
double timeout = 0.5;
|
||||
|
||||
// Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to
|
||||
// function before the window is mapped
|
||||
sendEventToWM(window, _glfw.x11.NET_REQUEST_FRAME_EXTENTS,
|
||||
0, 0, 0, 0, 0);
|
||||
|
||||
base = _glfwPlatformGetTimerValue();
|
||||
|
||||
// HACK: Poll with timeout for the required reply instead of blocking
|
||||
// This is done because some window managers (at least Unity,
|
||||
// Fluxbox and Xfwm) failed to send the required reply
|
||||
// HACK: Use a timeout because earlier versions of some window managers
|
||||
// (at least Unity, Fluxbox and Xfwm) failed to send the reply
|
||||
// They have been fixed but broken versions are still in the wild
|
||||
// If you are affected by this and your window manager is NOT
|
||||
// listed above, PLEASE report it to their and our issue trackers
|
||||
|
@ -1807,21 +1836,12 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
|||
isFrameExtentsEvent,
|
||||
(XPointer) window))
|
||||
{
|
||||
double remaining;
|
||||
struct timeval timeout;
|
||||
|
||||
remaining = 0.5 - (_glfwPlatformGetTimerValue() - base) /
|
||||
(double) _glfwPlatformGetTimerFrequency();
|
||||
if (remaining <= 0.0)
|
||||
if (!waitForEvent(&timeout))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: The window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation; please report this issue");
|
||||
return;
|
||||
}
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = (long) (remaining * 1e6);
|
||||
selectDisplayConnection(&timeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1871,8 +1891,11 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
|||
}
|
||||
|
||||
if (_glfwPlatformWindowIconified(window))
|
||||
{
|
||||
XMapWindow(_glfw.x11.display, window->x11.handle);
|
||||
else
|
||||
waitForVisibilityNotify(window);
|
||||
}
|
||||
else if (_glfwPlatformWindowVisible(window))
|
||||
{
|
||||
if (_glfw.x11.NET_WM_STATE &&
|
||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&
|
||||
|
@ -1908,8 +1931,11 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
|||
|
||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||
{
|
||||
if (_glfwPlatformWindowVisible(window))
|
||||
return;
|
||||
|
||||
XMapWindow(_glfw.x11.display, window->x11.handle);
|
||||
XFlush(_glfw.x11.display);
|
||||
waitForVisibilityNotify(window);
|
||||
}
|
||||
|
||||
void _glfwPlatformHideWindow(_GLFWwindow* window)
|
||||
|
@ -1964,6 +1990,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
|||
if (window->monitor)
|
||||
{
|
||||
XMapRaised(_glfw.x11.display, window->x11.handle);
|
||||
if (waitForVisibilityNotify(window))
|
||||
acquireMonitor(window);
|
||||
}
|
||||
else
|
||||
|
@ -2042,28 +2069,17 @@ void _glfwPlatformPollEvents(void)
|
|||
void _glfwPlatformWaitEvents(void)
|
||||
{
|
||||
while (!XPending(_glfw.x11.display))
|
||||
selectDisplayConnection(NULL);
|
||||
waitForEvent(NULL);
|
||||
|
||||
_glfwPlatformPollEvents();
|
||||
}
|
||||
|
||||
void _glfwPlatformWaitEventsTimeout(double timeout)
|
||||
{
|
||||
const double deadline = timeout + _glfwPlatformGetTimerValue() /
|
||||
(double) _glfwPlatformGetTimerFrequency();
|
||||
|
||||
while (!XPending(_glfw.x11.display))
|
||||
{
|
||||
const double remaining = deadline - _glfwPlatformGetTimerValue() /
|
||||
(double) _glfwPlatformGetTimerFrequency();
|
||||
if (remaining <= 0.0)
|
||||
return;
|
||||
|
||||
const long seconds = (long) remaining;
|
||||
const long microseconds = (long) ((remaining - seconds) * 1e6);
|
||||
struct timeval tv = { seconds, microseconds };
|
||||
|
||||
selectDisplayConnection(&tv);
|
||||
if (!waitForEvent(&timeout))
|
||||
break;
|
||||
}
|
||||
|
||||
_glfwPlatformPollEvents();
|
||||
|
@ -2254,10 +2270,8 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
|||
_glfw.x11.GLFW_SELECTION,
|
||||
window->x11.handle, CurrentTime);
|
||||
|
||||
// XCheckTypedEvent is used instead of XIfEvent in order not to lock
|
||||
// other threads out from the display during the entire wait period
|
||||
while (!XCheckTypedEvent(_glfw.x11.display, SelectionNotify, &event))
|
||||
selectDisplayConnection(NULL);
|
||||
waitForEvent(NULL);
|
||||
|
||||
if (event.xselection.property == None)
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue