mirror of
https://github.com/gwm17/glfw.git
synced 2024-11-22 10:18:51 -05:00
Compare commits
30 Commits
7fdb858a47
...
a3005b6cbe
Author | SHA1 | Date | |
---|---|---|---|
a3005b6cbe | |||
3fa2360720 | |||
0b94e1b29b | |||
f27daa34ad | |||
6f2d7064be | |||
9cce2896ee | |||
23ab972724 | |||
fbdb53b9ca | |||
cd466cf9fd | |||
39f0e86228 | |||
efa9297a41 | |||
91c837ace5 | |||
6d9083af03 | |||
4cf510511c | |||
c1a79c1c41 | |||
8397b39afa | |||
735fc101f5 | |||
228428fa4f | |||
82e77dbff4 | |||
9a87635686 | |||
2b580012da | |||
5c463a9070 | |||
9b1f63bad9 | |||
1c9fcdc9df | |||
30b91c8b60 | |||
e0ae1c45df | |||
8f470597d6 | |||
57cbded076 | |||
41d8da1cea | |||
00967cbb8a |
9
.github/workflows/build.yml
vendored
9
.github/workflows/build.yml
vendored
|
@ -3,6 +3,7 @@ on:
|
||||||
pull_request:
|
pull_request:
|
||||||
push:
|
push:
|
||||||
branches: [ ci, master, latest, 3.3-stable ]
|
branches: [ ci, master, latest, 3.3-stable ]
|
||||||
|
workflow_dispatch:
|
||||||
permissions:
|
permissions:
|
||||||
statuses: write
|
statuses: write
|
||||||
contents: read
|
contents: read
|
||||||
|
@ -15,7 +16,7 @@ jobs:
|
||||||
CC: clang
|
CC: clang
|
||||||
CFLAGS: -Werror
|
CFLAGS: -Werror
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt update
|
sudo apt update
|
||||||
|
@ -38,7 +39,7 @@ jobs:
|
||||||
CC: clang
|
CC: clang
|
||||||
CFLAGS: -Werror
|
CFLAGS: -Werror
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt update
|
sudo apt update
|
||||||
|
@ -61,7 +62,7 @@ jobs:
|
||||||
CFLAGS: -Werror
|
CFLAGS: -Werror
|
||||||
MACOSX_DEPLOYMENT_TARGET: 10.8
|
MACOSX_DEPLOYMENT_TARGET: 10.8
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Configure static library
|
- name: Configure static library
|
||||||
run: cmake -S . -B build-static
|
run: cmake -S . -B build-static
|
||||||
|
@ -79,7 +80,7 @@ jobs:
|
||||||
env:
|
env:
|
||||||
CFLAGS: /WX
|
CFLAGS: /WX
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Configure static library
|
- name: Configure static library
|
||||||
run: cmake -S . -B build-static -G "Visual Studio 17 2022"
|
run: cmake -S . -B build-static -G "Visual Studio 17 2022"
|
||||||
|
|
|
@ -2,12 +2,6 @@ cmake_minimum_required(VERSION 3.4...3.20 FATAL_ERROR)
|
||||||
|
|
||||||
project(GLFW VERSION 3.4.0 LANGUAGES C)
|
project(GLFW VERSION 3.4.0 LANGUAGES C)
|
||||||
|
|
||||||
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
|
|
||||||
|
|
||||||
if (POLICY CMP0054)
|
|
||||||
cmake_policy(SET CMP0054 NEW)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (POLICY CMP0069)
|
if (POLICY CMP0069)
|
||||||
cmake_policy(SET CMP0069 NEW)
|
cmake_policy(SET CMP0069 NEW)
|
||||||
endif()
|
endif()
|
||||||
|
@ -18,9 +12,7 @@ endif()
|
||||||
|
|
||||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
||||||
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
string(COMPARE EQUAL "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}" GLFW_STANDALONE)
|
||||||
set(GLFW_STANDALONE TRUE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
|
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
|
||||||
option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ${GLFW_STANDALONE})
|
option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ${GLFW_STANDALONE})
|
||||||
|
|
|
@ -8,6 +8,7 @@ video tutorials.
|
||||||
- Bobyshev Alexander
|
- Bobyshev Alexander
|
||||||
- Laurent Aphecetche
|
- Laurent Aphecetche
|
||||||
- Matt Arsenault
|
- Matt Arsenault
|
||||||
|
- Takuro Ashie
|
||||||
- ashishgamedev
|
- ashishgamedev
|
||||||
- David Avedissian
|
- David Avedissian
|
||||||
- Luca Bacci
|
- Luca Bacci
|
||||||
|
@ -187,6 +188,7 @@ video tutorials.
|
||||||
- pthom
|
- pthom
|
||||||
- Martin Pulec
|
- Martin Pulec
|
||||||
- Guillaume Racicot
|
- Guillaume Racicot
|
||||||
|
- Juan Ramos
|
||||||
- Christian Rauch
|
- Christian Rauch
|
||||||
- Philip Rideout
|
- Philip Rideout
|
||||||
- Eddie Ringle
|
- Eddie Ringle
|
||||||
|
@ -199,6 +201,7 @@ video tutorials.
|
||||||
- Aleksey Rybalkin
|
- Aleksey Rybalkin
|
||||||
- Mikko Rytkönen
|
- Mikko Rytkönen
|
||||||
- Riku Salminen
|
- Riku Salminen
|
||||||
|
- Yoshinori Sano
|
||||||
- Brandon Schaefer
|
- Brandon Schaefer
|
||||||
- Sebastian Schuberth
|
- Sebastian Schuberth
|
||||||
- Christian Sdunek
|
- Christian Sdunek
|
||||||
|
|
|
@ -311,6 +311,7 @@ information on what to include when reporting a bug.
|
||||||
- [X11] Bugfix: The OSMesa libray was not unloaded on termination
|
- [X11] Bugfix: The OSMesa libray was not unloaded on termination
|
||||||
- [X11] Bugfix: A malformed response during selection transfer could cause a segfault
|
- [X11] Bugfix: A malformed response during selection transfer could cause a segfault
|
||||||
- [X11] Bugfix: Some calls would reset Xlib to the default error handler (#2108)
|
- [X11] Bugfix: Some calls would reset Xlib to the default error handler (#2108)
|
||||||
|
- [Wayland] Added improved fallback window decorations via libdecor (#1639,#1693)
|
||||||
- [Wayland] Added dynamic loading of all Wayland libraries
|
- [Wayland] Added dynamic loading of all Wayland libraries
|
||||||
- [Wayland] Added support for key names via xkbcommon
|
- [Wayland] Added support for key names via xkbcommon
|
||||||
- [Wayland] Added support for file path drop events (#2040)
|
- [Wayland] Added support for file path drop events (#2040)
|
||||||
|
@ -382,6 +383,7 @@ information on what to include when reporting a bug.
|
||||||
- [Wayland] Bugfix: `GLFW_DECORATED` was ignored when showing a window with XDG
|
- [Wayland] Bugfix: `GLFW_DECORATED` was ignored when showing a window with XDG
|
||||||
decorations
|
decorations
|
||||||
- [Wayland] Bugfix: Connecting a mouse after `glfwInit` would segfault (#1450)
|
- [Wayland] Bugfix: Connecting a mouse after `glfwInit` would segfault (#1450)
|
||||||
|
- [Wayland] Bugfix: Joysticks connected after `glfwInit` were not detected (#2198)
|
||||||
- [POSIX] Removed use of deprecated function `gettimeofday`
|
- [POSIX] Removed use of deprecated function `gettimeofday`
|
||||||
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
|
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
|
||||||
- [Linux] Bugfix: Joysticks without buttons were ignored (#2042,#2043)
|
- [Linux] Bugfix: Joysticks without buttons were ignored (#2042,#2043)
|
||||||
|
|
|
@ -128,6 +128,14 @@ wayland-protocols 1.6, and mandatory at build time. If the running compositor
|
||||||
does not support this protocol, the screensaver may start even for full screen
|
does not support this protocol, the screensaver may start even for full screen
|
||||||
windows.
|
windows.
|
||||||
|
|
||||||
|
GLFW uses the [libdecor library](https://gitlab.freedesktop.org/libdecor/libdecor)
|
||||||
|
for window decorations, where available. This in turn provides good quality
|
||||||
|
client-side decorations (drawn by the application) on desktop systems that do
|
||||||
|
not support server-side decorations (drawn by the window manager). On systems
|
||||||
|
that do not provide either libdecor or xdg-decoration, very basic window
|
||||||
|
decorations are provided. These do not include the window title or any caption
|
||||||
|
buttons.
|
||||||
|
|
||||||
GLFW uses the [xdg-decoration
|
GLFW uses the [xdg-decoration
|
||||||
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml)
|
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml)
|
||||||
to request decorations to be drawn around its windows. This protocol is part
|
to request decorations to be drawn around its windows. This protocol is part
|
||||||
|
|
|
@ -144,6 +144,15 @@ the `VK_KHR_xlib_surface` extension. Possible values are `GLFW_TRUE` and
|
||||||
`GLFW_FALSE`. This is ignored on other platforms.
|
`GLFW_FALSE`. This is ignored on other platforms.
|
||||||
|
|
||||||
|
|
||||||
|
@subsubsection init_hints_wayland Wayland specific init hints
|
||||||
|
|
||||||
|
@anchor GLFW_WAYLAND_LIBDECOR_hint
|
||||||
|
__GLFW_WAYLAND_LIBDECOR__ specifies whether to use
|
||||||
|
[libdecor](https://gitlab.freedesktop.org/libdecor/libdecor) for window
|
||||||
|
decorations where available. Possible values are `GLFW_WAYLAND_PREFER_LIBDECOR`
|
||||||
|
and `GLFW_WAYLAND_DISABLE_LIBDECOR`. This is ignored on other platforms.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection init_hints_values Supported and default values
|
@subsubsection init_hints_values Supported and default values
|
||||||
|
|
||||||
Initialization hint | Default value | Supported values
|
Initialization hint | Default value | Supported values
|
||||||
|
@ -154,6 +163,7 @@ Initialization hint | Default value | Supported v
|
||||||
@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
@ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
@ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
@ref GLFW_X11_XCB_VULKAN_SURFACE | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
@ref GLFW_X11_XCB_VULKAN_SURFACE | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
|
@ref GLFW_WAYLAND_LIBDECOR | `GLFW_WAYLAND_PREFER_LIBDECOR` | `GLFW_WAYLAND_PREFER_LIBDECOR` or `GLFW_WAYLAND_DISABLE_LIBDECOR`
|
||||||
|
|
||||||
|
|
||||||
@subsection platform Runtime platform selection
|
@subsection platform Runtime platform selection
|
||||||
|
|
|
@ -43,6 +43,16 @@ to whatever window is behind it. This can also be changed after window
|
||||||
creation with the matching [window attribute](@ref GLFW_MOUSE_PASSTHROUGH_attrib).
|
creation with the matching [window attribute](@ref GLFW_MOUSE_PASSTHROUGH_attrib).
|
||||||
|
|
||||||
|
|
||||||
|
@subsubsection wayland_libdecor_34 Wayland libdecor decorations
|
||||||
|
|
||||||
|
GLFW now supports improved fallback window decorations via
|
||||||
|
[libdecor](https://gitlab.freedesktop.org/libdecor/libdecor).
|
||||||
|
|
||||||
|
Support for libdecor can be toggled before GLFW is initialized with the
|
||||||
|
[GLFW_WAYLAND_LIBDECOR](@ref GLFW_WAYLAND_LIBDECOR_hint) init hint. It is
|
||||||
|
enabled by default.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection wayland_app_id_34 Wayland app_id specification
|
@subsubsection wayland_app_id_34 Wayland app_id specification
|
||||||
|
|
||||||
GLFW now supports specifying the app_id for a Wayland window using the
|
GLFW now supports specifying the app_id for a Wayland window using the
|
||||||
|
@ -267,6 +277,9 @@ then GLFW will fail to initialize.
|
||||||
- @ref GLFW_POSITION_X
|
- @ref GLFW_POSITION_X
|
||||||
- @ref GLFW_POSITION_Y
|
- @ref GLFW_POSITION_Y
|
||||||
- @ref GLFW_ANY_POSITION
|
- @ref GLFW_ANY_POSITION
|
||||||
|
- @ref GLFW_WAYLAND_LIBDECOR
|
||||||
|
- @ref GLFW_WAYLAND_PREFER_LIBDECOR
|
||||||
|
- @ref GLFW_WAYLAND_DISABLE_LIBDECOR
|
||||||
|
|
||||||
|
|
||||||
@section news_archive Release notes for earlier versions
|
@section news_archive Release notes for earlier versions
|
||||||
|
|
|
@ -1164,6 +1164,9 @@ extern "C" {
|
||||||
#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007
|
#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007
|
||||||
#define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008
|
#define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008
|
||||||
|
|
||||||
|
#define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001
|
||||||
|
#define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002
|
||||||
|
|
||||||
#define GLFW_ANY_POSITION 0x80000000
|
#define GLFW_ANY_POSITION 0x80000000
|
||||||
|
|
||||||
/*! @defgroup shapes Standard cursor shapes
|
/*! @defgroup shapes Standard cursor shapes
|
||||||
|
@ -1307,6 +1310,11 @@ extern "C" {
|
||||||
* X11 specific [init hint](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint).
|
* X11 specific [init hint](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint).
|
||||||
*/
|
*/
|
||||||
#define GLFW_X11_XCB_VULKAN_SURFACE 0x00052001
|
#define GLFW_X11_XCB_VULKAN_SURFACE 0x00052001
|
||||||
|
/*! @brief Wayland specific init hint.
|
||||||
|
*
|
||||||
|
* Wayland specific [init hint](@ref GLFW_WAYLAND_LIBDECOR_hint).
|
||||||
|
*/
|
||||||
|
#define GLFW_WAYLAND_LIBDECOR 0x00053001
|
||||||
/*! @} */
|
/*! @} */
|
||||||
|
|
||||||
/*! @addtogroup init
|
/*! @addtogroup init
|
||||||
|
|
|
@ -62,6 +62,9 @@ static _GLFWinitconfig _glfwInitHints =
|
||||||
{
|
{
|
||||||
GLFW_TRUE, // X11 XCB Vulkan surface
|
GLFW_TRUE, // X11 XCB Vulkan surface
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
GLFW_WAYLAND_PREFER_LIBDECOR // Wayland libdecor mode
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// The allocation function used when no custom allocator is set
|
// The allocation function used when no custom allocator is set
|
||||||
|
@ -479,6 +482,9 @@ GLFWAPI void glfwInitHint(int hint, int value)
|
||||||
case GLFW_X11_XCB_VULKAN_SURFACE:
|
case GLFW_X11_XCB_VULKAN_SURFACE:
|
||||||
_glfwInitHints.x11.xcbVulkanSurface = value;
|
_glfwInitHints.x11.xcbVulkanSurface = value;
|
||||||
return;
|
return;
|
||||||
|
case GLFW_WAYLAND_LIBDECOR:
|
||||||
|
_glfwInitHints.wl.libdecorMode = value;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM,
|
_glfwInputError(GLFW_INVALID_ENUM,
|
||||||
|
|
|
@ -379,6 +379,9 @@ struct _GLFWinitconfig
|
||||||
struct {
|
struct {
|
||||||
GLFWbool xcbVulkanSurface;
|
GLFWbool xcbVulkanSurface;
|
||||||
} x11;
|
} x11;
|
||||||
|
struct {
|
||||||
|
int libdecorMode;
|
||||||
|
} wl;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Window configuration
|
// Window configuration
|
||||||
|
|
133
src/null_init.c
133
src/null_init.c
|
@ -30,6 +30,7 @@
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -120,6 +121,138 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
|
||||||
|
|
||||||
int _glfwInitNull(void)
|
int _glfwInitNull(void)
|
||||||
{
|
{
|
||||||
|
int scancode;
|
||||||
|
|
||||||
|
memset(_glfw.null.keycodes, -1, sizeof(_glfw.null.keycodes));
|
||||||
|
memset(_glfw.null.scancodes, -1, sizeof(_glfw.null.scancodes));
|
||||||
|
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_SPACE] = GLFW_KEY_SPACE;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_APOSTROPHE] = GLFW_KEY_APOSTROPHE;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_COMMA] = GLFW_KEY_COMMA;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_MINUS] = GLFW_KEY_MINUS;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_PERIOD] = GLFW_KEY_PERIOD;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_SLASH] = GLFW_KEY_SLASH;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_0] = GLFW_KEY_0;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_1] = GLFW_KEY_1;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_2] = GLFW_KEY_2;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_3] = GLFW_KEY_3;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_4] = GLFW_KEY_4;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_5] = GLFW_KEY_5;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_6] = GLFW_KEY_6;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_7] = GLFW_KEY_7;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_8] = GLFW_KEY_8;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_9] = GLFW_KEY_9;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_SEMICOLON] = GLFW_KEY_SEMICOLON;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_EQUAL] = GLFW_KEY_EQUAL;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_A] = GLFW_KEY_A;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_B] = GLFW_KEY_B;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_C] = GLFW_KEY_C;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_D] = GLFW_KEY_D;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_E] = GLFW_KEY_E;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F] = GLFW_KEY_F;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_G] = GLFW_KEY_G;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_H] = GLFW_KEY_H;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_I] = GLFW_KEY_I;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_J] = GLFW_KEY_J;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_K] = GLFW_KEY_K;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_L] = GLFW_KEY_L;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_M] = GLFW_KEY_M;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_N] = GLFW_KEY_N;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_O] = GLFW_KEY_O;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_P] = GLFW_KEY_P;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_Q] = GLFW_KEY_Q;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_R] = GLFW_KEY_R;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_S] = GLFW_KEY_S;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_T] = GLFW_KEY_T;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_U] = GLFW_KEY_U;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_V] = GLFW_KEY_V;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_W] = GLFW_KEY_W;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_X] = GLFW_KEY_X;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_Y] = GLFW_KEY_Y;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_Z] = GLFW_KEY_Z;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_LEFT_BRACKET] = GLFW_KEY_LEFT_BRACKET;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_BACKSLASH] = GLFW_KEY_BACKSLASH;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT_BRACKET] = GLFW_KEY_RIGHT_BRACKET;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_GRAVE_ACCENT] = GLFW_KEY_GRAVE_ACCENT;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_WORLD_1] = GLFW_KEY_WORLD_1;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_WORLD_2] = GLFW_KEY_WORLD_2;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_ESCAPE] = GLFW_KEY_ESCAPE;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_ENTER] = GLFW_KEY_ENTER;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_TAB] = GLFW_KEY_TAB;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_BACKSPACE] = GLFW_KEY_BACKSPACE;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_INSERT] = GLFW_KEY_INSERT;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_DELETE] = GLFW_KEY_DELETE;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT] = GLFW_KEY_RIGHT;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_LEFT] = GLFW_KEY_LEFT;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_DOWN] = GLFW_KEY_DOWN;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_UP] = GLFW_KEY_UP;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_PAGE_UP] = GLFW_KEY_PAGE_UP;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_PAGE_DOWN] = GLFW_KEY_PAGE_DOWN;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_HOME] = GLFW_KEY_HOME;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_END] = GLFW_KEY_END;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_CAPS_LOCK] = GLFW_KEY_CAPS_LOCK;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_SCROLL_LOCK] = GLFW_KEY_SCROLL_LOCK;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_NUM_LOCK] = GLFW_KEY_NUM_LOCK;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_PRINT_SCREEN] = GLFW_KEY_PRINT_SCREEN;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_PAUSE] = GLFW_KEY_PAUSE;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F1] = GLFW_KEY_F1;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F2] = GLFW_KEY_F2;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F3] = GLFW_KEY_F3;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F4] = GLFW_KEY_F4;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F5] = GLFW_KEY_F5;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F6] = GLFW_KEY_F6;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F7] = GLFW_KEY_F7;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F8] = GLFW_KEY_F8;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F9] = GLFW_KEY_F9;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F10] = GLFW_KEY_F10;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F11] = GLFW_KEY_F11;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F12] = GLFW_KEY_F12;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F13] = GLFW_KEY_F13;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F14] = GLFW_KEY_F14;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F15] = GLFW_KEY_F15;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F16] = GLFW_KEY_F16;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F17] = GLFW_KEY_F17;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F18] = GLFW_KEY_F18;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F19] = GLFW_KEY_F19;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F20] = GLFW_KEY_F20;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F21] = GLFW_KEY_F21;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F22] = GLFW_KEY_F22;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F23] = GLFW_KEY_F23;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F24] = GLFW_KEY_F24;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_F25] = GLFW_KEY_F25;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_0] = GLFW_KEY_KP_0;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_1] = GLFW_KEY_KP_1;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_2] = GLFW_KEY_KP_2;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_3] = GLFW_KEY_KP_3;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_4] = GLFW_KEY_KP_4;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_5] = GLFW_KEY_KP_5;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_6] = GLFW_KEY_KP_6;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_7] = GLFW_KEY_KP_7;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_8] = GLFW_KEY_KP_8;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_9] = GLFW_KEY_KP_9;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_DECIMAL] = GLFW_KEY_KP_DECIMAL;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_DIVIDE] = GLFW_KEY_KP_DIVIDE;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_MULTIPLY] = GLFW_KEY_KP_MULTIPLY;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_SUBTRACT] = GLFW_KEY_KP_SUBTRACT;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_ADD] = GLFW_KEY_KP_ADD;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_ENTER] = GLFW_KEY_KP_ENTER;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_KP_EQUAL] = GLFW_KEY_KP_EQUAL;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_LEFT_SHIFT] = GLFW_KEY_LEFT_SHIFT;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_LEFT_CONTROL] = GLFW_KEY_LEFT_CONTROL;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_LEFT_ALT] = GLFW_KEY_LEFT_ALT;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_LEFT_SUPER] = GLFW_KEY_LEFT_SUPER;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT_SHIFT] = GLFW_KEY_RIGHT_SHIFT;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT_CONTROL] = GLFW_KEY_RIGHT_CONTROL;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT_ALT] = GLFW_KEY_RIGHT_ALT;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT_SUPER] = GLFW_KEY_RIGHT_SUPER;
|
||||||
|
_glfw.null.keycodes[GLFW_NULL_SC_MENU] = GLFW_KEY_MENU;
|
||||||
|
|
||||||
|
for (scancode = GLFW_NULL_SC_FIRST; scancode < GLFW_NULL_SC_LAST; scancode++)
|
||||||
|
{
|
||||||
|
if (_glfw.null.keycodes[scancode] > 0)
|
||||||
|
_glfw.null.scancodes[_glfw.null.keycodes[scancode]] = scancode;
|
||||||
|
}
|
||||||
|
|
||||||
_glfwPollMonitorsNull();
|
_glfwPollMonitorsNull();
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,128 @@
|
||||||
#define GLFW_NULL_CURSOR_STATE
|
#define GLFW_NULL_CURSOR_STATE
|
||||||
#define GLFW_NULL_LIBRARY_CONTEXT_STATE
|
#define GLFW_NULL_LIBRARY_CONTEXT_STATE
|
||||||
|
|
||||||
|
#define GLFW_NULL_SC_FIRST GLFW_NULL_SC_SPACE
|
||||||
|
#define GLFW_NULL_SC_SPACE 1
|
||||||
|
#define GLFW_NULL_SC_APOSTROPHE 2
|
||||||
|
#define GLFW_NULL_SC_COMMA 3
|
||||||
|
#define GLFW_NULL_SC_MINUS 4
|
||||||
|
#define GLFW_NULL_SC_PERIOD 5
|
||||||
|
#define GLFW_NULL_SC_SLASH 6
|
||||||
|
#define GLFW_NULL_SC_0 7
|
||||||
|
#define GLFW_NULL_SC_1 8
|
||||||
|
#define GLFW_NULL_SC_2 9
|
||||||
|
#define GLFW_NULL_SC_3 10
|
||||||
|
#define GLFW_NULL_SC_4 11
|
||||||
|
#define GLFW_NULL_SC_5 12
|
||||||
|
#define GLFW_NULL_SC_6 13
|
||||||
|
#define GLFW_NULL_SC_7 14
|
||||||
|
#define GLFW_NULL_SC_8 15
|
||||||
|
#define GLFW_NULL_SC_9 16
|
||||||
|
#define GLFW_NULL_SC_SEMICOLON 17
|
||||||
|
#define GLFW_NULL_SC_EQUAL 18
|
||||||
|
#define GLFW_NULL_SC_LEFT_BRACKET 19
|
||||||
|
#define GLFW_NULL_SC_BACKSLASH 20
|
||||||
|
#define GLFW_NULL_SC_RIGHT_BRACKET 21
|
||||||
|
#define GLFW_NULL_SC_GRAVE_ACCENT 22
|
||||||
|
#define GLFW_NULL_SC_WORLD_1 23
|
||||||
|
#define GLFW_NULL_SC_WORLD_2 24
|
||||||
|
#define GLFW_NULL_SC_ESCAPE 25
|
||||||
|
#define GLFW_NULL_SC_ENTER 26
|
||||||
|
#define GLFW_NULL_SC_TAB 27
|
||||||
|
#define GLFW_NULL_SC_BACKSPACE 28
|
||||||
|
#define GLFW_NULL_SC_INSERT 29
|
||||||
|
#define GLFW_NULL_SC_DELETE 30
|
||||||
|
#define GLFW_NULL_SC_RIGHT 31
|
||||||
|
#define GLFW_NULL_SC_LEFT 32
|
||||||
|
#define GLFW_NULL_SC_DOWN 33
|
||||||
|
#define GLFW_NULL_SC_UP 34
|
||||||
|
#define GLFW_NULL_SC_PAGE_UP 35
|
||||||
|
#define GLFW_NULL_SC_PAGE_DOWN 36
|
||||||
|
#define GLFW_NULL_SC_HOME 37
|
||||||
|
#define GLFW_NULL_SC_END 38
|
||||||
|
#define GLFW_NULL_SC_CAPS_LOCK 39
|
||||||
|
#define GLFW_NULL_SC_SCROLL_LOCK 40
|
||||||
|
#define GLFW_NULL_SC_NUM_LOCK 41
|
||||||
|
#define GLFW_NULL_SC_PRINT_SCREEN 42
|
||||||
|
#define GLFW_NULL_SC_PAUSE 43
|
||||||
|
#define GLFW_NULL_SC_A 44
|
||||||
|
#define GLFW_NULL_SC_B 45
|
||||||
|
#define GLFW_NULL_SC_C 46
|
||||||
|
#define GLFW_NULL_SC_D 47
|
||||||
|
#define GLFW_NULL_SC_E 48
|
||||||
|
#define GLFW_NULL_SC_F 49
|
||||||
|
#define GLFW_NULL_SC_G 50
|
||||||
|
#define GLFW_NULL_SC_H 51
|
||||||
|
#define GLFW_NULL_SC_I 52
|
||||||
|
#define GLFW_NULL_SC_J 53
|
||||||
|
#define GLFW_NULL_SC_K 54
|
||||||
|
#define GLFW_NULL_SC_L 55
|
||||||
|
#define GLFW_NULL_SC_M 56
|
||||||
|
#define GLFW_NULL_SC_N 57
|
||||||
|
#define GLFW_NULL_SC_O 58
|
||||||
|
#define GLFW_NULL_SC_P 59
|
||||||
|
#define GLFW_NULL_SC_Q 60
|
||||||
|
#define GLFW_NULL_SC_R 61
|
||||||
|
#define GLFW_NULL_SC_S 62
|
||||||
|
#define GLFW_NULL_SC_T 63
|
||||||
|
#define GLFW_NULL_SC_U 64
|
||||||
|
#define GLFW_NULL_SC_V 65
|
||||||
|
#define GLFW_NULL_SC_W 66
|
||||||
|
#define GLFW_NULL_SC_X 67
|
||||||
|
#define GLFW_NULL_SC_Y 68
|
||||||
|
#define GLFW_NULL_SC_Z 69
|
||||||
|
#define GLFW_NULL_SC_F1 70
|
||||||
|
#define GLFW_NULL_SC_F2 71
|
||||||
|
#define GLFW_NULL_SC_F3 72
|
||||||
|
#define GLFW_NULL_SC_F4 73
|
||||||
|
#define GLFW_NULL_SC_F5 74
|
||||||
|
#define GLFW_NULL_SC_F6 75
|
||||||
|
#define GLFW_NULL_SC_F7 76
|
||||||
|
#define GLFW_NULL_SC_F8 77
|
||||||
|
#define GLFW_NULL_SC_F9 78
|
||||||
|
#define GLFW_NULL_SC_F10 79
|
||||||
|
#define GLFW_NULL_SC_F11 80
|
||||||
|
#define GLFW_NULL_SC_F12 81
|
||||||
|
#define GLFW_NULL_SC_F13 82
|
||||||
|
#define GLFW_NULL_SC_F14 83
|
||||||
|
#define GLFW_NULL_SC_F15 84
|
||||||
|
#define GLFW_NULL_SC_F16 85
|
||||||
|
#define GLFW_NULL_SC_F17 86
|
||||||
|
#define GLFW_NULL_SC_F18 87
|
||||||
|
#define GLFW_NULL_SC_F19 88
|
||||||
|
#define GLFW_NULL_SC_F20 89
|
||||||
|
#define GLFW_NULL_SC_F21 90
|
||||||
|
#define GLFW_NULL_SC_F22 91
|
||||||
|
#define GLFW_NULL_SC_F23 92
|
||||||
|
#define GLFW_NULL_SC_F24 93
|
||||||
|
#define GLFW_NULL_SC_F25 94
|
||||||
|
#define GLFW_NULL_SC_KP_0 95
|
||||||
|
#define GLFW_NULL_SC_KP_1 96
|
||||||
|
#define GLFW_NULL_SC_KP_2 97
|
||||||
|
#define GLFW_NULL_SC_KP_3 98
|
||||||
|
#define GLFW_NULL_SC_KP_4 99
|
||||||
|
#define GLFW_NULL_SC_KP_5 100
|
||||||
|
#define GLFW_NULL_SC_KP_6 101
|
||||||
|
#define GLFW_NULL_SC_KP_7 102
|
||||||
|
#define GLFW_NULL_SC_KP_8 103
|
||||||
|
#define GLFW_NULL_SC_KP_9 104
|
||||||
|
#define GLFW_NULL_SC_KP_DECIMAL 105
|
||||||
|
#define GLFW_NULL_SC_KP_DIVIDE 106
|
||||||
|
#define GLFW_NULL_SC_KP_MULTIPLY 107
|
||||||
|
#define GLFW_NULL_SC_KP_SUBTRACT 108
|
||||||
|
#define GLFW_NULL_SC_KP_ADD 109
|
||||||
|
#define GLFW_NULL_SC_KP_ENTER 110
|
||||||
|
#define GLFW_NULL_SC_KP_EQUAL 111
|
||||||
|
#define GLFW_NULL_SC_LEFT_SHIFT 112
|
||||||
|
#define GLFW_NULL_SC_LEFT_CONTROL 113
|
||||||
|
#define GLFW_NULL_SC_LEFT_ALT 114
|
||||||
|
#define GLFW_NULL_SC_LEFT_SUPER 115
|
||||||
|
#define GLFW_NULL_SC_RIGHT_SHIFT 116
|
||||||
|
#define GLFW_NULL_SC_RIGHT_CONTROL 117
|
||||||
|
#define GLFW_NULL_SC_RIGHT_ALT 118
|
||||||
|
#define GLFW_NULL_SC_RIGHT_SUPER 119
|
||||||
|
#define GLFW_NULL_SC_MENU 120
|
||||||
|
#define GLFW_NULL_SC_LAST GLFW_NULL_SC_MENU
|
||||||
|
|
||||||
// Null-specific per-window data
|
// Null-specific per-window data
|
||||||
//
|
//
|
||||||
|
@ -68,6 +190,8 @@ typedef struct _GLFWlibraryNull
|
||||||
int ycursor;
|
int ycursor;
|
||||||
char* clipboardString;
|
char* clipboardString;
|
||||||
_GLFWwindow* focusedWindow;
|
_GLFWwindow* focusedWindow;
|
||||||
|
uint16_t keycodes[GLFW_NULL_SC_LAST + 1];
|
||||||
|
uint8_t scancodes[GLFW_KEY_LAST + 1];
|
||||||
} _GLFWlibraryNull;
|
} _GLFWlibraryNull;
|
||||||
|
|
||||||
void _glfwPollMonitorsNull(void);
|
void _glfwPollMonitorsNull(void);
|
||||||
|
|
|
@ -568,7 +568,7 @@ EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window)
|
||||||
|
|
||||||
const char* _glfwGetScancodeNameNull(int scancode)
|
const char* _glfwGetScancodeNameNull(int scancode)
|
||||||
{
|
{
|
||||||
if (scancode < GLFW_KEY_SPACE || scancode > GLFW_KEY_LAST)
|
if (scancode < GLFW_NULL_SC_FIRST || scancode > GLFW_NULL_SC_LAST)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode);
|
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -576,117 +576,117 @@ const char* _glfwGetScancodeNameNull(int scancode)
|
||||||
|
|
||||||
switch (scancode)
|
switch (scancode)
|
||||||
{
|
{
|
||||||
case GLFW_KEY_APOSTROPHE:
|
case GLFW_NULL_SC_APOSTROPHE:
|
||||||
return "'";
|
return "'";
|
||||||
case GLFW_KEY_COMMA:
|
case GLFW_NULL_SC_COMMA:
|
||||||
return ",";
|
return ",";
|
||||||
case GLFW_KEY_MINUS:
|
case GLFW_NULL_SC_MINUS:
|
||||||
case GLFW_KEY_KP_SUBTRACT:
|
case GLFW_NULL_SC_KP_SUBTRACT:
|
||||||
return "-";
|
return "-";
|
||||||
case GLFW_KEY_PERIOD:
|
case GLFW_NULL_SC_PERIOD:
|
||||||
case GLFW_KEY_KP_DECIMAL:
|
case GLFW_NULL_SC_KP_DECIMAL:
|
||||||
return ".";
|
return ".";
|
||||||
case GLFW_KEY_SLASH:
|
case GLFW_NULL_SC_SLASH:
|
||||||
case GLFW_KEY_KP_DIVIDE:
|
case GLFW_NULL_SC_KP_DIVIDE:
|
||||||
return "/";
|
return "/";
|
||||||
case GLFW_KEY_SEMICOLON:
|
case GLFW_NULL_SC_SEMICOLON:
|
||||||
return ";";
|
return ";";
|
||||||
case GLFW_KEY_EQUAL:
|
case GLFW_NULL_SC_EQUAL:
|
||||||
case GLFW_KEY_KP_EQUAL:
|
case GLFW_NULL_SC_KP_EQUAL:
|
||||||
return "=";
|
return "=";
|
||||||
case GLFW_KEY_LEFT_BRACKET:
|
case GLFW_NULL_SC_LEFT_BRACKET:
|
||||||
return "[";
|
return "[";
|
||||||
case GLFW_KEY_RIGHT_BRACKET:
|
case GLFW_NULL_SC_RIGHT_BRACKET:
|
||||||
return "]";
|
return "]";
|
||||||
case GLFW_KEY_KP_MULTIPLY:
|
case GLFW_NULL_SC_KP_MULTIPLY:
|
||||||
return "*";
|
return "*";
|
||||||
case GLFW_KEY_KP_ADD:
|
case GLFW_NULL_SC_KP_ADD:
|
||||||
return "+";
|
return "+";
|
||||||
case GLFW_KEY_BACKSLASH:
|
case GLFW_NULL_SC_BACKSLASH:
|
||||||
case GLFW_KEY_WORLD_1:
|
case GLFW_NULL_SC_WORLD_1:
|
||||||
case GLFW_KEY_WORLD_2:
|
case GLFW_NULL_SC_WORLD_2:
|
||||||
return "\\";
|
return "\\";
|
||||||
case GLFW_KEY_0:
|
case GLFW_NULL_SC_0:
|
||||||
case GLFW_KEY_KP_0:
|
case GLFW_NULL_SC_KP_0:
|
||||||
return "0";
|
return "0";
|
||||||
case GLFW_KEY_1:
|
case GLFW_NULL_SC_1:
|
||||||
case GLFW_KEY_KP_1:
|
case GLFW_NULL_SC_KP_1:
|
||||||
return "1";
|
return "1";
|
||||||
case GLFW_KEY_2:
|
case GLFW_NULL_SC_2:
|
||||||
case GLFW_KEY_KP_2:
|
case GLFW_NULL_SC_KP_2:
|
||||||
return "2";
|
return "2";
|
||||||
case GLFW_KEY_3:
|
case GLFW_NULL_SC_3:
|
||||||
case GLFW_KEY_KP_3:
|
case GLFW_NULL_SC_KP_3:
|
||||||
return "3";
|
return "3";
|
||||||
case GLFW_KEY_4:
|
case GLFW_NULL_SC_4:
|
||||||
case GLFW_KEY_KP_4:
|
case GLFW_NULL_SC_KP_4:
|
||||||
return "4";
|
return "4";
|
||||||
case GLFW_KEY_5:
|
case GLFW_NULL_SC_5:
|
||||||
case GLFW_KEY_KP_5:
|
case GLFW_NULL_SC_KP_5:
|
||||||
return "5";
|
return "5";
|
||||||
case GLFW_KEY_6:
|
case GLFW_NULL_SC_6:
|
||||||
case GLFW_KEY_KP_6:
|
case GLFW_NULL_SC_KP_6:
|
||||||
return "6";
|
return "6";
|
||||||
case GLFW_KEY_7:
|
case GLFW_NULL_SC_7:
|
||||||
case GLFW_KEY_KP_7:
|
case GLFW_NULL_SC_KP_7:
|
||||||
return "7";
|
return "7";
|
||||||
case GLFW_KEY_8:
|
case GLFW_NULL_SC_8:
|
||||||
case GLFW_KEY_KP_8:
|
case GLFW_NULL_SC_KP_8:
|
||||||
return "8";
|
return "8";
|
||||||
case GLFW_KEY_9:
|
case GLFW_NULL_SC_9:
|
||||||
case GLFW_KEY_KP_9:
|
case GLFW_NULL_SC_KP_9:
|
||||||
return "9";
|
return "9";
|
||||||
case GLFW_KEY_A:
|
case GLFW_NULL_SC_A:
|
||||||
return "a";
|
return "a";
|
||||||
case GLFW_KEY_B:
|
case GLFW_NULL_SC_B:
|
||||||
return "b";
|
return "b";
|
||||||
case GLFW_KEY_C:
|
case GLFW_NULL_SC_C:
|
||||||
return "c";
|
return "c";
|
||||||
case GLFW_KEY_D:
|
case GLFW_NULL_SC_D:
|
||||||
return "d";
|
return "d";
|
||||||
case GLFW_KEY_E:
|
case GLFW_NULL_SC_E:
|
||||||
return "e";
|
return "e";
|
||||||
case GLFW_KEY_F:
|
case GLFW_NULL_SC_F:
|
||||||
return "f";
|
return "f";
|
||||||
case GLFW_KEY_G:
|
case GLFW_NULL_SC_G:
|
||||||
return "g";
|
return "g";
|
||||||
case GLFW_KEY_H:
|
case GLFW_NULL_SC_H:
|
||||||
return "h";
|
return "h";
|
||||||
case GLFW_KEY_I:
|
case GLFW_NULL_SC_I:
|
||||||
return "i";
|
return "i";
|
||||||
case GLFW_KEY_J:
|
case GLFW_NULL_SC_J:
|
||||||
return "j";
|
return "j";
|
||||||
case GLFW_KEY_K:
|
case GLFW_NULL_SC_K:
|
||||||
return "k";
|
return "k";
|
||||||
case GLFW_KEY_L:
|
case GLFW_NULL_SC_L:
|
||||||
return "l";
|
return "l";
|
||||||
case GLFW_KEY_M:
|
case GLFW_NULL_SC_M:
|
||||||
return "m";
|
return "m";
|
||||||
case GLFW_KEY_N:
|
case GLFW_NULL_SC_N:
|
||||||
return "n";
|
return "n";
|
||||||
case GLFW_KEY_O:
|
case GLFW_NULL_SC_O:
|
||||||
return "o";
|
return "o";
|
||||||
case GLFW_KEY_P:
|
case GLFW_NULL_SC_P:
|
||||||
return "p";
|
return "p";
|
||||||
case GLFW_KEY_Q:
|
case GLFW_NULL_SC_Q:
|
||||||
return "q";
|
return "q";
|
||||||
case GLFW_KEY_R:
|
case GLFW_NULL_SC_R:
|
||||||
return "r";
|
return "r";
|
||||||
case GLFW_KEY_S:
|
case GLFW_NULL_SC_S:
|
||||||
return "s";
|
return "s";
|
||||||
case GLFW_KEY_T:
|
case GLFW_NULL_SC_T:
|
||||||
return "t";
|
return "t";
|
||||||
case GLFW_KEY_U:
|
case GLFW_NULL_SC_U:
|
||||||
return "u";
|
return "u";
|
||||||
case GLFW_KEY_V:
|
case GLFW_NULL_SC_V:
|
||||||
return "v";
|
return "v";
|
||||||
case GLFW_KEY_W:
|
case GLFW_NULL_SC_W:
|
||||||
return "w";
|
return "w";
|
||||||
case GLFW_KEY_X:
|
case GLFW_NULL_SC_X:
|
||||||
return "x";
|
return "x";
|
||||||
case GLFW_KEY_Y:
|
case GLFW_NULL_SC_Y:
|
||||||
return "y";
|
return "y";
|
||||||
case GLFW_KEY_Z:
|
case GLFW_NULL_SC_Z:
|
||||||
return "z";
|
return "z";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,7 +695,7 @@ const char* _glfwGetScancodeNameNull(int scancode)
|
||||||
|
|
||||||
int _glfwGetKeyScancodeNull(int key)
|
int _glfwGetKeyScancodeNull(int key)
|
||||||
{
|
{
|
||||||
return key;
|
return _glfw.null.scancodes[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwGetRequiredInstanceExtensionsNull(char** extensions)
|
void _glfwGetRequiredInstanceExtensionsNull(char** extensions)
|
||||||
|
|
|
@ -384,7 +384,7 @@ static GLFWbool createHelperWindow(void)
|
||||||
if (!_glfw.win32.helperWindowClass)
|
if (!_glfw.win32.helperWindowClass)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
"WIn32: Failed to register helper window class");
|
"Win32: Failed to register helper window class");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
141
src/wl_init.c
141
src/wl_init.c
|
@ -102,10 +102,9 @@ static void registryHandleGlobal(void* userData,
|
||||||
{
|
{
|
||||||
if (strcmp(interface, "wl_compositor") == 0)
|
if (strcmp(interface, "wl_compositor") == 0)
|
||||||
{
|
{
|
||||||
_glfw.wl.compositorVersion = _glfw_min(3, version);
|
|
||||||
_glfw.wl.compositor =
|
_glfw.wl.compositor =
|
||||||
wl_registry_bind(registry, name, &wl_compositor_interface,
|
wl_registry_bind(registry, name, &wl_compositor_interface,
|
||||||
_glfw.wl.compositorVersion);
|
_glfw_min(3, version));
|
||||||
}
|
}
|
||||||
else if (strcmp(interface, "wl_subcompositor") == 0)
|
else if (strcmp(interface, "wl_subcompositor") == 0)
|
||||||
{
|
{
|
||||||
|
@ -125,10 +124,9 @@ static void registryHandleGlobal(void* userData,
|
||||||
{
|
{
|
||||||
if (!_glfw.wl.seat)
|
if (!_glfw.wl.seat)
|
||||||
{
|
{
|
||||||
_glfw.wl.seatVersion = _glfw_min(4, version);
|
|
||||||
_glfw.wl.seat =
|
_glfw.wl.seat =
|
||||||
wl_registry_bind(registry, name, &wl_seat_interface,
|
wl_registry_bind(registry, name, &wl_seat_interface,
|
||||||
_glfw.wl.seatVersion);
|
_glfw_min(4, version));
|
||||||
_glfwAddSeatListenerWayland(_glfw.wl.seat);
|
_glfwAddSeatListenerWayland(_glfw.wl.seat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,6 +202,20 @@ static const struct wl_registry_listener registryListener =
|
||||||
registryHandleGlobalRemove
|
registryHandleGlobalRemove
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void libdecorHandleError(struct libdecor* context,
|
||||||
|
enum libdecor_error error,
|
||||||
|
const char* message)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: libdecor error %u: %s",
|
||||||
|
error, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct libdecor_interface libdecorInterface =
|
||||||
|
{
|
||||||
|
libdecorHandleError
|
||||||
|
};
|
||||||
|
|
||||||
// Create key code translation tables
|
// Create key code translation tables
|
||||||
//
|
//
|
||||||
static void createKeyTables(void)
|
static void createKeyTables(void)
|
||||||
|
@ -339,7 +351,7 @@ static void createKeyTables(void)
|
||||||
|
|
||||||
static GLFWbool loadCursorTheme(void)
|
static GLFWbool loadCursorTheme(void)
|
||||||
{
|
{
|
||||||
int cursorSize = 32;
|
int cursorSize = 16;
|
||||||
|
|
||||||
const char* sizeString = getenv("XCURSOR_SIZE");
|
const char* sizeString = getenv("XCURSOR_SIZE");
|
||||||
if (sizeString)
|
if (sizeString)
|
||||||
|
@ -394,7 +406,7 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform)
|
||||||
_glfwGetKeyScancodeWayland,
|
_glfwGetKeyScancodeWayland,
|
||||||
_glfwSetClipboardStringWayland,
|
_glfwSetClipboardStringWayland,
|
||||||
_glfwGetClipboardStringWayland,
|
_glfwGetClipboardStringWayland,
|
||||||
#if defined(_GLFW_LINUX_JOYSTICK)
|
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
|
||||||
_glfwInitJoysticksLinux,
|
_glfwInitJoysticksLinux,
|
||||||
_glfwTerminateJoysticksLinux,
|
_glfwTerminateJoysticksLinux,
|
||||||
_glfwPollJoystickLinux,
|
_glfwPollJoystickLinux,
|
||||||
|
@ -509,6 +521,8 @@ int _glfwInitWayland(void)
|
||||||
_glfw.wl.keyRepeatTimerfd = -1;
|
_glfw.wl.keyRepeatTimerfd = -1;
|
||||||
_glfw.wl.cursorTimerfd = -1;
|
_glfw.wl.cursorTimerfd = -1;
|
||||||
|
|
||||||
|
_glfw.wl.tag = glfwGetVersionString();
|
||||||
|
|
||||||
_glfw.wl.client.display_flush = (PFN_wl_display_flush)
|
_glfw.wl.client.display_flush = (PFN_wl_display_flush)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_flush");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_flush");
|
||||||
_glfw.wl.client.display_cancel_read = (PFN_wl_display_cancel_read)
|
_glfw.wl.client.display_cancel_read = (PFN_wl_display_cancel_read)
|
||||||
|
@ -539,6 +553,10 @@ int _glfwInitWayland(void)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_user_data");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_user_data");
|
||||||
_glfw.wl.client.proxy_set_user_data = (PFN_wl_proxy_set_user_data)
|
_glfw.wl.client.proxy_set_user_data = (PFN_wl_proxy_set_user_data)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_user_data");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_user_data");
|
||||||
|
_glfw.wl.client.proxy_get_tag = (PFN_wl_proxy_get_tag)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_tag");
|
||||||
|
_glfw.wl.client.proxy_set_tag = (PFN_wl_proxy_set_tag)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_tag");
|
||||||
_glfw.wl.client.proxy_get_version = (PFN_wl_proxy_get_version)
|
_glfw.wl.client.proxy_get_version = (PFN_wl_proxy_get_version)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_version");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_version");
|
||||||
_glfw.wl.client.proxy_marshal_flags = (PFN_wl_proxy_marshal_flags)
|
_glfw.wl.client.proxy_marshal_flags = (PFN_wl_proxy_marshal_flags)
|
||||||
|
@ -558,7 +576,9 @@ int _glfwInitWayland(void)
|
||||||
!_glfw.wl.client.proxy_marshal_constructor ||
|
!_glfw.wl.client.proxy_marshal_constructor ||
|
||||||
!_glfw.wl.client.proxy_marshal_constructor_versioned ||
|
!_glfw.wl.client.proxy_marshal_constructor_versioned ||
|
||||||
!_glfw.wl.client.proxy_get_user_data ||
|
!_glfw.wl.client.proxy_get_user_data ||
|
||||||
!_glfw.wl.client.proxy_set_user_data)
|
!_glfw.wl.client.proxy_set_user_data ||
|
||||||
|
!_glfw.wl.client.proxy_get_tag ||
|
||||||
|
!_glfw.wl.client.proxy_set_tag)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Wayland: Failed to load libwayland-client entry point");
|
"Wayland: Failed to load libwayland-client entry point");
|
||||||
|
@ -646,6 +666,93 @@ int _glfwInitWayland(void)
|
||||||
_glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym)
|
_glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym");
|
||||||
|
|
||||||
|
if (_glfw.hints.init.wl.libdecorMode == GLFW_WAYLAND_PREFER_LIBDECOR)
|
||||||
|
_glfw.wl.libdecor.handle = _glfwPlatformLoadModule("libdecor-0.so.0");
|
||||||
|
|
||||||
|
if (_glfw.wl.libdecor.handle)
|
||||||
|
{
|
||||||
|
_glfw.wl.libdecor.libdecor_new_ = (PFN_libdecor_new)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_new");
|
||||||
|
_glfw.wl.libdecor.libdecor_unref_ = (PFN_libdecor_unref)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_unref");
|
||||||
|
_glfw.wl.libdecor.libdecor_get_fd_ = (PFN_libdecor_get_fd)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_get_fd");
|
||||||
|
_glfw.wl.libdecor.libdecor_dispatch_ = (PFN_libdecor_dispatch)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_dispatch");
|
||||||
|
_glfw.wl.libdecor.libdecor_decorate_ = (PFN_libdecor_decorate)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_decorate");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_unref_ = (PFN_libdecor_frame_unref)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unref");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_set_app_id_ = (PFN_libdecor_frame_set_app_id)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_app_id");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_set_title_ = (PFN_libdecor_frame_set_title)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_title");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_set_minimized_ = (PFN_libdecor_frame_set_minimized)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_minimized");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_set_fullscreen_ = (PFN_libdecor_frame_set_fullscreen)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_fullscreen");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ = (PFN_libdecor_frame_unset_fullscreen)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_fullscreen");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_map_ = (PFN_libdecor_frame_map)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_map");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_commit_ = (PFN_libdecor_frame_commit)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_commit");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_set_min_content_size_ = (PFN_libdecor_frame_set_min_content_size)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_min_content_size");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_set_max_content_size_ = (PFN_libdecor_frame_set_max_content_size)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_max_content_size");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_set_maximized_ = (PFN_libdecor_frame_set_maximized)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_maximized");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_unset_maximized_ = (PFN_libdecor_frame_unset_maximized)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_maximized");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_set_capabilities_ = (PFN_libdecor_frame_set_capabilities)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_capabilities");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_unset_capabilities_ = (PFN_libdecor_frame_unset_capabilities)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_capabilities");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_set_visibility_ = (PFN_libdecor_frame_set_visibility)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_visibility");
|
||||||
|
_glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ = (PFN_libdecor_frame_get_xdg_toplevel)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_get_xdg_toplevel");
|
||||||
|
_glfw.wl.libdecor.libdecor_configuration_get_content_size_ = (PFN_libdecor_configuration_get_content_size)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_configuration_get_content_size");
|
||||||
|
_glfw.wl.libdecor.libdecor_configuration_get_window_state_ = (PFN_libdecor_configuration_get_window_state)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_configuration_get_window_state");
|
||||||
|
_glfw.wl.libdecor.libdecor_state_new_ = (PFN_libdecor_state_new)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_state_new");
|
||||||
|
_glfw.wl.libdecor.libdecor_state_free_ = (PFN_libdecor_state_free)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_state_free");
|
||||||
|
|
||||||
|
if (!_glfw.wl.libdecor.libdecor_new_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_unref_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_get_fd_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_dispatch_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_decorate_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_unref_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_set_app_id_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_set_title_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_set_minimized_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_set_fullscreen_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_map_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_commit_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_set_min_content_size_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_set_max_content_size_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_set_maximized_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_unset_maximized_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_set_capabilities_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_unset_capabilities_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_set_visibility_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_configuration_get_content_size_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_configuration_get_window_state_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_state_new_ ||
|
||||||
|
!_glfw.wl.libdecor.libdecor_state_free_)
|
||||||
|
{
|
||||||
|
_glfwPlatformFreeModule(_glfw.wl.libdecor.handle);
|
||||||
|
memset(&_glfw.wl.libdecor, 0, sizeof(_glfw.wl.libdecor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
|
_glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
|
||||||
wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL);
|
wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL);
|
||||||
|
|
||||||
|
@ -665,8 +772,17 @@ int _glfwInitWayland(void)
|
||||||
// Sync so we got all initial output events
|
// Sync so we got all initial output events
|
||||||
wl_display_roundtrip(_glfw.wl.display);
|
wl_display_roundtrip(_glfw.wl.display);
|
||||||
|
|
||||||
|
if (_glfw.wl.libdecor.handle)
|
||||||
|
{
|
||||||
|
_glfw.wl.libdecor.context = libdecor_new(_glfw.wl.display, &libdecorInterface);
|
||||||
|
|
||||||
|
// Allow libdecor to receive its globals before proceeding
|
||||||
|
if (_glfw.wl.libdecor.context)
|
||||||
|
libdecor_dispatch(_glfw.wl.libdecor.context, 1);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION
|
#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION
|
||||||
if (_glfw.wl.seatVersion >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
|
if (wl_seat_get_version(_glfw.wl.seat) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
|
||||||
{
|
{
|
||||||
_glfw.wl.keyRepeatTimerfd =
|
_glfw.wl.keyRepeatTimerfd =
|
||||||
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
|
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
|
||||||
|
@ -706,6 +822,15 @@ void _glfwTerminateWayland(void)
|
||||||
_glfwTerminateEGL();
|
_glfwTerminateEGL();
|
||||||
_glfwTerminateOSMesa();
|
_glfwTerminateOSMesa();
|
||||||
|
|
||||||
|
if (_glfw.wl.libdecor.context)
|
||||||
|
libdecor_unref(_glfw.wl.libdecor.context);
|
||||||
|
|
||||||
|
if (_glfw.wl.libdecor.handle)
|
||||||
|
{
|
||||||
|
_glfwPlatformFreeModule(_glfw.wl.libdecor.handle);
|
||||||
|
_glfw.wl.libdecor.handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (_glfw.wl.egl.handle)
|
if (_glfw.wl.egl.handle)
|
||||||
{
|
{
|
||||||
_glfwPlatformFreeModule(_glfw.wl.egl.handle);
|
_glfwPlatformFreeModule(_glfw.wl.egl.handle);
|
||||||
|
|
|
@ -114,14 +114,15 @@ static void outputHandleScale(void* userData,
|
||||||
{
|
{
|
||||||
struct _GLFWmonitor* monitor = userData;
|
struct _GLFWmonitor* monitor = userData;
|
||||||
|
|
||||||
monitor->wl.scale = factor;
|
monitor->wl.contentScale = factor;
|
||||||
|
|
||||||
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
|
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < window->wl.monitorsCount; i++)
|
for (int i = 0; i < window->wl.scaleCount; i++)
|
||||||
{
|
{
|
||||||
if (window->wl.monitors[i] == monitor)
|
if (window->wl.scales[i].output == monitor->wl.output)
|
||||||
{
|
{
|
||||||
|
window->wl.scales[i].factor = monitor->wl.contentScale;
|
||||||
_glfwUpdateContentScaleWayland(window);
|
_glfwUpdateContentScaleWayland(window);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -187,10 +188,11 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
|
||||||
|
|
||||||
// The actual name of this output will be set in the geometry handler
|
// The actual name of this output will be set in the geometry handler
|
||||||
_GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0);
|
_GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0);
|
||||||
monitor->wl.scale = 1;
|
monitor->wl.contentScale = 1;
|
||||||
monitor->wl.output = output;
|
monitor->wl.output = output;
|
||||||
monitor->wl.name = name;
|
monitor->wl.name = name;
|
||||||
|
|
||||||
|
wl_proxy_set_tag((struct wl_proxy*) output, &_glfw.wl.tag);
|
||||||
wl_output_add_listener(output, &outputListener, monitor);
|
wl_output_add_listener(output, &outputListener, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,9 +219,9 @@ void _glfwGetMonitorContentScaleWayland(_GLFWmonitor* monitor,
|
||||||
float* xscale, float* yscale)
|
float* xscale, float* yscale)
|
||||||
{
|
{
|
||||||
if (xscale)
|
if (xscale)
|
||||||
*xscale = (float) monitor->wl.scale;
|
*xscale = (float) monitor->wl.contentScale;
|
||||||
if (yscale)
|
if (yscale)
|
||||||
*yscale = (float) monitor->wl.scale;
|
*yscale = (float) monitor->wl.contentScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwGetMonitorWorkareaWayland(_GLFWmonitor* monitor,
|
void _glfwGetMonitorWorkareaWayland(_GLFWmonitor* monitor,
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
#include <xkbcommon/xkbcommon-compose.h>
|
#include <xkbcommon/xkbcommon-compose.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
|
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
|
||||||
|
|
||||||
typedef struct VkWaylandSurfaceCreateInfoKHR
|
typedef struct VkWaylandSurfaceCreateInfoKHR
|
||||||
|
@ -61,6 +63,8 @@ typedef struct wl_proxy* (* PFN_wl_proxy_marshal_constructor)(struct wl_proxy*,u
|
||||||
typedef struct wl_proxy* (* PFN_wl_proxy_marshal_constructor_versioned)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,...);
|
typedef struct wl_proxy* (* PFN_wl_proxy_marshal_constructor_versioned)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,...);
|
||||||
typedef void* (* PFN_wl_proxy_get_user_data)(struct wl_proxy*);
|
typedef void* (* PFN_wl_proxy_get_user_data)(struct wl_proxy*);
|
||||||
typedef void (* PFN_wl_proxy_set_user_data)(struct wl_proxy*,void*);
|
typedef void (* PFN_wl_proxy_set_user_data)(struct wl_proxy*,void*);
|
||||||
|
typedef void (* PFN_wl_proxy_set_tag)(struct wl_proxy*,const char*const*);
|
||||||
|
typedef const char* const* (* PFN_wl_proxy_get_tag)(struct wl_proxy*);
|
||||||
typedef uint32_t (* PFN_wl_proxy_get_version)(struct wl_proxy*);
|
typedef uint32_t (* PFN_wl_proxy_get_version)(struct wl_proxy*);
|
||||||
typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,uint32_t,...);
|
typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,uint32_t,...);
|
||||||
#define wl_display_flush _glfw.wl.client.display_flush
|
#define wl_display_flush _glfw.wl.client.display_flush
|
||||||
|
@ -78,10 +82,13 @@ typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_
|
||||||
#define wl_proxy_marshal_constructor_versioned _glfw.wl.client.proxy_marshal_constructor_versioned
|
#define wl_proxy_marshal_constructor_versioned _glfw.wl.client.proxy_marshal_constructor_versioned
|
||||||
#define wl_proxy_get_user_data _glfw.wl.client.proxy_get_user_data
|
#define wl_proxy_get_user_data _glfw.wl.client.proxy_get_user_data
|
||||||
#define wl_proxy_set_user_data _glfw.wl.client.proxy_set_user_data
|
#define wl_proxy_set_user_data _glfw.wl.client.proxy_set_user_data
|
||||||
|
#define wl_proxy_get_tag _glfw.wl.client.proxy_get_tag
|
||||||
|
#define wl_proxy_set_tag _glfw.wl.client.proxy_set_tag
|
||||||
#define wl_proxy_get_version _glfw.wl.client.proxy_get_version
|
#define wl_proxy_get_version _glfw.wl.client.proxy_get_version
|
||||||
#define wl_proxy_marshal_flags _glfw.wl.client.proxy_marshal_flags
|
#define wl_proxy_marshal_flags _glfw.wl.client.proxy_marshal_flags
|
||||||
|
|
||||||
struct wl_shm;
|
struct wl_shm;
|
||||||
|
struct wl_output;
|
||||||
|
|
||||||
#define wl_display_interface _glfw_wl_display_interface
|
#define wl_display_interface _glfw_wl_display_interface
|
||||||
#define wl_subcompositor_interface _glfw_wl_subcompositor_interface
|
#define wl_subcompositor_interface _glfw_wl_subcompositor_interface
|
||||||
|
@ -198,13 +205,129 @@ typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_st
|
||||||
#define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status
|
#define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status
|
||||||
#define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym
|
#define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym
|
||||||
|
|
||||||
|
struct libdecor;
|
||||||
|
struct libdecor_frame;
|
||||||
|
struct libdecor_state;
|
||||||
|
struct libdecor_configuration;
|
||||||
|
|
||||||
|
enum libdecor_error
|
||||||
|
{
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
enum libdecor_capabilities
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct libdecor* (* PFN_libdecor_new)(struct wl_display*,const struct libdecor_interface*);
|
||||||
|
typedef void (* PFN_libdecor_unref)(struct libdecor*);
|
||||||
|
typedef int (* PFN_libdecor_get_fd)(struct libdecor*);
|
||||||
|
typedef int (* PFN_libdecor_dispatch)(struct libdecor*,int);
|
||||||
|
typedef struct libdecor_frame* (* PFN_libdecor_decorate)(struct libdecor*,struct wl_surface*,const struct libdecor_frame_interface*,void*);
|
||||||
|
typedef void (* PFN_libdecor_frame_unref)(struct libdecor_frame*);
|
||||||
|
typedef void (* PFN_libdecor_frame_set_app_id)(struct libdecor_frame*,const char*);
|
||||||
|
typedef void (* PFN_libdecor_frame_set_title)(struct libdecor_frame*,const char*);
|
||||||
|
typedef void (* PFN_libdecor_frame_set_minimized)(struct libdecor_frame*);
|
||||||
|
typedef void (* PFN_libdecor_frame_set_fullscreen)(struct libdecor_frame*,struct wl_output*);
|
||||||
|
typedef void (* PFN_libdecor_frame_unset_fullscreen)(struct libdecor_frame*);
|
||||||
|
typedef void (* PFN_libdecor_frame_map)(struct libdecor_frame*);
|
||||||
|
typedef void (* PFN_libdecor_frame_commit)(struct libdecor_frame*,struct libdecor_state*,struct libdecor_configuration*);
|
||||||
|
typedef void (* PFN_libdecor_frame_set_min_content_size)(struct libdecor_frame*,int,int);
|
||||||
|
typedef void (* PFN_libdecor_frame_set_max_content_size)(struct libdecor_frame*,int,int);
|
||||||
|
typedef void (* PFN_libdecor_frame_set_maximized)(struct libdecor_frame*);
|
||||||
|
typedef void (* PFN_libdecor_frame_unset_maximized)(struct libdecor_frame*);
|
||||||
|
typedef void (* PFN_libdecor_frame_set_capabilities)(struct libdecor_frame*,enum libdecor_capabilities);
|
||||||
|
typedef void (* PFN_libdecor_frame_unset_capabilities)(struct libdecor_frame*,enum libdecor_capabilities);
|
||||||
|
typedef void (* PFN_libdecor_frame_set_visibility)(struct libdecor_frame*,bool visible);
|
||||||
|
typedef struct xdg_toplevel* (* PFN_libdecor_frame_get_xdg_toplevel)(struct libdecor_frame*);
|
||||||
|
typedef bool (* PFN_libdecor_configuration_get_content_size)(struct libdecor_configuration*,struct libdecor_frame*,int*,int*);
|
||||||
|
typedef bool (* PFN_libdecor_configuration_get_window_state)(struct libdecor_configuration*,enum libdecor_window_state*);
|
||||||
|
typedef struct libdecor_state* (* PFN_libdecor_state_new)(int,int);
|
||||||
|
typedef void (* PFN_libdecor_state_free)(struct libdecor_state*);
|
||||||
|
#define libdecor_new _glfw.wl.libdecor.libdecor_new_
|
||||||
|
#define libdecor_unref _glfw.wl.libdecor.libdecor_unref_
|
||||||
|
#define libdecor_get_fd _glfw.wl.libdecor.libdecor_get_fd_
|
||||||
|
#define libdecor_dispatch _glfw.wl.libdecor.libdecor_dispatch_
|
||||||
|
#define libdecor_decorate _glfw.wl.libdecor.libdecor_decorate_
|
||||||
|
#define libdecor_frame_unref _glfw.wl.libdecor.libdecor_frame_unref_
|
||||||
|
#define libdecor_frame_set_app_id _glfw.wl.libdecor.libdecor_frame_set_app_id_
|
||||||
|
#define libdecor_frame_set_title _glfw.wl.libdecor.libdecor_frame_set_title_
|
||||||
|
#define libdecor_frame_set_minimized _glfw.wl.libdecor.libdecor_frame_set_minimized_
|
||||||
|
#define libdecor_frame_set_fullscreen _glfw.wl.libdecor.libdecor_frame_set_fullscreen_
|
||||||
|
#define libdecor_frame_unset_fullscreen _glfw.wl.libdecor.libdecor_frame_unset_fullscreen_
|
||||||
|
#define libdecor_frame_map _glfw.wl.libdecor.libdecor_frame_map_
|
||||||
|
#define libdecor_frame_commit _glfw.wl.libdecor.libdecor_frame_commit_
|
||||||
|
#define libdecor_frame_set_min_content_size _glfw.wl.libdecor.libdecor_frame_set_min_content_size_
|
||||||
|
#define libdecor_frame_set_max_content_size _glfw.wl.libdecor.libdecor_frame_set_max_content_size_
|
||||||
|
#define libdecor_frame_set_maximized _glfw.wl.libdecor.libdecor_frame_set_maximized_
|
||||||
|
#define libdecor_frame_unset_maximized _glfw.wl.libdecor.libdecor_frame_unset_maximized_
|
||||||
|
#define libdecor_frame_set_capabilities _glfw.wl.libdecor.libdecor_frame_set_capabilities_
|
||||||
|
#define libdecor_frame_unset_capabilities _glfw.wl.libdecor.libdecor_frame_unset_capabilities_
|
||||||
|
#define libdecor_frame_set_visibility _glfw.wl.libdecor.libdecor_frame_set_visibility_
|
||||||
|
#define libdecor_frame_get_xdg_toplevel _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_
|
||||||
|
#define libdecor_configuration_get_content_size _glfw.wl.libdecor.libdecor_configuration_get_content_size_
|
||||||
|
#define libdecor_configuration_get_window_state _glfw.wl.libdecor.libdecor_configuration_get_window_state_
|
||||||
|
#define libdecor_state_new _glfw.wl.libdecor.libdecor_state_new_
|
||||||
|
#define libdecor_state_free _glfw.wl.libdecor.libdecor_state_free_
|
||||||
|
|
||||||
typedef enum _GLFWdecorationSideWayland
|
typedef enum _GLFWdecorationSideWayland
|
||||||
{
|
{
|
||||||
mainWindow,
|
GLFW_MAIN_WINDOW,
|
||||||
topDecoration,
|
GLFW_TOP_DECORATION,
|
||||||
leftDecoration,
|
GLFW_LEFT_DECORATION,
|
||||||
rightDecoration,
|
GLFW_RIGHT_DECORATION,
|
||||||
bottomDecoration,
|
GLFW_BOTTOM_DECORATION
|
||||||
} _GLFWdecorationSideWayland;
|
} _GLFWdecorationSideWayland;
|
||||||
|
|
||||||
typedef struct _GLFWdecorationWayland
|
typedef struct _GLFWdecorationWayland
|
||||||
|
@ -221,6 +344,12 @@ typedef struct _GLFWofferWayland
|
||||||
GLFWbool text_uri_list;
|
GLFWbool text_uri_list;
|
||||||
} _GLFWofferWayland;
|
} _GLFWofferWayland;
|
||||||
|
|
||||||
|
typedef struct _GLFWscaleWayland
|
||||||
|
{
|
||||||
|
struct wl_output* output;
|
||||||
|
int factor;
|
||||||
|
} _GLFWscaleWayland;
|
||||||
|
|
||||||
// Wayland-specific per-window data
|
// Wayland-specific per-window data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWwindowWayland
|
typedef struct _GLFWwindowWayland
|
||||||
|
@ -254,6 +383,11 @@ typedef struct _GLFWwindowWayland
|
||||||
uint32_t decorationMode;
|
uint32_t decorationMode;
|
||||||
} xdg;
|
} xdg;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct libdecor_frame* frame;
|
||||||
|
int mode;
|
||||||
|
} libdecor;
|
||||||
|
|
||||||
_GLFWcursor* currentCursor;
|
_GLFWcursor* currentCursor;
|
||||||
double cursorPosX, cursorPosY;
|
double cursorPosX, cursorPosY;
|
||||||
|
|
||||||
|
@ -262,10 +396,10 @@ typedef struct _GLFWwindowWayland
|
||||||
|
|
||||||
// We need to track the monitors the window spans on to calculate the
|
// We need to track the monitors the window spans on to calculate the
|
||||||
// optimal scaling factor.
|
// optimal scaling factor.
|
||||||
int scale;
|
int contentScale;
|
||||||
_GLFWmonitor** monitors;
|
_GLFWscaleWayland* scales;
|
||||||
int monitorsCount;
|
int scaleCount;
|
||||||
int monitorsSize;
|
int scaleSize;
|
||||||
|
|
||||||
struct zwp_relative_pointer_v1* relativePointer;
|
struct zwp_relative_pointer_v1* relativePointer;
|
||||||
struct zwp_locked_pointer_v1* lockedPointer;
|
struct zwp_locked_pointer_v1* lockedPointer;
|
||||||
|
@ -311,8 +445,7 @@ typedef struct _GLFWlibraryWayland
|
||||||
_GLFWwindow* dragFocus;
|
_GLFWwindow* dragFocus;
|
||||||
uint32_t dragSerial;
|
uint32_t dragSerial;
|
||||||
|
|
||||||
int compositorVersion;
|
const char* tag;
|
||||||
int seatVersion;
|
|
||||||
|
|
||||||
struct wl_cursor_theme* cursorTheme;
|
struct wl_cursor_theme* cursorTheme;
|
||||||
struct wl_cursor_theme* cursorThemeHiDPI;
|
struct wl_cursor_theme* cursorThemeHiDPI;
|
||||||
|
@ -391,6 +524,8 @@ typedef struct _GLFWlibraryWayland
|
||||||
PFN_wl_proxy_marshal_constructor_versioned proxy_marshal_constructor_versioned;
|
PFN_wl_proxy_marshal_constructor_versioned proxy_marshal_constructor_versioned;
|
||||||
PFN_wl_proxy_get_user_data proxy_get_user_data;
|
PFN_wl_proxy_get_user_data proxy_get_user_data;
|
||||||
PFN_wl_proxy_set_user_data proxy_set_user_data;
|
PFN_wl_proxy_set_user_data proxy_set_user_data;
|
||||||
|
PFN_wl_proxy_get_tag proxy_get_tag;
|
||||||
|
PFN_wl_proxy_set_tag proxy_set_tag;
|
||||||
PFN_wl_proxy_get_version proxy_get_version;
|
PFN_wl_proxy_get_version proxy_get_version;
|
||||||
PFN_wl_proxy_marshal_flags proxy_marshal_flags;
|
PFN_wl_proxy_marshal_flags proxy_marshal_flags;
|
||||||
} client;
|
} client;
|
||||||
|
@ -411,6 +546,36 @@ typedef struct _GLFWlibraryWayland
|
||||||
PFN_wl_egl_window_destroy window_destroy;
|
PFN_wl_egl_window_destroy window_destroy;
|
||||||
PFN_wl_egl_window_resize window_resize;
|
PFN_wl_egl_window_resize window_resize;
|
||||||
} egl;
|
} egl;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
void* handle;
|
||||||
|
struct libdecor* context;
|
||||||
|
PFN_libdecor_new libdecor_new_;
|
||||||
|
PFN_libdecor_unref libdecor_unref_;
|
||||||
|
PFN_libdecor_get_fd libdecor_get_fd_;
|
||||||
|
PFN_libdecor_dispatch libdecor_dispatch_;
|
||||||
|
PFN_libdecor_decorate libdecor_decorate_;
|
||||||
|
PFN_libdecor_frame_unref libdecor_frame_unref_;
|
||||||
|
PFN_libdecor_frame_set_app_id libdecor_frame_set_app_id_;
|
||||||
|
PFN_libdecor_frame_set_title libdecor_frame_set_title_;
|
||||||
|
PFN_libdecor_frame_set_minimized libdecor_frame_set_minimized_;
|
||||||
|
PFN_libdecor_frame_set_fullscreen libdecor_frame_set_fullscreen_;
|
||||||
|
PFN_libdecor_frame_unset_fullscreen libdecor_frame_unset_fullscreen_;
|
||||||
|
PFN_libdecor_frame_map libdecor_frame_map_;
|
||||||
|
PFN_libdecor_frame_commit libdecor_frame_commit_;
|
||||||
|
PFN_libdecor_frame_set_min_content_size libdecor_frame_set_min_content_size_;
|
||||||
|
PFN_libdecor_frame_set_max_content_size libdecor_frame_set_max_content_size_;
|
||||||
|
PFN_libdecor_frame_set_maximized libdecor_frame_set_maximized_;
|
||||||
|
PFN_libdecor_frame_unset_maximized libdecor_frame_unset_maximized_;
|
||||||
|
PFN_libdecor_frame_set_capabilities libdecor_frame_set_capabilities_;
|
||||||
|
PFN_libdecor_frame_unset_capabilities libdecor_frame_unset_capabilities_;
|
||||||
|
PFN_libdecor_frame_set_visibility libdecor_frame_set_visibility_;
|
||||||
|
PFN_libdecor_frame_get_xdg_toplevel libdecor_frame_get_xdg_toplevel_;
|
||||||
|
PFN_libdecor_configuration_get_content_size libdecor_configuration_get_content_size_;
|
||||||
|
PFN_libdecor_configuration_get_window_state libdecor_configuration_get_window_state_;
|
||||||
|
PFN_libdecor_state_new libdecor_state_new_;
|
||||||
|
PFN_libdecor_state_free libdecor_state_free_;
|
||||||
|
} libdecor;
|
||||||
} _GLFWlibraryWayland;
|
} _GLFWlibraryWayland;
|
||||||
|
|
||||||
// Wayland-specific per-monitor data
|
// Wayland-specific per-monitor data
|
||||||
|
@ -423,7 +588,7 @@ typedef struct _GLFWmonitorWayland
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
int scale;
|
int contentScale;
|
||||||
} _GLFWmonitorWayland;
|
} _GLFWmonitorWayland;
|
||||||
|
|
||||||
// Wayland-specific per-cursor data
|
// Wayland-specific per-cursor data
|
||||||
|
|
581
src/wl_window.c
581
src/wl_window.c
|
@ -192,13 +192,16 @@ static struct wl_buffer* createShmBuffer(const GLFWimage* image)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void createFallbackDecoration(_GLFWdecorationWayland* decoration,
|
static void createFallbackDecoration(_GLFWwindow* window,
|
||||||
|
_GLFWdecorationWayland* decoration,
|
||||||
struct wl_surface* parent,
|
struct wl_surface* parent,
|
||||||
struct wl_buffer* buffer,
|
struct wl_buffer* buffer,
|
||||||
int x, int y,
|
int x, int y,
|
||||||
int width, int height)
|
int width, int height)
|
||||||
{
|
{
|
||||||
decoration->surface = wl_compositor_create_surface(_glfw.wl.compositor);
|
decoration->surface = wl_compositor_create_surface(_glfw.wl.compositor);
|
||||||
|
wl_surface_set_user_data(decoration->surface, window);
|
||||||
|
wl_proxy_set_tag((struct wl_proxy*) decoration->surface, &_glfw.wl.tag);
|
||||||
decoration->subsurface =
|
decoration->subsurface =
|
||||||
wl_subcompositor_get_subsurface(_glfw.wl.subcompositor,
|
wl_subcompositor_get_subsurface(_glfw.wl.subcompositor,
|
||||||
decoration->surface, parent);
|
decoration->surface, parent);
|
||||||
|
@ -228,19 +231,19 @@ static void createFallbackDecorations(_GLFWwindow* window)
|
||||||
if (!window->wl.decorations.buffer)
|
if (!window->wl.decorations.buffer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
createFallbackDecoration(&window->wl.decorations.top, window->wl.surface,
|
createFallbackDecoration(window, &window->wl.decorations.top, window->wl.surface,
|
||||||
window->wl.decorations.buffer,
|
window->wl.decorations.buffer,
|
||||||
0, -GLFW_CAPTION_HEIGHT,
|
0, -GLFW_CAPTION_HEIGHT,
|
||||||
window->wl.width, GLFW_CAPTION_HEIGHT);
|
window->wl.width, GLFW_CAPTION_HEIGHT);
|
||||||
createFallbackDecoration(&window->wl.decorations.left, window->wl.surface,
|
createFallbackDecoration(window, &window->wl.decorations.left, window->wl.surface,
|
||||||
window->wl.decorations.buffer,
|
window->wl.decorations.buffer,
|
||||||
-GLFW_BORDER_SIZE, -GLFW_CAPTION_HEIGHT,
|
-GLFW_BORDER_SIZE, -GLFW_CAPTION_HEIGHT,
|
||||||
GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT);
|
GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT);
|
||||||
createFallbackDecoration(&window->wl.decorations.right, window->wl.surface,
|
createFallbackDecoration(window, &window->wl.decorations.right, window->wl.surface,
|
||||||
window->wl.decorations.buffer,
|
window->wl.decorations.buffer,
|
||||||
window->wl.width, -GLFW_CAPTION_HEIGHT,
|
window->wl.width, -GLFW_CAPTION_HEIGHT,
|
||||||
GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT);
|
GLFW_BORDER_SIZE, window->wl.height + GLFW_CAPTION_HEIGHT);
|
||||||
createFallbackDecoration(&window->wl.decorations.bottom, window->wl.surface,
|
createFallbackDecoration(window, &window->wl.decorations.bottom, window->wl.surface,
|
||||||
window->wl.decorations.buffer,
|
window->wl.decorations.buffer,
|
||||||
-GLFW_BORDER_SIZE, window->wl.height,
|
-GLFW_BORDER_SIZE, window->wl.height,
|
||||||
window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE);
|
window->wl.width + GLFW_BORDER_SIZE * 2, GLFW_BORDER_SIZE);
|
||||||
|
@ -306,7 +309,7 @@ static void setContentAreaOpaque(_GLFWwindow* window)
|
||||||
|
|
||||||
static void resizeWindow(_GLFWwindow* window)
|
static void resizeWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
int scale = window->wl.scale;
|
int scale = window->wl.contentScale;
|
||||||
int scaledWidth = window->wl.width * scale;
|
int scaledWidth = window->wl.width * scale;
|
||||||
int scaledHeight = window->wl.height * scale;
|
int scaledHeight = window->wl.height * scale;
|
||||||
|
|
||||||
|
@ -342,22 +345,28 @@ static void resizeWindow(_GLFWwindow* window)
|
||||||
|
|
||||||
void _glfwUpdateContentScaleWayland(_GLFWwindow* window)
|
void _glfwUpdateContentScaleWayland(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (_glfw.wl.compositorVersion < WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
|
if (wl_compositor_get_version(_glfw.wl.compositor) <
|
||||||
|
WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the scale factor from the highest scale monitor.
|
// Get the scale factor from the highest scale monitor.
|
||||||
int maxScale = 1;
|
int maxScale = 1;
|
||||||
|
|
||||||
for (int i = 0; i < window->wl.monitorsCount; i++)
|
for (int i = 0; i < window->wl.scaleCount; i++)
|
||||||
maxScale = _glfw_max(window->wl.monitors[i]->wl.scale, maxScale);
|
maxScale = _glfw_max(window->wl.scales[i].factor, maxScale);
|
||||||
|
|
||||||
// Only change the framebuffer size if the scale changed.
|
// Only change the framebuffer size if the scale changed.
|
||||||
if (window->wl.scale != maxScale)
|
if (window->wl.contentScale != maxScale)
|
||||||
{
|
{
|
||||||
window->wl.scale = maxScale;
|
window->wl.contentScale = maxScale;
|
||||||
wl_surface_set_buffer_scale(window->wl.surface, maxScale);
|
wl_surface_set_buffer_scale(window->wl.surface, maxScale);
|
||||||
_glfwInputWindowContentScale(window, maxScale, maxScale);
|
_glfwInputWindowContentScale(window, maxScale, maxScale);
|
||||||
resizeWindow(window);
|
resizeWindow(window);
|
||||||
|
|
||||||
|
if (window->wl.visible)
|
||||||
|
_glfwInputWindowDamage(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,18 +374,25 @@ static void surfaceHandleEnter(void* userData,
|
||||||
struct wl_surface* surface,
|
struct wl_surface* surface,
|
||||||
struct wl_output* output)
|
struct wl_output* output)
|
||||||
{
|
{
|
||||||
|
if (wl_proxy_get_tag((struct wl_proxy*) output) != &_glfw.wl.tag)
|
||||||
|
return;
|
||||||
|
|
||||||
_GLFWwindow* window = userData;
|
_GLFWwindow* window = userData;
|
||||||
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
||||||
|
if (!window || !monitor)
|
||||||
|
return;
|
||||||
|
|
||||||
if (window->wl.monitorsCount + 1 > window->wl.monitorsSize)
|
if (window->wl.scaleCount + 1 > window->wl.scaleSize)
|
||||||
{
|
{
|
||||||
++window->wl.monitorsSize;
|
window->wl.scaleSize++;
|
||||||
window->wl.monitors =
|
window->wl.scales =
|
||||||
_glfw_realloc(window->wl.monitors,
|
_glfw_realloc(window->wl.scales,
|
||||||
window->wl.monitorsSize * sizeof(_GLFWmonitor*));
|
window->wl.scaleSize * sizeof(_GLFWscaleWayland));
|
||||||
}
|
}
|
||||||
|
|
||||||
window->wl.monitors[window->wl.monitorsCount++] = monitor;
|
window->wl.scaleCount++;
|
||||||
|
window->wl.scales[window->wl.scaleCount - 1].factor = monitor->wl.contentScale;
|
||||||
|
window->wl.scales[window->wl.scaleCount - 1].output = output;
|
||||||
|
|
||||||
_glfwUpdateContentScaleWayland(window);
|
_glfwUpdateContentScaleWayland(window);
|
||||||
}
|
}
|
||||||
|
@ -385,18 +401,20 @@ static void surfaceHandleLeave(void* userData,
|
||||||
struct wl_surface* surface,
|
struct wl_surface* surface,
|
||||||
struct wl_output* output)
|
struct wl_output* output)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = userData;
|
if (wl_proxy_get_tag((struct wl_proxy*) output) != &_glfw.wl.tag)
|
||||||
_GLFWmonitor* monitor = wl_output_get_user_data(output);
|
return;
|
||||||
GLFWbool found = GLFW_FALSE;
|
|
||||||
|
|
||||||
for (int i = 0; i < window->wl.monitorsCount - 1; ++i)
|
_GLFWwindow* window = userData;
|
||||||
|
|
||||||
|
for (int i = 0; i < window->wl.scaleCount; i++)
|
||||||
{
|
{
|
||||||
if (monitor == window->wl.monitors[i])
|
if (window->wl.scales[i].output == output)
|
||||||
found = GLFW_TRUE;
|
{
|
||||||
if (found)
|
window->wl.scales[i] = window->wl.scales[window->wl.scaleCount - 1];
|
||||||
window->wl.monitors[i] = window->wl.monitors[i + 1];
|
window->wl.scaleCount--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
window->wl.monitors[--window->wl.monitorsCount] = NULL;
|
|
||||||
|
|
||||||
_glfwUpdateContentScaleWayland(window);
|
_glfwUpdateContentScaleWayland(window);
|
||||||
}
|
}
|
||||||
|
@ -429,7 +447,12 @@ static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable)
|
||||||
//
|
//
|
||||||
static void acquireMonitor(_GLFWwindow* window)
|
static void acquireMonitor(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (window->wl.xdg.toplevel)
|
if (window->wl.libdecor.frame)
|
||||||
|
{
|
||||||
|
libdecor_frame_set_fullscreen(window->wl.libdecor.frame,
|
||||||
|
window->monitor->wl.output);
|
||||||
|
}
|
||||||
|
else if (window->wl.xdg.toplevel)
|
||||||
{
|
{
|
||||||
xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel,
|
xdg_toplevel_set_fullscreen(window->wl.xdg.toplevel,
|
||||||
window->monitor->wl.output);
|
window->monitor->wl.output);
|
||||||
|
@ -445,12 +468,15 @@ static void acquireMonitor(_GLFWwindow* window)
|
||||||
//
|
//
|
||||||
static void releaseMonitor(_GLFWwindow* window)
|
static void releaseMonitor(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (window->wl.xdg.toplevel)
|
if (window->wl.libdecor.frame)
|
||||||
|
libdecor_frame_unset_fullscreen(window->wl.libdecor.frame);
|
||||||
|
else if (window->wl.xdg.toplevel)
|
||||||
xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
|
xdg_toplevel_unset_fullscreen(window->wl.xdg.toplevel);
|
||||||
|
|
||||||
setIdleInhibitor(window, GLFW_FALSE);
|
setIdleInhibitor(window, GLFW_FALSE);
|
||||||
|
|
||||||
if (window->wl.xdg.decorationMode != ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE)
|
if (!window->wl.libdecor.frame &&
|
||||||
|
window->wl.xdg.decorationMode != ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE)
|
||||||
{
|
{
|
||||||
if (window->decorated)
|
if (window->decorated)
|
||||||
createFallbackDecorations(window);
|
createFallbackDecorations(window);
|
||||||
|
@ -593,7 +619,190 @@ static const struct xdg_surface_listener xdgSurfaceListener =
|
||||||
xdgSurfaceHandleConfigure
|
xdgSurfaceHandleConfigure
|
||||||
};
|
};
|
||||||
|
|
||||||
static GLFWbool createShellObjects(_GLFWwindow* window)
|
void libdecorFrameHandleConfigure(struct libdecor_frame* frame,
|
||||||
|
struct libdecor_configuration* config,
|
||||||
|
void* userData)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = userData;
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
enum libdecor_window_state windowState;
|
||||||
|
GLFWbool fullscreen, activated, maximized;
|
||||||
|
|
||||||
|
if (libdecor_configuration_get_window_state(config, &windowState))
|
||||||
|
{
|
||||||
|
fullscreen = (windowState & LIBDECOR_WINDOW_STATE_FULLSCREEN) != 0;
|
||||||
|
activated = (windowState & LIBDECOR_WINDOW_STATE_ACTIVE) != 0;
|
||||||
|
maximized = (windowState & LIBDECOR_WINDOW_STATE_MAXIMIZED) != 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fullscreen = window->wl.fullscreen;
|
||||||
|
activated = window->wl.activated;
|
||||||
|
maximized = window->wl.maximized;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!libdecor_configuration_get_content_size(config, frame, &width, &height))
|
||||||
|
{
|
||||||
|
width = window->wl.width;
|
||||||
|
height = window->wl.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!maximized && !fullscreen)
|
||||||
|
{
|
||||||
|
if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
const float aspectRatio = (float) width / (float) height;
|
||||||
|
const float targetRatio = (float) window->numer / (float) window->denom;
|
||||||
|
if (aspectRatio < targetRatio)
|
||||||
|
height = width / targetRatio;
|
||||||
|
else if (aspectRatio > targetRatio)
|
||||||
|
width = height * targetRatio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct libdecor_state* frameState = libdecor_state_new(width, height);
|
||||||
|
libdecor_frame_commit(frame, frameState, config);
|
||||||
|
libdecor_state_free(frameState);
|
||||||
|
|
||||||
|
if (window->wl.activated != activated)
|
||||||
|
{
|
||||||
|
window->wl.activated = activated;
|
||||||
|
if (!window->wl.activated)
|
||||||
|
{
|
||||||
|
if (window->monitor && window->autoIconify)
|
||||||
|
libdecor_frame_set_minimized(window->wl.libdecor.frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->wl.maximized != maximized)
|
||||||
|
{
|
||||||
|
window->wl.maximized = maximized;
|
||||||
|
_glfwInputWindowMaximize(window, window->wl.maximized);
|
||||||
|
}
|
||||||
|
|
||||||
|
window->wl.fullscreen = fullscreen;
|
||||||
|
|
||||||
|
GLFWbool damaged = GLFW_FALSE;
|
||||||
|
|
||||||
|
if (!window->wl.visible)
|
||||||
|
{
|
||||||
|
window->wl.visible = GLFW_TRUE;
|
||||||
|
damaged = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width != window->wl.width || height != window->wl.height)
|
||||||
|
{
|
||||||
|
window->wl.width = width;
|
||||||
|
window->wl.height = height;
|
||||||
|
resizeWindow(window);
|
||||||
|
|
||||||
|
_glfwInputWindowSize(window, width, height);
|
||||||
|
damaged = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (damaged)
|
||||||
|
_glfwInputWindowDamage(window);
|
||||||
|
else
|
||||||
|
wl_surface_commit(window->wl.surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void libdecorFrameHandleClose(struct libdecor_frame* frame, void* userData)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = userData;
|
||||||
|
_glfwInputWindowCloseRequest(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void libdecorFrameHandleCommit(struct libdecor_frame* frame, void* userData)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = userData;
|
||||||
|
wl_surface_commit(window->wl.surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void libdecorFrameHandleDismissPopup(struct libdecor_frame* frame,
|
||||||
|
const char* seatName,
|
||||||
|
void* userData)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct libdecor_frame_interface libdecorFrameInterface =
|
||||||
|
{
|
||||||
|
libdecorFrameHandleConfigure,
|
||||||
|
libdecorFrameHandleClose,
|
||||||
|
libdecorFrameHandleCommit,
|
||||||
|
libdecorFrameHandleDismissPopup
|
||||||
|
};
|
||||||
|
|
||||||
|
static GLFWbool createLibdecorFrame(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
window->wl.libdecor.frame = libdecor_decorate(_glfw.wl.libdecor.context,
|
||||||
|
window->wl.surface,
|
||||||
|
&libdecorFrameInterface,
|
||||||
|
window);
|
||||||
|
if (!window->wl.libdecor.frame)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to create libdecor frame");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(window->wl.appId))
|
||||||
|
libdecor_frame_set_app_id(window->wl.libdecor.frame, window->wl.appId);
|
||||||
|
|
||||||
|
if (strlen(window->wl.title))
|
||||||
|
libdecor_frame_set_title(window->wl.libdecor.frame, window->wl.title);
|
||||||
|
|
||||||
|
if (window->minwidth != GLFW_DONT_CARE &&
|
||||||
|
window->minheight != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
libdecor_frame_set_min_content_size(window->wl.libdecor.frame,
|
||||||
|
window->minwidth,
|
||||||
|
window->minheight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->maxwidth != GLFW_DONT_CARE &&
|
||||||
|
window->maxheight != GLFW_DONT_CARE)
|
||||||
|
{
|
||||||
|
libdecor_frame_set_max_content_size(window->wl.libdecor.frame,
|
||||||
|
window->maxwidth,
|
||||||
|
window->maxheight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!window->resizable)
|
||||||
|
{
|
||||||
|
libdecor_frame_unset_capabilities(window->wl.libdecor.frame,
|
||||||
|
LIBDECOR_ACTION_RESIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->monitor)
|
||||||
|
{
|
||||||
|
// HACK: Allow libdecor to finish initialization of itself and its
|
||||||
|
// plugin so it will create the xdg_toplevel for the frame
|
||||||
|
// This needs to exist when setting the frame to fullscreen
|
||||||
|
while (!libdecor_frame_get_xdg_toplevel(window->wl.libdecor.frame))
|
||||||
|
_glfwWaitEventsWayland();
|
||||||
|
|
||||||
|
libdecor_frame_set_fullscreen(window->wl.libdecor.frame,
|
||||||
|
window->monitor->wl.output);
|
||||||
|
setIdleInhibitor(window, GLFW_TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (window->wl.maximized)
|
||||||
|
libdecor_frame_set_maximized(window->wl.libdecor.frame);
|
||||||
|
|
||||||
|
if (!window->decorated)
|
||||||
|
libdecor_frame_set_visibility(window->wl.libdecor.frame, false);
|
||||||
|
|
||||||
|
setIdleInhibitor(window, GLFW_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
libdecor_frame_map(window->wl.libdecor.frame);
|
||||||
|
wl_display_roundtrip(_glfw.wl.display);
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLFWbool createXdgShellObjects(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(_glfw.wl.wmBase,
|
window->wl.xdg.surface = xdg_wm_base_get_xdg_surface(_glfw.wl.wmBase,
|
||||||
window->wl.surface);
|
window->wl.surface);
|
||||||
|
@ -633,30 +842,30 @@ static GLFWbool createShellObjects(_GLFWwindow* window)
|
||||||
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
|
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
|
||||||
|
|
||||||
setIdleInhibitor(window, GLFW_FALSE);
|
setIdleInhibitor(window, GLFW_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
if (_glfw.wl.decorationManager)
|
if (_glfw.wl.decorationManager)
|
||||||
{
|
{
|
||||||
window->wl.xdg.decoration =
|
window->wl.xdg.decoration =
|
||||||
zxdg_decoration_manager_v1_get_toplevel_decoration(
|
zxdg_decoration_manager_v1_get_toplevel_decoration(
|
||||||
_glfw.wl.decorationManager, window->wl.xdg.toplevel);
|
_glfw.wl.decorationManager, window->wl.xdg.toplevel);
|
||||||
zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration,
|
zxdg_toplevel_decoration_v1_add_listener(window->wl.xdg.decoration,
|
||||||
&xdgDecorationListener,
|
&xdgDecorationListener,
|
||||||
window);
|
window);
|
||||||
|
|
||||||
uint32_t mode;
|
uint32_t mode;
|
||||||
|
|
||||||
if (window->decorated)
|
if (window->decorated)
|
||||||
mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;
|
mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;
|
||||||
else
|
|
||||||
mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
|
|
||||||
|
|
||||||
zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
mode = ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
|
||||||
if (window->decorated)
|
|
||||||
createFallbackDecorations(window);
|
zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (window->decorated && !window->monitor)
|
||||||
|
createFallbackDecorations(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE)
|
if (window->minwidth != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE)
|
||||||
|
@ -689,14 +898,27 @@ static GLFWbool createShellObjects(_GLFWwindow* window)
|
||||||
|
|
||||||
wl_surface_commit(window->wl.surface);
|
wl_surface_commit(window->wl.surface);
|
||||||
wl_display_roundtrip(_glfw.wl.display);
|
wl_display_roundtrip(_glfw.wl.display);
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GLFWbool createShellObjects(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (_glfw.wl.libdecor.context)
|
||||||
|
{
|
||||||
|
if (createLibdecorFrame(window))
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return createXdgShellObjects(window);
|
||||||
|
}
|
||||||
|
|
||||||
static void destroyShellObjects(_GLFWwindow* window)
|
static void destroyShellObjects(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
destroyFallbackDecorations(window);
|
destroyFallbackDecorations(window);
|
||||||
|
|
||||||
|
if (window->wl.libdecor.frame)
|
||||||
|
libdecor_frame_unref(window->wl.libdecor.frame);
|
||||||
|
|
||||||
if (window->wl.xdg.decoration)
|
if (window->wl.xdg.decoration)
|
||||||
zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration);
|
zxdg_toplevel_decoration_v1_destroy(window->wl.xdg.decoration);
|
||||||
|
|
||||||
|
@ -706,6 +928,7 @@ static void destroyShellObjects(_GLFWwindow* window)
|
||||||
if (window->wl.xdg.surface)
|
if (window->wl.xdg.surface)
|
||||||
xdg_surface_destroy(window->wl.xdg.surface);
|
xdg_surface_destroy(window->wl.xdg.surface);
|
||||||
|
|
||||||
|
window->wl.libdecor.frame = NULL;
|
||||||
window->wl.xdg.decoration = NULL;
|
window->wl.xdg.decoration = NULL;
|
||||||
window->wl.xdg.decorationMode = 0;
|
window->wl.xdg.decorationMode = 0;
|
||||||
window->wl.xdg.toplevel = NULL;
|
window->wl.xdg.toplevel = NULL;
|
||||||
|
@ -723,15 +946,14 @@ static GLFWbool createNativeSurface(_GLFWwindow* window,
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wl_proxy_set_tag((struct wl_proxy*) window->wl.surface, &_glfw.wl.tag);
|
||||||
wl_surface_add_listener(window->wl.surface,
|
wl_surface_add_listener(window->wl.surface,
|
||||||
&surfaceListener,
|
&surfaceListener,
|
||||||
window);
|
window);
|
||||||
|
|
||||||
wl_surface_set_user_data(window->wl.surface, window);
|
|
||||||
|
|
||||||
window->wl.width = wndconfig->width;
|
window->wl.width = wndconfig->width;
|
||||||
window->wl.height = wndconfig->height;
|
window->wl.height = wndconfig->height;
|
||||||
window->wl.scale = 1;
|
window->wl.contentScale = 1;
|
||||||
window->wl.title = _glfw_strdup(wndconfig->title);
|
window->wl.title = _glfw_strdup(wndconfig->title);
|
||||||
window->wl.appId = _glfw_strdup(wndconfig->wl.appId);
|
window->wl.appId = _glfw_strdup(wndconfig->wl.appId);
|
||||||
|
|
||||||
|
@ -758,7 +980,7 @@ static void setCursorImage(_GLFWwindow* window,
|
||||||
buffer = cursorWayland->buffer;
|
buffer = cursorWayland->buffer;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (window->wl.scale > 1 && cursorWayland->cursorHiDPI)
|
if (window->wl.contentScale > 1 && cursorWayland->cursorHiDPI)
|
||||||
{
|
{
|
||||||
wlCursor = cursorWayland->cursorHiDPI;
|
wlCursor = cursorWayland->cursorHiDPI;
|
||||||
scale = 2;
|
scale = 2;
|
||||||
|
@ -794,7 +1016,7 @@ static void incrementCursorImage(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
_GLFWcursor* cursor;
|
_GLFWcursor* cursor;
|
||||||
|
|
||||||
if (!window || window->wl.decorations.focus != mainWindow)
|
if (!window || window->wl.decorations.focus != GLFW_MAIN_WINDOW)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cursor = window->wl.currentCursor;
|
cursor = window->wl.currentCursor;
|
||||||
|
@ -873,14 +1095,23 @@ static void inputText(_GLFWwindow* window, uint32_t scancode)
|
||||||
|
|
||||||
static void handleEvents(double* timeout)
|
static void handleEvents(double* timeout)
|
||||||
{
|
{
|
||||||
|
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
|
||||||
|
if (_glfw.joysticksInitialized)
|
||||||
|
_glfwDetectJoystickConnectionLinux();
|
||||||
|
#endif
|
||||||
|
|
||||||
GLFWbool event = GLFW_FALSE;
|
GLFWbool event = GLFW_FALSE;
|
||||||
struct pollfd fds[] =
|
struct pollfd fds[4] =
|
||||||
{
|
{
|
||||||
{ wl_display_get_fd(_glfw.wl.display), POLLIN },
|
{ wl_display_get_fd(_glfw.wl.display), POLLIN },
|
||||||
{ _glfw.wl.keyRepeatTimerfd, POLLIN },
|
{ _glfw.wl.keyRepeatTimerfd, POLLIN },
|
||||||
{ _glfw.wl.cursorTimerfd, POLLIN },
|
{ _glfw.wl.cursorTimerfd, POLLIN },
|
||||||
|
{ -1, POLLIN }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (_glfw.wl.libdecor.context)
|
||||||
|
fds[3].fd = libdecor_get_fd(_glfw.wl.libdecor.context);
|
||||||
|
|
||||||
while (!event)
|
while (!event)
|
||||||
{
|
{
|
||||||
while (wl_display_prepare_read(_glfw.wl.display) != 0)
|
while (wl_display_prepare_read(_glfw.wl.display) != 0)
|
||||||
|
@ -902,7 +1133,7 @@ static void handleEvents(double* timeout)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_glfwPollPOSIX(fds, 3, timeout))
|
if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), timeout))
|
||||||
{
|
{
|
||||||
wl_display_cancel_read(_glfw.wl.display);
|
wl_display_cancel_read(_glfw.wl.display);
|
||||||
return;
|
return;
|
||||||
|
@ -947,6 +1178,9 @@ static void handleEvents(double* timeout)
|
||||||
event = GLFW_TRUE;
|
event = GLFW_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fds[3].revents & POLLIN)
|
||||||
|
libdecor_dispatch(_glfw.wl.libdecor.context, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1014,40 +1248,6 @@ static char* readDataOfferAsString(struct wl_data_offer* offer, const char* mime
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
|
|
||||||
_GLFWdecorationSideWayland* which)
|
|
||||||
{
|
|
||||||
_GLFWdecorationSideWayland focus;
|
|
||||||
_GLFWwindow* window = _glfw.windowListHead;
|
|
||||||
if (!which)
|
|
||||||
which = &focus;
|
|
||||||
while (window)
|
|
||||||
{
|
|
||||||
if (surface == window->wl.decorations.top.surface)
|
|
||||||
{
|
|
||||||
*which = topDecoration;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (surface == window->wl.decorations.left.surface)
|
|
||||||
{
|
|
||||||
*which = leftDecoration;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (surface == window->wl.decorations.right.surface)
|
|
||||||
{
|
|
||||||
*which = rightDecoration;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (surface == window->wl.decorations.bottom.surface)
|
|
||||||
{
|
|
||||||
*which = bottomDecoration;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
window = window->next;
|
|
||||||
}
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pointerHandleEnter(void* userData,
|
static void pointerHandleEnter(void* userData,
|
||||||
struct wl_pointer* pointer,
|
struct wl_pointer* pointer,
|
||||||
uint32_t serial,
|
uint32_t serial,
|
||||||
|
@ -1059,16 +1259,22 @@ static void pointerHandleEnter(void* userData,
|
||||||
if (!surface)
|
if (!surface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_GLFWdecorationSideWayland focus = mainWindow;
|
if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag)
|
||||||
_GLFWwindow* window = wl_surface_get_user_data(surface);
|
return;
|
||||||
if (!window)
|
|
||||||
{
|
_GLFWwindow* window = wl_surface_get_user_data(surface);
|
||||||
window = findWindowFromDecorationSurface(surface, &focus);
|
|
||||||
if (!window)
|
if (surface == window->wl.decorations.top.surface)
|
||||||
return;
|
window->wl.decorations.focus = GLFW_TOP_DECORATION;
|
||||||
}
|
else if (surface == window->wl.decorations.left.surface)
|
||||||
|
window->wl.decorations.focus = GLFW_LEFT_DECORATION;
|
||||||
|
else if (surface == window->wl.decorations.right.surface)
|
||||||
|
window->wl.decorations.focus = GLFW_RIGHT_DECORATION;
|
||||||
|
else if (surface == window->wl.decorations.bottom.surface)
|
||||||
|
window->wl.decorations.focus = GLFW_BOTTOM_DECORATION;
|
||||||
|
else
|
||||||
|
window->wl.decorations.focus = GLFW_MAIN_WINDOW;
|
||||||
|
|
||||||
window->wl.decorations.focus = focus;
|
|
||||||
_glfw.wl.serial = serial;
|
_glfw.wl.serial = serial;
|
||||||
_glfw.wl.pointerEnterSerial = serial;
|
_glfw.wl.pointerEnterSerial = serial;
|
||||||
_glfw.wl.pointerFocus = window;
|
_glfw.wl.pointerFocus = window;
|
||||||
|
@ -1084,8 +1290,13 @@ static void pointerHandleLeave(void* userData,
|
||||||
uint32_t serial,
|
uint32_t serial,
|
||||||
struct wl_surface* surface)
|
struct wl_surface* surface)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
if (!surface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
||||||
if (!window)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1106,7 +1317,7 @@ static void setCursor(_GLFWwindow* window, const char* name)
|
||||||
struct wl_cursor_theme* theme = _glfw.wl.cursorTheme;
|
struct wl_cursor_theme* theme = _glfw.wl.cursorTheme;
|
||||||
int scale = 1;
|
int scale = 1;
|
||||||
|
|
||||||
if (window->wl.scale > 1 && _glfw.wl.cursorThemeHiDPI)
|
if (window->wl.contentScale > 1 && _glfw.wl.cursorThemeHiDPI)
|
||||||
{
|
{
|
||||||
// We only support up to scale=2 for now, since libwayland-cursor
|
// We only support up to scale=2 for now, since libwayland-cursor
|
||||||
// requires us to load a different theme for each size.
|
// requires us to load a different theme for each size.
|
||||||
|
@ -1164,29 +1375,29 @@ static void pointerHandleMotion(void* userData,
|
||||||
|
|
||||||
switch (window->wl.decorations.focus)
|
switch (window->wl.decorations.focus)
|
||||||
{
|
{
|
||||||
case mainWindow:
|
case GLFW_MAIN_WINDOW:
|
||||||
_glfw.wl.cursorPreviousName = NULL;
|
_glfw.wl.cursorPreviousName = NULL;
|
||||||
_glfwInputCursorPos(window, x, y);
|
_glfwInputCursorPos(window, x, y);
|
||||||
return;
|
return;
|
||||||
case topDecoration:
|
case GLFW_TOP_DECORATION:
|
||||||
if (y < GLFW_BORDER_SIZE)
|
if (y < GLFW_BORDER_SIZE)
|
||||||
cursorName = "n-resize";
|
cursorName = "n-resize";
|
||||||
else
|
else
|
||||||
cursorName = "left_ptr";
|
cursorName = "left_ptr";
|
||||||
break;
|
break;
|
||||||
case leftDecoration:
|
case GLFW_LEFT_DECORATION:
|
||||||
if (y < GLFW_BORDER_SIZE)
|
if (y < GLFW_BORDER_SIZE)
|
||||||
cursorName = "nw-resize";
|
cursorName = "nw-resize";
|
||||||
else
|
else
|
||||||
cursorName = "w-resize";
|
cursorName = "w-resize";
|
||||||
break;
|
break;
|
||||||
case rightDecoration:
|
case GLFW_RIGHT_DECORATION:
|
||||||
if (y < GLFW_BORDER_SIZE)
|
if (y < GLFW_BORDER_SIZE)
|
||||||
cursorName = "ne-resize";
|
cursorName = "ne-resize";
|
||||||
else
|
else
|
||||||
cursorName = "e-resize";
|
cursorName = "e-resize";
|
||||||
break;
|
break;
|
||||||
case bottomDecoration:
|
case GLFW_BOTTOM_DECORATION:
|
||||||
if (x < GLFW_BORDER_SIZE)
|
if (x < GLFW_BORDER_SIZE)
|
||||||
cursorName = "sw-resize";
|
cursorName = "sw-resize";
|
||||||
else if (x > window->wl.width + GLFW_BORDER_SIZE)
|
else if (x > window->wl.width + GLFW_BORDER_SIZE)
|
||||||
|
@ -1218,27 +1429,27 @@ static void pointerHandleButton(void* userData,
|
||||||
{
|
{
|
||||||
switch (window->wl.decorations.focus)
|
switch (window->wl.decorations.focus)
|
||||||
{
|
{
|
||||||
case mainWindow:
|
case GLFW_MAIN_WINDOW:
|
||||||
break;
|
break;
|
||||||
case topDecoration:
|
case GLFW_TOP_DECORATION:
|
||||||
if (window->wl.cursorPosY < GLFW_BORDER_SIZE)
|
if (window->wl.cursorPosY < GLFW_BORDER_SIZE)
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
|
||||||
else
|
else
|
||||||
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
|
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
|
||||||
break;
|
break;
|
||||||
case leftDecoration:
|
case GLFW_LEFT_DECORATION:
|
||||||
if (window->wl.cursorPosY < GLFW_BORDER_SIZE)
|
if (window->wl.cursorPosY < GLFW_BORDER_SIZE)
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
|
||||||
else
|
else
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
|
||||||
break;
|
break;
|
||||||
case rightDecoration:
|
case GLFW_RIGHT_DECORATION:
|
||||||
if (window->wl.cursorPosY < GLFW_BORDER_SIZE)
|
if (window->wl.cursorPosY < GLFW_BORDER_SIZE)
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
|
||||||
else
|
else
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
|
||||||
break;
|
break;
|
||||||
case bottomDecoration:
|
case GLFW_BOTTOM_DECORATION:
|
||||||
if (window->wl.cursorPosX < GLFW_BORDER_SIZE)
|
if (window->wl.cursorPosX < GLFW_BORDER_SIZE)
|
||||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
|
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
|
||||||
else if (window->wl.cursorPosX > window->wl.width + GLFW_BORDER_SIZE)
|
else if (window->wl.cursorPosX > window->wl.width + GLFW_BORDER_SIZE)
|
||||||
|
@ -1258,7 +1469,8 @@ static void pointerHandleButton(void* userData,
|
||||||
}
|
}
|
||||||
else if (button == BTN_RIGHT)
|
else if (button == BTN_RIGHT)
|
||||||
{
|
{
|
||||||
if (window->wl.decorations.focus != mainWindow && window->wl.xdg.toplevel)
|
if (window->wl.decorations.focus != GLFW_MAIN_WINDOW &&
|
||||||
|
window->wl.xdg.toplevel)
|
||||||
{
|
{
|
||||||
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
|
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
|
||||||
_glfw.wl.seat, serial,
|
_glfw.wl.seat, serial,
|
||||||
|
@ -1269,7 +1481,7 @@ static void pointerHandleButton(void* userData,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don’t pass the button to the user if it was related to a decoration.
|
// Don’t pass the button to the user if it was related to a decoration.
|
||||||
if (window->wl.decorations.focus != mainWindow)
|
if (window->wl.decorations.focus != GLFW_MAIN_WINDOW)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_glfw.wl.serial = serial;
|
_glfw.wl.serial = serial;
|
||||||
|
@ -1423,13 +1635,12 @@ static void keyboardHandleEnter(void* userData,
|
||||||
if (!surface)
|
if (!surface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag)
|
||||||
|
return;
|
||||||
|
|
||||||
_GLFWwindow* window = wl_surface_get_user_data(surface);
|
_GLFWwindow* window = wl_surface_get_user_data(surface);
|
||||||
if (!window)
|
if (surface != window->wl.surface)
|
||||||
{
|
return;
|
||||||
window = findWindowFromDecorationSurface(surface, NULL);
|
|
||||||
if (!window)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfw.wl.serial = serial;
|
_glfw.wl.serial = serial;
|
||||||
_glfw.wl.keyboardFocus = window;
|
_glfw.wl.keyboardFocus = window;
|
||||||
|
@ -1640,7 +1851,8 @@ static void dataDeviceHandleDataOffer(void* userData,
|
||||||
struct wl_data_offer* offer)
|
struct wl_data_offer* offer)
|
||||||
{
|
{
|
||||||
_GLFWofferWayland* offers =
|
_GLFWofferWayland* offers =
|
||||||
_glfw_realloc(_glfw.wl.offers, _glfw.wl.offerCount + 1);
|
_glfw_realloc(_glfw.wl.offers,
|
||||||
|
sizeof(_GLFWofferWayland) * (_glfw.wl.offerCount + 1));
|
||||||
if (!offers)
|
if (!offers)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_OUT_OF_MEMORY, NULL);
|
_glfwInputError(GLFW_OUT_OF_MEMORY, NULL);
|
||||||
|
@ -1676,9 +1888,12 @@ static void dataDeviceHandleEnter(void* userData,
|
||||||
_GLFWwindow* window = NULL;
|
_GLFWwindow* window = NULL;
|
||||||
|
|
||||||
if (surface)
|
if (surface)
|
||||||
window = wl_surface_get_user_data(surface);
|
{
|
||||||
|
if (wl_proxy_get_tag((struct wl_proxy*) surface) == &_glfw.wl.tag)
|
||||||
|
window = wl_surface_get_user_data(surface);
|
||||||
|
}
|
||||||
|
|
||||||
if (window && _glfw.wl.offers[i].text_uri_list)
|
if (surface == window->wl.surface && _glfw.wl.offers[i].text_uri_list)
|
||||||
{
|
{
|
||||||
_glfw.wl.dragOffer = offer;
|
_glfw.wl.dragOffer = offer;
|
||||||
_glfw.wl.dragFocus = window;
|
_glfw.wl.dragFocus = window;
|
||||||
|
@ -1691,6 +1906,9 @@ static void dataDeviceHandleEnter(void* userData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wl_proxy_get_tag((struct wl_proxy*) surface) != &_glfw.wl.tag)
|
||||||
|
return;
|
||||||
|
|
||||||
if (_glfw.wl.dragOffer)
|
if (_glfw.wl.dragOffer)
|
||||||
wl_data_offer_accept(offer, serial, "text/uri-list");
|
wl_data_offer_accept(offer, serial, "text/uri-list");
|
||||||
else
|
else
|
||||||
|
@ -1881,7 +2099,7 @@ void _glfwDestroyWindowWayland(_GLFWwindow* window)
|
||||||
|
|
||||||
_glfw_free(window->wl.title);
|
_glfw_free(window->wl.title);
|
||||||
_glfw_free(window->wl.appId);
|
_glfw_free(window->wl.appId);
|
||||||
_glfw_free(window->wl.monitors);
|
_glfw_free(window->wl.scales);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title)
|
void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title)
|
||||||
|
@ -1890,7 +2108,9 @@ void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title)
|
||||||
_glfw_free(window->wl.title);
|
_glfw_free(window->wl.title);
|
||||||
window->wl.title = copy;
|
window->wl.title = copy;
|
||||||
|
|
||||||
if (window->wl.xdg.toplevel)
|
if (window->wl.libdecor.frame)
|
||||||
|
libdecor_frame_set_title(window->wl.libdecor.frame, title);
|
||||||
|
else if (window->wl.xdg.toplevel)
|
||||||
xdg_toplevel_set_title(window->wl.xdg.toplevel, title);
|
xdg_toplevel_set_title(window->wl.xdg.toplevel, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1937,6 +2157,16 @@ void _glfwSetWindowSizeWayland(_GLFWwindow* window, int width, int height)
|
||||||
window->wl.width = width;
|
window->wl.width = width;
|
||||||
window->wl.height = height;
|
window->wl.height = height;
|
||||||
resizeWindow(window);
|
resizeWindow(window);
|
||||||
|
|
||||||
|
if (window->wl.libdecor.frame)
|
||||||
|
{
|
||||||
|
struct libdecor_state* frameState = libdecor_state_new(width, height);
|
||||||
|
libdecor_frame_commit(window->wl.libdecor.frame, frameState, NULL);
|
||||||
|
libdecor_state_free(frameState);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->wl.visible)
|
||||||
|
_glfwInputWindowDamage(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1944,7 +2174,20 @@ void _glfwSetWindowSizeLimitsWayland(_GLFWwindow* window,
|
||||||
int minwidth, int minheight,
|
int minwidth, int minheight,
|
||||||
int maxwidth, int maxheight)
|
int maxwidth, int maxheight)
|
||||||
{
|
{
|
||||||
if (window->wl.xdg.toplevel)
|
if (window->wl.libdecor.frame)
|
||||||
|
{
|
||||||
|
if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE)
|
||||||
|
minwidth = minheight = 0;
|
||||||
|
|
||||||
|
if (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE)
|
||||||
|
maxwidth = maxheight = 0;
|
||||||
|
|
||||||
|
libdecor_frame_set_min_content_size(window->wl.libdecor.frame,
|
||||||
|
minwidth, minheight);
|
||||||
|
libdecor_frame_set_max_content_size(window->wl.libdecor.frame,
|
||||||
|
maxwidth, maxheight);
|
||||||
|
}
|
||||||
|
else if (window->wl.xdg.toplevel)
|
||||||
{
|
{
|
||||||
if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE)
|
if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE)
|
||||||
minwidth = minheight = 0;
|
minwidth = minheight = 0;
|
||||||
|
@ -1979,16 +2222,35 @@ void _glfwSetWindowAspectRatioWayland(_GLFWwindow* window, int numer, int denom)
|
||||||
if (window->wl.maximized || window->wl.fullscreen)
|
if (window->wl.maximized || window->wl.fullscreen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
int width = window->wl.width, height = window->wl.height;
|
||||||
|
|
||||||
if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE)
|
if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE)
|
||||||
{
|
{
|
||||||
const float aspectRatio = (float) window->wl.width / (float) window->wl.height;
|
const float aspectRatio = (float) width / (float) height;
|
||||||
const float targetRatio = (float) numer / (float) denom;
|
const float targetRatio = (float) numer / (float) denom;
|
||||||
if (aspectRatio < targetRatio)
|
if (aspectRatio < targetRatio)
|
||||||
window->wl.height = window->wl.width / targetRatio;
|
height /= targetRatio;
|
||||||
else if (aspectRatio > targetRatio)
|
else if (aspectRatio > targetRatio)
|
||||||
window->wl.width = window->wl.height * targetRatio;
|
width *= targetRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width != window->wl.width || height != window->wl.height)
|
||||||
|
{
|
||||||
|
window->wl.width = width;
|
||||||
|
window->wl.height = height;
|
||||||
resizeWindow(window);
|
resizeWindow(window);
|
||||||
|
|
||||||
|
if (window->wl.libdecor.frame)
|
||||||
|
{
|
||||||
|
struct libdecor_state* frameState = libdecor_state_new(width, height);
|
||||||
|
libdecor_frame_commit(window->wl.libdecor.frame, frameState, NULL);
|
||||||
|
libdecor_state_free(frameState);
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwInputWindowSize(window, width, height);
|
||||||
|
|
||||||
|
if (window->wl.visible)
|
||||||
|
_glfwInputWindowDamage(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1996,16 +2258,16 @@ void _glfwGetFramebufferSizeWayland(_GLFWwindow* window, int* width, int* height
|
||||||
{
|
{
|
||||||
_glfwGetWindowSizeWayland(window, width, height);
|
_glfwGetWindowSizeWayland(window, width, height);
|
||||||
if (width)
|
if (width)
|
||||||
*width *= window->wl.scale;
|
*width *= window->wl.contentScale;
|
||||||
if (height)
|
if (height)
|
||||||
*height *= window->wl.scale;
|
*height *= window->wl.contentScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwGetWindowFrameSizeWayland(_GLFWwindow* window,
|
void _glfwGetWindowFrameSizeWayland(_GLFWwindow* window,
|
||||||
int* left, int* top,
|
int* left, int* top,
|
||||||
int* right, int* bottom)
|
int* right, int* bottom)
|
||||||
{
|
{
|
||||||
if (window->decorated && !window->monitor && window->wl.decorations.top.surface)
|
if (window->wl.decorations.top.surface)
|
||||||
{
|
{
|
||||||
if (top)
|
if (top)
|
||||||
*top = GLFW_CAPTION_HEIGHT;
|
*top = GLFW_CAPTION_HEIGHT;
|
||||||
|
@ -2022,14 +2284,16 @@ void _glfwGetWindowContentScaleWayland(_GLFWwindow* window,
|
||||||
float* xscale, float* yscale)
|
float* xscale, float* yscale)
|
||||||
{
|
{
|
||||||
if (xscale)
|
if (xscale)
|
||||||
*xscale = (float) window->wl.scale;
|
*xscale = (float) window->wl.contentScale;
|
||||||
if (yscale)
|
if (yscale)
|
||||||
*yscale = (float) window->wl.scale;
|
*yscale = (float) window->wl.contentScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwIconifyWindowWayland(_GLFWwindow* window)
|
void _glfwIconifyWindowWayland(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (window->wl.xdg.toplevel)
|
if (window->wl.libdecor.frame)
|
||||||
|
libdecor_frame_set_minimized(window->wl.libdecor.frame);
|
||||||
|
else if (window->wl.xdg.toplevel)
|
||||||
xdg_toplevel_set_minimized(window->wl.xdg.toplevel);
|
xdg_toplevel_set_minimized(window->wl.xdg.toplevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2046,7 +2310,9 @@ void _glfwRestoreWindowWayland(_GLFWwindow* window)
|
||||||
|
|
||||||
if (window->wl.maximized)
|
if (window->wl.maximized)
|
||||||
{
|
{
|
||||||
if (window->wl.xdg.toplevel)
|
if (window->wl.libdecor.frame)
|
||||||
|
libdecor_frame_unset_maximized(window->wl.libdecor.frame);
|
||||||
|
else if (window->wl.xdg.toplevel)
|
||||||
xdg_toplevel_unset_maximized(window->wl.xdg.toplevel);
|
xdg_toplevel_unset_maximized(window->wl.xdg.toplevel);
|
||||||
else
|
else
|
||||||
window->wl.maximized = GLFW_FALSE;
|
window->wl.maximized = GLFW_FALSE;
|
||||||
|
@ -2056,7 +2322,9 @@ void _glfwRestoreWindowWayland(_GLFWwindow* window)
|
||||||
|
|
||||||
void _glfwMaximizeWindowWayland(_GLFWwindow* window)
|
void _glfwMaximizeWindowWayland(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (window->wl.xdg.toplevel)
|
if (window->wl.libdecor.frame)
|
||||||
|
libdecor_frame_set_maximized(window->wl.libdecor.frame);
|
||||||
|
else if (window->wl.xdg.toplevel)
|
||||||
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
|
xdg_toplevel_set_maximized(window->wl.xdg.toplevel);
|
||||||
else
|
else
|
||||||
window->wl.maximized = GLFW_TRUE;
|
window->wl.maximized = GLFW_TRUE;
|
||||||
|
@ -2064,7 +2332,7 @@ void _glfwMaximizeWindowWayland(_GLFWwindow* window)
|
||||||
|
|
||||||
void _glfwShowWindowWayland(_GLFWwindow* window)
|
void _glfwShowWindowWayland(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (!window->wl.xdg.toplevel)
|
if (!window->wl.libdecor.frame && !window->wl.xdg.toplevel)
|
||||||
{
|
{
|
||||||
// NOTE: The XDG surface and role are created here so command-line applications
|
// NOTE: The XDG surface and role are created here so command-line applications
|
||||||
// with off-screen windows do not appear in for example the Unity dock
|
// with off-screen windows do not appear in for example the Unity dock
|
||||||
|
@ -2156,14 +2424,34 @@ GLFWbool _glfwFramebufferTransparentWayland(_GLFWwindow* window)
|
||||||
|
|
||||||
void _glfwSetWindowResizableWayland(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwSetWindowResizableWayland(_GLFWwindow* window, GLFWbool enabled)
|
||||||
{
|
{
|
||||||
// TODO
|
if (window->wl.libdecor.frame)
|
||||||
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
|
{
|
||||||
"Wayland: Window attribute setting not implemented yet");
|
if (enabled)
|
||||||
|
{
|
||||||
|
libdecor_frame_set_capabilities(window->wl.libdecor.frame,
|
||||||
|
LIBDECOR_ACTION_RESIZE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
libdecor_frame_unset_capabilities(window->wl.libdecor.frame,
|
||||||
|
LIBDECOR_ACTION_RESIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
|
||||||
|
"Wayland: Window attribute setting not implemented yet");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwSetWindowDecoratedWayland(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwSetWindowDecoratedWayland(_GLFWwindow* window, GLFWbool enabled)
|
||||||
{
|
{
|
||||||
if (window->wl.xdg.decoration)
|
if (window->wl.libdecor.frame)
|
||||||
|
{
|
||||||
|
libdecor_frame_set_visibility(window->wl.libdecor.frame, enabled);
|
||||||
|
}
|
||||||
|
else if (window->wl.xdg.decoration)
|
||||||
{
|
{
|
||||||
uint32_t mode;
|
uint32_t mode;
|
||||||
|
|
||||||
|
@ -2174,7 +2462,7 @@ void _glfwSetWindowDecoratedWayland(_GLFWwindow* window, GLFWbool enabled)
|
||||||
|
|
||||||
zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode);
|
zxdg_toplevel_decoration_v1_set_mode(window->wl.xdg.decoration, mode);
|
||||||
}
|
}
|
||||||
else
|
else if (window->wl.xdg.toplevel)
|
||||||
{
|
{
|
||||||
if (enabled)
|
if (enabled)
|
||||||
createFallbackDecorations(window);
|
createFallbackDecorations(window);
|
||||||
|
@ -2584,8 +2872,11 @@ void _glfwSetCursorWayland(_GLFWwindow* window, _GLFWcursor* cursor)
|
||||||
|
|
||||||
// If we're not in the correct window just save the cursor
|
// If we're not in the correct window just save the cursor
|
||||||
// the next time the pointer enters the window the cursor will change
|
// the next time the pointer enters the window the cursor will change
|
||||||
if (window != _glfw.wl.pointerFocus || window->wl.decorations.focus != mainWindow)
|
if (window != _glfw.wl.pointerFocus ||
|
||||||
|
window->wl.decorations.focus != GLFW_MAIN_WINDOW)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Update pointer lock to match cursor mode
|
// Update pointer lock to match cursor mode
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
|
|
|
@ -1184,7 +1184,7 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
|
||||||
_glfwGetKeyScancodeX11,
|
_glfwGetKeyScancodeX11,
|
||||||
_glfwSetClipboardStringX11,
|
_glfwSetClipboardStringX11,
|
||||||
_glfwGetClipboardStringX11,
|
_glfwGetClipboardStringX11,
|
||||||
#if defined(_GLFW_LINUX_JOYSTICK)
|
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
|
||||||
_glfwInitJoysticksLinux,
|
_glfwInitJoysticksLinux,
|
||||||
_glfwTerminateJoysticksLinux,
|
_glfwTerminateJoysticksLinux,
|
||||||
_glfwPollJoystickLinux,
|
_glfwPollJoystickLinux,
|
||||||
|
|
|
@ -88,7 +88,7 @@ static GLFWbool waitForAnyEvent(double* timeout)
|
||||||
{ _glfw.x11.emptyEventPipe[0], POLLIN }
|
{ _glfw.x11.emptyEventPipe[0], POLLIN }
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(_GLFW_LINUX_JOYSTICK)
|
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
|
||||||
if (_glfw.joysticksInitialized)
|
if (_glfw.joysticksInitialized)
|
||||||
fds[count++] = (struct pollfd) { _glfw.linjs.inotify, POLLIN };
|
fds[count++] = (struct pollfd) { _glfw.linjs.inotify, POLLIN };
|
||||||
#endif
|
#endif
|
||||||
|
@ -2783,7 +2783,7 @@ void _glfwPollEventsX11(void)
|
||||||
{
|
{
|
||||||
drainEmptyEvents();
|
drainEmptyEvents();
|
||||||
|
|
||||||
#if defined(_GLFW_LINUX_JOYSTICK)
|
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
|
||||||
if (_glfw.joysticksInitialized)
|
if (_glfw.joysticksInitialized)
|
||||||
_glfwDetectJoystickConnectionLinux();
|
_glfwDetectJoystickConnectionLinux();
|
||||||
#endif
|
#endif
|
||||||
|
|
359
tests/glfwinfo.c
359
tests/glfwinfo.c
|
@ -266,9 +266,10 @@ static void list_vulkan_instance_layers(void)
|
||||||
|
|
||||||
for (uint32_t i = 0; i < lp_count; i++)
|
for (uint32_t i = 0; i < lp_count; i++)
|
||||||
{
|
{
|
||||||
printf(" %s (spec version %u) \"%s\"\n",
|
printf(" %s (spec version %u.%u) \"%s\"\n",
|
||||||
lp[i].layerName,
|
lp[i].layerName,
|
||||||
lp[i].specVersion >> 22,
|
VK_VERSION_MAJOR(lp[i].specVersion),
|
||||||
|
VK_VERSION_MINOR(lp[i].specVersion),
|
||||||
lp[i].description);
|
lp[i].description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,9 +287,10 @@ static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice devi
|
||||||
|
|
||||||
for (uint32_t i = 0; i < lp_count; i++)
|
for (uint32_t i = 0; i < lp_count; i++)
|
||||||
{
|
{
|
||||||
printf(" %s (spec version %u) \"%s\"\n",
|
printf(" %s (spec version %u.%u) \"%s\"\n",
|
||||||
lp[i].layerName,
|
lp[i].layerName,
|
||||||
lp[i].specVersion >> 22,
|
VK_VERSION_MAJOR(lp[i].specVersion),
|
||||||
|
VK_VERSION_MINOR(lp[i].specVersion),
|
||||||
lp[i].description);
|
lp[i].description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -710,190 +712,187 @@ int main(int argc, char** argv)
|
||||||
glfwWindowHint(GLFW_COCOA_GRAPHICS_SWITCHING, cocoa_graphics_switching);
|
glfwWindowHint(GLFW_COCOA_GRAPHICS_SWITCHING, cocoa_graphics_switching);
|
||||||
|
|
||||||
GLFWwindow* window = glfwCreateWindow(200, 200, "Version", NULL, NULL);
|
GLFWwindow* window = glfwCreateWindow(200, 200, "Version", NULL, NULL);
|
||||||
if (!window)
|
if (window)
|
||||||
{
|
{
|
||||||
glfwTerminate();
|
glfwMakeContextCurrent(window);
|
||||||
exit(EXIT_FAILURE);
|
gladLoadGL(glfwGetProcAddress);
|
||||||
}
|
|
||||||
|
|
||||||
glfwMakeContextCurrent(window);
|
const GLenum error = glGetError();
|
||||||
gladLoadGL(glfwGetProcAddress);
|
if (error != GL_NO_ERROR)
|
||||||
|
printf("*** OpenGL error after make current: 0x%08x ***\n", error);
|
||||||
|
|
||||||
const GLenum error = glGetError();
|
// Report client API version
|
||||||
if (error != GL_NO_ERROR)
|
|
||||||
printf("*** OpenGL error after make current: 0x%08x ***\n", error);
|
|
||||||
|
|
||||||
// Report client API version
|
const int client = glfwGetWindowAttrib(window, GLFW_CLIENT_API);
|
||||||
|
const int major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
|
||||||
|
const int minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
|
||||||
|
const int revision = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION);
|
||||||
|
const int profile = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE);
|
||||||
|
|
||||||
const int client = glfwGetWindowAttrib(window, GLFW_CLIENT_API);
|
printf("%s context version string: \"%s\"\n",
|
||||||
const int major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
|
|
||||||
const int minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
|
|
||||||
const int revision = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION);
|
|
||||||
const int profile = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE);
|
|
||||||
|
|
||||||
printf("%s context version string: \"%s\"\n",
|
|
||||||
get_api_name(client),
|
|
||||||
glGetString(GL_VERSION));
|
|
||||||
|
|
||||||
printf("%s context version parsed by GLFW: %u.%u.%u\n",
|
|
||||||
get_api_name(client),
|
|
||||||
major, minor, revision);
|
|
||||||
|
|
||||||
// Report client API context properties
|
|
||||||
|
|
||||||
if (client == GLFW_OPENGL_API)
|
|
||||||
{
|
|
||||||
if (major >= 3)
|
|
||||||
{
|
|
||||||
GLint flags;
|
|
||||||
|
|
||||||
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
|
|
||||||
printf("%s context flags (0x%08x):", get_api_name(client), flags);
|
|
||||||
|
|
||||||
if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
|
|
||||||
printf(" forward-compatible");
|
|
||||||
if (flags & 2/*GL_CONTEXT_FLAG_DEBUG_BIT*/)
|
|
||||||
printf(" debug");
|
|
||||||
if (flags & GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB)
|
|
||||||
printf(" robustness");
|
|
||||||
if (flags & 8/*GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR*/)
|
|
||||||
printf(" no-error");
|
|
||||||
putchar('\n');
|
|
||||||
|
|
||||||
printf("%s context flags parsed by GLFW:", get_api_name(client));
|
|
||||||
|
|
||||||
if (glfwGetWindowAttrib(window, GLFW_OPENGL_FORWARD_COMPAT))
|
|
||||||
printf(" forward-compatible");
|
|
||||||
if (glfwGetWindowAttrib(window, GLFW_CONTEXT_DEBUG))
|
|
||||||
printf(" debug");
|
|
||||||
if (glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS) == GLFW_LOSE_CONTEXT_ON_RESET)
|
|
||||||
printf(" robustness");
|
|
||||||
if (glfwGetWindowAttrib(window, GLFW_CONTEXT_NO_ERROR))
|
|
||||||
printf(" no-error");
|
|
||||||
putchar('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (major >= 4 || (major == 3 && minor >= 2))
|
|
||||||
{
|
|
||||||
GLint mask;
|
|
||||||
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
|
|
||||||
|
|
||||||
printf("%s profile mask (0x%08x): %s\n",
|
|
||||||
get_api_name(client),
|
|
||||||
mask,
|
|
||||||
get_profile_name_gl(mask));
|
|
||||||
|
|
||||||
printf("%s profile mask parsed by GLFW: %s\n",
|
|
||||||
get_api_name(client),
|
|
||||||
get_profile_name_glfw(profile));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GLAD_GL_ARB_robustness)
|
|
||||||
{
|
|
||||||
const int robustness = glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS);
|
|
||||||
GLint strategy;
|
|
||||||
glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy);
|
|
||||||
|
|
||||||
printf("%s robustness strategy (0x%08x): %s\n",
|
|
||||||
get_api_name(client),
|
|
||||||
strategy,
|
|
||||||
get_strategy_name_gl(strategy));
|
|
||||||
|
|
||||||
printf("%s robustness strategy parsed by GLFW: %s\n",
|
|
||||||
get_api_name(client),
|
|
||||||
get_strategy_name_glfw(robustness));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s context renderer string: \"%s\"\n",
|
|
||||||
get_api_name(client),
|
|
||||||
glGetString(GL_RENDERER));
|
|
||||||
printf("%s context vendor string: \"%s\"\n",
|
|
||||||
get_api_name(client),
|
|
||||||
glGetString(GL_VENDOR));
|
|
||||||
|
|
||||||
if (major >= 2)
|
|
||||||
{
|
|
||||||
printf("%s context shading language version: \"%s\"\n",
|
|
||||||
get_api_name(client),
|
get_api_name(client),
|
||||||
glGetString(GL_SHADING_LANGUAGE_VERSION));
|
glGetString(GL_VERSION));
|
||||||
|
|
||||||
|
printf("%s context version parsed by GLFW: %u.%u.%u\n",
|
||||||
|
get_api_name(client),
|
||||||
|
major, minor, revision);
|
||||||
|
|
||||||
|
// Report client API context properties
|
||||||
|
|
||||||
|
if (client == GLFW_OPENGL_API)
|
||||||
|
{
|
||||||
|
if (major >= 3)
|
||||||
|
{
|
||||||
|
GLint flags;
|
||||||
|
|
||||||
|
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
|
||||||
|
printf("%s context flags (0x%08x):", get_api_name(client), flags);
|
||||||
|
|
||||||
|
if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
|
||||||
|
printf(" forward-compatible");
|
||||||
|
if (flags & 2/*GL_CONTEXT_FLAG_DEBUG_BIT*/)
|
||||||
|
printf(" debug");
|
||||||
|
if (flags & GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB)
|
||||||
|
printf(" robustness");
|
||||||
|
if (flags & 8/*GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR*/)
|
||||||
|
printf(" no-error");
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
printf("%s context flags parsed by GLFW:", get_api_name(client));
|
||||||
|
|
||||||
|
if (glfwGetWindowAttrib(window, GLFW_OPENGL_FORWARD_COMPAT))
|
||||||
|
printf(" forward-compatible");
|
||||||
|
if (glfwGetWindowAttrib(window, GLFW_CONTEXT_DEBUG))
|
||||||
|
printf(" debug");
|
||||||
|
if (glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS) == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||||
|
printf(" robustness");
|
||||||
|
if (glfwGetWindowAttrib(window, GLFW_CONTEXT_NO_ERROR))
|
||||||
|
printf(" no-error");
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (major >= 4 || (major == 3 && minor >= 2))
|
||||||
|
{
|
||||||
|
GLint mask;
|
||||||
|
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
|
||||||
|
|
||||||
|
printf("%s profile mask (0x%08x): %s\n",
|
||||||
|
get_api_name(client),
|
||||||
|
mask,
|
||||||
|
get_profile_name_gl(mask));
|
||||||
|
|
||||||
|
printf("%s profile mask parsed by GLFW: %s\n",
|
||||||
|
get_api_name(client),
|
||||||
|
get_profile_name_glfw(profile));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GLAD_GL_ARB_robustness)
|
||||||
|
{
|
||||||
|
const int robustness = glfwGetWindowAttrib(window, GLFW_CONTEXT_ROBUSTNESS);
|
||||||
|
GLint strategy;
|
||||||
|
glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy);
|
||||||
|
|
||||||
|
printf("%s robustness strategy (0x%08x): %s\n",
|
||||||
|
get_api_name(client),
|
||||||
|
strategy,
|
||||||
|
get_strategy_name_gl(strategy));
|
||||||
|
|
||||||
|
printf("%s robustness strategy parsed by GLFW: %s\n",
|
||||||
|
get_api_name(client),
|
||||||
|
get_strategy_name_glfw(robustness));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s context renderer string: \"%s\"\n",
|
||||||
|
get_api_name(client),
|
||||||
|
glGetString(GL_RENDERER));
|
||||||
|
printf("%s context vendor string: \"%s\"\n",
|
||||||
|
get_api_name(client),
|
||||||
|
glGetString(GL_VENDOR));
|
||||||
|
|
||||||
|
if (major >= 2)
|
||||||
|
{
|
||||||
|
printf("%s context shading language version: \"%s\"\n",
|
||||||
|
get_api_name(client),
|
||||||
|
glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s framebuffer:\n", get_api_name(client));
|
||||||
|
|
||||||
|
GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits;
|
||||||
|
|
||||||
|
if (client == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE)
|
||||||
|
{
|
||||||
|
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
||||||
|
GL_BACK_LEFT,
|
||||||
|
GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,
|
||||||
|
&redbits);
|
||||||
|
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
||||||
|
GL_BACK_LEFT,
|
||||||
|
GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
|
||||||
|
&greenbits);
|
||||||
|
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
||||||
|
GL_BACK_LEFT,
|
||||||
|
GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE,
|
||||||
|
&bluebits);
|
||||||
|
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
||||||
|
GL_BACK_LEFT,
|
||||||
|
GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
|
||||||
|
&alphabits);
|
||||||
|
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
||||||
|
GL_DEPTH,
|
||||||
|
GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE,
|
||||||
|
&depthbits);
|
||||||
|
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
||||||
|
GL_STENCIL,
|
||||||
|
GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
|
||||||
|
&stencilbits);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glGetIntegerv(GL_RED_BITS, &redbits);
|
||||||
|
glGetIntegerv(GL_GREEN_BITS, &greenbits);
|
||||||
|
glGetIntegerv(GL_BLUE_BITS, &bluebits);
|
||||||
|
glGetIntegerv(GL_ALPHA_BITS, &alphabits);
|
||||||
|
glGetIntegerv(GL_DEPTH_BITS, &depthbits);
|
||||||
|
glGetIntegerv(GL_STENCIL_BITS, &stencilbits);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" red: %u green: %u blue: %u alpha: %u depth: %u stencil: %u\n",
|
||||||
|
redbits, greenbits, bluebits, alphabits, depthbits, stencilbits);
|
||||||
|
|
||||||
|
if (client == GLFW_OPENGL_ES_API ||
|
||||||
|
GLAD_GL_ARB_multisample ||
|
||||||
|
major > 1 || minor >= 3)
|
||||||
|
{
|
||||||
|
GLint samples, samplebuffers;
|
||||||
|
glGetIntegerv(GL_SAMPLES, &samples);
|
||||||
|
glGetIntegerv(GL_SAMPLE_BUFFERS, &samplebuffers);
|
||||||
|
|
||||||
|
printf(" samples: %u sample buffers: %u\n", samples, samplebuffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client == GLFW_OPENGL_API && profile != GLFW_OPENGL_CORE_PROFILE)
|
||||||
|
{
|
||||||
|
GLint accumredbits, accumgreenbits, accumbluebits, accumalphabits;
|
||||||
|
GLint auxbuffers;
|
||||||
|
|
||||||
|
glGetIntegerv(GL_ACCUM_RED_BITS, &accumredbits);
|
||||||
|
glGetIntegerv(GL_ACCUM_GREEN_BITS, &accumgreenbits);
|
||||||
|
glGetIntegerv(GL_ACCUM_BLUE_BITS, &accumbluebits);
|
||||||
|
glGetIntegerv(GL_ACCUM_ALPHA_BITS, &accumalphabits);
|
||||||
|
glGetIntegerv(GL_AUX_BUFFERS, &auxbuffers);
|
||||||
|
|
||||||
|
printf(" accum red: %u accum green: %u accum blue: %u accum alpha: %u aux buffers: %u\n",
|
||||||
|
accumredbits, accumgreenbits, accumbluebits, accumalphabits, auxbuffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list_extensions)
|
||||||
|
list_context_extensions(client, major, minor);
|
||||||
|
|
||||||
|
glfwDestroyWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%s framebuffer:\n", get_api_name(client));
|
|
||||||
|
|
||||||
GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits;
|
|
||||||
|
|
||||||
if (client == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE)
|
|
||||||
{
|
|
||||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
|
||||||
GL_BACK_LEFT,
|
|
||||||
GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,
|
|
||||||
&redbits);
|
|
||||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
|
||||||
GL_BACK_LEFT,
|
|
||||||
GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
|
|
||||||
&greenbits);
|
|
||||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
|
||||||
GL_BACK_LEFT,
|
|
||||||
GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE,
|
|
||||||
&bluebits);
|
|
||||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
|
||||||
GL_BACK_LEFT,
|
|
||||||
GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
|
|
||||||
&alphabits);
|
|
||||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
|
||||||
GL_DEPTH,
|
|
||||||
GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE,
|
|
||||||
&depthbits);
|
|
||||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
|
||||||
GL_STENCIL,
|
|
||||||
GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
|
|
||||||
&stencilbits);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glGetIntegerv(GL_RED_BITS, &redbits);
|
|
||||||
glGetIntegerv(GL_GREEN_BITS, &greenbits);
|
|
||||||
glGetIntegerv(GL_BLUE_BITS, &bluebits);
|
|
||||||
glGetIntegerv(GL_ALPHA_BITS, &alphabits);
|
|
||||||
glGetIntegerv(GL_DEPTH_BITS, &depthbits);
|
|
||||||
glGetIntegerv(GL_STENCIL_BITS, &stencilbits);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(" red: %u green: %u blue: %u alpha: %u depth: %u stencil: %u\n",
|
|
||||||
redbits, greenbits, bluebits, alphabits, depthbits, stencilbits);
|
|
||||||
|
|
||||||
if (client == GLFW_OPENGL_ES_API ||
|
|
||||||
GLAD_GL_ARB_multisample ||
|
|
||||||
major > 1 || minor >= 3)
|
|
||||||
{
|
|
||||||
GLint samples, samplebuffers;
|
|
||||||
glGetIntegerv(GL_SAMPLES, &samples);
|
|
||||||
glGetIntegerv(GL_SAMPLE_BUFFERS, &samplebuffers);
|
|
||||||
|
|
||||||
printf(" samples: %u sample buffers: %u\n", samples, samplebuffers);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client == GLFW_OPENGL_API && profile != GLFW_OPENGL_CORE_PROFILE)
|
|
||||||
{
|
|
||||||
GLint accumredbits, accumgreenbits, accumbluebits, accumalphabits;
|
|
||||||
GLint auxbuffers;
|
|
||||||
|
|
||||||
glGetIntegerv(GL_ACCUM_RED_BITS, &accumredbits);
|
|
||||||
glGetIntegerv(GL_ACCUM_GREEN_BITS, &accumgreenbits);
|
|
||||||
glGetIntegerv(GL_ACCUM_BLUE_BITS, &accumbluebits);
|
|
||||||
glGetIntegerv(GL_ACCUM_ALPHA_BITS, &accumalphabits);
|
|
||||||
glGetIntegerv(GL_AUX_BUFFERS, &auxbuffers);
|
|
||||||
|
|
||||||
printf(" accum red: %u accum green: %u accum blue: %u accum alpha: %u aux buffers: %u\n",
|
|
||||||
accumredbits, accumgreenbits, accumbluebits, accumalphabits, auxbuffers);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list_extensions)
|
|
||||||
list_context_extensions(client, major, minor);
|
|
||||||
|
|
||||||
glfwDestroyWindow(window);
|
|
||||||
|
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
|
|
||||||
window = glfwCreateWindow(200, 200, "Version", NULL, NULL);
|
window = glfwCreateWindow(200, 200, "Version", NULL, NULL);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user