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:
Seunghun Lee 2015-08-20 14:55:14 -04:00 committed by Mike Blumenkrantz
parent ac56ba57d1
commit 26d352f219
17 changed files with 2955 additions and 0 deletions

View File

@ -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])

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,
};

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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,
};

View File

@ -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

View File

@ -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,
};

View File

@ -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