diff --git a/glfw/source-info.json b/glfw/source-info.json index ee7c666f3..c333e8508 100644 --- a/glfw/source-info.json +++ b/glfw/source-info.json @@ -55,6 +55,7 @@ "wl_platform.h", "posix_thread.h", "wl_cursors.h", + "wl_text_input.h", "xkb_glfw.h", "dbus_glfw.h", "ibus_glfw.h", @@ -73,13 +74,15 @@ "unstable/pointer-constraints/pointer-constraints-unstable-v1.xml", "unstable/idle-inhibit/idle-inhibit-unstable-v1.xml", "unstable/xdg-decoration/xdg-decoration-unstable-v1.xml", - "unstable/primary-selection/primary-selection-unstable-v1.xml" + "unstable/primary-selection/primary-selection-unstable-v1.xml", + "unstable/text-input/text-input-unstable-v3.xml" ], "sources": [ "wl_init.c", "wl_monitor.c", "wl_window.c", "wl_cursors.c", + "wl_text_input.c", "posix_thread.c", "xkb_glfw.c", "dbus_glfw.c", diff --git a/glfw/wl_init.c b/glfw/wl_init.c index ff9a35cd6..3903c6496 100644 --- a/glfw/wl_init.c +++ b/glfw/wl_init.c @@ -584,6 +584,7 @@ static void registryHandleGlobal(void* data UNUSED, if (_glfw.wl.primarySelectionDeviceManager && !_glfw.wl.primarySelectionDevice) { _glfwSetupWaylandPrimarySelectionDevice(); } + _glfwWaylandInitTextInput(); } } else if (strcmp(interface, "xdg_wm_base") == 0) @@ -617,6 +618,11 @@ static void registryHandleGlobal(void* data UNUSED, &zwp_pointer_constraints_v1_interface, 1); } + else if (strcmp(interface, GLFW_WAYLAND_TEXT_INPUT_INTERFACE_NAME) == 0) + { + _glfwWaylandBindTextInput(registry, name); + _glfwWaylandInitTextInput(); + } else if (strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0) { _glfw.wl.idleInhibitManager = @@ -847,6 +853,7 @@ void _glfwPlatformTerminate(void) zwp_relative_pointer_manager_v1_destroy(_glfw.wl.relativePointerManager); if (_glfw.wl.pointerConstraints) zwp_pointer_constraints_v1_destroy(_glfw.wl.pointerConstraints); + _glfwWaylandDestroyTextInput(); if (_glfw.wl.idleInhibitManager) zwp_idle_inhibit_manager_v1_destroy(_glfw.wl.idleInhibitManager); if (_glfw.wl.dataSourceForClipboard) diff --git a/glfw/wl_platform.h b/glfw/wl_platform.h index 7aaed8f1e..5b6ee79d4 100644 --- a/glfw/wl_platform.h +++ b/glfw/wl_platform.h @@ -59,6 +59,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR #include "wayland-pointer-constraints-unstable-v1-client-protocol.h" #include "wayland-idle-inhibit-unstable-v1-client-protocol.h" #include "wayland-primary-selection-unstable-v1-client-protocol.h" +#include "wl_text_input.h" #define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) #define _glfw_dlclose(handle) dlclose(handle) diff --git a/glfw/wl_text_input.c b/glfw/wl_text_input.c new file mode 100644 index 000000000..ae6a3d411 --- /dev/null +++ b/glfw/wl_text_input.c @@ -0,0 +1,85 @@ +/* + * wl_text_input.c + * Copyright (C) 2021 Kovid Goyal + * + * Distributed under terms of the GPL3 license. + */ + +#include "wl_text_input.h" +#include "internal.h" +#include "wayland-text-input-unstable-v3-client-protocol.h" + +static struct zwp_text_input_v3* text_input; +static struct zwp_text_input_manager_v3* text_input_manager; + +static void +text_input_enter(void *data UNUSED, struct zwp_text_input_v3 *text_input UNUSED, struct wl_surface *surface UNUSED) { + printf("enter text input\n"); +} + +static void +text_input_leave(void *data UNUSED, struct zwp_text_input_v3 *text_input UNUSED, struct wl_surface *surface UNUSED) { + printf("leave text input\n"); +} + +static void +text_input_preedit_string( + void *data UNUSED, + struct zwp_text_input_v3 *text_input UNUSED, + const char *text UNUSED, + int32_t cursor_begin UNUSED, + int32_t cursor_end UNUSED +) { +} + +static void +text_input_commit_string(void *data UNUSED, struct zwp_text_input_v3 *text_input UNUSED, const char *text UNUSED) { +} + +static void +text_input_delete_surrounding_text( + void *data UNUSED, + struct zwp_text_input_v3 *zwp_text_input_v3 UNUSED, + uint32_t before_length UNUSED, + uint32_t after_length UNUSED) { +} + +static void +text_input_done(void *data UNUSED, struct zwp_text_input_v3 *zwp_text_input_v3 UNUSED, uint32_t serial UNUSED) { +} + +void +_glfwWaylandBindTextInput(struct wl_registry* registry, uint32_t name) { + if (!text_input_manager) { + text_input_manager = + wl_registry_bind(registry, name, + &zwp_text_input_manager_v3_interface, + 1); + } +} + +void +_glfwWaylandInitTextInput(void) { + static const struct zwp_text_input_v3_listener text_input_listener = { + .enter = text_input_enter, + .leave = text_input_leave, + .preedit_string = text_input_preedit_string, + .commit_string = text_input_commit_string, + .delete_surrounding_text = text_input_delete_surrounding_text, + .done = text_input_done, + }; + if (!text_input) { + if (text_input_manager && _glfw.wl.seat) { + text_input = zwp_text_input_manager_v3_get_text_input( + text_input_manager, _glfw.wl.seat); + if (text_input) zwp_text_input_v3_add_listener(text_input, &text_input_listener, NULL); + } + } +} + +void +_glfwWaylandDestroyTextInput(void) { + if (text_input) zwp_text_input_v3_destroy(text_input); + if (text_input_manager) zwp_text_input_manager_v3_destroy(text_input_manager); + text_input = NULL; text_input_manager = NULL; +} diff --git a/glfw/wl_text_input.h b/glfw/wl_text_input.h new file mode 100644 index 000000000..a01934758 --- /dev/null +++ b/glfw/wl_text_input.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2021 Kovid Goyal + * + * Distributed under terms of the GPL3 license. + */ + +#pragma once +#include + +#define GLFW_WAYLAND_TEXT_INPUT_INTERFACE_NAME "zwp_text_input_manager_v3" + +void _glfwWaylandBindTextInput(struct wl_registry* registry, uint32_t name); +void _glfwWaylandInitTextInput(void); +void _glfwWaylandDestroyTextInput(void); diff --git a/glfw/xkb_glfw.c b/glfw/xkb_glfw.c index 6c92e7e87..ca3d148b1 100644 --- a/glfw/xkb_glfw.c +++ b/glfw/xkb_glfw.c @@ -349,7 +349,9 @@ glfw_xkb_create_context(_GLFWXKBData *xkb) { "Failed to initialize XKB context"); return false; } +#ifndef _GLFW_WAYLAND glfw_connect_to_ibus(&xkb->ibus); +#endif return true; }