diff --git a/Makefile b/Makefile index ad7e0a8..8ed75fa 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,9 @@ CC = 9c LD = 9l DBUS_CFLAGS := $(shell pkg-config --cflags dbus-1) DBUS_LIBS := $(shell pkg-config --libs dbus-1) -CFLAGS = -Wall -Wextra -O2 -g $(DBUS_CFLAGS) +WL_CFLAGS := $(shell pkg-config --cflags wayland-client xkbcommon) +WL_LIBS := $(shell pkg-config --libs wayland-client xkbcommon) +CFLAGS = -Wall -Wextra -O2 -g $(DBUS_CFLAGS) $(WL_CFLAGS) PROG = strans SRCS = $(wildcard *.c) @@ -11,7 +13,7 @@ OBJS = $(SRCS:.c=.o) all: $(PROG) xim bench $(PROG): $(OBJS) - $(LD) -o $@ $(OBJS) -lthread -lString -lbio -lxcb -lm $(DBUS_LIBS) + $(LD) -o $@ $(OBJS) -lthread -lString -lbio -lxcb -lm $(DBUS_LIBS) $(WL_LIBS) $(OBJS): dat.h fn.h ipc.h diff --git a/fn.h b/fn.h index 9ed303a..5936b92 100644 --- a/fn.h +++ b/fn.h @@ -34,6 +34,7 @@ void dictsend(Im*, Str*); void srvthread(void*); void ibusthread(void*); +void waylandthread(void*); void* emalloc(ulong); void* erealloc(void*, ulong); diff --git a/input-method-unstable-v2-client-protocol.h b/input-method-unstable-v2-client-protocol.h new file mode 100644 index 0000000..8eaf66f --- /dev/null +++ b/input-method-unstable-v2-client-protocol.h @@ -0,0 +1,955 @@ +/* Generated by wayland-scanner 1.21.0 */ + +#ifndef INPUT_METHOD_UNSTABLE_V2_CLIENT_PROTOCOL_H +#define INPUT_METHOD_UNSTABLE_V2_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_input_method_unstable_v2 The input_method_unstable_v2 protocol + * Protocol for creating input methods + * + * @section page_desc_input_method_unstable_v2 Description + * + * This protocol allows applications to act as input methods for compositors. + * + * An input method context is used to manage the state of the input method. + * + * Text strings are UTF-8 encoded, their indices and lengths are in bytes. + * + * This document adheres to the RFC 2119 when using words like "must", + * "should", "may", etc. + * + * Warning! The protocol described in this file is experimental and + * backward incompatible changes may be made. Backward compatible changes + * may be added together with the corresponding interface version bump. + * Backward incompatible changes are done by bumping the version number in + * the protocol and interface names and resetting the interface version. + * Once the protocol is to be declared stable, the 'z' prefix and the + * version number in the protocol and interface names are removed and the + * interface version number is reset. + * + * @section page_ifaces_input_method_unstable_v2 Interfaces + * - @subpage page_iface_zwp_input_method_v2 - input method + * - @subpage page_iface_zwp_input_popup_surface_v2 - popup surface + * - @subpage page_iface_zwp_input_method_keyboard_grab_v2 - keyboard grab + * - @subpage page_iface_zwp_input_method_manager_v2 - input method manager + * @section page_copyright_input_method_unstable_v2 Copyright + *
+ *
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2010-2011 Intel Corporation
+ * Copyright © 2012-2013 Collabora, Ltd.
+ * Copyright © 2012, 2013 Intel Corporation
+ * Copyright © 2015, 2016 Jan Arne Petersen
+ * Copyright © 2017, 2018 Red Hat, Inc.
+ * Copyright © 2018       Purism SPC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ */ +struct wl_seat; +struct wl_surface; +struct zwp_input_method_keyboard_grab_v2; +struct zwp_input_method_manager_v2; +struct zwp_input_method_v2; +struct zwp_input_popup_surface_v2; + +#ifndef ZWP_INPUT_METHOD_V2_INTERFACE +#define ZWP_INPUT_METHOD_V2_INTERFACE +/** + * @page page_iface_zwp_input_method_v2 zwp_input_method_v2 + * @section page_iface_zwp_input_method_v2_desc Description + * + * An input method object allows for clients to compose text. + * + * The objects connects the client to a text input in an application, and + * lets the client to serve as an input method for a seat. + * + * The zwp_input_method_v2 object can occupy two distinct states: active and + * inactive. In the active state, the object is associated to and + * communicates with a text input. In the inactive state, there is no + * associated text input, and the only communication is with the compositor. + * Initially, the input method is in the inactive state. + * + * Requests issued in the inactive state must be accepted by the compositor. + * Because of the serial mechanism, and the state reset on activate event, + * they will not have any effect on the state of the next text input. + * + * There must be no more than one input method object per seat. + * @section page_iface_zwp_input_method_v2_api API + * See @ref iface_zwp_input_method_v2. + */ +/** + * @defgroup iface_zwp_input_method_v2 The zwp_input_method_v2 interface + * + * An input method object allows for clients to compose text. + * + * The objects connects the client to a text input in an application, and + * lets the client to serve as an input method for a seat. + * + * The zwp_input_method_v2 object can occupy two distinct states: active and + * inactive. In the active state, the object is associated to and + * communicates with a text input. In the inactive state, there is no + * associated text input, and the only communication is with the compositor. + * Initially, the input method is in the inactive state. + * + * Requests issued in the inactive state must be accepted by the compositor. + * Because of the serial mechanism, and the state reset on activate event, + * they will not have any effect on the state of the next text input. + * + * There must be no more than one input method object per seat. + */ +extern const struct wl_interface zwp_input_method_v2_interface; +#endif +#ifndef ZWP_INPUT_POPUP_SURFACE_V2_INTERFACE +#define ZWP_INPUT_POPUP_SURFACE_V2_INTERFACE +/** + * @page page_iface_zwp_input_popup_surface_v2 zwp_input_popup_surface_v2 + * @section page_iface_zwp_input_popup_surface_v2_desc Description + * + * This interface marks a surface as a popup for interacting with an input + * method. + * + * The compositor should place it near the active text input area. It must + * be visible if and only if the input method is in the active state. + * + * The client must not destroy the underlying wl_surface while the + * zwp_input_popup_surface_v2 object exists. + * @section page_iface_zwp_input_popup_surface_v2_api API + * See @ref iface_zwp_input_popup_surface_v2. + */ +/** + * @defgroup iface_zwp_input_popup_surface_v2 The zwp_input_popup_surface_v2 interface + * + * This interface marks a surface as a popup for interacting with an input + * method. + * + * The compositor should place it near the active text input area. It must + * be visible if and only if the input method is in the active state. + * + * The client must not destroy the underlying wl_surface while the + * zwp_input_popup_surface_v2 object exists. + */ +extern const struct wl_interface zwp_input_popup_surface_v2_interface; +#endif +#ifndef ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_INTERFACE +#define ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_INTERFACE +/** + * @page page_iface_zwp_input_method_keyboard_grab_v2 zwp_input_method_keyboard_grab_v2 + * @section page_iface_zwp_input_method_keyboard_grab_v2_desc Description + * + * The zwp_input_method_keyboard_grab_v2 interface represents an exclusive + * grab of the wl_keyboard interface associated with the seat. + * @section page_iface_zwp_input_method_keyboard_grab_v2_api API + * See @ref iface_zwp_input_method_keyboard_grab_v2. + */ +/** + * @defgroup iface_zwp_input_method_keyboard_grab_v2 The zwp_input_method_keyboard_grab_v2 interface + * + * The zwp_input_method_keyboard_grab_v2 interface represents an exclusive + * grab of the wl_keyboard interface associated with the seat. + */ +extern const struct wl_interface zwp_input_method_keyboard_grab_v2_interface; +#endif +#ifndef ZWP_INPUT_METHOD_MANAGER_V2_INTERFACE +#define ZWP_INPUT_METHOD_MANAGER_V2_INTERFACE +/** + * @page page_iface_zwp_input_method_manager_v2 zwp_input_method_manager_v2 + * @section page_iface_zwp_input_method_manager_v2_desc Description + * + * The input method manager allows the client to become the input method on + * a chosen seat. + * + * No more than one input method must be associated with any seat at any + * given time. + * @section page_iface_zwp_input_method_manager_v2_api API + * See @ref iface_zwp_input_method_manager_v2. + */ +/** + * @defgroup iface_zwp_input_method_manager_v2 The zwp_input_method_manager_v2 interface + * + * The input method manager allows the client to become the input method on + * a chosen seat. + * + * No more than one input method must be associated with any seat at any + * given time. + */ +extern const struct wl_interface zwp_input_method_manager_v2_interface; +#endif + +#ifndef ZWP_INPUT_METHOD_V2_ERROR_ENUM +#define ZWP_INPUT_METHOD_V2_ERROR_ENUM +enum zwp_input_method_v2_error { + /** + * wl_surface has another role + */ + ZWP_INPUT_METHOD_V2_ERROR_ROLE = 0, +}; +#endif /* ZWP_INPUT_METHOD_V2_ERROR_ENUM */ + +/** + * @ingroup iface_zwp_input_method_v2 + * @struct zwp_input_method_v2_listener + */ +struct zwp_input_method_v2_listener { + /** + * input method has been requested + * + * Notification that a text input focused on this seat requested + * the input method to be activated. + * + * This event serves the purpose of providing the compositor with + * an active input method. + * + * This event resets all state associated with previous + * surrounding_text, text_change_cause, and content_type events, as + * well as the state associated with set_preedit_string, + * commit_string, and delete_surrounding_text requests. In + * addition, it marks the zwp_input_method_v2 object as active, and + * makes any existing zwp_input_popup_surface_v2 objects visible. + * + * The surrounding_text, and content_type events must follow before + * the next done event if the text input supports the respective + * functionality. + * + * State set with this event is double-buffered. It will get + * applied on the next zwp_input_method_v2.done event, and stay + * valid until changed. + */ + void (*activate)(void *data, + struct zwp_input_method_v2 *zwp_input_method_v2); + /** + * deactivate event + * + * Notification that no focused text input currently needs an + * active input method on this seat. + * + * This event marks the zwp_input_method_v2 object as inactive. The + * compositor must make all existing zwp_input_popup_surface_v2 + * objects invisible until the next activate event. + * + * State set with this event is double-buffered. It will get + * applied on the next zwp_input_method_v2.done event, and stay + * valid until changed. + */ + void (*deactivate)(void *data, + struct zwp_input_method_v2 *zwp_input_method_v2); + /** + * surrounding text event + * + * Updates the surrounding plain text around the cursor, + * excluding the preedit text. + * + * If any preedit text is present, it is replaced with the cursor + * for the purpose of this event. + * + * The argument text is a buffer containing the surrounding text, + * and must include the cursor position, and the complete + * selection. It should contain additional characters before and + * after these. There is a maximum length of wayland messages, so + * text can not be longer than 4000 bytes. + * + * cursor is the byte offset of the cursor within the text buffer. + * + * anchor is the byte offset of the selection anchor within the + * text buffer. If there is no selected text, anchor must be the + * same as cursor. + * + * If this event does not arrive before the first done event, the + * input method may assume that the text input does not support + * this functionality and ignore following surrounding_text events. + * + * Values set with this event are double-buffered. They will get + * applied and set to initial values on the next + * zwp_input_method_v2.done event. + * + * The initial state for affected fields is empty, meaning that the + * text input does not support sending surrounding text. If the + * empty values get applied, subsequent attempts to change them may + * have no effect. + */ + void (*surrounding_text)(void *data, + struct zwp_input_method_v2 *zwp_input_method_v2, + const char *text, + uint32_t cursor, + uint32_t anchor); + /** + * indicates the cause of surrounding text change + * + * Tells the input method why the text surrounding the cursor + * changed. + * + * Whenever the client detects an external change in text, cursor, + * or anchor position, it must issue this request to the + * compositor. This request is intended to give the input method a + * chance to update the preedit text in an appropriate way, e.g. by + * removing it when the user starts typing with a keyboard. + * + * cause describes the source of the change. + * + * The value set with this event is double-buffered. It will get + * applied and set to its initial value on the next + * zwp_input_method_v2.done event. + * + * The initial value of cause is input_method. + */ + void (*text_change_cause)(void *data, + struct zwp_input_method_v2 *zwp_input_method_v2, + uint32_t cause); + /** + * content purpose and hint + * + * Indicates the content type and hint for the current + * zwp_input_method_v2 instance. + * + * Values set with this event are double-buffered. They will get + * applied on the next zwp_input_method_v2.done event. + * + * The initial value for hint is none, and the initial value for + * purpose is normal. + */ + void (*content_type)(void *data, + struct zwp_input_method_v2 *zwp_input_method_v2, + uint32_t hint, + uint32_t purpose); + /** + * apply state + * + * Atomically applies state changes recently sent to the client. + * + * The done event establishes and updates the state of the client, + * and must be issued after any changes to apply them. + * + * Text input state (content purpose, content hint, surrounding + * text, and change cause) is conceptually double-buffered within + * an input method context. + * + * Events modify the pending state, as opposed to the current state + * in use by the input method. A done event atomically applies all + * pending state, replacing the current state. After done, the new + * pending state is as documented for each related request. + * + * Events must be applied in the order of arrival. + * + * Neither current nor pending state are modified unless noted + * otherwise. + */ + void (*done)(void *data, + struct zwp_input_method_v2 *zwp_input_method_v2); + /** + * input method unavailable + * + * The input method ceased to be available. + * + * The compositor must issue this event as the only event on the + * object if there was another input_method object associated with + * the same seat at the time of its creation. + * + * The compositor must issue this request when the object is no + * longer usable, e.g. due to seat removal. + * + * The input method context becomes inert and should be destroyed + * after deactivation is handled. Any further requests and events + * except for the destroy request must be ignored. + */ + void (*unavailable)(void *data, + struct zwp_input_method_v2 *zwp_input_method_v2); +}; + +/** + * @ingroup iface_zwp_input_method_v2 + */ +static inline int +zwp_input_method_v2_add_listener(struct zwp_input_method_v2 *zwp_input_method_v2, + const struct zwp_input_method_v2_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) zwp_input_method_v2, + (void (**)(void)) listener, data); +} + +#define ZWP_INPUT_METHOD_V2_COMMIT_STRING 0 +#define ZWP_INPUT_METHOD_V2_SET_PREEDIT_STRING 1 +#define ZWP_INPUT_METHOD_V2_DELETE_SURROUNDING_TEXT 2 +#define ZWP_INPUT_METHOD_V2_COMMIT 3 +#define ZWP_INPUT_METHOD_V2_GET_INPUT_POPUP_SURFACE 4 +#define ZWP_INPUT_METHOD_V2_GRAB_KEYBOARD 5 +#define ZWP_INPUT_METHOD_V2_DESTROY 6 + +/** + * @ingroup iface_zwp_input_method_v2 + */ +#define ZWP_INPUT_METHOD_V2_ACTIVATE_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_v2 + */ +#define ZWP_INPUT_METHOD_V2_DEACTIVATE_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_v2 + */ +#define ZWP_INPUT_METHOD_V2_SURROUNDING_TEXT_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_v2 + */ +#define ZWP_INPUT_METHOD_V2_TEXT_CHANGE_CAUSE_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_v2 + */ +#define ZWP_INPUT_METHOD_V2_CONTENT_TYPE_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_v2 + */ +#define ZWP_INPUT_METHOD_V2_DONE_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_v2 + */ +#define ZWP_INPUT_METHOD_V2_UNAVAILABLE_SINCE_VERSION 1 + +/** + * @ingroup iface_zwp_input_method_v2 + */ +#define ZWP_INPUT_METHOD_V2_COMMIT_STRING_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_v2 + */ +#define ZWP_INPUT_METHOD_V2_SET_PREEDIT_STRING_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_v2 + */ +#define ZWP_INPUT_METHOD_V2_DELETE_SURROUNDING_TEXT_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_v2 + */ +#define ZWP_INPUT_METHOD_V2_COMMIT_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_v2 + */ +#define ZWP_INPUT_METHOD_V2_GET_INPUT_POPUP_SURFACE_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_v2 + */ +#define ZWP_INPUT_METHOD_V2_GRAB_KEYBOARD_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_v2 + */ +#define ZWP_INPUT_METHOD_V2_DESTROY_SINCE_VERSION 1 + +/** @ingroup iface_zwp_input_method_v2 */ +static inline void +zwp_input_method_v2_set_user_data(struct zwp_input_method_v2 *zwp_input_method_v2, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwp_input_method_v2, user_data); +} + +/** @ingroup iface_zwp_input_method_v2 */ +static inline void * +zwp_input_method_v2_get_user_data(struct zwp_input_method_v2 *zwp_input_method_v2) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwp_input_method_v2); +} + +static inline uint32_t +zwp_input_method_v2_get_version(struct zwp_input_method_v2 *zwp_input_method_v2) +{ + return wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2); +} + +/** + * @ingroup iface_zwp_input_method_v2 + * + * Send the commit string text for insertion to the application. + * + * Inserts a string at current cursor position (see commit event + * sequence). The string to commit could be either just a single character + * after a key press or the result of some composing. + * + * The argument text is a buffer containing the string to insert. There is + * a maximum length of wayland messages, so text can not be longer than + * 4000 bytes. + * + * Values set with this event are double-buffered. They must be applied + * and reset to initial on the next zwp_text_input_v3.commit request. + * + * The initial value of text is an empty string. + */ +static inline void +zwp_input_method_v2_commit_string(struct zwp_input_method_v2 *zwp_input_method_v2, const char *text) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_v2, + ZWP_INPUT_METHOD_V2_COMMIT_STRING, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2), 0, text); +} + +/** + * @ingroup iface_zwp_input_method_v2 + * + * Send the pre-edit string text to the application text input. + * + * Place a new composing text (pre-edit) at the current cursor position. + * Any previously set composing text must be removed. Any previously + * existing selected text must be removed. The cursor is moved to a new + * position within the preedit string. + * + * The argument text is a buffer containing the preedit string. There is + * a maximum length of wayland messages, so text can not be longer than + * 4000 bytes. + * + * The arguments cursor_begin and cursor_end are counted in bytes relative + * to the beginning of the submitted string buffer. Cursor should be + * hidden by the text input when both are equal to -1. + * + * cursor_begin indicates the beginning of the cursor. cursor_end + * indicates the end of the cursor. It may be equal or different than + * cursor_begin. + * + * Values set with this event are double-buffered. They must be applied on + * the next zwp_input_method_v2.commit event. + * + * The initial value of text is an empty string. The initial value of + * cursor_begin, and cursor_end are both 0. + */ +static inline void +zwp_input_method_v2_set_preedit_string(struct zwp_input_method_v2 *zwp_input_method_v2, const char *text, int32_t cursor_begin, int32_t cursor_end) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_v2, + ZWP_INPUT_METHOD_V2_SET_PREEDIT_STRING, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2), 0, text, cursor_begin, cursor_end); +} + +/** + * @ingroup iface_zwp_input_method_v2 + * + * Remove the surrounding text. + * + * before_length and after_length are the number of bytes before and after + * the current cursor index (excluding the preedit text) to delete. + * + * If any preedit text is present, it is replaced with the cursor for the + * purpose of this event. In effect before_length is counted from the + * beginning of preedit text, and after_length from its end (see commit + * event sequence). + * + * Values set with this event are double-buffered. They must be applied + * and reset to initial on the next zwp_input_method_v2.commit request. + * + * The initial values of both before_length and after_length are 0. + */ +static inline void +zwp_input_method_v2_delete_surrounding_text(struct zwp_input_method_v2 *zwp_input_method_v2, uint32_t before_length, uint32_t after_length) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_v2, + ZWP_INPUT_METHOD_V2_DELETE_SURROUNDING_TEXT, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2), 0, before_length, after_length); +} + +/** + * @ingroup iface_zwp_input_method_v2 + * + * Apply state changes from commit_string, set_preedit_string and + * delete_surrounding_text requests. + * + * The state relating to these events is double-buffered, and each one + * modifies the pending state. This request replaces the current state + * with the pending state. + * + * The connected text input is expected to proceed by evaluating the + * changes in the following order: + * + * 1. Replace existing preedit string with the cursor. + * 2. Delete requested surrounding text. + * 3. Insert commit string with the cursor at its end. + * 4. Calculate surrounding text to send. + * 5. Insert new preedit text in cursor position. + * 6. Place cursor inside preedit text. + * + * The serial number reflects the last state of the zwp_input_method_v2 + * object known to the client. The value of the serial argument must be + * equal to the number of done events already issued by that object. When + * the compositor receives a commit request with a serial different than + * the number of past done events, it must proceed as normal, except it + * should not change the current state of the zwp_input_method_v2 object. + */ +static inline void +zwp_input_method_v2_commit(struct zwp_input_method_v2 *zwp_input_method_v2, uint32_t serial) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_v2, + ZWP_INPUT_METHOD_V2_COMMIT, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2), 0, serial); +} + +/** + * @ingroup iface_zwp_input_method_v2 + * + * Creates a new zwp_input_popup_surface_v2 object wrapping a given + * surface. + * + * The surface gets assigned the "input_popup" role. If the surface + * already has an assigned role, the compositor must issue a protocol + * error. + */ +static inline struct zwp_input_popup_surface_v2 * +zwp_input_method_v2_get_input_popup_surface(struct zwp_input_method_v2 *zwp_input_method_v2, struct wl_surface *surface) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_v2, + ZWP_INPUT_METHOD_V2_GET_INPUT_POPUP_SURFACE, &zwp_input_popup_surface_v2_interface, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2), 0, NULL, surface); + + return (struct zwp_input_popup_surface_v2 *) id; +} + +/** + * @ingroup iface_zwp_input_method_v2 + * + * Allow an input method to receive hardware keyboard input and process + * key events to generate text events (with pre-edit) over the wire. This + * allows input methods which compose multiple key events for inputting + * text like it is done for CJK languages. + * + * The compositor should send all keyboard events on the seat to the grab + * holder via the returned wl_keyboard object. Nevertheless, the + * compositor may decide not to forward any particular event. The + * compositor must not further process any event after it has been + * forwarded to the grab holder. + * + * Releasing the resulting wl_keyboard object releases the grab. + */ +static inline struct zwp_input_method_keyboard_grab_v2 * +zwp_input_method_v2_grab_keyboard(struct zwp_input_method_v2 *zwp_input_method_v2) +{ + struct wl_proxy *keyboard; + + keyboard = wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_v2, + ZWP_INPUT_METHOD_V2_GRAB_KEYBOARD, &zwp_input_method_keyboard_grab_v2_interface, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2), 0, NULL); + + return (struct zwp_input_method_keyboard_grab_v2 *) keyboard; +} + +/** + * @ingroup iface_zwp_input_method_v2 + * + * Destroys the zwp_text_input_v2 object and any associated child + * objects, i.e. zwp_input_popup_surface_v2 and + * zwp_input_method_keyboard_grab_v2. + */ +static inline void +zwp_input_method_v2_destroy(struct zwp_input_method_v2 *zwp_input_method_v2) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_v2, + ZWP_INPUT_METHOD_V2_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_zwp_input_popup_surface_v2 + * @struct zwp_input_popup_surface_v2_listener + */ +struct zwp_input_popup_surface_v2_listener { + /** + * set text input area position + * + * Notify about the position of the area of the text input + * expressed as a rectangle in surface local coordinates. + * + * This is a hint to the input method telling it the relative + * position of the text being entered. + */ + void (*text_input_rectangle)(void *data, + struct zwp_input_popup_surface_v2 *zwp_input_popup_surface_v2, + int32_t x, + int32_t y, + int32_t width, + int32_t height); +}; + +/** + * @ingroup iface_zwp_input_popup_surface_v2 + */ +static inline int +zwp_input_popup_surface_v2_add_listener(struct zwp_input_popup_surface_v2 *zwp_input_popup_surface_v2, + const struct zwp_input_popup_surface_v2_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) zwp_input_popup_surface_v2, + (void (**)(void)) listener, data); +} + +#define ZWP_INPUT_POPUP_SURFACE_V2_DESTROY 0 + +/** + * @ingroup iface_zwp_input_popup_surface_v2 + */ +#define ZWP_INPUT_POPUP_SURFACE_V2_TEXT_INPUT_RECTANGLE_SINCE_VERSION 1 + +/** + * @ingroup iface_zwp_input_popup_surface_v2 + */ +#define ZWP_INPUT_POPUP_SURFACE_V2_DESTROY_SINCE_VERSION 1 + +/** @ingroup iface_zwp_input_popup_surface_v2 */ +static inline void +zwp_input_popup_surface_v2_set_user_data(struct zwp_input_popup_surface_v2 *zwp_input_popup_surface_v2, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwp_input_popup_surface_v2, user_data); +} + +/** @ingroup iface_zwp_input_popup_surface_v2 */ +static inline void * +zwp_input_popup_surface_v2_get_user_data(struct zwp_input_popup_surface_v2 *zwp_input_popup_surface_v2) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwp_input_popup_surface_v2); +} + +static inline uint32_t +zwp_input_popup_surface_v2_get_version(struct zwp_input_popup_surface_v2 *zwp_input_popup_surface_v2) +{ + return wl_proxy_get_version((struct wl_proxy *) zwp_input_popup_surface_v2); +} + +/** + * @ingroup iface_zwp_input_popup_surface_v2 + */ +static inline void +zwp_input_popup_surface_v2_destroy(struct zwp_input_popup_surface_v2 *zwp_input_popup_surface_v2) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_popup_surface_v2, + ZWP_INPUT_POPUP_SURFACE_V2_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_popup_surface_v2), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_zwp_input_method_keyboard_grab_v2 + * @struct zwp_input_method_keyboard_grab_v2_listener + */ +struct zwp_input_method_keyboard_grab_v2_listener { + /** + * keyboard mapping + * + * This event provides a file descriptor to the client which can + * be memory-mapped to provide a keyboard mapping description. + * @param format keymap format + * @param fd keymap file descriptor + * @param size keymap size, in bytes + */ + void (*keymap)(void *data, + struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2, + uint32_t format, + int32_t fd, + uint32_t size); + /** + * key event + * + * A key was pressed or released. The time argument is a + * timestamp with millisecond granularity, with an undefined base. + * @param serial serial number of the key event + * @param time timestamp with millisecond granularity + * @param key key that produced the event + * @param state physical state of the key + */ + void (*key)(void *data, + struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2, + uint32_t serial, + uint32_t time, + uint32_t key, + uint32_t state); + /** + * modifier and group state + * + * Notifies clients that the modifier and/or group state has + * changed, and it should update its local state. + * @param serial serial number of the modifiers event + * @param mods_depressed depressed modifiers + * @param mods_latched latched modifiers + * @param mods_locked locked modifiers + * @param group keyboard layout + */ + void (*modifiers)(void *data, + struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2, + uint32_t serial, + uint32_t mods_depressed, + uint32_t mods_latched, + uint32_t mods_locked, + uint32_t group); + /** + * repeat rate and delay + * + * Informs the client about the keyboard's repeat rate and delay. + * + * This event is sent as soon as the + * zwp_input_method_keyboard_grab_v2 object has been created, and + * is guaranteed to be received by the client before any key press + * event. + * + * Negative values for either rate or delay are illegal. A rate of + * zero will disable any repeating (regardless of the value of + * delay). + * + * This event can be sent later on as well with a new value if + * necessary, so clients should continue listening for the event + * past the creation of zwp_input_method_keyboard_grab_v2. + * @param rate the rate of repeating keys in characters per second + * @param delay delay in milliseconds since key down until repeating starts + */ + void (*repeat_info)(void *data, + struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2, + int32_t rate, + int32_t delay); +}; + +/** + * @ingroup iface_zwp_input_method_keyboard_grab_v2 + */ +static inline int +zwp_input_method_keyboard_grab_v2_add_listener(struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2, + const struct zwp_input_method_keyboard_grab_v2_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) zwp_input_method_keyboard_grab_v2, + (void (**)(void)) listener, data); +} + +#define ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_RELEASE 0 + +/** + * @ingroup iface_zwp_input_method_keyboard_grab_v2 + */ +#define ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_KEYMAP_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_keyboard_grab_v2 + */ +#define ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_KEY_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_keyboard_grab_v2 + */ +#define ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_MODIFIERS_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_keyboard_grab_v2 + */ +#define ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_REPEAT_INFO_SINCE_VERSION 1 + +/** + * @ingroup iface_zwp_input_method_keyboard_grab_v2 + */ +#define ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_RELEASE_SINCE_VERSION 1 + +/** @ingroup iface_zwp_input_method_keyboard_grab_v2 */ +static inline void +zwp_input_method_keyboard_grab_v2_set_user_data(struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwp_input_method_keyboard_grab_v2, user_data); +} + +/** @ingroup iface_zwp_input_method_keyboard_grab_v2 */ +static inline void * +zwp_input_method_keyboard_grab_v2_get_user_data(struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwp_input_method_keyboard_grab_v2); +} + +static inline uint32_t +zwp_input_method_keyboard_grab_v2_get_version(struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2) +{ + return wl_proxy_get_version((struct wl_proxy *) zwp_input_method_keyboard_grab_v2); +} + +/** @ingroup iface_zwp_input_method_keyboard_grab_v2 */ +static inline void +zwp_input_method_keyboard_grab_v2_destroy(struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2) +{ + wl_proxy_destroy((struct wl_proxy *) zwp_input_method_keyboard_grab_v2); +} + +/** + * @ingroup iface_zwp_input_method_keyboard_grab_v2 + */ +static inline void +zwp_input_method_keyboard_grab_v2_release(struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_keyboard_grab_v2, + ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_keyboard_grab_v2), WL_MARSHAL_FLAG_DESTROY); +} + +#define ZWP_INPUT_METHOD_MANAGER_V2_GET_INPUT_METHOD 0 +#define ZWP_INPUT_METHOD_MANAGER_V2_DESTROY 1 + + +/** + * @ingroup iface_zwp_input_method_manager_v2 + */ +#define ZWP_INPUT_METHOD_MANAGER_V2_GET_INPUT_METHOD_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_input_method_manager_v2 + */ +#define ZWP_INPUT_METHOD_MANAGER_V2_DESTROY_SINCE_VERSION 1 + +/** @ingroup iface_zwp_input_method_manager_v2 */ +static inline void +zwp_input_method_manager_v2_set_user_data(struct zwp_input_method_manager_v2 *zwp_input_method_manager_v2, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwp_input_method_manager_v2, user_data); +} + +/** @ingroup iface_zwp_input_method_manager_v2 */ +static inline void * +zwp_input_method_manager_v2_get_user_data(struct zwp_input_method_manager_v2 *zwp_input_method_manager_v2) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwp_input_method_manager_v2); +} + +static inline uint32_t +zwp_input_method_manager_v2_get_version(struct zwp_input_method_manager_v2 *zwp_input_method_manager_v2) +{ + return wl_proxy_get_version((struct wl_proxy *) zwp_input_method_manager_v2); +} + +/** + * @ingroup iface_zwp_input_method_manager_v2 + * + * Request a new input zwp_input_method_v2 object associated with a given + * seat. + */ +static inline struct zwp_input_method_v2 * +zwp_input_method_manager_v2_get_input_method(struct zwp_input_method_manager_v2 *zwp_input_method_manager_v2, struct wl_seat *seat) +{ + struct wl_proxy *input_method; + + input_method = wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_manager_v2, + ZWP_INPUT_METHOD_MANAGER_V2_GET_INPUT_METHOD, &zwp_input_method_v2_interface, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_manager_v2), 0, seat, NULL); + + return (struct zwp_input_method_v2 *) input_method; +} + +/** + * @ingroup iface_zwp_input_method_manager_v2 + * + * Destroys the zwp_input_method_manager_v2 object. + * + * The zwp_input_method_v2 objects originating from it remain valid. + */ +static inline void +zwp_input_method_manager_v2_destroy(struct zwp_input_method_manager_v2 *zwp_input_method_manager_v2) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_manager_v2, + ZWP_INPUT_METHOD_MANAGER_V2_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_manager_v2), WL_MARSHAL_FLAG_DESTROY); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/input-method-unstable-v2-protocol.c b/input-method-unstable-v2-protocol.c new file mode 100644 index 0000000..9e49406 --- /dev/null +++ b/input-method-unstable-v2-protocol.c @@ -0,0 +1,132 @@ +/* Generated by wayland-scanner 1.21.0 */ + +/* + * Copyright © 2008-2011 Kristian Høgsberg + * Copyright © 2010-2011 Intel Corporation + * Copyright © 2012-2013 Collabora, Ltd. + * Copyright © 2012, 2013 Intel Corporation + * Copyright © 2015, 2016 Jan Arne Petersen + * Copyright © 2017, 2018 Red Hat, Inc. + * Copyright © 2018 Purism SPC + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface wl_seat_interface; +extern const struct wl_interface wl_surface_interface; +extern const struct wl_interface zwp_input_method_keyboard_grab_v2_interface; +extern const struct wl_interface zwp_input_method_v2_interface; +extern const struct wl_interface zwp_input_popup_surface_v2_interface; + +static const struct wl_interface *input_method_unstable_v2_types[] = { + NULL, + NULL, + NULL, + NULL, + NULL, + &zwp_input_popup_surface_v2_interface, + &wl_surface_interface, + &zwp_input_method_keyboard_grab_v2_interface, + &wl_seat_interface, + &zwp_input_method_v2_interface, +}; + +static const struct wl_message zwp_input_method_v2_requests[] = { + { "commit_string", "s", input_method_unstable_v2_types + 0 }, + { "set_preedit_string", "sii", input_method_unstable_v2_types + 0 }, + { "delete_surrounding_text", "uu", input_method_unstable_v2_types + 0 }, + { "commit", "u", input_method_unstable_v2_types + 0 }, + { "get_input_popup_surface", "no", input_method_unstable_v2_types + 5 }, + { "grab_keyboard", "n", input_method_unstable_v2_types + 7 }, + { "destroy", "", input_method_unstable_v2_types + 0 }, +}; + +static const struct wl_message zwp_input_method_v2_events[] = { + { "activate", "", input_method_unstable_v2_types + 0 }, + { "deactivate", "", input_method_unstable_v2_types + 0 }, + { "surrounding_text", "suu", input_method_unstable_v2_types + 0 }, + { "text_change_cause", "u", input_method_unstable_v2_types + 0 }, + { "content_type", "uu", input_method_unstable_v2_types + 0 }, + { "done", "", input_method_unstable_v2_types + 0 }, + { "unavailable", "", input_method_unstable_v2_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zwp_input_method_v2_interface = { + "zwp_input_method_v2", 1, + 7, zwp_input_method_v2_requests, + 7, zwp_input_method_v2_events, +}; + +static const struct wl_message zwp_input_popup_surface_v2_requests[] = { + { "destroy", "", input_method_unstable_v2_types + 0 }, +}; + +static const struct wl_message zwp_input_popup_surface_v2_events[] = { + { "text_input_rectangle", "iiii", input_method_unstable_v2_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zwp_input_popup_surface_v2_interface = { + "zwp_input_popup_surface_v2", 1, + 1, zwp_input_popup_surface_v2_requests, + 1, zwp_input_popup_surface_v2_events, +}; + +static const struct wl_message zwp_input_method_keyboard_grab_v2_requests[] = { + { "release", "", input_method_unstable_v2_types + 0 }, +}; + +static const struct wl_message zwp_input_method_keyboard_grab_v2_events[] = { + { "keymap", "uhu", input_method_unstable_v2_types + 0 }, + { "key", "uuuu", input_method_unstable_v2_types + 0 }, + { "modifiers", "uuuuu", input_method_unstable_v2_types + 0 }, + { "repeat_info", "ii", input_method_unstable_v2_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zwp_input_method_keyboard_grab_v2_interface = { + "zwp_input_method_keyboard_grab_v2", 1, + 1, zwp_input_method_keyboard_grab_v2_requests, + 4, zwp_input_method_keyboard_grab_v2_events, +}; + +static const struct wl_message zwp_input_method_manager_v2_requests[] = { + { "get_input_method", "on", input_method_unstable_v2_types + 8 }, + { "destroy", "", input_method_unstable_v2_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zwp_input_method_manager_v2_interface = { + "zwp_input_method_manager_v2", 1, + 2, zwp_input_method_manager_v2_requests, + 0, NULL, +}; + diff --git a/main.c b/main.c index 006bbc9..62d4e91 100644 --- a/main.c +++ b/main.c @@ -70,6 +70,7 @@ threadmain(int argc, char **argv) proccreate(drawthread, nil, 16384); proccreate(srvthread, nil, 16384); proccreate(ibusthread, nil, 32768); + proccreate(waylandthread, nil, 32768); threadcreate(dictthread, nil, 16384); threadcreate(imthread, nil, 16384); diff --git a/virtual-keyboard-unstable-v1-client-protocol.h b/virtual-keyboard-unstable-v1-client-protocol.h new file mode 100644 index 0000000..81cac0b --- /dev/null +++ b/virtual-keyboard-unstable-v1-client-protocol.h @@ -0,0 +1,280 @@ +/* Generated by wayland-scanner 1.23.1 */ + +#ifndef VIRTUAL_KEYBOARD_UNSTABLE_V1_CLIENT_PROTOCOL_H +#define VIRTUAL_KEYBOARD_UNSTABLE_V1_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_virtual_keyboard_unstable_v1 The virtual_keyboard_unstable_v1 protocol + * @section page_ifaces_virtual_keyboard_unstable_v1 Interfaces + * - @subpage page_iface_zwp_virtual_keyboard_v1 - virtual keyboard + * - @subpage page_iface_zwp_virtual_keyboard_manager_v1 - virtual keyboard manager + * @section page_copyright_virtual_keyboard_unstable_v1 Copyright + *
+ *
+ * Copyright © 2008-2011  Kristian Høgsberg
+ * Copyright © 2010-2013  Intel Corporation
+ * Copyright © 2012-2013  Collabora, Ltd.
+ * Copyright © 2018       Purism SPC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ */ +struct wl_seat; +struct zwp_virtual_keyboard_manager_v1; +struct zwp_virtual_keyboard_v1; + +#ifndef ZWP_VIRTUAL_KEYBOARD_V1_INTERFACE +#define ZWP_VIRTUAL_KEYBOARD_V1_INTERFACE +/** + * @page page_iface_zwp_virtual_keyboard_v1 zwp_virtual_keyboard_v1 + * @section page_iface_zwp_virtual_keyboard_v1_desc Description + * + * The virtual keyboard provides an application with requests which emulate + * the behaviour of a physical keyboard. + * + * This interface can be used by clients on its own to provide raw input + * events, or it can accompany the input method protocol. + * @section page_iface_zwp_virtual_keyboard_v1_api API + * See @ref iface_zwp_virtual_keyboard_v1. + */ +/** + * @defgroup iface_zwp_virtual_keyboard_v1 The zwp_virtual_keyboard_v1 interface + * + * The virtual keyboard provides an application with requests which emulate + * the behaviour of a physical keyboard. + * + * This interface can be used by clients on its own to provide raw input + * events, or it can accompany the input method protocol. + */ +extern const struct wl_interface zwp_virtual_keyboard_v1_interface; +#endif +#ifndef ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_INTERFACE +#define ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_INTERFACE +/** + * @page page_iface_zwp_virtual_keyboard_manager_v1 zwp_virtual_keyboard_manager_v1 + * @section page_iface_zwp_virtual_keyboard_manager_v1_desc Description + * + * A virtual keyboard manager allows an application to provide keyboard + * input events as if they came from a physical keyboard. + * @section page_iface_zwp_virtual_keyboard_manager_v1_api API + * See @ref iface_zwp_virtual_keyboard_manager_v1. + */ +/** + * @defgroup iface_zwp_virtual_keyboard_manager_v1 The zwp_virtual_keyboard_manager_v1 interface + * + * A virtual keyboard manager allows an application to provide keyboard + * input events as if they came from a physical keyboard. + */ +extern const struct wl_interface zwp_virtual_keyboard_manager_v1_interface; +#endif + +#ifndef ZWP_VIRTUAL_KEYBOARD_V1_ERROR_ENUM +#define ZWP_VIRTUAL_KEYBOARD_V1_ERROR_ENUM +enum zwp_virtual_keyboard_v1_error { + /** + * No keymap was set + */ + ZWP_VIRTUAL_KEYBOARD_V1_ERROR_NO_KEYMAP = 0, +}; +#endif /* ZWP_VIRTUAL_KEYBOARD_V1_ERROR_ENUM */ + +#define ZWP_VIRTUAL_KEYBOARD_V1_KEYMAP 0 +#define ZWP_VIRTUAL_KEYBOARD_V1_KEY 1 +#define ZWP_VIRTUAL_KEYBOARD_V1_MODIFIERS 2 +#define ZWP_VIRTUAL_KEYBOARD_V1_DESTROY 3 + + +/** + * @ingroup iface_zwp_virtual_keyboard_v1 + */ +#define ZWP_VIRTUAL_KEYBOARD_V1_KEYMAP_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_virtual_keyboard_v1 + */ +#define ZWP_VIRTUAL_KEYBOARD_V1_KEY_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_virtual_keyboard_v1 + */ +#define ZWP_VIRTUAL_KEYBOARD_V1_MODIFIERS_SINCE_VERSION 1 +/** + * @ingroup iface_zwp_virtual_keyboard_v1 + */ +#define ZWP_VIRTUAL_KEYBOARD_V1_DESTROY_SINCE_VERSION 1 + +/** @ingroup iface_zwp_virtual_keyboard_v1 */ +static inline void +zwp_virtual_keyboard_v1_set_user_data(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwp_virtual_keyboard_v1, user_data); +} + +/** @ingroup iface_zwp_virtual_keyboard_v1 */ +static inline void * +zwp_virtual_keyboard_v1_get_user_data(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwp_virtual_keyboard_v1); +} + +static inline uint32_t +zwp_virtual_keyboard_v1_get_version(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_v1); +} + +/** + * @ingroup iface_zwp_virtual_keyboard_v1 + * + * Provide a file descriptor to the compositor which can be + * memory-mapped to provide a keyboard mapping description. + * + * Format carries a value from the keymap_format enumeration. + */ +static inline void +zwp_virtual_keyboard_v1_keymap(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1, uint32_t format, int32_t fd, uint32_t size) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_virtual_keyboard_v1, + ZWP_VIRTUAL_KEYBOARD_V1_KEYMAP, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_v1), 0, format, fd, size); +} + +/** + * @ingroup iface_zwp_virtual_keyboard_v1 + * + * A key was pressed or released. + * The time argument is a timestamp with millisecond granularity, with an + * undefined base. All requests regarding a single object must share the + * same clock. + * + * Keymap must be set before issuing this request. + * + * State carries a value from the key_state enumeration. + */ +static inline void +zwp_virtual_keyboard_v1_key(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1, uint32_t time, uint32_t key, uint32_t state) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_virtual_keyboard_v1, + ZWP_VIRTUAL_KEYBOARD_V1_KEY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_v1), 0, time, key, state); +} + +/** + * @ingroup iface_zwp_virtual_keyboard_v1 + * + * Notifies the compositor that the modifier and/or group state has + * changed, and it should update state. + * + * The client should use wl_keyboard.modifiers event to synchronize its + * internal state with seat state. + * + * Keymap must be set before issuing this request. + */ +static inline void +zwp_virtual_keyboard_v1_modifiers(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_virtual_keyboard_v1, + ZWP_VIRTUAL_KEYBOARD_V1_MODIFIERS, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_v1), 0, mods_depressed, mods_latched, mods_locked, group); +} + +/** + * @ingroup iface_zwp_virtual_keyboard_v1 + */ +static inline void +zwp_virtual_keyboard_v1_destroy(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zwp_virtual_keyboard_v1, + ZWP_VIRTUAL_KEYBOARD_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_v1), WL_MARSHAL_FLAG_DESTROY); +} + +#ifndef ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_ERROR_ENUM +#define ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_ERROR_ENUM +enum zwp_virtual_keyboard_manager_v1_error { + /** + * client not authorized to use the interface + */ + ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_ERROR_UNAUTHORIZED = 0, +}; +#endif /* ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_ERROR_ENUM */ + +#define ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_CREATE_VIRTUAL_KEYBOARD 0 + + +/** + * @ingroup iface_zwp_virtual_keyboard_manager_v1 + */ +#define ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_CREATE_VIRTUAL_KEYBOARD_SINCE_VERSION 1 + +/** @ingroup iface_zwp_virtual_keyboard_manager_v1 */ +static inline void +zwp_virtual_keyboard_manager_v1_set_user_data(struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zwp_virtual_keyboard_manager_v1, user_data); +} + +/** @ingroup iface_zwp_virtual_keyboard_manager_v1 */ +static inline void * +zwp_virtual_keyboard_manager_v1_get_user_data(struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zwp_virtual_keyboard_manager_v1); +} + +static inline uint32_t +zwp_virtual_keyboard_manager_v1_get_version(struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_manager_v1); +} + +/** @ingroup iface_zwp_virtual_keyboard_manager_v1 */ +static inline void +zwp_virtual_keyboard_manager_v1_destroy(struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1) +{ + wl_proxy_destroy((struct wl_proxy *) zwp_virtual_keyboard_manager_v1); +} + +/** + * @ingroup iface_zwp_virtual_keyboard_manager_v1 + * + * Creates a new virtual keyboard associated to a seat. + * + * If the compositor enables a keyboard to perform arbitrary actions, it + * should present an error when an untrusted client requests a new + * keyboard. + */ +static inline struct zwp_virtual_keyboard_v1 * +zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1, struct wl_seat *seat) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_virtual_keyboard_manager_v1, + ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_CREATE_VIRTUAL_KEYBOARD, &zwp_virtual_keyboard_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_manager_v1), 0, seat, NULL); + + return (struct zwp_virtual_keyboard_v1 *) id; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/virtual-keyboard-unstable-v1-protocol.c b/virtual-keyboard-unstable-v1-protocol.c new file mode 100644 index 0000000..699b27a --- /dev/null +++ b/virtual-keyboard-unstable-v1-protocol.c @@ -0,0 +1,78 @@ +/* Generated by wayland-scanner 1.23.1 */ + +/* + * Copyright © 2008-2011 Kristian Høgsberg + * Copyright © 2010-2013 Intel Corporation + * Copyright © 2012-2013 Collabora, Ltd. + * Copyright © 2018 Purism SPC + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include "wayland-util.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif + +#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) +#define WL_PRIVATE __attribute__ ((visibility("hidden"))) +#else +#define WL_PRIVATE +#endif + +extern const struct wl_interface wl_seat_interface; +extern const struct wl_interface zwp_virtual_keyboard_v1_interface; + +static const struct wl_interface *virtual_keyboard_unstable_v1_types[] = { + NULL, + NULL, + NULL, + NULL, + &wl_seat_interface, + &zwp_virtual_keyboard_v1_interface, +}; + +static const struct wl_message zwp_virtual_keyboard_v1_requests[] = { + { "keymap", "uhu", virtual_keyboard_unstable_v1_types + 0 }, + { "key", "uuu", virtual_keyboard_unstable_v1_types + 0 }, + { "modifiers", "uuuu", virtual_keyboard_unstable_v1_types + 0 }, + { "destroy", "", virtual_keyboard_unstable_v1_types + 0 }, +}; + +WL_PRIVATE const struct wl_interface zwp_virtual_keyboard_v1_interface = { + "zwp_virtual_keyboard_v1", 1, + 4, zwp_virtual_keyboard_v1_requests, + 0, NULL, +}; + +static const struct wl_message zwp_virtual_keyboard_manager_v1_requests[] = { + { "create_virtual_keyboard", "on", virtual_keyboard_unstable_v1_types + 4 }, +}; + +WL_PRIVATE const struct wl_interface zwp_virtual_keyboard_manager_v1_interface = { + "zwp_virtual_keyboard_manager_v1", 1, + 1, zwp_virtual_keyboard_manager_v1_requests, + 0, NULL, +}; + diff --git a/wayland.c b/wayland.c new file mode 100644 index 0000000..dbd2dee --- /dev/null +++ b/wayland.c @@ -0,0 +1,350 @@ +#include "dat.h" +#include "fn.h" + +#include +#include +#include +#include +#include +#include +#include +#include "input-method-unstable-v2-client-protocol.h" +#include "virtual-keyboard-unstable-v1-client-protocol.h" + +static struct wl_display *dpy; +static struct wl_seat *seat; +static struct zwp_input_method_manager_v2 *immgr; +static struct zwp_virtual_keyboard_manager_v1 *vkmgr; +static struct zwp_input_method_v2 *im; +static struct zwp_input_method_keyboard_grab_v2 *grab; +static struct zwp_virtual_keyboard_v1 *vk; +static struct xkb_context *xkb; +static struct xkb_keymap *keymap; +static struct xkb_state *xkbst; +static int active; +static int pending; +static u32int imserial; + +static void +sendkey(u32int ks, u32int mod, char *com, int csz, char *pre, int psz, + int *eaten) +{ + Keyreq kr; + int p[2]; + uchar hdr[2]; + uchar pl; + int n; + + *eaten = 0; + com[0] = '\0'; + pre[0] = '\0'; + if(pipe(p) < 0) + return; + kr.fd = p[1]; + kr.ks = ks; + kr.mod = mod; + kr.want = 1; + chansend(keyc, &kr); + if(read(p[0], hdr, 2) != 2) + goto out; + *eaten = hdr[0]; + n = hdr[1]; + if(n > 0 && n < csz){ + if(read(p[0], com, n) != n) + goto out; + com[n] = '\0'; + } + if(read(p[0], &pl, 1) != 1) + goto out; + if(pl > 0 && pl < psz){ + if(read(p[0], pre, pl) != pl) + goto out; + pre[pl] = '\0'; + } +out: + close(p[0]); + close(p[1]); +} + +static void +sendreset(void) +{ + char com[64], pre[256]; + int eaten; + + sendkey(Kesc, 0, com, sizeof(com), pre, sizeof(pre), &eaten); +} + +static u32int +mget(void) +{ + u32int m; + + m = 0; + if(xkbst == nil) + return 0; + if(xkb_state_mod_name_is_active(xkbst, + XKB_MOD_NAME_SHIFT, XKB_STATE_MODS_EFFECTIVE) > 0) + m |= Mshift; + if(xkb_state_mod_name_is_active(xkbst, + XKB_MOD_NAME_CTRL, XKB_STATE_MODS_EFFECTIVE) > 0) + m |= Mctrl; + if(xkb_state_mod_name_is_active(xkbst, + XKB_MOD_NAME_ALT, XKB_STATE_MODS_EFFECTIVE) > 0) + m |= Malt; + if(xkb_state_mod_name_is_active(xkbst, + XKB_MOD_NAME_LOGO, XKB_STATE_MODS_EFFECTIVE) > 0) + m |= Msuper; + return m; +} + +static void +kpress(uint32_t time, uint32_t keycode, uint32_t state) +{ + xkb_keysym_t ks; + u32int k, mod; + char com[64], pre[256]; + int eaten, plen; + + if(state != WL_KEYBOARD_KEY_STATE_PRESSED || xkbst == nil){ + zwp_virtual_keyboard_v1_key(vk, time, keycode, state); + return; + } + ks = xkb_state_key_get_one_sym(xkbst, keycode + 8); + k = ks >= 0xff00 ? Kspec + (ks - 0xff00) : xkb_keysym_to_utf32(ks); + if(k == 0){ + zwp_virtual_keyboard_v1_key(vk, time, keycode, state); + return; + } + mod = mget(); + sendkey(k, mod, com, sizeof(com), pre, sizeof(pre), &eaten); + if(com[0] != '\0') + zwp_input_method_v2_commit_string(im, com); + plen = strlen(pre); + zwp_input_method_v2_set_preedit_string(im, pre, plen, plen); + zwp_input_method_v2_commit(im, imserial); + if(!eaten) + zwp_virtual_keyboard_v1_key(vk, time, keycode, state); +} + +static void +kg_keymap(void *data, struct zwp_input_method_keyboard_grab_v2 *g, + uint32_t format, int32_t fd, uint32_t size) +{ + char *s; + + (void)data; + (void)g; + if(format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1){ + close(fd); + return; + } + s = mmap(nil, size, PROT_READ, MAP_PRIVATE, fd, 0); + if(s != MAP_FAILED){ + if(xkbst != nil){ + xkb_state_unref(xkbst); + xkbst = nil; + } + if(keymap != nil) + xkb_keymap_unref(keymap); + keymap = xkb_keymap_new_from_string(xkb, s, + XKB_KEYMAP_FORMAT_TEXT_V1, + XKB_KEYMAP_COMPILE_NO_FLAGS); + if(keymap != nil) + xkbst = xkb_state_new(keymap); + munmap(s, size); + } + zwp_virtual_keyboard_v1_keymap(vk, format, fd, size); +} + +static void +kg_key(void *data, struct zwp_input_method_keyboard_grab_v2 *g, + uint32_t serial, uint32_t time, uint32_t key, uint32_t state) +{ + (void)data; + (void)g; + (void)serial; + kpress(time, key, state); +} + +static void +kg_mods(void *data, struct zwp_input_method_keyboard_grab_v2 *g, + uint32_t serial, uint32_t dep, uint32_t lat, uint32_t lck, + uint32_t group) +{ + (void)data; + (void)g; + (void)serial; + if(xkbst != nil) + xkb_state_update_mask(xkbst, dep, lat, lck, 0, 0, group); + zwp_virtual_keyboard_v1_modifiers(vk, dep, lat, lck, group); +} + +static void +kg_repeat(void *data, struct zwp_input_method_keyboard_grab_v2 *g, + int32_t rate, int32_t delay) +{ + (void)data; + (void)g; + (void)rate; + (void)delay; +} + +static const struct zwp_input_method_keyboard_grab_v2_listener +grab_listener = { + .keymap = kg_keymap, + .key = kg_key, + .modifiers = kg_mods, + .repeat_info = kg_repeat, +}; + +static void +im_activate(void *data, struct zwp_input_method_v2 *m) +{ + (void)data; + (void)m; + pending = 1; +} + +static void +im_deactivate(void *data, struct zwp_input_method_v2 *m) +{ + (void)data; + (void)m; + pending = 0; + if(active){ + active = 0; + sendreset(); + if(grab != nil){ + zwp_input_method_keyboard_grab_v2_release(grab); + grab = nil; + } + } +} + +static void +im_surrounding(void *data, struct zwp_input_method_v2 *m, + const char *text, uint32_t cursor, uint32_t anchor) +{ + (void)data; + (void)m; + (void)text; + (void)cursor; + (void)anchor; +} + +static void +im_textchange(void *data, struct zwp_input_method_v2 *m, uint32_t cause) +{ + (void)data; + (void)m; + (void)cause; +} + +static void +im_content(void *data, struct zwp_input_method_v2 *m, + uint32_t hint, uint32_t purpose) +{ + (void)data; + (void)m; + (void)hint; + (void)purpose; +} + +static void +im_done(void *data, struct zwp_input_method_v2 *m) +{ + (void)data; + (void)m; + imserial++; + if(pending && !active){ + active = 1; + grab = zwp_input_method_v2_grab_keyboard(im); + if(grab != nil) + zwp_input_method_keyboard_grab_v2_add_listener(grab, + &grab_listener, nil); + } +} + +static void +im_unavail(void *data, struct zwp_input_method_v2 *m) +{ + (void)data; + (void)m; + fprint(2, "strans: wayland: input-method unavailable\n"); +} + +static const struct zwp_input_method_v2_listener im_listener = { + .activate = im_activate, + .deactivate = im_deactivate, + .surrounding_text = im_surrounding, + .text_change_cause = im_textchange, + .content_type = im_content, + .done = im_done, + .unavailable = im_unavail, +}; + +static void +reg_global(void *data, struct wl_registry *r, uint32_t name, + const char *iface, uint32_t version) +{ + (void)data; + (void)version; + if(strcmp(iface, wl_seat_interface.name) == 0) + seat = wl_registry_bind(r, name, &wl_seat_interface, 5); + else if(strcmp(iface, zwp_input_method_manager_v2_interface.name) == 0) + immgr = wl_registry_bind(r, name, + &zwp_input_method_manager_v2_interface, 1); + else if(strcmp(iface, + zwp_virtual_keyboard_manager_v1_interface.name) == 0) + vkmgr = wl_registry_bind(r, name, + &zwp_virtual_keyboard_manager_v1_interface, 1); +} + +static void +reg_remove(void *data, struct wl_registry *r, uint32_t name) +{ + (void)data; + (void)r; + (void)name; +} + +static const struct wl_registry_listener reg_listener = { + .global = reg_global, + .global_remove = reg_remove, +}; + +void +waylandthread(void *_) +{ + struct wl_registry *reg; + + (void)_; + threadsetname("wayland"); + dpy = wl_display_connect(nil); + if(dpy == nil){ + fprint(2, "strans: wayland: cannot connect to display\n"); + return; + } + xkb = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + if(xkb == nil){ + wl_display_disconnect(dpy); + dpy = nil; + return; + } + reg = wl_display_get_registry(dpy); + wl_registry_add_listener(reg, ®_listener, nil); + wl_display_roundtrip(dpy); + if(seat == nil || immgr == nil || vkmgr == nil){ + fprint(2, + "strans: wayland: compositor missing input-method-v2\n"); + wl_display_disconnect(dpy); + dpy = nil; + return; + } + im = zwp_input_method_manager_v2_get_input_method(immgr, seat); + zwp_input_method_v2_add_listener(im, &im_listener, nil); + vk = zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(vkmgr, seat); + while(wl_display_dispatch(dpy) != -1) + ; +}