mirror of
https://github.com/glfw/glfw.git
synced 2025-12-21 06:31:58 +00:00
Compare commits
77 Commits
f171be476d
...
0ff54484fe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ff54484fe | ||
|
|
86fe58df39 | ||
|
|
d915058373 | ||
|
|
7d23b3c6c1 | ||
|
|
8e15281d34 | ||
|
|
621e99d53e | ||
|
|
1a0b7827d4 | ||
|
|
4c64184455 | ||
|
|
bfcb98fb6c | ||
|
|
f8582d26d0 | ||
|
|
1fdd39cf3e | ||
|
|
c9b129753a | ||
|
|
04a67c8267 | ||
|
|
5c87937e44 | ||
|
|
63a7e8b7f8 | ||
|
|
acb92944d4 | ||
|
|
7ef6efeb66 | ||
|
|
3cf9f6726d | ||
|
|
bfa1c424e5 | ||
|
|
0d2d85d19c | ||
|
|
768e81a0eb | ||
|
|
161fb1b6f6 | ||
|
|
645a35a38e | ||
|
|
7523b0e6bd | ||
|
|
5190a30d8a | ||
|
|
ddbb8e0f2c | ||
|
|
5245180c56 | ||
|
|
7b51a8eb31 | ||
|
|
ac10768495 | ||
|
|
feb2a6b728 | ||
|
|
d11cb3779b | ||
|
|
d1b87143bc | ||
|
|
940b7a8668 | ||
|
|
f6722ab492 | ||
|
|
439546caae | ||
|
|
125b1a2506 | ||
|
|
a8e3e5dbe6 | ||
|
|
e597552e75 | ||
|
|
8f1ddbb908 | ||
|
|
5842644e2e | ||
|
|
59514c4bb5 | ||
|
|
1824da004f | ||
|
|
dacb814e8b | ||
|
|
589e6b78d9 | ||
|
|
ef4d722b76 | ||
|
|
9f17a69a67 | ||
|
|
d173bf1fed | ||
|
|
14333117c4 | ||
|
|
df8349b747 | ||
|
|
8618927ef9 | ||
|
|
5301a924c4 | ||
|
|
2244051453 | ||
|
|
a9b36d48d7 | ||
|
|
0173252ee1 | ||
|
|
0f142e3a1a | ||
|
|
78e4f9bd67 | ||
|
|
34ee36c088 | ||
|
|
e387ef3fdf | ||
|
|
a480de9b1d | ||
|
|
3e7b016a00 | ||
|
|
1071cf1950 | ||
|
|
4a66bf3b60 | ||
|
|
74dac5cfb4 | ||
|
|
f590075121 | ||
|
|
19f9247a68 | ||
|
|
c8fd71c7e7 | ||
|
|
fb6826c934 | ||
|
|
efac372213 | ||
|
|
8b1b11c3c4 | ||
|
|
48818fc7a9 | ||
|
|
7d5bb13b88 | ||
|
|
48e08616d9 | ||
|
|
11ddcdde9f | ||
|
|
ec524797cc | ||
|
|
827cf79f63 | ||
|
|
fb4c22ed9c | ||
|
|
8acb72b9a1 |
@ -29,7 +29,7 @@ for:
|
||||
only:
|
||||
- GENERATOR: MinGW Makefiles
|
||||
build_script:
|
||||
- set PATH=%PATH:C:\Program Files\Git\usr\bin=C:\MinGW\bin%
|
||||
- set PATH=C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;%PATH:C:\Program Files\Git\usr\bin=%
|
||||
- cmake -B build -G "%GENERATOR%" -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS%
|
||||
- cmake --build build
|
||||
-
|
||||
|
||||
@ -41,12 +41,6 @@ indent_size = 2
|
||||
indent_style = tab
|
||||
indent_size = unset
|
||||
|
||||
[deps/mingw/*.h]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
tab_width = 8
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[deps/getopt.{c,h}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
@ -23,6 +23,7 @@ video tutorials.
|
||||
- Denis Bernard
|
||||
- BiBi
|
||||
- Doug Binks
|
||||
- bitb4ker
|
||||
- blanco
|
||||
- Waris Boonyasiriwat
|
||||
- Kyle Brenneman
|
||||
@ -55,6 +56,7 @@ video tutorials.
|
||||
- Jason Daly
|
||||
- danhambleton
|
||||
- Jarrod Davis
|
||||
- decce
|
||||
- Olivier Delannoy
|
||||
- Paul R. Deppe
|
||||
- Michael Dickens
|
||||
@ -68,6 +70,7 @@ video tutorials.
|
||||
- Jan Ekström
|
||||
- Siavash Eliasi
|
||||
- er-azh
|
||||
- Jan Hendrik Farr
|
||||
- Ahmad Fatoum
|
||||
- Nikita Fediuchin
|
||||
- Felipe Ferreira
|
||||
@ -110,6 +113,7 @@ video tutorials.
|
||||
- IntellectualKitty
|
||||
- Aaron Jacobs
|
||||
- JannikGM
|
||||
- Andreas O. Jansen
|
||||
- Erik S. V. Jansson
|
||||
- jjYBdx4IL
|
||||
- Peter Johnson
|
||||
@ -121,6 +125,7 @@ video tutorials.
|
||||
- Josh Kilmer
|
||||
- Byunghoon Kim
|
||||
- Cameron King
|
||||
- knokko
|
||||
- Peter Knut
|
||||
- Christoph Kubisch
|
||||
- Yuri Kunde Schlesner
|
||||
@ -228,6 +233,7 @@ video tutorials.
|
||||
- Yoshinori Sano
|
||||
- Brandon Schaefer
|
||||
- Sebastian Schuberth
|
||||
- Jan Schuerkamp
|
||||
- Scr3amer
|
||||
- Jan Schürkamp
|
||||
- Christian Sdunek
|
||||
|
||||
145
README.md
145
README.md
@ -9,34 +9,28 @@ GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan
|
||||
application development. It provides a simple, platform-independent API for
|
||||
creating windows, contexts and surfaces, reading input, handling events, etc.
|
||||
|
||||
GLFW natively supports Windows, macOS and Linux and other Unix-like systems. On
|
||||
Linux both Wayland and X11 are supported.
|
||||
GLFW is written primarily in C99, with parts of macOS support being written in
|
||||
Objective-C.
|
||||
|
||||
GLFW supports Windows, macOS and Linux, and also works on many other Unix-like
|
||||
systems. On Linux both Wayland and X11 are supported.
|
||||
|
||||
GLFW is licensed under the [zlib/libpng
|
||||
license](https://www.glfw.org/license.html).
|
||||
|
||||
You can [download](https://www.glfw.org/download.html) the latest stable release
|
||||
as source or Windows binaries. Each release starting with 3.0 also has
|
||||
a corresponding [annotated tag](https://github.com/glfw/glfw/releases) with
|
||||
source and binary archives.
|
||||
as source or Windows and macOS binaries. There are [release
|
||||
tags](https://github.com/glfw/glfw/releases) with source and binary archives
|
||||
attached for every version since 3.0.
|
||||
|
||||
The [documentation](https://www.glfw.org/docs/latest/) is available online and is
|
||||
included in all source and binary archives. See the [release
|
||||
notes](https://www.glfw.org/docs/latest/news.html) for new features, caveats and
|
||||
deprecations in the latest release. For more details see the [version
|
||||
history](https://www.glfw.org/changelog.html).
|
||||
|
||||
The `master` branch is the stable integration branch and _should_ always compile
|
||||
and run on all supported platforms, although details of newly added features may
|
||||
change until they have been included in a release. New features and many bug
|
||||
fixes live in [other branches](https://github.com/glfw/glfw/branches/all) until
|
||||
they are stable enough to merge.
|
||||
|
||||
If you are new to GLFW, you may find the
|
||||
[tutorial](https://www.glfw.org/docs/latest/quick.html) for GLFW 3 useful. If
|
||||
you have used GLFW 2 in the past, there is a [transition
|
||||
guide](https://www.glfw.org/docs/latest/moving.html) for moving to the GLFW
|
||||
3 API.
|
||||
also included in source and binary archives, except those generated
|
||||
automatically by Github. The documentation contains guides, a tutorial and the
|
||||
API reference. The [release
|
||||
notes](https://www.glfw.org/docs/latest/news.html) list the new features,
|
||||
caveats and deprecations in the latest release. The [version
|
||||
history](https://www.glfw.org/changelog.html) lists every user-visible change
|
||||
for every release.
|
||||
|
||||
GLFW exists because of the contributions of [many people](CONTRIBUTORS.md)
|
||||
around the world, whether by reporting bugs, providing community support, adding
|
||||
@ -44,57 +38,37 @@ features, reviewing or testing code, debugging, proofreading docs, suggesting
|
||||
features or fixing bugs.
|
||||
|
||||
|
||||
## Compiling GLFW
|
||||
|
||||
GLFW is written primarily in C99, with parts of macOS support being written in
|
||||
Objective-C. GLFW itself requires only the headers and libraries for your OS
|
||||
and window system. It does not need any additional headers for context creation
|
||||
APIs (WGL, GLX, EGL, NSGL, OSMesa) or rendering APIs (OpenGL, OpenGL ES, Vulkan)
|
||||
to enable support for them.
|
||||
|
||||
GLFW supports compilation on Windows with Visual C++ 2013 and later, MinGW and
|
||||
MinGW-w64, on macOS 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 [pre-compiled binaries](https://www.glfw.org/download.html) available
|
||||
for all supported compilers on Windows and macOS.
|
||||
|
||||
See the [compilation guide](https://www.glfw.org/docs/latest/compile.html) for
|
||||
more information about how to compile GLFW yourself.
|
||||
|
||||
|
||||
## Using GLFW
|
||||
|
||||
See the [documentation](https://www.glfw.org/docs/latest/) for tutorials, guides
|
||||
and the API reference.
|
||||
|
||||
|
||||
## Contributing to GLFW
|
||||
|
||||
See the [contribution
|
||||
guide](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md) for
|
||||
more information.
|
||||
|
||||
|
||||
## System requirements
|
||||
|
||||
GLFW supports Windows XP and later and macOS 10.11 and later. Linux and other
|
||||
Unix-like systems running the X Window System are supported even without
|
||||
a desktop environment or modern extensions, although some features require
|
||||
a running window or clipboard manager. The OSMesa backend requires Mesa 6.3.
|
||||
GLFW supports Windows 7 and later and macOS 10.11 and later. On GNOME Wayland,
|
||||
window decorations will be very basic unless the
|
||||
[libdecor](https://gitlab.freedesktop.org/libdecor/libdecor) package is
|
||||
installed. Linux and other Unix-like systems running X11 are supported even
|
||||
without a desktop environment or modern extensions, although some features
|
||||
require a clipboard manager or a modern window manager.
|
||||
|
||||
See the [compatibility guide](https://www.glfw.org/docs/latest/compat.html)
|
||||
in the documentation for more information.
|
||||
for more detailed information.
|
||||
|
||||
|
||||
## Dependencies
|
||||
## Compiling GLFW
|
||||
|
||||
GLFW itself needs only CMake 3.16 or later and the headers and libraries for your
|
||||
OS and window system.
|
||||
GLFW supports compilation with Visual C++ (2013 and later), GCC and Clang. Both
|
||||
Clang-CL and MinGW-w64 are supported. Other C99 compilers will likely also
|
||||
work, but this is not regularly tested.
|
||||
|
||||
There are [pre-compiled binaries](https://www.glfw.org/download.html)
|
||||
available for Windows and macOS.
|
||||
|
||||
GLFW itself needs only CMake and the headers and libraries for your operating
|
||||
system and window system. No other SDKs are required.
|
||||
|
||||
See the [compilation guide](https://www.glfw.org/docs/latest/compile.html) for
|
||||
more information about compiling GLFW and the exact dependencies required for
|
||||
each window system.
|
||||
|
||||
The examples and test programs depend on a number of tiny libraries. These are
|
||||
located in the `deps/` directory.
|
||||
bundled in the `deps/` directory. The repository has no submodules.
|
||||
|
||||
- [getopt\_port](https://github.com/kimgr/getopt_port/) for examples
|
||||
with command-line options
|
||||
@ -107,8 +81,33 @@ located in the `deps/` directory.
|
||||
- [Nuklear](https://github.com/Immediate-Mode-UI/Nuklear) for test and example UI
|
||||
- [stb\_image\_write](https://github.com/nothings/stb) for writing images to disk
|
||||
|
||||
The documentation is generated with [Doxygen](https://doxygen.org/) if CMake can
|
||||
find that tool.
|
||||
The documentation is generated with [Doxygen](https://doxygen.org/) when the
|
||||
library is built, provided CMake could find a sufficiently new version of it
|
||||
during configuration.
|
||||
|
||||
|
||||
## Using GLFW
|
||||
|
||||
See the [HTML documentation](https://www.glfw.org/docs/latest/) for a tutorial,
|
||||
guides and the API reference.
|
||||
|
||||
|
||||
## Contributing to GLFW
|
||||
|
||||
See the [contribution
|
||||
guide](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md) for
|
||||
more information.
|
||||
|
||||
The `master` branch is the stable integration branch and _should_ always compile
|
||||
and run on all supported platforms. Details of a newly added feature,
|
||||
including the public API, may change until it has been included in a release.
|
||||
|
||||
The `latest` branch is equivalent to the [highest numbered](https://semver.org/)
|
||||
release, although it may not always point to the same commit as the tag for that
|
||||
release.
|
||||
|
||||
The `ci` branch is used to trigger continuous integration jobs for code under
|
||||
testing and should never be relied on for any purpose.
|
||||
|
||||
|
||||
## Reporting bugs
|
||||
@ -121,15 +120,31 @@ information on what to include when reporting a bug.
|
||||
|
||||
## Changelog since 3.4
|
||||
|
||||
- Added `glfwSetWindowProgressIndicator` for displaying progress on the dock or taskbar (#2286,#1183)
|
||||
- Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond
|
||||
the limit of the mouse button tokens to be reported (#2423)
|
||||
- Added `glfwGetEGLConfig` function to query the `EGLConfig` of a window (#2045)
|
||||
- Added `glfwGetGLXFBConfig` function to query the `GLXFBConfig` of a window (#1925)
|
||||
- Updated minimum CMake version to 3.16 (#2541)
|
||||
- Removed support for building with original MinGW (#2540)
|
||||
- [Win32] Removed support for Windows XP and Vista (#2505)
|
||||
- [Cocoa] Added `QuartzCore` framework as link-time dependency
|
||||
- [Cocoa] Removed support for OS X 10.10 Yosemite and earlier (#2506)
|
||||
- [Wayland] Bugfix: The fractional scaling related objects were not destroyed
|
||||
- [Wayland] Bugfix: `glfwInit` would segfault on compositor with no seat (#2517)
|
||||
- [Wayland] Bugfix: A drag entering a non-GLFW surface could cause a segfault
|
||||
- [Wayland] Bugfix: Ignore key repeat events when no window has keyboard focus (#2727)
|
||||
- [Wayland] Bugfix: Reset key repeat timer when window destroyed (#2741,#2727)
|
||||
- [Wayland] Bugfix: Memory would leak if reading a data offer failed midway
|
||||
- [Wayland] Bugfix: Retrieved cursor position would be incorrect when hovering over
|
||||
fallback decorations
|
||||
- [Wayland] Bugfix: Fallback decorations would report scroll events
|
||||
- [Wayland] Bugfix: Keyboard repeat events halted when any key is released (#2568)
|
||||
- [Wayland] Bugfix: Fallback decorations would show menu at wrong position
|
||||
- [Wayland] Bugfix: The cursor was not updated when clicking through from
|
||||
a modal to a fallback decoration
|
||||
- [Wayland] Bugfix: The cursor position was not updated when clicking through
|
||||
from a modal to the content area
|
||||
- [X11] Bugfix: Running without a WM could trigger an assert (#2593,#2601,#2631)
|
||||
- [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface`
|
||||
- [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless`
|
||||
|
||||
117
deps/mingw/_mingw_dxhelper.h
vendored
117
deps/mingw/_mingw_dxhelper.h
vendored
@ -1,117 +0,0 @@
|
||||
/**
|
||||
* This file has no copyright assigned and is placed in the Public Domain.
|
||||
* This file is part of the mingw-w64 runtime package.
|
||||
* No warranty is given; refer to the file DISCLAIMER within this package.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_MSC_EXTENSIONS)
|
||||
#define NONAMELESSUNION 1
|
||||
#endif
|
||||
#if defined(NONAMELESSSTRUCT) && \
|
||||
!defined(NONAMELESSUNION)
|
||||
#define NONAMELESSUNION 1
|
||||
#endif
|
||||
#if defined(NONAMELESSUNION) && \
|
||||
!defined(NONAMELESSSTRUCT)
|
||||
#define NONAMELESSSTRUCT 1
|
||||
#endif
|
||||
#if !defined(__GNU_EXTENSION)
|
||||
#if defined(__GNUC__) || defined(__GNUG__)
|
||||
#define __GNU_EXTENSION __extension__
|
||||
#else
|
||||
#define __GNU_EXTENSION
|
||||
#endif
|
||||
#endif /* __extension__ */
|
||||
|
||||
#ifndef __ANONYMOUS_DEFINED
|
||||
#define __ANONYMOUS_DEFINED
|
||||
#if defined(__GNUC__) || defined(__GNUG__)
|
||||
#define _ANONYMOUS_UNION __extension__
|
||||
#define _ANONYMOUS_STRUCT __extension__
|
||||
#else
|
||||
#define _ANONYMOUS_UNION
|
||||
#define _ANONYMOUS_STRUCT
|
||||
#endif
|
||||
#ifndef NONAMELESSUNION
|
||||
#define _UNION_NAME(x)
|
||||
#define _STRUCT_NAME(x)
|
||||
#else /* NONAMELESSUNION */
|
||||
#define _UNION_NAME(x) x
|
||||
#define _STRUCT_NAME(x) x
|
||||
#endif
|
||||
#endif /* __ANONYMOUS_DEFINED */
|
||||
|
||||
#ifndef DUMMYUNIONNAME
|
||||
# ifdef NONAMELESSUNION
|
||||
# define DUMMYUNIONNAME u
|
||||
# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
|
||||
# define DUMMYUNIONNAME2 u2
|
||||
# define DUMMYUNIONNAME3 u3
|
||||
# define DUMMYUNIONNAME4 u4
|
||||
# define DUMMYUNIONNAME5 u5
|
||||
# define DUMMYUNIONNAME6 u6
|
||||
# define DUMMYUNIONNAME7 u7
|
||||
# define DUMMYUNIONNAME8 u8
|
||||
# define DUMMYUNIONNAME9 u9
|
||||
# else /* NONAMELESSUNION */
|
||||
# define DUMMYUNIONNAME
|
||||
# define DUMMYUNIONNAME1 /* Wine uses this variant */
|
||||
# define DUMMYUNIONNAME2
|
||||
# define DUMMYUNIONNAME3
|
||||
# define DUMMYUNIONNAME4
|
||||
# define DUMMYUNIONNAME5
|
||||
# define DUMMYUNIONNAME6
|
||||
# define DUMMYUNIONNAME7
|
||||
# define DUMMYUNIONNAME8
|
||||
# define DUMMYUNIONNAME9
|
||||
# endif
|
||||
#endif /* DUMMYUNIONNAME */
|
||||
|
||||
#if !defined(DUMMYUNIONNAME1) /* MinGW does not define this one */
|
||||
# ifdef NONAMELESSUNION
|
||||
# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
|
||||
# else
|
||||
# define DUMMYUNIONNAME1 /* Wine uses this variant */
|
||||
# endif
|
||||
#endif /* DUMMYUNIONNAME1 */
|
||||
|
||||
#ifndef DUMMYSTRUCTNAME
|
||||
# ifdef NONAMELESSUNION
|
||||
# define DUMMYSTRUCTNAME s
|
||||
# define DUMMYSTRUCTNAME1 s1 /* Wine uses this variant */
|
||||
# define DUMMYSTRUCTNAME2 s2
|
||||
# define DUMMYSTRUCTNAME3 s3
|
||||
# define DUMMYSTRUCTNAME4 s4
|
||||
# define DUMMYSTRUCTNAME5 s5
|
||||
# else
|
||||
# define DUMMYSTRUCTNAME
|
||||
# define DUMMYSTRUCTNAME1 /* Wine uses this variant */
|
||||
# define DUMMYSTRUCTNAME2
|
||||
# define DUMMYSTRUCTNAME3
|
||||
# define DUMMYSTRUCTNAME4
|
||||
# define DUMMYSTRUCTNAME5
|
||||
# endif
|
||||
#endif /* DUMMYSTRUCTNAME */
|
||||
|
||||
/* These are for compatibility with the Wine source tree */
|
||||
|
||||
#ifndef WINELIB_NAME_AW
|
||||
# ifdef __MINGW_NAME_AW
|
||||
# define WINELIB_NAME_AW __MINGW_NAME_AW
|
||||
# else
|
||||
# ifdef UNICODE
|
||||
# define WINELIB_NAME_AW(func) func##W
|
||||
# else
|
||||
# define WINELIB_NAME_AW(func) func##A
|
||||
# endif
|
||||
# endif
|
||||
#endif /* WINELIB_NAME_AW */
|
||||
|
||||
#ifndef DECL_WINELIB_TYPE_AW
|
||||
# ifdef __MINGW_TYPEDEF_AW
|
||||
# define DECL_WINELIB_TYPE_AW __MINGW_TYPEDEF_AW
|
||||
# else
|
||||
# define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type;
|
||||
# endif
|
||||
#endif /* DECL_WINELIB_TYPE_AW */
|
||||
|
||||
2467
deps/mingw/dinput.h
vendored
2467
deps/mingw/dinput.h
vendored
File diff suppressed because it is too large
Load Diff
239
deps/mingw/xinput.h
vendored
239
deps/mingw/xinput.h
vendored
@ -1,239 +0,0 @@
|
||||
/*
|
||||
* The Wine project - Xinput Joystick Library
|
||||
* Copyright 2008 Andrew Fenn
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_XINPUT_H
|
||||
#define __WINE_XINPUT_H
|
||||
|
||||
#include <windef.h>
|
||||
|
||||
/*
|
||||
* Bitmasks for the joysticks buttons, determines what has
|
||||
* been pressed on the joystick, these need to be mapped
|
||||
* to whatever device you're using instead of an xbox 360
|
||||
* joystick
|
||||
*/
|
||||
|
||||
#define XINPUT_GAMEPAD_DPAD_UP 0x0001
|
||||
#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002
|
||||
#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004
|
||||
#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
|
||||
#define XINPUT_GAMEPAD_START 0x0010
|
||||
#define XINPUT_GAMEPAD_BACK 0x0020
|
||||
#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040
|
||||
#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
|
||||
#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
|
||||
#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
|
||||
#define XINPUT_GAMEPAD_A 0x1000
|
||||
#define XINPUT_GAMEPAD_B 0x2000
|
||||
#define XINPUT_GAMEPAD_X 0x4000
|
||||
#define XINPUT_GAMEPAD_Y 0x8000
|
||||
|
||||
/*
|
||||
* Defines the flags used to determine if the user is pushing
|
||||
* down on a button, not holding a button, etc
|
||||
*/
|
||||
|
||||
#define XINPUT_KEYSTROKE_KEYDOWN 0x0001
|
||||
#define XINPUT_KEYSTROKE_KEYUP 0x0002
|
||||
#define XINPUT_KEYSTROKE_REPEAT 0x0004
|
||||
|
||||
/*
|
||||
* Defines the codes which are returned by XInputGetKeystroke
|
||||
*/
|
||||
|
||||
#define VK_PAD_A 0x5800
|
||||
#define VK_PAD_B 0x5801
|
||||
#define VK_PAD_X 0x5802
|
||||
#define VK_PAD_Y 0x5803
|
||||
#define VK_PAD_RSHOULDER 0x5804
|
||||
#define VK_PAD_LSHOULDER 0x5805
|
||||
#define VK_PAD_LTRIGGER 0x5806
|
||||
#define VK_PAD_RTRIGGER 0x5807
|
||||
#define VK_PAD_DPAD_UP 0x5810
|
||||
#define VK_PAD_DPAD_DOWN 0x5811
|
||||
#define VK_PAD_DPAD_LEFT 0x5812
|
||||
#define VK_PAD_DPAD_RIGHT 0x5813
|
||||
#define VK_PAD_START 0x5814
|
||||
#define VK_PAD_BACK 0x5815
|
||||
#define VK_PAD_LTHUMB_PRESS 0x5816
|
||||
#define VK_PAD_RTHUMB_PRESS 0x5817
|
||||
#define VK_PAD_LTHUMB_UP 0x5820
|
||||
#define VK_PAD_LTHUMB_DOWN 0x5821
|
||||
#define VK_PAD_LTHUMB_RIGHT 0x5822
|
||||
#define VK_PAD_LTHUMB_LEFT 0x5823
|
||||
#define VK_PAD_LTHUMB_UPLEFT 0x5824
|
||||
#define VK_PAD_LTHUMB_UPRIGHT 0x5825
|
||||
#define VK_PAD_LTHUMB_DOWNRIGHT 0x5826
|
||||
#define VK_PAD_LTHUMB_DOWNLEFT 0x5827
|
||||
#define VK_PAD_RTHUMB_UP 0x5830
|
||||
#define VK_PAD_RTHUMB_DOWN 0x5831
|
||||
#define VK_PAD_RTHUMB_RIGHT 0x5832
|
||||
#define VK_PAD_RTHUMB_LEFT 0x5833
|
||||
#define VK_PAD_RTHUMB_UPLEFT 0x5834
|
||||
#define VK_PAD_RTHUMB_UPRIGHT 0x5835
|
||||
#define VK_PAD_RTHUMB_DOWNRIGHT 0x5836
|
||||
#define VK_PAD_RTHUMB_DOWNLEFT 0x5837
|
||||
|
||||
/*
|
||||
* Deadzones are for analogue joystick controls on the joypad
|
||||
* which determine when input should be assumed to be in the
|
||||
* middle of the pad. This is a threshold to stop a joypad
|
||||
* controlling the game when the player isn't touching the
|
||||
* controls.
|
||||
*/
|
||||
|
||||
#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849
|
||||
#define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689
|
||||
#define XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30
|
||||
|
||||
|
||||
/*
|
||||
* Defines what type of abilities the type of joystick has
|
||||
* DEVTYPE_GAMEPAD is available for all joysticks, however
|
||||
* there may be more specific identifiers for other joysticks
|
||||
* which are being used.
|
||||
*/
|
||||
|
||||
#define XINPUT_DEVTYPE_GAMEPAD 0x01
|
||||
#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01
|
||||
#define XINPUT_DEVSUBTYPE_WHEEL 0x02
|
||||
#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
|
||||
#define XINPUT_DEVSUBTYPE_FLIGHT_SICK 0x04
|
||||
#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
|
||||
#define XINPUT_DEVSUBTYPE_GUITAR 0x06
|
||||
#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
|
||||
|
||||
/*
|
||||
* These are used with the XInputGetCapabilities function to
|
||||
* determine the abilities to the joystick which has been
|
||||
* plugged in.
|
||||
*/
|
||||
|
||||
#define XINPUT_CAPS_VOICE_SUPPORTED 0x0004
|
||||
#define XINPUT_FLAG_GAMEPAD 0x00000001
|
||||
|
||||
/*
|
||||
* Defines the status of the battery if one is used in the
|
||||
* attached joystick. The first two define if the joystick
|
||||
* supports a battery. Disconnected means that the joystick
|
||||
* isn't connected. Wired shows that the joystick is a wired
|
||||
* joystick.
|
||||
*/
|
||||
|
||||
#define BATTERY_DEVTYPE_GAMEPAD 0x00
|
||||
#define BATTERY_DEVTYPE_HEADSET 0x01
|
||||
#define BATTERY_TYPE_DISCONNECTED 0x00
|
||||
#define BATTERY_TYPE_WIRED 0x01
|
||||
#define BATTERY_TYPE_ALKALINE 0x02
|
||||
#define BATTERY_TYPE_NIMH 0x03
|
||||
#define BATTERY_TYPE_UNKNOWN 0xFF
|
||||
#define BATTERY_LEVEL_EMPTY 0x00
|
||||
#define BATTERY_LEVEL_LOW 0x01
|
||||
#define BATTERY_LEVEL_MEDIUM 0x02
|
||||
#define BATTERY_LEVEL_FULL 0x03
|
||||
|
||||
/*
|
||||
* How many joysticks can be used with this library. Games that
|
||||
* use the xinput library will not go over this number.
|
||||
*/
|
||||
|
||||
#define XUSER_MAX_COUNT 4
|
||||
#define XUSER_INDEX_ANY 0x000000FF
|
||||
|
||||
/*
|
||||
* Defines the structure of an xbox 360 joystick.
|
||||
*/
|
||||
|
||||
typedef struct _XINPUT_GAMEPAD {
|
||||
WORD wButtons;
|
||||
BYTE bLeftTrigger;
|
||||
BYTE bRightTrigger;
|
||||
SHORT sThumbLX;
|
||||
SHORT sThumbLY;
|
||||
SHORT sThumbRX;
|
||||
SHORT sThumbRY;
|
||||
} XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
|
||||
|
||||
typedef struct _XINPUT_STATE {
|
||||
DWORD dwPacketNumber;
|
||||
XINPUT_GAMEPAD Gamepad;
|
||||
} XINPUT_STATE, *PXINPUT_STATE;
|
||||
|
||||
/*
|
||||
* Defines the structure of how much vibration is set on both the
|
||||
* right and left motors in a joystick. If you're not using a 360
|
||||
* joystick you will have to map these to your device.
|
||||
*/
|
||||
|
||||
typedef struct _XINPUT_VIBRATION {
|
||||
WORD wLeftMotorSpeed;
|
||||
WORD wRightMotorSpeed;
|
||||
} XINPUT_VIBRATION, *PXINPUT_VIBRATION;
|
||||
|
||||
/*
|
||||
* Defines the structure for what kind of abilities the joystick has
|
||||
* such abilities are things such as if the joystick has the ability
|
||||
* to send and receive audio, if the joystick is in fact a driving
|
||||
* wheel or perhaps if the joystick is some kind of dance pad or
|
||||
* guitar.
|
||||
*/
|
||||
|
||||
typedef struct _XINPUT_CAPABILITIES {
|
||||
BYTE Type;
|
||||
BYTE SubType;
|
||||
WORD Flags;
|
||||
XINPUT_GAMEPAD Gamepad;
|
||||
XINPUT_VIBRATION Vibration;
|
||||
} XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
|
||||
|
||||
/*
|
||||
* Defines the structure for a joystick input event which is
|
||||
* retrieved using the function XInputGetKeystroke
|
||||
*/
|
||||
typedef struct _XINPUT_KEYSTROKE {
|
||||
WORD VirtualKey;
|
||||
WCHAR Unicode;
|
||||
WORD Flags;
|
||||
BYTE UserIndex;
|
||||
BYTE HidCode;
|
||||
} XINPUT_KEYSTROKE, *PXINPUT_KEYSTROKE;
|
||||
|
||||
typedef struct _XINPUT_BATTERY_INFORMATION
|
||||
{
|
||||
BYTE BatteryType;
|
||||
BYTE BatteryLevel;
|
||||
} XINPUT_BATTERY_INFORMATION, *PXINPUT_BATTERY_INFORMATION;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void WINAPI XInputEnable(WINBOOL);
|
||||
DWORD WINAPI XInputSetState(DWORD, XINPUT_VIBRATION*);
|
||||
DWORD WINAPI XInputGetState(DWORD, XINPUT_STATE*);
|
||||
DWORD WINAPI XInputGetKeystroke(DWORD, DWORD, PXINPUT_KEYSTROKE);
|
||||
DWORD WINAPI XInputGetCapabilities(DWORD, DWORD, XINPUT_CAPABILITIES*);
|
||||
DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD, GUID*, GUID*);
|
||||
DWORD WINAPI XInputGetBatteryInformation(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __WINE_XINPUT_H */
|
||||
@ -1,4 +1,8 @@
|
||||
|
||||
# Because of bugs and limitations in its Markdown support, only fairly recent
|
||||
# versions of Doxygen can produce acceptable output
|
||||
set(MINIMUM_DOXYGEN_VERSION 1.9.8)
|
||||
|
||||
# NOTE: The order of this list determines the order of items in the Guides
|
||||
# (i.e. Pages) list in the generated documentation
|
||||
set(source_files
|
||||
@ -32,10 +36,10 @@ foreach(file IN LISTS source_files)
|
||||
endforeach()
|
||||
|
||||
set(DOXYGEN_SKIP_DOT TRUE)
|
||||
find_package(Doxygen)
|
||||
find_package(Doxygen ${MINIMUM_DOXYGEN_VERSION} QUIET)
|
||||
|
||||
if (NOT DOXYGEN_FOUND OR DOXYGEN_VERSION VERSION_LESS "1.9.8")
|
||||
message(STATUS "Documentation generation requires Doxygen 1.9.8 or later")
|
||||
if (NOT DOXYGEN_FOUND)
|
||||
message(STATUS "Documentation generation requires Doxygen ${MINIMUM_DOXYGEN_VERSION} or later")
|
||||
else()
|
||||
configure_file(Doxyfile.in Doxyfile @ONLY)
|
||||
add_custom_command(OUTPUT "html/index.html"
|
||||
@ -46,7 +50,7 @@ else()
|
||||
COMMENT "Generating HTML documentation"
|
||||
VERBATIM)
|
||||
|
||||
add_custom_target(docs ALL SOURCES "html/index.html")
|
||||
add_custom_target(docs ALL SOURCES ${source_files} DEPENDS "html/index.html")
|
||||
set_target_properties(docs PROPERTIES FOLDER "GLFW3")
|
||||
|
||||
if (GLFW_INSTALL)
|
||||
|
||||
@ -278,13 +278,7 @@ ALIASES = "thread_safety=@par Thread safety^^" \
|
||||
"analysis=@par Analysis^^" \
|
||||
"reentrancy=@par Reentrancy^^" \
|
||||
"errors=@par Errors^^" \
|
||||
"callback_signature=@par Callback signature^^" \
|
||||
"glfw3=__GLFW 3:__" \
|
||||
"x11=__X11:__" \
|
||||
"wayland=__Wayland:__" \
|
||||
"win32=__Windows:__" \
|
||||
"macos=__macOS:__" \
|
||||
"linux=__Linux:__"
|
||||
"callback_signature=@par Callback signature^^"
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||
# only. Doxygen will then generate output that is more tailored for C. For
|
||||
|
||||
@ -50,10 +50,11 @@ compositing window manager to un-redirect full screen GLFW windows. If the
|
||||
running window manager uses compositing but does not support this property then
|
||||
additional copying may be performed for each buffer swap of full screen windows.
|
||||
|
||||
GLFW uses the [clipboard manager protocol][ClipboardManager] to push a clipboard
|
||||
string (i.e. selection) owned by a GLFW window about to be destroyed to the
|
||||
clipboard manager. If there is no running clipboard manager, the clipboard
|
||||
string will be unavailable once the window has been destroyed.
|
||||
GLFW uses the [clipboard manager protocol][ClipboardManager] to keep the
|
||||
clipboard string availble for the user after the libary has been terminated. If
|
||||
there is no running clipboard manager and the clipboard contents has been set
|
||||
with @ref glfwSetClipboardString, the clipboard will be emptied when the library
|
||||
is terminated.
|
||||
|
||||
[clipboardManager]: https://www.freedesktop.org/wiki/ClipboardManager/
|
||||
|
||||
|
||||
@ -36,9 +36,9 @@ specific to GLFW. It may be a useful companion to this one.
|
||||
|
||||
### Installing dependencies {#compile_deps}
|
||||
|
||||
The C/C++ development environments in Visual Studio, Xcode and MinGW come with
|
||||
all necessary dependencies for compiling GLFW, but on Unix-like systems like
|
||||
Linux and FreeBSD you will need a few extra packages.
|
||||
The C/C++ development environments in Visual Studio, Xcode and MinGW-w64 come
|
||||
with all necessary dependencies for compiling GLFW, but on Unix-like systems
|
||||
like Linux and FreeBSD you will need a few extra packages.
|
||||
|
||||
|
||||
#### Dependencies for Wayland and X11 {#compile_deps_wayland}
|
||||
@ -180,7 +180,7 @@ cd path/to/build
|
||||
make
|
||||
```
|
||||
|
||||
With MinGW, it is `mingw32-make`.
|
||||
With MinGW-w64, it is `mingw32-make`.
|
||||
|
||||
```sh
|
||||
cd path/to/build
|
||||
@ -299,12 +299,12 @@ library. This option is only available when compiling for Linux and other Unix-
|
||||
systems other than macOS. This is enabled by default.
|
||||
|
||||
|
||||
## Cross-compilation with CMake and MinGW {#compile_mingw_cross}
|
||||
## Cross-compilation with CMake and MinGW-w64 {#compile_mingw_cross}
|
||||
|
||||
Both Cygwin and many Linux distributions have MinGW or MinGW-w64 packages. For
|
||||
example, Cygwin has the `mingw64-i686-gcc` and `mingw64-x86_64-gcc` packages
|
||||
for 32- and 64-bit version of MinGW-w64, while Debian GNU/Linux and derivatives
|
||||
like Ubuntu have the `mingw-w64` package for both.
|
||||
Both Cygwin and many Linux distributions have MinGW-w64 packages. For example,
|
||||
Cygwin has the `mingw64-i686-gcc` and `mingw64-x86_64-gcc` packages for 32- and
|
||||
64-bit version of MinGW-w64, while Debian GNU/Linux and derivatives like Ubuntu
|
||||
have the `mingw-w64` package for both.
|
||||
|
||||
GLFW has CMake toolchain files in the `CMake` subdirectory that set up
|
||||
cross-compilation of Windows binaries. To use these files you set the
|
||||
@ -315,9 +315,9 @@ configuring and generating the build files.
|
||||
cmake -S path/to/glfw -B path/to/build -D CMAKE_TOOLCHAIN_FILE=path/to/file
|
||||
```
|
||||
|
||||
The exact toolchain file to use depends on the prefix used by the MinGW or
|
||||
MinGW-w64 binaries on your system. You can usually see this in the /usr
|
||||
directory. For example, both the Ubuntu and Cygwin MinGW-w64 packages have
|
||||
The exact toolchain file to use depends on the prefix used by the MinGW-w64
|
||||
binaries on your system. You can usually see this in the /usr directory. For
|
||||
example, both the Ubuntu and Cygwin MinGW-w64 packages have
|
||||
`/usr/x86_64-w64-mingw32` for the 64-bit compilers, so the correct invocation
|
||||
would be:
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ before the application exits. Modern systems are very good at freeing resources
|
||||
allocated by programs that exit, but GLFW sometimes has to change global system
|
||||
settings and these might not be restored without termination.
|
||||
|
||||
@macos When the library is initialized the main menu and dock icon are created.
|
||||
__macOS:__ When the library is initialized the main menu and dock icon are created.
|
||||
These are not desirable for a command-line only program. The creation of the
|
||||
main menu and dock icon can be disabled with the @ref GLFW_COCOA_MENUBAR init
|
||||
hint.
|
||||
@ -621,11 +621,11 @@ The format of the string is as follows:
|
||||
- The names of the always supported context creation APIs EGL and OSMesa
|
||||
- Any additional compile-time options, APIs and (on Windows) what compiler was used
|
||||
|
||||
For example, compiling GLFW 3.5 with MinGW as a DLL for Windows, may result in a version string
|
||||
like this:
|
||||
For example, compiling GLFW 3.5 with MinGW-64 as a DLL for Windows, may result
|
||||
in a version string like this:
|
||||
|
||||
```c
|
||||
3.5.0 Win32 WGL Null EGL OSMesa MinGW DLL
|
||||
3.5.0 Win32 WGL Null EGL OSMesa MinGW-w64 DLL
|
||||
```
|
||||
|
||||
Compiling GLFW as a static library for Linux, with both Wayland and X11 enabled, may
|
||||
|
||||
@ -255,3 +255,7 @@ hardware gamma correction, which today is typically an approximation of sRGB
|
||||
gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will
|
||||
produce the default (usually sRGB-like) behavior.
|
||||
|
||||
@note __Wayland:__ An application cannot read or modify the monitor gamma ramp.
|
||||
The @ref glfwGetGammaRamp, @ref glfwSetGammaRamp and @ref glfwSetGamma functions
|
||||
emit @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
|
||||
|
||||
32
docs/news.md
32
docs/news.md
@ -14,16 +14,48 @@ values over 8. For compatibility with older versions, the
|
||||
@ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode needs to be set to make use of
|
||||
this.
|
||||
|
||||
|
||||
### EGLConfig native access function {#eglconfig}
|
||||
|
||||
GLFW now provides the @ref glfwGetEGLConfig native access function for querying
|
||||
the `EGLConfig` of a window that has a `EGLSurface`.
|
||||
|
||||
|
||||
### GLXFBConfig native access function {#glxfbconfig}
|
||||
|
||||
GLFW now provides the @ref glfwGetGLXFBConfig native access function for
|
||||
querying the `GLXFBConfig` of a window that has a `GLXWindow`.
|
||||
|
||||
|
||||
## Caveats {#caveats}
|
||||
|
||||
## Deprecations {#deprecations}
|
||||
|
||||
## Removals {#removals}
|
||||
|
||||
### Windows XP and Vista support has been removed {#winxp_vista}
|
||||
|
||||
Support for Windows XP and Vista has been removed. Windows XP has been out of extended
|
||||
support since 2014.
|
||||
|
||||
|
||||
### Original MinGW support has been removed {#original_mingw}
|
||||
|
||||
Support for the now unmaintained original MinGW distribution has been removed.
|
||||
|
||||
This does not apply to the much more capable [MinGW-w64](https://www.mingw-w64.org/),
|
||||
which remains fully supported. MinGW-w64 can build both 32- and 64-bit binaries, is
|
||||
actively maintained and available on many platforms.
|
||||
|
||||
|
||||
## New symbols {#new_symbols}
|
||||
|
||||
### New functions {#new_functions}
|
||||
|
||||
- @ref glfwGetEGLConfig
|
||||
- @ref glfwGetGLXFBConfig
|
||||
|
||||
|
||||
### New types {#new_types}
|
||||
|
||||
### New constants {#new_constants}
|
||||
|
||||
@ -35,7 +35,7 @@ By default, GLFW will load the Vulkan loader dynamically at runtime via its stan
|
||||
`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other Unix-like systems and
|
||||
`libvulkan.1.dylib` on macOS.
|
||||
|
||||
@macos GLFW will also look up and search the `Frameworks` subdirectory of your
|
||||
__macOS:__ GLFW will also look up and search the `Frameworks` subdirectory of your
|
||||
application bundle.
|
||||
|
||||
If your code is using a Vulkan loader with a different name or in a non-standard location
|
||||
@ -47,7 +47,7 @@ entry point retrieval. This prevents GLFW from dynamically loading the Vulkan l
|
||||
glfwInitVulkanLoader(vkGetInstanceProcAddr);
|
||||
```
|
||||
|
||||
@macos To make your application be redistributable you will need to set up the application
|
||||
__macOS:__ To make your application be redistributable you will need to set up the application
|
||||
bundle according to the LunarG SDK documentation. This is explained in more detail in the
|
||||
[SDK documentation for macOS](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html).
|
||||
|
||||
@ -186,7 +186,7 @@ check whether any extensions you wish to enable are already in the returned
|
||||
array, as it is an error to specify an extension more than once in the
|
||||
`VkInstanceCreateInfo` struct.
|
||||
|
||||
@macos MoltenVK is (as of July 2022) not yet a fully conformant implementation
|
||||
__macOS:__ MoltenVK is (as of July 2022) not yet a fully conformant implementation
|
||||
of Vulkan. As of Vulkan SDK 1.3.216.0, this means you must also enable the
|
||||
`VK_KHR_portability_enumeration` instance extension and set the
|
||||
`VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR` bit in the instance creation
|
||||
|
||||
@ -363,10 +363,10 @@ which API was used to create the current context may fail if you change this
|
||||
hint. This can be resolved by having it load functions via @ref
|
||||
glfwGetProcAddress.
|
||||
|
||||
@note @wayland The EGL API _is_ the native context creation API, so this hint
|
||||
@note __Wayland:__ The EGL API _is_ the native context creation API, so this hint
|
||||
will have no effect.
|
||||
|
||||
@note @x11 On some Linux systems, creating contexts via both the native and EGL
|
||||
@note __X11:__ On some Linux systems, creating contexts via both the native and EGL
|
||||
APIs in a single process will cause the application to segfault. Stick to one
|
||||
API or the other on Linux for now.
|
||||
|
||||
@ -400,7 +400,7 @@ requested. Additionally, OpenGL ES 1.x cannot be returned if 2.0 or later was
|
||||
requested, and vice versa. This is because OpenGL ES 3.x is backward compatible
|
||||
with 2.0, but OpenGL ES 2.0 is not backward compatible with 1.x.
|
||||
|
||||
@note @macos The OS only supports core profile contexts for OpenGL versions 3.2
|
||||
@note __macOS:__ The OS only supports core profile contexts for OpenGL versions 3.2
|
||||
and later. Before creating an OpenGL context of version 3.2 or later you must
|
||||
set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) hint accordingly.
|
||||
OpenGL 3.0 and 3.1 contexts are not supported at all on macOS.
|
||||
@ -893,6 +893,12 @@ int xpos, ypos;
|
||||
glfwGetWindowPos(window, &xpos, &ypos);
|
||||
```
|
||||
|
||||
@note __Wayland:__ An applications cannot know the positions of its windows or
|
||||
whether one has been moved. The @ref GLFW_POSITION_X and @ref GLFW_POSITION_Y
|
||||
window hints are ignored. The @ref glfwGetWindowPos and @ref glfwSetWindowPos
|
||||
functions emit @ref GLFW_FEATURE_UNAVAILABLE. The window position callback will
|
||||
not be called.
|
||||
|
||||
|
||||
### Window title {#window_title}
|
||||
|
||||
@ -1038,6 +1044,12 @@ You can also get the current iconification state with @ref glfwGetWindowAttrib.
|
||||
int iconified = glfwGetWindowAttrib(window, GLFW_ICONIFIED);
|
||||
```
|
||||
|
||||
@note __Wayland:__ An application cannot know if any of its windows have been
|
||||
iconified or restore one from iconification. The @ref glfwRestoreWindow
|
||||
function can only restore windows from maximization and the iconify callback
|
||||
will not be called. The [GLFW_ICONIFIED](@ref GLFW_ICONIFIED_attrib) attribute
|
||||
will be false. The @ref glfwIconifyWindow function works normally.
|
||||
|
||||
|
||||
### Window maximization {#window_maximize}
|
||||
|
||||
@ -1202,6 +1214,26 @@ not supported, the application as a whole. Once the user has given it
|
||||
attention, the system will automatically end the request.
|
||||
|
||||
|
||||
### Window progress indicator {#window_progress_indicator}
|
||||
|
||||
If you wish to display the progress of some action on the Dock icon or task bar, you can
|
||||
do this with @ref glfwSetWindowProgressIndicator.
|
||||
|
||||
```c
|
||||
glfwSetWindowProgressIndicator(window, GLFW_PROGRESS_INDICATOR_NORMAL, 0.5);
|
||||
```
|
||||
|
||||
There are different progress states available for you to use:
|
||||
- @ref GLFW_PROGRESS_INDICATOR_DISABLED
|
||||
- @ref GLFW_PROGRESS_INDICATOR_INDETERMINATE
|
||||
- @ref GLFW_PROGRESS_INDICATOR_NORMAL
|
||||
- @ref GLFW_PROGRESS_INDICATOR_ERROR
|
||||
- @ref GLFW_PROGRESS_INDICATOR_PAUSED
|
||||
|
||||
The last argument is the progress percentage to display.
|
||||
It has a valid range of 0.0 to 1.0.
|
||||
|
||||
|
||||
### Window damage and refresh {#window_refresh}
|
||||
|
||||
If you wish to be notified when the contents of a window is damaged and needs
|
||||
|
||||
@ -1228,13 +1228,13 @@ extern "C" {
|
||||
* The top-left to bottom-right diagonal resize/move shape. This is usually
|
||||
* a diagonal double-headed arrow.
|
||||
*
|
||||
* @note @macos This shape is provided by a private system API and may fail
|
||||
* @note __macOS:__ This shape is provided by a private system API and may fail
|
||||
* with @ref GLFW_CURSOR_UNAVAILABLE in the future.
|
||||
*
|
||||
* @note @wayland This shape is provided by a newer standard not supported by
|
||||
* @note __Wayland:__ This shape is provided by a newer standard not supported by
|
||||
* all cursor themes.
|
||||
*
|
||||
* @note @x11 This shape is provided by a newer standard not supported by all
|
||||
* @note __X11:__ This shape is provided by a newer standard not supported by all
|
||||
* cursor themes.
|
||||
*/
|
||||
#define GLFW_RESIZE_NWSE_CURSOR 0x00036007
|
||||
@ -1243,13 +1243,13 @@ extern "C" {
|
||||
* The top-right to bottom-left diagonal resize/move shape. This is usually
|
||||
* a diagonal double-headed arrow.
|
||||
*
|
||||
* @note @macos This shape is provided by a private system API and may fail
|
||||
* @note __macOS:__ This shape is provided by a private system API and may fail
|
||||
* with @ref GLFW_CURSOR_UNAVAILABLE in the future.
|
||||
*
|
||||
* @note @wayland This shape is provided by a newer standard not supported by
|
||||
* @note __Wayland:__ This shape is provided by a newer standard not supported by
|
||||
* all cursor themes.
|
||||
*
|
||||
* @note @x11 This shape is provided by a newer standard not supported by all
|
||||
* @note __X11:__ This shape is provided by a newer standard not supported by all
|
||||
* cursor themes.
|
||||
*/
|
||||
#define GLFW_RESIZE_NESW_CURSOR 0x00036008
|
||||
@ -1264,10 +1264,10 @@ extern "C" {
|
||||
* The operation-not-allowed shape. This is usually a circle with a diagonal
|
||||
* line through it.
|
||||
*
|
||||
* @note @wayland This shape is provided by a newer standard not supported by
|
||||
* @note __Wayland:__ This shape is provided by a newer standard not supported by
|
||||
* all cursor themes.
|
||||
*
|
||||
* @note @x11 This shape is provided by a newer standard not supported by all
|
||||
* @note __X11:__ This shape is provided by a newer standard not supported by all
|
||||
* cursor themes.
|
||||
*/
|
||||
#define GLFW_NOT_ALLOWED_CURSOR 0x0003600A
|
||||
@ -1288,6 +1288,59 @@ extern "C" {
|
||||
#define GLFW_HAND_CURSOR GLFW_POINTING_HAND_CURSOR
|
||||
/*! @} */
|
||||
|
||||
/*! @addtogroup window
|
||||
* @{ */
|
||||
/*! @brief Disable the progress bar.
|
||||
*
|
||||
* Disable the progress bar.
|
||||
*
|
||||
* Used by @ref window_progress_indicator.
|
||||
*/
|
||||
#define GLFW_PROGRESS_INDICATOR_DISABLED 0
|
||||
/*! @brief Display the progress bar in an indeterminate state.
|
||||
*
|
||||
* Display the progress bar in an indeterminate state.
|
||||
*
|
||||
* @remark @win32 This displays the progress bar animation cycling repeatedly.
|
||||
*
|
||||
* @remark @x11 @wayland This behaves like @ref GLFW_PROGRESS_INDICATOR_NORMAL.
|
||||
*
|
||||
* @remark @macos This displays a standard indeterminate `NSProgressIndicator`.
|
||||
*
|
||||
* Used by @ref window_progress_indicator.
|
||||
*/
|
||||
#define GLFW_PROGRESS_INDICATOR_INDETERMINATE 1
|
||||
/*! @brief Display the normal progress bar.
|
||||
*
|
||||
* Display the normal progress bar.
|
||||
*
|
||||
* Used by @ref window_progress_indicator.
|
||||
*/
|
||||
#define GLFW_PROGRESS_INDICATOR_NORMAL 2
|
||||
/*! @brief Display the progress bar in an error state.
|
||||
*
|
||||
* Display the progress bar in an error state.
|
||||
*
|
||||
* @remark @win32 This displays a red progress bar.
|
||||
*
|
||||
* @remark @x11 @wayland @macos This behaves like @ref GLFW_PROGRESS_INDICATOR_NORMAL.
|
||||
*
|
||||
* Used by @ref window_progress_indicator.
|
||||
*/
|
||||
#define GLFW_PROGRESS_INDICATOR_ERROR 3
|
||||
/*! @brief Display the progress bar in a paused state.
|
||||
*
|
||||
* Display the progress bar in a paused state.
|
||||
*
|
||||
* @remark @win32 This displays a yellow progress bar.
|
||||
*
|
||||
* @remark @x11 @wayland @macos This behaves like @ref GLFW_PROGRESS_INDICATOR_NORMAL.
|
||||
*
|
||||
* Used by @ref window_progress_indicator.
|
||||
*/
|
||||
#define GLFW_PROGRESS_INDICATOR_PAUSED 4
|
||||
/*! @} */
|
||||
|
||||
#define GLFW_CONNECTED 0x00040001
|
||||
#define GLFW_DISCONNECTED 0x00040002
|
||||
|
||||
@ -1629,7 +1682,7 @@ typedef void (* GLFWwindowposfun)(GLFWwindow* window, int xpos, int ypos);
|
||||
* @sa @ref glfwSetWindowSizeCallback
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -1649,7 +1702,7 @@ typedef void (* GLFWwindowsizefun)(GLFWwindow* window, int width, int height);
|
||||
* @sa @ref glfwSetWindowCloseCallback
|
||||
*
|
||||
* @since Added in version 2.5.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -1669,7 +1722,7 @@ typedef void (* GLFWwindowclosefun)(GLFWwindow* window);
|
||||
* @sa @ref glfwSetWindowRefreshCallback
|
||||
*
|
||||
* @since Added in version 2.5.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -1800,7 +1853,7 @@ typedef void (* GLFWwindowcontentscalefun)(GLFWwindow* window, float xscale, flo
|
||||
* @sa @ref glfwSetMouseButtonCallback
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle and modifier mask parameters.
|
||||
* __GLFW 3:__ Added window handle and modifier mask parameters.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -1891,7 +1944,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow* window, double xoffset, double yoffse
|
||||
* @sa @ref glfwSetKeyCallback
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle, scancode and modifier mask parameters.
|
||||
* __GLFW 3:__ Added window handle, scancode and modifier mask parameters.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -1912,7 +1965,7 @@ typedef void (* GLFWkeyfun)(GLFWwindow* window, int key, int scancode, int actio
|
||||
* @sa @ref glfwSetCharCallback
|
||||
*
|
||||
* @since Added in version 2.4.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -2020,7 +2073,7 @@ typedef void (* GLFWjoystickfun)(int jid, int event);
|
||||
* @sa @ref glfwGetVideoModes
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added refresh rate member.
|
||||
* __GLFW 3:__ Added refresh rate member.
|
||||
*
|
||||
* @ingroup monitor
|
||||
*/
|
||||
@ -2083,7 +2136,7 @@ typedef struct GLFWgammaramp
|
||||
* @sa @ref window_icon
|
||||
*
|
||||
* @since Added in version 2.1.
|
||||
* @glfw3 Removed format and bytes-per-pixel members.
|
||||
* __GLFW 3:__ Removed format and bytes-per-pixel members.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -2183,12 +2236,12 @@ typedef struct GLFWallocator
|
||||
* @errors Possible errors include @ref GLFW_PLATFORM_UNAVAILABLE and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @macos This function will change the current directory of the
|
||||
* @remark __macOS:__ This function will change the current directory of the
|
||||
* application to the `Contents/Resources` subdirectory of the application's
|
||||
* bundle, if present. This can be disabled with the @ref
|
||||
* GLFW_COCOA_CHDIR_RESOURCES init hint.
|
||||
*
|
||||
* @remark @macos This function will create the main menu and dock icon for the
|
||||
* @remark __macOS:__ This function will create the main menu and dock icon for the
|
||||
* application. If GLFW finds a `MainMenu.nib` it is loaded and assumed to
|
||||
* contain a menu bar. Otherwise a minimal menu bar is created manually with
|
||||
* common commands like Hide, Quit and About. The About entry opens a minimal
|
||||
@ -2203,7 +2256,7 @@ typedef struct GLFWallocator
|
||||
* to something other than `wayland` or `x11`, the regular detection mechanism
|
||||
* will be used instead.
|
||||
*
|
||||
* @remark @x11 This function will set the `LC_CTYPE` category of the
|
||||
* @remark __X11:__ This function will set the `LC_CTYPE` category of the
|
||||
* application locale according to the current environment if that category is
|
||||
* still "C". This is because the "C" locale breaks Unicode text input.
|
||||
*
|
||||
@ -2679,7 +2732,7 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos,
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
* @remark @win32 On Windows 8 and earlier the physical size is calculated from
|
||||
* @remark __Win32:__ On Windows 8 and earlier the physical size is calculated from
|
||||
* the current resolution and system DPI instead of querying the monitor EDID data.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -2713,7 +2766,7 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @wayland Fractional scaling information is not yet available for
|
||||
* @remark __Wayland:__ Fractional scaling information is not yet available for
|
||||
* monitors, so this function only returns integer content scales.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -2861,7 +2914,7 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun callback);
|
||||
* @sa @ref glfwGetVideoMode
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Changed to return an array of modes for a specific monitor.
|
||||
* __GLFW 3:__ Changed to return an array of modes for a specific monitor.
|
||||
*
|
||||
* @ingroup monitor
|
||||
*/
|
||||
@ -2915,8 +2968,8 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_INVALID_VALUE,
|
||||
* @ref GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland Gamma handling is a privileged protocol, this function
|
||||
* will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
* @remark __Wayland:__ Monitor gamma is a privileged protocol, so this function
|
||||
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
@ -2939,8 +2992,8 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR
|
||||
* and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland Gamma handling is a privileged protocol, this function
|
||||
* will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while
|
||||
* @remark __Wayland:__ Monitor gamma is a privileged protocol, so this function
|
||||
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while
|
||||
* returning `NULL`.
|
||||
*
|
||||
* @pointer_lifetime The returned structure and its arrays are allocated and
|
||||
@ -2981,10 +3034,10 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
|
||||
* @remark The size of the specified gamma ramp should match the size of the
|
||||
* current ramp for that monitor.
|
||||
*
|
||||
* @remark @win32 The gamma ramp size must be 256.
|
||||
* @remark __Win32:__ The gamma ramp size must be 256.
|
||||
*
|
||||
* @remark @wayland Gamma handling is a privileged protocol, this function
|
||||
* will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
* @remark __Wayland:__ Monitor gamma is a privileged protocol, so this function
|
||||
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @pointer_lifetime The specified gamma ramp is copied before this function
|
||||
* returns.
|
||||
@ -3159,32 +3212,32 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
|
||||
* GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE, @ref
|
||||
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @win32 Window creation will fail if the Microsoft GDI software
|
||||
* @remark __Win32:__ Window creation will fail if the Microsoft GDI software
|
||||
* OpenGL implementation is the only one available.
|
||||
*
|
||||
* @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it
|
||||
* @remark __Win32:__ If the executable has an icon resource named `GLFW_ICON,` it
|
||||
* will be set as the initial icon for the window. If no such icon is present,
|
||||
* the `IDI_APPLICATION` icon will be used instead. To set a different icon,
|
||||
* see @ref glfwSetWindowIcon.
|
||||
*
|
||||
* @remark @win32 The context to share resources with must not be current on
|
||||
* @remark __Win32:__ The context to share resources with must not be current on
|
||||
* any other thread.
|
||||
*
|
||||
* @remark @macos The OS only supports core profile contexts for OpenGL
|
||||
* @remark __macOS:__ The OS only supports core profile contexts for OpenGL
|
||||
* versions 3.2 and later. Before creating an OpenGL context of version 3.2 or
|
||||
* later you must set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint)
|
||||
* hint accordingly. OpenGL 3.0 and 3.1 contexts are not supported at all
|
||||
* on macOS.
|
||||
*
|
||||
* @remark @macos The GLFW window has no icon, as it is not a document
|
||||
* @remark __macOS:__ The GLFW window has no icon, as it is not a document
|
||||
* window, but the dock icon will be the same as the application bundle's icon.
|
||||
* For more information on bundles, see the
|
||||
* [Bundle Programming Guide][bundle-guide] in the Mac Developer Library.
|
||||
*
|
||||
* [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/
|
||||
*
|
||||
* @remark @macos The window frame will not be rendered at full resolution on
|
||||
* Retina displays unless the
|
||||
* @remark __macOS:__ The window frame will not be rendered at full resolution
|
||||
* on Retina displays unless the
|
||||
* [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint)
|
||||
* hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the
|
||||
* application bundle's `Info.plist`. For more information, see
|
||||
@ -3195,11 +3248,11 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
|
||||
*
|
||||
* [hidpi-guide]: https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
|
||||
*
|
||||
* @remark @macos When activating frame autosaving with
|
||||
* @remark __macOS:__ When activating frame autosaving with
|
||||
* [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified
|
||||
* window size and position may be overridden by previously saved values.
|
||||
*
|
||||
* @remark @wayland GLFW uses [libdecor][] where available to create its window
|
||||
* @remark __Wayland:__ GLFW uses [libdecor][] where available to create its window
|
||||
* decorations. This in turn uses server-side XDG decorations where available
|
||||
* and provides high quality client-side decorations on compositors like GNOME.
|
||||
* If both XDG decorations and libdecor are unavailable, GLFW falls back to
|
||||
@ -3208,15 +3261,15 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
|
||||
*
|
||||
* [libdecor]: https://gitlab.freedesktop.org/libdecor/libdecor
|
||||
*
|
||||
* @remark @x11 Some window managers will not respect the placement of
|
||||
* @remark __X11:__ Some window managers will not respect the placement of
|
||||
* initially hidden windows.
|
||||
*
|
||||
* @remark @x11 Due to the asynchronous nature of X11, it may take a moment for
|
||||
* @remark __X11:__ Due to the asynchronous nature of X11, it may take a moment for
|
||||
* a window to reach its requested state. This means you may not be able to
|
||||
* query the final size, position or other attributes directly after window
|
||||
* creation.
|
||||
*
|
||||
* @remark @x11 The class part of the `WM_CLASS` window property will by
|
||||
* @remark __X11:__ The class part of the `WM_CLASS` window property will by
|
||||
* default be set to the window title passed to this function. The instance
|
||||
* part will use the contents of the `RESOURCE_NAME` environment variable, if
|
||||
* present and not empty, or fall back to the window title. Set the
|
||||
@ -3349,7 +3402,7 @@ GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @macos The window title will not be updated until the next time you
|
||||
* @remark __macOS:__ The window title will not be updated until the next time you
|
||||
* process events.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -3358,7 +3411,7 @@ GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window);
|
||||
* @sa @ref glfwGetWindowTitle
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -3392,14 +3445,14 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
|
||||
* @pointer_lifetime The specified image data is copied before this function
|
||||
* returns.
|
||||
*
|
||||
* @remark @macos Regular windows do not have icons on macOS. This function
|
||||
* @remark __macOS:__ Regular windows do not have icons on macOS. This function
|
||||
* will emit @ref GLFW_FEATURE_UNAVAILABLE. The dock icon will be the same as
|
||||
* the application bundle's icon. For more information on bundles, see the
|
||||
* [Bundle Programming Guide][bundle-guide] in the Mac Developer Library.
|
||||
*
|
||||
* [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/
|
||||
*
|
||||
* @remark @wayland There is no existing protocol to change an icon, the
|
||||
* @remark __Wayland:__ There is no existing protocol to change an icon, the
|
||||
* window will thus inherit the one defined in the application's desktop file.
|
||||
* This function will emit @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
@ -3413,6 +3466,46 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
|
||||
*/
|
||||
GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images);
|
||||
|
||||
/*! @brief Sets the dock or taskbar progress indicator for the specified window.
|
||||
*
|
||||
* This function sets the dock or taskbar progress indicator of the specified window.
|
||||
*
|
||||
* @param[in] window The window whose progress to set.
|
||||
* @param[in] progressState The state of the progress to be displayed in the dock
|
||||
* or taskbar. Valid values are: @ref GLFW_PROGRESS_INDICATOR_DISABLED,
|
||||
* @ref GLFW_PROGRESS_INDICATOR_INDETERMINATE, @ref GLFW_PROGRESS_INDICATOR_NORMAL,
|
||||
* @ref GLFW_PROGRESS_INDICATOR_ERROR and @ref GLFW_PROGRESS_INDICATOR_PAUSED.
|
||||
* @param[in] value The amount of completed progress to set. Valid range is 0.0 to 1.0.
|
||||
* This is ignored if progressState is set to @ref GLFW_PROGRESS_INDICATOR_DISABLED.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_VALUE, @ref GLFW_INVALID_ENUM, @ref GLFW_PLATFORM_ERROR,
|
||||
* @ref GLFW_FEATURE_UNIMPLEMENTED and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @win32 On Windows Vista and earlier, this function will emit
|
||||
* @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @remark @macos There exists only one Dock icon progress bar, and this
|
||||
* displays the combined values of all the windows.
|
||||
*
|
||||
* @remark @x11 @wayland Requires a valid application desktop file with the same name
|
||||
* as the compiled executable. Due to limitations in the Unity Launcher API
|
||||
* @ref GLFW_PROGRESS_INDICATOR_INDETERMINATE, @ref GLFW_PROGRESS_INDICATOR_ERROR
|
||||
* and @ref GLFW_PROGRESS_INDICATOR_PAUSED have the same behaviour as
|
||||
* @ref GLFW_PROGRESS_INDICATOR_NORMAL. The Unity Launcher API is only known
|
||||
* to be supported on the Unity and KDE desktop environments; on other desktop
|
||||
* environments this function may do nothing.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref window_progress_indicator
|
||||
*
|
||||
* @since Added in version 3.4.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
GLFWAPI void glfwSetWindowProgressIndicator(GLFWwindow* window, int progressState, double value);
|
||||
|
||||
/*! @brief Retrieves the position of the content area of the specified window.
|
||||
*
|
||||
* This function retrieves the position, in screen coordinates, of the
|
||||
@ -3430,8 +3523,8 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* i
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland There is no way for an application to retrieve the global
|
||||
* position of its windows. This function will emit @ref
|
||||
* @remark __Wayland:__ Window positions are not currently part of any common
|
||||
* Wayland protocol, so this function cannot be implemented and will emit @ref
|
||||
* GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -3464,8 +3557,8 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland There is no way for an application to set the global
|
||||
* position of its windows. This function will emit @ref
|
||||
* @remark __Wayland:__ Window positions are not currently part of any common
|
||||
* Wayland protocol, so this function cannot be implemented and will emit @ref
|
||||
* GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -3474,7 +3567,7 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
|
||||
* @sa @ref glfwGetWindowPos
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -3504,7 +3597,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
|
||||
* @sa @ref glfwSetWindowSize
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -3539,7 +3632,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
|
||||
* @remark If you set size limits and an aspect ratio that conflict, the
|
||||
* results are undefined.
|
||||
*
|
||||
* @remark @wayland The size limits will not be applied until the window is
|
||||
* @remark __Wayland:__ The size limits will not be applied until the window is
|
||||
* actually resized, either by the user or by the compositor.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -3582,7 +3675,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe
|
||||
* @remark If you set size limits and an aspect ratio that conflict, the
|
||||
* results are undefined.
|
||||
*
|
||||
* @remark @wayland The aspect ratio will not be applied until the window is
|
||||
* @remark __Wayland:__ The aspect ratio will not be applied until the window is
|
||||
* actually resized, either by the user or by the compositor.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -3628,7 +3721,7 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
|
||||
* @sa @ref glfwSetWindowMonitor
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -3778,7 +3871,7 @@ GLFWAPI float glfwGetWindowOpacity(GLFWwindow* window);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland There is no way to set an opacity factor for a window.
|
||||
* @remark __Wayland:__ There is no way to set an opacity factor for a window.
|
||||
* This function will emit @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -3807,10 +3900,6 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @wayland Once a window is iconified, @ref glfwRestoreWindow won’t
|
||||
* be able to restore it. This is a design decision of the xdg-shell
|
||||
* protocol.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref window_iconify
|
||||
@ -3818,7 +3907,7 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity);
|
||||
* @sa @ref glfwMaximizeWindow
|
||||
*
|
||||
* @since Added in version 2.1.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -3838,6 +3927,10 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark __Wayland:__ Restoring a window from maximization is not currently
|
||||
* part of any common Wayland protocol, so this function can only restore
|
||||
* windows from maximization.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref window_iconify
|
||||
@ -3845,7 +3938,7 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
|
||||
* @sa @ref glfwMaximizeWindow
|
||||
*
|
||||
* @since Added in version 2.1.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -3892,7 +3985,7 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @wayland Because Wayland wants every frame of the desktop to be
|
||||
* @remark __Wayland:__ Because Wayland wants every frame of the desktop to be
|
||||
* complete, this function does not immediately make the window visible.
|
||||
* Instead it will become visible the next time the window framebuffer is
|
||||
* updated after this call.
|
||||
@ -3955,7 +4048,7 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @wayland The compositor will likely ignore focus requests unless
|
||||
* @remark __Wayland:__ The compositor will likely ignore focus requests unless
|
||||
* another window created by the same application already has input focus.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -3983,7 +4076,7 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* window);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @macos Attention is requested to the application as a whole, not the
|
||||
* @remark __macOS:__ Attention is requested to the application as a whole, not the
|
||||
* specific window.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -4058,8 +4151,8 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
|
||||
* affected by any resizing or mode switching, although you may need to update
|
||||
* your viewport if the framebuffer size has changed.
|
||||
*
|
||||
* @remark @wayland The desired window position is ignored, as there is no way
|
||||
* for an application to set this property.
|
||||
* @remark __Wayland:__ Window positions are not currently part of any common
|
||||
* Wayland protocol. The window position arguments are ignored.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
@ -4096,8 +4189,9 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int
|
||||
* errors. However, this function should not fail as long as it is passed
|
||||
* valid arguments and the library has been [initialized](@ref intro_init).
|
||||
*
|
||||
* @remark @wayland The Wayland protocol provides no way to check whether a
|
||||
* window is iconfied, so @ref GLFW_ICONIFIED always returns `GLFW_FALSE`.
|
||||
* @remark __Wayland:__ Checking whether a window is iconified is not currently
|
||||
* part of any common Wayland protocol, so the @ref GLFW_ICONIFIED attribute
|
||||
* cannot be implemented and is always `GLFW_FALSE`.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
@ -4139,7 +4233,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
|
||||
* @remark Calling @ref glfwGetWindowAttrib will always return the latest
|
||||
* value, even if that value is ignored by the current mode of the window.
|
||||
*
|
||||
* @remark @wayland The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window attribute is
|
||||
* @remark __Wayland:__ The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window attribute is
|
||||
* not supported. Setting this will emit @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -4219,8 +4313,8 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
* @remark @wayland This callback will never be called, as there is no way for
|
||||
* an application to know its global position.
|
||||
* @remark __Wayland:__ This callback will not be called. The Wayland protocol
|
||||
* provides no way to be notified of when a window is moved.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
@ -4258,7 +4352,7 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindow
|
||||
* @sa @ref window_size
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter and return value.
|
||||
* __GLFW 3:__ Added window handle parameter and return value.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -4290,7 +4384,7 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
* @remark @macos Selecting Quit from the application menu will trigger the
|
||||
* @remark __macOS:__ Selecting Quit from the application menu will trigger the
|
||||
* close callback for all windows.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -4298,7 +4392,7 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind
|
||||
* @sa @ref window_close
|
||||
*
|
||||
* @since Added in version 2.5.
|
||||
* @glfw3 Added window handle parameter and return value.
|
||||
* __GLFW 3:__ Added window handle parameter and return value.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -4334,7 +4428,7 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi
|
||||
* @sa @ref window_refresh
|
||||
*
|
||||
* @since Added in version 2.5.
|
||||
* @glfw3 Added window handle parameter and return value.
|
||||
* __GLFW 3:__ Added window handle parameter and return value.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -4395,6 +4489,10 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
* @remark __Wayland:__ This callback will not be called. The Wayland protocol
|
||||
* provides no way to be notified of when a window is iconified, and no way to
|
||||
* check whether a window is currently iconified.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref window_iconify
|
||||
@ -4900,7 +4998,7 @@ GLFWAPI int glfwGetKeyScancode(int key);
|
||||
* @sa @ref input_key
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -4932,7 +5030,7 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
|
||||
* @sa @ref input_mouse_button
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -5002,7 +5100,7 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland This function will only work when the cursor mode is
|
||||
* @remark __Wayland:__ This function will only work when the cursor mode is
|
||||
* `GLFW_CURSOR_DISABLED`, otherwise it will emit @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -5200,7 +5298,7 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
|
||||
* @sa @ref input_key
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter and return value.
|
||||
* __GLFW 3:__ Added window handle parameter and return value.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -5243,7 +5341,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun callback);
|
||||
* @sa @ref input_char
|
||||
*
|
||||
* @since Added in version 2.4.
|
||||
* @glfw3 Added window handle parameter and return value.
|
||||
* __GLFW 3:__ Added window handle parameter and return value.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -5327,7 +5425,7 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods
|
||||
* @sa @ref input_mouse_button
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter and return value.
|
||||
* __GLFW 3:__ Added window handle parameter and return value.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -5557,7 +5655,7 @@ GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count);
|
||||
* @sa @ref joystick_button
|
||||
*
|
||||
* @since Added in version 2.2.
|
||||
* @glfw3 Changed to return a dynamic array.
|
||||
* __GLFW 3:__ Changed to return a dynamic array.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
@ -5921,7 +6019,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @win32 The clipboard on Windows has a single global lock for reading and
|
||||
* @remark __Win32:__ The clipboard on Windows has a single global lock for reading and
|
||||
* writing. GLFW tries to acquire it a few times, which is almost always enough. If it
|
||||
* cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns.
|
||||
* It is safe to try this multiple times.
|
||||
@ -5954,7 +6052,7 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_FORMAT_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @win32 The clipboard on Windows has a single global lock for reading and
|
||||
* @remark __Win32:__ The clipboard on Windows has a single global lock for reading and
|
||||
* writing. GLFW tries to acquire it a few times, which is almost always enough. If it
|
||||
* cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns.
|
||||
* It is safe to try this multiple times.
|
||||
@ -6171,7 +6269,7 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void);
|
||||
* @sa @ref glfwSwapInterval
|
||||
*
|
||||
* @since Added in version 1.0.
|
||||
* @glfw3 Added window handle parameter.
|
||||
* __GLFW 3:__ Added window handle parameter.
|
||||
*
|
||||
* @ingroup window
|
||||
*/
|
||||
@ -6438,7 +6536,7 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* p
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @macos This function currently always returns `GLFW_TRUE`, as the
|
||||
* @remark __macOS:__ This function currently always returns `GLFW_TRUE`, as the
|
||||
* `VK_MVK_macos_surface` and `VK_EXT_metal_surface` extensions do not provide
|
||||
* a `vkGetPhysicalDevice*PresentationSupport` type function.
|
||||
*
|
||||
@ -6496,15 +6594,15 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhys
|
||||
* @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should
|
||||
* eliminate almost all occurrences of these errors.
|
||||
*
|
||||
* @remark @macos GLFW prefers the `VK_EXT_metal_surface` extension, with the
|
||||
* @remark __macOS:__ GLFW prefers the `VK_EXT_metal_surface` extension, with the
|
||||
* `VK_MVK_macos_surface` extension as a fallback. The name of the selected
|
||||
* extension, if any, is included in the array returned by @ref
|
||||
* glfwGetRequiredInstanceExtensions.
|
||||
*
|
||||
* @remark @macos This function creates and sets a `CAMetalLayer` instance for
|
||||
* @remark __macOS:__ This function creates and sets a `CAMetalLayer` instance for
|
||||
* the window content view, which is required for MoltenVK to function.
|
||||
*
|
||||
* @remark @x11 By default GLFW prefers the `VK_KHR_xcb_surface` extension,
|
||||
* @remark __X11:__ By default GLFW prefers the `VK_KHR_xcb_surface` extension,
|
||||
* with the `VK_KHR_xlib_surface` extension as a fallback. You can make
|
||||
* `VK_KHR_xlib_surface` the preferred extension by setting the
|
||||
* [GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init
|
||||
|
||||
@ -478,6 +478,29 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
|
||||
|
||||
/*! @brief Retrieves the `GLXFBConfig` of the specified window's `GLXWindow`.
|
||||
*
|
||||
* @param[in] window The window whose `GLXWindow` to query.
|
||||
* @param[out] config The `GLXFBConfig` of the window `GLXWindow`, if available.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE.
|
||||
*
|
||||
* @remark `GLXFBConfig` is an opaque type. Unlike other GLFW functions, the
|
||||
* @p config out parameter is not cleared on error, as core GLX does not define
|
||||
* any invalid value.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.5
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI int glfwGetGLXFBConfig(GLFWwindow* window, GLXFBConfig* config);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||
@ -586,6 +609,29 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
|
||||
|
||||
/*! @brief Retrieves the `EGLConfig` of the specified window's `EGLSurface`.
|
||||
*
|
||||
* @param[in] window The window whose `EGLSurface` to query.
|
||||
* @param[out] config The `EGLConfig` of the window `EGLSurface`, if available.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_NO_WINDOW_CONTEXT.
|
||||
*
|
||||
* @remark `EGLConfig` is an opaque type. Unlike other GLFW functions, the @p
|
||||
* config out parameter is not cleared on error, as core EGL does not define
|
||||
* any invalid value.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.5.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI int glfwGetEGLConfig(GLFWwindow* window, EGLConfig* config);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||
|
||||
@ -17,7 +17,8 @@ elseif (WIN32)
|
||||
win32_time.c win32_thread.c)
|
||||
else()
|
||||
target_sources(glfw PRIVATE posix_time.h posix_thread.h posix_module.c
|
||||
posix_time.c posix_thread.c)
|
||||
posix_time.c posix_thread.c posix_dbus.h
|
||||
posix_dbus.c)
|
||||
endif()
|
||||
|
||||
add_custom_target(update_mappings
|
||||
@ -255,24 +256,6 @@ if (GLFW_BUILD_WIN32)
|
||||
target_compile_definitions(glfw PRIVATE UNICODE _UNICODE)
|
||||
endif()
|
||||
|
||||
# HACK: When building on MinGW, WINVER and UNICODE need to be defined before
|
||||
# the inclusion of stddef.h (by glfw3.h), which is itself included before
|
||||
# win32_platform.h. We define them here until a saner solution can be found
|
||||
# NOTE: MinGW-w64 and Visual C++ do /not/ need this hack.
|
||||
if (MINGW)
|
||||
target_compile_definitions(glfw PRIVATE WINVER=0x0501)
|
||||
endif()
|
||||
|
||||
# Workaround for legacy MinGW not providing XInput and DirectInput
|
||||
if (MINGW)
|
||||
include(CheckIncludeFile)
|
||||
check_include_file(dinput.h DINPUT_H_FOUND)
|
||||
check_include_file(xinput.h XINPUT_H_FOUND)
|
||||
if (NOT DINPUT_H_FOUND OR NOT XINPUT_H_FOUND)
|
||||
target_include_directories(glfw PRIVATE "${GLFW_SOURCE_DIR}/deps/mingw")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Workaround for the MS CRT deprecating parts of the standard library
|
||||
if (MSVC OR CMAKE_C_SIMULATE_ID STREQUAL "MSVC")
|
||||
target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||
@ -286,10 +269,6 @@ endif()
|
||||
if (GLFW_BUILD_SHARED_LIBRARY)
|
||||
if (WIN32)
|
||||
if (MINGW)
|
||||
# Remove the dependency on the shared version of libgcc
|
||||
# NOTE: MinGW-w64 has the correct default but MinGW needs this
|
||||
target_link_libraries(glfw PRIVATE "-static-libgcc")
|
||||
|
||||
# Remove the lib prefix on the DLL (but not the import library)
|
||||
set_target_properties(glfw PROPERTIES PREFIX "")
|
||||
|
||||
|
||||
@ -526,6 +526,7 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
|
||||
.destroyWindow = _glfwDestroyWindowCocoa,
|
||||
.setWindowTitle = _glfwSetWindowTitleCocoa,
|
||||
.setWindowIcon = _glfwSetWindowIconCocoa,
|
||||
.setWindowProgressIndicator = _glfwSetWindowProgressIndicatorCocoa,
|
||||
.getWindowPos = _glfwGetWindowPosCocoa,
|
||||
.setWindowPos = _glfwSetWindowPosCocoa,
|
||||
.getWindowSize = _glfwGetWindowSizeCocoa,
|
||||
@ -646,6 +647,12 @@ int _glfwInitCocoa(void)
|
||||
void _glfwTerminateCocoa(void)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
if (_glfw.ns.dockProgressIndicator.view != nil)
|
||||
{
|
||||
[_glfw.ns.dockProgressIndicator.view removeFromSuperview];
|
||||
[_glfw.ns.dockProgressIndicator.view release];
|
||||
}
|
||||
|
||||
if (_glfw.ns.inputSource)
|
||||
{
|
||||
|
||||
@ -156,6 +156,11 @@ typedef struct _GLFWwindowNS
|
||||
// since the last cursor motion event was processed
|
||||
// This is kept to counteract Cocoa doing the same internally
|
||||
double cursorWarpDeltaX, cursorWarpDeltaY;
|
||||
|
||||
struct {
|
||||
int state;
|
||||
double value;
|
||||
} dockProgressIndicator;
|
||||
} _GLFWwindowNS;
|
||||
|
||||
// Cocoa-specific global data
|
||||
@ -189,6 +194,13 @@ typedef struct _GLFWlibraryNS
|
||||
PFN_LMGetKbdType GetKbdType;
|
||||
CFStringRef kPropertyUnicodeKeyLayoutData;
|
||||
} tis;
|
||||
|
||||
struct {
|
||||
id view;
|
||||
int windowCount;
|
||||
int indeterminateCount;
|
||||
double totalValue;
|
||||
} dockProgressIndicator;
|
||||
} _GLFWlibraryNS;
|
||||
|
||||
// Cocoa-specific per-monitor data
|
||||
@ -218,6 +230,7 @@ GLFWbool _glfwCreateWindowCocoa(_GLFWwindow* window, const _GLFWwndconfig* wndco
|
||||
void _glfwDestroyWindowCocoa(_GLFWwindow* window);
|
||||
void _glfwSetWindowTitleCocoa(_GLFWwindow* window, const char* title);
|
||||
void _glfwSetWindowIconCocoa(_GLFWwindow* window, int count, const GLFWimage* images);
|
||||
void _glfwSetWindowProgressIndicatorCocoa(_GLFWwindow* window, int progressState, double value);
|
||||
void _glfwGetWindowPosCocoa(_GLFWwindow* window, int* xpos, int* ypos);
|
||||
void _glfwSetWindowPosCocoa(_GLFWwindow* window, int xpos, int ypos);
|
||||
void _glfwGetWindowSizeCocoa(_GLFWwindow* window, int* width, int* height);
|
||||
|
||||
@ -198,6 +198,83 @@ static NSUInteger translateKeyToModifierFlag(int key)
|
||||
//
|
||||
static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
|
||||
static NSProgressIndicator* createProgressIndicator(const NSDockTile* dockTile)
|
||||
{
|
||||
NSView* contentView = [dockTile contentView];
|
||||
|
||||
NSProgressIndicator* indicator = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(0.0f, 0.0f, contentView.frame.size.width, 15.0f)];
|
||||
|
||||
[indicator setStyle:NSProgressIndicatorStyleBar];
|
||||
|
||||
if (@available(macOS 11.0, *))
|
||||
{
|
||||
[indicator setControlSize:NSControlSizeLarge];
|
||||
}
|
||||
|
||||
[indicator setMinValue:0.0f];
|
||||
[indicator setMaxValue:1.0f];
|
||||
|
||||
[indicator sizeToFit];
|
||||
|
||||
[contentView addSubview:indicator];
|
||||
|
||||
_glfw.ns.dockProgressIndicator.view = indicator;
|
||||
|
||||
return indicator;
|
||||
}
|
||||
|
||||
static void setDockProgressIndicator(int progressState, double value)
|
||||
{
|
||||
NSProgressIndicator* indicator = _glfw.ns.dockProgressIndicator.view;
|
||||
|
||||
NSDockTile* dockTile = [[NSApplication sharedApplication] dockTile];
|
||||
|
||||
if (indicator == nil)
|
||||
{
|
||||
if ([dockTile contentView] == nil)
|
||||
{
|
||||
NSImageView *iconView = [[NSImageView alloc] init];
|
||||
[iconView setImage:[[NSApplication sharedApplication] applicationIconImage]];
|
||||
[dockTile setContentView:iconView];
|
||||
[iconView release];
|
||||
}
|
||||
|
||||
indicator = createProgressIndicator(dockTile);
|
||||
}
|
||||
|
||||
// ### Switching from INDETERMINATE to NORMAL, PAUSED or ERROR requires 2 invocations in different frames.
|
||||
// In MacOS 12 (and probably other versions), an indeterminate progress bar is rendered as a normal bar
|
||||
// with 0.0 progress. So when calling [progressIndicator setIndeterminate:YES], the indicator actually
|
||||
// sets its doubleValue to 0.0.
|
||||
// The bug is caused by NSProgressIndicator not immediately updating its value when it's increasing.
|
||||
// This code illustrates the exact same problem, but this time from NORMAL, PAUSED and ERROR to INDETERMINATE:
|
||||
//
|
||||
// if (progressState == GLFW_PROGRESS_INDICATOR_INDETERMINATE)
|
||||
// [progressIndicator setDoubleValue:0.75];
|
||||
// else
|
||||
// [progressIndicator setDoubleValue:0.25];
|
||||
//
|
||||
// This is likely a bug in Cocoa.
|
||||
//
|
||||
// ### Progress increments are delayed
|
||||
// What this also means, is that each time the progress increments, the bar's progress will be 1 frame delayed,
|
||||
// and only updated once a higher or similar value is again set the next frame.
|
||||
|
||||
// Workaround for the aforementioned issues. If there's any versions of MacOS where
|
||||
// this issue is not present, this should be ommitted in those versions.
|
||||
if ([indicator isIndeterminate] || [indicator doubleValue] < value)
|
||||
{
|
||||
[indicator removeFromSuperview];
|
||||
[indicator release];
|
||||
indicator = createProgressIndicator(dockTile);
|
||||
}
|
||||
|
||||
[indicator setIndeterminate:progressState == GLFW_PROGRESS_INDICATOR_INDETERMINATE];
|
||||
[indicator setHidden:progressState == GLFW_PROGRESS_INDICATOR_DISABLED];
|
||||
[indicator setDoubleValue:value];
|
||||
|
||||
[dockTile display];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Delegate for window related notifications
|
||||
@ -884,7 +961,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
|
||||
[window->ns.object setContentView:window->ns.view];
|
||||
[window->ns.object makeFirstResponder:window->ns.view];
|
||||
[window->ns.object setTitle:@(wndconfig->title)];
|
||||
[window->ns.object setTitle:@(window->title)];
|
||||
[window->ns.object setDelegate:window->ns.delegate];
|
||||
[window->ns.object setAcceptsMouseMovedEvents:YES];
|
||||
[window->ns.object setRestorable:NO];
|
||||
@ -990,6 +1067,8 @@ GLFWbool _glfwCreateWindowCocoa(_GLFWwindow* window,
|
||||
void _glfwDestroyWindowCocoa(_GLFWwindow* window)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
_glfwSetWindowProgressIndicatorCocoa(window, GLFW_PROGRESS_INDICATOR_DISABLED, 0.0);
|
||||
|
||||
if (_glfw.ns.disabledCursorWindow == window)
|
||||
_glfw.ns.disabledCursorWindow = NULL;
|
||||
@ -1036,6 +1115,62 @@ void _glfwSetWindowIconCocoa(_GLFWwindow* window,
|
||||
"Cocoa: Regular windows do not have icons on macOS");
|
||||
}
|
||||
|
||||
void _glfwSetWindowProgressIndicatorCocoa(_GLFWwindow* window, int progressState, double value)
|
||||
{
|
||||
if (progressState == GLFW_PROGRESS_INDICATOR_ERROR || progressState == GLFW_PROGRESS_INDICATOR_PAUSED)
|
||||
progressState = GLFW_PROGRESS_INDICATOR_NORMAL;
|
||||
|
||||
const int oldState = window->ns.dockProgressIndicator.state;
|
||||
const int state = progressState;
|
||||
|
||||
const double oldValue = window->ns.dockProgressIndicator.value;
|
||||
|
||||
if (oldState == state)
|
||||
{
|
||||
if (state == GLFW_PROGRESS_INDICATOR_DISABLED ||
|
||||
state == GLFW_PROGRESS_INDICATOR_INDETERMINATE ||
|
||||
oldValue == value)
|
||||
return;
|
||||
}
|
||||
|
||||
if (oldState != state)
|
||||
{
|
||||
// Reset
|
||||
if (oldState == GLFW_PROGRESS_INDICATOR_INDETERMINATE)
|
||||
--_glfw.ns.dockProgressIndicator.indeterminateCount;
|
||||
if (oldState != GLFW_PROGRESS_INDICATOR_DISABLED)
|
||||
{
|
||||
--_glfw.ns.dockProgressIndicator.windowCount;
|
||||
_glfw.ns.dockProgressIndicator.totalValue -= oldValue;
|
||||
}
|
||||
|
||||
// Set
|
||||
if (state == GLFW_PROGRESS_INDICATOR_INDETERMINATE)
|
||||
++_glfw.ns.dockProgressIndicator.indeterminateCount;
|
||||
if (state != GLFW_PROGRESS_INDICATOR_DISABLED)
|
||||
{
|
||||
++_glfw.ns.dockProgressIndicator.windowCount;
|
||||
_glfw.ns.dockProgressIndicator.totalValue += value;
|
||||
}
|
||||
}
|
||||
else if (state != GLFW_PROGRESS_INDICATOR_DISABLED)
|
||||
_glfw.ns.dockProgressIndicator.totalValue += (value - oldValue);
|
||||
|
||||
|
||||
if (_glfw.ns.dockProgressIndicator.windowCount > _glfw.ns.dockProgressIndicator.indeterminateCount)
|
||||
{
|
||||
const double finalValue = _glfw.ns.dockProgressIndicator.totalValue / _glfw.ns.dockProgressIndicator.windowCount;
|
||||
setDockProgressIndicator(GLFW_PROGRESS_INDICATOR_NORMAL, finalValue);
|
||||
}
|
||||
else if (_glfw.ns.dockProgressIndicator.indeterminateCount > 0)
|
||||
setDockProgressIndicator(GLFW_PROGRESS_INDICATOR_INDETERMINATE, 0.0f);
|
||||
else
|
||||
setDockProgressIndicator(GLFW_PROGRESS_INDICATOR_DISABLED, 0.0f);
|
||||
|
||||
window->ns.dockProgressIndicator.state = state;
|
||||
window->ns.dockProgressIndicator.value = value;
|
||||
}
|
||||
|
||||
void _glfwGetWindowPosCocoa(_GLFWwindow* window, int* xpos, int* ypos)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
@ -939,10 +939,32 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
|
||||
window->context.source != GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return EGL_NO_CONTEXT;
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
}
|
||||
|
||||
return window->context.egl.surface;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetEGLConfig(GLFWwindow* handle, EGLConfig* config)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
assert(config != NULL);
|
||||
|
||||
if (window->context.source != GLFW_EGL_CONTEXT_API)
|
||||
{
|
||||
if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND ||
|
||||
window->context.source != GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
*config = window->context.egl.config;
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -626,6 +626,8 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
window->context.glx.fbconfig = native;
|
||||
|
||||
window->context.makeCurrent = makeContextCurrentGLX;
|
||||
window->context.swapBuffers = swapBuffersGLX;
|
||||
window->context.swapInterval = swapIntervalGLX;
|
||||
@ -719,5 +721,29 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
|
||||
return window->context.glx.window;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetGLXFBConfig(GLFWwindow* handle, GLXFBConfig* config)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
|
||||
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "GLX: Platform not initialized");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
assert(config != NULL);
|
||||
|
||||
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
*config = window->context.glx.fbconfig;
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
#endif // _GLFW_X11
|
||||
|
||||
|
||||
@ -402,7 +402,6 @@ struct _GLFWwndconfig
|
||||
int ypos;
|
||||
int width;
|
||||
int height;
|
||||
const char* title;
|
||||
GLFWbool resizable;
|
||||
GLFWbool visible;
|
||||
GLFWbool decorated;
|
||||
@ -718,6 +717,7 @@ struct _GLFWplatform
|
||||
void (*destroyWindow)(_GLFWwindow*);
|
||||
void (*setWindowTitle)(_GLFWwindow*,const char*);
|
||||
void (*setWindowIcon)(_GLFWwindow*,int,const GLFWimage*);
|
||||
void (*setWindowProgressIndicator)(_GLFWwindow*,const int,double);
|
||||
void (*getWindowPos)(_GLFWwindow*,int*,int*);
|
||||
void (*setWindowPos)(_GLFWwindow*,int,int);
|
||||
void (*getWindowSize)(_GLFWwindow*,int*,int*);
|
||||
@ -884,6 +884,7 @@ struct _GLFWlibrary
|
||||
GLFW_PLATFORM_LIBRARY_WINDOW_STATE
|
||||
GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
||||
GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE
|
||||
GLFW_PLATFORM_LIBRARY_DBUS_STATE
|
||||
};
|
||||
|
||||
// Global state shared between compilation units of GLFW
|
||||
|
||||
@ -72,6 +72,7 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
|
||||
.destroyWindow = _glfwDestroyWindowNull,
|
||||
.setWindowTitle = _glfwSetWindowTitleNull,
|
||||
.setWindowIcon = _glfwSetWindowIconNull,
|
||||
.setWindowProgressIndicator = _glfwSetWindowProgressIndicatorNull,
|
||||
.getWindowPos = _glfwGetWindowPosNull,
|
||||
.setWindowPos = _glfwSetWindowPosNull,
|
||||
.getWindowSize = _glfwGetWindowSizeNull,
|
||||
|
||||
@ -223,6 +223,7 @@ GLFWbool _glfwCreateWindowNull(_GLFWwindow* window, const _GLFWwndconfig* wndcon
|
||||
void _glfwDestroyWindowNull(_GLFWwindow* window);
|
||||
void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title);
|
||||
void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* images);
|
||||
void _glfwSetWindowProgressIndicatorNull(_GLFWwindow* window, int progressState, double value);
|
||||
void _glfwSetWindowMonitorNull(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
|
||||
void _glfwGetWindowPosNull(_GLFWwindow* window, int* xpos, int* ypos);
|
||||
void _glfwSetWindowPosNull(_GLFWwindow* window, int xpos, int ypos);
|
||||
|
||||
@ -186,6 +186,10 @@ void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* ima
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwSetWindowProgressIndicatorNull(_GLFWwindow* window, int progressState, double value)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwSetWindowMonitorNull(_GLFWwindow* window,
|
||||
_GLFWmonitor* monitor,
|
||||
int xpos, int ypos,
|
||||
|
||||
@ -187,8 +187,6 @@ GLFWAPI const char* glfwGetVersionString(void)
|
||||
" OSMesa"
|
||||
#if defined(__MINGW64_VERSION_MAJOR)
|
||||
" MinGW-w64"
|
||||
#elif defined(__MINGW32__)
|
||||
" MinGW"
|
||||
#elif defined(_MSC_VER)
|
||||
" VisualC"
|
||||
#endif
|
||||
|
||||
@ -187,6 +187,7 @@
|
||||
#define GLFW_BUILD_COCOA_TIMER
|
||||
#else
|
||||
#define GLFW_BUILD_POSIX_TIMER
|
||||
#define GLFW_BUILD_POSIX_DBUS
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_BUILD_WIN32_TIMER)
|
||||
@ -200,6 +201,13 @@
|
||||
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_POSIX_LIBRARY_TIMER_STATE
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_BUILD_POSIX_DBUS)
|
||||
#include "posix_dbus.h"
|
||||
#define GLFW_PLATFORM_LIBRARY_DBUS_STATE GLFW_POSIX_LIBRARY_DBUS_STATE
|
||||
#else
|
||||
#define GLFW_PLATFORM_LIBRARY_DBUS_STATE
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define GLFW_BUILD_WIN32_MODULE
|
||||
#else
|
||||
|
||||
519
src/posix_dbus.c
Normal file
519
src/posix_dbus.c
Normal file
@ -0,0 +1,519 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 POSIX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2023 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
void _glfwInitDBusPOSIX(void)
|
||||
{
|
||||
//Initialize DBus library functions
|
||||
_glfw.dbus.handle = NULL;
|
||||
_glfw.dbus.connection = NULL;
|
||||
|
||||
_glfw.dbus.handle = _glfwPlatformLoadModule("libdbus-1.so.3");
|
||||
if (!_glfw.dbus.handle)
|
||||
return;
|
||||
|
||||
_glfw.dbus.error_init = (PFN_dbus_error_init)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.dbus.handle, "dbus_error_init");
|
||||
_glfw.dbus.error_is_set = (PFN_dbus_error_is_set)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.dbus.handle, "dbus_error_is_set");
|
||||
_glfw.dbus.error_free = (PFN_dbus_error_free)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.dbus.handle, "dbus_error_free");
|
||||
_glfw.dbus.connection_unref = (PFN_dbus_connection_unref)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.dbus.handle, "dbus_connection_unref");
|
||||
_glfw.dbus.connection_send = (PFN_dbus_connection_send)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.dbus.handle, "dbus_connection_send");
|
||||
_glfw.dbus.connection_flush = (PFN_dbus_connection_flush)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.dbus.handle, "dbus_connection_flush");
|
||||
_glfw.dbus.bus_request_name = (PFN_dbus_bus_request_name)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.dbus.handle, "dbus_bus_request_name");
|
||||
_glfw.dbus.bus_get = (PFN_dbus_bus_get)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.dbus.handle, "dbus_bus_get");
|
||||
_glfw.dbus.message_unref = (PFN_dbus_message_unref)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.dbus.handle, "dbus_message_unref");
|
||||
_glfw.dbus.message_new_signal = (PFN_dbus_message_new_signal)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.dbus.handle, "dbus_message_new_signal");
|
||||
_glfw.dbus.message_iter_init_append = (PFN_dbus_message_iter_init_append)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.dbus.handle, "dbus_message_iter_init_append");
|
||||
_glfw.dbus.message_iter_append_basic = (PFN_dbus_message_iter_append_basic)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.dbus.handle, "dbus_message_iter_append_basic");
|
||||
_glfw.dbus.message_iter_open_container = (PFN_dbus_message_iter_open_container)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.dbus.handle, "dbus_message_iter_open_container");
|
||||
_glfw.dbus.message_iter_close_container = (PFN_dbus_message_iter_close_container)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.dbus.handle, "dbus_message_iter_close_container");
|
||||
|
||||
if (!_glfw.dbus.error_init ||
|
||||
!_glfw.dbus.error_is_set ||
|
||||
!_glfw.dbus.error_free ||
|
||||
!_glfw.dbus.connection_unref ||
|
||||
!_glfw.dbus.connection_send ||
|
||||
!_glfw.dbus.connection_flush ||
|
||||
!_glfw.dbus.bus_request_name ||
|
||||
!_glfw.dbus.bus_get ||
|
||||
!_glfw.dbus.message_unref ||
|
||||
!_glfw.dbus.message_new_signal ||
|
||||
!_glfw.dbus.message_iter_init_append ||
|
||||
!_glfw.dbus.message_iter_append_basic ||
|
||||
!_glfw.dbus.message_iter_open_container ||
|
||||
!_glfw.dbus.message_iter_close_container)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"POSIX: Failed to load DBus entry points");
|
||||
return;
|
||||
}
|
||||
|
||||
//Initialize DBus connection
|
||||
dbus_error_init(&_glfw.dbus.error);
|
||||
_glfw.dbus.connection = dbus_bus_get(DBUS_BUS_SESSION, &_glfw.dbus.error);
|
||||
|
||||
//Check for errors
|
||||
if(dbus_error_is_set(&_glfw.dbus.error) || !_glfw.dbus.connection)
|
||||
{
|
||||
if(dbus_error_is_set(&_glfw.dbus.error))
|
||||
dbus_error_free(&_glfw.dbus.error);
|
||||
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to connect to DBus");
|
||||
|
||||
dbus_connection_unref(_glfw.dbus.connection);
|
||||
_glfw.dbus.connection = NULL;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Request name
|
||||
|
||||
_glfwCacheLegalExecutableNameDBusPOSIX();
|
||||
if(!_glfw.dbus.legalExecutableName)
|
||||
return;
|
||||
|
||||
//"org.glfw.<exe_name>_<pid>"
|
||||
char* busName = _glfw_calloc(21 + strlen(_glfw.dbus.legalExecutableName), sizeof(char));
|
||||
if(!busName)
|
||||
{
|
||||
_glfwInputError(GLFW_OUT_OF_MEMORY, "Failed to allocate memory for bus name");
|
||||
return;
|
||||
}
|
||||
memset(busName, '\0', (21 + strlen(_glfw.dbus.legalExecutableName)) * sizeof(char));
|
||||
|
||||
const pid_t pid = getpid();
|
||||
sprintf(busName, "org.glfw.%s_%d", _glfw.dbus.legalExecutableName, pid);
|
||||
|
||||
const int res = dbus_bus_request_name(_glfw.dbus.connection, busName, DBUS_NAME_FLAG_REPLACE_EXISTING, &_glfw.dbus.error);
|
||||
|
||||
_glfw_free(busName);
|
||||
|
||||
//Check for errors
|
||||
if(dbus_error_is_set(&_glfw.dbus.error) || res != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
|
||||
{
|
||||
if(dbus_error_is_set(&_glfw.dbus.error))
|
||||
dbus_error_free(&_glfw.dbus.error);
|
||||
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to request DBus name");
|
||||
|
||||
dbus_connection_unref(_glfw.dbus.connection);
|
||||
_glfw.dbus.connection = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
_glfwCacheFullExecutableNameDBusPOSIX();
|
||||
_glfwCacheDesktopFilePathDBusPOSIX();
|
||||
_glfwCacheSignalNameDBusPOSIX();
|
||||
}
|
||||
|
||||
void _glfwCacheSignalNameDBusPOSIX(void)
|
||||
{
|
||||
if(!_glfw.dbus.legalExecutableName)
|
||||
return;
|
||||
|
||||
//"/org/glfw/<exe_name>_<pid>"
|
||||
char* signalName = _glfw_calloc(22 + strlen(_glfw.dbus.legalExecutableName), sizeof(char));
|
||||
if(!signalName)
|
||||
{
|
||||
_glfwInputError(GLFW_OUT_OF_MEMORY, "Failed to allocate memory for signal name");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(signalName, '\0', (22 + strlen(_glfw.dbus.legalExecutableName)) * sizeof(char));
|
||||
|
||||
const pid_t pid = getpid();
|
||||
if(sprintf(signalName, "/org/glfw/%s_%d", _glfw.dbus.legalExecutableName, pid) < 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM, "Failed to create signal name");
|
||||
_glfw_free(signalName);
|
||||
return;
|
||||
}
|
||||
|
||||
_glfw.dbus.signalName = signalName;
|
||||
}
|
||||
|
||||
void _glfwCacheFullExecutableNameDBusPOSIX(void)
|
||||
{
|
||||
char exeName[PATH_MAX];
|
||||
memset(exeName, 0, sizeof(char) * PATH_MAX);
|
||||
if(readlink("/proc/self/exe", exeName, PATH_MAX) == -1)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to get name of the running executable");
|
||||
return;
|
||||
}
|
||||
char* exeNameEnd = strchr(exeName, '\0');
|
||||
char* lastFound = strrchr(exeName, '/');
|
||||
if(!lastFound || !exeNameEnd)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to get name of the running executable");
|
||||
return;
|
||||
}
|
||||
unsigned int exeNameLength = (exeNameEnd - lastFound) - 1;
|
||||
|
||||
char* exeNameFinal = _glfw_calloc(exeNameLength + 1, sizeof(char));
|
||||
if(!exeNameFinal)
|
||||
{
|
||||
_glfwInputError(GLFW_OUT_OF_MEMORY, "Failed to allocate memory for executable name");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(exeNameFinal, 0, sizeof(char) * (exeNameLength + 1));
|
||||
|
||||
memcpy(exeNameFinal, (lastFound + 1), exeNameLength);
|
||||
|
||||
_glfw.dbus.fullExecutableName = exeNameFinal;
|
||||
}
|
||||
|
||||
void _glfwCacheLegalExecutableNameDBusPOSIX(void)
|
||||
{
|
||||
//The executable name is stripped of any illegal characters
|
||||
//according to the DBus specification
|
||||
|
||||
int i = 0;
|
||||
int validExeNameLength = 0;
|
||||
int output = 0;
|
||||
char exeName[PATH_MAX];
|
||||
memset(exeName, 0, sizeof(char) * PATH_MAX);
|
||||
if(readlink("/proc/self/exe", exeName, PATH_MAX) == -1)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to get name of the running executable");
|
||||
return;
|
||||
}
|
||||
char* exeNameEnd = strchr(exeName, '\0');
|
||||
char* lastFound = strrchr(exeName, '/');
|
||||
if(!lastFound || !exeNameEnd)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to get name of the running executable");
|
||||
return;
|
||||
}
|
||||
unsigned int exeNameLength = (exeNameEnd - lastFound) - 1;
|
||||
|
||||
for(i = 0; i < exeNameLength; ++i)
|
||||
{
|
||||
if(isalnum(*(lastFound + 1 + i)))
|
||||
validExeNameLength++;
|
||||
}
|
||||
|
||||
char* exeNameFinal = _glfw_calloc(validExeNameLength + 1, sizeof(char));
|
||||
if(!exeNameFinal)
|
||||
{
|
||||
_glfwInputError(GLFW_OUT_OF_MEMORY, "Failed to allocate memory for executable name");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(exeNameFinal, 0, sizeof(char) * (validExeNameLength + 1));
|
||||
|
||||
for(i = 0; i < exeNameLength; ++i)
|
||||
{
|
||||
if(isalnum(*(lastFound + 1 + i)))
|
||||
exeNameFinal[output++] = *(lastFound + 1 + i);
|
||||
}
|
||||
|
||||
_glfw.dbus.legalExecutableName = exeNameFinal;
|
||||
}
|
||||
|
||||
void _glfwCacheDesktopFilePathDBusPOSIX(void)
|
||||
{
|
||||
if(!_glfw.dbus.fullExecutableName)
|
||||
return;
|
||||
|
||||
//Cache path of .desktop file
|
||||
|
||||
//Create our final desktop file uri
|
||||
//"application://<exe_name>.desktop"
|
||||
unsigned int desktopFileLength = strlen("application://") + strlen(_glfw.dbus.fullExecutableName) + strlen(".desktop") + 1;
|
||||
_glfw.dbus.desktopFilePath = _glfw_calloc(desktopFileLength, sizeof(char));
|
||||
if(!_glfw.dbus.desktopFilePath)
|
||||
{
|
||||
_glfwInputError(GLFW_OUT_OF_MEMORY, "Failed to allocate memory for .desktop file path");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(_glfw.dbus.desktopFilePath, 0, sizeof(char) * desktopFileLength);
|
||||
strcpy(_glfw.dbus.desktopFilePath, "application://");
|
||||
memcpy(_glfw.dbus.desktopFilePath + strlen("application://"), _glfw.dbus.fullExecutableName, strlen(_glfw.dbus.fullExecutableName));
|
||||
strcpy(_glfw.dbus.desktopFilePath + strlen("application://") + strlen(_glfw.dbus.fullExecutableName), ".desktop");
|
||||
_glfw.dbus.desktopFilePath[desktopFileLength - 1] = '\0';
|
||||
}
|
||||
|
||||
void _glfwTerminateDBusPOSIX(void)
|
||||
{
|
||||
if(_glfw.dbus.signalName)
|
||||
_glfw_free(_glfw.dbus.signalName);
|
||||
|
||||
if(_glfw.dbus.legalExecutableName)
|
||||
_glfw_free(_glfw.dbus.legalExecutableName);
|
||||
|
||||
if(_glfw.dbus.fullExecutableName)
|
||||
_glfw_free(_glfw.dbus.fullExecutableName);
|
||||
|
||||
if(_glfw.dbus.desktopFilePath)
|
||||
_glfw_free(_glfw.dbus.desktopFilePath);
|
||||
|
||||
if (_glfw.dbus.connection)
|
||||
{
|
||||
dbus_connection_unref(_glfw.dbus.connection);
|
||||
_glfw.dbus.connection = NULL;
|
||||
}
|
||||
|
||||
if (_glfw.dbus.handle)
|
||||
{
|
||||
_glfwPlatformFreeModule(_glfw.dbus.handle);
|
||||
_glfw.dbus.handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwUpdateTaskbarProgressDBusPOSIX(dbus_bool_t progressVisible, double progressValue)
|
||||
{
|
||||
struct DBusMessage* msg = NULL;
|
||||
|
||||
if(!_glfw.dbus.handle || !_glfw.dbus.connection || !_glfw.dbus.desktopFilePath || !_glfw.dbus.signalName)
|
||||
return;
|
||||
|
||||
//Signal signature:
|
||||
//signal com.canonical.Unity.LauncherEntry.Update (in s app_uri, in a{sv} properties)
|
||||
|
||||
struct DBusMessageIter args;
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
if(!_glfwNewMessageSignalDBusPOSIX(_glfw.dbus.signalName, "com.canonical.Unity.LauncherEntry", "Update", &msg))
|
||||
return;
|
||||
|
||||
dbus_message_iter_init_append(msg, &args);
|
||||
|
||||
//Setup app_uri parameter
|
||||
_glfwAppendDataDBusPOSIX(&args, DBUS_TYPE_STRING, &_glfw.dbus.desktopFilePath);
|
||||
|
||||
//Set properties parameter
|
||||
struct DBusMessageIter sub1;
|
||||
memset(&sub1, 0, sizeof(sub1));
|
||||
|
||||
_glfwOpenContainerDBusPOSIX(&args, DBUS_TYPE_ARRAY, "{sv}", &sub1);
|
||||
|
||||
//Set progress visible property
|
||||
const char* progressVisibleStr = "progress-visible";
|
||||
_glfwAppendDictDataDBusPOSIX(&sub1, DBUS_TYPE_STRING, &progressVisibleStr, DBUS_TYPE_BOOLEAN, &progressVisible);
|
||||
|
||||
//Set progress value property
|
||||
const char* progressStr = "progress";
|
||||
_glfwAppendDictDataDBusPOSIX(&sub1, DBUS_TYPE_STRING, &progressStr, DBUS_TYPE_DOUBLE, &progressValue);
|
||||
|
||||
_glfwCloseContainerDBusPOSIX(&args, &sub1);
|
||||
|
||||
_glfwSendMessageDBusPOSIX(msg);
|
||||
|
||||
//Free the message
|
||||
dbus_message_unref(msg);
|
||||
}
|
||||
|
||||
dbus_bool_t _glfwNewMessageSignalDBusPOSIX(const char* objectPath, const char* interfaceName, const char* signalName, struct DBusMessage** outMessage)
|
||||
{
|
||||
if(!outMessage)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to create new DBus message, output message pointer is NULL");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
*outMessage = dbus_message_new_signal(objectPath, interfaceName, signalName);
|
||||
if(!(*outMessage))
|
||||
{
|
||||
*outMessage = NULL;
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to create new DBus message");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
dbus_bool_t _glfwOpenContainerDBusPOSIX(struct DBusMessageIter* iterator, int DBusType, const char* signature, struct DBusMessageIter* subIterator)
|
||||
{
|
||||
if(DBusType != DBUS_TYPE_ARRAY && DBusType != DBUS_TYPE_STRUCT_OPEN &&
|
||||
DBusType != DBUS_TYPE_STRUCT_CLOSE && DBusType != DBUS_TYPE_VARIANT &&
|
||||
DBusType != DBUS_TYPE_DICT_ENTRY)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Invalid DBUS container type provided");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
if(!iterator || !subIterator)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "DBus message iterator is NULL");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return dbus_message_iter_open_container(iterator, DBusType, signature, subIterator);
|
||||
}
|
||||
|
||||
dbus_bool_t _glfwCloseContainerDBusPOSIX(struct DBusMessageIter* iterator, struct DBusMessageIter* subIterator)
|
||||
{
|
||||
if(!iterator || !subIterator)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "DBus message iterator is NULL");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return dbus_message_iter_close_container(iterator, subIterator);
|
||||
}
|
||||
|
||||
dbus_bool_t _glfwAppendDataDBusPOSIX(struct DBusMessageIter* iterator, int DBusType, const void* data)
|
||||
{
|
||||
if(DBusType == DBUS_TYPE_ARRAY || DBusType == DBUS_TYPE_VARIANT || DBusType == DBUS_TYPE_DICT_ENTRY || DBusType == DBUS_TYPE_STRUCT_OPEN || DBusType == DBUS_TYPE_STRUCT_CLOSE)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Invalid DBus type provided");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
if(!iterator)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "DBus message iterator is NULL");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
if(!data)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "DBus data to append is NULL");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return dbus_message_iter_append_basic(iterator, DBusType, data);
|
||||
}
|
||||
|
||||
dbus_bool_t _glfwAppendDictDataDBusPOSIX(struct DBusMessageIter* iterator, int keyType, const void* keyData, int valueType, const void* valueData)
|
||||
{
|
||||
struct DBusMessageIter keyIterator;
|
||||
struct DBusMessageIter valueIterator;
|
||||
memset(&keyIterator, 0, sizeof(keyIterator));
|
||||
memset(&valueIterator, 0, sizeof(valueIterator));
|
||||
|
||||
if(!_glfwOpenContainerDBusPOSIX(iterator, DBUS_TYPE_DICT_ENTRY, NULL, &keyIterator))
|
||||
return GLFW_FALSE;
|
||||
|
||||
//Append key data
|
||||
if(!_glfwAppendDataDBusPOSIX(&keyIterator, keyType, keyData))
|
||||
return GLFW_FALSE;
|
||||
|
||||
char* valueTypeStr = _glfwDBusTypeToStrPOSIX(valueType);
|
||||
assert(valueTypeStr != NULL);
|
||||
if(!_glfwOpenContainerDBusPOSIX(&keyIterator, DBUS_TYPE_VARIANT, valueTypeStr, &valueIterator))
|
||||
return GLFW_FALSE;
|
||||
|
||||
//Append value data
|
||||
if(!_glfwAppendDataDBusPOSIX(&valueIterator, valueType, valueData))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if(!_glfwCloseContainerDBusPOSIX(&keyIterator, &valueIterator))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if(!_glfwCloseContainerDBusPOSIX(iterator, &keyIterator))
|
||||
return GLFW_FALSE;
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
dbus_bool_t _glfwSendMessageDBusPOSIX(struct DBusMessage* message)
|
||||
{
|
||||
if(!message)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "DBus message is NULL");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
unsigned int serial = 0;
|
||||
if(!dbus_connection_send(_glfw.dbus.connection, message, &serial))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to send DBus message");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
dbus_connection_flush(_glfw.dbus.connection);
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
char* _glfwDBusTypeToStrPOSIX(int valueType)
|
||||
{
|
||||
switch (valueType)
|
||||
{
|
||||
case DBUS_TYPE_STRING:
|
||||
return DBUS_TYPE_STRING_AS_STRING;
|
||||
case DBUS_TYPE_ARRAY:
|
||||
return DBUS_TYPE_ARRAY_AS_STRING;
|
||||
case DBUS_TYPE_DICT_ENTRY:
|
||||
return DBUS_TYPE_DICT_ENTRY_AS_STRING;
|
||||
case DBUS_TYPE_VARIANT:
|
||||
return DBUS_TYPE_VARIANT_AS_STRING;
|
||||
case DBUS_TYPE_BOOLEAN:
|
||||
return DBUS_TYPE_BOOLEAN_AS_STRING;
|
||||
case DBUS_TYPE_DOUBLE:
|
||||
return DBUS_TYPE_DOUBLE_AS_STRING;
|
||||
case DBUS_TYPE_INT16:
|
||||
return DBUS_TYPE_INT16_AS_STRING;
|
||||
case DBUS_TYPE_UINT16:
|
||||
return DBUS_TYPE_UINT16_AS_STRING;
|
||||
case DBUS_TYPE_INT32:
|
||||
return DBUS_TYPE_INT32_AS_STRING;
|
||||
case DBUS_TYPE_UINT32:
|
||||
return DBUS_TYPE_UINT32_AS_STRING;
|
||||
case DBUS_TYPE_INT64:
|
||||
return DBUS_TYPE_INT64_AS_STRING;
|
||||
case DBUS_TYPE_UINT64:
|
||||
return DBUS_TYPE_UINT64_AS_STRING;
|
||||
case DBUS_TYPE_STRUCT_OPEN:
|
||||
return DBUS_TYPE_STRUCT_OPEN_AS_STRING;
|
||||
case DBUS_TYPE_STRUCT_CLOSE:
|
||||
return DBUS_TYPE_STRUCT_CLOSE_AS_STRING;
|
||||
case DBUS_TYPE_BYTE:
|
||||
return DBUS_TYPE_BYTE_AS_STRING;
|
||||
case DBUS_TYPE_OBJECT_PATH:
|
||||
return DBUS_TYPE_OBJECT_PATH_AS_STRING;
|
||||
case DBUS_TYPE_SIGNATURE:
|
||||
return DBUS_TYPE_SIGNATURE_AS_STRING;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
177
src/posix_dbus.h
Normal file
177
src/posix_dbus.h
Normal file
@ -0,0 +1,177 @@
|
||||
//========================================================================
|
||||
// GLFW 3.4 POSIX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2023 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
//Taken from DBus docs (https://dbus.freedesktop.org/doc/api/html/index.html)
|
||||
typedef struct DBusConnection DBusConnection;
|
||||
typedef struct DBusMessage DBusMessage;
|
||||
typedef unsigned int dbus_bool_t;
|
||||
typedef unsigned int dbus_uint32_t;
|
||||
|
||||
enum DBusBusType
|
||||
{
|
||||
DBUS_BUS_SESSION,
|
||||
DBUS_BUS_SYSTEM,
|
||||
DBUS_BUS_STARTER
|
||||
};
|
||||
|
||||
struct DBusError
|
||||
{
|
||||
const char* name;
|
||||
const char* message;
|
||||
unsigned int dummy1 : 1;
|
||||
unsigned int dummy2 : 1;
|
||||
unsigned int dummy3 : 1;
|
||||
unsigned int dummy4 : 1;
|
||||
unsigned int dummy5 : 1;
|
||||
void* padding1;
|
||||
};
|
||||
|
||||
struct DBusMessageIter
|
||||
{
|
||||
void* dummy1;
|
||||
void* dummy2;
|
||||
dbus_uint32_t dummy3;
|
||||
int dummy4, dummy5, dummy6, dummy7, dummy8, dummy9, dummy10, dummy11;
|
||||
int pad1;
|
||||
void* pad2;
|
||||
void* pad3;
|
||||
};
|
||||
|
||||
#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2
|
||||
#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
|
||||
#define DBUS_TYPE_STRING (unsigned int)'s'
|
||||
#define DBUS_TYPE_ARRAY (unsigned int)'a'
|
||||
#define DBUS_TYPE_DICT_ENTRY (unsigned int)'e'
|
||||
#define DBUS_TYPE_VARIANT (unsigned int)'v'
|
||||
#define DBUS_TYPE_BOOLEAN (unsigned int)'b'
|
||||
#define DBUS_TYPE_DOUBLE (unsigned int)'d'
|
||||
#define DBUS_TYPE_INT16 (unsigned int)'n'
|
||||
#define DBUS_TYPE_UINT16 (unsigned int)'q'
|
||||
#define DBUS_TYPE_INT32 (unsigned int)'i'
|
||||
#define DBUS_TYPE_UINT32 (unsigned int)'u'
|
||||
#define DBUS_TYPE_INT64 (unsigned int)'x'
|
||||
#define DBUS_TYPE_UINT64 (unsigned int)'t'
|
||||
#define DBUS_TYPE_STRUCT_OPEN (unsigned int)'('
|
||||
#define DBUS_TYPE_STRUCT_CLOSE (unsigned int)')'
|
||||
#define DBUS_TYPE_BYTE (unsigned int)'y'
|
||||
#define DBUS_TYPE_OBJECT_PATH (unsigned int)'o'
|
||||
#define DBUS_TYPE_SIGNATURE (unsigned int)'g'
|
||||
|
||||
#define DBUS_TYPE_STRING_AS_STRING "s"
|
||||
#define DBUS_TYPE_ARRAY_AS_STRING "a"
|
||||
#define DBUS_TYPE_DICT_ENTRY_AS_STRING "e"
|
||||
#define DBUS_TYPE_VARIANT_AS_STRING "v"
|
||||
#define DBUS_TYPE_BOOLEAN_AS_STRING "b"
|
||||
#define DBUS_TYPE_DOUBLE_AS_STRING "d"
|
||||
#define DBUS_TYPE_INT16_AS_STRING "n"
|
||||
#define DBUS_TYPE_UINT16_AS_STRING "q"
|
||||
#define DBUS_TYPE_INT32_AS_STRING "i"
|
||||
#define DBUS_TYPE_UINT32_AS_STRING "u"
|
||||
#define DBUS_TYPE_INT64_AS_STRING "x"
|
||||
#define DBUS_TYPE_UINT64_AS_STRING "t"
|
||||
#define DBUS_TYPE_STRUCT_OPEN_AS_STRING "("
|
||||
#define DBUS_TYPE_STRUCT_CLOSE_AS_STRING ")"
|
||||
#define DBUS_TYPE_BYTE_AS_STRING "y"
|
||||
#define DBUS_TYPE_OBJECT_PATH_AS_STRING "o"
|
||||
#define DBUS_TYPE_SIGNATURE_AS_STRING "g"
|
||||
|
||||
typedef void (* PFN_dbus_error_init)(struct DBusError*);
|
||||
typedef dbus_bool_t (* PFN_dbus_error_is_set)(const struct DBusError*);
|
||||
typedef void (* PFN_dbus_error_free)(struct DBusError*);
|
||||
typedef void (* PFN_dbus_connection_unref)(DBusConnection*);
|
||||
typedef dbus_bool_t (* PFN_dbus_connection_send)(DBusConnection*, DBusMessage*, dbus_uint32_t*);
|
||||
typedef void (* PFN_dbus_connection_flush)(DBusConnection*);
|
||||
typedef int (* PFN_dbus_bus_request_name)(DBusConnection*, const char*, unsigned int, struct DBusError*);
|
||||
typedef DBusConnection* (* PFN_dbus_bus_get)(enum DBusBusType, struct DBusError*);
|
||||
typedef void (* PFN_dbus_message_unref)(DBusMessage*);
|
||||
typedef DBusMessage* (* PFN_dbus_message_new_signal)(const char*, const char*, const char*);
|
||||
typedef void (* PFN_dbus_message_iter_init_append)(DBusMessage*, struct DBusMessageIter*);
|
||||
typedef dbus_bool_t (* PFN_dbus_message_iter_append_basic)(struct DBusMessageIter*, int, const void*);
|
||||
typedef dbus_bool_t (* PFN_dbus_message_iter_open_container)(struct DBusMessageIter*, int, const char*, struct DBusMessageIter*);
|
||||
typedef dbus_bool_t (* PFN_dbus_message_iter_close_container)(struct DBusMessageIter*, struct DBusMessageIter*);
|
||||
|
||||
#define dbus_error_init _glfw.dbus.error_init
|
||||
#define dbus_error_is_set _glfw.dbus.error_is_set
|
||||
#define dbus_error_free _glfw.dbus.error_free
|
||||
#define dbus_connection_unref _glfw.dbus.connection_unref
|
||||
#define dbus_connection_send _glfw.dbus.connection_send
|
||||
#define dbus_connection_flush _glfw.dbus.connection_flush
|
||||
#define dbus_bus_request_name _glfw.dbus.bus_request_name
|
||||
#define dbus_bus_get _glfw.dbus.bus_get
|
||||
#define dbus_message_unref _glfw.dbus.message_unref
|
||||
#define dbus_message_new_signal _glfw.dbus.message_new_signal
|
||||
#define dbus_message_iter_init_append _glfw.dbus.message_iter_init_append
|
||||
#define dbus_message_iter_append_basic _glfw.dbus.message_iter_append_basic
|
||||
#define dbus_message_iter_open_container _glfw.dbus.message_iter_open_container
|
||||
#define dbus_message_iter_close_container _glfw.dbus.message_iter_close_container
|
||||
|
||||
#define GLFW_POSIX_LIBRARY_DBUS_STATE _GLFWDBusPOSIX dbus;
|
||||
|
||||
// POSIX-specific dbus data
|
||||
//
|
||||
typedef struct _GLFWDBusPOSIX
|
||||
{
|
||||
void* handle;
|
||||
|
||||
PFN_dbus_error_init error_init;
|
||||
PFN_dbus_error_is_set error_is_set;
|
||||
PFN_dbus_error_free error_free;
|
||||
PFN_dbus_connection_unref connection_unref;
|
||||
PFN_dbus_connection_send connection_send;
|
||||
PFN_dbus_connection_flush connection_flush;
|
||||
PFN_dbus_bus_request_name bus_request_name;
|
||||
PFN_dbus_bus_get bus_get;
|
||||
PFN_dbus_message_unref message_unref;
|
||||
PFN_dbus_message_new_signal message_new_signal;
|
||||
PFN_dbus_message_iter_init_append message_iter_init_append;
|
||||
PFN_dbus_message_iter_append_basic message_iter_append_basic;
|
||||
PFN_dbus_message_iter_open_container message_iter_open_container;
|
||||
PFN_dbus_message_iter_close_container message_iter_close_container;
|
||||
|
||||
DBusConnection* connection;
|
||||
struct DBusError error;
|
||||
|
||||
char* desktopFilePath;
|
||||
char* fullExecutableName;
|
||||
char* legalExecutableName;
|
||||
char* signalName;
|
||||
} _GLFWDBusPOSIX;
|
||||
|
||||
void _glfwInitDBusPOSIX(void);
|
||||
void _glfwCacheSignalNameDBusPOSIX(void);
|
||||
void _glfwCacheFullExecutableNameDBusPOSIX(void);
|
||||
void _glfwCacheLegalExecutableNameDBusPOSIX(void);
|
||||
void _glfwCacheDesktopFilePathDBusPOSIX(void);
|
||||
void _glfwTerminateDBusPOSIX(void);
|
||||
void _glfwUpdateTaskbarProgressDBusPOSIX(dbus_bool_t progressVisible, double progressValue);
|
||||
|
||||
dbus_bool_t _glfwNewMessageSignalDBusPOSIX(const char* objectPath, const char* interfaceName, const char* signalName, struct DBusMessage** outMessage);
|
||||
dbus_bool_t _glfwOpenContainerDBusPOSIX(struct DBusMessageIter* iterator, int DBusType, const char* signature, struct DBusMessageIter* subIterator);
|
||||
dbus_bool_t _glfwCloseContainerDBusPOSIX(struct DBusMessageIter* iterator, struct DBusMessageIter* subIterator);
|
||||
dbus_bool_t _glfwAppendDataDBusPOSIX(struct DBusMessageIter* iterator, int DBusType, const void* data);
|
||||
dbus_bool_t _glfwAppendDictDataDBusPOSIX(struct DBusMessageIter* iterator, int keyType, const void* keyData, int valueType, const void* valueData);
|
||||
dbus_bool_t _glfwSendMessageDBusPOSIX(struct DBusMessage* message);
|
||||
char* _glfwDBusTypeToStrPOSIX(int valueType);
|
||||
@ -327,8 +327,8 @@ static void swapBuffersWGL(_GLFWwindow* window)
|
||||
{
|
||||
if (!window->monitor)
|
||||
{
|
||||
// HACK: Use DwmFlush when desktop composition is enabled on Windows Vista and 7
|
||||
if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater())
|
||||
// HACK: Use DwmFlush when desktop composition is enabled on Windows 7
|
||||
if (!IsWindows8OrGreater())
|
||||
{
|
||||
BOOL enabled = FALSE;
|
||||
|
||||
@ -353,9 +353,9 @@ static void swapIntervalWGL(int interval)
|
||||
|
||||
if (!window->monitor)
|
||||
{
|
||||
// HACK: Disable WGL swap interval when desktop composition is enabled on Windows
|
||||
// Vista and 7 to avoid interfering with DWM vsync
|
||||
if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater())
|
||||
// HACK: Disable WGL swap interval when desktop composition is enabled on
|
||||
// Windows 7 to avoid interfering with DWM vsync
|
||||
if (!IsWindows8OrGreater())
|
||||
{
|
||||
BOOL enabled = FALSE;
|
||||
|
||||
|
||||
@ -89,10 +89,6 @@ static GLFWbool loadLibraries(void)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "SetProcessDPIAware");
|
||||
_glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
|
||||
_glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "EnableNonClientDpiScaling");
|
||||
_glfw.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext)
|
||||
@ -635,6 +631,7 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
|
||||
.destroyWindow = _glfwDestroyWindowWin32,
|
||||
.setWindowTitle = _glfwSetWindowTitleWin32,
|
||||
.setWindowIcon = _glfwSetWindowIconWin32,
|
||||
.setWindowProgressIndicator = _glfwSetWindowProgressIndicatorWin32,
|
||||
.getWindowPos = _glfwGetWindowPosWin32,
|
||||
.setWindowPos = _glfwSetWindowPosWin32,
|
||||
.getWindowSize = _glfwGetWindowSizeWin32,
|
||||
@ -692,7 +689,7 @@ int _glfwInitWin32(void)
|
||||
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||
else if (IsWindows8Point1OrGreater())
|
||||
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||
else if (IsWindowsVistaOrGreater())
|
||||
else
|
||||
SetProcessDPIAware();
|
||||
|
||||
if (!createHelperWindow())
|
||||
|
||||
@ -48,14 +48,14 @@
|
||||
#define UNICODE
|
||||
#endif
|
||||
|
||||
// GLFW requires Windows XP or later
|
||||
#if WINVER < 0x0501
|
||||
// GLFW requires Windows 7 or later
|
||||
#if WINVER < 0x0601
|
||||
#undef WINVER
|
||||
#define WINVER 0x0501
|
||||
#define WINVER 0x0601
|
||||
#endif
|
||||
#if _WIN32_WINNT < 0x0501
|
||||
#if _WIN32_WINNT < 0x0601
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#define _WIN32_WINNT 0x0601
|
||||
#endif
|
||||
|
||||
// GLFW uses DirectInput8 interfaces
|
||||
@ -66,41 +66,21 @@
|
||||
|
||||
#include <wctype.h>
|
||||
#include <windows.h>
|
||||
#include <dwmapi.h>
|
||||
#include <dinput.h>
|
||||
#include <xinput.h>
|
||||
#include <dbt.h>
|
||||
|
||||
// HACK: Define macros that some windows.h variants don't
|
||||
#ifndef WM_MOUSEHWHEEL
|
||||
#define WM_MOUSEHWHEEL 0x020E
|
||||
#endif
|
||||
#ifndef WM_DWMCOMPOSITIONCHANGED
|
||||
#define WM_DWMCOMPOSITIONCHANGED 0x031E
|
||||
#endif
|
||||
#ifndef WM_DWMCOLORIZATIONCOLORCHANGED
|
||||
#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320
|
||||
#endif
|
||||
#ifndef WM_COPYGLOBALDATA
|
||||
#define WM_COPYGLOBALDATA 0x0049
|
||||
#endif
|
||||
#ifndef WM_UNICHAR
|
||||
#define WM_UNICHAR 0x0109
|
||||
#endif
|
||||
#ifndef UNICODE_NOCHAR
|
||||
#define UNICODE_NOCHAR 0xFFFF
|
||||
#endif
|
||||
#ifndef WM_DPICHANGED
|
||||
#define WM_DPICHANGED 0x02E0
|
||||
#endif
|
||||
#ifndef GET_XBUTTON_WPARAM
|
||||
#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
|
||||
#endif
|
||||
#ifndef EDS_ROTATEDMODE
|
||||
#define EDS_ROTATEDMODE 0x00000004
|
||||
#endif
|
||||
#ifndef DISPLAY_DEVICE_ACTIVE
|
||||
#define DISPLAY_DEVICE_ACTIVE 0x00000001
|
||||
#endif
|
||||
#ifndef _WIN32_WINNT_WINBLUE
|
||||
#define _WIN32_WINNT_WINBLUE 0x0603
|
||||
#endif
|
||||
@ -113,34 +93,6 @@
|
||||
#ifndef USER_DEFAULT_SCREEN_DPI
|
||||
#define USER_DEFAULT_SCREEN_DPI 96
|
||||
#endif
|
||||
#ifndef OCR_HAND
|
||||
#define OCR_HAND 32649
|
||||
#endif
|
||||
|
||||
#if WINVER < 0x0601
|
||||
typedef struct
|
||||
{
|
||||
DWORD cbSize;
|
||||
DWORD ExtStatus;
|
||||
} CHANGEFILTERSTRUCT;
|
||||
#ifndef MSGFLT_ALLOW
|
||||
#define MSGFLT_ALLOW 1
|
||||
#endif
|
||||
#endif /*Windows 7*/
|
||||
|
||||
#if WINVER < 0x0600
|
||||
#define DWM_BB_ENABLE 0x00000001
|
||||
#define DWM_BB_BLURREGION 0x00000002
|
||||
typedef struct
|
||||
{
|
||||
DWORD dwFlags;
|
||||
BOOL fEnable;
|
||||
HRGN hRgnBlur;
|
||||
BOOL fTransitionOnMaximized;
|
||||
} DWM_BLURBEHIND;
|
||||
#else
|
||||
#include <dwmapi.h>
|
||||
#endif /*Windows Vista*/
|
||||
|
||||
#ifndef DPI_ENUMS_DECLARED
|
||||
typedef enum
|
||||
@ -165,12 +117,6 @@ typedef enum
|
||||
// Replacement for versionhelpers.h macros, as we cannot rely on the
|
||||
// application having a correct embedded manifest
|
||||
//
|
||||
#define IsWindowsVistaOrGreater() \
|
||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \
|
||||
LOBYTE(_WIN32_WINNT_VISTA), 0)
|
||||
#define IsWindows7OrGreater() \
|
||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN7), \
|
||||
LOBYTE(_WIN32_WINNT_WIN7), 0)
|
||||
#define IsWindows8OrGreater() \
|
||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN8), \
|
||||
LOBYTE(_WIN32_WINNT_WIN8), 0)
|
||||
@ -281,15 +227,11 @@ typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*
|
||||
#define DirectInput8Create _glfw.win32.dinput8.Create
|
||||
|
||||
// user32.dll function pointer typedefs
|
||||
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
|
||||
typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,CHANGEFILTERSTRUCT*);
|
||||
typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND);
|
||||
typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(HANDLE);
|
||||
typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND);
|
||||
typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
|
||||
typedef int (WINAPI * PFN_GetSystemMetricsForDpi)(int,UINT);
|
||||
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
|
||||
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
|
||||
#define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_
|
||||
#define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_
|
||||
#define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_
|
||||
@ -366,6 +308,79 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(
|
||||
#define GLFW_WGL_CONTEXT_STATE _GLFWcontextWGL wgl;
|
||||
#define GLFW_WGL_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TBPF_NOPROGRESS = 0x0,
|
||||
TBPF_INDETERMINATE = 0x1,
|
||||
TBPF_NORMAL = 0x2,
|
||||
TBPF_ERROR = 0x4,
|
||||
TBPF_PAUSED = 0x8
|
||||
} TBPFLAG;
|
||||
|
||||
static const IID IID_ITaskbarList3 = { 0xea1afb91, 0x9e28, 0x4b86, {0x90, 0xe9, 0x9e, 0x9f, 0x8a, 0x5e, 0xef, 0xaf} };
|
||||
static const IID CLSID_TaskbarList = { 0x56fdf344, 0xfd6d, 0x11d0, {0x95, 0x8a, 0x00, 0x60, 0x97, 0xc9, 0xa0, 0x90} };
|
||||
|
||||
typedef enum THUMBBUTTONMASK
|
||||
{
|
||||
THB_BITMAP = 0x1,
|
||||
THB_ICON = 0x2,
|
||||
THB_TOOLTIP = 0x4,
|
||||
THB_FLAGS = 0x8
|
||||
} THUMBBUTTONMASK;
|
||||
|
||||
typedef enum THUMBBUTTONFLAGS
|
||||
{
|
||||
THBF_ENABLED = 0,
|
||||
THBF_DISABLED = 0x1,
|
||||
THBF_DISMISSONCLICK = 0x2,
|
||||
THBF_NOBACKGROUND = 0x4,
|
||||
THBF_HIDDEN = 0x8,
|
||||
THBF_NONINTERACTIVE = 0x10
|
||||
} THUMBBUTTONFLAGS;
|
||||
|
||||
typedef struct THUMBBUTTON {
|
||||
THUMBBUTTONMASK dwMask;
|
||||
UINT iId;
|
||||
UINT iBitmap;
|
||||
HICON hIcon;
|
||||
WCHAR szTip[260];
|
||||
THUMBBUTTONFLAGS dwFlags;
|
||||
} THUMBBUTTON, *LPTHUMBBUTTON;
|
||||
|
||||
struct _IMAGELIST;
|
||||
typedef struct _IMAGELIST* HIMAGELIST;
|
||||
|
||||
typedef struct ITaskbarList3 ITaskbarList3;
|
||||
|
||||
typedef struct ITaskbarList3Vtbl
|
||||
{
|
||||
HRESULT(WINAPI* QueryInterface)(struct ITaskbarList3*, const IID* const, void**);
|
||||
ULONG(WINAPI* AddRef)(struct ITaskbarList3*);
|
||||
ULONG(WINAPI* Release)(struct ITaskbarList3*);
|
||||
HRESULT(WINAPI* HrInit)(struct ITaskbarList3*);
|
||||
HRESULT(WINAPI* AddTab)(struct ITaskbarList3*, HWND);
|
||||
HRESULT(WINAPI* DeleteTab)(struct ITaskbarList3*, HWND);
|
||||
HRESULT(WINAPI* ActivateTab)(struct ITaskbarList3*, HWND);
|
||||
HRESULT(WINAPI* SetActiveAlt)(struct ITaskbarList3*, HWND);
|
||||
HRESULT(WINAPI* MarkFullscreenWindow)(struct ITaskbarList3*, HWND, BOOL);
|
||||
HRESULT(WINAPI* SetProgressValue)(struct ITaskbarList3*, HWND, ULONGLONG, ULONGLONG);
|
||||
HRESULT(WINAPI* SetProgressState)(struct ITaskbarList3*, HWND, TBPFLAG);
|
||||
HRESULT(WINAPI* RegisterTab)(struct ITaskbarList3*, HWND, HWND);
|
||||
HRESULT(WINAPI* UnregisterTab)(struct ITaskbarList3*, HWND);
|
||||
HRESULT(WINAPI* SetTabOrder)(struct ITaskbarList3*, HWND, HWND);
|
||||
HRESULT(WINAPI* SetTabActive)(struct ITaskbarList3*, HWND, HWND, DWORD);
|
||||
HRESULT(WINAPI* ThumbBarAddButtons)(struct ITaskbarList3*, HWND, UINT, LPTHUMBBUTTON);
|
||||
HRESULT(WINAPI* ThumbBarUpdateButtons)(struct ITaskbarList3*, HWND, UINT, LPTHUMBBUTTON);
|
||||
HRESULT(WINAPI* ThumbBarSetImageList)(struct ITaskbarList3*, HWND, HIMAGELIST);
|
||||
HRESULT(WINAPI* SetOverlayIcon)(struct ITaskbarList3*, HWND, HICON, LPCWSTR);
|
||||
HRESULT(WINAPI* SetThumbnailTooltip)(struct ITaskbarList3*, HWND, LPCWSTR);
|
||||
HRESULT(WINAPI* SetThumbnailClip)(struct ITaskbarList3*, HWND, RECT*);
|
||||
} ITaskbarList3Vtbl;
|
||||
|
||||
struct ITaskbarList3
|
||||
{
|
||||
struct ITaskbarList3Vtbl* lpVtbl;
|
||||
};
|
||||
|
||||
// WGL-specific per-context data
|
||||
//
|
||||
@ -433,6 +448,9 @@ typedef struct _GLFWwindowWin32
|
||||
int lastCursorPosX, lastCursorPosY;
|
||||
// The last received high surrogate when decoding pairs of UTF-16 messages
|
||||
WCHAR highSurrogate;
|
||||
|
||||
ITaskbarList3* taskbarList;
|
||||
UINT taskbarListMsgID;
|
||||
} _GLFWwindowWin32;
|
||||
|
||||
// Win32-specific global data
|
||||
@ -475,8 +493,6 @@ typedef struct _GLFWlibraryWin32
|
||||
|
||||
struct {
|
||||
HINSTANCE instance;
|
||||
PFN_SetProcessDPIAware SetProcessDPIAware_;
|
||||
PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_;
|
||||
PFN_EnableNonClientDpiScaling EnableNonClientDpiScaling_;
|
||||
PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_;
|
||||
PFN_GetDpiForWindow GetDpiForWindow_;
|
||||
@ -525,7 +541,6 @@ typedef struct _GLFWcursorWin32
|
||||
HCURSOR handle;
|
||||
} _GLFWcursorWin32;
|
||||
|
||||
|
||||
GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform);
|
||||
int _glfwInitWin32(void);
|
||||
void _glfwTerminateWin32(void);
|
||||
@ -546,6 +561,7 @@ GLFWbool _glfwCreateWindowWin32(_GLFWwindow* window, const _GLFWwndconfig* wndco
|
||||
void _glfwDestroyWindowWin32(_GLFWwindow* window);
|
||||
void _glfwSetWindowTitleWin32(_GLFWwindow* window, const char* title);
|
||||
void _glfwSetWindowIconWin32(_GLFWwindow* window, int count, const GLFWimage* images);
|
||||
void _glfwSetWindowProgressIndicatorWin32(_GLFWwindow* window, int progressState, double value);
|
||||
void _glfwGetWindowPosWin32(_GLFWwindow* window, int* xpos, int* ypos);
|
||||
void _glfwSetWindowPosWin32(_GLFWwindow* window, int xpos, int ypos);
|
||||
void _glfwGetWindowSizeWin32(_GLFWwindow* window, int* width, int* height);
|
||||
|
||||
@ -374,9 +374,6 @@ static void updateFramebufferTransparency(const _GLFWwindow* window)
|
||||
BOOL composition, opaque;
|
||||
DWORD color;
|
||||
|
||||
if (!IsWindowsVistaOrGreater())
|
||||
return;
|
||||
|
||||
if (FAILED(DwmIsCompositionEnabled(&composition)) || !composition)
|
||||
return;
|
||||
|
||||
@ -983,7 +980,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
|
||||
|
||||
case WM_MOUSEHWHEEL:
|
||||
{
|
||||
// This message is only sent on Windows Vista and later
|
||||
// NOTE: The X-axis is inverted for consistency with macOS and X11
|
||||
_glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0);
|
||||
return 0;
|
||||
@ -1268,6 +1264,18 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
|
||||
}
|
||||
}
|
||||
|
||||
if(uMsg == window->win32.taskbarListMsgID)
|
||||
{
|
||||
HRESULT res = CoCreateInstance(&CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, &IID_ITaskbarList3, (LPVOID*)&window->win32.taskbarList);
|
||||
if (res != S_OK && window->win32.taskbarList)
|
||||
window->win32.taskbarList->lpVtbl->Release(window->win32.taskbarList);
|
||||
else
|
||||
{
|
||||
window->win32.taskbarList->lpVtbl->AddRef(window->win32.taskbarList);
|
||||
window->win32.taskbarList->lpVtbl->HrInit(window->win32.taskbarList);
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
@ -1381,7 +1389,7 @@ static int createNativeWindow(_GLFWwindow* window,
|
||||
frameHeight = rect.bottom - rect.top;
|
||||
}
|
||||
|
||||
wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
|
||||
wideTitle = _glfwCreateWideStringFromUTF8Win32(window->title);
|
||||
if (!wideTitle)
|
||||
return GLFW_FALSE;
|
||||
|
||||
@ -1407,15 +1415,13 @@ static int createNativeWindow(_GLFWwindow* window,
|
||||
|
||||
SetPropW(window->win32.handle, L"GLFW", window);
|
||||
|
||||
if (IsWindows7OrGreater())
|
||||
{
|
||||
ChangeWindowMessageFilterEx(window->win32.handle,
|
||||
WM_DROPFILES, MSGFLT_ALLOW, NULL);
|
||||
ChangeWindowMessageFilterEx(window->win32.handle,
|
||||
WM_COPYDATA, MSGFLT_ALLOW, NULL);
|
||||
ChangeWindowMessageFilterEx(window->win32.handle,
|
||||
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
|
||||
}
|
||||
ChangeWindowMessageFilterEx(window->win32.handle, WM_DROPFILES, MSGFLT_ALLOW, NULL);
|
||||
ChangeWindowMessageFilterEx(window->win32.handle, WM_COPYDATA, MSGFLT_ALLOW, NULL);
|
||||
ChangeWindowMessageFilterEx(window->win32.handle, WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
|
||||
|
||||
window->win32.taskbarListMsgID = RegisterWindowMessageW(L"TaskbarButtonCreated");
|
||||
if (window->win32.taskbarListMsgID)
|
||||
ChangeWindowMessageFilterEx(window->win32.handle, window->win32.taskbarListMsgID, MSGFLT_ALLOW, NULL);
|
||||
|
||||
window->win32.scaleToMonitor = wndconfig->scaleToMonitor;
|
||||
window->win32.keymenu = wndconfig->win32.keymenu;
|
||||
@ -1568,6 +1574,9 @@ void _glfwDestroyWindowWin32(_GLFWwindow* window)
|
||||
if (_glfw.win32.capturedCursorWindow == window)
|
||||
releaseCursor();
|
||||
|
||||
if (window->win32.taskbarList)
|
||||
window->win32.taskbarList->lpVtbl->Release(window->win32.taskbarList);
|
||||
|
||||
if (window->win32.handle)
|
||||
{
|
||||
RemovePropW(window->win32.handle, L"GLFW");
|
||||
@ -1630,6 +1639,47 @@ void _glfwSetWindowIconWin32(_GLFWwindow* window, int count, const GLFWimage* im
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwSetWindowProgressIndicatorWin32(_GLFWwindow* window, int progressState, double value)
|
||||
{
|
||||
HRESULT res = S_OK;
|
||||
int winProgressState = 0;
|
||||
int progressValue = (int)(value * 100.0);
|
||||
|
||||
if(!window->win32.taskbarList)
|
||||
return;
|
||||
|
||||
res = window->win32.taskbarList->lpVtbl->SetProgressValue(window->win32.taskbarList, window->win32.handle, progressValue, 100);
|
||||
if(res != S_OK)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, "Win32: Failed to set taskbar progress value");
|
||||
return;
|
||||
}
|
||||
|
||||
switch(progressState)
|
||||
{
|
||||
case GLFW_PROGRESS_INDICATOR_INDETERMINATE:
|
||||
winProgressState = TBPF_INDETERMINATE;
|
||||
break;
|
||||
case GLFW_PROGRESS_INDICATOR_NORMAL:
|
||||
winProgressState = TBPF_NORMAL;
|
||||
break;
|
||||
case GLFW_PROGRESS_INDICATOR_ERROR:
|
||||
winProgressState = TBPF_ERROR;
|
||||
break;
|
||||
case GLFW_PROGRESS_INDICATOR_PAUSED:
|
||||
winProgressState = TBPF_PAUSED;
|
||||
break;
|
||||
|
||||
default:
|
||||
winProgressState = TBPF_NOPROGRESS;
|
||||
break;
|
||||
}
|
||||
|
||||
res = window->win32.taskbarList->lpVtbl->SetProgressState(window->win32.taskbarList, window->win32.handle, winProgressState);
|
||||
if (res != S_OK)
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, "Win32: Failed to set taskbar progress state");
|
||||
}
|
||||
|
||||
void _glfwGetWindowPosWin32(_GLFWwindow* window, int* xpos, int* ypos)
|
||||
{
|
||||
POINT pos = { 0, 0 };
|
||||
@ -1981,9 +2031,6 @@ GLFWbool _glfwFramebufferTransparentWin32(_GLFWwindow* window)
|
||||
if (!window->win32.transparent)
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!IsWindowsVistaOrGreater())
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (FAILED(DwmIsCompositionEnabled(&composition)) || !composition)
|
||||
return GLFW_FALSE;
|
||||
|
||||
|
||||
26
src/window.c
26
src/window.c
@ -208,7 +208,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
|
||||
wndconfig.width = width;
|
||||
wndconfig.height = height;
|
||||
wndconfig.title = title;
|
||||
ctxconfig.share = (_GLFWwindow*) share;
|
||||
|
||||
if (!_glfwIsValidContextConfig(&ctxconfig))
|
||||
@ -579,6 +578,31 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle,
|
||||
_glfw.platform.setWindowIcon(window, count, images);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSetWindowProgressIndicator(GLFWwindow* handle, int progressState, double value)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (value < 0.0 || value > 1.0)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, "Invalid progress amount for window progress indicator");
|
||||
return;
|
||||
}
|
||||
|
||||
if (progressState != GLFW_PROGRESS_INDICATOR_DISABLED && progressState != GLFW_PROGRESS_INDICATOR_INDETERMINATE &&
|
||||
progressState != GLFW_PROGRESS_INDICATOR_NORMAL && progressState != GLFW_PROGRESS_INDICATOR_ERROR &&
|
||||
progressState != GLFW_PROGRESS_INDICATOR_PAUSED)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid progress state 0x%08X", progressState);
|
||||
return;
|
||||
}
|
||||
|
||||
_glfw.platform.setWindowProgressIndicator(window, progressState, value);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos)
|
||||
{
|
||||
if (xpos)
|
||||
|
||||
@ -477,6 +477,7 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform)
|
||||
.destroyWindow = _glfwDestroyWindowWayland,
|
||||
.setWindowTitle = _glfwSetWindowTitleWayland,
|
||||
.setWindowIcon = _glfwSetWindowIconWayland,
|
||||
.setWindowProgressIndicator = _glfwSetWindowProgressIndicatorWayland,
|
||||
.getWindowPos = _glfwGetWindowPosWayland,
|
||||
.setWindowPos = _glfwSetWindowPosWayland,
|
||||
.getWindowSize = _glfwGetWindowSizeWayland,
|
||||
@ -563,6 +564,8 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform)
|
||||
|
||||
int _glfwInitWayland(void)
|
||||
{
|
||||
_glfwInitDBusPOSIX();
|
||||
|
||||
// These must be set before any failure checks
|
||||
_glfw.wl.keyRepeatTimerfd = -1;
|
||||
_glfw.wl.cursorTimerfd = -1;
|
||||
@ -1002,6 +1005,8 @@ void _glfwTerminateWayland(void)
|
||||
close(_glfw.wl.cursorTimerfd);
|
||||
|
||||
_glfw_free(_glfw.wl.clipboardString);
|
||||
|
||||
_glfwTerminateDBusPOSIX();
|
||||
}
|
||||
|
||||
#endif // _GLFW_WAYLAND
|
||||
|
||||
@ -217,62 +217,62 @@ struct libdecor_configuration;
|
||||
|
||||
enum libdecor_error
|
||||
{
|
||||
LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE,
|
||||
LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION,
|
||||
LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE,
|
||||
LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION,
|
||||
};
|
||||
|
||||
enum libdecor_window_state
|
||||
{
|
||||
LIBDECOR_WINDOW_STATE_NONE = 0,
|
||||
LIBDECOR_WINDOW_STATE_ACTIVE = 1,
|
||||
LIBDECOR_WINDOW_STATE_MAXIMIZED = 2,
|
||||
LIBDECOR_WINDOW_STATE_FULLSCREEN = 4,
|
||||
LIBDECOR_WINDOW_STATE_TILED_LEFT = 8,
|
||||
LIBDECOR_WINDOW_STATE_TILED_RIGHT = 16,
|
||||
LIBDECOR_WINDOW_STATE_TILED_TOP = 32,
|
||||
LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 64
|
||||
LIBDECOR_WINDOW_STATE_NONE = 0,
|
||||
LIBDECOR_WINDOW_STATE_ACTIVE = 1,
|
||||
LIBDECOR_WINDOW_STATE_MAXIMIZED = 2,
|
||||
LIBDECOR_WINDOW_STATE_FULLSCREEN = 4,
|
||||
LIBDECOR_WINDOW_STATE_TILED_LEFT = 8,
|
||||
LIBDECOR_WINDOW_STATE_TILED_RIGHT = 16,
|
||||
LIBDECOR_WINDOW_STATE_TILED_TOP = 32,
|
||||
LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 64
|
||||
};
|
||||
|
||||
enum libdecor_capabilities
|
||||
{
|
||||
LIBDECOR_ACTION_MOVE = 1,
|
||||
LIBDECOR_ACTION_RESIZE = 2,
|
||||
LIBDECOR_ACTION_MINIMIZE = 4,
|
||||
LIBDECOR_ACTION_FULLSCREEN = 8,
|
||||
LIBDECOR_ACTION_CLOSE = 16
|
||||
LIBDECOR_ACTION_MOVE = 1,
|
||||
LIBDECOR_ACTION_RESIZE = 2,
|
||||
LIBDECOR_ACTION_MINIMIZE = 4,
|
||||
LIBDECOR_ACTION_FULLSCREEN = 8,
|
||||
LIBDECOR_ACTION_CLOSE = 16
|
||||
};
|
||||
|
||||
struct libdecor_interface
|
||||
{
|
||||
void (* error)(struct libdecor*,enum libdecor_error,const char*);
|
||||
void (* reserved0)(void);
|
||||
void (* reserved1)(void);
|
||||
void (* reserved2)(void);
|
||||
void (* reserved3)(void);
|
||||
void (* reserved4)(void);
|
||||
void (* reserved5)(void);
|
||||
void (* reserved6)(void);
|
||||
void (* reserved7)(void);
|
||||
void (* reserved8)(void);
|
||||
void (* reserved9)(void);
|
||||
void (* error)(struct libdecor*,enum libdecor_error,const char*);
|
||||
void (* reserved0)(void);
|
||||
void (* reserved1)(void);
|
||||
void (* reserved2)(void);
|
||||
void (* reserved3)(void);
|
||||
void (* reserved4)(void);
|
||||
void (* reserved5)(void);
|
||||
void (* reserved6)(void);
|
||||
void (* reserved7)(void);
|
||||
void (* reserved8)(void);
|
||||
void (* reserved9)(void);
|
||||
};
|
||||
|
||||
struct libdecor_frame_interface
|
||||
{
|
||||
void (* configure)(struct libdecor_frame*,struct libdecor_configuration*,void*);
|
||||
void (* close)(struct libdecor_frame*,void*);
|
||||
void (* commit)(struct libdecor_frame*,void*);
|
||||
void (* dismiss_popup)(struct libdecor_frame*,const char*,void*);
|
||||
void (* reserved0)(void);
|
||||
void (* reserved1)(void);
|
||||
void (* reserved2)(void);
|
||||
void (* reserved3)(void);
|
||||
void (* reserved4)(void);
|
||||
void (* reserved5)(void);
|
||||
void (* reserved6)(void);
|
||||
void (* reserved7)(void);
|
||||
void (* reserved8)(void);
|
||||
void (* reserved9)(void);
|
||||
void (* configure)(struct libdecor_frame*,struct libdecor_configuration*,void*);
|
||||
void (* close)(struct libdecor_frame*,void*);
|
||||
void (* commit)(struct libdecor_frame*,void*);
|
||||
void (* dismiss_popup)(struct libdecor_frame*,const char*,void*);
|
||||
void (* reserved0)(void);
|
||||
void (* reserved1)(void);
|
||||
void (* reserved2)(void);
|
||||
void (* reserved3)(void);
|
||||
void (* reserved4)(void);
|
||||
void (* reserved5)(void);
|
||||
void (* reserved6)(void);
|
||||
void (* reserved7)(void);
|
||||
void (* reserved8)(void);
|
||||
void (* reserved9)(void);
|
||||
};
|
||||
|
||||
typedef struct libdecor* (* PFN_libdecor_new)(struct wl_display*,const struct libdecor_interface*);
|
||||
@ -413,6 +413,8 @@ typedef struct _GLFWwindowWayland
|
||||
struct wl_buffer* buffer;
|
||||
_GLFWfallbackEdgeWayland top, left, right, bottom;
|
||||
struct wl_surface* focus;
|
||||
wl_fixed_t pointerX, pointerY;
|
||||
const char* cursorName;
|
||||
} fallback;
|
||||
} _GLFWwindowWayland;
|
||||
|
||||
@ -454,7 +456,6 @@ typedef struct _GLFWlibraryWayland
|
||||
struct wl_cursor_theme* cursorTheme;
|
||||
struct wl_cursor_theme* cursorThemeHiDPI;
|
||||
struct wl_surface* cursorSurface;
|
||||
const char* cursorPreviousName;
|
||||
int cursorTimerfd;
|
||||
uint32_t serial;
|
||||
uint32_t pointerEnterSerial;
|
||||
@ -619,6 +620,7 @@ GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window, const _GLFWwndconfig* wnd
|
||||
void _glfwDestroyWindowWayland(_GLFWwindow* window);
|
||||
void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title);
|
||||
void _glfwSetWindowIconWayland(_GLFWwindow* window, int count, const GLFWimage* images);
|
||||
void _glfwSetWindowProgressIndicatorWayland(_GLFWwindow* window, int progressState, double value);
|
||||
void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos);
|
||||
void _glfwSetWindowPosWayland(_GLFWwindow* window, int xpos, int ypos);
|
||||
void _glfwGetWindowSizeWayland(_GLFWwindow* window, int* width, int* height);
|
||||
|
||||
347
src/wl_window.c
347
src/wl_window.c
@ -275,6 +275,152 @@ static void destroyFallbackDecorations(_GLFWwindow* window)
|
||||
destroyFallbackEdge(&window->wl.fallback.bottom);
|
||||
}
|
||||
|
||||
static void updateFallbackDecorationCursor(_GLFWwindow* window,
|
||||
wl_fixed_t sx,
|
||||
wl_fixed_t sy)
|
||||
{
|
||||
window->wl.fallback.pointerX = sx;
|
||||
window->wl.fallback.pointerY = sy;
|
||||
|
||||
const double xpos = wl_fixed_to_double(sx);
|
||||
const double ypos = wl_fixed_to_double(sy);
|
||||
const char* cursorName = "left_ptr";
|
||||
|
||||
if (window->resizable)
|
||||
{
|
||||
if (window->wl.fallback.focus == window->wl.fallback.top.surface)
|
||||
{
|
||||
if (ypos < GLFW_BORDER_SIZE)
|
||||
cursorName = "n-resize";
|
||||
}
|
||||
else if (window->wl.fallback.focus == window->wl.fallback.left.surface)
|
||||
{
|
||||
if (ypos < GLFW_BORDER_SIZE)
|
||||
cursorName = "nw-resize";
|
||||
else
|
||||
cursorName = "w-resize";
|
||||
}
|
||||
else if (window->wl.fallback.focus == window->wl.fallback.right.surface)
|
||||
{
|
||||
if (ypos < GLFW_BORDER_SIZE)
|
||||
cursorName = "ne-resize";
|
||||
else
|
||||
cursorName = "e-resize";
|
||||
}
|
||||
else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)
|
||||
{
|
||||
if (xpos < GLFW_BORDER_SIZE)
|
||||
cursorName = "sw-resize";
|
||||
else if (xpos > window->wl.width + GLFW_BORDER_SIZE)
|
||||
cursorName = "se-resize";
|
||||
else
|
||||
cursorName = "s-resize";
|
||||
}
|
||||
}
|
||||
|
||||
if (window->wl.fallback.cursorName != cursorName)
|
||||
{
|
||||
struct wl_surface* surface = _glfw.wl.cursorSurface;
|
||||
struct wl_cursor_theme* theme = _glfw.wl.cursorTheme;
|
||||
int scale = 1;
|
||||
|
||||
if (window->wl.bufferScale > 1 && _glfw.wl.cursorThemeHiDPI)
|
||||
{
|
||||
// We only support up to scale=2 for now, since libwayland-cursor
|
||||
// requires us to load a different theme for each size.
|
||||
scale = 2;
|
||||
theme = _glfw.wl.cursorThemeHiDPI;
|
||||
}
|
||||
|
||||
struct wl_cursor* cursor = wl_cursor_theme_get_cursor(theme, cursorName);
|
||||
if (!cursor)
|
||||
return;
|
||||
|
||||
// TODO: handle animated cursors too.
|
||||
struct wl_cursor_image* image = cursor->images[0];
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
struct wl_buffer* buffer = wl_cursor_image_get_buffer(image);
|
||||
if (!buffer)
|
||||
return;
|
||||
|
||||
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial,
|
||||
surface,
|
||||
image->hotspot_x / scale,
|
||||
image->hotspot_y / scale);
|
||||
wl_surface_set_buffer_scale(surface, scale);
|
||||
wl_surface_attach(surface, buffer, 0, 0);
|
||||
wl_surface_damage(surface, 0, 0, image->width, image->height);
|
||||
wl_surface_commit(surface);
|
||||
|
||||
window->wl.fallback.cursorName = cursorName;
|
||||
}
|
||||
}
|
||||
|
||||
static void handleFallbackDecorationButton(_GLFWwindow* window,
|
||||
uint32_t serial,
|
||||
uint32_t button)
|
||||
{
|
||||
const double xpos = wl_fixed_to_double(window->wl.fallback.pointerX);
|
||||
const double ypos = wl_fixed_to_double(window->wl.fallback.pointerY);
|
||||
|
||||
if (button == BTN_LEFT)
|
||||
{
|
||||
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
|
||||
|
||||
if (window->wl.fallback.focus == window->wl.fallback.top.surface)
|
||||
{
|
||||
if (ypos < GLFW_BORDER_SIZE)
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
|
||||
else
|
||||
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
|
||||
}
|
||||
else if (window->wl.fallback.focus == window->wl.fallback.left.surface)
|
||||
{
|
||||
if (ypos < GLFW_BORDER_SIZE)
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
|
||||
else
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
|
||||
}
|
||||
else if (window->wl.fallback.focus == window->wl.fallback.right.surface)
|
||||
{
|
||||
if (ypos < GLFW_BORDER_SIZE)
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
|
||||
else
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
|
||||
}
|
||||
else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)
|
||||
{
|
||||
if (xpos < GLFW_BORDER_SIZE)
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
|
||||
else if (xpos > window->wl.width + GLFW_BORDER_SIZE)
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
|
||||
else
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
|
||||
}
|
||||
|
||||
if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE)
|
||||
xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat, serial, edges);
|
||||
}
|
||||
else if (button == BTN_RIGHT)
|
||||
{
|
||||
if (!window->wl.xdg.toplevel)
|
||||
return;
|
||||
|
||||
if (window->wl.fallback.focus != window->wl.fallback.top.surface)
|
||||
return;
|
||||
|
||||
if (ypos < GLFW_BORDER_SIZE)
|
||||
return;
|
||||
|
||||
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
|
||||
_glfw.wl.seat, serial,
|
||||
xpos,
|
||||
ypos - GLFW_CAPTION_HEIGHT - GLFW_BORDER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
static void xdgDecorationHandleConfigure(void* userData,
|
||||
struct zxdg_toplevel_decoration_v1* decoration,
|
||||
uint32_t mode)
|
||||
@ -1333,6 +1479,7 @@ static char* readDataOfferAsString(struct wl_data_offer* offer, const char* mime
|
||||
if (!longer)
|
||||
{
|
||||
_glfwInputError(GLFW_OUT_OF_MEMORY, NULL);
|
||||
_glfw_free(string);
|
||||
close(fds[0]);
|
||||
return NULL;
|
||||
}
|
||||
@ -1352,6 +1499,7 @@ static char* readDataOfferAsString(struct wl_data_offer* offer, const char* mime
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to read from data offer pipe: %s",
|
||||
strerror(errno));
|
||||
_glfw_free(string);
|
||||
close(fds[0]);
|
||||
return NULL;
|
||||
}
|
||||
@ -1390,11 +1538,21 @@ static void pointerHandleEnter(void* userData,
|
||||
window->wl.hovered = GLFW_TRUE;
|
||||
_glfwSetCursorWayland(window, window->wl.currentCursor);
|
||||
_glfwInputCursorEnter(window, GLFW_TRUE);
|
||||
|
||||
if (window->cursorMode != GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
window->wl.cursorPosX = wl_fixed_to_double(sx);
|
||||
window->wl.cursorPosY = wl_fixed_to_double(sy);
|
||||
_glfwInputCursorPos(window, window->wl.cursorPosX, window->wl.cursorPosY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (window->wl.fallback.decorations)
|
||||
{
|
||||
window->wl.fallback.focus = surface;
|
||||
updateFallbackDecorationCursor(window, sx, sy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1415,7 +1573,6 @@ static void pointerHandleLeave(void* userData,
|
||||
|
||||
_glfw.wl.serial = serial;
|
||||
_glfw.wl.pointerFocus = NULL;
|
||||
_glfw.wl.cursorPreviousName = NULL;
|
||||
|
||||
if (window->wl.hovered)
|
||||
{
|
||||
@ -1425,7 +1582,10 @@ static void pointerHandleLeave(void* userData,
|
||||
else
|
||||
{
|
||||
if (window->wl.fallback.decorations)
|
||||
{
|
||||
window->wl.fallback.focus = NULL;
|
||||
window->wl.fallback.cursorName = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1442,92 +1602,16 @@ static void pointerHandleMotion(void* userData,
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
return;
|
||||
|
||||
const double xpos = wl_fixed_to_double(sx);
|
||||
const double ypos = wl_fixed_to_double(sy);
|
||||
window->wl.cursorPosX = xpos;
|
||||
window->wl.cursorPosY = ypos;
|
||||
|
||||
if (window->wl.hovered)
|
||||
{
|
||||
_glfw.wl.cursorPreviousName = NULL;
|
||||
_glfwInputCursorPos(window, xpos, ypos);
|
||||
return;
|
||||
window->wl.cursorPosX = wl_fixed_to_double(sx);
|
||||
window->wl.cursorPosY = wl_fixed_to_double(sy);
|
||||
_glfwInputCursorPos(window, window->wl.cursorPosX, window->wl.cursorPosY);
|
||||
}
|
||||
|
||||
if (window->wl.fallback.decorations)
|
||||
else
|
||||
{
|
||||
const char* cursorName = "left_ptr";
|
||||
|
||||
if (window->resizable)
|
||||
{
|
||||
if (window->wl.fallback.focus == window->wl.fallback.top.surface)
|
||||
{
|
||||
if (ypos < GLFW_BORDER_SIZE)
|
||||
cursorName = "n-resize";
|
||||
}
|
||||
else if (window->wl.fallback.focus == window->wl.fallback.left.surface)
|
||||
{
|
||||
if (ypos < GLFW_BORDER_SIZE)
|
||||
cursorName = "nw-resize";
|
||||
else
|
||||
cursorName = "w-resize";
|
||||
}
|
||||
else if (window->wl.fallback.focus == window->wl.fallback.right.surface)
|
||||
{
|
||||
if (ypos < GLFW_BORDER_SIZE)
|
||||
cursorName = "ne-resize";
|
||||
else
|
||||
cursorName = "e-resize";
|
||||
}
|
||||
else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)
|
||||
{
|
||||
if (xpos < GLFW_BORDER_SIZE)
|
||||
cursorName = "sw-resize";
|
||||
else if (xpos > window->wl.width + GLFW_BORDER_SIZE)
|
||||
cursorName = "se-resize";
|
||||
else
|
||||
cursorName = "s-resize";
|
||||
}
|
||||
}
|
||||
|
||||
if (_glfw.wl.cursorPreviousName != cursorName)
|
||||
{
|
||||
struct wl_surface* surface = _glfw.wl.cursorSurface;
|
||||
struct wl_cursor_theme* theme = _glfw.wl.cursorTheme;
|
||||
int scale = 1;
|
||||
|
||||
if (window->wl.bufferScale > 1 && _glfw.wl.cursorThemeHiDPI)
|
||||
{
|
||||
// We only support up to scale=2 for now, since libwayland-cursor
|
||||
// requires us to load a different theme for each size.
|
||||
scale = 2;
|
||||
theme = _glfw.wl.cursorThemeHiDPI;
|
||||
}
|
||||
|
||||
struct wl_cursor* cursor = wl_cursor_theme_get_cursor(theme, cursorName);
|
||||
if (!cursor)
|
||||
return;
|
||||
|
||||
// TODO: handle animated cursors too.
|
||||
struct wl_cursor_image* image = cursor->images[0];
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
struct wl_buffer* buffer = wl_cursor_image_get_buffer(image);
|
||||
if (!buffer)
|
||||
return;
|
||||
|
||||
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial,
|
||||
surface,
|
||||
image->hotspot_x / scale,
|
||||
image->hotspot_y / scale);
|
||||
wl_surface_set_buffer_scale(surface, scale);
|
||||
wl_surface_attach(surface, buffer, 0, 0);
|
||||
wl_surface_damage(surface, 0, 0, image->width, image->height);
|
||||
wl_surface_commit(surface);
|
||||
|
||||
_glfw.wl.cursorPreviousName = cursorName;
|
||||
}
|
||||
if (window->wl.fallback.decorations)
|
||||
updateFallbackDecorationCursor(window, sx, sy);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1550,62 +1634,11 @@ static void pointerHandleButton(void* userData,
|
||||
button - BTN_LEFT,
|
||||
state == WL_POINTER_BUTTON_STATE_PRESSED,
|
||||
_glfw.wl.xkb.modifiers);
|
||||
return;
|
||||
}
|
||||
|
||||
if (window->wl.fallback.decorations)
|
||||
else
|
||||
{
|
||||
if (button == BTN_LEFT)
|
||||
{
|
||||
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
|
||||
|
||||
if (window->wl.fallback.focus == window->wl.fallback.top.surface)
|
||||
{
|
||||
if (window->wl.cursorPosY < GLFW_BORDER_SIZE)
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
|
||||
else
|
||||
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
|
||||
}
|
||||
else if (window->wl.fallback.focus == window->wl.fallback.left.surface)
|
||||
{
|
||||
if (window->wl.cursorPosY < GLFW_BORDER_SIZE)
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
|
||||
else
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
|
||||
}
|
||||
else if (window->wl.fallback.focus == window->wl.fallback.right.surface)
|
||||
{
|
||||
if (window->wl.cursorPosY < GLFW_BORDER_SIZE)
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
|
||||
else
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
|
||||
}
|
||||
else if (window->wl.fallback.focus == window->wl.fallback.bottom.surface)
|
||||
{
|
||||
if (window->wl.cursorPosX < GLFW_BORDER_SIZE)
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
|
||||
else if (window->wl.cursorPosX > window->wl.width + GLFW_BORDER_SIZE)
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
|
||||
else
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
|
||||
}
|
||||
|
||||
if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE)
|
||||
{
|
||||
xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat,
|
||||
serial, edges);
|
||||
}
|
||||
}
|
||||
else if (button == BTN_RIGHT)
|
||||
{
|
||||
if (window->wl.xdg.toplevel)
|
||||
{
|
||||
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
|
||||
_glfw.wl.seat, serial,
|
||||
window->wl.cursorPosX,
|
||||
window->wl.cursorPosY);
|
||||
}
|
||||
}
|
||||
if (window->wl.fallback.decorations)
|
||||
handleFallbackDecorationButton(window, serial, button);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1619,11 +1652,14 @@ static void pointerHandleAxis(void* userData,
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
// NOTE: 10 units of motion per mouse wheel step seems to be a common ratio
|
||||
if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
|
||||
_glfwInputScroll(window, -wl_fixed_to_double(value) / 10.0, 0.0);
|
||||
else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
|
||||
_glfwInputScroll(window, 0.0, -wl_fixed_to_double(value) / 10.0);
|
||||
if (window->wl.hovered)
|
||||
{
|
||||
// NOTE: 10 units of motion per mouse wheel step seems to be a common ratio
|
||||
if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
|
||||
_glfwInputScroll(window, -wl_fixed_to_double(value) / 10.0, 0.0);
|
||||
else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
|
||||
_glfwInputScroll(window, 0.0, -wl_fixed_to_double(value) / 10.0);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_pointer_listener pointerListener =
|
||||
@ -1800,11 +1836,12 @@ static void keyboardHandleKey(void* userData,
|
||||
|
||||
timer.it_value.tv_sec = _glfw.wl.keyRepeatDelay / 1000;
|
||||
timer.it_value.tv_nsec = (_glfw.wl.keyRepeatDelay % 1000) * 1000000;
|
||||
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
||||
}
|
||||
} else if (scancode == _glfw.wl.keyRepeatScancode) {
|
||||
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
||||
}
|
||||
|
||||
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
||||
|
||||
_glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers);
|
||||
|
||||
if (action == GLFW_PRESS)
|
||||
@ -2178,6 +2215,14 @@ GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window,
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
//Reset progress state as it gets saved between application runs
|
||||
if(_glfw.dbus.connection)
|
||||
{
|
||||
//Window NULL is safe here because it won't get
|
||||
//used inside the SetWindowTaskbarProgress function
|
||||
_glfwSetWindowProgressIndicatorWayland(NULL, GLFW_PROGRESS_INDICATOR_DISABLED, 0.0);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
@ -2187,7 +2232,12 @@ void _glfwDestroyWindowWayland(_GLFWwindow* window)
|
||||
_glfw.wl.pointerFocus = NULL;
|
||||
|
||||
if (window == _glfw.wl.keyboardFocus)
|
||||
{
|
||||
struct itimerspec timer = {0};
|
||||
timerfd_settime(_glfw.wl.keyRepeatTimerfd, 0, &timer, NULL);
|
||||
|
||||
_glfw.wl.keyboardFocus = NULL;
|
||||
}
|
||||
|
||||
if (window->wl.fractionalScale)
|
||||
wp_fractional_scale_v1_destroy(window->wl.fractionalScale);
|
||||
@ -2243,6 +2293,15 @@ void _glfwSetWindowIconWayland(_GLFWwindow* window,
|
||||
"Wayland: The platform does not support setting the window icon");
|
||||
}
|
||||
|
||||
void _glfwSetWindowProgressIndicatorWayland(_GLFWwindow* window, const int progressState, double value)
|
||||
{
|
||||
(void)window;
|
||||
|
||||
const dbus_bool_t progressVisible = (progressState != GLFW_PROGRESS_INDICATOR_DISABLED);
|
||||
|
||||
_glfwUpdateTaskbarProgressDBusPOSIX(progressVisible, value);
|
||||
}
|
||||
|
||||
void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos)
|
||||
{
|
||||
// A Wayland client is not aware of its position, so just warn and leave it
|
||||
|
||||
@ -1208,6 +1208,7 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
|
||||
.destroyWindow = _glfwDestroyWindowX11,
|
||||
.setWindowTitle = _glfwSetWindowTitleX11,
|
||||
.setWindowIcon = _glfwSetWindowIconX11,
|
||||
.setWindowProgressIndicator = _glfwSetWindowProgressIndicatorX11,
|
||||
.getWindowPos = _glfwGetWindowPosX11,
|
||||
.setWindowPos = _glfwSetWindowPosX11,
|
||||
.getWindowSize = _glfwGetWindowSizeX11,
|
||||
@ -1320,6 +1321,8 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
|
||||
|
||||
int _glfwInitX11(void)
|
||||
{
|
||||
_glfwInitDBusPOSIX();
|
||||
|
||||
_glfw.x11.xlib.AllocClassHint = (PFN_XAllocClassHint)
|
||||
_glfwPlatformGetModuleSymbol(_glfw.x11.xlib.handle, "XAllocClassHint");
|
||||
_glfw.x11.xlib.AllocSizeHints = (PFN_XAllocSizeHints)
|
||||
@ -1651,6 +1654,8 @@ void _glfwTerminateX11(void)
|
||||
close(_glfw.x11.emptyEventPipe[0]);
|
||||
close(_glfw.x11.emptyEventPipe[1]);
|
||||
}
|
||||
|
||||
_glfwTerminateDBusPOSIX();
|
||||
}
|
||||
|
||||
#endif // _GLFW_X11
|
||||
|
||||
@ -470,6 +470,7 @@ typedef struct _GLFWcontextGLX
|
||||
{
|
||||
GLXContext handle;
|
||||
GLXWindow window;
|
||||
GLXFBConfig fbconfig;
|
||||
} _GLFWcontextGLX;
|
||||
|
||||
// GLX-specific global data
|
||||
@ -905,6 +906,7 @@ GLFWbool _glfwCreateWindowX11(_GLFWwindow* window, const _GLFWwndconfig* wndconf
|
||||
void _glfwDestroyWindowX11(_GLFWwindow* window);
|
||||
void _glfwSetWindowTitleX11(_GLFWwindow* window, const char* title);
|
||||
void _glfwSetWindowIconX11(_GLFWwindow* window, int count, const GLFWimage* images);
|
||||
void _glfwSetWindowProgressIndicatorX11(_GLFWwindow* window, int progressState, double value);
|
||||
void _glfwGetWindowPosX11(_GLFWwindow* window, int* xpos, int* ypos);
|
||||
void _glfwSetWindowPosX11(_GLFWwindow* window, int xpos, int ypos);
|
||||
void _glfwGetWindowSizeX11(_GLFWwindow* window, int* width, int* height);
|
||||
|
||||
@ -754,13 +754,13 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
const char* resourceName = getenv("RESOURCE_NAME");
|
||||
if (resourceName && strlen(resourceName))
|
||||
hint->res_name = (char*) resourceName;
|
||||
else if (strlen(wndconfig->title))
|
||||
hint->res_name = (char*) wndconfig->title;
|
||||
else if (strlen(window->title))
|
||||
hint->res_name = (char*) window->title;
|
||||
else
|
||||
hint->res_name = (char*) "glfw-application";
|
||||
|
||||
if (strlen(wndconfig->title))
|
||||
hint->res_class = (char*) wndconfig->title;
|
||||
if (strlen(window->title))
|
||||
hint->res_class = (char*) window->title;
|
||||
else
|
||||
hint->res_class = (char*) "GLFW-Application";
|
||||
}
|
||||
@ -780,7 +780,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
if (_glfw.x11.im)
|
||||
_glfwCreateInputContextX11(window);
|
||||
|
||||
_glfwSetWindowTitleX11(window, wndconfig->title);
|
||||
_glfwSetWindowTitleX11(window, window->title);
|
||||
_glfwGetWindowPosX11(window, &window->x11.xpos, &window->x11.ypos);
|
||||
_glfwGetWindowSizeX11(window, &window->x11.width, &window->x11.height);
|
||||
|
||||
@ -2040,6 +2040,14 @@ GLFWbool _glfwCreateWindowX11(_GLFWwindow* window,
|
||||
}
|
||||
}
|
||||
|
||||
//Reset progress state as it gets saved between application runs
|
||||
if(_glfw.dbus.connection)
|
||||
{
|
||||
//Window NULL is safe here because it won't get
|
||||
//used inside the SetWindowTaskbarProgress function
|
||||
_glfwSetWindowProgressIndicatorX11(NULL, GLFW_PROGRESS_INDICATOR_DISABLED, 0.0);
|
||||
}
|
||||
|
||||
XFlush(_glfw.x11.display);
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
@ -2152,6 +2160,15 @@ void _glfwSetWindowIconX11(_GLFWwindow* window, int count, const GLFWimage* imag
|
||||
XFlush(_glfw.x11.display);
|
||||
}
|
||||
|
||||
void _glfwSetWindowProgressIndicatorX11(_GLFWwindow* window, int progressState, double value)
|
||||
{
|
||||
(void)window;
|
||||
|
||||
const dbus_bool_t progressVisible = (progressState != GLFW_PROGRESS_INDICATOR_DISABLED);
|
||||
|
||||
_glfwUpdateTaskbarProgressDBusPOSIX(progressVisible, value);
|
||||
}
|
||||
|
||||
void _glfwGetWindowPosX11(_GLFWwindow* window, int* xpos, int* ypos)
|
||||
{
|
||||
Window dummy;
|
||||
|
||||
@ -72,7 +72,7 @@ int main(int argc, char** argv)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
||||
|
||||
GLFWwindow* window = glfwCreateWindow(600, 660, "Window Features", NULL, NULL);
|
||||
GLFWwindow* window = glfwCreateWindow(600, 700, "Window Features", NULL, NULL);
|
||||
if (!window)
|
||||
{
|
||||
glfwTerminate();
|
||||
@ -441,6 +441,29 @@ int main(int argc, char** argv)
|
||||
nk_value_bool(nk, "Visible", glfwGetWindowAttrib(window, GLFW_VISIBLE));
|
||||
nk_value_bool(nk, "Iconified", glfwGetWindowAttrib(window, GLFW_ICONIFIED));
|
||||
nk_value_bool(nk, "Maximized", glfwGetWindowAttrib(window, GLFW_MAXIMIZED));
|
||||
|
||||
nk_layout_row_dynamic(nk, 30, 1);
|
||||
|
||||
nk_label(nk, "Window Progress indicator", NK_TEXT_CENTERED);
|
||||
|
||||
nk_layout_row_dynamic(nk, 30, 5);
|
||||
|
||||
static int state = GLFW_PROGRESS_INDICATOR_DISABLED;
|
||||
static float progress = 0;
|
||||
if(nk_button_label(nk, "No progress"))
|
||||
glfwSetWindowProgressIndicator(window, state = GLFW_PROGRESS_INDICATOR_DISABLED, (double) progress);
|
||||
if (nk_button_label(nk, "Indeterminate"))
|
||||
glfwSetWindowProgressIndicator(window, state = GLFW_PROGRESS_INDICATOR_INDETERMINATE, (double) progress);
|
||||
if (nk_button_label(nk, "Normal"))
|
||||
glfwSetWindowProgressIndicator(window, state = GLFW_PROGRESS_INDICATOR_NORMAL, (double) progress);
|
||||
if (nk_button_label(nk, "Error"))
|
||||
glfwSetWindowProgressIndicator(window, state = GLFW_PROGRESS_INDICATOR_ERROR, (double) progress);
|
||||
if (nk_button_label(nk, "Paused"))
|
||||
glfwSetWindowProgressIndicator(window, state = GLFW_PROGRESS_INDICATOR_PAUSED, (double) progress);
|
||||
|
||||
nk_label(nk, "Progress: ", NK_TEXT_ALIGN_LEFT);
|
||||
if (nk_slider_float(nk, 0.0f, &progress, 1.0f, 0.05f))
|
||||
glfwSetWindowProgressIndicator(window, state, (double) progress);
|
||||
}
|
||||
nk_end(nk);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user