forked from enlightenment/enlightenment
Add module "wl_text_input" for supporting *wl_text_input* and *wl_input_method* protocol in wayland.
Summary: this patch allow to use virtual keyboard such as weston-keyboard. it was tested in wayland verion 1.6. Test Plan: <prerequisite> - Configure with --enable-wl-text-input - edit configuration file, e.cfg to enable module wl_text_input. 1. run enlightenment as a wayland display server. 2. run weston-keyboard. 3. run weston-editor. Reviewers: raster, Sergeant_Whitespace, devilhorns, zmike Reviewed By: zmike Subscribers: ManMower, Sergeant_Whitespace, cedric, jihoon Differential Revision: https://phab.enlightenment.org/D2275
This commit is contained in:
parent
ac56ba57d1
commit
26d352f219
11
configure.ac
11
configure.ac
|
@ -845,6 +845,16 @@ define([CHECK_MODULE_XWAYLAND],
|
|||
])
|
||||
AM_CONDITIONAL([HAVE_XWAYLAND], [test "x${HAVE_XWAYLAND}" != "xno"])
|
||||
|
||||
define([CHECK_MODULE_WL_TEXT_INPUT],
|
||||
[
|
||||
if test "x${have_wayland}" = "xyes"; then
|
||||
AC_E_CHECK_PKG(WL_TEXT_INPUT, [ ecore >= $efl_version eina >= $efl_version ], [WL_TEXT_INPUT=true], [WL_TEXT_INPUT=false])
|
||||
else
|
||||
WL_TEXT_INPUT=false
|
||||
fi
|
||||
])
|
||||
AM_CONDITIONAL([HAVE_WL_TEXT_INPUT], [test "x${WL_TEXT_INPUT}" = "xtrue"])
|
||||
|
||||
AC_E_OPTIONAL_MODULE([ibar], true)
|
||||
AC_E_OPTIONAL_MODULE([clock], true)
|
||||
AC_E_OPTIONAL_MODULE([pager], true)
|
||||
|
@ -899,6 +909,7 @@ AC_E_OPTIONAL_MODULE([wl_x11], $have_wayland, [CHECK_MODULE_WL_X11])
|
|||
AC_E_OPTIONAL_MODULE([wl_wl], $have_wayland, [CHECK_MODULE_WL_WL])
|
||||
#AC_E_OPTIONAL_MODULE([wl_fb], $have_wayland, [CHECK_MODULE_WL_FB])
|
||||
AC_E_OPTIONAL_MODULE([wl_drm], $have_wayland, [CHECK_MODULE_WL_DRM])
|
||||
AC_E_OPTIONAL_MODULE([wl_text_input], $have_wayland, [CHECK_MODULE_WL_TEXT_INPUT])
|
||||
AC_E_OPTIONAL_MODULE([policy_mobile], true)
|
||||
AC_E_OPTIONAL_MODULE([geolocation], true)
|
||||
AC_E_OPTIONAL_MODULE([xwayland], $have_wayland, [CHECK_MODULE_XWAYLAND])
|
||||
|
|
|
@ -178,6 +178,12 @@ struct _E_Comp_Wl_Data
|
|||
Eina_List *resources;
|
||||
uint32_t version;
|
||||
char *name;
|
||||
|
||||
struct
|
||||
{
|
||||
struct wl_global *global;
|
||||
struct wl_resource *resource;
|
||||
} im;
|
||||
} seat;
|
||||
|
||||
struct
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include "e.h"
|
||||
#include <sys/mman.h>
|
||||
|
||||
EAPI int E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = -1;
|
||||
|
||||
static void
|
||||
_e_comp_wl_input_update_seat_caps(void)
|
||||
{
|
||||
|
@ -426,6 +428,8 @@ e_comp_wl_input_init(void)
|
|||
|
||||
wl_array_init(&e_comp_wl->kbd.keys);
|
||||
|
||||
E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = ecore_event_type_new();
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,15 @@
|
|||
# ifndef E_COMP_WL_INPUT_H
|
||||
# define E_COMP_WL_INPUT_H
|
||||
|
||||
EAPI extern int E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE;
|
||||
|
||||
typedef struct _E_Event_Text_Input_Panel_Visibility_Change E_Event_Text_Input_Panel_Visibility_Change;
|
||||
|
||||
struct _E_Event_Text_Input_Panel_Visibility_Change
|
||||
{
|
||||
Eina_Bool visible;
|
||||
};
|
||||
|
||||
EINTERN Eina_Bool e_comp_wl_input_init(void);
|
||||
EINTERN void e_comp_wl_input_shutdown(void);
|
||||
EINTERN Eina_Bool e_comp_wl_input_pointer_check(struct wl_resource *res);
|
||||
|
|
|
@ -121,6 +121,8 @@ include src/modules/Makefile_wl_x11.mk
|
|||
|
||||
include src/modules/Makefile_xwayland.mk
|
||||
|
||||
include src/modules/Makefile_wl_text_input.mk
|
||||
|
||||
include src/modules/Makefile_policy_mobile.mk
|
||||
|
||||
include src/modules/Makefile_geolocation.mk
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
EXTRA_DIST += src/modules/wl_desktop_shell/module.desktop.in \
|
||||
src/modules/wl_desktop_shell/e-module-wl_desktop_shell.edj \
|
||||
src/modules/wl_desktop_shell/module.desktop.in \
|
||||
src/modules/wl_desktop_shell/e_input_method_protocol.h \
|
||||
src/modules/wl_desktop_shell/e_input_method_protocol.c \
|
||||
src/modules/wl_desktop_shell/e_desktop_shell_protocol.h \
|
||||
src/modules/wl_desktop_shell/e_desktop_shell_protocol.c
|
||||
if USE_MODULE_WL_DESKTOP_SHELL
|
||||
|
@ -18,6 +20,9 @@ src_modules_wl_desktop_shell_module_la_LDFLAGS = $(MOD_LDFLAGS)
|
|||
|
||||
src_modules_wl_desktop_shell_module_la_SOURCES = \
|
||||
src/modules/wl_desktop_shell/e_mod_main.c \
|
||||
src/modules/wl_desktop_shell/e_mod_input_panel.c \
|
||||
src/modules/wl_desktop_shell/e_input_method_protocol.c \
|
||||
src/modules/wl_desktop_shell/e_input_method_protocol.h \
|
||||
src/modules/wl_desktop_shell/e_desktop_shell_protocol.c \
|
||||
src/modules/wl_desktop_shell/e_desktop_shell_protocol.h
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
EXTRA_DIST += \
|
||||
src/modules/wl_text_input/text-protocol.h \
|
||||
src/modules/wl_text_input/text-protocol.c \
|
||||
src/modules/wl_text_input/input-method-protocol.h \
|
||||
src/modules/wl_text_input/input-method-protocol.c
|
||||
|
||||
if USE_MODULE_WL_TEXT_INPUT
|
||||
wl_text_inputdir = $(MDIR)/wl_text_input
|
||||
|
||||
wl_text_inputpkgdir = $(MDIR)/wl_text_input/$(MODULE_ARCH)
|
||||
wl_text_inputpkg_LTLIBRARIES = src/modules/wl_text_input/module.la
|
||||
|
||||
src_modules_wl_text_input_module_la_DEPENDENCIES = $(MDEPENDENCIES)
|
||||
src_modules_wl_text_input_module_la_CPPFLAGS = $(MOD_CPPFLAGS) @WAYLAND_CFLAGS@
|
||||
src_modules_wl_text_input_module_la_LIBADD = $(LIBS) @WAYLAND_LIBS@
|
||||
src_modules_wl_text_input_module_la_LDFLAGS = $(MOD_LDFLAGS)
|
||||
src_modules_wl_text_input_module_la_SOURCES = \
|
||||
src/modules/wl_text_input/e_mod_main.c \
|
||||
src/modules/wl_text_input/text-protocol.c \
|
||||
src/modules/wl_text_input/text-protocol.h \
|
||||
src/modules/wl_text_input/input-method-protocol.c \
|
||||
src/modules/wl_text_input/input-method-protocol.h
|
||||
|
||||
PHONIES += wl_text_input install-wl_text_input
|
||||
wl_text_input: $(wl_text_inputpkg_LTLIBRARIES) $(wl_text_input_DATA)
|
||||
install-wl_text_input: install-wl_text_inputDATA install-wl_text_inputpkgLTLIBRARIES
|
||||
endif
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright © 2012, 2013 Intel Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this
|
||||
* software and its documentation for any purpose is hereby granted
|
||||
* without fee, provided that the above copyright notice appear in
|
||||
* all copies and that both that copyright notice and this permission
|
||||
* notice appear in supporting documentation, and that the name of
|
||||
* the copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
* THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
extern const struct wl_interface wl_input_method_context_interface;
|
||||
extern const struct wl_interface wl_input_panel_surface_interface;
|
||||
extern const struct wl_interface wl_keyboard_interface;
|
||||
extern const struct wl_interface wl_output_interface;
|
||||
extern const struct wl_interface wl_surface_interface;
|
||||
|
||||
static const struct wl_interface *types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&wl_keyboard_interface,
|
||||
&wl_input_method_context_interface,
|
||||
&wl_input_method_context_interface,
|
||||
&wl_input_panel_surface_interface,
|
||||
&wl_surface_interface,
|
||||
&wl_output_interface,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message wl_input_method_context_requests[] = {
|
||||
{ "destroy", "", types + 0 },
|
||||
{ "commit_string", "us", types + 0 },
|
||||
{ "preedit_string", "uss", types + 0 },
|
||||
{ "preedit_styling", "uuu", types + 0 },
|
||||
{ "preedit_cursor", "i", types + 0 },
|
||||
{ "delete_surrounding_text", "iu", types + 0 },
|
||||
{ "cursor_position", "ii", types + 0 },
|
||||
{ "modifiers_map", "a", types + 0 },
|
||||
{ "keysym", "uuuuu", types + 0 },
|
||||
{ "grab_keyboard", "n", types + 5 },
|
||||
{ "key", "uuuu", types + 0 },
|
||||
{ "modifiers", "uuuuu", types + 0 },
|
||||
{ "language", "us", types + 0 },
|
||||
{ "text_direction", "uu", types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message wl_input_method_context_events[] = {
|
||||
{ "surrounding_text", "suu", types + 0 },
|
||||
{ "reset", "", types + 0 },
|
||||
{ "content_type", "uu", types + 0 },
|
||||
{ "invoke_action", "uu", types + 0 },
|
||||
{ "commit_state", "u", types + 0 },
|
||||
{ "preferred_language", "s", types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface wl_input_method_context_interface = {
|
||||
"wl_input_method_context", 1,
|
||||
14, wl_input_method_context_requests,
|
||||
6, wl_input_method_context_events,
|
||||
};
|
||||
|
||||
static const struct wl_message wl_input_method_events[] = {
|
||||
{ "activate", "n", types + 6 },
|
||||
{ "deactivate", "o", types + 7 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface wl_input_method_interface = {
|
||||
"wl_input_method", 1,
|
||||
0, NULL,
|
||||
2, wl_input_method_events,
|
||||
};
|
||||
|
||||
static const struct wl_message wl_input_panel_requests[] = {
|
||||
{ "get_input_panel_surface", "no", types + 8 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface wl_input_panel_interface = {
|
||||
"wl_input_panel", 1,
|
||||
1, wl_input_panel_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message wl_input_panel_surface_requests[] = {
|
||||
{ "set_toplevel", "ou", types + 10 },
|
||||
{ "set_overlay_panel", "", types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface wl_input_panel_surface_interface = {
|
||||
"wl_input_panel_surface", 1,
|
||||
2, wl_input_panel_surface_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
|
@ -0,0 +1,418 @@
|
|||
/*
|
||||
* Copyright © 2012, 2013 Intel Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this
|
||||
* software and its documentation for any purpose is hereby granted
|
||||
* without fee, provided that the above copyright notice appear in
|
||||
* all copies and that both that copyright notice and this permission
|
||||
* notice appear in supporting documentation, and that the name of
|
||||
* the copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
* THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef INPUT_METHOD_SERVER_PROTOCOL_H
|
||||
#define INPUT_METHOD_SERVER_PROTOCOL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "wayland-server.h"
|
||||
|
||||
struct wl_client;
|
||||
struct wl_resource;
|
||||
|
||||
struct wl_input_method_context;
|
||||
struct wl_input_method;
|
||||
struct wl_input_panel;
|
||||
struct wl_input_panel_surface;
|
||||
|
||||
extern const struct wl_interface wl_input_method_context_interface;
|
||||
extern const struct wl_interface wl_input_method_interface;
|
||||
extern const struct wl_interface wl_input_panel_interface;
|
||||
extern const struct wl_interface wl_input_panel_surface_interface;
|
||||
|
||||
/**
|
||||
* wl_input_method_context - input method context
|
||||
* @destroy: (none)
|
||||
* @commit_string: commit string
|
||||
* @preedit_string: pre-edit string
|
||||
* @preedit_styling: pre-edit styling
|
||||
* @preedit_cursor: pre-edit cursor
|
||||
* @delete_surrounding_text: delete text
|
||||
* @cursor_position: set cursor to a new position
|
||||
* @modifiers_map: (none)
|
||||
* @keysym: keysym
|
||||
* @grab_keyboard: grab hardware keyboard
|
||||
* @key: forward key event
|
||||
* @modifiers: forward modifiers event
|
||||
* @language: (none)
|
||||
* @text_direction: (none)
|
||||
*
|
||||
* Corresponds to a text model on input method side. An input method
|
||||
* context is created on text model activation on the input method side. It
|
||||
* allows to receive information about the text model from the application
|
||||
* via events. Input method contexts do not keep state after deactivation
|
||||
* and should be destroyed after deactivation is handled.
|
||||
*
|
||||
* Text is generally UTF-8 encoded, indices and lengths are in bytes.
|
||||
*
|
||||
* Serials are used to synchronize the state between the text input and an
|
||||
* input method. New serials are sent by the text input in the commit_state
|
||||
* request and are used by the input method to indicate the known text
|
||||
* input state in events like preedit_string, commit_string, and keysym.
|
||||
* The text input can then ignore events from the input method which are
|
||||
* based on an outdated state (for example after a reset).
|
||||
*/
|
||||
struct wl_input_method_context_interface {
|
||||
/**
|
||||
* destroy - (none)
|
||||
*/
|
||||
void (*destroy)(struct wl_client *client,
|
||||
struct wl_resource *resource);
|
||||
/**
|
||||
* commit_string - commit string
|
||||
* @serial: serial of the latest known text input state
|
||||
* @text: (none)
|
||||
*
|
||||
* Send the commit string text for insertion to the application.
|
||||
*
|
||||
* The text to commit could be either just a single character after
|
||||
* a key press or the result of some composing (pre-edit). It could
|
||||
* be also an empty text when some text should be removed (see
|
||||
* delete_surrounding_text) or when the input cursor should be
|
||||
* moved (see cursor_position).
|
||||
*
|
||||
* Any previously set composing text will be removed.
|
||||
*/
|
||||
void (*commit_string)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
const char *text);
|
||||
/**
|
||||
* preedit_string - pre-edit string
|
||||
* @serial: serial of the latest known text input state
|
||||
* @text: (none)
|
||||
* @commit: (none)
|
||||
*
|
||||
* Send the pre-edit string text to the application text input.
|
||||
*
|
||||
* The commit text can be used to replace the preedit text on reset
|
||||
* (for example on unfocus).
|
||||
*
|
||||
* Also previously sent preedit_style and preedit_cursor requests
|
||||
* are processed bt the text_input also.
|
||||
*/
|
||||
void (*preedit_string)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
const char *text,
|
||||
const char *commit);
|
||||
/**
|
||||
* preedit_styling - pre-edit styling
|
||||
* @index: (none)
|
||||
* @length: (none)
|
||||
* @style: (none)
|
||||
*
|
||||
* Sets styling information on composing text. The style is
|
||||
* applied for length in bytes from index relative to the beginning
|
||||
* of the composing text (as byte offset). Multiple styles can be
|
||||
* applied to a composing text.
|
||||
*
|
||||
* This request should be sent before sending preedit_string
|
||||
* request.
|
||||
*/
|
||||
void (*preedit_styling)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t index,
|
||||
uint32_t length,
|
||||
uint32_t style);
|
||||
/**
|
||||
* preedit_cursor - pre-edit cursor
|
||||
* @index: (none)
|
||||
*
|
||||
* Sets the cursor position inside the composing text (as byte
|
||||
* offset) relative to the start of the composing text.
|
||||
*
|
||||
* When index is negative no cursor should be displayed.
|
||||
*
|
||||
* This request should be sent before sending preedit_string
|
||||
* request.
|
||||
*/
|
||||
void (*preedit_cursor)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
int32_t index);
|
||||
/**
|
||||
* delete_surrounding_text - delete text
|
||||
* @index: (none)
|
||||
* @length: (none)
|
||||
*
|
||||
*
|
||||
*
|
||||
* This request will be handled on text_input side as part of a
|
||||
* directly following commit_string request.
|
||||
*/
|
||||
void (*delete_surrounding_text)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
int32_t index,
|
||||
uint32_t length);
|
||||
/**
|
||||
* cursor_position - set cursor to a new position
|
||||
* @index: (none)
|
||||
* @anchor: (none)
|
||||
*
|
||||
* Sets the cursor and anchor to a new position. Index is the new
|
||||
* cursor position in bytes (when >= 0 relative to the end of
|
||||
* inserted text else relative to beginning of inserted text).
|
||||
* Anchor is the new anchor position in bytes (when >= 0 relative
|
||||
* to the end of inserted text, else relative to beginning of
|
||||
* inserted text). When there should be no selected text anchor
|
||||
* should be the same as index.
|
||||
*
|
||||
* This request will be handled on text_input side as part of a
|
||||
* directly following commit_string request.
|
||||
*/
|
||||
void (*cursor_position)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
int32_t index,
|
||||
int32_t anchor);
|
||||
/**
|
||||
* modifiers_map - (none)
|
||||
* @map: (none)
|
||||
*/
|
||||
void (*modifiers_map)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_array *map);
|
||||
/**
|
||||
* keysym - keysym
|
||||
* @serial: serial of the latest known text input state
|
||||
* @time: (none)
|
||||
* @sym: (none)
|
||||
* @state: (none)
|
||||
* @modifiers: (none)
|
||||
*
|
||||
* Notify when a key event was sent. Key events should not be
|
||||
* used for normal text input operations, which should be done with
|
||||
* commit_string, delete_surrounfing_text, etc. The key event
|
||||
* follows the wl_keyboard key event convention. Sym is a XKB
|
||||
* keysym, state a wl_keyboard key_state.
|
||||
*/
|
||||
void (*keysym)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
uint32_t sym,
|
||||
uint32_t state,
|
||||
uint32_t modifiers);
|
||||
/**
|
||||
* grab_keyboard - grab hardware keyboard
|
||||
* @keyboard: (none)
|
||||
*
|
||||
* Allows 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.
|
||||
*/
|
||||
void (*grab_keyboard)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t keyboard);
|
||||
/**
|
||||
* key - forward key event
|
||||
* @serial: serial from wl_keyboard::key
|
||||
* @time: time from wl_keyboard::key
|
||||
* @key: key from wl_keyboard::key
|
||||
* @state: state from wl_keyboard::key
|
||||
*
|
||||
* Should be used when filtering key events with grab_keyboard.
|
||||
*
|
||||
* When the wl_keyboard::key event is not processed by the input
|
||||
* method itself and should be sent to the client instead, forward
|
||||
* it with this request. The arguments should be the ones from the
|
||||
* wl_keyboard::key event.
|
||||
*
|
||||
* For generating custom key events use the keysym request instead.
|
||||
*/
|
||||
void (*key)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
uint32_t key,
|
||||
uint32_t state);
|
||||
/**
|
||||
* modifiers - forward modifiers event
|
||||
* @serial: serial from wl_keyboard::modifiers
|
||||
* @mods_depressed: mods_depressed from wl_keyboard::modifiers
|
||||
* @mods_latched: mods_latched from wl_keyboard::modifiers
|
||||
* @mods_locked: mods_locked from wl_keyboard::modifiers
|
||||
* @group: group from wl_keyboard::modifiers
|
||||
*
|
||||
* Should be used when filtering key events with grab_keyboard.
|
||||
*
|
||||
* When the wl_keyboard::modifiers event should be also send to the
|
||||
* client, forward it with this request. The arguments should be
|
||||
* the ones from the wl_keyboard::modifiers event.
|
||||
*/
|
||||
void (*modifiers)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
uint32_t mods_depressed,
|
||||
uint32_t mods_latched,
|
||||
uint32_t mods_locked,
|
||||
uint32_t group);
|
||||
/**
|
||||
* language - (none)
|
||||
* @serial: serial of the latest known text input state
|
||||
* @language: (none)
|
||||
*/
|
||||
void (*language)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
const char *language);
|
||||
/**
|
||||
* text_direction - (none)
|
||||
* @serial: serial of the latest known text input state
|
||||
* @direction: (none)
|
||||
*/
|
||||
void (*text_direction)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
uint32_t direction);
|
||||
};
|
||||
|
||||
#define WL_INPUT_METHOD_CONTEXT_SURROUNDING_TEXT 0
|
||||
#define WL_INPUT_METHOD_CONTEXT_RESET 1
|
||||
#define WL_INPUT_METHOD_CONTEXT_CONTENT_TYPE 2
|
||||
#define WL_INPUT_METHOD_CONTEXT_INVOKE_ACTION 3
|
||||
#define WL_INPUT_METHOD_CONTEXT_COMMIT_STATE 4
|
||||
#define WL_INPUT_METHOD_CONTEXT_PREFERRED_LANGUAGE 5
|
||||
|
||||
#define WL_INPUT_METHOD_CONTEXT_SURROUNDING_TEXT_SINCE_VERSION 1
|
||||
#define WL_INPUT_METHOD_CONTEXT_RESET_SINCE_VERSION 1
|
||||
#define WL_INPUT_METHOD_CONTEXT_CONTENT_TYPE_SINCE_VERSION 1
|
||||
#define WL_INPUT_METHOD_CONTEXT_INVOKE_ACTION_SINCE_VERSION 1
|
||||
#define WL_INPUT_METHOD_CONTEXT_COMMIT_STATE_SINCE_VERSION 1
|
||||
#define WL_INPUT_METHOD_CONTEXT_PREFERRED_LANGUAGE_SINCE_VERSION 1
|
||||
|
||||
static inline void
|
||||
wl_input_method_context_send_surrounding_text(struct wl_resource *resource_, const char *text, uint32_t cursor, uint32_t anchor)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_SURROUNDING_TEXT, text, cursor, anchor);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_input_method_context_send_reset(struct wl_resource *resource_)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_RESET);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_input_method_context_send_content_type(struct wl_resource *resource_, uint32_t hint, uint32_t purpose)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_CONTENT_TYPE, hint, purpose);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_input_method_context_send_invoke_action(struct wl_resource *resource_, uint32_t button, uint32_t index)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_INVOKE_ACTION, button, index);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_input_method_context_send_commit_state(struct wl_resource *resource_, uint32_t serial)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_COMMIT_STATE, serial);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_input_method_context_send_preferred_language(struct wl_resource *resource_, const char *language)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_PREFERRED_LANGUAGE, language);
|
||||
}
|
||||
|
||||
#define WL_INPUT_METHOD_ACTIVATE 0
|
||||
#define WL_INPUT_METHOD_DEACTIVATE 1
|
||||
|
||||
#define WL_INPUT_METHOD_ACTIVATE_SINCE_VERSION 1
|
||||
#define WL_INPUT_METHOD_DEACTIVATE_SINCE_VERSION 1
|
||||
|
||||
static inline void
|
||||
wl_input_method_send_activate(struct wl_resource *resource_, struct wl_resource *id)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_ACTIVATE, id);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_input_method_send_deactivate(struct wl_resource *resource_, struct wl_resource *context)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_DEACTIVATE, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* wl_input_panel - interface for implementing keyboards
|
||||
* @get_input_panel_surface: (none)
|
||||
*
|
||||
* Only one client can bind this interface at a time.
|
||||
*/
|
||||
struct wl_input_panel_interface {
|
||||
/**
|
||||
* get_input_panel_surface - (none)
|
||||
* @id: (none)
|
||||
* @surface: (none)
|
||||
*/
|
||||
void (*get_input_panel_surface)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t id,
|
||||
struct wl_resource *surface);
|
||||
};
|
||||
|
||||
|
||||
#ifndef WL_INPUT_PANEL_SURFACE_POSITION_ENUM
|
||||
#define WL_INPUT_PANEL_SURFACE_POSITION_ENUM
|
||||
enum wl_input_panel_surface_position {
|
||||
WL_INPUT_PANEL_SURFACE_POSITION_CENTER_BOTTOM = 0,
|
||||
};
|
||||
#endif /* WL_INPUT_PANEL_SURFACE_POSITION_ENUM */
|
||||
|
||||
struct wl_input_panel_surface_interface {
|
||||
/**
|
||||
* set_toplevel - set the surface type as a keyboard
|
||||
* @output: (none)
|
||||
* @position: (none)
|
||||
*
|
||||
* A keyboard surface is only shown, when a text model is active
|
||||
*/
|
||||
void (*set_toplevel)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *output,
|
||||
uint32_t position);
|
||||
/**
|
||||
* set_overlay_panel - set the surface type as an overlay panel
|
||||
*
|
||||
* An overlay panel is shown near the input cursor above the
|
||||
* application window when a text model is active.
|
||||
*/
|
||||
void (*set_overlay_panel)(struct wl_client *client,
|
||||
struct wl_resource *resource);
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,336 @@
|
|||
#define E_COMP_WL
|
||||
#include "e.h"
|
||||
#include "e_mod_main.h"
|
||||
#include "e_input_method_protocol.h"
|
||||
|
||||
typedef struct _E_Input_Panel E_Input_Panel;
|
||||
typedef struct _E_Input_Panel_Surface E_Input_Panel_Surface;
|
||||
|
||||
struct _E_Input_Panel
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
Eina_List *surfaces;
|
||||
};
|
||||
|
||||
struct _E_Input_Panel_Surface
|
||||
{
|
||||
E_Client *ec;
|
||||
|
||||
Eina_Bool panel;
|
||||
Eina_Bool showing;
|
||||
};
|
||||
|
||||
static E_Input_Panel input_panel;
|
||||
static Eina_List *handlers = NULL;
|
||||
static struct wl_global *input_panel_global = NULL;
|
||||
|
||||
static void
|
||||
_e_input_panel_surface_cb_toplevel_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *output_resource EINA_UNUSED, uint32_t position EINA_UNUSED)
|
||||
{
|
||||
E_Input_Panel_Surface *ips;
|
||||
|
||||
ips = wl_resource_get_user_data(resource);
|
||||
ips->panel = EINA_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_e_input_panel_surface_cb_overlay_panel_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
||||
{
|
||||
E_Input_Panel_Surface *ips;
|
||||
|
||||
ips = wl_resource_get_user_data(resource);
|
||||
ips->panel = EINA_TRUE;
|
||||
}
|
||||
|
||||
static const struct wl_input_panel_surface_interface _e_input_panel_surface_implementation = {
|
||||
_e_input_panel_surface_cb_toplevel_set,
|
||||
_e_input_panel_surface_cb_overlay_panel_set
|
||||
};
|
||||
|
||||
static void
|
||||
_e_input_panel_surface_resource_destroy(struct wl_resource *resource)
|
||||
{
|
||||
E_Input_Panel_Surface *ips;
|
||||
E_Client *ec;
|
||||
|
||||
ips = wl_resource_get_user_data(resource);
|
||||
ec = ips->ec;
|
||||
if (!e_object_is_del(E_OBJECT(ec)))
|
||||
{
|
||||
if (ec->comp_data->mapped)
|
||||
{
|
||||
if ((ec->comp_data->shell.surface) &&
|
||||
(ec->comp_data->shell.unmap))
|
||||
ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
|
||||
}
|
||||
if (ec->parent)
|
||||
{
|
||||
ec->parent->transients =
|
||||
eina_list_remove(ec->parent->transients, ec);
|
||||
}
|
||||
ec->comp_data->shell.surface = NULL;
|
||||
}
|
||||
|
||||
input_panel.surfaces = eina_list_remove(input_panel.surfaces, ips);
|
||||
|
||||
free(ips);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_input_panel_position_set(E_Client *ec, int w, int h)
|
||||
{
|
||||
int nx, ny;
|
||||
int zx, zy, zw, zh;
|
||||
|
||||
e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh);
|
||||
|
||||
nx = zx + (zw - w) / 2;
|
||||
ny = zy + zh - h;
|
||||
|
||||
e_client_util_move_without_frame(ec, nx, ny);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_input_panel_surface_visible_update(E_Input_Panel_Surface *ips)
|
||||
{
|
||||
E_Client *ec;
|
||||
|
||||
ec = ips->ec;
|
||||
if ((ips->showing) &&
|
||||
(e_pixmap_usable_get(ec->pixmap)))
|
||||
{
|
||||
if (!ips->panel)
|
||||
_e_input_panel_position_set(ec, ec->client.w, ec->client.h);
|
||||
|
||||
ec->visible = EINA_TRUE;
|
||||
evas_object_geometry_set(ec->frame, ec->x, ec->y, ec->w, ec->h);
|
||||
evas_object_show(ec->frame);
|
||||
e_comp_object_damage(ec->frame, ec->x, ec->y, ec->w, ec->h);
|
||||
}
|
||||
else
|
||||
{
|
||||
ec->visible = EINA_FALSE;
|
||||
evas_object_hide(ec->frame);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_e_input_panel_surface_configure(struct wl_resource *resource, Evas_Coord x EINA_UNUSED, Evas_Coord y EINA_UNUSED, Evas_Coord w, Evas_Coord h)
|
||||
{
|
||||
E_Input_Panel_Surface *ips;
|
||||
|
||||
ips = wl_resource_get_user_data(resource);
|
||||
|
||||
e_client_util_resize_without_frame(ips->ec, w, h);
|
||||
|
||||
if (ips->showing)
|
||||
_e_input_panel_surface_visible_update(ips);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_input_panel_surface_map(struct wl_resource *resource)
|
||||
{
|
||||
E_Input_Panel_Surface *ips;
|
||||
E_Client *ec;
|
||||
|
||||
ips = wl_resource_get_user_data(resource);
|
||||
ec = ips->ec;
|
||||
|
||||
if (e_object_is_del(E_OBJECT(ec)))
|
||||
return;
|
||||
|
||||
// NOTE: we need to set mapped, so that avoid showing evas_object and continue buffer's commit process.
|
||||
if ((!ec->comp_data->mapped) && (e_pixmap_usable_get(ec->pixmap)))
|
||||
ec->comp_data->mapped = EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_e_input_panel_surface_unmap(struct wl_resource *resource)
|
||||
{
|
||||
E_Input_Panel_Surface *ips;
|
||||
E_Client *ec;
|
||||
|
||||
ips = wl_resource_get_user_data(resource);
|
||||
ec = ips->ec;
|
||||
|
||||
if (e_object_is_del(E_OBJECT(ec)))
|
||||
return;
|
||||
|
||||
if (ec->comp_data->mapped)
|
||||
{
|
||||
ec->visible = EINA_FALSE;
|
||||
evas_object_hide(ec->frame);
|
||||
ec->comp_data->mapped = EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_e_input_panel_cb_surface_get(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t id, struct wl_resource *surface_resource)
|
||||
{
|
||||
E_Client *ec;
|
||||
E_Input_Panel_Surface *ips;
|
||||
E_Comp_Client_Data *cd;
|
||||
|
||||
ec = wl_resource_get_user_data(surface_resource);
|
||||
if (!ec)
|
||||
{
|
||||
wl_resource_post_error(surface_resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Client Set On Surface");
|
||||
return;
|
||||
}
|
||||
|
||||
cd = ec->comp_data;
|
||||
if (!cd)
|
||||
{
|
||||
wl_resource_post_error(surface_resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Comp Data For Client");
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for existing shell surface */
|
||||
if (ec->comp_data->shell.surface)
|
||||
{
|
||||
wl_resource_post_error(surface_resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"Client already has shell surface");
|
||||
return;
|
||||
}
|
||||
|
||||
ips = E_NEW(E_Input_Panel_Surface, 1);
|
||||
if (!ips)
|
||||
{
|
||||
wl_client_post_no_memory(client);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cd->shell.surface = wl_resource_create(client,
|
||||
&wl_input_panel_surface_interface,
|
||||
1, id);
|
||||
if (!cd->shell.surface)
|
||||
{
|
||||
wl_client_post_no_memory(client);
|
||||
free(ips);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ips->ec = ec;
|
||||
|
||||
EC_CHANGED(ec);
|
||||
if (!ec->new_client)
|
||||
{
|
||||
ec->new_client = EINA_TRUE;
|
||||
e_comp->new_clients++;
|
||||
}
|
||||
if (ec->ignored)
|
||||
e_client_unignore(ec);
|
||||
|
||||
/* set input panel client properties */
|
||||
ec->borderless = EINA_TRUE;
|
||||
ec->argb = EINA_TRUE;
|
||||
ec->lock_border = EINA_TRUE;
|
||||
ec->lock_focus_in = ec->lock_focus_out = EINA_TRUE;
|
||||
ec->netwm.state.skip_taskbar = EINA_TRUE;
|
||||
ec->netwm.state.skip_pager = EINA_TRUE;
|
||||
ec->no_shape_cut = EINA_TRUE;
|
||||
ec->border_size = 0;
|
||||
ec->netwm.type = E_WINDOW_TYPE_UTILITY;
|
||||
ec->comp_data->set_win_type = EINA_TRUE;
|
||||
|
||||
|
||||
cd->surface = surface_resource;
|
||||
cd->shell.configure_send = NULL;
|
||||
cd->shell.configure = _e_input_panel_surface_configure;
|
||||
cd->shell.ping = NULL;
|
||||
cd->shell.map = _e_input_panel_surface_map;
|
||||
cd->shell.unmap = _e_input_panel_surface_unmap;
|
||||
|
||||
|
||||
wl_resource_set_implementation(cd->shell.surface,
|
||||
&_e_input_panel_surface_implementation,
|
||||
ips, _e_input_panel_surface_resource_destroy);
|
||||
|
||||
input_panel.surfaces = eina_list_append(input_panel.surfaces, ips);
|
||||
}
|
||||
|
||||
static const struct wl_input_panel_interface _e_input_panel_implementation = {
|
||||
_e_input_panel_cb_surface_get
|
||||
};
|
||||
|
||||
static void
|
||||
_e_input_panel_unbind(struct wl_resource *resource EINA_UNUSED)
|
||||
{
|
||||
input_panel.resource = NULL;
|
||||
|
||||
E_FREE_FUNC(input_panel.surfaces, eina_list_free);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_input_panel_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version EINA_UNUSED, uint32_t id)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create(client, &wl_input_panel_interface, 1, id);
|
||||
if (!resource)
|
||||
{
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
|
||||
if (input_panel.resource)
|
||||
{
|
||||
wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"interface object already bound");
|
||||
return;
|
||||
}
|
||||
|
||||
input_panel.resource = resource;
|
||||
|
||||
wl_resource_set_implementation(resource,
|
||||
&_e_input_panel_implementation,
|
||||
NULL, _e_input_panel_unbind);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_input_panel_cb_visible_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
||||
{
|
||||
E_Event_Text_Input_Panel_Visibility_Change *ev = event;
|
||||
E_Input_Panel_Surface *ips;
|
||||
Eina_List *l;
|
||||
|
||||
EINA_LIST_FOREACH(input_panel.surfaces, l, ips)
|
||||
{
|
||||
if (!ips->ec) continue;
|
||||
ips->showing = ev->visible;
|
||||
_e_input_panel_surface_visible_update(ips);
|
||||
}
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
EINTERN Eina_Bool
|
||||
e_input_panel_init(void)
|
||||
{
|
||||
E_LIST_HANDLER_APPEND(handlers, E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE,
|
||||
_e_input_panel_cb_visible_change, NULL);
|
||||
// TODO: add signal handler - update input panel
|
||||
|
||||
input_panel_global = wl_global_create(e_comp->wl_comp_data->wl.disp,
|
||||
&wl_input_panel_interface, 1,
|
||||
NULL, _e_input_panel_bind);
|
||||
if (!input_panel_global)
|
||||
{
|
||||
ERR("failed to create wl_global for input panel");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EINTERN void
|
||||
e_input_panel_shutdown(void)
|
||||
{
|
||||
E_FREE_FUNC(input_panel_global, wl_global_destroy);
|
||||
E_FREE_LIST(handlers, ecore_event_handler_del);
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
#define E_COMP_WL
|
||||
#include "e.h"
|
||||
#include "e_mod_main.h"
|
||||
#include "e_desktop_shell_protocol.h"
|
||||
|
||||
#define XDG_SERVER_VERSION 5
|
||||
|
@ -1379,11 +1380,21 @@ e_modapi_init(E_Module *m)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_WL_TEXT_INPUT
|
||||
if (!e_input_panel_init())
|
||||
{
|
||||
ERR("Could not init input panel");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
E_API int
|
||||
e_modapi_shutdown(E_Module *m EINA_UNUSED)
|
||||
{
|
||||
e_input_panel_shutdown();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef _E_MOD_MAIN_H
|
||||
#define _E_MOD_MAIN_H
|
||||
|
||||
Eina_Bool e_input_panel_init(void);
|
||||
void e_input_panel_shutdown(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,933 @@
|
|||
#define E_COMP_WL
|
||||
#include "e.h"
|
||||
#include "text-protocol.h"
|
||||
#include "input-method-protocol.h"
|
||||
|
||||
typedef struct _E_Text_Input E_Text_Input;
|
||||
typedef struct _E_Input_Method E_Input_Method;
|
||||
typedef struct _E_Input_Method_Context E_Input_Method_Context;
|
||||
|
||||
struct _E_Text_Input
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
E_Client *ec;
|
||||
Eina_List *input_methods;
|
||||
Eina_Rectangle *cursor_rect;
|
||||
Eina_Bool input_panel_visible;
|
||||
};
|
||||
|
||||
struct _E_Input_Method
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
E_Text_Input *model;
|
||||
E_Input_Method_Context *context;
|
||||
Eina_List *handlers;
|
||||
};
|
||||
|
||||
struct _E_Input_Method_Context
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
E_Text_Input *model;
|
||||
E_Input_Method *input_method;
|
||||
|
||||
struct
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
Eina_List *handlers;
|
||||
Eina_Bool grabbed;
|
||||
} kbd;
|
||||
};
|
||||
|
||||
static struct wl_global *text_input_manager_global;
|
||||
|
||||
static void
|
||||
_e_text_input_event_visible_change_send(Eina_Bool visible)
|
||||
{
|
||||
E_Event_Text_Input_Panel_Visibility_Change *ev;
|
||||
|
||||
ev = E_NEW(E_Event_Text_Input_Panel_Visibility_Change, 1);
|
||||
ev->visible = visible;
|
||||
ecore_event_add(E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE, ev, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_key_send(E_Input_Method_Context *context, unsigned int keycode, unsigned int timestamp, enum wl_keyboard_key_state state)
|
||||
{
|
||||
uint32_t serial, nk;
|
||||
|
||||
nk = keycode - 8;
|
||||
|
||||
serial = wl_display_next_serial(e_comp->wl_comp_data->wl.disp);
|
||||
wl_keyboard_send_key(context->kbd.resource, serial, timestamp, nk, state);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_text_input_method_context_ecore_cb_key_down(void *data, int ev_type EINA_UNUSED, Ecore_Event_Key *ev)
|
||||
{
|
||||
E_Input_Method_Context *context = data;
|
||||
|
||||
_e_text_input_method_context_key_send(context, ev->keycode, ev->timestamp,
|
||||
WL_KEYBOARD_KEY_STATE_PRESSED);
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_text_input_method_context_ecore_cb_key_up(void *data, int ev_type EINA_UNUSED, Ecore_Event_Key *ev)
|
||||
{
|
||||
E_Input_Method_Context *context = data;
|
||||
|
||||
_e_text_input_method_context_key_send(context, ev->keycode, ev->timestamp,
|
||||
WL_KEYBOARD_KEY_STATE_RELEASED);
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_grab_set(E_Input_Method_Context *context, Eina_Bool set)
|
||||
{
|
||||
if (set == context->kbd.grabbed)
|
||||
return;
|
||||
|
||||
context->kbd.grabbed = set;
|
||||
|
||||
if (set)
|
||||
{
|
||||
E_LIST_HANDLER_APPEND(context->kbd.handlers, ECORE_EVENT_KEY_DOWN,
|
||||
_e_text_input_method_context_ecore_cb_key_down,
|
||||
context);
|
||||
E_LIST_HANDLER_APPEND(context->kbd.handlers, ECORE_EVENT_KEY_UP,
|
||||
_e_text_input_method_context_ecore_cb_key_up,
|
||||
context);
|
||||
|
||||
e_comp_grab_input(0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
E_FREE_LIST(context->kbd.handlers, ecore_event_handler_del);
|
||||
e_comp_ungrab_input(0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_deactivate(E_Text_Input *text_input, E_Input_Method *input_method)
|
||||
{
|
||||
if (input_method->model == text_input)
|
||||
{
|
||||
if ((input_method->context) && (input_method->resource))
|
||||
{
|
||||
if (input_method->context)
|
||||
_e_text_input_method_context_grab_set(input_method->context,
|
||||
EINA_FALSE);
|
||||
|
||||
wl_input_method_send_deactivate(input_method->resource,
|
||||
input_method->context->resource);
|
||||
}
|
||||
|
||||
input_method->model = NULL;
|
||||
input_method->context = NULL;
|
||||
|
||||
text_input->input_methods = eina_list_remove(text_input->input_methods, input_method);
|
||||
|
||||
wl_text_input_send_leave(text_input->resource);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy(resource);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_cb_string_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *text)
|
||||
{
|
||||
E_Input_Method_Context *context = wl_resource_get_user_data(resource);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Input Method Context For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->model)
|
||||
wl_text_input_send_commit_string(context->model->resource,
|
||||
serial, text);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_cb_preedit_string(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *text, const char *commit)
|
||||
{
|
||||
E_Input_Method_Context *context = wl_resource_get_user_data(resource);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Input Method Context For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->model)
|
||||
wl_text_input_send_preedit_string(context->model->resource,
|
||||
serial, text, commit);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_cb_preedit_styling(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t index, uint32_t length, uint32_t style)
|
||||
{
|
||||
E_Input_Method_Context *context = wl_resource_get_user_data(resource);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Input Method Context For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->model)
|
||||
wl_text_input_send_preedit_styling(context->model->resource,
|
||||
index, length, style);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_cb_preedit_cursor(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t cursor)
|
||||
{
|
||||
E_Input_Method_Context *context = wl_resource_get_user_data(resource);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Input Method Context For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->model)
|
||||
wl_text_input_send_preedit_cursor(context->model->resource,
|
||||
cursor);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_cb_surrounding_text_delete(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t index, uint32_t length)
|
||||
{
|
||||
E_Input_Method_Context *context = wl_resource_get_user_data(resource);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Input Method Context For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->model)
|
||||
wl_text_input_send_delete_surrounding_text(context->model->resource,
|
||||
index, length);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_cb_cursor_position(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t index, int32_t anchor)
|
||||
{
|
||||
E_Input_Method_Context *context = wl_resource_get_user_data(resource);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Input Method Context For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->model)
|
||||
wl_text_input_send_cursor_position(context->model->resource,
|
||||
index, anchor);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_cb_modifiers_map(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_array *map)
|
||||
{
|
||||
E_Input_Method_Context *context = wl_resource_get_user_data(resource);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Input Method Context For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->model)
|
||||
wl_text_input_send_modifiers_map(context->model->resource, map);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_cb_keysym(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers)
|
||||
{
|
||||
E_Input_Method_Context *context = wl_resource_get_user_data(resource);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Input Method Context For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->model)
|
||||
wl_text_input_send_keysym(context->model->resource,
|
||||
serial, time, sym, state, modifiers);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_keyboard_unbind(struct wl_resource *resource)
|
||||
{
|
||||
E_Input_Method_Context *context;
|
||||
|
||||
context = wl_resource_get_user_data(resource);
|
||||
|
||||
_e_text_input_method_context_grab_set(context, EINA_FALSE);
|
||||
|
||||
context->kbd.resource = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_cb_keyboard_grab(struct wl_client *client, struct wl_resource *resource, uint32_t id)
|
||||
{
|
||||
E_Input_Method_Context *context;
|
||||
struct wl_resource *new_resource;
|
||||
|
||||
DBG("Input Method Context - grab keyboard %d", wl_resource_get_id(resource));
|
||||
|
||||
context = wl_resource_get_user_data(resource);
|
||||
if (!context)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Input Method Context For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
new_resource = wl_resource_create(client, &wl_keyboard_interface, 1, id);
|
||||
if (!new_resource)
|
||||
{
|
||||
wl_resource_post_no_memory(resource);
|
||||
return;
|
||||
}
|
||||
|
||||
wl_resource_set_implementation(new_resource, NULL, context,
|
||||
_e_text_input_method_context_keyboard_unbind);
|
||||
|
||||
wl_keyboard_send_keymap(new_resource, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
||||
e_comp_wl->xkb.fd,
|
||||
e_comp_wl->xkb.size);
|
||||
|
||||
context->kbd.resource = new_resource;
|
||||
|
||||
_e_text_input_method_context_grab_set(context, EINA_TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_cb_key(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, uint32_t serial EINA_UNUSED, uint32_t time EINA_UNUSED, uint32_t key EINA_UNUSED, uint32_t state_w EINA_UNUSED)
|
||||
{
|
||||
DBG("Input Method Context - key %d", wl_resource_get_id(resource));
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_cb_modifiers(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, uint32_t serial EINA_UNUSED, uint32_t mods_depressed EINA_UNUSED, uint32_t mods_latched EINA_UNUSED, uint32_t mods_locked EINA_UNUSED, uint32_t group EINA_UNUSED)
|
||||
{
|
||||
DBG("Input Method Context - modifiers %d", wl_resource_get_id(resource));
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_cb_language(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *language)
|
||||
{
|
||||
E_Input_Method_Context *context = wl_resource_get_user_data(resource);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Input Method Context For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->model)
|
||||
wl_text_input_send_language(context->model->resource,
|
||||
serial, language);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_cb_text_direction(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, uint32_t direction)
|
||||
{
|
||||
E_Input_Method_Context *context = wl_resource_get_user_data(resource);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Input Method Context For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->model)
|
||||
wl_text_input_send_text_direction(context->model->resource,
|
||||
serial, direction);
|
||||
}
|
||||
|
||||
static const struct wl_input_method_context_interface _e_text_input_method_context_implementation = {
|
||||
_e_text_input_method_context_cb_destroy,
|
||||
_e_text_input_method_context_cb_string_commit,
|
||||
_e_text_input_method_context_cb_preedit_string,
|
||||
_e_text_input_method_context_cb_preedit_styling,
|
||||
_e_text_input_method_context_cb_preedit_cursor,
|
||||
_e_text_input_method_context_cb_surrounding_text_delete,
|
||||
_e_text_input_method_context_cb_cursor_position,
|
||||
_e_text_input_method_context_cb_modifiers_map,
|
||||
_e_text_input_method_context_cb_keysym,
|
||||
_e_text_input_method_context_cb_keyboard_grab,
|
||||
_e_text_input_method_context_cb_key,
|
||||
_e_text_input_method_context_cb_modifiers,
|
||||
_e_text_input_method_context_cb_language,
|
||||
_e_text_input_method_context_cb_text_direction
|
||||
};
|
||||
|
||||
static void
|
||||
_e_text_input_method_context_cb_resource_destroy(struct wl_resource *resource)
|
||||
{
|
||||
E_Input_Method_Context *context = wl_resource_get_user_data(resource);
|
||||
|
||||
if (!context)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Input Method Context For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
if (context->kbd.resource)
|
||||
wl_resource_destroy(context->kbd.resource);
|
||||
|
||||
free(context);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_text_input_cb_event_client_focus_in(void *data, int type EINA_UNUSED, void *event)
|
||||
{
|
||||
E_Input_Method *input_method = data;
|
||||
E_Event_Client *ev = event;
|
||||
|
||||
if (!input_method->model)
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
|
||||
if ((!ev->ec) ||
|
||||
(input_method->model->ec != ev->ec))
|
||||
{
|
||||
_e_text_input_deactivate(input_method->model, input_method);
|
||||
_e_text_input_event_visible_change_send(EINA_FALSE);
|
||||
}
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_cb_activate(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat, struct wl_resource *surface)
|
||||
{
|
||||
E_Text_Input *text_input;
|
||||
E_Input_Method *input_method;
|
||||
E_Text_Input *old;
|
||||
E_Input_Method_Context *context;
|
||||
|
||||
text_input = wl_resource_get_user_data(resource);
|
||||
if (!text_input)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Text Input For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
input_method =
|
||||
wl_resource_get_user_data(e_comp->wl_comp_data->seat.im.resource);
|
||||
if (!input_method)
|
||||
{
|
||||
wl_resource_post_error(seat,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Input Method For Seat");
|
||||
return;
|
||||
}
|
||||
|
||||
old = input_method->model;
|
||||
if (old == text_input)
|
||||
return;
|
||||
|
||||
if (old)
|
||||
_e_text_input_deactivate(old, input_method);
|
||||
|
||||
input_method->model = text_input;
|
||||
text_input->input_methods =
|
||||
eina_list_append(text_input->input_methods, input_method);
|
||||
|
||||
text_input->ec = wl_resource_get_user_data(surface);
|
||||
|
||||
if (input_method->resource)
|
||||
{
|
||||
context = E_NEW(E_Input_Method_Context, 1);
|
||||
if (!context)
|
||||
{
|
||||
wl_client_post_no_memory(client);
|
||||
ERR("Could not allocate space for Input_Method_Context");
|
||||
return;
|
||||
}
|
||||
|
||||
context->resource =
|
||||
wl_resource_create(wl_resource_get_client(input_method->resource),
|
||||
&wl_input_method_context_interface, 1, 0);
|
||||
wl_resource_set_implementation(context->resource,
|
||||
&_e_text_input_method_context_implementation,
|
||||
context, _e_text_input_method_context_cb_resource_destroy);
|
||||
|
||||
context->model = text_input;
|
||||
context->input_method = input_method;
|
||||
input_method->context = context;
|
||||
|
||||
wl_input_method_send_activate(input_method->resource, context->resource);
|
||||
}
|
||||
|
||||
if (text_input->input_panel_visible)
|
||||
_e_text_input_event_visible_change_send(EINA_TRUE);
|
||||
|
||||
wl_text_input_send_enter(text_input->resource, surface);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_cb_deactivate(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat)
|
||||
{
|
||||
E_Text_Input *text_input;
|
||||
E_Input_Method *input_method;
|
||||
|
||||
text_input = wl_resource_get_user_data(resource);
|
||||
if (!text_input)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Text Input For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
input_method =
|
||||
wl_resource_get_user_data(e_comp->wl_comp_data->seat.im.resource);
|
||||
if (!input_method)
|
||||
{
|
||||
wl_resource_post_error(seat,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Input Method For Seat");
|
||||
return;
|
||||
}
|
||||
|
||||
_e_text_input_deactivate(text_input, input_method);
|
||||
_e_text_input_event_visible_change_send(EINA_FALSE);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_cb_input_panel_show(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
||||
{
|
||||
E_Text_Input *text_input = wl_resource_get_user_data(resource);
|
||||
E_Input_Method *input_method;
|
||||
Eina_List *l;
|
||||
|
||||
if (!text_input)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Text Input For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
text_input->input_panel_visible = 1;
|
||||
|
||||
EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
|
||||
{
|
||||
if (input_method->model == text_input)
|
||||
_e_text_input_event_visible_change_send(EINA_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_cb_input_panel_hide(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
||||
{
|
||||
E_Text_Input *text_input = wl_resource_get_user_data(resource);
|
||||
E_Input_Method *input_method;
|
||||
Eina_List *l;
|
||||
|
||||
if (!text_input)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Text Input For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
text_input->input_panel_visible = 0;
|
||||
|
||||
EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
|
||||
{
|
||||
if (input_method->model == text_input)
|
||||
_e_text_input_event_visible_change_send(EINA_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_cb_reset(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
||||
{
|
||||
E_Text_Input *text_input = wl_resource_get_user_data(resource);
|
||||
E_Input_Method *input_method;
|
||||
Eina_List *l;
|
||||
|
||||
if (!text_input)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Text Input For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
|
||||
{
|
||||
if (!input_method->context) continue;
|
||||
wl_input_method_context_send_reset(input_method->context->resource);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_cb_surrounding_text_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *text, uint32_t cursor, uint32_t anchor)
|
||||
{
|
||||
E_Text_Input *text_input = wl_resource_get_user_data(resource);
|
||||
E_Input_Method *input_method;
|
||||
Eina_List *l;
|
||||
|
||||
if (!text_input)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Text Input For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
|
||||
{
|
||||
if (!input_method->context) continue;
|
||||
wl_input_method_context_send_surrounding_text(input_method->context->resource,
|
||||
text, cursor, anchor);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_cb_content_type_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t hint, uint32_t purpose)
|
||||
{
|
||||
E_Text_Input *text_input = wl_resource_get_user_data(resource);
|
||||
E_Input_Method *input_method;
|
||||
Eina_List *l;
|
||||
|
||||
if (!text_input)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Text Input For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
|
||||
{
|
||||
if (!input_method->context) continue;
|
||||
wl_input_method_context_send_content_type(input_method->context->resource,
|
||||
hint, purpose);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_cb_cursor_rectangle_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height)
|
||||
{
|
||||
E_Text_Input *text_input = wl_resource_get_user_data(resource);
|
||||
|
||||
if (!text_input)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Text Input For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
text_input->cursor_rect = eina_rectangle_new(x, y, width, height);
|
||||
|
||||
// TODO: issue event update input_panel
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_cb_preferred_language_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *language)
|
||||
{
|
||||
E_Text_Input *text_input = wl_resource_get_user_data(resource);
|
||||
E_Input_Method *input_method;
|
||||
Eina_List *l;
|
||||
|
||||
if (!text_input)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Text Input For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
|
||||
{
|
||||
if (!input_method->context) continue;
|
||||
wl_input_method_context_send_preferred_language(input_method->context->resource,
|
||||
language);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_cb_state_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial)
|
||||
{
|
||||
E_Text_Input *text_input = wl_resource_get_user_data(resource);
|
||||
E_Input_Method *input_method;
|
||||
Eina_List *l;
|
||||
|
||||
if (!text_input)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Text Input For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
|
||||
{
|
||||
if (!input_method->context) continue;
|
||||
wl_input_method_context_send_commit_state(input_method->context->resource, serial);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_cb_action_invoke(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t button, uint32_t index)
|
||||
{
|
||||
E_Text_Input *text_input = wl_resource_get_user_data(resource);
|
||||
E_Input_Method *input_method;
|
||||
Eina_List *l;
|
||||
|
||||
if (!text_input)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Text Input For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
|
||||
{
|
||||
if (!input_method->context) continue;
|
||||
wl_input_method_context_send_invoke_action(input_method->context->resource,
|
||||
button, index);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_text_input_interface _e_text_input_implementation = {
|
||||
_e_text_input_cb_activate,
|
||||
_e_text_input_cb_deactivate,
|
||||
_e_text_input_cb_input_panel_show,
|
||||
_e_text_input_cb_input_panel_hide,
|
||||
_e_text_input_cb_reset,
|
||||
_e_text_input_cb_surrounding_text_set,
|
||||
_e_text_input_cb_content_type_set,
|
||||
_e_text_input_cb_cursor_rectangle_set,
|
||||
_e_text_input_cb_preferred_language_set,
|
||||
_e_text_input_cb_state_commit,
|
||||
_e_text_input_cb_action_invoke
|
||||
};
|
||||
|
||||
static void
|
||||
_e_text_input_cb_destroy(struct wl_resource *resource)
|
||||
{
|
||||
E_Text_Input *text_input = wl_resource_get_user_data(resource);
|
||||
E_Input_Method *input_method;
|
||||
|
||||
if (!text_input)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Text Input For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
EINA_LIST_FREE(text_input->input_methods, input_method)
|
||||
_e_text_input_deactivate(text_input, input_method);
|
||||
|
||||
eina_rectangle_free(text_input->cursor_rect);
|
||||
free(text_input);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_manager_cb_text_input_create(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t id)
|
||||
{
|
||||
E_Text_Input *text_input;
|
||||
|
||||
text_input = E_NEW(E_Text_Input, 1);
|
||||
if (!text_input)
|
||||
{
|
||||
wl_client_post_no_memory(client);
|
||||
ERR("Could not allocate space for Text_Input");
|
||||
return;
|
||||
}
|
||||
|
||||
text_input->resource = wl_resource_create(client,
|
||||
&wl_text_input_interface,
|
||||
1, id);
|
||||
if (!text_input->resource)
|
||||
{
|
||||
wl_client_post_no_memory(client);
|
||||
ERR("could not create wl_resource for text input");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_resource_set_implementation(text_input->resource,
|
||||
&_e_text_input_implementation,
|
||||
text_input, _e_text_input_cb_destroy);
|
||||
}
|
||||
|
||||
static const struct wl_text_input_manager_interface _e_text_input_manager_implementation = {
|
||||
_e_text_input_manager_cb_text_input_create
|
||||
};
|
||||
|
||||
static void
|
||||
_e_text_cb_bind_text_input_manager(struct wl_client *client, void *data EINA_UNUSED, uint32_t version EINA_UNUSED, uint32_t id)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create(client, &wl_text_input_manager_interface, 1, id);
|
||||
if (!resource)
|
||||
{
|
||||
wl_client_post_no_memory(client);
|
||||
ERR("could not create resource for text input manager");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_resource_set_implementation(resource, &_e_text_input_manager_implementation, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_input_method_cb_unbind(struct wl_resource *resource)
|
||||
{
|
||||
E_Input_Method *input_method = wl_resource_get_user_data(resource);
|
||||
|
||||
e_comp->wl_comp_data->seat.im.resource = NULL;
|
||||
|
||||
input_method = wl_resource_get_user_data(resource);
|
||||
if (!input_method)
|
||||
{
|
||||
wl_resource_post_error(resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"No Input Method For Resource");
|
||||
return;
|
||||
}
|
||||
|
||||
if (input_method->model)
|
||||
_e_text_input_deactivate(input_method->model, input_method);
|
||||
|
||||
E_FREE_FUNC(input_method->handlers, ecore_event_handler_del);
|
||||
|
||||
input_method->resource = NULL;
|
||||
input_method->context = NULL;
|
||||
|
||||
free(input_method);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_text_cb_bind_input_method(struct wl_client *client, void *data EINA_UNUSED, uint32_t version EINA_UNUSED, uint32_t id)
|
||||
{
|
||||
E_Input_Method *input_method;
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create(client, &wl_input_method_interface, 1, id);
|
||||
if (!resource)
|
||||
{
|
||||
wl_client_post_no_memory(client);
|
||||
ERR("could not create wl_resource for input method");
|
||||
return;
|
||||
}
|
||||
|
||||
if (e_comp->wl_comp_data->seat.im.resource)
|
||||
{
|
||||
wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"interface object already bound");
|
||||
wl_resource_destroy(resource);
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME: we need to make sure the client attempting to bind
|
||||
this interface really provides vkbd. */
|
||||
|
||||
input_method = E_NEW(E_Input_Method, 1);
|
||||
if (!input_method)
|
||||
{
|
||||
wl_client_post_no_memory(client);
|
||||
wl_resource_destroy(resource);
|
||||
ERR("Could not allocate space for Input_Method");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_resource_set_implementation(resource, NULL, input_method,
|
||||
_e_text_input_method_cb_unbind);
|
||||
|
||||
input_method->model = NULL;
|
||||
input_method->context = NULL;
|
||||
input_method->resource = resource;
|
||||
|
||||
e_comp->wl_comp_data->seat.im.resource = resource;
|
||||
|
||||
E_LIST_HANDLER_APPEND(input_method->handlers, E_EVENT_CLIENT_FOCUS_IN,
|
||||
_e_text_input_cb_event_client_focus_in, input_method);
|
||||
}
|
||||
|
||||
EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_Text_Input" };
|
||||
|
||||
EAPI void *
|
||||
e_modapi_init(E_Module *m)
|
||||
{
|
||||
// FIXME: create only one input method object per seat.
|
||||
e_comp->wl_comp_data->seat.im.global =
|
||||
wl_global_create(e_comp->wl_comp_data->wl.disp, &wl_input_method_interface, 1,
|
||||
NULL, _e_text_cb_bind_input_method);
|
||||
if (!e_comp->wl_comp_data->seat.im.global)
|
||||
{
|
||||
ERR("failed to create wl_global for input method");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
text_input_manager_global =
|
||||
wl_global_create(e_comp->wl_comp_data->wl.disp, &wl_text_input_manager_interface, 1,
|
||||
NULL, _e_text_cb_bind_text_input_manager);
|
||||
if (!text_input_manager_global)
|
||||
{
|
||||
ERR("failed to create wl_global for text input manager");
|
||||
wl_global_destroy(e_comp->wl_comp_data->seat.im.global);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
e_modapi_shutdown(E_Module *m EINA_UNUSED)
|
||||
{
|
||||
E_FREE_FUNC(e_comp->wl_comp_data->seat.im.global, wl_global_destroy);
|
||||
E_FREE_FUNC(text_input_manager_global, wl_global_destroy);
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright © 2012, 2013 Intel Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this
|
||||
* software and its documentation for any purpose is hereby granted
|
||||
* without fee, provided that the above copyright notice appear in
|
||||
* all copies and that both that copyright notice and this permission
|
||||
* notice appear in supporting documentation, and that the name of
|
||||
* the copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
* THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
extern const struct wl_interface wl_input_method_context_interface;
|
||||
extern const struct wl_interface wl_input_panel_surface_interface;
|
||||
extern const struct wl_interface wl_keyboard_interface;
|
||||
extern const struct wl_interface wl_output_interface;
|
||||
extern const struct wl_interface wl_surface_interface;
|
||||
|
||||
static const struct wl_interface *types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&wl_keyboard_interface,
|
||||
&wl_input_method_context_interface,
|
||||
&wl_input_method_context_interface,
|
||||
&wl_input_panel_surface_interface,
|
||||
&wl_surface_interface,
|
||||
&wl_output_interface,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message wl_input_method_context_requests[] = {
|
||||
{ "destroy", "", types + 0 },
|
||||
{ "commit_string", "us", types + 0 },
|
||||
{ "preedit_string", "uss", types + 0 },
|
||||
{ "preedit_styling", "uuu", types + 0 },
|
||||
{ "preedit_cursor", "i", types + 0 },
|
||||
{ "delete_surrounding_text", "iu", types + 0 },
|
||||
{ "cursor_position", "ii", types + 0 },
|
||||
{ "modifiers_map", "a", types + 0 },
|
||||
{ "keysym", "uuuuu", types + 0 },
|
||||
{ "grab_keyboard", "n", types + 5 },
|
||||
{ "key", "uuuu", types + 0 },
|
||||
{ "modifiers", "uuuuu", types + 0 },
|
||||
{ "language", "us", types + 0 },
|
||||
{ "text_direction", "uu", types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message wl_input_method_context_events[] = {
|
||||
{ "surrounding_text", "suu", types + 0 },
|
||||
{ "reset", "", types + 0 },
|
||||
{ "content_type", "uu", types + 0 },
|
||||
{ "invoke_action", "uu", types + 0 },
|
||||
{ "commit_state", "u", types + 0 },
|
||||
{ "preferred_language", "s", types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface wl_input_method_context_interface = {
|
||||
"wl_input_method_context", 1,
|
||||
14, wl_input_method_context_requests,
|
||||
6, wl_input_method_context_events,
|
||||
};
|
||||
|
||||
static const struct wl_message wl_input_method_events[] = {
|
||||
{ "activate", "n", types + 6 },
|
||||
{ "deactivate", "o", types + 7 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface wl_input_method_interface = {
|
||||
"wl_input_method", 1,
|
||||
0, NULL,
|
||||
2, wl_input_method_events,
|
||||
};
|
||||
|
||||
static const struct wl_message wl_input_panel_requests[] = {
|
||||
{ "get_input_panel_surface", "no", types + 8 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface wl_input_panel_interface = {
|
||||
"wl_input_panel", 1,
|
||||
1, wl_input_panel_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message wl_input_panel_surface_requests[] = {
|
||||
{ "set_toplevel", "ou", types + 10 },
|
||||
{ "set_overlay_panel", "", types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface wl_input_panel_surface_interface = {
|
||||
"wl_input_panel_surface", 1,
|
||||
2, wl_input_panel_surface_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
|
@ -0,0 +1,418 @@
|
|||
/*
|
||||
* Copyright © 2012, 2013 Intel Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this
|
||||
* software and its documentation for any purpose is hereby granted
|
||||
* without fee, provided that the above copyright notice appear in
|
||||
* all copies and that both that copyright notice and this permission
|
||||
* notice appear in supporting documentation, and that the name of
|
||||
* the copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
* THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef INPUT_METHOD_SERVER_PROTOCOL_H
|
||||
#define INPUT_METHOD_SERVER_PROTOCOL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "wayland-server.h"
|
||||
|
||||
struct wl_client;
|
||||
struct wl_resource;
|
||||
|
||||
struct wl_input_method_context;
|
||||
struct wl_input_method;
|
||||
struct wl_input_panel;
|
||||
struct wl_input_panel_surface;
|
||||
|
||||
extern const struct wl_interface wl_input_method_context_interface;
|
||||
extern const struct wl_interface wl_input_method_interface;
|
||||
extern const struct wl_interface wl_input_panel_interface;
|
||||
extern const struct wl_interface wl_input_panel_surface_interface;
|
||||
|
||||
/**
|
||||
* wl_input_method_context - input method context
|
||||
* @destroy: (none)
|
||||
* @commit_string: commit string
|
||||
* @preedit_string: pre-edit string
|
||||
* @preedit_styling: pre-edit styling
|
||||
* @preedit_cursor: pre-edit cursor
|
||||
* @delete_surrounding_text: delete text
|
||||
* @cursor_position: set cursor to a new position
|
||||
* @modifiers_map: (none)
|
||||
* @keysym: keysym
|
||||
* @grab_keyboard: grab hardware keyboard
|
||||
* @key: forward key event
|
||||
* @modifiers: forward modifiers event
|
||||
* @language: (none)
|
||||
* @text_direction: (none)
|
||||
*
|
||||
* Corresponds to a text model on input method side. An input method
|
||||
* context is created on text model activation on the input method side. It
|
||||
* allows to receive information about the text model from the application
|
||||
* via events. Input method contexts do not keep state after deactivation
|
||||
* and should be destroyed after deactivation is handled.
|
||||
*
|
||||
* Text is generally UTF-8 encoded, indices and lengths are in bytes.
|
||||
*
|
||||
* Serials are used to synchronize the state between the text input and an
|
||||
* input method. New serials are sent by the text input in the commit_state
|
||||
* request and are used by the input method to indicate the known text
|
||||
* input state in events like preedit_string, commit_string, and keysym.
|
||||
* The text input can then ignore events from the input method which are
|
||||
* based on an outdated state (for example after a reset).
|
||||
*/
|
||||
struct wl_input_method_context_interface {
|
||||
/**
|
||||
* destroy - (none)
|
||||
*/
|
||||
void (*destroy)(struct wl_client *client,
|
||||
struct wl_resource *resource);
|
||||
/**
|
||||
* commit_string - commit string
|
||||
* @serial: serial of the latest known text input state
|
||||
* @text: (none)
|
||||
*
|
||||
* Send the commit string text for insertion to the application.
|
||||
*
|
||||
* The text to commit could be either just a single character after
|
||||
* a key press or the result of some composing (pre-edit). It could
|
||||
* be also an empty text when some text should be removed (see
|
||||
* delete_surrounding_text) or when the input cursor should be
|
||||
* moved (see cursor_position).
|
||||
*
|
||||
* Any previously set composing text will be removed.
|
||||
*/
|
||||
void (*commit_string)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
const char *text);
|
||||
/**
|
||||
* preedit_string - pre-edit string
|
||||
* @serial: serial of the latest known text input state
|
||||
* @text: (none)
|
||||
* @commit: (none)
|
||||
*
|
||||
* Send the pre-edit string text to the application text input.
|
||||
*
|
||||
* The commit text can be used to replace the preedit text on reset
|
||||
* (for example on unfocus).
|
||||
*
|
||||
* Also previously sent preedit_style and preedit_cursor requests
|
||||
* are processed bt the text_input also.
|
||||
*/
|
||||
void (*preedit_string)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
const char *text,
|
||||
const char *commit);
|
||||
/**
|
||||
* preedit_styling - pre-edit styling
|
||||
* @index: (none)
|
||||
* @length: (none)
|
||||
* @style: (none)
|
||||
*
|
||||
* Sets styling information on composing text. The style is
|
||||
* applied for length in bytes from index relative to the beginning
|
||||
* of the composing text (as byte offset). Multiple styles can be
|
||||
* applied to a composing text.
|
||||
*
|
||||
* This request should be sent before sending preedit_string
|
||||
* request.
|
||||
*/
|
||||
void (*preedit_styling)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t index,
|
||||
uint32_t length,
|
||||
uint32_t style);
|
||||
/**
|
||||
* preedit_cursor - pre-edit cursor
|
||||
* @index: (none)
|
||||
*
|
||||
* Sets the cursor position inside the composing text (as byte
|
||||
* offset) relative to the start of the composing text.
|
||||
*
|
||||
* When index is negative no cursor should be displayed.
|
||||
*
|
||||
* This request should be sent before sending preedit_string
|
||||
* request.
|
||||
*/
|
||||
void (*preedit_cursor)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
int32_t index);
|
||||
/**
|
||||
* delete_surrounding_text - delete text
|
||||
* @index: (none)
|
||||
* @length: (none)
|
||||
*
|
||||
*
|
||||
*
|
||||
* This request will be handled on text_input side as part of a
|
||||
* directly following commit_string request.
|
||||
*/
|
||||
void (*delete_surrounding_text)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
int32_t index,
|
||||
uint32_t length);
|
||||
/**
|
||||
* cursor_position - set cursor to a new position
|
||||
* @index: (none)
|
||||
* @anchor: (none)
|
||||
*
|
||||
* Sets the cursor and anchor to a new position. Index is the new
|
||||
* cursor position in bytes (when >= 0 relative to the end of
|
||||
* inserted text else relative to beginning of inserted text).
|
||||
* Anchor is the new anchor position in bytes (when >= 0 relative
|
||||
* to the end of inserted text, else relative to beginning of
|
||||
* inserted text). When there should be no selected text anchor
|
||||
* should be the same as index.
|
||||
*
|
||||
* This request will be handled on text_input side as part of a
|
||||
* directly following commit_string request.
|
||||
*/
|
||||
void (*cursor_position)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
int32_t index,
|
||||
int32_t anchor);
|
||||
/**
|
||||
* modifiers_map - (none)
|
||||
* @map: (none)
|
||||
*/
|
||||
void (*modifiers_map)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_array *map);
|
||||
/**
|
||||
* keysym - keysym
|
||||
* @serial: serial of the latest known text input state
|
||||
* @time: (none)
|
||||
* @sym: (none)
|
||||
* @state: (none)
|
||||
* @modifiers: (none)
|
||||
*
|
||||
* Notify when a key event was sent. Key events should not be
|
||||
* used for normal text input operations, which should be done with
|
||||
* commit_string, delete_surrounfing_text, etc. The key event
|
||||
* follows the wl_keyboard key event convention. Sym is a XKB
|
||||
* keysym, state a wl_keyboard key_state.
|
||||
*/
|
||||
void (*keysym)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
uint32_t sym,
|
||||
uint32_t state,
|
||||
uint32_t modifiers);
|
||||
/**
|
||||
* grab_keyboard - grab hardware keyboard
|
||||
* @keyboard: (none)
|
||||
*
|
||||
* Allows 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.
|
||||
*/
|
||||
void (*grab_keyboard)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t keyboard);
|
||||
/**
|
||||
* key - forward key event
|
||||
* @serial: serial from wl_keyboard::key
|
||||
* @time: time from wl_keyboard::key
|
||||
* @key: key from wl_keyboard::key
|
||||
* @state: state from wl_keyboard::key
|
||||
*
|
||||
* Should be used when filtering key events with grab_keyboard.
|
||||
*
|
||||
* When the wl_keyboard::key event is not processed by the input
|
||||
* method itself and should be sent to the client instead, forward
|
||||
* it with this request. The arguments should be the ones from the
|
||||
* wl_keyboard::key event.
|
||||
*
|
||||
* For generating custom key events use the keysym request instead.
|
||||
*/
|
||||
void (*key)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
uint32_t key,
|
||||
uint32_t state);
|
||||
/**
|
||||
* modifiers - forward modifiers event
|
||||
* @serial: serial from wl_keyboard::modifiers
|
||||
* @mods_depressed: mods_depressed from wl_keyboard::modifiers
|
||||
* @mods_latched: mods_latched from wl_keyboard::modifiers
|
||||
* @mods_locked: mods_locked from wl_keyboard::modifiers
|
||||
* @group: group from wl_keyboard::modifiers
|
||||
*
|
||||
* Should be used when filtering key events with grab_keyboard.
|
||||
*
|
||||
* When the wl_keyboard::modifiers event should be also send to the
|
||||
* client, forward it with this request. The arguments should be
|
||||
* the ones from the wl_keyboard::modifiers event.
|
||||
*/
|
||||
void (*modifiers)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
uint32_t mods_depressed,
|
||||
uint32_t mods_latched,
|
||||
uint32_t mods_locked,
|
||||
uint32_t group);
|
||||
/**
|
||||
* language - (none)
|
||||
* @serial: serial of the latest known text input state
|
||||
* @language: (none)
|
||||
*/
|
||||
void (*language)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
const char *language);
|
||||
/**
|
||||
* text_direction - (none)
|
||||
* @serial: serial of the latest known text input state
|
||||
* @direction: (none)
|
||||
*/
|
||||
void (*text_direction)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial,
|
||||
uint32_t direction);
|
||||
};
|
||||
|
||||
#define WL_INPUT_METHOD_CONTEXT_SURROUNDING_TEXT 0
|
||||
#define WL_INPUT_METHOD_CONTEXT_RESET 1
|
||||
#define WL_INPUT_METHOD_CONTEXT_CONTENT_TYPE 2
|
||||
#define WL_INPUT_METHOD_CONTEXT_INVOKE_ACTION 3
|
||||
#define WL_INPUT_METHOD_CONTEXT_COMMIT_STATE 4
|
||||
#define WL_INPUT_METHOD_CONTEXT_PREFERRED_LANGUAGE 5
|
||||
|
||||
#define WL_INPUT_METHOD_CONTEXT_SURROUNDING_TEXT_SINCE_VERSION 1
|
||||
#define WL_INPUT_METHOD_CONTEXT_RESET_SINCE_VERSION 1
|
||||
#define WL_INPUT_METHOD_CONTEXT_CONTENT_TYPE_SINCE_VERSION 1
|
||||
#define WL_INPUT_METHOD_CONTEXT_INVOKE_ACTION_SINCE_VERSION 1
|
||||
#define WL_INPUT_METHOD_CONTEXT_COMMIT_STATE_SINCE_VERSION 1
|
||||
#define WL_INPUT_METHOD_CONTEXT_PREFERRED_LANGUAGE_SINCE_VERSION 1
|
||||
|
||||
static inline void
|
||||
wl_input_method_context_send_surrounding_text(struct wl_resource *resource_, const char *text, uint32_t cursor, uint32_t anchor)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_SURROUNDING_TEXT, text, cursor, anchor);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_input_method_context_send_reset(struct wl_resource *resource_)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_RESET);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_input_method_context_send_content_type(struct wl_resource *resource_, uint32_t hint, uint32_t purpose)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_CONTENT_TYPE, hint, purpose);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_input_method_context_send_invoke_action(struct wl_resource *resource_, uint32_t button, uint32_t index)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_INVOKE_ACTION, button, index);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_input_method_context_send_commit_state(struct wl_resource *resource_, uint32_t serial)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_COMMIT_STATE, serial);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_input_method_context_send_preferred_language(struct wl_resource *resource_, const char *language)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_CONTEXT_PREFERRED_LANGUAGE, language);
|
||||
}
|
||||
|
||||
#define WL_INPUT_METHOD_ACTIVATE 0
|
||||
#define WL_INPUT_METHOD_DEACTIVATE 1
|
||||
|
||||
#define WL_INPUT_METHOD_ACTIVATE_SINCE_VERSION 1
|
||||
#define WL_INPUT_METHOD_DEACTIVATE_SINCE_VERSION 1
|
||||
|
||||
static inline void
|
||||
wl_input_method_send_activate(struct wl_resource *resource_, struct wl_resource *id)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_ACTIVATE, id);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_input_method_send_deactivate(struct wl_resource *resource_, struct wl_resource *context)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_INPUT_METHOD_DEACTIVATE, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* wl_input_panel - interface for implementing keyboards
|
||||
* @get_input_panel_surface: (none)
|
||||
*
|
||||
* Only one client can bind this interface at a time.
|
||||
*/
|
||||
struct wl_input_panel_interface {
|
||||
/**
|
||||
* get_input_panel_surface - (none)
|
||||
* @id: (none)
|
||||
* @surface: (none)
|
||||
*/
|
||||
void (*get_input_panel_surface)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t id,
|
||||
struct wl_resource *surface);
|
||||
};
|
||||
|
||||
|
||||
#ifndef WL_INPUT_PANEL_SURFACE_POSITION_ENUM
|
||||
#define WL_INPUT_PANEL_SURFACE_POSITION_ENUM
|
||||
enum wl_input_panel_surface_position {
|
||||
WL_INPUT_PANEL_SURFACE_POSITION_CENTER_BOTTOM = 0,
|
||||
};
|
||||
#endif /* WL_INPUT_PANEL_SURFACE_POSITION_ENUM */
|
||||
|
||||
struct wl_input_panel_surface_interface {
|
||||
/**
|
||||
* set_toplevel - set the surface type as a keyboard
|
||||
* @output: (none)
|
||||
* @position: (none)
|
||||
*
|
||||
* A keyboard surface is only shown, when a text model is active
|
||||
*/
|
||||
void (*set_toplevel)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *output,
|
||||
uint32_t position);
|
||||
/**
|
||||
* set_overlay_panel - set the surface type as an overlay panel
|
||||
*
|
||||
* An overlay panel is shown near the input cursor above the
|
||||
* application window when a text model is active.
|
||||
*/
|
||||
void (*set_overlay_panel)(struct wl_client *client,
|
||||
struct wl_resource *resource);
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright © 2012, 2013 Intel Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this
|
||||
* software and its documentation for any purpose is hereby granted
|
||||
* without fee, provided that the above copyright notice appear in
|
||||
* all copies and that both that copyright notice and this permission
|
||||
* notice appear in supporting documentation, and that the name of
|
||||
* the copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
* THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
extern const struct wl_interface wl_seat_interface;
|
||||
extern const struct wl_interface wl_surface_interface;
|
||||
extern const struct wl_interface wl_text_input_interface;
|
||||
|
||||
static const struct wl_interface *types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&wl_seat_interface,
|
||||
&wl_surface_interface,
|
||||
&wl_seat_interface,
|
||||
&wl_surface_interface,
|
||||
&wl_text_input_interface,
|
||||
};
|
||||
|
||||
static const struct wl_message wl_text_input_requests[] = {
|
||||
{ "activate", "oo", types + 5 },
|
||||
{ "deactivate", "o", types + 7 },
|
||||
{ "show_input_panel", "", types + 0 },
|
||||
{ "hide_input_panel", "", types + 0 },
|
||||
{ "reset", "", types + 0 },
|
||||
{ "set_surrounding_text", "suu", types + 0 },
|
||||
{ "set_content_type", "uu", types + 0 },
|
||||
{ "set_cursor_rectangle", "iiii", types + 0 },
|
||||
{ "set_preferred_language", "s", types + 0 },
|
||||
{ "commit_state", "u", types + 0 },
|
||||
{ "invoke_action", "uu", types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message wl_text_input_events[] = {
|
||||
{ "enter", "o", types + 8 },
|
||||
{ "leave", "", types + 0 },
|
||||
{ "modifiers_map", "a", types + 0 },
|
||||
{ "input_panel_state", "u", types + 0 },
|
||||
{ "preedit_string", "uss", types + 0 },
|
||||
{ "preedit_styling", "uuu", types + 0 },
|
||||
{ "preedit_cursor", "i", types + 0 },
|
||||
{ "commit_string", "us", types + 0 },
|
||||
{ "cursor_position", "ii", types + 0 },
|
||||
{ "delete_surrounding_text", "iu", types + 0 },
|
||||
{ "keysym", "uuuuu", types + 0 },
|
||||
{ "language", "us", types + 0 },
|
||||
{ "text_direction", "uu", types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface wl_text_input_interface = {
|
||||
"wl_text_input", 1,
|
||||
11, wl_text_input_requests,
|
||||
13, wl_text_input_events,
|
||||
};
|
||||
|
||||
static const struct wl_message wl_text_input_manager_requests[] = {
|
||||
{ "create_text_input", "n", types + 9 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface wl_text_input_manager_interface = {
|
||||
"wl_text_input_manager", 1,
|
||||
1, wl_text_input_manager_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
|
@ -0,0 +1,448 @@
|
|||
/*
|
||||
* Copyright © 2012, 2013 Intel Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this
|
||||
* software and its documentation for any purpose is hereby granted
|
||||
* without fee, provided that the above copyright notice appear in
|
||||
* all copies and that both that copyright notice and this permission
|
||||
* notice appear in supporting documentation, and that the name of
|
||||
* the copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
* THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef TEXT_SERVER_PROTOCOL_H
|
||||
#define TEXT_SERVER_PROTOCOL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
struct wl_client;
|
||||
struct wl_resource;
|
||||
|
||||
struct wl_text_input;
|
||||
struct wl_text_input_manager;
|
||||
|
||||
extern const struct wl_interface wl_text_input_interface;
|
||||
extern const struct wl_interface wl_text_input_manager_interface;
|
||||
|
||||
#ifndef WL_TEXT_INPUT_CONTENT_HINT_ENUM
|
||||
#define WL_TEXT_INPUT_CONTENT_HINT_ENUM
|
||||
/**
|
||||
* wl_text_input_content_hint - content hint
|
||||
* @WL_TEXT_INPUT_CONTENT_HINT_NONE: no special behaviour
|
||||
* @WL_TEXT_INPUT_CONTENT_HINT_DEFAULT: auto completion, correction and
|
||||
* capitalization
|
||||
* @WL_TEXT_INPUT_CONTENT_HINT_PASSWORD: hidden and sensitive text
|
||||
* @WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION: suggest word completions
|
||||
* @WL_TEXT_INPUT_CONTENT_HINT_AUTO_CORRECTION: suggest word corrections
|
||||
* @WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION: switch to uppercase
|
||||
* letters at the start of a sentence
|
||||
* @WL_TEXT_INPUT_CONTENT_HINT_LOWERCASE: prefer lowercase letters
|
||||
* @WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE: prefer uppercase letters
|
||||
* @WL_TEXT_INPUT_CONTENT_HINT_TITLECASE: prefer casing for titles and
|
||||
* headings (can be language dependent)
|
||||
* @WL_TEXT_INPUT_CONTENT_HINT_HIDDEN_TEXT: characters should be hidden
|
||||
* @WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA: typed text should not be
|
||||
* stored
|
||||
* @WL_TEXT_INPUT_CONTENT_HINT_LATIN: just latin characters should be
|
||||
* entered
|
||||
* @WL_TEXT_INPUT_CONTENT_HINT_MULTILINE: the text input is multiline
|
||||
*
|
||||
* Content hint is a bitmask to allow to modify the behavior of the text
|
||||
* input.
|
||||
*/
|
||||
enum wl_text_input_content_hint {
|
||||
WL_TEXT_INPUT_CONTENT_HINT_NONE = 0x0,
|
||||
WL_TEXT_INPUT_CONTENT_HINT_DEFAULT = 0x7,
|
||||
WL_TEXT_INPUT_CONTENT_HINT_PASSWORD = 0xc0,
|
||||
WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION = 0x1,
|
||||
WL_TEXT_INPUT_CONTENT_HINT_AUTO_CORRECTION = 0x2,
|
||||
WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION = 0x4,
|
||||
WL_TEXT_INPUT_CONTENT_HINT_LOWERCASE = 0x8,
|
||||
WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE = 0x10,
|
||||
WL_TEXT_INPUT_CONTENT_HINT_TITLECASE = 0x20,
|
||||
WL_TEXT_INPUT_CONTENT_HINT_HIDDEN_TEXT = 0x40,
|
||||
WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA = 0x80,
|
||||
WL_TEXT_INPUT_CONTENT_HINT_LATIN = 0x100,
|
||||
WL_TEXT_INPUT_CONTENT_HINT_MULTILINE = 0x200,
|
||||
};
|
||||
#endif /* WL_TEXT_INPUT_CONTENT_HINT_ENUM */
|
||||
|
||||
#ifndef WL_TEXT_INPUT_CONTENT_PURPOSE_ENUM
|
||||
#define WL_TEXT_INPUT_CONTENT_PURPOSE_ENUM
|
||||
/**
|
||||
* wl_text_input_content_purpose - content purpose
|
||||
* @WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL: default input, allowing all
|
||||
* characters
|
||||
* @WL_TEXT_INPUT_CONTENT_PURPOSE_ALPHA: allow only alphabetic characters
|
||||
* @WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS: allow only digits
|
||||
* @WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER: input a number (including
|
||||
* decimal separator and sign)
|
||||
* @WL_TEXT_INPUT_CONTENT_PURPOSE_PHONE: input a phone number
|
||||
* @WL_TEXT_INPUT_CONTENT_PURPOSE_URL: input an URL
|
||||
* @WL_TEXT_INPUT_CONTENT_PURPOSE_EMAIL: input an email address
|
||||
* @WL_TEXT_INPUT_CONTENT_PURPOSE_NAME: input a name of a person
|
||||
* @WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD: input a password (combine
|
||||
* with password or sensitive_data hint)
|
||||
* @WL_TEXT_INPUT_CONTENT_PURPOSE_DATE: input a date
|
||||
* @WL_TEXT_INPUT_CONTENT_PURPOSE_TIME: input a time
|
||||
* @WL_TEXT_INPUT_CONTENT_PURPOSE_DATETIME: input a date and time
|
||||
* @WL_TEXT_INPUT_CONTENT_PURPOSE_TERMINAL: input for a terminal
|
||||
*
|
||||
* The content purpose allows to specify the primary purpose of a text
|
||||
* input.
|
||||
*
|
||||
* This allows an input method to show special purpose input panels with
|
||||
* extra characters or to disallow some characters.
|
||||
*/
|
||||
enum wl_text_input_content_purpose {
|
||||
WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL = 0,
|
||||
WL_TEXT_INPUT_CONTENT_PURPOSE_ALPHA = 1,
|
||||
WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS = 2,
|
||||
WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER = 3,
|
||||
WL_TEXT_INPUT_CONTENT_PURPOSE_PHONE = 4,
|
||||
WL_TEXT_INPUT_CONTENT_PURPOSE_URL = 5,
|
||||
WL_TEXT_INPUT_CONTENT_PURPOSE_EMAIL = 6,
|
||||
WL_TEXT_INPUT_CONTENT_PURPOSE_NAME = 7,
|
||||
WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD = 8,
|
||||
WL_TEXT_INPUT_CONTENT_PURPOSE_DATE = 9,
|
||||
WL_TEXT_INPUT_CONTENT_PURPOSE_TIME = 10,
|
||||
WL_TEXT_INPUT_CONTENT_PURPOSE_DATETIME = 11,
|
||||
WL_TEXT_INPUT_CONTENT_PURPOSE_TERMINAL = 12,
|
||||
};
|
||||
#endif /* WL_TEXT_INPUT_CONTENT_PURPOSE_ENUM */
|
||||
|
||||
#ifndef WL_TEXT_INPUT_PREEDIT_STYLE_ENUM
|
||||
#define WL_TEXT_INPUT_PREEDIT_STYLE_ENUM
|
||||
enum wl_text_input_preedit_style {
|
||||
WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT = 0,
|
||||
WL_TEXT_INPUT_PREEDIT_STYLE_NONE = 1,
|
||||
WL_TEXT_INPUT_PREEDIT_STYLE_ACTIVE = 2,
|
||||
WL_TEXT_INPUT_PREEDIT_STYLE_INACTIVE = 3,
|
||||
WL_TEXT_INPUT_PREEDIT_STYLE_HIGHLIGHT = 4,
|
||||
WL_TEXT_INPUT_PREEDIT_STYLE_UNDERLINE = 5,
|
||||
WL_TEXT_INPUT_PREEDIT_STYLE_SELECTION = 6,
|
||||
WL_TEXT_INPUT_PREEDIT_STYLE_INCORRECT = 7,
|
||||
};
|
||||
#endif /* WL_TEXT_INPUT_PREEDIT_STYLE_ENUM */
|
||||
|
||||
#ifndef WL_TEXT_INPUT_TEXT_DIRECTION_ENUM
|
||||
#define WL_TEXT_INPUT_TEXT_DIRECTION_ENUM
|
||||
enum wl_text_input_text_direction {
|
||||
WL_TEXT_INPUT_TEXT_DIRECTION_AUTO = 0,
|
||||
WL_TEXT_INPUT_TEXT_DIRECTION_LTR = 1,
|
||||
WL_TEXT_INPUT_TEXT_DIRECTION_RTL = 2,
|
||||
};
|
||||
#endif /* WL_TEXT_INPUT_TEXT_DIRECTION_ENUM */
|
||||
|
||||
/**
|
||||
* wl_text_input - text input
|
||||
* @activate: request activation
|
||||
* @deactivate: request deactivation
|
||||
* @show_input_panel: show input panels
|
||||
* @hide_input_panel: hide input panels
|
||||
* @reset: reset
|
||||
* @set_surrounding_text: sets the surrounding text
|
||||
* @set_content_type: set content purpose and hint
|
||||
* @set_cursor_rectangle: (none)
|
||||
* @set_preferred_language: sets preferred language
|
||||
* @commit_state: (none)
|
||||
* @invoke_action: (none)
|
||||
*
|
||||
* An object used for text input. Adds support for text input and input
|
||||
* methods to applications. A text-input object is created from a
|
||||
* wl_text_input_manager and corresponds typically to a text entry in an
|
||||
* application. Requests are used to activate/deactivate the text-input
|
||||
* object and set state information like surrounding and selected text or
|
||||
* the content type. The information about entered text is sent to the
|
||||
* text-input object via the pre-edit and commit events. Using this
|
||||
* interface removes the need for applications to directly process hardware
|
||||
* key events and compose text out of them.
|
||||
*
|
||||
* Text is generally UTF-8 encoded, indices and lengths are in bytes.
|
||||
*
|
||||
* Serials are used to synchronize the state between the text input and an
|
||||
* input method. New serials are sent by the text input in the commit_state
|
||||
* request and are used by the input method to indicate the known text
|
||||
* input state in events like preedit_string, commit_string, and keysym.
|
||||
* The text input can then ignore events from the input method which are
|
||||
* based on an outdated state (for example after a reset).
|
||||
*/
|
||||
struct wl_text_input_interface {
|
||||
/**
|
||||
* activate - request activation
|
||||
* @seat: (none)
|
||||
* @surface: (none)
|
||||
*
|
||||
* Requests the text-input object to be activated (typically when
|
||||
* the text entry gets focus). The seat argument is a wl_seat which
|
||||
* maintains the focus for this activation. The surface argument is
|
||||
* a wl_surface assigned to the text-input object and tracked for
|
||||
* focus lost. The enter event is emitted on successful activation.
|
||||
*/
|
||||
void (*activate)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *seat,
|
||||
struct wl_resource *surface);
|
||||
/**
|
||||
* deactivate - request deactivation
|
||||
* @seat: (none)
|
||||
*
|
||||
* Requests the text-input object to be deactivated (typically
|
||||
* when the text entry lost focus). The seat argument is a wl_seat
|
||||
* which was used for activation.
|
||||
*/
|
||||
void (*deactivate)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *seat);
|
||||
/**
|
||||
* show_input_panel - show input panels
|
||||
*
|
||||
* Requests input panels (virtual keyboard) to show.
|
||||
*/
|
||||
void (*show_input_panel)(struct wl_client *client,
|
||||
struct wl_resource *resource);
|
||||
/**
|
||||
* hide_input_panel - hide input panels
|
||||
*
|
||||
* Requests input panels (virtual keyboard) to hide.
|
||||
*/
|
||||
void (*hide_input_panel)(struct wl_client *client,
|
||||
struct wl_resource *resource);
|
||||
/**
|
||||
* reset - reset
|
||||
*
|
||||
* Should be called by an editor widget when the input state
|
||||
* should be reset, for example after the text was changed outside
|
||||
* of the normal input method flow.
|
||||
*/
|
||||
void (*reset)(struct wl_client *client,
|
||||
struct wl_resource *resource);
|
||||
/**
|
||||
* set_surrounding_text - sets the surrounding text
|
||||
* @text: (none)
|
||||
* @cursor: (none)
|
||||
* @anchor: (none)
|
||||
*
|
||||
* Sets the plain surrounding text around the input position.
|
||||
* Text is UTF-8 encoded. Cursor is the byte offset within the
|
||||
* surrounding text. Anchor is the byte offset of the selection
|
||||
* anchor within the surrounding text. If there is no selected text
|
||||
* anchor is the same as cursor.
|
||||
*/
|
||||
void (*set_surrounding_text)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
const char *text,
|
||||
uint32_t cursor,
|
||||
uint32_t anchor);
|
||||
/**
|
||||
* set_content_type - set content purpose and hint
|
||||
* @hint: (none)
|
||||
* @purpose: (none)
|
||||
*
|
||||
* Sets the content purpose and content hint. While the purpose
|
||||
* is the basic purpose of an input field, the hint flags allow to
|
||||
* modify some of the behavior.
|
||||
*
|
||||
* When no content type is explicitly set, a normal content purpose
|
||||
* with default hints (auto completion, auto correction, auto
|
||||
* capitalization) should be assumed.
|
||||
*/
|
||||
void (*set_content_type)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t hint,
|
||||
uint32_t purpose);
|
||||
/**
|
||||
* set_cursor_rectangle - (none)
|
||||
* @x: (none)
|
||||
* @y: (none)
|
||||
* @width: (none)
|
||||
* @height: (none)
|
||||
*/
|
||||
void (*set_cursor_rectangle)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
int32_t x,
|
||||
int32_t y,
|
||||
int32_t width,
|
||||
int32_t height);
|
||||
/**
|
||||
* set_preferred_language - sets preferred language
|
||||
* @language: (none)
|
||||
*
|
||||
* Sets a specific language. This allows for example a virtual
|
||||
* keyboard to show a language specific layout. The "language"
|
||||
* argument is a RFC-3066 format language tag.
|
||||
*
|
||||
* It could be used for example in a word processor to indicate
|
||||
* language of currently edited document or in an instant message
|
||||
* application which tracks languages of contacts.
|
||||
*/
|
||||
void (*set_preferred_language)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
const char *language);
|
||||
/**
|
||||
* commit_state - (none)
|
||||
* @serial: used to identify the known state
|
||||
*/
|
||||
void (*commit_state)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t serial);
|
||||
/**
|
||||
* invoke_action - (none)
|
||||
* @button: (none)
|
||||
* @index: (none)
|
||||
*/
|
||||
void (*invoke_action)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t button,
|
||||
uint32_t index);
|
||||
};
|
||||
|
||||
#define WL_TEXT_INPUT_ENTER 0
|
||||
#define WL_TEXT_INPUT_LEAVE 1
|
||||
#define WL_TEXT_INPUT_MODIFIERS_MAP 2
|
||||
#define WL_TEXT_INPUT_INPUT_PANEL_STATE 3
|
||||
#define WL_TEXT_INPUT_PREEDIT_STRING 4
|
||||
#define WL_TEXT_INPUT_PREEDIT_STYLING 5
|
||||
#define WL_TEXT_INPUT_PREEDIT_CURSOR 6
|
||||
#define WL_TEXT_INPUT_COMMIT_STRING 7
|
||||
#define WL_TEXT_INPUT_CURSOR_POSITION 8
|
||||
#define WL_TEXT_INPUT_DELETE_SURROUNDING_TEXT 9
|
||||
#define WL_TEXT_INPUT_KEYSYM 10
|
||||
#define WL_TEXT_INPUT_LANGUAGE 11
|
||||
#define WL_TEXT_INPUT_TEXT_DIRECTION 12
|
||||
|
||||
#define WL_TEXT_INPUT_ENTER_SINCE_VERSION 1
|
||||
#define WL_TEXT_INPUT_LEAVE_SINCE_VERSION 1
|
||||
#define WL_TEXT_INPUT_MODIFIERS_MAP_SINCE_VERSION 1
|
||||
#define WL_TEXT_INPUT_INPUT_PANEL_STATE_SINCE_VERSION 1
|
||||
#define WL_TEXT_INPUT_PREEDIT_STRING_SINCE_VERSION 1
|
||||
#define WL_TEXT_INPUT_PREEDIT_STYLING_SINCE_VERSION 1
|
||||
#define WL_TEXT_INPUT_PREEDIT_CURSOR_SINCE_VERSION 1
|
||||
#define WL_TEXT_INPUT_COMMIT_STRING_SINCE_VERSION 1
|
||||
#define WL_TEXT_INPUT_CURSOR_POSITION_SINCE_VERSION 1
|
||||
#define WL_TEXT_INPUT_DELETE_SURROUNDING_TEXT_SINCE_VERSION 1
|
||||
#define WL_TEXT_INPUT_KEYSYM_SINCE_VERSION 1
|
||||
#define WL_TEXT_INPUT_LANGUAGE_SINCE_VERSION 1
|
||||
#define WL_TEXT_INPUT_TEXT_DIRECTION_SINCE_VERSION 1
|
||||
|
||||
static inline void
|
||||
wl_text_input_send_enter(struct wl_resource *resource_, struct wl_resource *surface)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_TEXT_INPUT_ENTER, surface);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_send_leave(struct wl_resource *resource_)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_TEXT_INPUT_LEAVE);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_send_modifiers_map(struct wl_resource *resource_, struct wl_array *map)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_TEXT_INPUT_MODIFIERS_MAP, map);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_send_input_panel_state(struct wl_resource *resource_, uint32_t state)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_TEXT_INPUT_INPUT_PANEL_STATE, state);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_send_preedit_string(struct wl_resource *resource_, uint32_t serial, const char *text, const char *commit)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_TEXT_INPUT_PREEDIT_STRING, serial, text, commit);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_send_preedit_styling(struct wl_resource *resource_, uint32_t index, uint32_t length, uint32_t style)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_TEXT_INPUT_PREEDIT_STYLING, index, length, style);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_send_preedit_cursor(struct wl_resource *resource_, int32_t index)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_TEXT_INPUT_PREEDIT_CURSOR, index);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_send_commit_string(struct wl_resource *resource_, uint32_t serial, const char *text)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_TEXT_INPUT_COMMIT_STRING, serial, text);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_send_cursor_position(struct wl_resource *resource_, int32_t index, int32_t anchor)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_TEXT_INPUT_CURSOR_POSITION, index, anchor);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_send_delete_surrounding_text(struct wl_resource *resource_, int32_t index, uint32_t length)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_TEXT_INPUT_DELETE_SURROUNDING_TEXT, index, length);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_send_keysym(struct wl_resource *resource_, uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_TEXT_INPUT_KEYSYM, serial, time, sym, state, modifiers);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_send_language(struct wl_resource *resource_, uint32_t serial, const char *language)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_TEXT_INPUT_LANGUAGE, serial, language);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_send_text_direction(struct wl_resource *resource_, uint32_t serial, uint32_t direction)
|
||||
{
|
||||
wl_resource_post_event(resource_, WL_TEXT_INPUT_TEXT_DIRECTION, serial, direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* wl_text_input_manager - text input manager
|
||||
* @create_text_input: create text input
|
||||
*
|
||||
* A factory for text-input objects. This object is a global singleton.
|
||||
*/
|
||||
struct wl_text_input_manager_interface {
|
||||
/**
|
||||
* create_text_input - create text input
|
||||
* @id: (none)
|
||||
*
|
||||
* Creates a new text-input object.
|
||||
*/
|
||||
void (*create_text_input)(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t id);
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue