forked from enlightenment/efl
ecore_imf: Add support for wayland
Add an input method module supporting the Wayland input method protocol. In v2: - Missing call to ecore_wl_shutdown() in im_module_shutdown() - Access the already stored 'wayland globals' with ecore_wl_globals_get() - Fixed compilation by adding -I(top_srcdir)/src/efl to CFLAGS - EFL formatting fixes Signed-off-by: Eduardo Lima (Etrunko) <eduardo.lima@intel.com>
This commit is contained in:
parent
1f298139d8
commit
f656aa397f
18
configure.ac
18
configure.ac
|
@ -2771,6 +2771,7 @@ want_ecore_imf="yes"
|
|||
want_ecore_imf_xim="no"
|
||||
want_ecore_imf_scim="no"
|
||||
want_ecore_imf_ibus="no"
|
||||
want_ecore_imf_wayland="no"
|
||||
|
||||
if test "${have_wince}" = "yes"; then
|
||||
want_ecore_imf="no"
|
||||
|
@ -2782,6 +2783,9 @@ else
|
|||
want_ecore_imf_xim="yes"
|
||||
want_ecore_imf_scim="yes"
|
||||
want_ecore_imf_ibus="yes"
|
||||
if test "${want_wayland}" = "yes"; then
|
||||
want_ecore_imf_wayland="yes"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -2851,6 +2855,20 @@ fi
|
|||
AM_CONDITIONAL([BUILD_ECORE_IMF_XIM], [test "x${have_ecore_imf_xim}" = "xyes"])
|
||||
EFL_ADD_FEATURE([ECORE_IMF], [xim])
|
||||
|
||||
# wayland
|
||||
if test "x${want_ecore_imf_wayland}" = "xyes" ; then
|
||||
PKG_CHECK_MODULES([WAYLAND],
|
||||
[wayland-client],
|
||||
[
|
||||
have_ecore_imf_wayland="yes"
|
||||
AC_DEFINE([BUILD_ECORE_IMF_WAYLAND], [1], [Ecore Imf Wayland Support])
|
||||
],
|
||||
[have_ecore_imf_wayland="no"])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([BUILD_ECORE_IMF_WAYLAND], [test "x${have_ecore_imf_wayland}" = "xyes"])
|
||||
EFL_ADD_FEATURE([ECORE_IMF], [wayland], [${want_ecore_imf_wayland}])
|
||||
|
||||
### Checks for header files
|
||||
|
||||
### Checks for types
|
||||
|
|
|
@ -101,3 +101,29 @@ modules_ecore_imf_xim_module_la_DEPENDENCIES = \
|
|||
modules_ecore_imf_xim_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
modules_ecore_imf_xim_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
||||
# Wayland
|
||||
if BUILD_ECORE_IMF_WAYLAND
|
||||
ecoreimfwaylandpkgdir = $(libdir)/ecore_imf/modules/wayland/$(MODULE_ARCH)
|
||||
ecoreimfwaylandpkg_LTLIBRARIES = modules/ecore_imf/wayland/module.la
|
||||
modules_ecore_imf_wayland_module_la_SOURCES = \
|
||||
modules/ecore_imf/wayland/wayland_module.c \
|
||||
modules/ecore_imf/wayland/wayland_imcontext.c \
|
||||
modules/ecore_imf/wayland/wayland_imcontext.h \
|
||||
modules/ecore_imf/wayland/text-client-protocol.h \
|
||||
modules/ecore_imf/wayland/text-protocol.c
|
||||
modules_ecore_imf_wayland_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
@ECORE_IMF_CFLAGS@ \
|
||||
@ECORE_EVAS_CFLAGS@ \
|
||||
@ECORE_WAYLAND_CFLAGS@
|
||||
modules_ecore_imf_wayland_module_la_LIBADD = \
|
||||
@USE_ECORE_IMF_LIBS@ \
|
||||
@USE_ECORE_EVAS_LIBS@ \
|
||||
@USE_ECORE_WAYLAND_LIBS@
|
||||
modules_ecore_imf_wayland_module_la_DEPENDENCIES = \
|
||||
@USE_ECORE_IMF_INTERNAL_LIBS@ \
|
||||
@USE_ECORE_EVAS_INTERNAL_LIBS@ \
|
||||
@USE_ECORE_WAYLAND_INTERNAL_LIBS@
|
||||
modules_ecore_imf_wayland_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
|
||||
modules_ecore_imf_wayland_module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,544 @@
|
|||
/*
|
||||
* 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_CLIENT_PROTOCOL_H
|
||||
#define TEXT_CLIENT_PROTOCOL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "wayland-client.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
|
||||
* @enter: enter event
|
||||
* @leave: leave event
|
||||
* @modifiers_map: modifiers map
|
||||
* @input_panel_state: state of the input panel
|
||||
* @preedit_string: pre-edit
|
||||
* @preedit_styling: pre-edit styling
|
||||
* @preedit_cursor: pre-edit cursor
|
||||
* @commit_string: commit
|
||||
* @cursor_position: set cursor to new position
|
||||
* @delete_surrounding_text: delete surrounding text
|
||||
* @keysym: keysym
|
||||
* @language: language
|
||||
* @text_direction: text direction
|
||||
*
|
||||
* 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 Unicode
|
||||
* characters.
|
||||
*
|
||||
* 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_listener {
|
||||
/**
|
||||
* enter - enter event
|
||||
* @surface: (none)
|
||||
*
|
||||
* Notify the text-input object when it received focus. Typically
|
||||
* in response to an activate request.
|
||||
*/
|
||||
void (*enter)(void *data,
|
||||
struct wl_text_input *wl_text_input,
|
||||
struct wl_surface *surface);
|
||||
/**
|
||||
* leave - leave event
|
||||
*
|
||||
* Notify the text-input object when it lost focus. Either in
|
||||
* response to a deactivate request or when the assigned surface
|
||||
* lost focus or was destroyed.
|
||||
*/
|
||||
void (*leave)(void *data,
|
||||
struct wl_text_input *wl_text_input);
|
||||
/**
|
||||
* modifiers_map - modifiers map
|
||||
* @map: (none)
|
||||
*
|
||||
* Transfer an array of 0-terminated modifiers names. The
|
||||
* position in the array is the index of the modifier as used in
|
||||
* the modifiers bitmask in the keysym event.
|
||||
*/
|
||||
void (*modifiers_map)(void *data,
|
||||
struct wl_text_input *wl_text_input,
|
||||
struct wl_array *map);
|
||||
/**
|
||||
* input_panel_state - state of the input panel
|
||||
* @state: (none)
|
||||
*
|
||||
* Notify when the visibility state of the input panel changed.
|
||||
*/
|
||||
void (*input_panel_state)(void *data,
|
||||
struct wl_text_input *wl_text_input,
|
||||
uint32_t state);
|
||||
/**
|
||||
* preedit_string - pre-edit
|
||||
* @serial: serial of the latest known text input state
|
||||
* @text: (none)
|
||||
* @commit: (none)
|
||||
*
|
||||
* Notify when a new composing text (pre-edit) should be set
|
||||
* around the current cursor position. Any previously set composing
|
||||
* text should be removed.
|
||||
*
|
||||
* The commit text can be used to replace the preedit text on reset
|
||||
* (for example on unfocus).
|
||||
*
|
||||
* The text input should also handle all preedit_style and
|
||||
* preedit_cursor events occuring directly before preedit_string.
|
||||
*/
|
||||
void (*preedit_string)(void *data,
|
||||
struct wl_text_input *wl_text_input,
|
||||
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 Unicode characters from index relative to the
|
||||
* beginning of the composing text (as Unicode character offset).
|
||||
* Multiple styles can be applied to a composing text by sending
|
||||
* multiple preedit_styling events.
|
||||
*
|
||||
* This event is handled as part of a following preedit_string
|
||||
* event.
|
||||
*/
|
||||
void (*preedit_styling)(void *data,
|
||||
struct wl_text_input *wl_text_input,
|
||||
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 Unicode
|
||||
* character offset) relative to the start of the composing text.
|
||||
* When index is a negative number no cursor is shown.
|
||||
*
|
||||
* This event is handled as part of a following preedit_string
|
||||
* event.
|
||||
*/
|
||||
void (*preedit_cursor)(void *data,
|
||||
struct wl_text_input *wl_text_input,
|
||||
int32_t index);
|
||||
/**
|
||||
* commit_string - commit
|
||||
* @serial: serial of the latest known text input state
|
||||
* @text: (none)
|
||||
*
|
||||
* Notify when text should be inserted into the editor widget.
|
||||
* 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 should be removed.
|
||||
*/
|
||||
void (*commit_string)(void *data,
|
||||
struct wl_text_input *wl_text_input,
|
||||
uint32_t serial,
|
||||
const char *text);
|
||||
/**
|
||||
* cursor_position - set cursor to new position
|
||||
* @index: (none)
|
||||
* @anchor: (none)
|
||||
*
|
||||
* Notify when the cursor or anchor position should be modified.
|
||||
*
|
||||
* This event should be handled as part of a following
|
||||
* commit_string event.
|
||||
*/
|
||||
void (*cursor_position)(void *data,
|
||||
struct wl_text_input *wl_text_input,
|
||||
int32_t index,
|
||||
int32_t anchor);
|
||||
/**
|
||||
* delete_surrounding_text - delete surrounding text
|
||||
* @index: (none)
|
||||
* @length: (none)
|
||||
*
|
||||
* Notify when the text around the current cursor position should
|
||||
* be deleted.
|
||||
*
|
||||
* Index is relative to the current cursor (in Unicode characters).
|
||||
* Length is the length of deleted text (in Unicode characters).
|
||||
*
|
||||
* This event should be handled as part of a following
|
||||
* commit_string event.
|
||||
*/
|
||||
void (*delete_surrounding_text)(void *data,
|
||||
struct wl_text_input *wl_text_input,
|
||||
int32_t index,
|
||||
uint32_t length);
|
||||
/**
|
||||
* 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_surrounding_text, etc. The key event
|
||||
* follows the wl_keyboard key event convention. Sym is a XKB
|
||||
* keysym, state a wl_keyboard key_state. Modifiers are a mask for
|
||||
* effective modifiers (where the modifier indices are set by the
|
||||
* modifiers_map event)
|
||||
*/
|
||||
void (*keysym)(void *data,
|
||||
struct wl_text_input *wl_text_input,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
uint32_t sym,
|
||||
uint32_t state,
|
||||
uint32_t modifiers);
|
||||
/**
|
||||
* language - language
|
||||
* @serial: serial of the latest known text input state
|
||||
* @language: (none)
|
||||
*
|
||||
* Sets the language of the input text. The "language" argument
|
||||
* is a RFC-3066 format language tag.
|
||||
*/
|
||||
void (*language)(void *data,
|
||||
struct wl_text_input *wl_text_input,
|
||||
uint32_t serial,
|
||||
const char *language);
|
||||
/**
|
||||
* text_direction - text direction
|
||||
* @serial: serial of the latest known text input state
|
||||
* @direction: (none)
|
||||
*
|
||||
* Sets the text direction of input text.
|
||||
*
|
||||
* It is mainly needed for showing input cursor on correct side of
|
||||
* the editor when there is no input yet done and making sure
|
||||
* neutral direction text is laid out properly.
|
||||
*/
|
||||
void (*text_direction)(void *data,
|
||||
struct wl_text_input *wl_text_input,
|
||||
uint32_t serial,
|
||||
uint32_t direction);
|
||||
};
|
||||
|
||||
static inline int
|
||||
wl_text_input_add_listener(struct wl_text_input *wl_text_input,
|
||||
const struct wl_text_input_listener *listener, void *data)
|
||||
{
|
||||
return wl_proxy_add_listener((struct wl_proxy *) wl_text_input,
|
||||
(void (**)(void)) listener, data);
|
||||
}
|
||||
|
||||
#define WL_TEXT_INPUT_ACTIVATE 0
|
||||
#define WL_TEXT_INPUT_DEACTIVATE 1
|
||||
#define WL_TEXT_INPUT_SHOW_INPUT_PANEL 2
|
||||
#define WL_TEXT_INPUT_HIDE_INPUT_PANEL 3
|
||||
#define WL_TEXT_INPUT_RESET 4
|
||||
#define WL_TEXT_INPUT_SET_SURROUNDING_TEXT 5
|
||||
#define WL_TEXT_INPUT_SET_CONTENT_TYPE 6
|
||||
#define WL_TEXT_INPUT_SET_CURSOR_RECTANGLE 7
|
||||
#define WL_TEXT_INPUT_SET_PREFERRED_LANGUAGE 8
|
||||
#define WL_TEXT_INPUT_COMMIT_STATE 9
|
||||
#define WL_TEXT_INPUT_INVOKE_ACTION 10
|
||||
|
||||
static inline void
|
||||
wl_text_input_set_user_data(struct wl_text_input *wl_text_input, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) wl_text_input, user_data);
|
||||
}
|
||||
|
||||
static inline void *
|
||||
wl_text_input_get_user_data(struct wl_text_input *wl_text_input)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) wl_text_input);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_destroy(struct wl_text_input *wl_text_input)
|
||||
{
|
||||
wl_proxy_destroy((struct wl_proxy *) wl_text_input);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_activate(struct wl_text_input *wl_text_input, struct wl_seat *seat, struct wl_surface *surface)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) wl_text_input,
|
||||
WL_TEXT_INPUT_ACTIVATE, seat, surface);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_deactivate(struct wl_text_input *wl_text_input, struct wl_seat *seat)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) wl_text_input,
|
||||
WL_TEXT_INPUT_DEACTIVATE, seat);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_show_input_panel(struct wl_text_input *wl_text_input)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) wl_text_input,
|
||||
WL_TEXT_INPUT_SHOW_INPUT_PANEL);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_hide_input_panel(struct wl_text_input *wl_text_input)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) wl_text_input,
|
||||
WL_TEXT_INPUT_HIDE_INPUT_PANEL);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_reset(struct wl_text_input *wl_text_input)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) wl_text_input,
|
||||
WL_TEXT_INPUT_RESET);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_set_surrounding_text(struct wl_text_input *wl_text_input, const char *text, uint32_t cursor, uint32_t anchor)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) wl_text_input,
|
||||
WL_TEXT_INPUT_SET_SURROUNDING_TEXT, text, cursor, anchor);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_set_content_type(struct wl_text_input *wl_text_input, uint32_t hint, uint32_t purpose)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) wl_text_input,
|
||||
WL_TEXT_INPUT_SET_CONTENT_TYPE, hint, purpose);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_set_cursor_rectangle(struct wl_text_input *wl_text_input, int32_t x, int32_t y, int32_t width, int32_t height)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) wl_text_input,
|
||||
WL_TEXT_INPUT_SET_CURSOR_RECTANGLE, x, y, width, height);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_set_preferred_language(struct wl_text_input *wl_text_input, const char *language)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) wl_text_input,
|
||||
WL_TEXT_INPUT_SET_PREFERRED_LANGUAGE, language);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_commit_state(struct wl_text_input *wl_text_input, uint32_t serial)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) wl_text_input,
|
||||
WL_TEXT_INPUT_COMMIT_STATE, serial);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_invoke_action(struct wl_text_input *wl_text_input, uint32_t button, uint32_t index)
|
||||
{
|
||||
wl_proxy_marshal((struct wl_proxy *) wl_text_input,
|
||||
WL_TEXT_INPUT_INVOKE_ACTION, button, index);
|
||||
}
|
||||
|
||||
#define WL_TEXT_INPUT_MANAGER_CREATE_TEXT_INPUT 0
|
||||
|
||||
static inline void
|
||||
wl_text_input_manager_set_user_data(struct wl_text_input_manager *wl_text_input_manager, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) wl_text_input_manager, user_data);
|
||||
}
|
||||
|
||||
static inline void *
|
||||
wl_text_input_manager_get_user_data(struct wl_text_input_manager *wl_text_input_manager)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) wl_text_input_manager);
|
||||
}
|
||||
|
||||
static inline void
|
||||
wl_text_input_manager_destroy(struct wl_text_input_manager *wl_text_input_manager)
|
||||
{
|
||||
wl_proxy_destroy((struct wl_proxy *) wl_text_input_manager);
|
||||
}
|
||||
|
||||
static inline struct wl_text_input *
|
||||
wl_text_input_manager_create_text_input(struct wl_text_input_manager *wl_text_input_manager)
|
||||
{
|
||||
struct wl_proxy *id;
|
||||
|
||||
id = wl_proxy_create((struct wl_proxy *) wl_text_input_manager,
|
||||
&wl_text_input_interface);
|
||||
if (!id)
|
||||
return NULL;
|
||||
|
||||
wl_proxy_marshal((struct wl_proxy *) wl_text_input_manager,
|
||||
WL_TEXT_INPUT_MANAGER_CREATE_TEXT_INPUT, id);
|
||||
|
||||
return (struct wl_text_input *) id;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* 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_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,778 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_Evas.h>
|
||||
#include <Ecore_Input.h>
|
||||
#include <Ecore_Wayland.h>
|
||||
|
||||
#include "wayland_imcontext.h"
|
||||
|
||||
struct _WaylandIMContext
|
||||
{
|
||||
Ecore_IMF_Context *ctx;
|
||||
|
||||
struct wl_text_input_manager *text_input_manager;
|
||||
struct wl_text_input *text_input;
|
||||
|
||||
Ecore_Wl_Window *window;
|
||||
Evas *canvas;
|
||||
|
||||
char *preedit_text;
|
||||
char *preedit_commit;
|
||||
Eina_List *preedit_attrs;
|
||||
int32_t preedit_cursor;
|
||||
|
||||
struct
|
||||
{
|
||||
Eina_List *attrs;
|
||||
int32_t cursor;
|
||||
} pending_preedit;
|
||||
|
||||
struct
|
||||
{
|
||||
int32_t cursor;
|
||||
int32_t anchor;
|
||||
uint32_t delete_index;
|
||||
uint32_t delete_length;
|
||||
} pending_commit;
|
||||
|
||||
struct
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
} cursor_location;
|
||||
|
||||
xkb_mod_mask_t control_mask;
|
||||
xkb_mod_mask_t alt_mask;
|
||||
xkb_mod_mask_t shift_mask;
|
||||
|
||||
uint32_t serial;
|
||||
uint32_t reset_serial;
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
utf8_offset_to_characters(const char *str, int offset)
|
||||
{
|
||||
int index = 0;
|
||||
unsigned int i = 0;
|
||||
for (; index < offset; i++)
|
||||
eina_unicode_utf8_next_get(str, &index);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
update_state(WaylandIMContext *imcontext)
|
||||
{
|
||||
char *surrounding;
|
||||
int cursor_pos;
|
||||
Ecore_Evas *ee;
|
||||
int canvas_x = 0, canvas_y = 0;
|
||||
|
||||
if (!imcontext->ctx)
|
||||
return;
|
||||
|
||||
/* cursor_pos is a byte index */
|
||||
if (ecore_imf_context_surrounding_get(imcontext->ctx, &surrounding, &cursor_pos))
|
||||
{
|
||||
wl_text_input_set_surrounding_text(imcontext->text_input,
|
||||
surrounding,
|
||||
cursor_pos,
|
||||
cursor_pos);
|
||||
free(surrounding);
|
||||
}
|
||||
|
||||
if (imcontext->canvas)
|
||||
{
|
||||
ee = ecore_evas_ecore_evas_get(imcontext->canvas);
|
||||
if (ee)
|
||||
ecore_evas_geometry_get(ee, &canvas_x, &canvas_y, NULL, NULL);
|
||||
}
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "canvas (x: %d, y: %d)", canvas_x, canvas_y);
|
||||
|
||||
wl_text_input_set_cursor_rectangle(imcontext->text_input,
|
||||
imcontext->cursor_location.x + canvas_x,
|
||||
imcontext->cursor_location.y + canvas_y,
|
||||
imcontext->cursor_location.width,
|
||||
imcontext->cursor_location.height);
|
||||
|
||||
wl_text_input_commit_state(imcontext->text_input, ++imcontext->serial);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
check_serial(WaylandIMContext *imcontext, uint32_t serial)
|
||||
{
|
||||
Ecore_IMF_Preedit_Attr *attr;
|
||||
|
||||
if ((imcontext->serial - serial) > (imcontext->serial - imcontext->reset_serial))
|
||||
{
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
|
||||
"outdated serial: %u, current: %u, reset: %u",
|
||||
serial, imcontext->serial, imcontext->reset_serial);
|
||||
|
||||
/* Clear pending data */
|
||||
imcontext->pending_commit.delete_index = 0;
|
||||
imcontext->pending_commit.delete_length = 0;
|
||||
imcontext->pending_commit.cursor = 0;
|
||||
imcontext->pending_commit.anchor = 0;
|
||||
|
||||
imcontext->pending_preedit.cursor = 0;
|
||||
EINA_LIST_FREE(imcontext->pending_preedit.attrs, attr) free(attr);
|
||||
imcontext->pending_preedit.attrs = NULL;
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_preedit(WaylandIMContext *imcontext)
|
||||
{
|
||||
Ecore_IMF_Preedit_Attr *attr;
|
||||
|
||||
imcontext->preedit_cursor = 0;
|
||||
|
||||
free(imcontext->preedit_text);
|
||||
imcontext->preedit_text = NULL;
|
||||
|
||||
free(imcontext->preedit_commit);
|
||||
imcontext->preedit_commit = NULL;
|
||||
|
||||
EINA_LIST_FREE(imcontext->preedit_attrs, attr)
|
||||
free(attr);
|
||||
|
||||
imcontext->preedit_attrs = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
text_input_commit_string(void *data,
|
||||
struct wl_text_input *text_input EINA_UNUSED,
|
||||
uint32_t serial,
|
||||
const char *text)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)data;
|
||||
Eina_Bool old_preedit = EINA_FALSE;
|
||||
char *surrounding;
|
||||
int cursor_pos, cursor;
|
||||
Ecore_IMF_Event_Delete_Surrounding ev;
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
|
||||
"commit event (text: `%s', current pre-edit: `%s')",
|
||||
text,
|
||||
imcontext->preedit_text ? imcontext->preedit_text : "");
|
||||
|
||||
old_preedit = imcontext->preedit_text && strlen(imcontext->preedit_text) > 0;
|
||||
|
||||
if (!imcontext->ctx)
|
||||
return;
|
||||
|
||||
if (!check_serial(imcontext, serial))
|
||||
return;
|
||||
|
||||
if (old_preedit)
|
||||
{
|
||||
ecore_imf_context_preedit_end_event_add(imcontext->ctx);
|
||||
ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
|
||||
}
|
||||
|
||||
clear_preedit(imcontext);
|
||||
|
||||
if (imcontext->pending_commit.delete_length > 0)
|
||||
{
|
||||
/* cursor_pos is a byte index */
|
||||
if (ecore_imf_context_surrounding_get(imcontext->ctx, &surrounding, &cursor_pos))
|
||||
{
|
||||
ev.ctx = imcontext->ctx;
|
||||
/* offset and n_chars are in characters */
|
||||
ev.offset = utf8_offset_to_characters(surrounding, cursor_pos + imcontext->pending_commit.delete_index);
|
||||
ev.n_chars = utf8_offset_to_characters(surrounding,
|
||||
cursor_pos + imcontext->pending_commit.delete_index + imcontext->pending_commit.delete_length) - ev.offset;
|
||||
|
||||
/* cursor in characters */
|
||||
cursor = utf8_offset_to_characters(surrounding, cursor_pos);
|
||||
|
||||
ev.offset -= cursor;
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
|
||||
"delete on commit (text: `%s', offset `%d', length: `%d')",
|
||||
surrounding, ev.offset, ev.n_chars);
|
||||
|
||||
ecore_imf_context_delete_surrounding_event_add(imcontext->ctx, ev.offset, ev.n_chars);
|
||||
ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, &ev);
|
||||
}
|
||||
}
|
||||
|
||||
imcontext->pending_commit.delete_index = 0;
|
||||
imcontext->pending_commit.delete_length = 0;
|
||||
imcontext->pending_commit.cursor = 0;
|
||||
imcontext->pending_commit.anchor = 0;
|
||||
|
||||
ecore_imf_context_commit_event_add(imcontext->ctx, text);
|
||||
ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)text);
|
||||
}
|
||||
|
||||
static void
|
||||
commit_preedit(WaylandIMContext *imcontext)
|
||||
{
|
||||
if (!imcontext->preedit_commit)
|
||||
return;
|
||||
|
||||
if (!imcontext->ctx)
|
||||
return;
|
||||
|
||||
ecore_imf_context_commit_event_add(imcontext->ctx, imcontext->preedit_commit);
|
||||
ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)imcontext->preedit_commit);
|
||||
}
|
||||
|
||||
static void
|
||||
text_input_preedit_string(void *data,
|
||||
struct wl_text_input *text_input EINA_UNUSED,
|
||||
uint32_t serial,
|
||||
const char *text,
|
||||
const char *commit)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)data;
|
||||
Eina_Bool old_preedit = EINA_FALSE;
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
|
||||
"preedit event (text: `%s', current pre-edit: `%s')",
|
||||
text,
|
||||
imcontext->preedit_text ? imcontext->preedit_text : "");
|
||||
|
||||
if (!check_serial(imcontext, serial))
|
||||
return;
|
||||
|
||||
old_preedit = imcontext->preedit_text && strlen(imcontext->preedit_text) > 0;
|
||||
|
||||
clear_preedit(imcontext);
|
||||
|
||||
imcontext->preedit_text = strdup(text);
|
||||
imcontext->preedit_commit = strdup(commit);
|
||||
imcontext->preedit_cursor = utf8_offset_to_characters(text, imcontext->pending_preedit.cursor);
|
||||
imcontext->preedit_attrs = imcontext->pending_preedit.attrs;
|
||||
|
||||
imcontext->pending_preedit.attrs = NULL;
|
||||
|
||||
if (!old_preedit)
|
||||
{
|
||||
ecore_imf_context_preedit_start_event_add(imcontext->ctx);
|
||||
ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL);
|
||||
}
|
||||
|
||||
ecore_imf_context_preedit_changed_event_add(imcontext->ctx);
|
||||
ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
|
||||
|
||||
if (strlen(imcontext->preedit_text) == 0)
|
||||
{
|
||||
ecore_imf_context_preedit_end_event_add(imcontext->ctx);
|
||||
ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
text_input_delete_surrounding_text(void *data,
|
||||
struct wl_text_input *text_input EINA_UNUSED,
|
||||
int32_t index,
|
||||
uint32_t length)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)data;
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
|
||||
"delete surrounding text (index: %d, length: %u)",
|
||||
index,
|
||||
length);
|
||||
|
||||
imcontext->pending_commit.delete_index = index;
|
||||
imcontext->pending_commit.delete_length = length;
|
||||
}
|
||||
|
||||
static void
|
||||
text_input_cursor_position(void *data,
|
||||
struct wl_text_input *text_input EINA_UNUSED,
|
||||
int32_t index,
|
||||
int32_t anchor)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)data;
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
|
||||
"cursor_position for next commit (index: %d, anchor: %d)",
|
||||
index,
|
||||
anchor);
|
||||
|
||||
imcontext->pending_commit.cursor = index;
|
||||
imcontext->pending_commit.anchor = anchor;
|
||||
}
|
||||
|
||||
static void
|
||||
text_input_preedit_styling(void *data,
|
||||
struct wl_text_input *text_input EINA_UNUSED,
|
||||
uint32_t index,
|
||||
uint32_t length,
|
||||
uint32_t style)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)data;
|
||||
Ecore_IMF_Preedit_Attr *attr = calloc(1, sizeof(*attr));
|
||||
|
||||
switch (style)
|
||||
{
|
||||
case WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT:
|
||||
case WL_TEXT_INPUT_PREEDIT_STYLE_UNDERLINE:
|
||||
case WL_TEXT_INPUT_PREEDIT_STYLE_INCORRECT:
|
||||
case WL_TEXT_INPUT_PREEDIT_STYLE_HIGHLIGHT:
|
||||
case WL_TEXT_INPUT_PREEDIT_STYLE_ACTIVE:
|
||||
case WL_TEXT_INPUT_PREEDIT_STYLE_INACTIVE:
|
||||
attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1;
|
||||
break;
|
||||
case WL_TEXT_INPUT_PREEDIT_STYLE_SELECTION:
|
||||
attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2;
|
||||
break;
|
||||
}
|
||||
|
||||
attr->start_index = index;
|
||||
attr->end_index = index + length;
|
||||
|
||||
imcontext->pending_preedit.attrs = eina_list_append(imcontext->pending_preedit.attrs, attr);
|
||||
}
|
||||
|
||||
static void
|
||||
text_input_preedit_cursor(void *data,
|
||||
struct wl_text_input *text_input EINA_UNUSED,
|
||||
int32_t index)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)data;
|
||||
|
||||
imcontext->pending_preedit.cursor = index;
|
||||
}
|
||||
|
||||
static xkb_mod_index_t
|
||||
modifiers_get_index(struct wl_array *modifiers_map,
|
||||
const char *name)
|
||||
{
|
||||
xkb_mod_index_t index = 0;
|
||||
char *p = modifiers_map->data;
|
||||
|
||||
while ((const char *)p < ((const char *)modifiers_map->data + modifiers_map->size))
|
||||
{
|
||||
if (strcmp(p, name) == 0)
|
||||
return index;
|
||||
|
||||
index++;
|
||||
p += strlen(p) + 1;
|
||||
}
|
||||
|
||||
return XKB_MOD_INVALID;
|
||||
}
|
||||
|
||||
static xkb_mod_mask_t
|
||||
modifiers_get_mask(struct wl_array *modifiers_map,
|
||||
const char *name)
|
||||
{
|
||||
xkb_mod_index_t index = modifiers_get_index(modifiers_map, name);
|
||||
|
||||
if (index == XKB_MOD_INVALID)
|
||||
return XKB_MOD_INVALID;
|
||||
|
||||
return 1 << index;
|
||||
}
|
||||
static void
|
||||
text_input_modifiers_map(void *data,
|
||||
struct wl_text_input *text_input EINA_UNUSED,
|
||||
struct wl_array *map)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)data;
|
||||
|
||||
imcontext->shift_mask = modifiers_get_mask(map, "Shift");
|
||||
imcontext->control_mask = modifiers_get_mask(map, "Control");
|
||||
imcontext->alt_mask = modifiers_get_mask(map, "Mod1");
|
||||
}
|
||||
|
||||
static void
|
||||
text_input_keysym(void *data,
|
||||
struct wl_text_input *text_input EINA_UNUSED,
|
||||
uint32_t serial EINA_UNUSED,
|
||||
uint32_t time,
|
||||
uint32_t sym,
|
||||
uint32_t state,
|
||||
uint32_t modifiers)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)data;
|
||||
char string[32], key[32], keyname[32];
|
||||
Ecore_Event_Key *e;
|
||||
|
||||
memset(key, 0, sizeof(key));
|
||||
xkb_keysym_get_name(sym, key, sizeof(key));
|
||||
|
||||
memset(keyname, 0, sizeof(keyname));
|
||||
xkb_keysym_get_name(sym, keyname, sizeof(keyname));
|
||||
if (keyname[0] == '\0')
|
||||
snprintf(keyname, sizeof(keyname), "Keysym-%u", sym);
|
||||
|
||||
memset(string, 0, sizeof(string));
|
||||
xkb_keysym_to_utf8(sym, string, 32);
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
|
||||
"key event (key: %s)",
|
||||
keyname);
|
||||
|
||||
e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + strlen(string) + 3);
|
||||
if (!e)
|
||||
return;
|
||||
|
||||
e->keyname = (char *)(e + 1);
|
||||
e->key = e->keyname + strlen(keyname) + 1;
|
||||
e->string = e->key + strlen(key) + 1;
|
||||
e->compose = e->string;
|
||||
|
||||
strcpy((char *)e->keyname, keyname);
|
||||
strcpy((char *)e->key, key);
|
||||
strcpy((char *)e->string, string);
|
||||
|
||||
e->window = imcontext->window->id;
|
||||
e->event_window = imcontext->window->id;
|
||||
e->timestamp = time;
|
||||
|
||||
e->modifiers = 0;
|
||||
if (modifiers & imcontext->shift_mask)
|
||||
e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
|
||||
|
||||
if (modifiers & imcontext->control_mask)
|
||||
e->modifiers |= ECORE_EVENT_MODIFIER_CTRL;
|
||||
|
||||
if (modifiers & imcontext->alt_mask)
|
||||
e->modifiers |= ECORE_EVENT_MODIFIER_ALT;
|
||||
|
||||
if (state)
|
||||
ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL);
|
||||
else
|
||||
ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
text_input_enter(void *data,
|
||||
struct wl_text_input *text_input EINA_UNUSED,
|
||||
struct wl_surface *surface EINA_UNUSED)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)data;
|
||||
|
||||
update_state(imcontext);
|
||||
|
||||
imcontext->reset_serial = imcontext->serial;
|
||||
}
|
||||
|
||||
static void
|
||||
text_input_leave(void *data,
|
||||
struct wl_text_input *text_input)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)data;
|
||||
|
||||
wl_text_input_hide_input_panel(text_input);
|
||||
|
||||
/* clear preedit */
|
||||
commit_preedit(imcontext);
|
||||
clear_preedit(imcontext);
|
||||
|
||||
ecore_imf_context_preedit_changed_event_add(imcontext->ctx);
|
||||
ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
|
||||
|
||||
ecore_imf_context_preedit_end_event_add(imcontext->ctx);
|
||||
ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
text_input_input_panel_state(void *data EINA_UNUSED,
|
||||
struct wl_text_input *text_input EINA_UNUSED,
|
||||
uint32_t state EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
text_input_language(void *data EINA_UNUSED,
|
||||
struct wl_text_input *text_input EINA_UNUSED,
|
||||
uint32_t serial EINA_UNUSED,
|
||||
const char *language EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
text_input_text_direction(void *data EINA_UNUSED,
|
||||
struct wl_text_input *text_input EINA_UNUSED,
|
||||
uint32_t serial EINA_UNUSED,
|
||||
uint32_t direction EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_text_input_listener text_input_listener =
|
||||
{
|
||||
text_input_enter,
|
||||
text_input_leave,
|
||||
text_input_modifiers_map,
|
||||
text_input_input_panel_state,
|
||||
text_input_preedit_string,
|
||||
text_input_preedit_styling,
|
||||
text_input_preedit_cursor,
|
||||
text_input_commit_string,
|
||||
text_input_cursor_position,
|
||||
text_input_delete_surrounding_text,
|
||||
text_input_keysym,
|
||||
text_input_language,
|
||||
text_input_text_direction
|
||||
};
|
||||
|
||||
EAPI void
|
||||
wayland_im_context_add(Ecore_IMF_Context *ctx)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "context_add");
|
||||
|
||||
imcontext->ctx = ctx;
|
||||
|
||||
imcontext->text_input = wl_text_input_manager_create_text_input(imcontext->text_input_manager);
|
||||
wl_text_input_add_listener(imcontext->text_input, &text_input_listener, imcontext);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
wayland_im_context_del(Ecore_IMF_Context *ctx)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "context_del");
|
||||
|
||||
wl_text_input_destroy(imcontext->text_input);
|
||||
|
||||
clear_preedit(imcontext);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
wayland_im_context_reset(Ecore_IMF_Context *ctx)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
|
||||
|
||||
commit_preedit(imcontext);
|
||||
clear_preedit(imcontext);
|
||||
|
||||
wl_text_input_reset(imcontext->text_input);
|
||||
|
||||
update_state(imcontext);
|
||||
|
||||
imcontext->reset_serial = imcontext->serial;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
wayland_im_context_focus_in(Ecore_IMF_Context *ctx)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
|
||||
Ecore_Wl_Input *input;
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "focus-in");
|
||||
|
||||
if (!imcontext->window)
|
||||
return;
|
||||
|
||||
input = imcontext->window->keyboard_device;
|
||||
if (!input || !input->seat)
|
||||
return;
|
||||
|
||||
wl_text_input_show_input_panel(imcontext->text_input);
|
||||
wl_text_input_activate(imcontext->text_input,
|
||||
input->seat,
|
||||
ecore_wl_window_surface_get(imcontext->window));
|
||||
}
|
||||
|
||||
EAPI void
|
||||
wayland_im_context_focus_out(Ecore_IMF_Context *ctx)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "focus-out");
|
||||
|
||||
if (!imcontext->window)
|
||||
return;
|
||||
|
||||
wl_text_input_deactivate(imcontext->text_input,
|
||||
imcontext->window->display->input->seat);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
wayland_im_context_preedit_string_get(Ecore_IMF_Context *ctx,
|
||||
char **str,
|
||||
int *cursor_pos)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
|
||||
"pre-edit string requested (preedit: `%s')",
|
||||
imcontext->preedit_text ? imcontext->preedit_text : "");
|
||||
|
||||
if (str)
|
||||
*str = strdup(imcontext->preedit_text ? imcontext->preedit_text : "");
|
||||
|
||||
if (cursor_pos)
|
||||
*cursor_pos = imcontext->preedit_cursor;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
wayland_im_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx,
|
||||
char **str,
|
||||
Eina_List **attrs,
|
||||
int *cursor_pos)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
|
||||
"pre-edit string with attributes requested (preedit: `%s')",
|
||||
imcontext->preedit_text ? imcontext->preedit_text : "");
|
||||
|
||||
if (str)
|
||||
*str = strdup(imcontext->preedit_text ? imcontext->preedit_text : "");
|
||||
|
||||
if (attrs)
|
||||
{
|
||||
Eina_List *l;
|
||||
Ecore_IMF_Preedit_Attr *a, *attr;
|
||||
|
||||
EINA_LIST_FOREACH(imcontext->preedit_attrs, l, a)
|
||||
{
|
||||
attr = malloc(sizeof(*attr));
|
||||
attr = memcpy(attr, a, sizeof(*attr));
|
||||
*attrs = eina_list_append(*attrs, attr);
|
||||
}
|
||||
}
|
||||
|
||||
if (cursor_pos)
|
||||
*cursor_pos = imcontext->preedit_cursor;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
wayland_im_context_cursor_position_set(Ecore_IMF_Context *ctx,
|
||||
int cursor_pos)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom,
|
||||
"set cursor position (cursor: %d)",
|
||||
cursor_pos);
|
||||
|
||||
update_state(imcontext);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
wayland_im_context_use_preedit_set(Ecore_IMF_Context *ctx EINA_UNUSED,
|
||||
Eina_Bool use_preedit EINA_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
EAPI void
|
||||
wayland_im_context_client_window_set(Ecore_IMF_Context *ctx,
|
||||
void *window)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "client window set (window: %p)", window);
|
||||
|
||||
if (window != NULL)
|
||||
imcontext->window = ecore_wl_window_find((Ecore_Window)window);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
wayland_im_context_client_canvas_set(Ecore_IMF_Context *ctx,
|
||||
void *canvas)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "client canvas set (canvas: %p)", canvas);
|
||||
|
||||
if (canvas != NULL)
|
||||
imcontext->canvas = canvas;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
wayland_im_context_show(Ecore_IMF_Context *ctx)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "context_show");
|
||||
|
||||
wl_text_input_show_input_panel(imcontext->text_input);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
wayland_im_context_hide(Ecore_IMF_Context *ctx)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "context_hide");
|
||||
|
||||
wl_text_input_hide_input_panel(imcontext->text_input);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
wayland_im_context_filter_event(Ecore_IMF_Context *ctx EINA_UNUSED,
|
||||
Ecore_IMF_Event_Type type EINA_UNUSED,
|
||||
Ecore_IMF_Event *event EINA_UNUSED)
|
||||
{
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
wayland_im_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int width, int height)
|
||||
{
|
||||
WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "cursor_location_set (x: %d, y: %d, w: %d, h: %d)", x, y, width, height);
|
||||
|
||||
if ((imcontext->cursor_location.x != x) ||
|
||||
(imcontext->cursor_location.y != y) ||
|
||||
(imcontext->cursor_location.width != width) ||
|
||||
(imcontext->cursor_location.height != height))
|
||||
{
|
||||
imcontext->cursor_location.x = x;
|
||||
imcontext->cursor_location.y = y;
|
||||
imcontext->cursor_location.width = width;
|
||||
imcontext->cursor_location.height = height;
|
||||
|
||||
update_state(imcontext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WaylandIMContext *wayland_im_context_new (struct wl_text_input_manager *text_input_manager)
|
||||
{
|
||||
WaylandIMContext *context = calloc(1, sizeof(WaylandIMContext));
|
||||
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "new context created");
|
||||
context->text_input_manager = text_input_manager;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/* vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0
|
||||
*/
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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 __WAYLAND_IM_CONTEXT_H_
|
||||
#define __WAYLAND_IM_CONTEXT_H_
|
||||
|
||||
#include <Ecore_IMF.h>
|
||||
#include "text-client-protocol.h"
|
||||
|
||||
typedef struct _WaylandIMContext WaylandIMContext;
|
||||
|
||||
EAPI void wayland_im_context_add (Ecore_IMF_Context *ctx);
|
||||
EAPI void wayland_im_context_del (Ecore_IMF_Context *ctx);
|
||||
EAPI void wayland_im_context_reset (Ecore_IMF_Context *ctx);
|
||||
EAPI void wayland_im_context_focus_in (Ecore_IMF_Context *ctx);
|
||||
EAPI void wayland_im_context_focus_out (Ecore_IMF_Context *ctx);
|
||||
EAPI void wayland_im_context_preedit_string_get (Ecore_IMF_Context *ctx,
|
||||
char **str,
|
||||
int *cursor_pos);
|
||||
EAPI void wayland_im_context_preedit_string_with_attributes_get(Ecore_IMF_Context *ctx,
|
||||
char **str,
|
||||
Eina_List **attr,
|
||||
int *cursor_pos);
|
||||
|
||||
EAPI void wayland_im_context_cursor_position_set(Ecore_IMF_Context *ctx,
|
||||
int cursor_pos);
|
||||
EAPI void wayland_im_context_use_preedit_set (Ecore_IMF_Context *ctx,
|
||||
Eina_Bool use_preedit);
|
||||
EAPI void wayland_im_context_client_window_set (Ecore_IMF_Context *ctx,
|
||||
void *window);
|
||||
EAPI void wayland_im_context_client_canvas_set (Ecore_IMF_Context *ctx,
|
||||
void *canvas);
|
||||
EAPI void wayland_im_context_show (Ecore_IMF_Context *ctx);
|
||||
EAPI void wayland_im_context_hide (Ecore_IMF_Context *ctx);
|
||||
EAPI Eina_Bool wayland_im_context_filter_event (Ecore_IMF_Context *ctx,
|
||||
Ecore_IMF_Event_Type type,
|
||||
Ecore_IMF_Event *event);
|
||||
EAPI void wayland_im_context_cursor_location_set(Ecore_IMF_Context *ctx,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
WaylandIMContext *wayland_im_context_new (struct wl_text_input_manager *text_input_manager);
|
||||
|
||||
extern int _ecore_imf_wayland_log_dom;
|
||||
|
||||
#endif
|
||||
|
||||
/* vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0
|
||||
*/
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* 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 <Ecore.h>
|
||||
#include <Ecore_IMF.h>
|
||||
#include <Ecore_Wayland.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wayland_imcontext.h"
|
||||
#include "text-client-protocol.h"
|
||||
|
||||
int _ecore_imf_wayland_log_dom = -1;
|
||||
|
||||
static const Ecore_IMF_Context_Info wayland_im_info =
|
||||
{
|
||||
"wayland",
|
||||
"Wayland",
|
||||
"*",
|
||||
NULL,
|
||||
0
|
||||
};
|
||||
|
||||
static Ecore_IMF_Context_Class wayland_imf_class =
|
||||
{
|
||||
wayland_im_context_add, /* add */
|
||||
wayland_im_context_del, /* del */
|
||||
wayland_im_context_client_window_set, /* client_window_set */
|
||||
wayland_im_context_client_canvas_set, /* client_canvas_set */
|
||||
wayland_im_context_show, /* show */
|
||||
wayland_im_context_hide, /* hide */
|
||||
wayland_im_context_preedit_string_get, /* get_preedit_string */
|
||||
wayland_im_context_focus_in, /* focus_in */
|
||||
wayland_im_context_focus_out, /* focus_out */
|
||||
wayland_im_context_reset, /* reset */
|
||||
wayland_im_context_cursor_position_set, /* cursor_position_set */
|
||||
wayland_im_context_use_preedit_set, /* use_preedit_set */
|
||||
NULL, /* input_mode_set */
|
||||
wayland_im_context_filter_event, /* filter_event */
|
||||
wayland_im_context_preedit_string_with_attributes_get, /* preedit_string_with_attribute_get */
|
||||
NULL, /* prediction_allow_set */
|
||||
NULL, /* autocapital_type_set */
|
||||
NULL, /* control panel show */
|
||||
NULL, /* control panel hide */
|
||||
NULL, /* input_panel_layout_set */
|
||||
NULL, /* input_panel_layout_get, */
|
||||
NULL, /* input_panel_language_set, */
|
||||
NULL, /* input_panel_language_get, */
|
||||
wayland_im_context_cursor_location_set, /* cursor_location_set */
|
||||
NULL, /* input_panel_imdata_set */
|
||||
NULL, /* input_panel_imdata_get */
|
||||
NULL, /* input_panel_return_key_type_set */
|
||||
NULL, /* input_panel_return_key_disabled_set */
|
||||
NULL, /* input_panel_caps_lock_mode_set */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct wl_text_input_manager *text_input_manager = NULL;
|
||||
|
||||
static Ecore_IMF_Context *
|
||||
im_module_exit(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Ecore_IMF_Context *
|
||||
im_module_create()
|
||||
{
|
||||
Ecore_IMF_Context *ctx = NULL;
|
||||
WaylandIMContext *ctxd = NULL;
|
||||
|
||||
ctxd = wayland_im_context_new(text_input_manager);
|
||||
if (!ctxd)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx = ecore_imf_context_new(&wayland_imf_class);
|
||||
if (!ctx)
|
||||
{
|
||||
free(ctxd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ecore_imf_context_data_set(ctx, ctxd);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
im_module_init(void)
|
||||
{
|
||||
struct wl_registry *registry;
|
||||
struct wl_list *globals;
|
||||
Ecore_Wl_Global *global;
|
||||
|
||||
ecore_wl_init(NULL);
|
||||
|
||||
_ecore_imf_wayland_log_dom = eina_log_domain_register("ecore_imf_wayland", EINA_COLOR_YELLOW);
|
||||
|
||||
ecore_wl_display_iterate();
|
||||
registry = ecore_wl_registry_get();
|
||||
globals = ecore_wl_globals_get();
|
||||
|
||||
wl_list_for_each(global, globals, link)
|
||||
{
|
||||
if (!strcmp(global->interface, "wl_text_input_manager"))
|
||||
{
|
||||
text_input_manager = wl_registry_bind(registry, global->id, &wl_text_input_manager_interface, 1);
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "bound wl_text_input_manager interface");
|
||||
}
|
||||
}
|
||||
|
||||
ecore_imf_module_register(&wayland_im_info, im_module_create, im_module_exit);
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "im module initalized");
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
im_module_shutdown(void)
|
||||
{
|
||||
ecore_wl_shutdown();
|
||||
EINA_LOG_DOM_INFO(_ecore_imf_wayland_log_dom, "im module shutdown");
|
||||
}
|
||||
|
||||
EINA_MODULE_INIT(im_module_init);
|
||||
EINA_MODULE_SHUTDOWN(im_module_shutdown);
|
||||
|
||||
/* vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0
|
||||
*/
|
Loading…
Reference in New Issue