diff --git a/.gitignore b/.gitignore index ec1ec46..0bd04e0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ wayland xdg-shell-client-protocol.h xdg-shell-protocol.c +zwp-text-input-unstable-v3-client-protocol.c +zwp-text-input-unstable-v3-protocol.h diff --git a/Makefile b/Makefile index 00e4788..614ee43 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,13 @@ INTERFACEDIR:=$(shell pkg-config --variable=pkgdatadir wayland-protocols) CFLAGS=-Wall -Wextra -Og -ggdb3 -Wno-unused-but-set-variable -Wno-unused-parameter LIBS=-lwayland-client -lwayland-egl -lEGL -lOpenGL -lxkbcommon -wayland: wayland.c xdg-shell-protocol.c xdg-shell-client-protocol.h - gcc $(CFLAGS) $(LIBS) wayland.c xdg-shell-protocol.c -o wayland +wayland: wayland.c xdg-shell-protocol.c xdg-shell-client-protocol.h zwp-text-input-unstable-v3-client-protocol.c zwp-text-input-unstable-v3-protocol.h + gcc $(CFLAGS) $(LIBS) wayland.c xdg-shell-protocol.c zwp-text-input-unstable-v3-client-protocol.c -o wayland xdg-shell-protocol.c: wayland-scanner private-code $(INTERFACEDIR)/stable/xdg-shell/xdg-shell.xml xdg-shell-protocol.c xdg-shell-client-protocol.h: wayland-scanner client-header $(INTERFACEDIR)/stable/xdg-shell/xdg-shell.xml xdg-shell-client-protocol.h +zwp-text-input-unstable-v3-client-protocol.c: + wayland-scanner private-code $(INTERFACEDIR)/unstable/text-input/text-input-unstable-v3.xml zwp-text-input-unstable-v3-client-protocol.c +zwp-text-input-unstable-v3-protocol.h: + wayland-scanner client-header $(INTERFACEDIR)/unstable/text-input/text-input-unstable-v3.xml zwp-text-input-unstable-v3-protocol.h diff --git a/wayland.c b/wayland.c index 5892de5..6ceeaa9 100644 --- a/wayland.c +++ b/wayland.c @@ -11,6 +11,7 @@ #include // Generated header using wayland-scanner #include "xdg-shell-client-protocol.h" +#include "zwp-text-input-unstable-v3-protocol.h" struct wl_compositor *compositor = NULL; struct wl_registry *registry = NULL; @@ -25,6 +26,11 @@ struct wl_seat *wl_seat = NULL; struct wl_keyboard *wl_keyboard = NULL; struct wl_pointer *wl_pointer = NULL; +/* ZWP text input extension */ +struct zwp_text_input_v3 *zwp_text_input_v3 = NULL; +struct zwp_text_input_manager_v3 *zwp_text_input_manager_v3 = NULL; + + /* XKB library */ struct xkb_context *xkb_context = NULL; struct xkb_state *xkb_state = NULL; @@ -57,8 +63,7 @@ char *egl_s(int code) void registry_handle_global( void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { - fprintf(stdout, "Wayland interface: '%s', version: %d, name: %d\n", - interface, version, name); + fprintf(stdout, "Wayland interface: '%s', version: %d, name: %d\n", interface, version, name); if (!strcmp(interface, wl_compositor_interface.name)) { fprintf(stdout, "Registering compositor...\n"); @@ -69,19 +74,59 @@ void registry_handle_global( void *data, struct wl_registry *registry, fprintf(stdout, "Registering XDG WM base interface...\n"); wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1); } - /* NOTE: Since wl_seat v5, pointer events are grouped into "frames", which do not appear to be useful for non-touch applications and - also create more events which are more complicated to dispatch. */ + /* NOTE: Since wl_seat v5, pointer events are grouped into "frames", which do not appear to be useful for non-touch + applications and also create more events which are more complicated to dispatch. */ if (!strcmp(interface, wl_seat_interface.name)) { fprintf(stdout, "Registering WL seat interface...\n"); - wl_seat = wl_registry_bind(registry, name, &wl_seat_interface, 9); + wl_seat = wl_registry_bind(registry, name, &wl_seat_interface, 8); } + + if (!strcmp(interface, zwp_text_input_manager_v3_interface.name)) + { + zwp_text_input_manager_v3 = wl_registry_bind(registry, name, &zwp_text_input_manager_v3_interface, 1); + } +} + +void zwp_text_input_v3_enter_callback(void *data, struct zwp_text_input_v3 *text_input, struct wl_surface *surface) +{ + fprintf(stdout, "ZWP text input v3 enter callback\n"); + zwp_text_input_v3 = text_input; + zwp_text_input_v3_enable(zwp_text_input_v3); + zwp_text_input_v3_commit(zwp_text_input_v3); +} + +void zwp_text_input_v3_leave_callback(void *data, struct zwp_text_input_v3 *text_input, struct wl_surface *surface) +{ + fprintf(stdout, "ZWP text input v3 leave callback\n"); + zwp_text_input_v3_disable(zwp_text_input_v3); + zwp_text_input_v3_commit(zwp_text_input_v3); +} + +void zwp_text_input_v3_preedit_string_callback(void *data, struct zwp_text_input_v3 *text_input, const char *text, int32_t cursor_begin, int32_t cursor_end) +{ + fprintf(stdout, "ZWP text input v3 preedit string callback\n"); +} + +void zwp_text_input_v3_commit_string_callback(void *data, struct zwp_text_input_v3 *text_input, const char *text) +{ + fprintf(stdout, "ZWP text input v3 commit string callback\n"); +} + +void zwp_text_input_v3_delete_surrounding_text_callback(void *data, struct zwp_text_input_v3 *text_input, uint32_t before_length, uint32_t after_length) +{ + fprintf(stdout, "ZWP text input v3 delete surrounding text callback\n"); +} + +void zwp_text_input_v3_done_callback(void *data, struct zwp_text_input_v3 *text_input, uint32_t surface) +{ + fprintf(stdout, "ZWP text input v3 done callback\n"); } void registry_handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) { - // This space deliberately left blank + // This space deliberately left blank } static const struct wl_registry_listener @@ -175,52 +220,52 @@ void repeat_info_callback(void *data, struct wl_keyboard *kb, int rate, int dela void pointer_enter_callback(void *data, struct wl_pointer *pointer, uint serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y) { - fprintf(stdout, "Pointer entered WL surface on coordinates %d %d\n", x, y); + //fprintf(stdout, "Pointer entered WL surface on coordinates %d %d\n", x, y); } void pointer_leave_callback(void *data, struct wl_pointer *pointer, uint serial, struct wl_surface *surface) { - fprintf(stdout, "Pointer left WL surface\n"); + //fprintf(stdout, "Pointer left WL surface\n"); } void pointer_motion_callback(void *data, struct wl_pointer *pointer, uint time, wl_fixed_t x, wl_fixed_t y) { - fprintf(stdout, "Pointer moved to %d %d\n", x, y); + //fprintf(stdout, "Pointer moved to %d %d\n", x, y); } void pointer_button_callback(void *data, struct wl_pointer *pointer, uint serial, uint time, uint button, uint state) { - fprintf(stdout, "Pointer button %d changed state\n", button); + //fprintf(stdout, "Pointer button %d changed state\n", button); } void pointer_axis_callback(void *data, struct wl_pointer *pointer, uint time, uint axis, wl_fixed_t value) { - fprintf(stdout, "Pointer scroll on axis %d value %d\n", axis, value); + //fprintf(stdout, "Pointer scroll on axis %d value %d\n", axis, value); } /* NOTE: *some* events are logically grouped together. The frame event marks the boundary between groups of them. More info: https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_pointer */ void pointer_frame_callback(void *data, struct wl_pointer *frame) { - fprintf(stdout, "Pointer frame ended\n"); + //fprintf(stdout, "Pointer frame ended\n"); } /* NOTE: This event is also used to group pointer events together. It specifies info about all events in its frame */ void pointer_axis_source_callback(void *data, struct wl_pointer *pointer, uint axis_source) { - fprintf(stdout, "Pointer axis source: %d\n", axis_source); + //fprintf(stdout, "Pointer axis source: %d\n", axis_source); } /* Optional event to implement kinetic scrolling */ void pointer_axis_stop_callback(void *data, struct wl_pointer *pointer, uint time, uint axis) { - fprintf(stdout, "Pointer axis stopped: %d\n", axis); + //fprintf(stdout, "Pointer axis stopped: %d\n", axis); } /* Optional event. Carries discrete scroll info after an 'axis' event */ void pointer_axis_discrete_callback(void *data, struct wl_pointer *pointer, uint axis, int discrete) { - fprintf(stdout, "Pointer axis discrete step: %d\n", discrete); + //fprintf(stdout, "Pointer axis discrete step: %d\n", discrete); } int main() @@ -275,6 +320,23 @@ int main() fprintf(stderr, "Could not get XKB keyboard\n"); if (!(wl_pointer = wl_seat_get_pointer(wl_seat))) fprintf(stderr, "Could not get WL pointer\n"); + + if (!zwp_text_input_manager_v3) + fprintf(stderr, "Could not get ZWP text input manager\n"); + else if (!(zwp_text_input_v3 = zwp_text_input_manager_v3_get_text_input(zwp_text_input_manager_v3, wl_seat))) + fprintf(stderr, "Could not get ZWP text input handle\n"); + + const struct zwp_text_input_v3_listener zwp_text_input_v3_listener = { + .enter = zwp_text_input_v3_enter_callback, + .leave = zwp_text_input_v3_leave_callback, + .preedit_string = zwp_text_input_v3_preedit_string_callback, + .commit_string = zwp_text_input_v3_commit_string_callback, + .delete_surrounding_text = zwp_text_input_v3_delete_surrounding_text_callback, + .done = zwp_text_input_v3_done_callback + }; + + if (zwp_text_input_v3_add_listener(zwp_text_input_v3, &zwp_text_input_v3_listener, NULL)) + fprintf(stderr, "Could not add ZWP text input callback\n"); const struct wl_seat_listener wl_seat_listener = { .capabilities = wl_seat_capabilities_callback