Updated glfw
parent
48c8cde66b
commit
cf59f6b6ae
|
@ -1,35 +1,118 @@
|
||||||
# Contribution Guide
|
# Contribution Guide
|
||||||
|
|
||||||
This file is a work in progress and you can report errors or submit patches for
|
## Contents
|
||||||
it the same as any other file.
|
|
||||||
|
- [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
|
## Reporting a bug
|
||||||
|
|
||||||
If GLFW is behaving unexpectedly, make sure you have set an error callback.
|
If GLFW is behaving unexpectedly at run-time, start by setting an [error
|
||||||
GLFW will often tell you the cause of an issue via this callback.
|
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
|
If GLFW is crashing or triggering asserts, make sure that all your object
|
||||||
handles and other pointers are valid.
|
handles and other pointers are valid.
|
||||||
|
|
||||||
Always include the __operating system name and version__ (i.e. `Windows
|
For bugs where it makes sense, a [Short, Self Contained, Correct (Compilable),
|
||||||
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW,
|
Example](http://www.sscce.org/) is absolutely invaluable. Just put it inline in
|
||||||
include the __GLFW release version__ (i.e. `3.1.2`), otherwise include the
|
the body text. Note that if the bug is reproducible with one of the test
|
||||||
__GLFW commit ID__ (i.e. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
|
programs that come with GLFW, just mention that instead.
|
||||||
If possible, please also include the __GLFW version string__ (`3.2.0 X11 EGL
|
|
||||||
clock_gettime /dev/js XI Xf86vm`), as described
|
__Don't worry about adding too much information__. Unimportant information can
|
||||||
[here](http://www.glfw.org/docs/latest/intro.html#intro_version_string).
|
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
|
### Reporting a compile or link bug
|
||||||
|
|
||||||
__Note:__ GLFW needs many system APIs to do its job. See the [Building
|
__Note:__ GLFW needs many system APIs to do its job, which on some platforms
|
||||||
applications](http://www.glfw.org/docs/latest/build.html) guide for more
|
means linking to many system libraries. If you are using GLFW as a static
|
||||||
information.
|
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
|
__Note:__ Check the [Compiling
|
||||||
your compiler and linker. Issue posts are editable so it can always be
|
GLFW](http://www.glfw.org/docs/latest/compile.html) guide and or [Building
|
||||||
shortened later.
|
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
|
### 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.
|
GLFW says that your machine lacks support for OpenGL, it very likely does.
|
||||||
Install drivers from the computer manufacturer or graphics card manufacturer
|
Install drivers from the computer manufacturer or graphics card manufacturer
|
||||||
([Nvidia](http://www.geforce.com/drivers),
|
([Nvidia](http://www.geforce.com/drivers),
|
||||||
[AMD](http://support.amd.com/en-us/download),
|
[AMD](http://support.amd.com/en-us/download),
|
||||||
[Intel](https://www-ssl.intel.com/content/www/us/en/support/detect.html)) to
|
[Intel](https://www-ssl.intel.com/content/www/us/en/support/detect.html)) to
|
||||||
fix this.
|
fix this.
|
||||||
|
|
||||||
__Note:__ AMD only supports OpenGL ES on Windows via EGL. EGL support is not
|
__Note:__ AMD only supports OpenGL ES on Windows via EGL. See the
|
||||||
enabled in GLFW by default. You need to [enable EGL when
|
[GLFW\_CONTEXT\_CREATION\_API](http://www.glfw.org/docs/latest/window_guide.html#window_hints_ctx)
|
||||||
compiling](http://www.glfw.org/docs/latest/compile.html) GLFW to use this.
|
hint for how to select EGL.
|
||||||
|
|
||||||
The `glfwinfo` tool is included in the GLFW source tree as `tests/glfwinfo.c`
|
Please verify that context creation also fails with the `glfwinfo` tool before
|
||||||
and is built along with the library. It lets you request any kind of context
|
reporting it as a bug. This tool is included in the GLFW source tree as
|
||||||
and framebuffer format supported by the GLFW API without having to recompile.
|
`tests/glfwinfo.c` and is built along with the library. It has switches for all
|
||||||
If context creation fails in your application, please verify that it also fails
|
GLFW context and framebuffer hints. Run `glfwinfo -h` for a complete list.
|
||||||
with this tool before reporting it as a bug.
|
|
||||||
|
|
||||||
In addition to the information above (OS and GLFW version), always include the
|
Always include the __operating system name and version__ (e.g. `Windows
|
||||||
__GPU model and driver version__ (i.e. `GeForce GTX660 with 352.79`) when
|
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW,
|
||||||
reporting this kind of bug.
|
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
|
### 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
|
causes glfwGetPrimaryMonitor to return `NULL`, which not all applications are
|
||||||
prepared for.
|
prepared for.
|
||||||
|
|
||||||
__Note:__ Some third-party tools report more video modes than those approved of
|
__Note:__ Some third-party tools report more video modes than are approved of
|
||||||
by the OS. For safety and compatbility, GLFW only reports video modes the OS
|
by the OS. For safety and compatibility, GLFW only reports video modes the OS
|
||||||
wants programs to use. This is not a bug.
|
wants programs to use. This is not a bug.
|
||||||
|
|
||||||
The `monitors` tool is included in the GLFW source tree as `tests/monitors.c`
|
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
|
and is built along with the library. It lists all information GLFW provides
|
||||||
monitors made available by GLFW.
|
about monitors it detects.
|
||||||
|
|
||||||
In addition to the information above (OS and GLFW version), please also include
|
Always include the __operating system name and version__ (e.g. `Windows
|
||||||
the output of the `monitors` tool when reporting this kind of bug. If it
|
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW,
|
||||||
doesn't work at all, please mention this.
|
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
|
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
|
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
|
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.
|
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
|
### Reporting a documentation bug
|
||||||
|
|
||||||
If you found the error in the generated documentation then it's fine to just
|
If you found a bug in the documentation, including this file, then it's fine to
|
||||||
link to that webpage. You don't need to figure out which documentation source
|
just link to that web page or mention that source file. You don't need to match
|
||||||
file the text comes from.
|
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
|
## 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
|
## 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
|
find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS
|
||||||
"$ENV{VULKAN_SDK}/Bin"
|
"$ENV{VULKAN_SDK}/Bin"
|
||||||
"$ENV{VK_SDK_PATH}/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()
|
else()
|
||||||
find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS
|
find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS
|
||||||
"$ENV{VULKAN_SDK}/Bin32"
|
"$ENV{VULKAN_SDK}/Bin32"
|
||||||
|
@ -27,5 +30,5 @@ endif()
|
||||||
include(FindPackageHandleStandardArgs)
|
include(FindPackageHandleStandardArgs)
|
||||||
find_package_handle_standard_args(Vulkan DEFAULT_MSG VULKAN_LIBRARY VULKAN_INCLUDE_DIR)
|
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_TESTS "Build the GLFW test programs" ON)
|
||||||
option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON)
|
option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON)
|
||||||
option(GLFW_INSTALL "Generate installation target" 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)
|
option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF)
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
|
@ -57,7 +58,11 @@ else()
|
||||||
set(GLFW_LIB_NAME glfw3)
|
set(GLFW_LIB_NAME glfw3)
|
||||||
endif()
|
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(Threads REQUIRED)
|
||||||
find_package(Vulkan)
|
find_package(Vulkan)
|
||||||
|
@ -148,6 +153,21 @@ else()
|
||||||
message(FATAL_ERROR "No supported platform was detected")
|
message(FATAL_ERROR "No supported platform was detected")
|
||||||
endif()
|
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
|
# Find and add Unix math and time libraries
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
|
@ -253,7 +273,7 @@ endif()
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
if (_GLFW_WAYLAND)
|
if (_GLFW_WAYLAND)
|
||||||
find_package(ECM REQUIRED NO_MODULE)
|
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(Wayland REQUIRED)
|
||||||
find_package(WaylandScanner 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://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)
|
[![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
|
## Introduction
|
||||||
|
|
||||||
GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and
|
GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan
|
||||||
Vulkan application development. It provides a simple, platform-independent API
|
application development. It provides a simple, platform-independent API for
|
||||||
for creating windows, contexts and surfaces, reading input, handling events, etc.
|
creating windows, contexts and surfaces, reading input, handling events, etc.
|
||||||
|
|
||||||
The current stable release is version 3.2. See the
|
GLFW is licensed under the [zlib/libpng
|
||||||
[downloads](http://www.glfw.org/download.html) page for details and files, or
|
license](https://opensource.org/licenses/Zlib).
|
||||||
fetch the `latest` branch, which always points to the latest stable release.
|
|
||||||
Each release starting with 3.0 also has a corresponding annotated tag.
|
|
||||||
|
|
||||||
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
|
If you are new to GLFW, you may find the
|
||||||
[tutorial](http://www.glfw.org/docs/latest/quick.html) for GLFW
|
[tutorial](http://www.glfw.org/docs/latest/quick.html) for GLFW
|
||||||
|
@ -25,37 +31,43 @@ the GLFW 3 API.
|
||||||
|
|
||||||
## Compiling GLFW
|
## Compiling GLFW
|
||||||
|
|
||||||
See the [Compiling GLFW](http://www.glfw.org/docs/latest/compile.html) guide in
|
GLFW itself requires only the headers and libraries for your window system. It
|
||||||
the GLFW documentation.
|
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
|
## Using GLFW
|
||||||
|
|
||||||
See the
|
See the [building application guide](http://www.glfw.org/docs/latest/build.html)
|
||||||
[Building programs that use GLFW](http://www.glfw.org/docs/latest/build.html)
|
guide in the documentation for more information.
|
||||||
guide in the GLFW documentation.
|
|
||||||
|
|
||||||
|
|
||||||
## Reporting bugs
|
## System requirements
|
||||||
|
|
||||||
Bugs are reported to our [issue tracker](https://github.com/glfw/glfw/issues).
|
GLFW supports Windows XP and later, OS X 10.7 Lion and later, and Linux and
|
||||||
Please always include the name and version of the OS where the bug occurs and
|
other Unix-like systems with the X Window System. Experimental implementations
|
||||||
the version of GLFW used. If you have cloned it, include the commit ID used.
|
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
|
See the [compatibility guide](http://www.glfw.org/docs/latest/compat.html)
|
||||||
version of your development environment.
|
in the documentation for more information.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
GLFW itself needs only the headers and libraries for your window system. It
|
GLFW itself depends only on the headers and libraries for your window system.
|
||||||
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.
|
|
||||||
|
|
||||||
The examples and test programs depend on a number of tiny libraries. These are
|
The examples and test programs depend on a number of tiny libraries. These are
|
||||||
located in the `deps/` directory.
|
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.
|
will not be included in the build.
|
||||||
|
|
||||||
The documentation is generated with [Doxygen](http://doxygen.org/). If CMake
|
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
|
## 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
|
## Contact
|
||||||
|
|
||||||
The official website for GLFW is [glfw.org](http://www.glfw.org/). There you
|
On [glfw.org](http://www.glfw.org/) you can find the latest version of GLFW, as
|
||||||
can find the latest version of GLFW, as well as news, documentation and other
|
well as news, documentation and other information about the project.
|
||||||
information about the project.
|
|
||||||
|
|
||||||
If you have questions related to the use of GLFW, we have a
|
If you have questions related to the use of GLFW, we have a
|
||||||
[support forum](http://discourse.glfw.org/), and the IRC
|
[forum](http://discourse.glfw.org/), and the `#glfw` IRC channel on
|
||||||
channel `#glfw` on [Freenode](http://freenode.net/).
|
[Freenode](http://freenode.net/).
|
||||||
|
|
||||||
If you have a bug to report, a patch to submit or a feature you'd like to
|
If you have a bug to report, a patch to submit or a feature you'd like to
|
||||||
request, please file it in the
|
request, please file it in the
|
||||||
[issue tracker](https://github.com/glfw/glfw/issues) on GitHub.
|
[issue tracker](https://github.com/glfw/glfw/issues) on GitHub.
|
||||||
|
|
||||||
Finally, if you're interested in helping out with the development of GLFW or
|
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
|
## Acknowledgements
|
||||||
|
@ -140,8 +186,10 @@ skills.
|
||||||
- heromyth
|
- heromyth
|
||||||
- Lucas Hinderberger
|
- Lucas Hinderberger
|
||||||
- Paul Holden
|
- Paul Holden
|
||||||
|
- Warren Hu
|
||||||
- IntellectualKitty
|
- IntellectualKitty
|
||||||
- Aaron Jacobs
|
- Aaron Jacobs
|
||||||
|
- Erik S. V. Jansson
|
||||||
- Toni Jovanoski
|
- Toni Jovanoski
|
||||||
- Arseny Kapoulkine
|
- Arseny Kapoulkine
|
||||||
- Osman Keskin
|
- Osman Keskin
|
||||||
|
@ -181,6 +229,7 @@ skills.
|
||||||
- Emmanuel Gil Peyrot
|
- Emmanuel Gil Peyrot
|
||||||
- Cyril Pichard
|
- Cyril Pichard
|
||||||
- Pieroman
|
- Pieroman
|
||||||
|
- Philip Rideout
|
||||||
- Jorge Rodriguez
|
- Jorge Rodriguez
|
||||||
- Ed Ropple
|
- Ed Ropple
|
||||||
- Aleksey Rybalkin
|
- Aleksey Rybalkin
|
||||||
|
@ -195,6 +244,7 @@ skills.
|
||||||
- Dmitri Shuralyov
|
- Dmitri Shuralyov
|
||||||
- Daniel Skorupski
|
- Daniel Skorupski
|
||||||
- Bradley Smith
|
- Bradley Smith
|
||||||
|
- Patrick Snape
|
||||||
- Julian Squires
|
- Julian Squires
|
||||||
- Johannes Stein
|
- Johannes Stein
|
||||||
- Justin Stoecker
|
- Justin Stoecker
|
||||||
|
@ -202,7 +252,7 @@ skills.
|
||||||
- Nathan Sweet
|
- Nathan Sweet
|
||||||
- TTK-Bandit
|
- TTK-Bandit
|
||||||
- Sergey Tikhomirov
|
- Sergey Tikhomirov
|
||||||
- A. Tombs
|
- Arthur Tombs
|
||||||
- Ioannis Tsakpinis
|
- Ioannis Tsakpinis
|
||||||
- Samuli Tuomola
|
- Samuli Tuomola
|
||||||
- urraka
|
- urraka
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define inline __inline
|
#define inline __inline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -192,19 +192,20 @@ static inline void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z,
|
||||||
vec3 u = {x, y, z};
|
vec3 u = {x, y, z};
|
||||||
|
|
||||||
if(vec3_len(u) > 1e-4) {
|
if(vec3_len(u) > 1e-4) {
|
||||||
|
mat4x4 T, C, S;
|
||||||
|
|
||||||
vec3_norm(u, u);
|
vec3_norm(u, u);
|
||||||
mat4x4 T;
|
|
||||||
mat4x4_from_vec3_mul_outer(T, u, u);
|
mat4x4_from_vec3_mul_outer(T, u, u);
|
||||||
|
|
||||||
mat4x4 S = {
|
S[1][2] = u[0];
|
||||||
{ 0, u[2], -u[1], 0},
|
S[2][1] = -u[0];
|
||||||
{-u[2], 0, u[0], 0},
|
S[2][0] = u[1];
|
||||||
{ u[1], -u[0], 0, 0},
|
S[0][2] = -u[1];
|
||||||
{ 0, 0, 0, 0}
|
S[0][1] = u[2];
|
||||||
};
|
S[1][0] = -u[2];
|
||||||
|
|
||||||
mat4x4_scale(S, S, s);
|
mat4x4_scale(S, S, s);
|
||||||
|
|
||||||
mat4x4 C;
|
|
||||||
mat4x4_identity(C);
|
mat4x4_identity(C);
|
||||||
mat4x4_sub(C, C, T);
|
mat4x4_sub(C, C, T);
|
||||||
|
|
||||||
|
@ -213,7 +214,7 @@ static inline void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z,
|
||||||
mat4x4_add(T, T, C);
|
mat4x4_add(T, T, C);
|
||||||
mat4x4_add(T, T, S);
|
mat4x4_add(T, T, S);
|
||||||
|
|
||||||
T[3][3] = 1.;
|
T[3][3] = 1.;
|
||||||
mat4x4_mul(R, M, T);
|
mat4x4_mul(R, M, T);
|
||||||
} else {
|
} else {
|
||||||
mat4x4_dup(R, M);
|
mat4x4_dup(R, M);
|
||||||
|
@ -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)
|
static inline void mat4x4_invert(mat4x4 T, mat4x4 M)
|
||||||
{
|
{
|
||||||
|
float idet;
|
||||||
float s[6];
|
float s[6];
|
||||||
float c[6];
|
float c[6];
|
||||||
s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1];
|
s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1];
|
||||||
|
@ -272,10 +274,10 @@ static inline void mat4x4_invert(mat4x4 T, mat4x4 M)
|
||||||
c[3] = M[2][1]*M[3][2] - M[3][1]*M[2][2];
|
c[3] = M[2][1]*M[3][2] - M[3][1]*M[2][2];
|
||||||
c[4] = M[2][1]*M[3][3] - M[3][1]*M[2][3];
|
c[4] = M[2][1]*M[3][3] - M[3][1]*M[2][3];
|
||||||
c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3];
|
c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3];
|
||||||
|
|
||||||
/* Assumes it is invertible */
|
/* 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][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;
|
T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet;
|
||||||
T[0][2] = ( M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet;
|
T[0][2] = ( M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet;
|
||||||
|
@ -298,12 +300,12 @@ static inline void mat4x4_invert(mat4x4 T, mat4x4 M)
|
||||||
}
|
}
|
||||||
static inline void mat4x4_orthonormalize(mat4x4 R, mat4x4 M)
|
static inline void mat4x4_orthonormalize(mat4x4 R, mat4x4 M)
|
||||||
{
|
{
|
||||||
mat4x4_dup(R, M);
|
|
||||||
float s = 1.;
|
float s = 1.;
|
||||||
vec3 h;
|
vec3 h;
|
||||||
|
|
||||||
|
mat4x4_dup(R, M);
|
||||||
vec3_norm(R[2], R[2]);
|
vec3_norm(R[2], R[2]);
|
||||||
|
|
||||||
s = vec3_mul_inner(R[1], R[2]);
|
s = vec3_mul_inner(R[1], R[2]);
|
||||||
vec3_scale(h, R[2], s);
|
vec3_scale(h, R[2], s);
|
||||||
vec3_sub(R[1], R[1], h);
|
vec3_sub(R[1], R[1], h);
|
||||||
|
@ -324,7 +326,7 @@ static inline void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t,
|
||||||
{
|
{
|
||||||
M[0][0] = 2.f*n/(r-l);
|
M[0][0] = 2.f*n/(r-l);
|
||||||
M[0][1] = M[0][2] = M[0][3] = 0.f;
|
M[0][1] = M[0][2] = M[0][3] = 0.f;
|
||||||
|
|
||||||
M[1][1] = 2.f*n/(t-b);
|
M[1][1] = 2.f*n/(t-b);
|
||||||
M[1][0] = M[1][2] = M[1][3] = 0.f;
|
M[1][0] = M[1][2] = M[1][3] = 0.f;
|
||||||
|
|
||||||
|
@ -332,7 +334,7 @@ static inline void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t,
|
||||||
M[2][1] = (t+b)/(t-b);
|
M[2][1] = (t+b)/(t-b);
|
||||||
M[2][2] = -(f+n)/(f-n);
|
M[2][2] = -(f+n)/(f-n);
|
||||||
M[2][3] = -1.f;
|
M[2][3] = -1.f;
|
||||||
|
|
||||||
M[3][2] = -2.f*(f*n)/(f-n);
|
M[3][2] = -2.f*(f*n)/(f-n);
|
||||||
M[3][0] = M[3][1] = M[3][3] = 0.f;
|
M[3][0] = M[3][1] = M[3][3] = 0.f;
|
||||||
}
|
}
|
||||||
|
@ -346,7 +348,7 @@ static inline void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t, fl
|
||||||
|
|
||||||
M[2][2] = -2.f/(f-n);
|
M[2][2] = -2.f/(f-n);
|
||||||
M[2][0] = M[2][1] = M[2][3] = 0.f;
|
M[2][0] = M[2][1] = M[2][3] = 0.f;
|
||||||
|
|
||||||
M[3][0] = -(r+l)/(r-l);
|
M[3][0] = -(r+l)/(r-l);
|
||||||
M[3][1] = -(t+b)/(t-b);
|
M[3][1] = -(t+b)/(t-b);
|
||||||
M[3][2] = -(f+n)/(f-n);
|
M[3][2] = -(f+n)/(f-n);
|
||||||
|
@ -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
|
/* TODO: The negation of of can be spared by swapping the order of
|
||||||
* operands in the following cross products in the right way. */
|
* operands in the following cross products in the right way. */
|
||||||
vec3 f;
|
vec3 f;
|
||||||
vec3_sub(f, center, eye);
|
|
||||||
vec3_norm(f, f);
|
|
||||||
|
|
||||||
vec3 s;
|
vec3 s;
|
||||||
|
vec3 t;
|
||||||
|
|
||||||
|
vec3_sub(f, center, eye);
|
||||||
|
vec3_norm(f, f);
|
||||||
|
|
||||||
vec3_mul_cross(s, f, up);
|
vec3_mul_cross(s, f, up);
|
||||||
vec3_norm(s, s);
|
vec3_norm(s, s);
|
||||||
|
|
||||||
vec3 t;
|
|
||||||
vec3_mul_cross(t, s, f);
|
vec3_mul_cross(t, s, f);
|
||||||
|
|
||||||
m[0][0] = s[0];
|
m[0][0] = s[0];
|
||||||
|
@ -470,9 +473,9 @@ static inline void quat_conj(quat r, quat q)
|
||||||
r[3] = q[3];
|
r[3] = q[3];
|
||||||
}
|
}
|
||||||
static inline void quat_rotate(quat r, float angle, vec3 axis) {
|
static inline void quat_rotate(quat r, float angle, vec3 axis) {
|
||||||
|
int i;
|
||||||
vec3 v;
|
vec3 v;
|
||||||
vec3_scale(v, axis, sinf(angle / 2));
|
vec3_scale(v, axis, sinf(angle / 2));
|
||||||
int i;
|
|
||||||
for(i=0; i<3; ++i)
|
for(i=0; i<3; ++i)
|
||||||
r[i] = v[i];
|
r[i] = v[i];
|
||||||
r[3] = cosf(angle / 2);
|
r[3] = cosf(angle / 2);
|
||||||
|
@ -507,7 +510,7 @@ static inline void mat4x4_from_quat(mat4x4 M, quat q)
|
||||||
float b2 = b*b;
|
float b2 = b*b;
|
||||||
float c2 = c*c;
|
float c2 = c*c;
|
||||||
float d2 = d*d;
|
float d2 = d*d;
|
||||||
|
|
||||||
M[0][0] = a2 + b2 - c2 - d2;
|
M[0][0] = a2 + b2 - c2 - d2;
|
||||||
M[0][1] = 2.f*(b*c + a*d);
|
M[0][1] = 2.f*(b*c + a*d);
|
||||||
M[0][2] = 2.f*(b*d - a*c);
|
M[0][2] = 2.f*(b*d - a*c);
|
||||||
|
|
|
@ -115,11 +115,14 @@ extern "C" {
|
||||||
#define GLFW_CALLBACK_DEFINED
|
#define GLFW_CALLBACK_DEFINED
|
||||||
#endif /* CALLBACK */
|
#endif /* CALLBACK */
|
||||||
|
|
||||||
/* Most Windows GLU headers need wchar_t.
|
/* Include because most Windows GLU headers need wchar_t and
|
||||||
* The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h.
|
* the OS X OpenGL header blocks the definition of ptrdiff_t by glext.h.
|
||||||
* Include it unconditionally to avoid surprising side-effects.
|
* Include it unconditionally to avoid surprising side-effects.
|
||||||
*/
|
*/
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* Include because it is needed by Vulkan and related functions.
|
||||||
|
*/
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/* Include the chosen client API headers.
|
/* Include the chosen client API headers.
|
||||||
|
@ -1182,6 +1185,7 @@ typedef struct GLFWgammaramp
|
||||||
/*! @brief Image data.
|
/*! @brief Image data.
|
||||||
*
|
*
|
||||||
* @sa @ref cursor_custom
|
* @sa @ref cursor_custom
|
||||||
|
* @sa @ref window_icon
|
||||||
*
|
*
|
||||||
* @since Added in version 2.1.
|
* @since Added in version 2.1.
|
||||||
* @glfw3 Removed format and bytes-per-pixel members.
|
* @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_
|
* screen windows, including the creation of so called _windowed full screen_
|
||||||
* or _borderless full screen_ windows, see @ref window_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
|
* By default, newly created windows use the placement recommended by the
|
||||||
* window system. To create the window at a specific position, make it
|
* window system. To create the window at a specific position, make it
|
||||||
* initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window
|
* initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window
|
||||||
|
@ -2390,8 +2398,8 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* window);
|
||||||
* in full screen on.
|
* in full screen on.
|
||||||
*
|
*
|
||||||
* @param[in] window The window to query.
|
* @param[in] window The window to query.
|
||||||
* @return The monitor, or `NULL` if the window is in windowed mode or an error
|
* @return The monitor, or `NULL` if the window is in windowed mode or an
|
||||||
* occurred.
|
* [error](@ref error_handling) occurred.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
* @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.
|
/*! @brief Posts an empty event to the event queue.
|
||||||
*
|
*
|
||||||
* This function posts an empty event from the current thread to the event
|
* 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
|
* If no windows exist, this function returns immediately. For synchronization
|
||||||
* of threads in applications that do not create windows, use your threading
|
* 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 @ref events
|
||||||
* @sa glfwWaitEvents
|
* @sa glfwWaitEvents
|
||||||
|
* @sa glfwWaitEventsTimeout
|
||||||
*
|
*
|
||||||
* @since Added in version 3.1.
|
* @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
|
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
|
||||||
* callback.
|
* callback.
|
||||||
* @return The previously set callback, or `NULL` if no callback was set or an
|
* @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.
|
* @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[in] joy The [joystick](@ref joysticks) to query.
|
||||||
* @param[out] count Where to store the number of axis values in the returned
|
* @param[out] count Where to store the number of axis values in the returned
|
||||||
* array. This is set to zero if an error occurred.
|
* array. This is set to zero if the joystick is not present or an error
|
||||||
* @return An array of axis values, or `NULL` if the joystick is not present.
|
* 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
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
* 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[in] joy The [joystick](@ref joysticks) to query.
|
||||||
* @param[out] count Where to store the number of button states in the returned
|
* @param[out] count Where to store the number of button states in the returned
|
||||||
* array. This is set to zero if an error occurred.
|
* array. This is set to zero if the joystick is not present or an error
|
||||||
* @return An array of button states, or `NULL` if the joystick is not present.
|
* 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
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
* 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.
|
* @param[in] joy The [joystick](@ref joysticks) to query.
|
||||||
* @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick
|
* @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
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
||||||
|
|
|
@ -325,9 +325,6 @@ int _glfwPlatformInit(void)
|
||||||
if (!_glfwInitThreadLocalStoragePOSIX())
|
if (!_glfwInitThreadLocalStoragePOSIX())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (!_glfwInitNSGL())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
_glfwInitTimerNS();
|
_glfwInitTimerNS();
|
||||||
_glfwInitJoysticksNS();
|
_glfwInitJoysticksNS();
|
||||||
|
|
||||||
|
@ -362,6 +359,8 @@ void _glfwPlatformTerminate(void)
|
||||||
removeObserver:_glfw.ns.listener
|
removeObserver:_glfw.ns.listener
|
||||||
name:(__bridge NSString*)kTISNotifySelectedKeyboardInputSourceChanged
|
name:(__bridge NSString*)kTISNotifySelectedKeyboardInputSourceChanged
|
||||||
object:nil];
|
object:nil];
|
||||||
|
[[NSDistributedNotificationCenter defaultCenter]
|
||||||
|
removeObserver:_glfw.ns.listener];
|
||||||
[_glfw.ns.listener release];
|
[_glfw.ns.listener release];
|
||||||
_glfw.ns.listener = nil;
|
_glfw.ns.listener = nil;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,11 +27,9 @@
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
|
||||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||||
#include <CoreVideo/CVBase.h>
|
#include <CoreVideo/CVBase.h>
|
||||||
#include <CoreVideo/CVDisplayLink.h>
|
#include <CoreVideo/CVDisplayLink.h>
|
||||||
|
@ -66,7 +64,7 @@ static char* getDisplayName(CGDirectDisplayID displayID)
|
||||||
|
|
||||||
size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value),
|
size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value),
|
||||||
kCFStringEncodingUTF8);
|
kCFStringEncodingUTF8);
|
||||||
name = calloc(size + 1, sizeof(char));
|
name = calloc(size + 1, 1);
|
||||||
CFStringGetCString(value, name, size, kCFStringEncodingUTF8);
|
CFStringGetCString(value, name, size, kCFStringEncodingUTF8);
|
||||||
|
|
||||||
CFRelease(info);
|
CFRelease(info);
|
||||||
|
|
|
@ -944,8 +944,8 @@ static GLFWbool initializeAppKit(void)
|
||||||
|
|
||||||
// Create the Cocoa window
|
// Create the Cocoa window
|
||||||
//
|
//
|
||||||
static GLFWbool createWindow(_GLFWwindow* window,
|
static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||||
const _GLFWwndconfig* wndconfig)
|
const _GLFWwndconfig* wndconfig)
|
||||||
{
|
{
|
||||||
window->ns.delegate = [[GLFWWindowDelegate alloc] initWithGlfwWindow:window];
|
window->ns.delegate = [[GLFWWindowDelegate alloc] initWithGlfwWindow:window];
|
||||||
if (window->ns.delegate == nil)
|
if (window->ns.delegate == nil)
|
||||||
|
@ -1027,13 +1027,15 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||||
if (!initializeAppKit())
|
if (!initializeAppKit())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (!createWindow(window, wndconfig))
|
if (!createNativeWindow(window, wndconfig))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
if (ctxconfig->client != GLFW_NO_API)
|
||||||
{
|
{
|
||||||
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
||||||
{
|
{
|
||||||
|
if (!_glfwInitNSGL())
|
||||||
|
return GLFW_FALSE;
|
||||||
if (!_glfwCreateContextNSGL(window, ctxconfig, fbconfig))
|
if (!_glfwCreateContextNSGL(window, ctxconfig, fbconfig))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1067,7 +1069,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||||
if (window->monitor)
|
if (window->monitor)
|
||||||
releaseMonitor(window);
|
releaseMonitor(window);
|
||||||
|
|
||||||
if (window->context.client != GLFW_NO_API)
|
if (window->context.destroy)
|
||||||
window->context.destroy(window);
|
window->context.destroy(window);
|
||||||
|
|
||||||
[window->ns.object setDelegate:nil];
|
[window->ns.object setDelegate:nil];
|
||||||
|
@ -1538,7 +1540,7 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
||||||
memcpy([rep bitmapData], image->pixels, image->width * image->height * 4);
|
memcpy([rep bitmapData], image->pixels, image->width * image->height * 4);
|
||||||
|
|
||||||
native = [[NSImage alloc] initWithSize:NSMakeSize(image->width, image->height)];
|
native = [[NSImage alloc] initWithSize:NSMakeSize(image->width, image->height)];
|
||||||
[native addRepresentation: rep];
|
[native addRepresentation:rep];
|
||||||
|
|
||||||
cursor->ns.object = [[NSCursor alloc] initWithImage:native
|
cursor->ns.object = [[NSCursor alloc] initWithImage:native
|
||||||
hotSpot:NSMakePoint(xhot, yhot)];
|
hotSpot:NSMakePoint(xhot, yhot)];
|
||||||
|
|
|
@ -34,56 +34,6 @@
|
||||||
#include <stdio.h>
|
#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 //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -369,27 +319,79 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
|
||||||
|
|
||||||
GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
|
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)
|
window->context.GetIntegerv = (PFNGLGETINTEGERVPROC)
|
||||||
glfwGetProcAddress("glGetIntegerv");
|
window->context.getProcAddress("glGetIntegerv");
|
||||||
window->context.GetString = (PFNGLGETSTRINGPROC)
|
window->context.GetString = (PFNGLGETSTRINGPROC)
|
||||||
glfwGetProcAddress("glGetString");
|
window->context.getProcAddress("glGetString");
|
||||||
if (!window->context.GetIntegerv || !window->context.GetString)
|
if (!window->context.GetIntegerv || !window->context.GetString)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parseVersionString(&window->context.client,
|
version = (const char*) window->context.GetString(GL_VERSION);
|
||||||
&window->context.major,
|
if (!version)
|
||||||
&window->context.minor,
|
|
||||||
&window->context.revision))
|
|
||||||
{
|
{
|
||||||
|
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;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
window->context.source = ctxconfig->source;
|
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))
|
||||||
|
{
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (window->context.major < ctxconfig->major ||
|
if (window->context.major < ctxconfig->major ||
|
||||||
(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
|
// For API consistency, we emulate the behavior of the
|
||||||
// {GLX|WGL}_ARB_create_context extension and fail here
|
// {GLX|WGL}_ARB_create_context extension and fail here
|
||||||
|
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
if (window->context.client == GLFW_OPENGL_API)
|
||||||
"Requested client API version %i.%i, got version %i.%i",
|
{
|
||||||
ctxconfig->major, ctxconfig->minor,
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
window->context.major, window->context.minor);
|
"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;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,7 +429,7 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
|
||||||
// users as early as possible that their build may be broken
|
// users as early as possible that their build may be broken
|
||||||
|
|
||||||
window->context.GetStringi = (PFNGLGETSTRINGIPROC)
|
window->context.GetStringi = (PFNGLGETSTRINGIPROC)
|
||||||
glfwGetProcAddress("glGetStringi");
|
window->context.getProcAddress("glGetStringi");
|
||||||
if (!window->context.GetStringi)
|
if (!window->context.GetStringi)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_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
|
// Clearing the front buffer to black to avoid garbage pixels left over from
|
||||||
// previous uses of our bit of VRAM
|
// previous uses of our bit of VRAM
|
||||||
{
|
{
|
||||||
PFNGLCLEARPROC glClear = (PFNGLCLEARPROC) glfwGetProcAddress("glClear");
|
PFNGLCLEARPROC glClear = (PFNGLCLEARPROC)
|
||||||
|
window->context.getProcAddress("glClear");
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
window->context.swapBuffers(window);
|
window->context.swapBuffers(window);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
@ -296,6 +297,9 @@ GLFWbool _glfwInitEGL(void)
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (_glfw.egl.handle)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
for (i = 0; sonames[i]; i++)
|
for (i = 0; sonames[i]; i++)
|
||||||
{
|
{
|
||||||
_glfw.egl.handle = _glfw_dlopen(sonames[i]);
|
_glfw.egl.handle = _glfw_dlopen(sonames[i]);
|
||||||
|
@ -304,7 +308,12 @@ GLFWbool _glfwInitEGL(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_glfw.egl.handle)
|
if (!_glfw.egl.handle)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Library not found");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0);
|
||||||
|
|
||||||
_glfw.egl.GetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC)
|
_glfw.egl.GetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC)
|
||||||
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib");
|
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib");
|
||||||
|
@ -339,6 +348,30 @@ GLFWbool _glfwInitEGL(void)
|
||||||
_glfw.egl.GetProcAddress = (PFNEGLGETPROCADDRESSPROC)
|
_glfw.egl.GetProcAddress = (PFNEGLGETPROCADDRESSPROC)
|
||||||
_glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress");
|
_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);
|
_glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY);
|
||||||
if (_glfw.egl.display == EGL_NO_DISPLAY)
|
if (_glfw.egl.display == EGL_NO_DISPLAY)
|
||||||
{
|
{
|
||||||
|
@ -600,6 +633,11 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||||
|
|
||||||
for (i = 0; sonames[i]; i++)
|
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]);
|
window->context.egl.client = _glfw_dlopen(sonames[i]);
|
||||||
if (window->context.egl.client)
|
if (window->context.egl.client)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -171,6 +171,7 @@ typedef struct _GLFWlibraryEGL
|
||||||
{
|
{
|
||||||
EGLDisplay display;
|
EGLDisplay display;
|
||||||
EGLint major, minor;
|
EGLint major, minor;
|
||||||
|
GLFWbool prefix;
|
||||||
|
|
||||||
GLFWbool KHR_create_context;
|
GLFWbool KHR_create_context;
|
||||||
GLFWbool KHR_create_context_no_error;
|
GLFWbool KHR_create_context_no_error;
|
||||||
|
|
|
@ -47,6 +47,8 @@
|
||||||
|
|
||||||
// Define this to 1 if building as a shared library / dynamic library / DLL
|
// Define this to 1 if building as a shared library / dynamic library / DLL
|
||||||
#cmakedefine _GLFW_BUILD_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
|
// Define this to 1 to force use of high-performance GPU on hybrid systems
|
||||||
#cmakedefine _GLFW_USE_HYBRID_HPG
|
#cmakedefine _GLFW_USE_HYBRID_HPG
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifndef GLXBadProfileARB
|
#ifndef GLXBadProfileARB
|
||||||
#define GLXBadProfileARB 13
|
#define GLXBadProfileARB 13
|
||||||
|
@ -180,20 +179,15 @@ static void swapIntervalGLX(int interval)
|
||||||
|
|
||||||
if (_glfw.glx.EXT_swap_control)
|
if (_glfw.glx.EXT_swap_control)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "swapping with glXSwapIntervalEXT\n");
|
|
||||||
_glfw.glx.SwapIntervalEXT(_glfw.x11.display,
|
_glfw.glx.SwapIntervalEXT(_glfw.x11.display,
|
||||||
window->context.glx.window,
|
window->context.glx.window,
|
||||||
interval);
|
interval);
|
||||||
}
|
}
|
||||||
else if (_glfw.glx.MESA_swap_control)
|
else if (_glfw.glx.MESA_swap_control)
|
||||||
{
|
|
||||||
fprintf (stderr, "swapping with glXSwapIntervalMESA %d %p\n", interval, _glfw.glx.SwapIntervalMESA);
|
|
||||||
_glfw.glx.SwapIntervalMESA(interval);
|
_glfw.glx.SwapIntervalMESA(interval);
|
||||||
}
|
|
||||||
else if (_glfw.glx.SGI_swap_control)
|
else if (_glfw.glx.SGI_swap_control)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "swapping with glXSwapIntervalSGI\n");
|
if (interval > 0)
|
||||||
if (interval > 0)
|
|
||||||
_glfw.glx.SwapIntervalSGI(interval);
|
_glfw.glx.SwapIntervalSGI(interval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,6 +253,9 @@ GLFWbool _glfwInitGLX(void)
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (_glfw.glx.handle)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
for (i = 0; sonames[i]; i++)
|
for (i = 0; sonames[i]; i++)
|
||||||
{
|
{
|
||||||
_glfw.glx.handle = dlopen(sonames[i], RTLD_LAZY | RTLD_GLOBAL);
|
_glfw.glx.handle = dlopen(sonames[i], RTLD_LAZY | RTLD_GLOBAL);
|
||||||
|
@ -303,6 +300,27 @@ GLFWbool _glfwInitGLX(void)
|
||||||
_glfw.glx.GetVisualFromFBConfig =
|
_glfw.glx.GetVisualFromFBConfig =
|
||||||
dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig");
|
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,
|
if (!glXQueryExtension(_glfw.x11.display,
|
||||||
&_glfw.glx.errorBase,
|
&_glfw.glx.errorBase,
|
||||||
&_glfw.glx.eventBase))
|
&_glfw.glx.eventBase))
|
||||||
|
@ -330,8 +348,6 @@ GLFWbool _glfwInitGLX(void)
|
||||||
_glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)
|
_glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)
|
||||||
getProcAddressGLX("glXSwapIntervalEXT");
|
getProcAddressGLX("glXSwapIntervalEXT");
|
||||||
|
|
||||||
fprintf (stderr, "using glXSwapIntervalEXT\n");
|
|
||||||
|
|
||||||
if (_glfw.glx.SwapIntervalEXT)
|
if (_glfw.glx.SwapIntervalEXT)
|
||||||
_glfw.glx.EXT_swap_control = GLFW_TRUE;
|
_glfw.glx.EXT_swap_control = GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -341,9 +357,6 @@ GLFWbool _glfwInitGLX(void)
|
||||||
_glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)
|
_glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)
|
||||||
getProcAddressGLX("glXSwapIntervalSGI");
|
getProcAddressGLX("glXSwapIntervalSGI");
|
||||||
|
|
||||||
fprintf (stderr, "using glXSwapIntervalSGI\n");
|
|
||||||
|
|
||||||
|
|
||||||
if (_glfw.glx.SwapIntervalSGI)
|
if (_glfw.glx.SwapIntervalSGI)
|
||||||
_glfw.glx.SGI_swap_control = GLFW_TRUE;
|
_glfw.glx.SGI_swap_control = GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -353,8 +366,6 @@ GLFWbool _glfwInitGLX(void)
|
||||||
_glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)
|
_glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)
|
||||||
getProcAddressGLX("glXSwapIntervalMESA");
|
getProcAddressGLX("glXSwapIntervalMESA");
|
||||||
|
|
||||||
fprintf (stderr, "using glXSwapIntervalMESA\n");
|
|
||||||
|
|
||||||
if (_glfw.glx.SwapIntervalMESA)
|
if (_glfw.glx.SwapIntervalMESA)
|
||||||
_glfw.glx.MESA_swap_control = GLFW_TRUE;
|
_glfw.glx.MESA_swap_control = GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ typedef void (*PFNGLXSWAPBUFFERSPROC)(Display*,GLXDrawable);
|
||||||
typedef const char* (*PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display*,int);
|
typedef const char* (*PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display*,int);
|
||||||
typedef GLXFBConfig* (*PFNGLXGETFBCONFIGSPROC)(Display*,int,int*);
|
typedef GLXFBConfig* (*PFNGLXGETFBCONFIGSPROC)(Display*,int,int*);
|
||||||
typedef GLXContext (*PFNGLXCREATENEWCONTEXTPROC)(Display*,GLXFBConfig,int,GLXContext,Bool);
|
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 (*PFNGLXSWAPINTERVALMESAPROC)(int);
|
||||||
typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int);
|
typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int);
|
||||||
typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*,GLXDrawable,int);
|
typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*,GLXDrawable,int);
|
||||||
|
|
|
@ -65,9 +65,9 @@ static const char* getErrorString(int error)
|
||||||
case GLFW_OUT_OF_MEMORY:
|
case GLFW_OUT_OF_MEMORY:
|
||||||
return "Out of memory";
|
return "Out of memory";
|
||||||
case GLFW_API_UNAVAILABLE:
|
case GLFW_API_UNAVAILABLE:
|
||||||
return "The requested client API is unavailable";
|
return "The requested API is unavailable";
|
||||||
case GLFW_VERSION_UNAVAILABLE:
|
case GLFW_VERSION_UNAVAILABLE:
|
||||||
return "The requested client API version is unavailable";
|
return "The requested API version is unavailable";
|
||||||
case GLFW_PLATFORM_ERROR:
|
case GLFW_PLATFORM_ERROR:
|
||||||
return "A platform-specific error occurred";
|
return "A platform-specific error occurred";
|
||||||
case GLFW_FORMAT_UNAVAILABLE:
|
case GLFW_FORMAT_UNAVAILABLE:
|
||||||
|
@ -130,8 +130,6 @@ GLFWAPI int glfwInit(void)
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwInitVulkan();
|
|
||||||
|
|
||||||
_glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
|
_glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
|
||||||
_glfwInitialized = GLFW_TRUE;
|
_glfwInitialized = GLFW_TRUE;
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
defined(GLFW_INCLUDE_NONE) || \
|
defined(GLFW_INCLUDE_NONE) || \
|
||||||
defined(GLFW_INCLUDE_GLEXT) || \
|
defined(GLFW_INCLUDE_GLEXT) || \
|
||||||
defined(GLFW_INCLUDE_GLU) || \
|
defined(GLFW_INCLUDE_GLU) || \
|
||||||
|
defined(GLFW_INCLUDE_VULKAN) || \
|
||||||
defined(GLFW_DLL)
|
defined(GLFW_DLL)
|
||||||
#error "You must not define any header option macros when compiling GLFW"
|
#error "You must not define any header option macros when compiling GLFW"
|
||||||
#endif
|
#endif
|
||||||
|
@ -149,11 +150,16 @@ typedef struct VkExtensionProperties
|
||||||
} VkExtensionProperties;
|
} VkExtensionProperties;
|
||||||
|
|
||||||
typedef void (APIENTRY * PFN_vkVoidFunction)(void);
|
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
|
#if defined(_GLFW_VULKAN_STATIC)
|
||||||
#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
|
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)
|
#if defined(_GLFW_COCOA)
|
||||||
#include "cocoa_platform.h"
|
#include "cocoa_platform.h"
|
||||||
|
@ -445,8 +451,10 @@ struct _GLFWlibrary
|
||||||
void* handle;
|
void* handle;
|
||||||
char** extensions;
|
char** extensions;
|
||||||
uint32_t extensionCount;
|
uint32_t extensionCount;
|
||||||
|
#if !defined(_GLFW_VULKAN_STATIC)
|
||||||
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
|
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
|
||||||
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
|
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
|
||||||
|
#endif
|
||||||
GLFWbool KHR_surface;
|
GLFWbool KHR_surface;
|
||||||
GLFWbool KHR_win32_surface;
|
GLFWbool KHR_win32_surface;
|
||||||
GLFWbool KHR_xlib_surface;
|
GLFWbool KHR_xlib_surface;
|
||||||
|
@ -1034,7 +1042,7 @@ GLFWbool _glfwIsPrintable(int key);
|
||||||
|
|
||||||
/*! @ingroup utility
|
/*! @ingroup utility
|
||||||
*/
|
*/
|
||||||
void _glfwInitVulkan(void);
|
GLFWbool _glfwInitVulkan(void);
|
||||||
|
|
||||||
/*! @ingroup utility
|
/*! @ingroup utility
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
static GLFWbool openJoystickDevice(const char* path)
|
static GLFWbool openJoystickDevice(const char* path)
|
||||||
{
|
{
|
||||||
char axisCount, buttonCount;
|
char axisCount, buttonCount;
|
||||||
char name[256];
|
char name[256] = "";
|
||||||
int joy, fd, version;
|
int joy, fd, version;
|
||||||
_GLFWjoystickLinux* js;
|
_GLFWjoystickLinux* js;
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ static GLFWbool pollJoystickEvents(_GLFWjoystickLinux* js)
|
||||||
return js->present;
|
return js->present;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lexically compare joysticks, used by quicksort
|
// Lexically compare joysticks by name; used by qsort
|
||||||
//
|
//
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
static int compareJoysticks(const void* fp, const void* sp)
|
static int compareJoysticks(const void* fp, const void* sp)
|
||||||
|
|
|
@ -183,9 +183,6 @@ int _glfwPlatformInit(void)
|
||||||
if (!_glfwInitThreadLocalStoragePOSIX())
|
if (!_glfwInitThreadLocalStoragePOSIX())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (!_glfwInitEGL())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
if (!_glfwInitJoysticksLinux())
|
if (!_glfwInitJoysticksLinux())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
|
|
@ -379,6 +379,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
if (ctxconfig->client != GLFW_NO_API)
|
||||||
{
|
{
|
||||||
|
if (!_glfwInitEGL())
|
||||||
|
return GLFW_FALSE;
|
||||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -394,7 +396,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||||
window->mir.surface = NULL;
|
window->mir.surface = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->context.client != GLFW_NO_API)
|
if (window->context.destroy)
|
||||||
window->context.destroy(window);
|
window->context.destroy(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,9 @@ static void destroyContextNSGL(_GLFWwindow* window)
|
||||||
//
|
//
|
||||||
GLFWbool _glfwInitNSGL(void)
|
GLFWbool _glfwInitNSGL(void)
|
||||||
{
|
{
|
||||||
|
if (_glfw.nsgl.framework)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
_glfw.nsgl.framework =
|
_glfw.nsgl.framework =
|
||||||
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
|
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
|
||||||
if (_glfw.nsgl.framework == NULL)
|
if (_glfw.nsgl.framework == NULL)
|
||||||
|
|
|
@ -36,20 +36,25 @@
|
||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void _glfwInitVulkan(void)
|
GLFWbool _glfwInitVulkan(void)
|
||||||
{
|
{
|
||||||
VkResult err;
|
VkResult err;
|
||||||
VkExtensionProperties* ep;
|
VkExtensionProperties* ep;
|
||||||
uint32_t i, count;
|
uint32_t i, count;
|
||||||
|
|
||||||
|
#if !defined(_GLFW_VULKAN_STATIC)
|
||||||
#if defined(_GLFW_WIN32)
|
#if defined(_GLFW_WIN32)
|
||||||
const char* name = "vulkan-1.dll";
|
const char* name = "vulkan-1.dll";
|
||||||
#else
|
#else
|
||||||
const char* name = "libvulkan.so.1";
|
const char* name = "libvulkan.so.1";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (_glfw.vk.available)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
_glfw.vk.handle = _glfw_dlopen(name);
|
_glfw.vk.handle = _glfw_dlopen(name);
|
||||||
if (!_glfw.vk.handle)
|
if (!_glfw.vk.handle)
|
||||||
return;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
|
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
|
||||||
_glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
|
_glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
|
||||||
|
@ -57,7 +62,9 @@ void _glfwInitVulkan(void)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
"Vulkan: Loader does not export vkGetInstanceProcAddr");
|
"Vulkan: Loader does not export vkGetInstanceProcAddr");
|
||||||
return;
|
|
||||||
|
_glfwTerminateVulkan();
|
||||||
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
|
_glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
|
||||||
|
@ -66,8 +73,11 @@ void _glfwInitVulkan(void)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
|
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
|
||||||
return;
|
|
||||||
|
_glfwTerminateVulkan();
|
||||||
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
#endif // _GLFW_VULKAN_STATIC
|
||||||
|
|
||||||
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
|
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -75,7 +85,9 @@ void _glfwInitVulkan(void)
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Vulkan: Failed to query instance extension count: %s",
|
"Vulkan: Failed to query instance extension count: %s",
|
||||||
_glfwGetVulkanResultString(err));
|
_glfwGetVulkanResultString(err));
|
||||||
return;
|
|
||||||
|
_glfwTerminateVulkan();
|
||||||
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ep = calloc(count, sizeof(VkExtensionProperties));
|
ep = calloc(count, sizeof(VkExtensionProperties));
|
||||||
|
@ -88,7 +100,8 @@ void _glfwInitVulkan(void)
|
||||||
_glfwGetVulkanResultString(err));
|
_glfwGetVulkanResultString(err));
|
||||||
|
|
||||||
free(ep);
|
free(ep);
|
||||||
return;
|
_glfwTerminateVulkan();
|
||||||
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
|
@ -111,11 +124,13 @@ void _glfwInitVulkan(void)
|
||||||
|
|
||||||
_glfw.vk.available = GLFW_TRUE;
|
_glfw.vk.available = GLFW_TRUE;
|
||||||
|
|
||||||
if (!_glfw.vk.KHR_surface)
|
if (_glfw.vk.KHR_surface)
|
||||||
return;
|
{
|
||||||
|
_glfw.vk.extensions =
|
||||||
|
_glfwPlatformGetRequiredInstanceExtensions(&_glfw.vk.extensionCount);
|
||||||
|
}
|
||||||
|
|
||||||
_glfw.vk.extensions =
|
return GLFW_TRUE;
|
||||||
_glfwPlatformGetRequiredInstanceExtensions(&_glfw.vk.extensionCount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwTerminateVulkan(void)
|
void _glfwTerminateVulkan(void)
|
||||||
|
@ -193,7 +208,7 @@ const char* _glfwGetVulkanResultString(VkResult result)
|
||||||
GLFWAPI int glfwVulkanSupported(void)
|
GLFWAPI int glfwVulkanSupported(void)
|
||||||
{
|
{
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||||
return _glfw.vk.available;
|
return _glfwInitVulkan();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
|
GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
|
||||||
|
@ -202,9 +217,9 @@ GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,9 +234,9 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,9 +253,9 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||||
{
|
{
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
_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;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,15 +278,15 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
assert(window != NULL);
|
assert(window != NULL);
|
||||||
|
|
||||||
assert(surface != NULL);
|
assert(surface != NULL);
|
||||||
|
|
||||||
*surface = VK_NULL_HANDLE;
|
*surface = VK_NULL_HANDLE;
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED);
|
_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;
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,19 +55,17 @@ static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib
|
||||||
|
|
||||||
// Return a list of available and usable framebuffer configs
|
// Return a list of available and usable framebuffer configs
|
||||||
//
|
//
|
||||||
static GLFWbool choosePixelFormat(_GLFWwindow* window,
|
static int choosePixelFormat(_GLFWwindow* window, const _GLFWfbconfig* desired)
|
||||||
const _GLFWfbconfig* desired,
|
|
||||||
int* result)
|
|
||||||
{
|
{
|
||||||
_GLFWfbconfig* usableConfigs;
|
_GLFWfbconfig* usableConfigs;
|
||||||
const _GLFWfbconfig* closest;
|
const _GLFWfbconfig* closest;
|
||||||
int i, nativeCount, usableCount;
|
int i, pixelFormat, nativeCount, usableCount;
|
||||||
|
|
||||||
if (_glfw.wgl.ARB_pixel_format)
|
if (_glfw.wgl.ARB_pixel_format)
|
||||||
{
|
{
|
||||||
nativeCount = getPixelFormatAttrib(window,
|
nativeCount = getPixelFormatAttrib(window,
|
||||||
1,
|
1,
|
||||||
WGL_NUMBER_PIXEL_FORMATS_ARB);
|
WGL_NUMBER_PIXEL_FORMATS_ARB);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -197,7 +195,7 @@ static GLFWbool choosePixelFormat(_GLFWwindow* window,
|
||||||
"WGL: The driver does not appear to support OpenGL");
|
"WGL: The driver does not appear to support OpenGL");
|
||||||
|
|
||||||
free(usableConfigs);
|
free(usableConfigs);
|
||||||
return GLFW_FALSE;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
|
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
|
||||||
|
@ -207,13 +205,13 @@ static GLFWbool choosePixelFormat(_GLFWwindow* window,
|
||||||
"WGL: Failed to find a suitable pixel format");
|
"WGL: Failed to find a suitable pixel format");
|
||||||
|
|
||||||
free(usableConfigs);
|
free(usableConfigs);
|
||||||
return GLFW_FALSE;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*result = (int) closest->handle;
|
pixelFormat = (int) closest->handle;
|
||||||
free(usableConfigs);
|
free(usableConfigs);
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return pixelFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns whether desktop compositing is enabled
|
// Returns whether desktop compositing is enabled
|
||||||
|
@ -288,8 +286,6 @@ static int extensionSupportedWGL(const char* extension)
|
||||||
{
|
{
|
||||||
const char* extensions;
|
const char* extensions;
|
||||||
|
|
||||||
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
|
|
||||||
|
|
||||||
if (_glfw.wgl.GetExtensionsStringEXT)
|
if (_glfw.wgl.GetExtensionsStringEXT)
|
||||||
{
|
{
|
||||||
extensions = _glfw.wgl.GetExtensionsStringEXT();
|
extensions = _glfw.wgl.GetExtensionsStringEXT();
|
||||||
|
@ -302,7 +298,7 @@ static int extensionSupportedWGL(const char* extension)
|
||||||
|
|
||||||
if (_glfw.wgl.GetExtensionsStringARB)
|
if (_glfw.wgl.GetExtensionsStringARB)
|
||||||
{
|
{
|
||||||
extensions = _glfw.wgl.GetExtensionsStringARB(window->context.wgl.dc);
|
extensions = _glfw.wgl.GetExtensionsStringARB(wglGetCurrentDC());
|
||||||
if (extensions)
|
if (extensions)
|
||||||
{
|
{
|
||||||
if (_glfwStringInExtensionString(extension, extensions))
|
if (_glfwStringInExtensionString(extension, extensions))
|
||||||
|
@ -335,29 +331,65 @@ static void destroyContextWGL(_GLFWwindow* window)
|
||||||
|
|
||||||
// Initialize WGL-specific extensions
|
// Initialize WGL-specific extensions
|
||||||
//
|
//
|
||||||
static void loadExtensions(void)
|
static void loadWGLExtensions(void)
|
||||||
{
|
{
|
||||||
// Functions for WGL_EXT_extension_string
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
// NOTE: These are needed by extensionSupported
|
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)
|
_glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
|
||||||
wglGetProcAddress("wglGetExtensionsStringEXT");
|
wglGetProcAddress("wglGetExtensionsStringEXT");
|
||||||
_glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
|
_glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
|
||||||
wglGetProcAddress("wglGetExtensionsStringARB");
|
wglGetProcAddress("wglGetExtensionsStringARB");
|
||||||
|
|
||||||
// Functions for WGL_ARB_create_context
|
|
||||||
_glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
|
_glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
|
||||||
wglGetProcAddress("wglCreateContextAttribsARB");
|
wglGetProcAddress("wglCreateContextAttribsARB");
|
||||||
|
|
||||||
// Functions for WGL_EXT_swap_control
|
|
||||||
_glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
|
_glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
|
||||||
wglGetProcAddress("wglSwapIntervalEXT");
|
wglGetProcAddress("wglSwapIntervalEXT");
|
||||||
|
|
||||||
// Functions for WGL_ARB_pixel_format
|
|
||||||
_glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
|
_glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
|
||||||
wglGetProcAddress("wglGetPixelFormatAttribivARB");
|
wglGetProcAddress("wglGetPixelFormatAttribivARB");
|
||||||
|
|
||||||
// This needs to include every extension used below except for
|
// NOTE: WGL_ARB_extensions_string and WGL_EXT_extensions_string are not
|
||||||
// WGL_ARB_extensions_string and WGL_EXT_extensions_string
|
// checked below as we are already using them
|
||||||
_glfw.wgl.ARB_multisample =
|
_glfw.wgl.ARB_multisample =
|
||||||
extensionSupportedWGL("WGL_ARB_multisample");
|
extensionSupportedWGL("WGL_ARB_multisample");
|
||||||
_glfw.wgl.ARB_framebuffer_sRGB =
|
_glfw.wgl.ARB_framebuffer_sRGB =
|
||||||
|
@ -379,7 +411,8 @@ static void loadExtensions(void)
|
||||||
_glfw.wgl.ARB_context_flush_control =
|
_glfw.wgl.ARB_context_flush_control =
|
||||||
extensionSupportedWGL("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)
|
GLFWbool _glfwInitWGL(void)
|
||||||
{
|
{
|
||||||
|
if (_glfw.wgl.instance)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
_glfw.wgl.instance = LoadLibraryA("opengl32.dll");
|
_glfw.wgl.instance = LoadLibraryA("opengl32.dll");
|
||||||
if (!_glfw.wgl.instance)
|
if (!_glfw.wgl.instance)
|
||||||
{
|
{
|
||||||
|
@ -404,6 +440,8 @@ GLFWbool _glfwInitWGL(void)
|
||||||
GetProcAddress(_glfw.wgl.instance, "wglDeleteContext");
|
GetProcAddress(_glfw.wgl.instance, "wglDeleteContext");
|
||||||
_glfw.wgl.GetProcAddress = (WGLGETPROCADDRESS_T)
|
_glfw.wgl.GetProcAddress = (WGLGETPROCADDRESS_T)
|
||||||
GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress");
|
GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress");
|
||||||
|
_glfw.wgl.GetCurrentDC = (WGLGETCURRENTDC_T)
|
||||||
|
GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC");
|
||||||
_glfw.wgl.MakeCurrent = (WGLMAKECURRENT_T)
|
_glfw.wgl.MakeCurrent = (WGLMAKECURRENT_T)
|
||||||
GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent");
|
GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent");
|
||||||
_glfw.wgl.ShareLists = (WGLSHARELISTS_T)
|
_glfw.wgl.ShareLists = (WGLSHARELISTS_T)
|
||||||
|
@ -434,12 +472,12 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||||
const _GLFWfbconfig* fbconfig)
|
const _GLFWfbconfig* fbconfig)
|
||||||
{
|
{
|
||||||
int attribs[40];
|
int attribs[40];
|
||||||
int pixelFormat = 0;
|
int pixelFormat;
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
HGLRC share = NULL;
|
HGLRC share = NULL;
|
||||||
|
|
||||||
if (ctxconfig->client == GLFW_NO_API)
|
if (!_glfw.wgl.extensionsLoaded)
|
||||||
return GLFW_TRUE;
|
loadWGLExtensions();
|
||||||
|
|
||||||
if (ctxconfig->share)
|
if (ctxconfig->share)
|
||||||
share = ctxconfig->share->context.wgl.handle;
|
share = ctxconfig->share->context.wgl.handle;
|
||||||
|
@ -452,7 +490,8 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!choosePixelFormat(window, fbconfig, &pixelFormat))
|
pixelFormat = choosePixelFormat(window, fbconfig);
|
||||||
|
if (!pixelFormat)
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (!DescribePixelFormat(window->context.wgl.dc,
|
if (!DescribePixelFormat(window->context.wgl.dc,
|
||||||
|
@ -470,6 +509,40 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||||
return GLFW_FALSE;
|
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)
|
if (_glfw.wgl.ARB_create_context)
|
||||||
{
|
{
|
||||||
int index = 0, mask = 0, flags = 0;
|
int index = 0, mask = 0, flags = 0;
|
||||||
|
@ -550,8 +623,44 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||||
share, attribs);
|
share, attribs);
|
||||||
if (!window->context.wgl.handle)
|
if (!window->context.wgl.handle)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
const DWORD error = GetLastError();
|
||||||
"WGL: Failed to create OpenGL context");
|
|
||||||
|
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;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -588,102 +697,6 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||||
|
|
||||||
#undef setWGLattrib
|
#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 //////
|
////// GLFW native API //////
|
||||||
|
|
|
@ -73,6 +73,9 @@
|
||||||
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
|
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
|
||||||
#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
|
#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 * PFNWGLSWAPINTERVALEXTPROC)(int);
|
||||||
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*);
|
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*);
|
||||||
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void);
|
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 HGLRC (WINAPI * WGLCREATECONTEXT_T)(HDC);
|
||||||
typedef BOOL (WINAPI * WGLDELETECONTEXT_T)(HGLRC);
|
typedef BOOL (WINAPI * WGLDELETECONTEXT_T)(HGLRC);
|
||||||
typedef PROC (WINAPI * WGLGETPROCADDRESS_T)(LPCSTR);
|
typedef PROC (WINAPI * WGLGETPROCADDRESS_T)(LPCSTR);
|
||||||
|
typedef HDC (WINAPI * WGLGETCURRENTDC_T)(void);
|
||||||
typedef BOOL (WINAPI * WGLMAKECURRENT_T)(HDC,HGLRC);
|
typedef BOOL (WINAPI * WGLMAKECURRENT_T)(HDC,HGLRC);
|
||||||
typedef BOOL (WINAPI * WGLSHARELISTS_T)(HGLRC,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 wglCreateContext _glfw.wgl.CreateContext
|
||||||
#define wglDeleteContext _glfw.wgl.DeleteContext
|
#define wglDeleteContext _glfw.wgl.DeleteContext
|
||||||
#define wglGetProcAddress _glfw.wgl.GetProcAddress
|
#define wglGetProcAddress _glfw.wgl.GetProcAddress
|
||||||
|
#define wglGetCurrentDC _glfw.wgl.GetCurrentDC
|
||||||
#define wglMakeCurrent _glfw.wgl.MakeCurrent
|
#define wglMakeCurrent _glfw.wgl.MakeCurrent
|
||||||
#define wglShareLists _glfw.wgl.ShareLists
|
#define wglShareLists _glfw.wgl.ShareLists
|
||||||
|
|
||||||
|
@ -118,6 +123,7 @@ typedef struct _GLFWlibraryWGL
|
||||||
WGLCREATECONTEXT_T CreateContext;
|
WGLCREATECONTEXT_T CreateContext;
|
||||||
WGLDELETECONTEXT_T DeleteContext;
|
WGLDELETECONTEXT_T DeleteContext;
|
||||||
WGLGETPROCADDRESS_T GetProcAddress;
|
WGLGETPROCADDRESS_T GetProcAddress;
|
||||||
|
WGLGETCURRENTDC_T GetCurrentDC;
|
||||||
WGLMAKECURRENT_T MakeCurrent;
|
WGLMAKECURRENT_T MakeCurrent;
|
||||||
WGLSHARELISTS_T ShareLists;
|
WGLSHARELISTS_T ShareLists;
|
||||||
|
|
||||||
|
@ -147,8 +153,5 @@ void _glfwTerminateWGL(void);
|
||||||
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig);
|
const _GLFWfbconfig* fbconfig);
|
||||||
int _glfwAnalyzeContextWGL(_GLFWwindow* window,
|
|
||||||
const _GLFWctxconfig* ctxconfig,
|
|
||||||
const _GLFWfbconfig* fbconfig);
|
|
||||||
|
|
||||||
#endif // _glfw3_wgl_context_h_
|
#endif // _glfw3_wgl_context_h_
|
||||||
|
|
|
@ -319,6 +319,10 @@ static HWND createHelperWindow(void)
|
||||||
return NULL;
|
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
|
// Register for HID device notifications
|
||||||
{
|
{
|
||||||
DEV_BROADCAST_DEVICEINTERFACE_W dbi;
|
DEV_BROADCAST_DEVICEINTERFACE_W dbi;
|
||||||
|
@ -373,7 +377,7 @@ char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
|
||||||
if (!length)
|
if (!length)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
target = calloc(length, sizeof(char));
|
target = calloc(length, 1);
|
||||||
|
|
||||||
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, length, NULL, NULL))
|
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, length, NULL, NULL))
|
||||||
{
|
{
|
||||||
|
@ -421,10 +425,6 @@ int _glfwPlatformInit(void)
|
||||||
|
|
||||||
_glfwPlatformPollEvents();
|
_glfwPlatformPollEvents();
|
||||||
|
|
||||||
if (!_glfwInitWGL())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
_glfwInitEGL();
|
|
||||||
_glfwInitTimerWin32();
|
_glfwInitTimerWin32();
|
||||||
_glfwInitJoysticksWin32();
|
_glfwInitJoysticksWin32();
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,7 @@ static int compareJoystickObjects(const void* first, const void* second)
|
||||||
//
|
//
|
||||||
static GLFWbool supportsXInput(const GUID* guid)
|
static GLFWbool supportsXInput(const GUID* guid)
|
||||||
{
|
{
|
||||||
UINT i, count;
|
UINT i, count = 0;
|
||||||
RAWINPUTDEVICELIST* ridl;
|
RAWINPUTDEVICELIST* ridl;
|
||||||
GLFWbool result = GLFW_FALSE;
|
GLFWbool result = GLFW_FALSE;
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ static GLFWbool supportsXInput(const GUID* guid)
|
||||||
|
|
||||||
ridl = calloc(count, sizeof(RAWINPUTDEVICELIST));
|
ridl = calloc(count, sizeof(RAWINPUTDEVICELIST));
|
||||||
|
|
||||||
if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == -1)
|
if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1)
|
||||||
{
|
{
|
||||||
free(ridl);
|
free(ridl);
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
@ -211,7 +211,7 @@ static GLFWbool supportsXInput(const GUID* guid)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != guid->Data1)
|
if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != (LONG) guid->Data1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
memset(name, 0, sizeof(name));
|
memset(name, 0, sizeof(name));
|
||||||
|
|
|
@ -850,9 +850,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
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;
|
int xpos, ypos, fullWidth, fullHeight;
|
||||||
WCHAR* wideTitle;
|
WCHAR* wideTitle;
|
||||||
|
@ -928,21 +929,6 @@ static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig)
|
||||||
return GLFW_TRUE;
|
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 //////
|
////// GLFW internal API //////
|
||||||
|
@ -1001,60 +987,22 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig)
|
const _GLFWfbconfig* fbconfig)
|
||||||
{
|
{
|
||||||
int status;
|
if (!createNativeWindow(window, wndconfig))
|
||||||
|
|
||||||
if (!createWindow(window, wndconfig))
|
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
if (ctxconfig->client != GLFW_NO_API)
|
||||||
{
|
{
|
||||||
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
||||||
{
|
{
|
||||||
|
if (!_glfwInitWGL())
|
||||||
|
return GLFW_FALSE;
|
||||||
if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
|
if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
|
||||||
return GLFW_FALSE;
|
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))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!_glfwInitEGL())
|
||||||
|
return GLFW_FALSE;
|
||||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1078,10 +1026,18 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||||
if (window->monitor)
|
if (window->monitor)
|
||||||
releaseMonitor(window);
|
releaseMonitor(window);
|
||||||
|
|
||||||
if (window->context.client != GLFW_NO_API)
|
if (window->context.destroy)
|
||||||
window->context.destroy(window);
|
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)
|
if (window->win32.bigIcon)
|
||||||
DestroyIcon(window->win32.bigIcon);
|
DestroyIcon(window->win32.bigIcon);
|
||||||
|
@ -1594,52 +1550,55 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
||||||
|
|
||||||
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
|
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
|
||||||
{
|
{
|
||||||
WCHAR* wideString;
|
int characterCount;
|
||||||
HANDLE stringHandle;
|
HANDLE object;
|
||||||
size_t wideSize;
|
WCHAR* buffer;
|
||||||
|
|
||||||
wideString = _glfwCreateWideStringFromUTF8Win32(string);
|
characterCount = MultiByteToWideChar(CP_UTF8, 0, string, -1, NULL, 0);
|
||||||
if (!wideString)
|
if (!characterCount)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Win32: Failed to convert string to UTF-16");
|
"Win32: Failed to convert clipboard string to UTF-16");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wideSize = (wcslen(wideString) + 1) * sizeof(WCHAR);
|
object = GlobalAlloc(GMEM_MOVEABLE, characterCount * sizeof(WCHAR));
|
||||||
|
if (!object)
|
||||||
stringHandle = GlobalAlloc(GMEM_MOVEABLE, wideSize);
|
|
||||||
if (!stringHandle)
|
|
||||||
{
|
{
|
||||||
free(wideString);
|
|
||||||
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Win32: Failed to allocate global handle for clipboard");
|
"Win32: Failed to allocate global handle for clipboard");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(GlobalLock(stringHandle), wideString, wideSize);
|
buffer = GlobalLock(object);
|
||||||
GlobalUnlock(stringHandle);
|
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))
|
if (!OpenClipboard(_glfw.win32.helperWindowHandle))
|
||||||
{
|
{
|
||||||
GlobalFree(stringHandle);
|
GlobalFree(object);
|
||||||
free(wideString);
|
|
||||||
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard");
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmptyClipboard();
|
EmptyClipboard();
|
||||||
SetClipboardData(CF_UNICODETEXT, stringHandle);
|
SetClipboardData(CF_UNICODETEXT, object);
|
||||||
CloseClipboard();
|
CloseClipboard();
|
||||||
|
|
||||||
free(wideString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
HANDLE stringHandle;
|
HANDLE object;
|
||||||
|
WCHAR* buffer;
|
||||||
|
|
||||||
if (!OpenClipboard(_glfw.win32.helperWindowHandle))
|
if (!OpenClipboard(_glfw.win32.helperWindowHandle))
|
||||||
{
|
{
|
||||||
|
@ -1647,8 +1606,8 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
stringHandle = GetClipboardData(CF_UNICODETEXT);
|
object = GetClipboardData(CF_UNICODETEXT);
|
||||||
if (!stringHandle)
|
if (!object)
|
||||||
{
|
{
|
||||||
CloseClipboard();
|
CloseClipboard();
|
||||||
|
|
||||||
|
@ -1657,11 +1616,20 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buffer = GlobalLock(object);
|
||||||
|
if (!buffer)
|
||||||
|
{
|
||||||
|
CloseClipboard();
|
||||||
|
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to lock global handle");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
free(_glfw.win32.clipboardString);
|
free(_glfw.win32.clipboardString);
|
||||||
_glfw.win32.clipboardString =
|
_glfw.win32.clipboardString =
|
||||||
_glfwCreateUTF8FromWideStringWin32(GlobalLock(stringHandle));
|
_glfwCreateUTF8FromWideStringWin32(buffer);
|
||||||
|
|
||||||
GlobalUnlock(stringHandle);
|
GlobalUnlock(object);
|
||||||
CloseClipboard();
|
CloseClipboard();
|
||||||
|
|
||||||
if (!_glfw.win32.clipboardString)
|
if (!_glfw.win32.clipboardString)
|
||||||
|
|
|
@ -151,7 +151,8 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||||
|
|
||||||
if (ctxconfig.share)
|
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);
|
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -627,6 +628,8 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* handle)
|
||||||
GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle)
|
GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
assert(window != NULL);
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
_glfwPlatformMaximizeWindow(window);
|
_glfwPlatformMaximizeWindow(window);
|
||||||
}
|
}
|
||||||
|
|
|
@ -600,9 +600,6 @@ int _glfwPlatformInit(void)
|
||||||
if (!_glfwInitThreadLocalStoragePOSIX())
|
if (!_glfwInitThreadLocalStoragePOSIX())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (!_glfwInitEGL())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
if (!_glfwInitJoysticksLinux())
|
if (!_glfwInitJoysticksLinux())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
|
||||||
struct wl_output *output;
|
struct wl_output *output;
|
||||||
char name_str[80];
|
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);
|
snprintf(name_str, 79, "wl_output@%u", name);
|
||||||
|
|
||||||
if (version < 2)
|
if (version < 2)
|
||||||
|
|
|
@ -393,6 +393,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
if (ctxconfig->client != GLFW_NO_API)
|
||||||
{
|
{
|
||||||
|
if (!_glfwInitEGL())
|
||||||
|
return GLFW_FALSE;
|
||||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -435,7 +437,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->context.client != GLFW_NO_API)
|
if (window->context.destroy)
|
||||||
window->context.destroy(window);
|
window->context.destroy(window);
|
||||||
|
|
||||||
if (window->wl.native)
|
if (window->wl.native)
|
||||||
|
|
|
@ -72,9 +72,8 @@ static int translateKeyCode(int scancode)
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now try primary keysym for function keys (non-printable keys). These
|
// Now try primary keysym for function keys (non-printable keys)
|
||||||
// should not be layout dependent (i.e. US layout and international
|
// These should not depend on the current keyboard layout
|
||||||
// layouts should give the same result).
|
|
||||||
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0);
|
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -766,13 +765,9 @@ int _glfwPlatformInit(void)
|
||||||
if (!_glfwInitThreadLocalStoragePOSIX())
|
if (!_glfwInitThreadLocalStoragePOSIX())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (!_glfwInitGLX())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
if (!_glfwInitJoysticksLinux())
|
if (!_glfwInitJoysticksLinux())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
_glfwInitEGL();
|
|
||||||
_glfwInitTimerPOSIX();
|
_glfwInitTimerPOSIX();
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
|
|
|
@ -123,10 +123,8 @@ typedef struct _GLFWwindowX11
|
||||||
int warpCursorPosX, warpCursorPosY;
|
int warpCursorPosX, warpCursorPosY;
|
||||||
|
|
||||||
// The information from the last KeyPress event
|
// The information from the last KeyPress event
|
||||||
struct {
|
unsigned int lastKeyCode;
|
||||||
unsigned int keycode;
|
Time lastKeyTime;
|
||||||
Time time;
|
|
||||||
} last;
|
|
||||||
|
|
||||||
} _GLFWwindowX11;
|
} _GLFWwindowX11;
|
||||||
|
|
||||||
|
|
|
@ -49,15 +49,15 @@
|
||||||
#define Button7 7
|
#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;
|
fd_set fds;
|
||||||
int result, count;
|
|
||||||
const int fd = ConnectionNumber(_glfw.x11.display);
|
const int fd = ConnectionNumber(_glfw.x11.display);
|
||||||
|
int count = fd + 1;
|
||||||
count = fd + 1;
|
|
||||||
|
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(fd, &fds);
|
FD_SET(fd, &fds);
|
||||||
|
@ -67,18 +67,49 @@ void selectDisplayConnection(struct timeval* timeout)
|
||||||
if (fd < _glfw.linux_js.inotify)
|
if (fd < _glfw.linux_js.inotify)
|
||||||
count = _glfw.linux_js.inotify + 1;
|
count = _glfw.linux_js.inotify + 1;
|
||||||
#endif
|
#endif
|
||||||
|
for (;;)
|
||||||
// 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
|
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
}
|
||||||
|
else if (select(count, &fds, NULL, NULL, NULL) != -1 || errno != EINTR)
|
||||||
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
while (result == -1 && errno == EINTR && timeout == NULL);
|
}
|
||||||
|
|
||||||
|
// 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
|
// Returns whether the window is iconified
|
||||||
|
@ -105,6 +136,15 @@ static int getWindowState(_GLFWwindow* window)
|
||||||
|
|
||||||
// Returns whether the event is a selection event
|
// 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)
|
static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointer)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = (_GLFWwindow*) pointer;
|
_GLFWwindow* window = (_GLFWwindow*) pointer;
|
||||||
|
@ -218,14 +258,18 @@ static void updateNormalHints(_GLFWwindow* window, int width, int height)
|
||||||
if (window->resizable)
|
if (window->resizable)
|
||||||
{
|
{
|
||||||
if (window->minwidth != GLFW_DONT_CARE &&
|
if (window->minwidth != GLFW_DONT_CARE &&
|
||||||
window->minheight != GLFW_DONT_CARE &&
|
window->minheight != GLFW_DONT_CARE)
|
||||||
window->maxwidth != GLFW_DONT_CARE &&
|
{
|
||||||
|
hints->flags |= PMinSize;
|
||||||
|
hints->min_width = window->minwidth;
|
||||||
|
hints->min_height = window->minheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->maxwidth != GLFW_DONT_CARE &&
|
||||||
window->maxheight != GLFW_DONT_CARE)
|
window->maxheight != GLFW_DONT_CARE)
|
||||||
{
|
{
|
||||||
hints->flags |= (PMinSize | PMaxSize);
|
hints->flags |= PMaxSize;
|
||||||
hints->min_width = window->minwidth;
|
hints->max_width = window->maxwidth;
|
||||||
hints->min_height = window->minheight;
|
|
||||||
hints->max_width = window->maxwidth;
|
|
||||||
hints->max_height = window->maxheight;
|
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);
|
XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);
|
||||||
XFree(hints);
|
XFree(hints);
|
||||||
}
|
}
|
||||||
|
@ -416,9 +463,9 @@ static void updateCursorImage(_GLFWwindow* window)
|
||||||
|
|
||||||
// Create the X11 window (and its colormap)
|
// Create the X11 window (and its colormap)
|
||||||
//
|
//
|
||||||
static GLFWbool createWindow(_GLFWwindow* window,
|
static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||||
const _GLFWwndconfig* wndconfig,
|
const _GLFWwndconfig* wndconfig,
|
||||||
Visual* visual, int depth)
|
Visual* visual, int depth)
|
||||||
{
|
{
|
||||||
// Create a colormap based on the visual used by the current context
|
// Create a colormap based on the visual used by the current context
|
||||||
window->x11.colormap = XCreateColormap(_glfw.x11.display,
|
window->x11.colormap = XCreateColormap(_glfw.x11.display,
|
||||||
|
@ -608,15 +655,6 @@ static GLFWbool createWindow(_GLFWwindow* window,
|
||||||
return GLFW_TRUE;
|
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
|
// Set the specified property to the selection converted to the requested target
|
||||||
//
|
//
|
||||||
static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
|
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
|
// HACK: Ignore duplicate key press events generated by ibus
|
||||||
// Corresponding release events are filtered out by the
|
// Corresponding release events are filtered out by the
|
||||||
// GLFW key repeat logic
|
// GLFW key repeat logic
|
||||||
if (window->x11.last.keycode != keycode ||
|
if (window->x11.lastKeyCode != keycode ||
|
||||||
window->x11.last.time != event->xkey.time)
|
window->x11.lastKeyTime != event->xkey.time)
|
||||||
{
|
{
|
||||||
if (keycode)
|
if (keycode)
|
||||||
_glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
|
_glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
window->x11.last.keycode = keycode;
|
window->x11.lastKeyCode = keycode;
|
||||||
window->x11.last.time = event->xkey.time;
|
window->x11.lastKeyTime = event->xkey.time;
|
||||||
|
|
||||||
if (!filtered)
|
if (!filtered)
|
||||||
{
|
{
|
||||||
|
@ -1514,17 +1552,21 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||||
{
|
{
|
||||||
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
||||||
{
|
{
|
||||||
|
if (!_glfwInitGLX())
|
||||||
|
return GLFW_FALSE;
|
||||||
if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth))
|
if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!_glfwInitEGL())
|
||||||
|
return GLFW_FALSE;
|
||||||
if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth))
|
if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!createWindow(window, wndconfig, visual, depth))
|
if (!createNativeWindow(window, wndconfig, visual, depth))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
if (ctxconfig->client != GLFW_NO_API)
|
||||||
|
@ -1569,7 +1611,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||||
window->x11.ic = NULL;
|
window->x11.ic = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->context.client != GLFW_NO_API)
|
if (window->context.destroy)
|
||||||
window->context.destroy(window);
|
window->context.destroy(window);
|
||||||
|
|
||||||
if (window->x11.handle)
|
if (window->x11.handle)
|
||||||
|
@ -1673,21 +1715,11 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||||
|
|
||||||
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
||||||
{
|
{
|
||||||
Window child;
|
Window dummy;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
XTranslateCoordinates(_glfw.x11.display, window->x11.handle, _glfw.x11.root,
|
XTranslateCoordinates(_glfw.x11.display, window->x11.handle, _glfw.x11.root,
|
||||||
0, 0, &x, &y, &child);
|
0, 0, &x, &y, &dummy);
|
||||||
|
|
||||||
if (child)
|
|
||||||
{
|
|
||||||
int left, top;
|
|
||||||
XTranslateCoordinates(_glfw.x11.display, window->x11.handle, child,
|
|
||||||
0, 0, &left, &top, &child);
|
|
||||||
|
|
||||||
x -= left;
|
|
||||||
y -= top;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xpos)
|
if (xpos)
|
||||||
*xpos = x;
|
*xpos = x;
|
||||||
|
@ -1786,19 +1818,16 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||||
if (!_glfwPlatformWindowVisible(window) &&
|
if (!_glfwPlatformWindowVisible(window) &&
|
||||||
_glfw.x11.NET_REQUEST_FRAME_EXTENTS)
|
_glfw.x11.NET_REQUEST_FRAME_EXTENTS)
|
||||||
{
|
{
|
||||||
uint64_t base;
|
|
||||||
XEvent event;
|
XEvent event;
|
||||||
|
double timeout = 0.5;
|
||||||
|
|
||||||
// Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to
|
// Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to
|
||||||
// function before the window is mapped
|
// function before the window is mapped
|
||||||
sendEventToWM(window, _glfw.x11.NET_REQUEST_FRAME_EXTENTS,
|
sendEventToWM(window, _glfw.x11.NET_REQUEST_FRAME_EXTENTS,
|
||||||
0, 0, 0, 0, 0);
|
0, 0, 0, 0, 0);
|
||||||
|
|
||||||
base = _glfwPlatformGetTimerValue();
|
// HACK: Use a timeout because earlier versions of some window managers
|
||||||
|
// (at least Unity, Fluxbox and Xfwm) failed to send the reply
|
||||||
// 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
|
|
||||||
// They have been fixed but broken versions are still in the wild
|
// They have been fixed but broken versions are still in the wild
|
||||||
// If you are affected by this and your window manager is NOT
|
// If you are affected by this and your window manager is NOT
|
||||||
// listed above, PLEASE report it to their and our issue trackers
|
// listed above, PLEASE report it to their and our issue trackers
|
||||||
|
@ -1807,21 +1836,12 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||||
isFrameExtentsEvent,
|
isFrameExtentsEvent,
|
||||||
(XPointer) window))
|
(XPointer) window))
|
||||||
{
|
{
|
||||||
double remaining;
|
if (!waitForEvent(&timeout))
|
||||||
struct timeval timeout;
|
|
||||||
|
|
||||||
remaining = 0.5 - (_glfwPlatformGetTimerValue() - base) /
|
|
||||||
(double) _glfwPlatformGetTimerFrequency();
|
|
||||||
if (remaining <= 0.0)
|
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"X11: The window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation; please report this issue");
|
"X11: The window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation; please report this issue");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
timeout.tv_sec = 0;
|
|
||||||
timeout.tv_usec = (long) (remaining * 1e6);
|
|
||||||
selectDisplayConnection(&timeout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1871,8 +1891,11 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_glfwPlatformWindowIconified(window))
|
if (_glfwPlatformWindowIconified(window))
|
||||||
|
{
|
||||||
XMapWindow(_glfw.x11.display, window->x11.handle);
|
XMapWindow(_glfw.x11.display, window->x11.handle);
|
||||||
else
|
waitForVisibilityNotify(window);
|
||||||
|
}
|
||||||
|
else if (_glfwPlatformWindowVisible(window))
|
||||||
{
|
{
|
||||||
if (_glfw.x11.NET_WM_STATE &&
|
if (_glfw.x11.NET_WM_STATE &&
|
||||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&
|
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&
|
||||||
|
@ -1908,8 +1931,11 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
||||||
|
|
||||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
|
if (_glfwPlatformWindowVisible(window))
|
||||||
|
return;
|
||||||
|
|
||||||
XMapWindow(_glfw.x11.display, window->x11.handle);
|
XMapWindow(_glfw.x11.display, window->x11.handle);
|
||||||
XFlush(_glfw.x11.display);
|
waitForVisibilityNotify(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformHideWindow(_GLFWwindow* window)
|
void _glfwPlatformHideWindow(_GLFWwindow* window)
|
||||||
|
@ -1964,7 +1990,8 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
||||||
if (window->monitor)
|
if (window->monitor)
|
||||||
{
|
{
|
||||||
XMapRaised(_glfw.x11.display, window->x11.handle);
|
XMapRaised(_glfw.x11.display, window->x11.handle);
|
||||||
acquireMonitor(window);
|
if (waitForVisibilityNotify(window))
|
||||||
|
acquireMonitor(window);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2042,28 +2069,17 @@ void _glfwPlatformPollEvents(void)
|
||||||
void _glfwPlatformWaitEvents(void)
|
void _glfwPlatformWaitEvents(void)
|
||||||
{
|
{
|
||||||
while (!XPending(_glfw.x11.display))
|
while (!XPending(_glfw.x11.display))
|
||||||
selectDisplayConnection(NULL);
|
waitForEvent(NULL);
|
||||||
|
|
||||||
_glfwPlatformPollEvents();
|
_glfwPlatformPollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformWaitEventsTimeout(double timeout)
|
void _glfwPlatformWaitEventsTimeout(double timeout)
|
||||||
{
|
{
|
||||||
const double deadline = timeout + _glfwPlatformGetTimerValue() /
|
|
||||||
(double) _glfwPlatformGetTimerFrequency();
|
|
||||||
|
|
||||||
while (!XPending(_glfw.x11.display))
|
while (!XPending(_glfw.x11.display))
|
||||||
{
|
{
|
||||||
const double remaining = deadline - _glfwPlatformGetTimerValue() /
|
if (!waitForEvent(&timeout))
|
||||||
(double) _glfwPlatformGetTimerFrequency();
|
break;
|
||||||
if (remaining <= 0.0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const long seconds = (long) remaining;
|
|
||||||
const long microseconds = (long) ((remaining - seconds) * 1e6);
|
|
||||||
struct timeval tv = { seconds, microseconds };
|
|
||||||
|
|
||||||
selectDisplayConnection(&tv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwPlatformPollEvents();
|
_glfwPlatformPollEvents();
|
||||||
|
@ -2254,10 +2270,8 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
||||||
_glfw.x11.GLFW_SELECTION,
|
_glfw.x11.GLFW_SELECTION,
|
||||||
window->x11.handle, CurrentTime);
|
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))
|
while (!XCheckTypedEvent(_glfw.x11.display, SelectionNotify, &event))
|
||||||
selectDisplayConnection(NULL);
|
waitForEvent(NULL);
|
||||||
|
|
||||||
if (event.xselection.property == None)
|
if (event.xselection.property == None)
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in New Issue