mirror of
https://github.com/glfw/glfw.git
synced 2025-04-20 23:52:51 +00:00
Merge branch 'glfw:master' into master
This commit is contained in:
commit
b062262fcc
@ -266,6 +266,7 @@ information on what to include when reporting a bug.
|
|||||||
undefined behavior (#1986)
|
undefined behavior (#1986)
|
||||||
- [X11] Bugfix: Dynamic loading on OpenBSD failed due to soname differences
|
- [X11] Bugfix: Dynamic loading on OpenBSD failed due to soname differences
|
||||||
- [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] Removed support for `wl_shell` (#1443)
|
- [Wayland] Removed support for `wl_shell` (#1443)
|
||||||
- [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432)
|
- [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432)
|
||||||
- [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled
|
- [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled
|
||||||
@ -283,6 +284,11 @@ information on what to include when reporting a bug.
|
|||||||
- [Wayland] Bugfix: Activating a window would emit two input focus events
|
- [Wayland] Bugfix: Activating a window would emit two input focus events
|
||||||
- [Wayland] Bugfix: Disable key repeat mechanism when window loses input focus
|
- [Wayland] Bugfix: Disable key repeat mechanism when window loses input focus
|
||||||
- [Wayland] Bugfix: Window hiding and showing did not work (#1492,#1731)
|
- [Wayland] Bugfix: Window hiding and showing did not work (#1492,#1731)
|
||||||
|
- [Wayland] Bugfix: A key being repeated was not released when window lost focus
|
||||||
|
- [Wayland] Bugfix: Showing a hidden window did not emit a window refresh event
|
||||||
|
- [Wayland] Bugfix: Full screen window creation did not ignore `GLFW_VISIBLE`
|
||||||
|
- [Wayland] Bugfix: Some keys were reported as wrong key or `GLFW_KEY_UNKNOWN`
|
||||||
|
- [Wayland] Bugfix: Text input did not repeat along with key repeat
|
||||||
- [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
|
||||||
- [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072)
|
- [WGL] Disabled the DWM swap interval hack for Windows 8 and later (#1072)
|
||||||
|
@ -104,9 +104,8 @@ integration by libwayland-egl, and keyboard handling by
|
|||||||
from wayland-protocols to provide additional features if the compositor
|
from wayland-protocols to provide additional features if the compositor
|
||||||
supports them.
|
supports them.
|
||||||
|
|
||||||
GLFW uses xkbcommon 0.5.0 to provide compose key support. When it has been
|
GLFW uses xkbcommon 0.5.0 to provide key and text input support. Earlier
|
||||||
built against an older xkbcommon, the compose key will be disabled even if it
|
versions are not supported.
|
||||||
has been configured in the compositor.
|
|
||||||
|
|
||||||
GLFW uses the [xdg-shell
|
GLFW uses the [xdg-shell
|
||||||
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/xdg-shell/xdg-shell.xml)
|
protocol](https://cgit.freedesktop.org/wayland/wayland-protocols/tree/stable/xdg-shell/xdg-shell.xml)
|
||||||
|
@ -3764,6 +3764,11 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
|
|||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||||
* GLFW_PLATFORM_ERROR.
|
* GLFW_PLATFORM_ERROR.
|
||||||
*
|
*
|
||||||
|
* @remark @wayland Because Wayland wants every frame of the desktop to be
|
||||||
|
* complete, this function does not immediately make the window visible.
|
||||||
|
* Instead it will become visible the next time the window framebuffer is
|
||||||
|
* updated after this call.
|
||||||
|
*
|
||||||
* @thread_safety This function must only be called from the main thread.
|
* @thread_safety This function must only be called from the main thread.
|
||||||
*
|
*
|
||||||
* @sa @ref window_hide
|
* @sa @ref window_hide
|
||||||
@ -6189,9 +6194,6 @@ GLFWAPI int glfwVulkanSupported(void);
|
|||||||
* returned array, as it is an error to specify an extension more than once in
|
* returned array, as it is an error to specify an extension more than once in
|
||||||
* the `VkInstanceCreateInfo` struct.
|
* the `VkInstanceCreateInfo` struct.
|
||||||
*
|
*
|
||||||
* @remark @macos GLFW currently supports both the `VK_MVK_macos_surface` and
|
|
||||||
* the newer `VK_EXT_metal_surface` extensions.
|
|
||||||
*
|
|
||||||
* @pointer_lifetime The returned array is allocated and freed by GLFW. You
|
* @pointer_lifetime The returned array is allocated and freed by GLFW. You
|
||||||
* should not free it yourself. It is guaranteed to be valid only until the
|
* should not free it yourself. It is guaranteed to be valid only until the
|
||||||
* library is terminated.
|
* library is terminated.
|
||||||
@ -6330,17 +6332,20 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhys
|
|||||||
* @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should
|
* @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should
|
||||||
* eliminate almost all occurrences of these errors.
|
* eliminate almost all occurrences of these errors.
|
||||||
*
|
*
|
||||||
* @remark @macos This function currently only supports the
|
* @remark @macos GLFW prefers the `VK_EXT_metal_surface` extension, with the
|
||||||
* `VK_MVK_macos_surface` extension from MoltenVK.
|
* `VK_MVK_macos_surface` extension as a fallback. The name of the selected
|
||||||
|
* extension, if any, is included in the array returned by @ref
|
||||||
|
* glfwGetRequiredInstanceExtensions.
|
||||||
*
|
*
|
||||||
* @remark @macos This function creates and sets a `CAMetalLayer` instance for
|
* @remark @macos This function creates and sets a `CAMetalLayer` instance for
|
||||||
* the window content view, which is required for MoltenVK to function.
|
* the window content view, which is required for MoltenVK to function.
|
||||||
*
|
*
|
||||||
* @remark @x11 GLFW by default attempts to use the `VK_KHR_xcb_surface`
|
* @remark @x11 By default GLFW prefers the `VK_KHR_xcb_surface` extension,
|
||||||
* extension, if available. You can make it prefer the `VK_KHR_xlib_surface`
|
* with the `VK_KHR_xlib_surface` extension as a fallback. You can make
|
||||||
* extension by setting the
|
* `VK_KHR_xlib_surface` the preferred extension by setting the
|
||||||
* [GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init
|
* [GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init
|
||||||
* hint.
|
* hint. The name of the selected extension, if any, is included in the array
|
||||||
|
* returned by @ref glfwGetRequiredInstanceExtensions.
|
||||||
*
|
*
|
||||||
* @thread_safety This function may be called from any thread. For
|
* @thread_safety This function may be called from any thread. For
|
||||||
* synchronization details of Vulkan objects, see the Vulkan specification.
|
* synchronization details of Vulkan objects, see the Vulkan specification.
|
||||||
|
@ -65,10 +65,6 @@ endif()
|
|||||||
if (GLFW_BUILD_WAYLAND)
|
if (GLFW_BUILD_WAYLAND)
|
||||||
include(CheckIncludeFiles)
|
include(CheckIncludeFiles)
|
||||||
include(CheckFunctionExists)
|
include(CheckFunctionExists)
|
||||||
check_include_files(xkbcommon/xkbcommon-compose.h HAVE_XKBCOMMON_COMPOSE_H)
|
|
||||||
if (HAVE_XKBCOMMON_COMPOSE_H)
|
|
||||||
target_compile_definitions(glfw PRIVATE HAVE_XKBCOMMON_COMPOSE_H)
|
|
||||||
endif()
|
|
||||||
check_function_exists(memfd_create HAVE_MEMFD_CREATE)
|
check_function_exists(memfd_create HAVE_MEMFD_CREATE)
|
||||||
if (HAVE_MEMFD_CREATE)
|
if (HAVE_MEMFD_CREATE)
|
||||||
target_compile_definitions(glfw PRIVATE HAVE_MEMFD_CREATE)
|
target_compile_definitions(glfw PRIVATE HAVE_MEMFD_CREATE)
|
||||||
@ -173,7 +169,7 @@ if (GLFW_BUILD_WAYLAND)
|
|||||||
wayland-client>=0.2.7
|
wayland-client>=0.2.7
|
||||||
wayland-cursor>=0.2.7
|
wayland-cursor>=0.2.7
|
||||||
wayland-egl>=0.2.7
|
wayland-egl>=0.2.7
|
||||||
xkbcommon)
|
xkbcommon>=0.5.0)
|
||||||
|
|
||||||
target_include_directories(glfw PRIVATE ${Wayland_INCLUDE_DIRS})
|
target_include_directories(glfw PRIVATE ${Wayland_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
31
src/init.c
31
src/init.c
@ -140,6 +140,37 @@ static void terminate(void)
|
|||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Encode a Unicode code point to a UTF-8 stream
|
||||||
|
// Based on cutef8 by Jeff Bezanson (Public Domain)
|
||||||
|
//
|
||||||
|
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint)
|
||||||
|
{
|
||||||
|
size_t count = 0;
|
||||||
|
|
||||||
|
if (codepoint < 0x80)
|
||||||
|
s[count++] = (char) codepoint;
|
||||||
|
else if (codepoint < 0x800)
|
||||||
|
{
|
||||||
|
s[count++] = (codepoint >> 6) | 0xc0;
|
||||||
|
s[count++] = (codepoint & 0x3f) | 0x80;
|
||||||
|
}
|
||||||
|
else if (codepoint < 0x10000)
|
||||||
|
{
|
||||||
|
s[count++] = (codepoint >> 12) | 0xe0;
|
||||||
|
s[count++] = ((codepoint >> 6) & 0x3f) | 0x80;
|
||||||
|
s[count++] = (codepoint & 0x3f) | 0x80;
|
||||||
|
}
|
||||||
|
else if (codepoint < 0x110000)
|
||||||
|
{
|
||||||
|
s[count++] = (codepoint >> 18) | 0xf0;
|
||||||
|
s[count++] = ((codepoint >> 12) & 0x3f) | 0x80;
|
||||||
|
s[count++] = ((codepoint >> 6) & 0x3f) | 0x80;
|
||||||
|
s[count++] = (codepoint & 0x3f) | 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
char* _glfw_strdup(const char* source)
|
char* _glfw_strdup(const char* source)
|
||||||
{
|
{
|
||||||
const size_t length = strlen(source);
|
const size_t length = strlen(source);
|
||||||
|
@ -302,7 +302,7 @@ void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int m
|
|||||||
// Notifies shared code of a Unicode codepoint input event
|
// Notifies shared code of a Unicode codepoint input event
|
||||||
// The 'plain' parameter determines whether to emit a regular character event
|
// The 'plain' parameter determines whether to emit a regular character event
|
||||||
//
|
//
|
||||||
void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWbool plain)
|
void _glfwInputChar(_GLFWwindow* window, uint32_t codepoint, int mods, GLFWbool plain)
|
||||||
{
|
{
|
||||||
if (codepoint < 32 || (codepoint > 126 && codepoint < 160))
|
if (codepoint < 32 || (codepoint > 126 && codepoint < 160))
|
||||||
return;
|
return;
|
||||||
|
@ -919,7 +919,7 @@ void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor);
|
|||||||
void _glfwInputKey(_GLFWwindow* window,
|
void _glfwInputKey(_GLFWwindow* window,
|
||||||
int key, int scancode, int action, int mods);
|
int key, int scancode, int action, int mods);
|
||||||
void _glfwInputChar(_GLFWwindow* window,
|
void _glfwInputChar(_GLFWwindow* window,
|
||||||
unsigned int codepoint, int mods, GLFWbool plain);
|
uint32_t codepoint, int mods, GLFWbool plain);
|
||||||
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset);
|
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset);
|
||||||
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
|
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
|
||||||
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
||||||
@ -995,6 +995,8 @@ GLFWbool _glfwInitVulkan(int mode);
|
|||||||
void _glfwTerminateVulkan(void);
|
void _glfwTerminateVulkan(void);
|
||||||
const char* _glfwGetVulkanResultString(VkResult result);
|
const char* _glfwGetVulkanResultString(VkResult result);
|
||||||
|
|
||||||
|
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint);
|
||||||
|
|
||||||
char* _glfw_strdup(const char* source);
|
char* _glfw_strdup(const char* source);
|
||||||
float _glfw_fminf(float a, float b);
|
float _glfw_fminf(float a, float b);
|
||||||
float _glfw_fmaxf(float a, float b);
|
float _glfw_fmaxf(float a, float b);
|
||||||
|
@ -649,7 +649,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
window->win32.highSurrogate = (WCHAR) wParam;
|
window->win32.highSurrogate = (WCHAR) wParam;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int codepoint = 0;
|
uint32_t codepoint = 0;
|
||||||
|
|
||||||
if (wParam >= 0xdc00 && wParam <= 0xdfff)
|
if (wParam >= 0xdc00 && wParam <= 0xdfff)
|
||||||
{
|
{
|
||||||
@ -683,7 +683,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GLFW_TRUE);
|
_glfwInputChar(window, (uint32_t) wParam, getKeyMods(), GLFW_TRUE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
127
src/wl_init.c
127
src/wl_init.c
@ -207,12 +207,12 @@ static void pointerHandleMotion(void* data,
|
|||||||
return;
|
return;
|
||||||
x = wl_fixed_to_double(sx);
|
x = wl_fixed_to_double(sx);
|
||||||
y = wl_fixed_to_double(sy);
|
y = wl_fixed_to_double(sy);
|
||||||
|
window->wl.cursorPosX = x;
|
||||||
|
window->wl.cursorPosY = y;
|
||||||
|
|
||||||
switch (window->wl.decorations.focus)
|
switch (window->wl.decorations.focus)
|
||||||
{
|
{
|
||||||
case mainWindow:
|
case mainWindow:
|
||||||
window->wl.cursorPosX = x;
|
|
||||||
window->wl.cursorPosY = y;
|
|
||||||
_glfwInputCursorPos(window, x, y);
|
_glfwInputCursorPos(window, x, y);
|
||||||
_glfw.wl.cursorPreviousName = NULL;
|
_glfw.wl.cursorPreviousName = NULL;
|
||||||
return;
|
return;
|
||||||
@ -272,9 +272,7 @@ static void pointerHandleButton(void* data,
|
|||||||
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
||||||
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 leftDecoration:
|
||||||
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
||||||
@ -303,6 +301,7 @@ static void pointerHandleButton(void* data,
|
|||||||
{
|
{
|
||||||
xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat,
|
xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat,
|
||||||
serial, edges);
|
serial, edges);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (button == BTN_RIGHT)
|
else if (button == BTN_RIGHT)
|
||||||
@ -378,11 +377,8 @@ static void keyboardHandleKeymap(void* data,
|
|||||||
{
|
{
|
||||||
struct xkb_keymap* keymap;
|
struct xkb_keymap* keymap;
|
||||||
struct xkb_state* state;
|
struct xkb_state* state;
|
||||||
|
|
||||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
|
||||||
struct xkb_compose_table* composeTable;
|
struct xkb_compose_table* composeTable;
|
||||||
struct xkb_compose_state* composeState;
|
struct xkb_compose_state* composeState;
|
||||||
#endif
|
|
||||||
|
|
||||||
char* mapStr;
|
char* mapStr;
|
||||||
const char* locale;
|
const char* locale;
|
||||||
@ -431,7 +427,6 @@ static void keyboardHandleKeymap(void* data,
|
|||||||
if (!locale)
|
if (!locale)
|
||||||
locale = "C";
|
locale = "C";
|
||||||
|
|
||||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
|
||||||
composeTable =
|
composeTable =
|
||||||
xkb_compose_table_new_from_locale(_glfw.wl.xkb.context, locale,
|
xkb_compose_table_new_from_locale(_glfw.wl.xkb.context, locale,
|
||||||
XKB_COMPOSE_COMPILE_NO_FLAGS);
|
XKB_COMPOSE_COMPILE_NO_FLAGS);
|
||||||
@ -451,7 +446,6 @@ static void keyboardHandleKeymap(void* data,
|
|||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Wayland: Failed to create XKB compose table");
|
"Wayland: Failed to create XKB compose table");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
xkb_keymap_unref(_glfw.wl.xkb.keymap);
|
xkb_keymap_unref(_glfw.wl.xkb.keymap);
|
||||||
xkb_state_unref(_glfw.wl.xkb.state);
|
xkb_state_unref(_glfw.wl.xkb.state);
|
||||||
@ -505,23 +499,22 @@ static void keyboardHandleLeave(void* data,
|
|||||||
if (!window)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
struct itimerspec timer = {};
|
||||||
|
timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL);
|
||||||
|
|
||||||
_glfw.wl.serial = serial;
|
_glfw.wl.serial = serial;
|
||||||
_glfw.wl.keyboardFocus = NULL;
|
_glfw.wl.keyboardFocus = NULL;
|
||||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||||
|
|
||||||
struct itimerspec timer = {};
|
|
||||||
timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int toGLFWKeyCode(uint32_t key)
|
static int translateKey(uint32_t scancode)
|
||||||
{
|
{
|
||||||
if (key < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0]))
|
if (scancode < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0]))
|
||||||
return _glfw.wl.keycodes[key];
|
return _glfw.wl.keycodes[scancode];
|
||||||
|
|
||||||
return GLFW_KEY_UNKNOWN;
|
return GLFW_KEY_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
|
||||||
static xkb_keysym_t composeSymbol(xkb_keysym_t sym)
|
static xkb_keysym_t composeSymbol(xkb_keysym_t sym)
|
||||||
{
|
{
|
||||||
if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState)
|
if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState)
|
||||||
@ -541,77 +534,65 @@ static xkb_keysym_t composeSymbol(xkb_keysym_t sym)
|
|||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static GLFWbool inputChar(_GLFWwindow* window, uint32_t key)
|
GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode)
|
||||||
{
|
{
|
||||||
uint32_t code, numSyms;
|
const xkb_keysym_t* keysyms;
|
||||||
long cp;
|
const xkb_keycode_t keycode = scancode + 8;
|
||||||
const xkb_keysym_t *syms;
|
|
||||||
xkb_keysym_t sym;
|
|
||||||
|
|
||||||
code = key + 8;
|
if (xkb_state_key_get_syms(_glfw.wl.xkb.state, keycode, &keysyms) == 1)
|
||||||
numSyms = xkb_state_key_get_syms(_glfw.wl.xkb.state, code, &syms);
|
|
||||||
|
|
||||||
if (numSyms == 1)
|
|
||||||
{
|
{
|
||||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
const xkb_keysym_t keysym = composeSymbol(keysyms[0]);
|
||||||
sym = composeSymbol(syms[0]);
|
const uint32_t codepoint = _glfwKeySym2Unicode(keysym);
|
||||||
#else
|
if (codepoint != GLFW_INVALID_CODEPOINT)
|
||||||
sym = syms[0];
|
|
||||||
#endif
|
|
||||||
cp = _glfwKeySym2Unicode(sym);
|
|
||||||
if (cp != -1)
|
|
||||||
{
|
{
|
||||||
const int mods = _glfw.wl.xkb.modifiers;
|
const int mods = _glfw.wl.xkb.modifiers;
|
||||||
const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
|
const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
|
||||||
_glfwInputChar(window, cp, mods, plain);
|
_glfwInputChar(window, codepoint, mods, plain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, code);
|
return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, keycode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keyboardHandleKey(void* data,
|
static void keyboardHandleKey(void* data,
|
||||||
struct wl_keyboard* keyboard,
|
struct wl_keyboard* keyboard,
|
||||||
uint32_t serial,
|
uint32_t serial,
|
||||||
uint32_t time,
|
uint32_t time,
|
||||||
uint32_t key,
|
uint32_t scancode,
|
||||||
uint32_t state)
|
uint32_t state)
|
||||||
{
|
{
|
||||||
int keyCode;
|
|
||||||
int action;
|
|
||||||
_GLFWwindow* window = _glfw.wl.keyboardFocus;
|
_GLFWwindow* window = _glfw.wl.keyboardFocus;
|
||||||
GLFWbool shouldRepeat;
|
|
||||||
struct itimerspec timer = {};
|
|
||||||
|
|
||||||
if (!window)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
keyCode = toGLFWKeyCode(key);
|
const int key = translateKey(scancode);
|
||||||
action = state == WL_KEYBOARD_KEY_STATE_PRESSED
|
const int action =
|
||||||
? GLFW_PRESS : GLFW_RELEASE;
|
state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE;
|
||||||
|
|
||||||
_glfw.wl.serial = serial;
|
_glfw.wl.serial = serial;
|
||||||
_glfwInputKey(window, keyCode, key, action,
|
_glfwInputKey(window, key, scancode, action, _glfw.wl.xkb.modifiers);
|
||||||
_glfw.wl.xkb.modifiers);
|
|
||||||
|
struct itimerspec timer = {};
|
||||||
|
|
||||||
if (action == GLFW_PRESS)
|
if (action == GLFW_PRESS)
|
||||||
{
|
{
|
||||||
shouldRepeat = inputChar(window, key);
|
const GLFWbool shouldRepeat = _glfwInputTextWayland(window, scancode);
|
||||||
|
|
||||||
if (shouldRepeat && _glfw.wl.keyboardRepeatRate > 0)
|
if (shouldRepeat && _glfw.wl.keyboardRepeatRate > 0)
|
||||||
{
|
{
|
||||||
_glfw.wl.keyboardLastKey = keyCode;
|
_glfw.wl.keyboardLastKey = key;
|
||||||
_glfw.wl.keyboardLastScancode = key;
|
_glfw.wl.keyboardLastScancode = scancode;
|
||||||
if (_glfw.wl.keyboardRepeatRate > 1)
|
if (_glfw.wl.keyboardRepeatRate > 1)
|
||||||
timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyboardRepeatRate;
|
timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyboardRepeatRate;
|
||||||
else
|
else
|
||||||
timer.it_interval.tv_sec = 1;
|
timer.it_interval.tv_sec = 1;
|
||||||
|
|
||||||
timer.it_value.tv_sec = _glfw.wl.keyboardRepeatDelay / 1000;
|
timer.it_value.tv_sec = _glfw.wl.keyboardRepeatDelay / 1000;
|
||||||
timer.it_value.tv_nsec = (_glfw.wl.keyboardRepeatDelay % 1000) * 1000000;
|
timer.it_value.tv_nsec = (_glfw.wl.keyboardRepeatDelay % 1000) * 1000000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL);
|
timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -623,9 +604,6 @@ static void keyboardHandleModifiers(void* data,
|
|||||||
uint32_t modsLocked,
|
uint32_t modsLocked,
|
||||||
uint32_t group)
|
uint32_t group)
|
||||||
{
|
{
|
||||||
xkb_mod_mask_t mask;
|
|
||||||
unsigned int modifiers = 0;
|
|
||||||
|
|
||||||
_glfw.wl.serial = serial;
|
_glfw.wl.serial = serial;
|
||||||
|
|
||||||
if (!_glfw.wl.xkb.keymap)
|
if (!_glfw.wl.xkb.keymap)
|
||||||
@ -639,24 +617,29 @@ static void keyboardHandleModifiers(void* data,
|
|||||||
0,
|
0,
|
||||||
group);
|
group);
|
||||||
|
|
||||||
mask = xkb_state_serialize_mods(_glfw.wl.xkb.state,
|
const xkb_mod_mask_t mask =
|
||||||
XKB_STATE_MODS_DEPRESSED |
|
xkb_state_serialize_mods(_glfw.wl.xkb.state,
|
||||||
XKB_STATE_LAYOUT_DEPRESSED |
|
XKB_STATE_MODS_DEPRESSED |
|
||||||
XKB_STATE_MODS_LATCHED |
|
XKB_STATE_LAYOUT_DEPRESSED |
|
||||||
XKB_STATE_LAYOUT_LATCHED);
|
XKB_STATE_MODS_LATCHED |
|
||||||
|
XKB_STATE_LAYOUT_LATCHED);
|
||||||
|
|
||||||
|
unsigned int mods = 0;
|
||||||
|
|
||||||
if (mask & _glfw.wl.xkb.controlMask)
|
if (mask & _glfw.wl.xkb.controlMask)
|
||||||
modifiers |= GLFW_MOD_CONTROL;
|
mods |= GLFW_MOD_CONTROL;
|
||||||
if (mask & _glfw.wl.xkb.altMask)
|
if (mask & _glfw.wl.xkb.altMask)
|
||||||
modifiers |= GLFW_MOD_ALT;
|
mods |= GLFW_MOD_ALT;
|
||||||
if (mask & _glfw.wl.xkb.shiftMask)
|
if (mask & _glfw.wl.xkb.shiftMask)
|
||||||
modifiers |= GLFW_MOD_SHIFT;
|
mods |= GLFW_MOD_SHIFT;
|
||||||
if (mask & _glfw.wl.xkb.superMask)
|
if (mask & _glfw.wl.xkb.superMask)
|
||||||
modifiers |= GLFW_MOD_SUPER;
|
mods |= GLFW_MOD_SUPER;
|
||||||
if (mask & _glfw.wl.xkb.capsLockMask)
|
if (mask & _glfw.wl.xkb.capsLockMask)
|
||||||
modifiers |= GLFW_MOD_CAPS_LOCK;
|
mods |= GLFW_MOD_CAPS_LOCK;
|
||||||
if (mask & _glfw.wl.xkb.numLockMask)
|
if (mask & _glfw.wl.xkb.numLockMask)
|
||||||
modifiers |= GLFW_MOD_NUM_LOCK;
|
mods |= GLFW_MOD_NUM_LOCK;
|
||||||
_glfw.wl.xkb.modifiers = modifiers;
|
|
||||||
|
_glfw.wl.xkb.modifiers = mods;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION
|
#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION
|
||||||
@ -973,7 +956,7 @@ static void createKeyTables(void)
|
|||||||
_glfw.wl.keycodes[KEY_RIGHTALT] = GLFW_KEY_RIGHT_ALT;
|
_glfw.wl.keycodes[KEY_RIGHTALT] = GLFW_KEY_RIGHT_ALT;
|
||||||
_glfw.wl.keycodes[KEY_LEFTMETA] = GLFW_KEY_LEFT_SUPER;
|
_glfw.wl.keycodes[KEY_LEFTMETA] = GLFW_KEY_LEFT_SUPER;
|
||||||
_glfw.wl.keycodes[KEY_RIGHTMETA] = GLFW_KEY_RIGHT_SUPER;
|
_glfw.wl.keycodes[KEY_RIGHTMETA] = GLFW_KEY_RIGHT_SUPER;
|
||||||
_glfw.wl.keycodes[KEY_MENU] = GLFW_KEY_MENU;
|
_glfw.wl.keycodes[KEY_COMPOSE] = GLFW_KEY_MENU;
|
||||||
_glfw.wl.keycodes[KEY_NUMLOCK] = GLFW_KEY_NUM_LOCK;
|
_glfw.wl.keycodes[KEY_NUMLOCK] = GLFW_KEY_NUM_LOCK;
|
||||||
_glfw.wl.keycodes[KEY_CAPSLOCK] = GLFW_KEY_CAPS_LOCK;
|
_glfw.wl.keycodes[KEY_CAPSLOCK] = GLFW_KEY_CAPS_LOCK;
|
||||||
_glfw.wl.keycodes[KEY_PRINT] = GLFW_KEY_PRINT_SCREEN;
|
_glfw.wl.keycodes[KEY_PRINT] = GLFW_KEY_PRINT_SCREEN;
|
||||||
@ -1016,7 +999,7 @@ static void createKeyTables(void)
|
|||||||
_glfw.wl.keycodes[KEY_F23] = GLFW_KEY_F23;
|
_glfw.wl.keycodes[KEY_F23] = GLFW_KEY_F23;
|
||||||
_glfw.wl.keycodes[KEY_F24] = GLFW_KEY_F24;
|
_glfw.wl.keycodes[KEY_F24] = GLFW_KEY_F24;
|
||||||
_glfw.wl.keycodes[KEY_KPSLASH] = GLFW_KEY_KP_DIVIDE;
|
_glfw.wl.keycodes[KEY_KPSLASH] = GLFW_KEY_KP_DIVIDE;
|
||||||
_glfw.wl.keycodes[KEY_KPDOT] = GLFW_KEY_KP_MULTIPLY;
|
_glfw.wl.keycodes[KEY_KPASTERISK] = GLFW_KEY_KP_MULTIPLY;
|
||||||
_glfw.wl.keycodes[KEY_KPMINUS] = GLFW_KEY_KP_SUBTRACT;
|
_glfw.wl.keycodes[KEY_KPMINUS] = GLFW_KEY_KP_SUBTRACT;
|
||||||
_glfw.wl.keycodes[KEY_KPPLUS] = GLFW_KEY_KP_ADD;
|
_glfw.wl.keycodes[KEY_KPPLUS] = GLFW_KEY_KP_ADD;
|
||||||
_glfw.wl.keycodes[KEY_KP0] = GLFW_KEY_KP_0;
|
_glfw.wl.keycodes[KEY_KP0] = GLFW_KEY_KP_0;
|
||||||
@ -1029,9 +1012,10 @@ static void createKeyTables(void)
|
|||||||
_glfw.wl.keycodes[KEY_KP7] = GLFW_KEY_KP_7;
|
_glfw.wl.keycodes[KEY_KP7] = GLFW_KEY_KP_7;
|
||||||
_glfw.wl.keycodes[KEY_KP8] = GLFW_KEY_KP_8;
|
_glfw.wl.keycodes[KEY_KP8] = GLFW_KEY_KP_8;
|
||||||
_glfw.wl.keycodes[KEY_KP9] = GLFW_KEY_KP_9;
|
_glfw.wl.keycodes[KEY_KP9] = GLFW_KEY_KP_9;
|
||||||
_glfw.wl.keycodes[KEY_KPCOMMA] = GLFW_KEY_KP_DECIMAL;
|
_glfw.wl.keycodes[KEY_KPDOT] = GLFW_KEY_KP_DECIMAL;
|
||||||
_glfw.wl.keycodes[KEY_KPEQUAL] = GLFW_KEY_KP_EQUAL;
|
_glfw.wl.keycodes[KEY_KPEQUAL] = GLFW_KEY_KP_EQUAL;
|
||||||
_glfw.wl.keycodes[KEY_KPENTER] = GLFW_KEY_KP_ENTER;
|
_glfw.wl.keycodes[KEY_KPENTER] = GLFW_KEY_KP_ENTER;
|
||||||
|
_glfw.wl.keycodes[KEY_102ND] = GLFW_KEY_WORLD_2;
|
||||||
|
|
||||||
for (int scancode = 0; scancode < 256; scancode++)
|
for (int scancode = 0; scancode < 256; scancode++)
|
||||||
{
|
{
|
||||||
@ -1290,6 +1274,8 @@ int _glfwInitWayland(void)
|
|||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_mod_get_index");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_mod_get_index");
|
||||||
_glfw.wl.xkb.keymap_key_repeats = (PFN_xkb_keymap_key_repeats)
|
_glfw.wl.xkb.keymap_key_repeats = (PFN_xkb_keymap_key_repeats)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_key_repeats");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_key_repeats");
|
||||||
|
_glfw.wl.xkb.keymap_key_get_syms_by_level = (PFN_xkb_keymap_key_get_syms_by_level)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_key_get_syms_by_level");
|
||||||
_glfw.wl.xkb.state_new = (PFN_xkb_state_new)
|
_glfw.wl.xkb.state_new = (PFN_xkb_state_new)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_new");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_new");
|
||||||
_glfw.wl.xkb.state_unref = (PFN_xkb_state_unref)
|
_glfw.wl.xkb.state_unref = (PFN_xkb_state_unref)
|
||||||
@ -1300,8 +1286,8 @@ int _glfwInitWayland(void)
|
|||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_update_mask");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_update_mask");
|
||||||
_glfw.wl.xkb.state_serialize_mods = (PFN_xkb_state_serialize_mods)
|
_glfw.wl.xkb.state_serialize_mods = (PFN_xkb_state_serialize_mods)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_serialize_mods");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_serialize_mods");
|
||||||
|
_glfw.wl.xkb.state_key_get_layout = (PFN_xkb_state_key_get_layout)
|
||||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_key_get_layout");
|
||||||
_glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale)
|
_glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_table_new_from_locale");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_table_new_from_locale");
|
||||||
_glfw.wl.xkb.compose_table_unref = (PFN_xkb_compose_table_unref)
|
_glfw.wl.xkb.compose_table_unref = (PFN_xkb_compose_table_unref)
|
||||||
@ -1316,7 +1302,6 @@ int _glfwInitWayland(void)
|
|||||||
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_status");
|
_glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_status");
|
||||||
_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");
|
||||||
#endif
|
|
||||||
|
|
||||||
_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);
|
||||||
@ -1404,10 +1389,8 @@ void _glfwTerminateWayland(void)
|
|||||||
_glfw.wl.egl.handle = NULL;
|
_glfw.wl.egl.handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
|
||||||
if (_glfw.wl.xkb.composeState)
|
if (_glfw.wl.xkb.composeState)
|
||||||
xkb_compose_state_unref(_glfw.wl.xkb.composeState);
|
xkb_compose_state_unref(_glfw.wl.xkb.composeState);
|
||||||
#endif
|
|
||||||
if (_glfw.wl.xkb.keymap)
|
if (_glfw.wl.xkb.keymap)
|
||||||
xkb_keymap_unref(_glfw.wl.xkb.keymap);
|
xkb_keymap_unref(_glfw.wl.xkb.keymap);
|
||||||
if (_glfw.wl.xkb.state)
|
if (_glfw.wl.xkb.state)
|
||||||
|
@ -26,9 +26,7 @@
|
|||||||
|
|
||||||
#include <wayland-client-core.h>
|
#include <wayland-client-core.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
|
||||||
#include <xkbcommon/xkbcommon-compose.h>
|
#include <xkbcommon/xkbcommon-compose.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
|
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
|
||||||
|
|
||||||
@ -163,24 +161,27 @@ typedef struct xkb_keymap* (* PFN_xkb_keymap_new_from_string)(struct xkb_context
|
|||||||
typedef void (* PFN_xkb_keymap_unref)(struct xkb_keymap*);
|
typedef void (* PFN_xkb_keymap_unref)(struct xkb_keymap*);
|
||||||
typedef xkb_mod_index_t (* PFN_xkb_keymap_mod_get_index)(struct xkb_keymap*, const char*);
|
typedef xkb_mod_index_t (* PFN_xkb_keymap_mod_get_index)(struct xkb_keymap*, const char*);
|
||||||
typedef int (* PFN_xkb_keymap_key_repeats)(struct xkb_keymap*, xkb_keycode_t);
|
typedef int (* PFN_xkb_keymap_key_repeats)(struct xkb_keymap*, xkb_keycode_t);
|
||||||
|
typedef int (* PFN_xkb_keymap_key_get_syms_by_level)(struct xkb_keymap*,xkb_keycode_t,xkb_layout_index_t,xkb_level_index_t,const xkb_keysym_t**);
|
||||||
typedef struct xkb_state* (* PFN_xkb_state_new)(struct xkb_keymap*);
|
typedef struct xkb_state* (* PFN_xkb_state_new)(struct xkb_keymap*);
|
||||||
typedef void (* PFN_xkb_state_unref)(struct xkb_state*);
|
typedef void (* PFN_xkb_state_unref)(struct xkb_state*);
|
||||||
typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**);
|
typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**);
|
||||||
typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t);
|
typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t);
|
||||||
typedef xkb_mod_mask_t (* PFN_xkb_state_serialize_mods)(struct xkb_state*, enum xkb_state_component);
|
typedef xkb_mod_mask_t (* PFN_xkb_state_serialize_mods)(struct xkb_state*, enum xkb_state_component);
|
||||||
|
typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xkb_keycode_t);
|
||||||
#define xkb_context_new _glfw.wl.xkb.context_new
|
#define xkb_context_new _glfw.wl.xkb.context_new
|
||||||
#define xkb_context_unref _glfw.wl.xkb.context_unref
|
#define xkb_context_unref _glfw.wl.xkb.context_unref
|
||||||
#define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string
|
#define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string
|
||||||
#define xkb_keymap_unref _glfw.wl.xkb.keymap_unref
|
#define xkb_keymap_unref _glfw.wl.xkb.keymap_unref
|
||||||
#define xkb_keymap_mod_get_index _glfw.wl.xkb.keymap_mod_get_index
|
#define xkb_keymap_mod_get_index _glfw.wl.xkb.keymap_mod_get_index
|
||||||
#define xkb_keymap_key_repeats _glfw.wl.xkb.keymap_key_repeats
|
#define xkb_keymap_key_repeats _glfw.wl.xkb.keymap_key_repeats
|
||||||
|
#define xkb_keymap_key_get_syms_by_level _glfw.wl.xkb.keymap_key_get_syms_by_level
|
||||||
#define xkb_state_new _glfw.wl.xkb.state_new
|
#define xkb_state_new _glfw.wl.xkb.state_new
|
||||||
#define xkb_state_unref _glfw.wl.xkb.state_unref
|
#define xkb_state_unref _glfw.wl.xkb.state_unref
|
||||||
#define xkb_state_key_get_syms _glfw.wl.xkb.state_key_get_syms
|
#define xkb_state_key_get_syms _glfw.wl.xkb.state_key_get_syms
|
||||||
#define xkb_state_update_mask _glfw.wl.xkb.state_update_mask
|
#define xkb_state_update_mask _glfw.wl.xkb.state_update_mask
|
||||||
#define xkb_state_serialize_mods _glfw.wl.xkb.state_serialize_mods
|
#define xkb_state_serialize_mods _glfw.wl.xkb.state_serialize_mods
|
||||||
|
#define xkb_state_key_get_layout _glfw.wl.xkb.state_key_get_layout
|
||||||
|
|
||||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
|
||||||
typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags);
|
typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags);
|
||||||
typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*);
|
typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*);
|
||||||
typedef struct xkb_compose_state* (* PFN_xkb_compose_state_new)(struct xkb_compose_table*, enum xkb_compose_state_flags);
|
typedef struct xkb_compose_state* (* PFN_xkb_compose_state_new)(struct xkb_compose_table*, enum xkb_compose_state_flags);
|
||||||
@ -195,7 +196,6 @@ typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_st
|
|||||||
#define xkb_compose_state_feed _glfw.wl.xkb.compose_state_feed
|
#define xkb_compose_state_feed _glfw.wl.xkb.compose_state_feed
|
||||||
#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
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _GLFW_DECORATION_WIDTH 4
|
#define _GLFW_DECORATION_WIDTH 4
|
||||||
#define _GLFW_DECORATION_TOP 24
|
#define _GLFW_DECORATION_TOP 24
|
||||||
@ -311,6 +311,7 @@ typedef struct _GLFWlibraryWayland
|
|||||||
int timerfd;
|
int timerfd;
|
||||||
short int keycodes[256];
|
short int keycodes[256];
|
||||||
short int scancodes[GLFW_KEY_LAST + 1];
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
|
char keynames[GLFW_KEY_LAST + 1][5];
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
void* handle;
|
void* handle;
|
||||||
@ -318,9 +319,7 @@ typedef struct _GLFWlibraryWayland
|
|||||||
struct xkb_keymap* keymap;
|
struct xkb_keymap* keymap;
|
||||||
struct xkb_state* state;
|
struct xkb_state* state;
|
||||||
|
|
||||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
|
||||||
struct xkb_compose_state* composeState;
|
struct xkb_compose_state* composeState;
|
||||||
#endif
|
|
||||||
|
|
||||||
xkb_mod_mask_t controlMask;
|
xkb_mod_mask_t controlMask;
|
||||||
xkb_mod_mask_t altMask;
|
xkb_mod_mask_t altMask;
|
||||||
@ -336,13 +335,14 @@ typedef struct _GLFWlibraryWayland
|
|||||||
PFN_xkb_keymap_unref keymap_unref;
|
PFN_xkb_keymap_unref keymap_unref;
|
||||||
PFN_xkb_keymap_mod_get_index keymap_mod_get_index;
|
PFN_xkb_keymap_mod_get_index keymap_mod_get_index;
|
||||||
PFN_xkb_keymap_key_repeats keymap_key_repeats;
|
PFN_xkb_keymap_key_repeats keymap_key_repeats;
|
||||||
|
PFN_xkb_keymap_key_get_syms_by_level keymap_key_get_syms_by_level;
|
||||||
PFN_xkb_state_new state_new;
|
PFN_xkb_state_new state_new;
|
||||||
PFN_xkb_state_unref state_unref;
|
PFN_xkb_state_unref state_unref;
|
||||||
PFN_xkb_state_key_get_syms state_key_get_syms;
|
PFN_xkb_state_key_get_syms state_key_get_syms;
|
||||||
PFN_xkb_state_update_mask state_update_mask;
|
PFN_xkb_state_update_mask state_update_mask;
|
||||||
PFN_xkb_state_serialize_mods state_serialize_mods;
|
PFN_xkb_state_serialize_mods state_serialize_mods;
|
||||||
|
PFN_xkb_state_key_get_layout state_key_get_layout;
|
||||||
|
|
||||||
#ifdef HAVE_XKBCOMMON_COMPOSE_H
|
|
||||||
PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale;
|
PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale;
|
||||||
PFN_xkb_compose_table_unref compose_table_unref;
|
PFN_xkb_compose_table_unref compose_table_unref;
|
||||||
PFN_xkb_compose_state_new compose_state_new;
|
PFN_xkb_compose_state_new compose_state_new;
|
||||||
@ -350,7 +350,6 @@ typedef struct _GLFWlibraryWayland
|
|||||||
PFN_xkb_compose_state_feed compose_state_feed;
|
PFN_xkb_compose_state_feed compose_state_feed;
|
||||||
PFN_xkb_compose_state_get_status compose_state_get_status;
|
PFN_xkb_compose_state_get_status compose_state_get_status;
|
||||||
PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym;
|
PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym;
|
||||||
#endif
|
|
||||||
} xkb;
|
} xkb;
|
||||||
|
|
||||||
_GLFWwindow* pointerFocus;
|
_GLFWwindow* pointerFocus;
|
||||||
@ -496,4 +495,5 @@ GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
|
|||||||
void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
||||||
|
|
||||||
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
|
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
|
||||||
|
GLFWbool _glfwInputTextWayland(_GLFWwindow* window, uint32_t scancode);
|
||||||
|
|
||||||
|
188
src/wl_window.c
188
src/wl_window.c
@ -432,35 +432,6 @@ static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLFWbool createSurface(_GLFWwindow* window,
|
|
||||||
const _GLFWwndconfig* wndconfig)
|
|
||||||
{
|
|
||||||
window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor);
|
|
||||||
if (!window->wl.surface)
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
wl_surface_add_listener(window->wl.surface,
|
|
||||||
&surfaceListener,
|
|
||||||
window);
|
|
||||||
|
|
||||||
wl_surface_set_user_data(window->wl.surface, window);
|
|
||||||
|
|
||||||
window->wl.native = wl_egl_window_create(window->wl.surface,
|
|
||||||
wndconfig->width,
|
|
||||||
wndconfig->height);
|
|
||||||
if (!window->wl.native)
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
window->wl.width = wndconfig->width;
|
|
||||||
window->wl.height = wndconfig->height;
|
|
||||||
window->wl.scale = 1;
|
|
||||||
|
|
||||||
if (!window->wl.transparent)
|
|
||||||
setOpaqueRegion(window);
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor,
|
static void setFullscreen(_GLFWwindow* window, _GLFWmonitor* monitor,
|
||||||
int refreshRate)
|
int refreshRate)
|
||||||
{
|
{
|
||||||
@ -644,6 +615,46 @@ static GLFWbool createXdgSurface(_GLFWwindow* window)
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GLFWbool createSurface(_GLFWwindow* window,
|
||||||
|
const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig)
|
||||||
|
{
|
||||||
|
window->wl.surface = wl_compositor_create_surface(_glfw.wl.compositor);
|
||||||
|
if (!window->wl.surface)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
wl_surface_add_listener(window->wl.surface,
|
||||||
|
&surfaceListener,
|
||||||
|
window);
|
||||||
|
|
||||||
|
wl_surface_set_user_data(window->wl.surface, window);
|
||||||
|
|
||||||
|
window->wl.native = wl_egl_window_create(window->wl.surface,
|
||||||
|
wndconfig->width,
|
||||||
|
wndconfig->height);
|
||||||
|
if (!window->wl.native)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
window->wl.width = wndconfig->width;
|
||||||
|
window->wl.height = wndconfig->height;
|
||||||
|
window->wl.scale = 1;
|
||||||
|
window->wl.title = _glfw_strdup(wndconfig->title);
|
||||||
|
|
||||||
|
window->wl.transparent = fbconfig->transparent;
|
||||||
|
if (!window->wl.transparent)
|
||||||
|
setOpaqueRegion(window);
|
||||||
|
|
||||||
|
if (window->monitor || wndconfig->visible)
|
||||||
|
{
|
||||||
|
if (!createXdgSurface(window))
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
window->wl.visible = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void setCursorImage(_GLFWwindow* window,
|
static void setCursorImage(_GLFWwindow* window,
|
||||||
_GLFWcursorWayland* cursorWayland)
|
_GLFWcursorWayland* cursorWayland)
|
||||||
{
|
{
|
||||||
@ -708,22 +719,19 @@ static void incrementCursorImage(_GLFWwindow* window)
|
|||||||
|
|
||||||
static void handleEvents(int timeout)
|
static void handleEvents(int timeout)
|
||||||
{
|
{
|
||||||
struct wl_display* display = _glfw.wl.display;
|
struct pollfd fds[] =
|
||||||
struct pollfd fds[] = {
|
{
|
||||||
{ wl_display_get_fd(display), POLLIN },
|
{ wl_display_get_fd(_glfw.wl.display), POLLIN },
|
||||||
{ _glfw.wl.timerfd, POLLIN },
|
{ _glfw.wl.timerfd, POLLIN },
|
||||||
{ _glfw.wl.cursorTimerfd, POLLIN },
|
{ _glfw.wl.cursorTimerfd, POLLIN },
|
||||||
};
|
};
|
||||||
ssize_t read_ret;
|
|
||||||
uint64_t repeats;
|
|
||||||
|
|
||||||
while (wl_display_prepare_read(display) != 0)
|
while (wl_display_prepare_read(_glfw.wl.display) != 0)
|
||||||
wl_display_dispatch_pending(display);
|
wl_display_dispatch_pending(_glfw.wl.display);
|
||||||
|
|
||||||
// If an error different from EAGAIN happens, we have likely been
|
// If an error other than EAGAIN happens, we have likely been disconnected
|
||||||
// disconnected from the Wayland session, try to handle that the best we
|
// from the Wayland session; try to handle that the best we can.
|
||||||
// can.
|
if (wl_display_flush(_glfw.wl.display) < 0 && errno != EAGAIN)
|
||||||
if (wl_display_flush(display) < 0 && errno != EAGAIN)
|
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = _glfw.windowListHead;
|
_GLFWwindow* window = _glfw.windowListHead;
|
||||||
while (window)
|
while (window)
|
||||||
@ -731,7 +739,8 @@ static void handleEvents(int timeout)
|
|||||||
_glfwInputWindowCloseRequest(window);
|
_glfwInputWindowCloseRequest(window);
|
||||||
window = window->next;
|
window = window->next;
|
||||||
}
|
}
|
||||||
wl_display_cancel_read(display);
|
|
||||||
|
wl_display_cancel_read(_glfw.wl.display);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -739,41 +748,41 @@ static void handleEvents(int timeout)
|
|||||||
{
|
{
|
||||||
if (fds[0].revents & POLLIN)
|
if (fds[0].revents & POLLIN)
|
||||||
{
|
{
|
||||||
wl_display_read_events(display);
|
wl_display_read_events(_glfw.wl.display);
|
||||||
wl_display_dispatch_pending(display);
|
wl_display_dispatch_pending(_glfw.wl.display);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
wl_display_cancel_read(_glfw.wl.display);
|
||||||
wl_display_cancel_read(display);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fds[1].revents & POLLIN)
|
if (fds[1].revents & POLLIN)
|
||||||
{
|
{
|
||||||
read_ret = read(_glfw.wl.timerfd, &repeats, sizeof(repeats));
|
uint64_t repeats;
|
||||||
if (read_ret == 8 && _glfw.wl.keyboardFocus)
|
|
||||||
|
if (read(_glfw.wl.timerfd, &repeats, sizeof(repeats)) == 8)
|
||||||
{
|
{
|
||||||
for (uint64_t i = 0; i < repeats; ++i)
|
for (uint64_t i = 0; i < repeats; i++)
|
||||||
{
|
{
|
||||||
_glfwInputKey(_glfw.wl.keyboardFocus,
|
_glfwInputKey(_glfw.wl.keyboardFocus,
|
||||||
_glfw.wl.keyboardLastKey,
|
_glfw.wl.keyboardLastKey,
|
||||||
_glfw.wl.keyboardLastScancode,
|
_glfw.wl.keyboardLastScancode,
|
||||||
GLFW_REPEAT,
|
GLFW_PRESS,
|
||||||
_glfw.wl.xkb.modifiers);
|
_glfw.wl.xkb.modifiers);
|
||||||
|
_glfwInputTextWayland(_glfw.wl.keyboardFocus,
|
||||||
|
_glfw.wl.keyboardLastScancode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fds[2].revents & POLLIN)
|
if (fds[2].revents & POLLIN)
|
||||||
{
|
{
|
||||||
read_ret = read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats));
|
uint64_t repeats;
|
||||||
if (read_ret == 8)
|
|
||||||
|
if (read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)) == 8)
|
||||||
incrementCursorImage(_glfw.wl.pointerFocus);
|
incrementCursorImage(_glfw.wl.pointerFocus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
wl_display_cancel_read(_glfw.wl.display);
|
||||||
wl_display_cancel_read(display);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -785,9 +794,7 @@ int _glfwCreateWindowWayland(_GLFWwindow* window,
|
|||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig)
|
const _GLFWfbconfig* fbconfig)
|
||||||
{
|
{
|
||||||
window->wl.transparent = fbconfig->transparent;
|
if (!createSurface(window, wndconfig, fbconfig))
|
||||||
|
|
||||||
if (!createSurface(window, wndconfig))
|
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
if (ctxconfig->client != GLFW_NO_API)
|
||||||
@ -809,15 +816,6 @@ int _glfwCreateWindowWayland(_GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wndconfig->title)
|
|
||||||
window->wl.title = _glfw_strdup(wndconfig->title);
|
|
||||||
|
|
||||||
window->wl.currentCursor = NULL;
|
|
||||||
|
|
||||||
window->wl.monitors = _glfw_calloc(1, sizeof(_GLFWmonitor*));
|
|
||||||
window->wl.monitorsCount = 0;
|
|
||||||
window->wl.monitorsSize = 1;
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1010,6 +1008,7 @@ void _glfwShowWindowWayland(_GLFWwindow* window)
|
|||||||
createXdgSurface(window);
|
createXdgSurface(window);
|
||||||
|
|
||||||
window->wl.visible = GLFW_TRUE;
|
window->wl.visible = GLFW_TRUE;
|
||||||
|
_glfwInputWindowDamage(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1196,10 +1195,57 @@ void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode)
|
|||||||
|
|
||||||
const char* _glfwGetScancodeNameWayland(int scancode)
|
const char* _glfwGetScancodeNameWayland(int scancode)
|
||||||
{
|
{
|
||||||
// TODO
|
if (scancode < 0 || scancode > 255 ||
|
||||||
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
|
_glfw.wl.keycodes[scancode] == GLFW_KEY_UNKNOWN)
|
||||||
"Wayland: Key names not yet implemented");
|
{
|
||||||
return NULL;
|
_glfwInputError(GLFW_INVALID_VALUE,
|
||||||
|
"Wayland: Invalid scancode %i",
|
||||||
|
scancode);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int key = _glfw.wl.keycodes[scancode];
|
||||||
|
const xkb_keycode_t keycode = scancode + 8;
|
||||||
|
const xkb_layout_index_t layout =
|
||||||
|
xkb_state_key_get_layout(_glfw.wl.xkb.state, keycode);
|
||||||
|
if (layout == XKB_LAYOUT_INVALID)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to retrieve layout for key name");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const xkb_keysym_t* keysyms = NULL;
|
||||||
|
xkb_keymap_key_get_syms_by_level(_glfw.wl.xkb.keymap,
|
||||||
|
keycode,
|
||||||
|
layout,
|
||||||
|
0,
|
||||||
|
&keysyms);
|
||||||
|
if (keysyms == NULL)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to retrieve keysym for key name");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t codepoint = _glfwKeySym2Unicode(keysyms[0]);
|
||||||
|
if (codepoint == GLFW_INVALID_CODEPOINT)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to retrieve codepoint for key name");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t count = _glfwEncodeUTF8(_glfw.wl.keynames[key], codepoint);
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Failed to encode codepoint for key name");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.wl.keynames[key][count] = '\0';
|
||||||
|
return _glfw.wl.keynames[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwGetKeyScancodeWayland(int key)
|
int _glfwGetKeyScancodeWayland(int key)
|
||||||
|
@ -429,44 +429,13 @@ static char** parseUriList(char* text, int* count)
|
|||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode a Unicode code point to a UTF-8 stream
|
|
||||||
// Based on cutef8 by Jeff Bezanson (Public Domain)
|
|
||||||
//
|
|
||||||
static size_t encodeUTF8(char* s, unsigned int ch)
|
|
||||||
{
|
|
||||||
size_t count = 0;
|
|
||||||
|
|
||||||
if (ch < 0x80)
|
|
||||||
s[count++] = (char) ch;
|
|
||||||
else if (ch < 0x800)
|
|
||||||
{
|
|
||||||
s[count++] = (ch >> 6) | 0xc0;
|
|
||||||
s[count++] = (ch & 0x3f) | 0x80;
|
|
||||||
}
|
|
||||||
else if (ch < 0x10000)
|
|
||||||
{
|
|
||||||
s[count++] = (ch >> 12) | 0xe0;
|
|
||||||
s[count++] = ((ch >> 6) & 0x3f) | 0x80;
|
|
||||||
s[count++] = (ch & 0x3f) | 0x80;
|
|
||||||
}
|
|
||||||
else if (ch < 0x110000)
|
|
||||||
{
|
|
||||||
s[count++] = (ch >> 18) | 0xf0;
|
|
||||||
s[count++] = ((ch >> 12) & 0x3f) | 0x80;
|
|
||||||
s[count++] = ((ch >> 6) & 0x3f) | 0x80;
|
|
||||||
s[count++] = (ch & 0x3f) | 0x80;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode a Unicode code point from a UTF-8 stream
|
// Decode a Unicode code point from a UTF-8 stream
|
||||||
// Based on cutef8 by Jeff Bezanson (Public Domain)
|
// Based on cutef8 by Jeff Bezanson (Public Domain)
|
||||||
//
|
//
|
||||||
static unsigned int decodeUTF8(const char** s)
|
static uint32_t decodeUTF8(const char** s)
|
||||||
{
|
{
|
||||||
unsigned int ch = 0, count = 0;
|
uint32_t codepoint = 0, count = 0;
|
||||||
static const unsigned int offsets[] =
|
static const uint32_t offsets[] =
|
||||||
{
|
{
|
||||||
0x00000000u, 0x00003080u, 0x000e2080u,
|
0x00000000u, 0x00003080u, 0x000e2080u,
|
||||||
0x03c82080u, 0xfa082080u, 0x82082080u
|
0x03c82080u, 0xfa082080u, 0x82082080u
|
||||||
@ -474,13 +443,13 @@ static unsigned int decodeUTF8(const char** s)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ch = (ch << 6) + (unsigned char) **s;
|
codepoint = (codepoint << 6) + (unsigned char) **s;
|
||||||
(*s)++;
|
(*s)++;
|
||||||
count++;
|
count++;
|
||||||
} while ((**s & 0xc0) == 0x80);
|
} while ((**s & 0xc0) == 0x80);
|
||||||
|
|
||||||
assert(count <= 6);
|
assert(count <= 6);
|
||||||
return ch - offsets[count - 1];
|
return codepoint - offsets[count - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the specified Latin-1 string to UTF-8
|
// Convert the specified Latin-1 string to UTF-8
|
||||||
@ -497,7 +466,7 @@ static char* convertLatin1toUTF8(const char* source)
|
|||||||
char* tp = target;
|
char* tp = target;
|
||||||
|
|
||||||
for (sp = source; *sp; sp++)
|
for (sp = source; *sp; sp++)
|
||||||
tp += encodeUTF8(tp, *sp);
|
tp += _glfwEncodeUTF8(tp, *sp);
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
@ -1317,9 +1286,9 @@ static void processEvent(XEvent *event)
|
|||||||
|
|
||||||
_glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
|
_glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
|
||||||
|
|
||||||
const long character = _glfwKeySym2Unicode(keysym);
|
const uint32_t codepoint = _glfwKeySym2Unicode(keysym);
|
||||||
if (character != -1)
|
if (codepoint != GLFW_INVALID_CODEPOINT)
|
||||||
_glfwInputChar(window, character, mods, plain);
|
_glfwInputChar(window, codepoint, mods, plain);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -2899,11 +2868,11 @@ const char* _glfwGetScancodeNameX11(int scancode)
|
|||||||
if (keysym == NoSymbol)
|
if (keysym == NoSymbol)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
const long ch = _glfwKeySym2Unicode(keysym);
|
const uint32_t codepoint = _glfwKeySym2Unicode(keysym);
|
||||||
if (ch == -1)
|
if (codepoint == GLFW_INVALID_CODEPOINT)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
const size_t count = encodeUTF8(_glfw.x11.keynames[key], (unsigned int) ch);
|
const size_t count = _glfwEncodeUTF8(_glfw.x11.keynames[key], codepoint);
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -907,7 +907,7 @@ static const struct codepair {
|
|||||||
|
|
||||||
// Convert XKB KeySym to Unicode
|
// Convert XKB KeySym to Unicode
|
||||||
//
|
//
|
||||||
long _glfwKeySym2Unicode(unsigned int keysym)
|
uint32_t _glfwKeySym2Unicode(unsigned int keysym)
|
||||||
{
|
{
|
||||||
int min = 0;
|
int min = 0;
|
||||||
int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
|
int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
|
||||||
@ -937,6 +937,6 @@ long _glfwKeySym2Unicode(unsigned int keysym)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No matching Unicode value found
|
// No matching Unicode value found
|
||||||
return -1;
|
return GLFW_INVALID_CODEPOINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,5 +24,7 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
long _glfwKeySym2Unicode(unsigned int keysym);
|
#define GLFW_INVALID_CODEPOINT 0xffffffffu
|
||||||
|
|
||||||
|
uint32_t _glfwKeySym2Unicode(unsigned int keysym);
|
||||||
|
|
||||||
|
@ -113,6 +113,12 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
{
|
{
|
||||||
const GLFWgammaramp* ramp = glfwGetGammaRamp(monitor);
|
const GLFWgammaramp* ramp = glfwGetGammaRamp(monitor);
|
||||||
|
if (!ramp)
|
||||||
|
{
|
||||||
|
glfwTerminate();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
const size_t array_size = ramp->size * sizeof(short);
|
const size_t array_size = ramp->size * sizeof(short);
|
||||||
orig_ramp.size = ramp->size;
|
orig_ramp.size = ramp->size;
|
||||||
orig_ramp.red = malloc(array_size);
|
orig_ramp.red = malloc(array_size);
|
||||||
|
Loading…
Reference in New Issue
Block a user