|
|
ee2c8d7 |
From 27788fb3bf62411c2b13d24bac45eb060483162f Mon Sep 17 00:00:00 2001
|
|
|
6cc8efa |
From: Daiki Ueno <ueno@unixuser.org>
|
|
|
ee2c8d7 |
Date: Tue, 8 Feb 2011 18:27:00 +0900
|
|
|
6cc8efa |
Subject: [PATCH] Support surrounding-text retrieval.
|
|
|
6cc8efa |
|
|
|
6cc8efa |
This change adds a new API function ibus_engine_get_surrounding_text().
|
|
|
6cc8efa |
In the implementation, engines do not proactively requests surrounding-text to
|
|
|
6cc8efa |
target applications via the GTK+ client (IBusIMContext) every time the
|
|
|
6cc8efa |
function is called. Instead, IBusIMContext retrieves surrounding-text when
|
|
|
6cc8efa |
certain events occur in the input context (IBusInputContext) and maintains
|
|
|
6cc8efa |
it within the input context.
|
|
|
6cc8efa |
|
|
|
6cc8efa |
This logic is similar to Qt's QInputContext. The following events trigger
|
|
|
6cc8efa |
surrounding-text retrieval:
|
|
|
6cc8efa |
|
|
|
6cc8efa |
- focus_in
|
|
|
6cc8efa |
- commit_text
|
|
|
6cc8efa |
- show_preedit_text
|
|
|
6cc8efa |
- (just before) process_key_event
|
|
|
6cc8efa |
|
|
|
6cc8efa |
Also,
|
|
|
6cc8efa |
- destroy
|
|
|
6cc8efa |
resets the current surrounding-text.
|
|
|
6cc8efa |
---
|
|
|
069aa90 |
bus/engineproxy.c | 43 ++++++++++++
|
|
|
cf977d1 |
bus/engineproxy.h | 11 +++
|
|
|
069aa90 |
bus/inputcontext.c | 36 ++++++++++
|
|
|
069aa90 |
client/gtk2/ibusimcontext.c | 138 ++++++++++++++++++++++++++++++++++-----
|
|
|
3b5789d |
configure.ac | 14 ++++
|
|
|
eb1661e |
ibus/engine.py | 6 ++
|
|
|
7232d5e |
ibus/interface/iengine.py | 3 +
|
|
|
069aa90 |
ibus/interface/iinputcontext.py | 5 ++
|
|
|
069aa90 |
src/ibusengine.c | 138 +++++++++++++++++++++++++++++++++++++++
|
|
|
f7291cc |
src/ibusengine.h | 21 ++++++-
|
|
|
069aa90 |
src/ibusenginedesc.c | 132 +++++++++++++++++++++++++++++++++++++
|
|
|
fbc5579 |
src/ibusenginedesc.h | 11 +++
|
|
|
069aa90 |
src/ibusinputcontext.c | 91 +++++++++++++++++++++++++
|
|
|
069aa90 |
src/ibusinputcontext.h | 11 +++
|
|
|
7232d5e |
src/ibusmarshalers.list | 1 +
|
|
|
069aa90 |
15 files changed, 644 insertions(+), 17 deletions(-)
|
|
|
6cc8efa |
|
|
|
6cc8efa |
diff --git a/bus/engineproxy.c b/bus/engineproxy.c
|
|
|
069aa90 |
index f808727..b35933f 100644
|
|
|
6cc8efa |
--- a/bus/engineproxy.c
|
|
|
6cc8efa |
+++ b/bus/engineproxy.c
|
|
|
cf977d1 |
@@ -47,6 +47,10 @@ struct _BusEngineProxy {
|
|
|
cf977d1 |
/* a key mapping for the engine that converts keycode into keysym. the mapping is used only when use_sys_layout is FALSE. */
|
|
|
3b5789d |
IBusKeymap *keymap;
|
|
|
f0777a3 |
/* private member */
|
|
|
f0777a3 |
+
|
|
|
f0777a3 |
+ /* surrounding text */
|
|
|
f0777a3 |
+ IBusText *surrounding_text;
|
|
|
f0777a3 |
+ guint surrounding_cursor_pos;
|
|
|
f0777a3 |
};
|
|
|
f0777a3 |
|
|
|
f0777a3 |
struct _BusEngineProxyClass {
|
|
|
cf977d1 |
@@ -83,6 +87,8 @@ enum {
|
|
|
cf977d1 |
|
|
|
eb1661e |
static guint engine_signals[LAST_SIGNAL] = { 0 };
|
|
|
eb1661e |
|
|
|
eb1661e |
+static IBusText *text_empty = NULL;
|
|
|
eb1661e |
+
|
|
|
eb1661e |
/* functions prototype */
|
|
|
3b5789d |
static void bus_engine_proxy_set_property (BusEngineProxy *engine,
|
|
|
3b5789d |
guint prop_id,
|
|
|
cf977d1 |
@@ -330,11 +336,16 @@ bus_engine_proxy_class_init (BusEngineProxyClass *class)
|
|
|
3b5789d |
G_TYPE_NONE,
|
|
|
eb1661e |
1,
|
|
|
eb1661e |
IBUS_TYPE_PROPERTY);
|
|
|
3b5789d |
+
|
|
|
e36fdde |
+ text_empty = ibus_text_new_from_static_string ("");
|
|
|
eb1661e |
+ g_object_ref_sink (text_empty);
|
|
|
eb1661e |
}
|
|
|
eb1661e |
|
|
|
eb1661e |
static void
|
|
|
f0777a3 |
bus_engine_proxy_init (BusEngineProxy *engine)
|
|
|
f0777a3 |
{
|
|
|
eb1661e |
+ engine->surrounding_text = g_object_ref_sink (text_empty);
|
|
|
eb1661e |
+ engine->surrounding_cursor_pos = 0;
|
|
|
eb1661e |
}
|
|
|
eb1661e |
|
|
|
eb1661e |
static void
|
|
|
cf977d1 |
@@ -393,6 +404,11 @@ bus_engine_proxy_real_destroy (IBusProxy *proxy)
|
|
|
eb1661e |
engine->keymap = NULL;
|
|
|
eb1661e |
}
|
|
|
eb1661e |
|
|
|
eb1661e |
+ if (engine->surrounding_text) {
|
|
|
eb1661e |
+ g_object_unref (engine->surrounding_text);
|
|
|
eb1661e |
+ engine->surrounding_text = NULL;
|
|
|
eb1661e |
+ }
|
|
|
eb1661e |
+
|
|
|
3b5789d |
IBUS_PROXY_CLASS (bus_engine_proxy_parent_class)->destroy ((IBusProxy *)engine);
|
|
|
eb1661e |
}
|
|
|
eb1661e |
|
|
|
069aa90 |
@@ -950,6 +966,33 @@ void bus_engine_proxy_property_hide (BusEngineProxy *engine,
|
|
|
f0777a3 |
NULL);
|
|
|
6cc8efa |
}
|
|
|
6cc8efa |
|
|
|
e36fdde |
+void bus_engine_proxy_set_surrounding_text (BusEngineProxy *engine,
|
|
|
e36fdde |
+ IBusText *text,
|
|
|
e36fdde |
+ guint cursor_pos)
|
|
|
6cc8efa |
+{
|
|
|
6cc8efa |
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
|
|
|
6cc8efa |
+ g_assert (text != NULL);
|
|
|
6cc8efa |
+
|
|
|
eb1661e |
+ if (!engine->surrounding_text ||
|
|
|
eb1661e |
+ g_strcmp0 (text->text, engine->surrounding_text->text) != 0 ||
|
|
|
eb1661e |
+ cursor_pos != engine->surrounding_cursor_pos) {
|
|
|
f0777a3 |
+ GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)text);
|
|
|
e36fdde |
+ if (engine->surrounding_text)
|
|
|
eb1661e |
+ g_object_unref (engine->surrounding_text);
|
|
|
eb1661e |
+ engine->surrounding_text = (IBusText *) g_object_ref_sink (text);
|
|
|
eb1661e |
+ engine->surrounding_cursor_pos = cursor_pos;
|
|
|
eb1661e |
+
|
|
|
f0777a3 |
+ g_dbus_proxy_call ((GDBusProxy *)engine,
|
|
|
f0777a3 |
+ "SetSurroundingText",
|
|
|
f0777a3 |
+ g_variant_new ("(vu)", variant, cursor_pos),
|
|
|
f0777a3 |
+ G_DBUS_CALL_FLAGS_NONE,
|
|
|
f0777a3 |
+ -1,
|
|
|
f0777a3 |
+ NULL,
|
|
|
f0777a3 |
+ NULL,
|
|
|
f0777a3 |
+ NULL);
|
|
|
eb1661e |
+ }
|
|
|
6cc8efa |
+}
|
|
|
6cc8efa |
+
|
|
|
cf977d1 |
/* a macro to generate a function to call a nullary D-Bus method. */
|
|
|
6cc8efa |
#define DEFINE_FUNCTION(Name, name) \
|
|
|
6cc8efa |
void \
|
|
|
6cc8efa |
diff --git a/bus/engineproxy.h b/bus/engineproxy.h
|
|
|
069aa90 |
index 2a82fc6..0680917 100644
|
|
|
6cc8efa |
--- a/bus/engineproxy.h
|
|
|
6cc8efa |
+++ b/bus/engineproxy.h
|
|
|
069aa90 |
@@ -212,5 +212,16 @@ void bus_engine_proxy_property_hide (BusEngineProxy *engine,
|
|
|
cf977d1 |
*/
|
|
|
6cc8efa |
gboolean bus_engine_proxy_is_enabled (BusEngineProxy *engine);
|
|
|
cf977d1 |
|
|
|
cf977d1 |
+/**
|
|
|
cf977d1 |
+ * bus_engine_proxy_set_surrounding_text:
|
|
|
cf977d1 |
+ *
|
|
|
cf977d1 |
+ * Call "SetSurroundingText" method of an engine asynchronously.
|
|
|
cf977d1 |
+ */
|
|
|
6cc8efa |
+void bus_engine_proxy_set_surrounding_text
|
|
|
6cc8efa |
+ (BusEngineProxy *engine,
|
|
|
6cc8efa |
+ IBusText *text,
|
|
|
6cc8efa |
+ guint cursor_pos);
|
|
|
cf977d1 |
+
|
|
|
cf977d1 |
+
|
|
|
6cc8efa |
G_END_DECLS
|
|
|
6cc8efa |
#endif
|
|
|
6cc8efa |
diff --git a/bus/inputcontext.c b/bus/inputcontext.c
|
|
|
069aa90 |
index 32d51e8..20f561c 100644
|
|
|
6cc8efa |
--- a/bus/inputcontext.c
|
|
|
6cc8efa |
+++ b/bus/inputcontext.c
|
|
|
cf977d1 |
@@ -247,6 +247,11 @@ static const gchar introspection_xml[] =
|
|
|
f0777a3 |
" <method name='GetEngine'>"
|
|
|
f0777a3 |
" <arg direction='out' type='v' name='desc' />"
|
|
|
f0777a3 |
" </method>"
|
|
|
f0777a3 |
+ " <method name='SetSurroundingText'>"
|
|
|
f0777a3 |
+ " <arg direction='in' type='v' name='text' />"
|
|
|
f0777a3 |
+ " <arg direction='in' type='u' name='cursor_pos' />"
|
|
|
f0777a3 |
+ " </method>"
|
|
|
f0777a3 |
+
|
|
|
f0777a3 |
/* signals */
|
|
|
f0777a3 |
" <signal name='CommitText'>"
|
|
|
f0777a3 |
" <arg type='v' name='text' />"
|
|
|
069aa90 |
@@ -961,6 +966,32 @@ _ic_get_engine (BusInputContext *context,
|
|
|
cf977d1 |
* Handle a D-Bus method call whose destination and interface name are both "org.freedesktop.IBus.InputContext"
|
|
|
cf977d1 |
*/
|
|
|
f0777a3 |
static void
|
|
|
f0777a3 |
+_ic_set_surrounding_text (BusInputContext *context,
|
|
|
f0777a3 |
+ GVariant *parameters,
|
|
|
f0777a3 |
+ GDBusMethodInvocation *invocation)
|
|
|
6cc8efa |
+{
|
|
|
f0777a3 |
+ GVariant *variant = NULL;
|
|
|
6cc8efa |
+ IBusText *text;
|
|
|
6cc8efa |
+ guint cursor_pos = 0;
|
|
|
f0777a3 |
+
|
|
|
f0777a3 |
+ g_variant_get (parameters, "(vu)", &variant, &cursor_pos);
|
|
|
f0777a3 |
+ text = IBUS_TEXT (ibus_serializable_deserialize (variant));
|
|
|
f0777a3 |
+ g_variant_unref (variant);
|
|
|
6cc8efa |
+
|
|
|
6cc8efa |
+ if ((context->capabilities & IBUS_CAP_SURROUNDING_TEXT) &&
|
|
|
f0777a3 |
+ context->has_focus && context->enabled && context->engine) {
|
|
|
eb1661e |
+ bus_engine_proxy_set_surrounding_text (context->engine,
|
|
|
eb1661e |
+ text,
|
|
|
eb1661e |
+ cursor_pos);
|
|
|
6cc8efa |
+ }
|
|
|
6cc8efa |
+
|
|
|
6cc8efa |
+ if (g_object_is_floating (text))
|
|
|
6cc8efa |
+ g_object_unref (text);
|
|
|
6cc8efa |
+
|
|
|
f0777a3 |
+ g_dbus_method_invocation_return_value (invocation, NULL);
|
|
|
6cc8efa |
+}
|
|
|
6cc8efa |
+
|
|
|
f0777a3 |
+static void
|
|
|
f0777a3 |
bus_input_context_service_method_call (IBusService *service,
|
|
|
f0777a3 |
GDBusConnection *connection,
|
|
|
f0777a3 |
const gchar *sender,
|
|
|
069aa90 |
@@ -999,6 +1030,7 @@ bus_input_context_service_method_call (IBusService *service,
|
|
|
f0777a3 |
{ "IsEnabled", _ic_is_enabled },
|
|
|
f0777a3 |
{ "SetEngine", _ic_set_engine },
|
|
|
f0777a3 |
{ "GetEngine", _ic_get_engine },
|
|
|
f0777a3 |
+ { "SetSurroundingText", _ic_set_surrounding_text},
|
|
|
6cc8efa |
};
|
|
|
6cc8efa |
|
|
|
f0777a3 |
gint i;
|
|
|
069aa90 |
@@ -2059,6 +2091,10 @@ bus_input_context_set_engine (BusInputContext *context,
|
|
|
fbc5579 |
bus_engine_proxy_set_cursor_location (context->engine, context->x, context->y, context->w, context->h);
|
|
|
fbc5579 |
}
|
|
|
fbc5579 |
}
|
|
|
fbc5579 |
+ bus_input_context_emit_signal (context,
|
|
|
fbc5579 |
+ "EngineChanged",
|
|
|
fbc5579 |
+ NULL,
|
|
|
fbc5579 |
+ NULL);
|
|
|
fbc5579 |
g_signal_emit (context,
|
|
|
fbc5579 |
context_signals[ENGINE_CHANGED],
|
|
|
fbc5579 |
0);
|
|
|
6cc8efa |
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
|
|
|
ee2c8d7 |
index a4e46cb..d029b5c 100644
|
|
|
6cc8efa |
--- a/client/gtk2/ibusimcontext.c
|
|
|
6cc8efa |
+++ b/client/gtk2/ibusimcontext.c
|
|
|
069aa90 |
@@ -27,6 +27,7 @@
|
|
|
069aa90 |
#include <gtk/gtk.h>
|
|
|
069aa90 |
#include <gdk/gdkkeysyms.h>
|
|
|
069aa90 |
#include <ibus.h>
|
|
|
069aa90 |
+#include <string.h>
|
|
|
069aa90 |
#include "ibusimcontext.h"
|
|
|
069aa90 |
|
|
|
069aa90 |
#if !GTK_CHECK_VERSION (2, 91, 0)
|
|
|
069aa90 |
@@ -60,7 +61,8 @@ struct _IBusIMContext {
|
|
|
fbc5579 |
gboolean has_focus;
|
|
|
fbc5579 |
|
|
|
069aa90 |
guint32 time;
|
|
|
fbc5579 |
- gint caps;
|
|
|
fbc5579 |
+ guint supported_caps;
|
|
|
fbc5579 |
+ guint caps;
|
|
|
fbc5579 |
};
|
|
|
fbc5579 |
|
|
|
fbc5579 |
struct _IBusIMContextClass {
|
|
|
ee2c8d7 |
@@ -111,11 +113,18 @@ static void ibus_im_context_set_cursor_location
|
|
|
6cc8efa |
static void ibus_im_context_set_use_preedit
|
|
|
6cc8efa |
(GtkIMContext *context,
|
|
|
6cc8efa |
gboolean use_preedit);
|
|
|
6cc8efa |
+static void ibus_im_context_set_surrounding
|
|
|
6cc8efa |
+ (GtkIMContext *slave,
|
|
|
6cc8efa |
+ const gchar *text,
|
|
|
6cc8efa |
+ gint len,
|
|
|
6cc8efa |
+ gint cursor_index);
|
|
|
6cc8efa |
+
|
|
|
6cc8efa |
|
|
|
6cc8efa |
/* static methods*/
|
|
|
6cc8efa |
static void _create_input_context (IBusIMContext *context);
|
|
|
fbc5579 |
static void _set_cursor_location_internal
|
|
|
fbc5579 |
(GtkIMContext *context);
|
|
|
fbc5579 |
+static void _negotiate_capabilities (IBusIMContext *context);
|
|
|
fbc5579 |
|
|
|
fbc5579 |
static void _bus_connected_cb (IBusBus *bus,
|
|
|
fbc5579 |
IBusIMContext *context);
|
|
|
ee2c8d7 |
@@ -129,14 +138,15 @@ static void _slave_preedit_start_cb (GtkIMContext *slave,
|
|
|
6cc8efa |
IBusIMContext *context);
|
|
|
6cc8efa |
static void _slave_preedit_end_cb (GtkIMContext *slave,
|
|
|
6cc8efa |
IBusIMContext *context);
|
|
|
6cc8efa |
-static void _slave_retrieve_surrounding_cb
|
|
|
6cc8efa |
+static gboolean _slave_retrieve_surrounding_cb
|
|
|
6cc8efa |
(GtkIMContext *slave,
|
|
|
f7291cc |
- IBusIMContext *context);
|
|
|
6cc8efa |
-static void _slave_delete_surrounding_cb
|
|
|
f7291cc |
+ IBusIMContext *context);
|
|
|
6cc8efa |
+static gboolean _slave_delete_surrounding_cb
|
|
|
6cc8efa |
(GtkIMContext *slave,
|
|
|
f7291cc |
- gint offset_from_cursor,
|
|
|
f7291cc |
- guint nchars,
|
|
|
f7291cc |
- IBusIMContext *context);
|
|
|
f7291cc |
+ gint offset_from_cursor,
|
|
|
f7291cc |
+ guint nchars,
|
|
|
f7291cc |
+ IBusIMContext *context);
|
|
|
eb1661e |
+static void _request_surrounding_text (IBusIMContext *context);
|
|
|
069aa90 |
static void _create_fake_input_context (void);
|
|
|
069aa90 |
|
|
|
eb1661e |
|
|
|
ee2c8d7 |
@@ -248,6 +258,17 @@ _process_key_event_done (GObject *object,
|
|
|
eb1661e |
}
|
|
|
eb1661e |
|
|
|
0610dd6 |
|
|
|
eb1661e |
+static void
|
|
|
eb1661e |
+_request_surrounding_text (IBusIMContext *context)
|
|
|
eb1661e |
+{
|
|
|
f7291cc |
+ if (context->enable &&
|
|
|
f7291cc |
+ (context->caps & IBUS_CAP_SURROUNDING_TEXT)) {
|
|
|
6cc8efa |
+ gboolean return_value;
|
|
|
eb1661e |
+ g_signal_emit (context, _signal_retrieve_surrounding_id, 0,
|
|
|
6cc8efa |
+ &return_value);
|
|
|
6cc8efa |
+ }
|
|
|
eb1661e |
+}
|
|
|
eb1661e |
+
|
|
|
eb1661e |
static gint
|
|
|
eb1661e |
_key_snooper_cb (GtkWidget *widget,
|
|
|
eb1661e |
GdkEventKey *event,
|
|
|
ee2c8d7 |
@@ -334,6 +355,8 @@ _key_snooper_cb (GtkWidget *widget,
|
|
|
0610dd6 |
|
|
|
0610dd6 |
} while (0);
|
|
|
eb1661e |
|
|
|
eb1661e |
+ _request_surrounding_text (ibusimcontext);
|
|
|
6cc8efa |
+
|
|
|
0610dd6 |
if (ibusimcontext != NULL) {
|
|
|
0610dd6 |
ibusimcontext->time = event->time;
|
|
|
0610dd6 |
}
|
|
|
ee2c8d7 |
@@ -430,6 +453,7 @@ ibus_im_context_class_init (IBusIMContextClass *class)
|
|
|
6cc8efa |
im_context_class->set_client_window = ibus_im_context_set_client_window;
|
|
|
6cc8efa |
im_context_class->set_cursor_location = ibus_im_context_set_cursor_location;
|
|
|
6cc8efa |
im_context_class->set_use_preedit = ibus_im_context_set_use_preedit;
|
|
|
6cc8efa |
+ im_context_class->set_surrounding = ibus_im_context_set_surrounding;
|
|
|
6cc8efa |
gobject_class->finalize = ibus_im_context_finalize;
|
|
|
6cc8efa |
|
|
|
6cc8efa |
_signal_commit_id =
|
|
|
ee2c8d7 |
@@ -577,7 +601,12 @@ ibus_im_context_init (GObject *obj)
|
|
|
f7291cc |
ibusimcontext->ibuscontext = NULL;
|
|
|
f7291cc |
ibusimcontext->has_focus = FALSE;
|
|
|
069aa90 |
ibusimcontext->time = GDK_CURRENT_TIME;
|
|
|
fbc5579 |
- ibusimcontext->caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS | IBUS_CAP_SURROUNDING_TEXT;
|
|
|
f7291cc |
+#ifdef ENABLE_SURROUNDING
|
|
|
fbc5579 |
+ ibusimcontext->supported_caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS | IBUS_CAP_SURROUNDING_TEXT;
|
|
|
f7291cc |
+#else
|
|
|
fbc5579 |
+ ibusimcontext->supported_caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS;
|
|
|
f7291cc |
+#endif
|
|
|
fbc5579 |
+ ibusimcontext->caps = ibusimcontext->supported_caps;
|
|
|
f7291cc |
|
|
|
f7291cc |
|
|
|
f7291cc |
// Create slave im context
|
|
|
ee2c8d7 |
@@ -674,6 +703,8 @@ ibus_im_context_filter_keypress (GtkIMContext *context,
|
|
|
0610dd6 |
if (ibusimcontext->client_window == NULL && event->window != NULL)
|
|
|
0610dd6 |
gtk_im_context_set_client_window ((GtkIMContext *)ibusimcontext, event->window);
|
|
|
6cc8efa |
|
|
|
eb1661e |
+ _request_surrounding_text (ibusimcontext);
|
|
|
6cc8efa |
+
|
|
|
0610dd6 |
if (ibusimcontext != NULL) {
|
|
|
0610dd6 |
ibusimcontext->time = event->time;
|
|
|
0610dd6 |
}
|
|
|
ee2c8d7 |
@@ -768,6 +799,8 @@ ibus_im_context_focus_in (GtkIMContext *context)
|
|
|
cf977d1 |
(gpointer *) &_focus_im_context);
|
|
|
6cc8efa |
_focus_im_context = context;
|
|
|
6cc8efa |
}
|
|
|
6cc8efa |
+
|
|
|
eb1661e |
+ _request_surrounding_text (ibusimcontext);
|
|
|
6cc8efa |
}
|
|
|
6cc8efa |
|
|
|
6cc8efa |
static void
|
|
|
ee2c8d7 |
@@ -925,6 +958,25 @@ ibus_im_context_set_cursor_location (GtkIMContext *context, GdkRectangle *area)
|
|
|
fbc5579 |
}
|
|
|
fbc5579 |
|
|
|
fbc5579 |
static void
|
|
|
fbc5579 |
+_negotiate_capabilities (IBusIMContext *context)
|
|
|
fbc5579 |
+{
|
|
|
fbc5579 |
+ IBusEngineDesc *engine;
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
+ engine = ibus_input_context_get_engine (context->ibuscontext);
|
|
|
fbc5579 |
+ if (engine) {
|
|
|
fbc5579 |
+ context->caps = context->supported_caps &
|
|
|
fbc5579 |
+ ibus_engine_desc_get_requires (engine);
|
|
|
fbc5579 |
+ ibus_input_context_set_capabilities (context->ibuscontext,
|
|
|
fbc5579 |
+ context->caps);
|
|
|
fbc5579 |
+ IDEBUG ("engine %s: supported caps = %u, engine wants = %u, caps = %u",
|
|
|
fbc5579 |
+ ibus_engine_desc_get_name (engine)
|
|
|
fbc5579 |
+ context->supported_caps,
|
|
|
fbc5579 |
+ ibus_engine_desc_get_requires (engine),
|
|
|
fbc5579 |
+ context->caps);
|
|
|
fbc5579 |
+ }
|
|
|
fbc5579 |
+}
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
+static void
|
|
|
fbc5579 |
ibus_im_context_set_use_preedit (GtkIMContext *context, gboolean use_preedit)
|
|
|
fbc5579 |
{
|
|
|
fbc5579 |
IDEBUG ("%s", __FUNCTION__);
|
|
|
ee2c8d7 |
@@ -933,17 +985,50 @@ ibus_im_context_set_use_preedit (GtkIMContext *context, gboolean use_preedit)
|
|
|
fbc5579 |
|
|
|
fbc5579 |
if(ibusimcontext->ibuscontext) {
|
|
|
fbc5579 |
if (use_preedit) {
|
|
|
fbc5579 |
- ibusimcontext->caps |= IBUS_CAP_PREEDIT_TEXT;
|
|
|
fbc5579 |
+ ibusimcontext->supported_caps |= IBUS_CAP_PREEDIT_TEXT;
|
|
|
fbc5579 |
}
|
|
|
fbc5579 |
else {
|
|
|
fbc5579 |
- ibusimcontext->caps &= ~IBUS_CAP_PREEDIT_TEXT;
|
|
|
fbc5579 |
+ ibusimcontext->supported_caps &= ~IBUS_CAP_PREEDIT_TEXT;
|
|
|
fbc5579 |
}
|
|
|
fbc5579 |
- ibus_input_context_set_capabilities (ibusimcontext->ibuscontext, ibusimcontext->caps);
|
|
|
fbc5579 |
+ _negotiate_capabilities (ibusimcontext);
|
|
|
fbc5579 |
}
|
|
|
fbc5579 |
gtk_im_context_set_use_preedit (ibusimcontext->slave, use_preedit);
|
|
|
6cc8efa |
}
|
|
|
6cc8efa |
|
|
|
6cc8efa |
static void
|
|
|
6cc8efa |
+ibus_im_context_set_surrounding (GtkIMContext *context,
|
|
|
6cc8efa |
+ const gchar *text,
|
|
|
6cc8efa |
+ gint len,
|
|
|
6cc8efa |
+ gint cursor_index)
|
|
|
6cc8efa |
+{
|
|
|
6cc8efa |
+ g_return_if_fail (context != NULL);
|
|
|
6cc8efa |
+ g_return_if_fail (IBUS_IS_IM_CONTEXT (context));
|
|
|
eb1661e |
+ g_return_if_fail (text != NULL);
|
|
|
eb1661e |
+ g_return_if_fail (strlen (text) >= len);
|
|
|
eb1661e |
+ g_return_if_fail (0 <= cursor_index && cursor_index <= len);
|
|
|
6cc8efa |
+
|
|
|
e36fdde |
+ IBusIMContext *ibusimcontext = IBUS_IM_CONTEXT (context);
|
|
|
6cc8efa |
+
|
|
|
6cc8efa |
+ if (ibusimcontext->enable && ibusimcontext->ibuscontext) {
|
|
|
6cc8efa |
+ IBusText *ibustext;
|
|
|
6cc8efa |
+ guint cursor_pos;
|
|
|
eb1661e |
+ gchar *p;
|
|
|
6cc8efa |
+
|
|
|
eb1661e |
+ p = g_strndup (text, len);
|
|
|
eb1661e |
+ cursor_pos = g_utf8_strlen (p, cursor_index);
|
|
|
eb1661e |
+ ibustext = ibus_text_new_from_string (p);
|
|
|
eb1661e |
+ g_free (p);
|
|
|
6cc8efa |
+ ibus_input_context_set_surrounding_text (ibusimcontext->ibuscontext,
|
|
|
6cc8efa |
+ ibustext,
|
|
|
6cc8efa |
+ cursor_pos);
|
|
|
6cc8efa |
+ }
|
|
|
6cc8efa |
+ gtk_im_context_set_surrounding (ibusimcontext->slave,
|
|
|
6cc8efa |
+ text,
|
|
|
6cc8efa |
+ len,
|
|
|
6cc8efa |
+ cursor_index);
|
|
|
6cc8efa |
+}
|
|
|
6cc8efa |
+
|
|
|
6cc8efa |
+static void
|
|
|
6cc8efa |
_bus_connected_cb (IBusBus *bus,
|
|
|
6cc8efa |
IBusIMContext *ibusimcontext)
|
|
|
6cc8efa |
{
|
|
|
ee2c8d7 |
@@ -962,6 +1047,8 @@ _ibus_context_commit_text_cb (IBusInputContext *ibuscontext,
|
|
|
6cc8efa |
IDEBUG ("%s", __FUNCTION__);
|
|
|
6cc8efa |
|
|
|
6cc8efa |
g_signal_emit (ibusimcontext, _signal_commit_id, 0, text->text);
|
|
|
6cc8efa |
+
|
|
|
eb1661e |
+ _request_surrounding_text (ibusimcontext);
|
|
|
6cc8efa |
}
|
|
|
6cc8efa |
|
|
|
6cc8efa |
static gboolean
|
|
|
ee2c8d7 |
@@ -1256,6 +1343,8 @@ _ibus_context_show_preedit_text_cb (IBusInputContext *ibuscontext,
|
|
|
6cc8efa |
ibusimcontext->preedit_visible = TRUE;
|
|
|
6cc8efa |
g_signal_emit (ibusimcontext, _signal_preedit_start_id, 0);
|
|
|
6cc8efa |
g_signal_emit (ibusimcontext, _signal_preedit_changed_id, 0);
|
|
|
6cc8efa |
+
|
|
|
eb1661e |
+ _request_surrounding_text (ibusimcontext);
|
|
|
6cc8efa |
}
|
|
|
6cc8efa |
|
|
|
6cc8efa |
static void
|
|
|
ee2c8d7 |
@@ -1321,6 +1410,14 @@ _ibus_context_destroy_cb (IBusInputContext *ibuscontext,
|
|
|
fbc5579 |
}
|
|
|
fbc5579 |
|
|
|
fbc5579 |
static void
|
|
|
fbc5579 |
+_ibus_context_engine_changed_cb (IBusInputContext *ibuscontext,
|
|
|
fbc5579 |
+ IBusIMContext *ibusimcontext)
|
|
|
fbc5579 |
+{
|
|
|
fbc5579 |
+ IDEBUG ("%s", __FUNCTION__);
|
|
|
fbc5579 |
+ _negotiate_capabilities (ibusimcontext);
|
|
|
fbc5579 |
+}
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
+static void
|
|
|
fbc5579 |
_create_input_context (IBusIMContext *ibusimcontext)
|
|
|
fbc5579 |
{
|
|
|
fbc5579 |
IDEBUG ("%s", __FUNCTION__);
|
|
|
ee2c8d7 |
@@ -1363,6 +1460,10 @@ _create_input_context (IBusIMContext *ibusimcontext)
|
|
|
fbc5579 |
"disabled",
|
|
|
fbc5579 |
G_CALLBACK (_ibus_context_disabled_cb),
|
|
|
fbc5579 |
ibusimcontext);
|
|
|
fbc5579 |
+ g_signal_connect (ibusimcontext->ibuscontext,
|
|
|
fbc5579 |
+ "engine-changed",
|
|
|
fbc5579 |
+ G_CALLBACK (_ibus_context_engine_changed_cb),
|
|
|
fbc5579 |
+ ibusimcontext);
|
|
|
fbc5579 |
g_signal_connect (ibusimcontext->ibuscontext, "destroy",
|
|
|
fbc5579 |
G_CALLBACK (_ibus_context_destroy_cb),
|
|
|
fbc5579 |
ibusimcontext);
|
|
|
ee2c8d7 |
@@ -1419,17 +1520,21 @@ _slave_preedit_end_cb (GtkIMContext *slave,
|
|
|
6cc8efa |
g_signal_emit (ibusimcontext, _signal_preedit_end_id, 0);
|
|
|
6cc8efa |
}
|
|
|
6cc8efa |
|
|
|
6cc8efa |
-static void
|
|
|
6cc8efa |
+static gboolean
|
|
|
6cc8efa |
_slave_retrieve_surrounding_cb (GtkIMContext *slave,
|
|
|
6cc8efa |
IBusIMContext *ibusimcontext)
|
|
|
6cc8efa |
{
|
|
|
6cc8efa |
+ gboolean return_value;
|
|
|
6cc8efa |
+
|
|
|
6cc8efa |
if (ibusimcontext->enable && ibusimcontext->ibuscontext) {
|
|
|
6cc8efa |
- return;
|
|
|
6cc8efa |
+ return FALSE;
|
|
|
6cc8efa |
}
|
|
|
6cc8efa |
- g_signal_emit (ibusimcontext, _signal_retrieve_surrounding_id, 0);
|
|
|
6cc8efa |
+ g_signal_emit (ibusimcontext, _signal_retrieve_surrounding_id, 0,
|
|
|
6cc8efa |
+ &return_value);
|
|
|
6cc8efa |
+ return return_value;
|
|
|
6cc8efa |
}
|
|
|
6cc8efa |
|
|
|
6cc8efa |
-static void
|
|
|
6cc8efa |
+static gboolean
|
|
|
6cc8efa |
_slave_delete_surrounding_cb (GtkIMContext *slave,
|
|
|
6cc8efa |
gint offset_from_cursor,
|
|
|
6cc8efa |
guint nchars,
|
|
|
ee2c8d7 |
@@ -1438,9 +1543,10 @@ _slave_delete_surrounding_cb (GtkIMContext *slave,
|
|
|
6cc8efa |
gboolean return_value;
|
|
|
6cc8efa |
|
|
|
6cc8efa |
if (ibusimcontext->enable && ibusimcontext->ibuscontext) {
|
|
|
6cc8efa |
- return;
|
|
|
6cc8efa |
+ return FALSE;
|
|
|
6cc8efa |
}
|
|
|
6cc8efa |
g_signal_emit (ibusimcontext, _signal_delete_surrounding_id, 0, offset_from_cursor, nchars, &return_value);
|
|
|
6cc8efa |
+ return return_value;
|
|
|
6cc8efa |
}
|
|
|
6cc8efa |
|
|
|
069aa90 |
#ifdef OS_CHROMEOS
|
|
|
f7291cc |
diff --git a/configure.ac b/configure.ac
|
|
|
ee2c8d7 |
index 81efe81..e5fe925 100644
|
|
|
f7291cc |
--- a/configure.ac
|
|
|
f7291cc |
+++ b/configure.ac
|
|
|
ee2c8d7 |
@@ -364,6 +364,19 @@ AC_ARG_WITH(sync-mode-apps,
|
|
|
ee2c8d7 |
AC_DEFINE_UNQUOTED(SYNC_MODE_APPS, "$SYNC_MODE_APPS",
|
|
|
ee2c8d7 |
[Enbale sync mode in those applications])
|
|
|
f7291cc |
|
|
|
f7291cc |
+# option for enable surrounding-text
|
|
|
f7291cc |
+AC_ARG_ENABLE(surrounding-text,
|
|
|
f7291cc |
+ AS_HELP_STRING([--enable-surrounding-text],
|
|
|
f7291cc |
+ [Enable surrounding-text support]),
|
|
|
f7291cc |
+ [enable_surrounding_text=$enableval],
|
|
|
f7291cc |
+ [enable_surrounding_text=no]
|
|
|
f7291cc |
+)
|
|
|
f7291cc |
+if test x"$enable_surrounding_text" = x"yes"; then
|
|
|
f7291cc |
+ AC_DEFINE(ENABLE_SURROUNDING, TRUE, [Enable surrounding-text support])
|
|
|
f7291cc |
+else
|
|
|
f7291cc |
+ enable_surrounding_text="no (disabled, use --enable-surrounding-text to enable)"
|
|
|
f7291cc |
+fi
|
|
|
f7291cc |
+
|
|
|
f7291cc |
# check iso-codes
|
|
|
f7291cc |
PKG_CHECK_MODULES(ISOCODES, [
|
|
|
f7291cc |
iso-codes
|
|
|
ee2c8d7 |
@@ -435,5 +448,6 @@ Build options:
|
|
|
f7291cc |
Enable key snooper $enable_key_snooper
|
|
|
ee2c8d7 |
Sync mode regexes "$SYNC_MODE_APPS"
|
|
|
f7291cc |
No snooper regexes "$NO_SNOOPER_APPS"
|
|
|
f7291cc |
+ Enable surrounding-text $enable_surrounding_text
|
|
|
f7291cc |
])
|
|
|
f7291cc |
|
|
|
7232d5e |
diff --git a/ibus/engine.py b/ibus/engine.py
|
|
|
7232d5e |
index b1df2fe..ec42fa4 100644
|
|
|
7232d5e |
--- a/ibus/engine.py
|
|
|
7232d5e |
+++ b/ibus/engine.py
|
|
|
7232d5e |
@@ -46,6 +46,9 @@ class EngineBase(object.Object):
|
|
|
7232d5e |
def set_cursor_location(self, x, y, w, h):
|
|
|
7232d5e |
pass
|
|
|
7232d5e |
|
|
|
7232d5e |
+ def set_surrounding_text(self, text, cursor_index):
|
|
|
7232d5e |
+ pass
|
|
|
7232d5e |
+
|
|
|
7232d5e |
def set_capabilities(self, cap):
|
|
|
7232d5e |
pass
|
|
|
7232d5e |
|
|
|
7232d5e |
@@ -163,6 +166,9 @@ class EngineProxy(interface.IEngine):
|
|
|
7232d5e |
def SetCursorLocation(self, x, y, w, h):
|
|
|
7232d5e |
return self.__engine.set_cursor_location(x, y, w, h)
|
|
|
7232d5e |
|
|
|
7232d5e |
+ def SetSurroundingText(self, text, cursor_index):
|
|
|
7232d5e |
+ return self.__engine.set_surrounding_text(text, cursor_index)
|
|
|
7232d5e |
+
|
|
|
7232d5e |
def SetCapabilities(self, caps):
|
|
|
7232d5e |
return self.__engine.set_capabilities(caps)
|
|
|
7232d5e |
|
|
|
7232d5e |
diff --git a/ibus/interface/iengine.py b/ibus/interface/iengine.py
|
|
|
f0777a3 |
index 2386c0f..5db2012 100644
|
|
|
7232d5e |
--- a/ibus/interface/iengine.py
|
|
|
7232d5e |
+++ b/ibus/interface/iengine.py
|
|
|
7232d5e |
@@ -50,6 +50,9 @@ class IEngine(dbus.service.Object):
|
|
|
7232d5e |
@method(in_signature="iiii")
|
|
|
7232d5e |
def SetCursorLocation(self, x, y, w, h): pass
|
|
|
7232d5e |
|
|
|
7232d5e |
+ @method(in_signature="vu")
|
|
|
7232d5e |
+ def SetSurroundingText(self, text, cursor_index): pass
|
|
|
7232d5e |
+
|
|
|
7232d5e |
@method(in_signature="u")
|
|
|
7232d5e |
def SetCapabilities(self, cap): pass
|
|
|
7232d5e |
|
|
|
7232d5e |
diff --git a/ibus/interface/iinputcontext.py b/ibus/interface/iinputcontext.py
|
|
|
069aa90 |
index 89f6dbd..bb25c5a 100644
|
|
|
7232d5e |
--- a/ibus/interface/iinputcontext.py
|
|
|
7232d5e |
+++ b/ibus/interface/iinputcontext.py
|
|
|
069aa90 |
@@ -49,6 +49,9 @@ class IInputContext(dbus.service.Object):
|
|
|
7232d5e |
@method(in_signature="iiii")
|
|
|
7232d5e |
def SetCursorLocation(self, x, y, w, h): pass
|
|
|
7232d5e |
|
|
|
7232d5e |
+ @method(in_signature="vu")
|
|
|
7232d5e |
+ def SetSurroundingText(self, text, cursor_index): pass
|
|
|
7232d5e |
+
|
|
|
7232d5e |
@method()
|
|
|
7232d5e |
def FocusIn(self): pass
|
|
|
7232d5e |
|
|
|
069aa90 |
@@ -137,4 +140,6 @@ class IInputContext(dbus.service.Object):
|
|
|
fbc5579 |
@signal(signature="v")
|
|
|
fbc5579 |
def UpdateProperty(self, prop): pass
|
|
|
fbc5579 |
|
|
|
fbc5579 |
+ @signal()
|
|
|
fbc5579 |
+ def EngineChanged(self): pass
|
|
|
fbc5579 |
|
|
|
6cc8efa |
diff --git a/src/ibusengine.c b/src/ibusengine.c
|
|
|
0610dd6 |
index 519d7ca..fc129a2 100644
|
|
|
6cc8efa |
--- a/src/ibusengine.c
|
|
|
6cc8efa |
+++ b/src/ibusengine.c
|
|
|
eb1661e |
@@ -45,6 +45,7 @@ enum {
|
|
|
6cc8efa |
PROPERTY_SHOW,
|
|
|
6cc8efa |
PROPERTY_HIDE,
|
|
|
6cc8efa |
CANDIDATE_CLICKED,
|
|
|
6cc8efa |
+ SET_SURROUNDING_TEXT,
|
|
|
6cc8efa |
LAST_SIGNAL,
|
|
|
6cc8efa |
};
|
|
|
6cc8efa |
|
|
|
f0777a3 |
@@ -58,10 +59,15 @@ enum {
|
|
|
6cc8efa |
struct _IBusEnginePrivate {
|
|
|
f0777a3 |
gchar *engine_name;
|
|
|
f0777a3 |
GDBusConnection *connection;
|
|
|
6cc8efa |
+
|
|
|
6cc8efa |
+ IBusText *surrounding_text;
|
|
|
6cc8efa |
+ guint surrounding_cursor_pos;
|
|
|
6cc8efa |
};
|
|
|
6cc8efa |
|
|
|
6cc8efa |
static guint engine_signals[LAST_SIGNAL] = { 0 };
|
|
|
6cc8efa |
|
|
|
6cc8efa |
+static IBusText *text_empty = NULL;
|
|
|
6cc8efa |
+
|
|
|
6cc8efa |
/* functions prototype */
|
|
|
f0777a3 |
static void ibus_engine_destroy (IBusEngine *engine);
|
|
|
f0777a3 |
static void ibus_engine_set_property (IBusEngine *engine,
|
|
|
f0777a3 |
@@ -135,6 +141,10 @@ static void ibus_engine_property_show (IBusEngine *engine,
|
|
|
f0777a3 |
const gchar *prop_name);
|
|
|
f0777a3 |
static void ibus_engine_property_hide (IBusEngine *engine,
|
|
|
f0777a3 |
const gchar *prop_name);
|
|
|
f0777a3 |
+static void ibus_engine_set_surrounding_text
|
|
|
6cc8efa |
+ (IBusEngine *engine,
|
|
|
6cc8efa |
+ IBusText *text,
|
|
|
6cc8efa |
+ guint cursor_pos);
|
|
|
f0777a3 |
static void ibus_engine_emit_signal (IBusEngine *engine,
|
|
|
f0777a3 |
const gchar *signal_name,
|
|
|
f0777a3 |
GVariant *parameters);
|
|
|
0610dd6 |
@@ -185,6 +195,10 @@ static const gchar introspection_xml[] =
|
|
|
fc455bb |
" <method name='PageDown' />"
|
|
|
fc455bb |
" <method name='CursorUp' />"
|
|
|
fc455bb |
" <method name='CursorDown' />"
|
|
|
fc455bb |
+ " <method name='SetSurroundingText'>"
|
|
|
fc455bb |
+ " <arg direction='in' type='v' name='text' />"
|
|
|
fc455bb |
+ " <arg direction='in' type='u' name='cursor_pos' />"
|
|
|
fc455bb |
+ " </method>"
|
|
|
fc455bb |
/* FIXME signals */
|
|
|
fc455bb |
" <signal name='CommitText'>"
|
|
|
fc455bb |
" <arg type='v' name='text' />"
|
|
|
0610dd6 |
@@ -250,6 +264,7 @@ ibus_engine_class_init (IBusEngineClass *class)
|
|
|
f0777a3 |
class->property_hide = ibus_engine_property_hide;
|
|
|
f0777a3 |
class->set_cursor_location = ibus_engine_set_cursor_location;
|
|
|
f0777a3 |
class->set_capabilities = ibus_engine_set_capabilities;
|
|
|
f0777a3 |
+ class->set_surrounding_text = ibus_engine_set_surrounding_text;
|
|
|
6cc8efa |
|
|
|
6cc8efa |
/* install properties */
|
|
|
f0777a3 |
/**
|
|
|
0610dd6 |
@@ -616,12 +631,39 @@ ibus_engine_class_init (IBusEngineClass *class)
|
|
|
6cc8efa |
G_TYPE_STRING);
|
|
|
6cc8efa |
|
|
|
f0777a3 |
g_type_class_add_private (class, sizeof (IBusEnginePrivate));
|
|
|
f0777a3 |
+
|
|
|
6cc8efa |
+ /**
|
|
|
6cc8efa |
+ * IBusEngine::set-surrounding-text:
|
|
|
6cc8efa |
+ * @engine: An IBusEngine.
|
|
|
6cc8efa |
+ *
|
|
|
6cc8efa |
+ * Emitted when a surrounding text is set.
|
|
|
6cc8efa |
+ * Implement the member function set_surrounding_text() in extended class to receive this signal.
|
|
|
6cc8efa |
+ *
|
|
|
6cc8efa |
+ * <note><para>Argument @user_data is ignored in this function.</para></note>
|
|
|
6cc8efa |
+ */
|
|
|
6cc8efa |
+ engine_signals[SET_SURROUNDING_TEXT] =
|
|
|
6cc8efa |
+ g_signal_new (I_("set-surrounding-text"),
|
|
|
6cc8efa |
+ G_TYPE_FROM_CLASS (gobject_class),
|
|
|
6cc8efa |
+ G_SIGNAL_RUN_LAST,
|
|
|
6cc8efa |
+ G_STRUCT_OFFSET (IBusEngineClass, set_surrounding_text),
|
|
|
6cc8efa |
+ NULL, NULL,
|
|
|
f0777a3 |
+ _ibus_marshal_VOID__OBJECT_UINT,
|
|
|
6cc8efa |
+ G_TYPE_NONE,
|
|
|
6cc8efa |
+ 2,
|
|
|
eb1661e |
+ G_TYPE_OBJECT,
|
|
|
6cc8efa |
+ G_TYPE_UINT);
|
|
|
6cc8efa |
+
|
|
|
e36fdde |
+ text_empty = ibus_text_new_from_static_string ("");
|
|
|
eb1661e |
+ g_object_ref_sink (text_empty);
|
|
|
6cc8efa |
}
|
|
|
6cc8efa |
|
|
|
6cc8efa |
static void
|
|
|
f0777a3 |
ibus_engine_init (IBusEngine *engine)
|
|
|
f0777a3 |
{
|
|
|
f0777a3 |
engine->priv = IBUS_ENGINE_GET_PRIVATE (engine);
|
|
|
6cc8efa |
+
|
|
|
f0777a3 |
+ engine->priv->surrounding_text = g_object_ref_sink (text_empty);
|
|
|
f0777a3 |
+ engine->priv->surrounding_cursor_pos = 0;
|
|
|
6cc8efa |
}
|
|
|
6cc8efa |
|
|
|
6cc8efa |
static void
|
|
|
0610dd6 |
@@ -630,6 +672,11 @@ ibus_engine_destroy (IBusEngine *engine)
|
|
|
f0777a3 |
g_free (engine->priv->engine_name);
|
|
|
f0777a3 |
engine->priv->engine_name = NULL;
|
|
|
6cc8efa |
|
|
|
f0777a3 |
+ if (engine->priv->surrounding_text) {
|
|
|
f0777a3 |
+ g_object_unref (engine->priv->surrounding_text);
|
|
|
f0777a3 |
+ engine->priv->surrounding_text = NULL;
|
|
|
6cc8efa |
+ }
|
|
|
6cc8efa |
+
|
|
|
6cc8efa |
IBUS_OBJECT_CLASS(ibus_engine_parent_class)->destroy (IBUS_OBJECT (engine));
|
|
|
6cc8efa |
}
|
|
|
6cc8efa |
|
|
|
0610dd6 |
@@ -801,6 +848,25 @@ ibus_engine_service_method_call (IBusService *service,
|
|
|
f0777a3 |
return;
|
|
|
f0777a3 |
}
|
|
|
f0777a3 |
|
|
|
f0777a3 |
+ if (g_strcmp0 (method_name, "SetSurroundingText") == 0) {
|
|
|
f0777a3 |
+ GVariant *variant = NULL;
|
|
|
f0777a3 |
+ IBusText *text;
|
|
|
f0777a3 |
+ guint cursor_pos;
|
|
|
f0777a3 |
+
|
|
|
f0777a3 |
+ g_variant_get (parameters, "(vu)", &variant, &cursor_pos);
|
|
|
f0777a3 |
+ text = IBUS_TEXT (ibus_serializable_deserialize (variant));
|
|
|
f0777a3 |
+ g_variant_unref (variant);
|
|
|
f0777a3 |
+
|
|
|
f0777a3 |
+ g_signal_emit (engine, engine_signals[SET_SURROUNDING_TEXT], 0,
|
|
|
f0777a3 |
+ text,
|
|
|
f0777a3 |
+ cursor_pos);
|
|
|
f0777a3 |
+ if (g_object_is_floating (text)) {
|
|
|
f0777a3 |
+ g_object_unref (text);
|
|
|
6cc8efa |
+ }
|
|
|
f0777a3 |
+ g_dbus_method_invocation_return_value (invocation, NULL);
|
|
|
f0777a3 |
+ return;
|
|
|
f0777a3 |
+ }
|
|
|
f0777a3 |
+
|
|
|
f0777a3 |
/* should not be reached */
|
|
|
f0777a3 |
g_return_if_reached ();
|
|
|
f0777a3 |
}
|
|
|
0610dd6 |
@@ -955,6 +1021,26 @@ ibus_engine_property_hide (IBusEngine *engine, const gchar *prop_name)
|
|
|
6cc8efa |
}
|
|
|
6cc8efa |
|
|
|
6cc8efa |
static void
|
|
|
6cc8efa |
+ibus_engine_set_surrounding_text (IBusEngine *engine,
|
|
|
6cc8efa |
+ IBusText *text,
|
|
|
6cc8efa |
+ guint cursor_pos)
|
|
|
6cc8efa |
+{
|
|
|
e36fdde |
+ g_assert (IBUS_IS_ENGINE (engine));
|
|
|
e36fdde |
+
|
|
|
e36fdde |
+ IBusEnginePrivate *priv;
|
|
|
e36fdde |
+
|
|
|
e36fdde |
+ priv = IBUS_ENGINE_GET_PRIVATE (engine);
|
|
|
e36fdde |
+
|
|
|
e36fdde |
+ if (priv->surrounding_text) {
|
|
|
e36fdde |
+ g_object_unref (priv->surrounding_text);
|
|
|
e36fdde |
+ }
|
|
|
e36fdde |
+
|
|
|
e36fdde |
+ priv->surrounding_text = (IBusText *) g_object_ref_sink (text ? text : text_empty);
|
|
|
e36fdde |
+ priv->surrounding_cursor_pos = cursor_pos;
|
|
|
6cc8efa |
+ // g_debug ("set-surrounding-text ('%s', %d)", text->text, cursor_pos);
|
|
|
6cc8efa |
+}
|
|
|
6cc8efa |
+
|
|
|
6cc8efa |
+static void
|
|
|
f0777a3 |
ibus_engine_emit_signal (IBusEngine *engine,
|
|
|
f0777a3 |
const gchar *signal_name,
|
|
|
f0777a3 |
GVariant *parameters)
|
|
|
0610dd6 |
@@ -1138,14 +1224,66 @@ void ibus_engine_delete_surrounding_text (IBusEngine *engine,
|
|
|
e36fdde |
gint offset_from_cursor,
|
|
|
e36fdde |
guint nchars)
|
|
|
eb1661e |
{
|
|
|
e36fdde |
+ IBusEnginePrivate *priv;
|
|
|
e36fdde |
+
|
|
|
f0777a3 |
g_return_if_fail (IBUS_IS_ENGINE (engine));
|
|
|
f0777a3 |
|
|
|
eb1661e |
+ priv = IBUS_ENGINE_GET_PRIVATE (engine);
|
|
|
eb1661e |
+
|
|
|
f7291cc |
+ /* Update surrounding-text cache. This is necessary since some
|
|
|
f7291cc |
+ engines call ibus_engine_get_surrounding_text() immediately
|
|
|
f7291cc |
+ after ibus_engine_delete_surrounding_text(). */
|
|
|
eb1661e |
+ if (priv->surrounding_text) {
|
|
|
f7291cc |
+ IBusText *text;
|
|
|
f7291cc |
+ glong cursor_pos, len;
|
|
|
f7291cc |
+
|
|
|
f7291cc |
+ cursor_pos = priv->surrounding_cursor_pos + offset_from_cursor;
|
|
|
f7291cc |
+ len = ibus_text_get_length (priv->surrounding_text);
|
|
|
f7291cc |
+ if (cursor_pos >= 0 && len - cursor_pos >= nchars) {
|
|
|
f7291cc |
+ gunichar *ucs;
|
|
|
f7291cc |
+
|
|
|
f7291cc |
+ ucs = g_utf8_to_ucs4_fast (priv->surrounding_text->text,
|
|
|
f7291cc |
+ -1,
|
|
|
f7291cc |
+ NULL);
|
|
|
f7291cc |
+ memmove (&ucs[cursor_pos],
|
|
|
f7291cc |
+ &ucs[cursor_pos + nchars],
|
|
|
f7291cc |
+ sizeof(gunichar) * (len - cursor_pos - nchars));
|
|
|
f7291cc |
+ ucs[len - nchars] = 0;
|
|
|
f7291cc |
+ text = ibus_text_new_from_ucs4 (ucs);
|
|
|
f7291cc |
+ g_free (ucs);
|
|
|
f7291cc |
+ priv->surrounding_cursor_pos = cursor_pos;
|
|
|
f7291cc |
+ } else {
|
|
|
f7291cc |
+ text = text_empty;
|
|
|
f7291cc |
+ priv->surrounding_cursor_pos = 0;
|
|
|
f7291cc |
+ }
|
|
|
f7291cc |
+
|
|
|
eb1661e |
+ g_object_unref (priv->surrounding_text);
|
|
|
f7291cc |
+ priv->surrounding_text = g_object_ref_sink (text);
|
|
|
eb1661e |
+ }
|
|
|
eb1661e |
+
|
|
|
f0777a3 |
ibus_engine_emit_signal (engine,
|
|
|
f0777a3 |
"DeleteSurroundingText",
|
|
|
f0777a3 |
g_variant_new ("(iu)", offset_from_cursor, nchars));
|
|
|
eb1661e |
}
|
|
|
eb1661e |
|
|
|
eb1661e |
void
|
|
|
eb1661e |
+ibus_engine_get_surrounding_text (IBusEngine *engine,
|
|
|
eb1661e |
+ IBusText **text,
|
|
|
eb1661e |
+ guint *cursor_pos)
|
|
|
6cc8efa |
+{
|
|
|
6cc8efa |
+ IBusEnginePrivate *priv;
|
|
|
6cc8efa |
+
|
|
|
e36fdde |
+ g_return_if_fail (IBUS_IS_ENGINE (engine));
|
|
|
eb1661e |
+ g_return_if_fail (text != NULL);
|
|
|
eb1661e |
+ g_return_if_fail (cursor_pos != NULL);
|
|
|
eb1661e |
+
|
|
|
6cc8efa |
+ priv = IBUS_ENGINE_GET_PRIVATE (engine);
|
|
|
6cc8efa |
+
|
|
|
e36fdde |
+ *text = g_object_ref (priv->surrounding_text);
|
|
|
6cc8efa |
+ *cursor_pos = priv->surrounding_cursor_pos;
|
|
|
6cc8efa |
+}
|
|
|
6cc8efa |
+
|
|
|
eb1661e |
+void
|
|
|
6cc8efa |
ibus_engine_register_properties (IBusEngine *engine,
|
|
|
6cc8efa |
IBusPropList *prop_list)
|
|
|
eb1661e |
{
|
|
|
6cc8efa |
diff --git a/src/ibusengine.h b/src/ibusengine.h
|
|
|
f0777a3 |
index 46d0a04..a5f5aea 100644
|
|
|
6cc8efa |
--- a/src/ibusengine.h
|
|
|
6cc8efa |
+++ b/src/ibusengine.h
|
|
|
f0777a3 |
@@ -136,10 +136,14 @@ struct _IBusEngineClass {
|
|
|
6cc8efa |
guint index,
|
|
|
6cc8efa |
guint button,
|
|
|
6cc8efa |
guint state);
|
|
|
6cc8efa |
+ void (* set_surrounding_text)
|
|
|
6cc8efa |
+ (IBusEngine *engine,
|
|
|
6cc8efa |
+ IBusText *text,
|
|
|
6cc8efa |
+ guint cursor_index);
|
|
|
6cc8efa |
|
|
|
6cc8efa |
/*< private >*/
|
|
|
6cc8efa |
/* padding */
|
|
|
6cc8efa |
- gpointer pdummy[8];
|
|
|
6cc8efa |
+ gpointer pdummy[7];
|
|
|
6cc8efa |
};
|
|
|
6cc8efa |
|
|
|
6cc8efa |
GType ibus_engine_get_type (void);
|
|
|
f0777a3 |
@@ -394,6 +398,21 @@ void ibus_engine_delete_surrounding_text(IBusEngine *engine,
|
|
|
6cc8efa |
guint nchars);
|
|
|
6cc8efa |
|
|
|
6cc8efa |
/**
|
|
|
6cc8efa |
+ * ibus_engine_get_surrounding_text:
|
|
|
6cc8efa |
+ * @engine: An IBusEngine.
|
|
|
6cc8efa |
+ * @text: Location to store surrounding text.
|
|
|
6cc8efa |
+ * @cursor_pos: Cursor position in characters in @text.
|
|
|
6cc8efa |
+ *
|
|
|
6cc8efa |
+ * Get surrounding text.
|
|
|
6cc8efa |
+ *
|
|
|
6cc8efa |
+ * @see_also #IBusEngine::set-surrounding-text
|
|
|
6cc8efa |
+ */
|
|
|
6cc8efa |
+void ibus_engine_get_surrounding_text(IBusEngine *engine,
|
|
|
6cc8efa |
+ IBusText **text,
|
|
|
6cc8efa |
+ guint *cursor_pos);
|
|
|
6cc8efa |
+
|
|
|
e36fdde |
+
|
|
|
6cc8efa |
+/**
|
|
|
6cc8efa |
* ibus_engine_get_name:
|
|
|
6cc8efa |
* @engine: An IBusEngine.
|
|
|
6cc8efa |
* @returns: Name of IBusEngine.
|
|
|
fbc5579 |
diff --git a/src/ibusenginedesc.c b/src/ibusenginedesc.c
|
|
|
069aa90 |
index ca5ef60..956ce73 100644
|
|
|
fbc5579 |
--- a/src/ibusenginedesc.c
|
|
|
fbc5579 |
+++ b/src/ibusenginedesc.c
|
|
|
fbc5579 |
@@ -22,6 +22,7 @@
|
|
|
fbc5579 |
#include <stdlib.h>
|
|
|
fbc5579 |
#include "ibusenginedesc.h"
|
|
|
fbc5579 |
#include "ibusxml.h"
|
|
|
fbc5579 |
+#include "ibusenumtypes.h"
|
|
|
fbc5579 |
|
|
|
fbc5579 |
enum {
|
|
|
fbc5579 |
LAST_SIGNAL,
|
|
|
fbc5579 |
@@ -39,6 +40,7 @@ enum {
|
|
|
fbc5579 |
PROP_LAYOUT,
|
|
|
fbc5579 |
PROP_RANK,
|
|
|
fbc5579 |
PROP_HOTKEYS,
|
|
|
fbc5579 |
+ PROP_REQUIRES,
|
|
|
fbc5579 |
};
|
|
|
fbc5579 |
|
|
|
fbc5579 |
|
|
|
fbc5579 |
@@ -54,6 +56,7 @@ struct _IBusEngineDescPrivate {
|
|
|
fbc5579 |
gchar *layout;
|
|
|
fbc5579 |
guint rank;
|
|
|
fbc5579 |
gchar *hotkeys;
|
|
|
fbc5579 |
+ guint requires;
|
|
|
fbc5579 |
};
|
|
|
fbc5579 |
|
|
|
fbc5579 |
#define IBUS_ENGINE_DESC_GET_PRIVATE(o) \
|
|
|
069aa90 |
@@ -79,9 +82,20 @@ static gboolean ibus_engine_desc_copy (IBusEngineDesc *des
|
|
|
fbc5579 |
const IBusEngineDesc *src);
|
|
|
fbc5579 |
static gboolean ibus_engine_desc_parse_xml_node (IBusEngineDesc *desc,
|
|
|
fbc5579 |
XMLNode *node);
|
|
|
fbc5579 |
+static void ibus_engine_desc_output_capabilities
|
|
|
fbc5579 |
+ (guint caps,
|
|
|
fbc5579 |
+ GString *output,
|
|
|
fbc5579 |
+ gint indent);
|
|
|
fbc5579 |
+static guint ibus_engine_desc_parse_capabilities
|
|
|
fbc5579 |
+ (XMLNode *node);
|
|
|
fbc5579 |
|
|
|
fbc5579 |
G_DEFINE_TYPE (IBusEngineDesc, ibus_engine_desc, IBUS_TYPE_SERIALIZABLE)
|
|
|
fbc5579 |
|
|
|
fbc5579 |
+#define DEFAULT_REQUIRES (IBUS_CAP_PREEDIT_TEXT | \
|
|
|
fbc5579 |
+ IBUS_CAP_AUXILIARY_TEXT | \
|
|
|
fbc5579 |
+ IBUS_CAP_LOOKUP_TABLE | \
|
|
|
fbc5579 |
+ IBUS_CAP_FOCUS | \
|
|
|
fbc5579 |
+ IBUS_CAP_PROPERTY)
|
|
|
fbc5579 |
|
|
|
fbc5579 |
static void
|
|
|
fbc5579 |
ibus_engine_desc_class_init (IBusEngineDescClass *class)
|
|
|
069aa90 |
@@ -232,6 +246,21 @@ ibus_engine_desc_class_init (IBusEngineDescClass *class)
|
|
|
fbc5579 |
"The hotkeys of engine description",
|
|
|
fbc5579 |
"",
|
|
|
fbc5579 |
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
+ /**
|
|
|
fbc5579 |
+ * IBusEngineDesc:requires:
|
|
|
fbc5579 |
+ *
|
|
|
fbc5579 |
+ * The required capabilities of engine description
|
|
|
fbc5579 |
+ */
|
|
|
fbc5579 |
+ g_object_class_install_property (gobject_class,
|
|
|
fbc5579 |
+ PROP_REQUIRES,
|
|
|
fbc5579 |
+ g_param_spec_uint ("requires",
|
|
|
fbc5579 |
+ "description requires",
|
|
|
fbc5579 |
+ "The required capabilities of engine description",
|
|
|
fbc5579 |
+ 0,
|
|
|
fbc5579 |
+ G_MAXUINT,
|
|
|
fbc5579 |
+ DEFAULT_REQUIRES,
|
|
|
fbc5579 |
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
|
fbc5579 |
}
|
|
|
fbc5579 |
|
|
|
fbc5579 |
static void
|
|
|
069aa90 |
@@ -249,6 +278,7 @@ ibus_engine_desc_init (IBusEngineDesc *desc)
|
|
|
fbc5579 |
desc->priv->layout = NULL;
|
|
|
fbc5579 |
desc->priv->rank = 0;
|
|
|
fbc5579 |
desc->priv->hotkeys = NULL;
|
|
|
fbc5579 |
+ desc->priv->requires = DEFAULT_REQUIRES;
|
|
|
fbc5579 |
}
|
|
|
fbc5579 |
|
|
|
fbc5579 |
static void
|
|
|
069aa90 |
@@ -313,6 +343,9 @@ ibus_engine_desc_set_property (IBusEngineDesc *desc,
|
|
|
fbc5579 |
g_assert (desc->priv->hotkeys == NULL);
|
|
|
fbc5579 |
desc->priv->hotkeys = g_value_dup_string (value);
|
|
|
fbc5579 |
break;
|
|
|
fbc5579 |
+ case PROP_REQUIRES:
|
|
|
fbc5579 |
+ desc->priv->requires = g_value_get_uint (value);
|
|
|
fbc5579 |
+ break;
|
|
|
fbc5579 |
default:
|
|
|
fbc5579 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (desc, prop_id, pspec);
|
|
|
fbc5579 |
}
|
|
|
069aa90 |
@@ -355,6 +388,9 @@ ibus_engine_desc_get_property (IBusEngineDesc *desc,
|
|
|
fbc5579 |
case PROP_HOTKEYS:
|
|
|
fbc5579 |
g_value_set_string (value, ibus_engine_desc_get_hotkeys (desc));
|
|
|
fbc5579 |
break;
|
|
|
fbc5579 |
+ case PROP_REQUIRES:
|
|
|
fbc5579 |
+ g_value_set_uint (value, ibus_engine_desc_get_requires (desc));
|
|
|
fbc5579 |
+ break;
|
|
|
fbc5579 |
default:
|
|
|
fbc5579 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (desc, prop_id, pspec);
|
|
|
fbc5579 |
}
|
|
|
069aa90 |
@@ -382,9 +418,28 @@ ibus_engine_desc_serialize (IBusEngineDesc *desc,
|
|
|
fbc5579 |
g_variant_builder_add (builder, "u", desc->priv->rank);
|
|
|
fbc5579 |
g_variant_builder_add (builder, "s", NOTNULL (desc->priv->hotkeys));
|
|
|
fbc5579 |
#undef NOTNULL
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
+ /* append extra properties */
|
|
|
fbc5579 |
+ GVariantBuilder array;
|
|
|
fbc5579 |
+ g_variant_builder_init (&array, G_VARIANT_TYPE ("a{sv}"));
|
|
|
fbc5579 |
+ g_variant_builder_add (&array, "{sv}", "requires", g_variant_new_uint32 (desc->priv->requires));
|
|
|
fbc5579 |
+ g_variant_builder_add (builder, "v", g_variant_builder_end (&array));
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
return TRUE;
|
|
|
fbc5579 |
}
|
|
|
fbc5579 |
|
|
|
fbc5579 |
+static gboolean
|
|
|
fbc5579 |
+ibus_engine_desc_deserialize_property (IBusEngineDesc *desc,
|
|
|
fbc5579 |
+ const gchar *name,
|
|
|
fbc5579 |
+ GVariant *variant)
|
|
|
fbc5579 |
+{
|
|
|
fbc5579 |
+ if (g_strcmp0 (name, "requires") == 0) {
|
|
|
fbc5579 |
+ g_variant_get (variant, "u", &desc->priv->requires);
|
|
|
fbc5579 |
+ return TRUE;
|
|
|
fbc5579 |
+ }
|
|
|
fbc5579 |
+ return FALSE;
|
|
|
fbc5579 |
+}
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
static gint
|
|
|
fbc5579 |
ibus_engine_desc_deserialize (IBusEngineDesc *desc,
|
|
|
fbc5579 |
GVariant *variant)
|
|
|
069aa90 |
@@ -405,6 +460,23 @@ ibus_engine_desc_deserialize (IBusEngineDesc *desc,
|
|
|
fbc5579 |
g_variant_get_child (variant, retval++, "u", &desc->priv->rank);
|
|
|
fbc5579 |
g_variant_get_child (variant, retval++, "s", &desc->priv->hotkeys);
|
|
|
fbc5579 |
|
|
|
fbc5579 |
+ /* extract extra properties */
|
|
|
fbc5579 |
+ GVariantIter iter;
|
|
|
fbc5579 |
+ GVariant *child, *array;
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
+ g_variant_get_child (variant, retval++, "v", &array);
|
|
|
fbc5579 |
+ g_variant_iter_init (&iter, array);
|
|
|
fbc5579 |
+ while ((child = g_variant_iter_next_value (&iter))) {
|
|
|
fbc5579 |
+ gchar *name;
|
|
|
fbc5579 |
+ GVariant *value;
|
|
|
fbc5579 |
+ g_variant_get (child, "{sv}", &name, &value);
|
|
|
fbc5579 |
+ if (ibus_engine_desc_deserialize_property (desc, name, value))
|
|
|
fbc5579 |
+ retval++;
|
|
|
fbc5579 |
+ g_free (name);
|
|
|
fbc5579 |
+ g_variant_unref (value);
|
|
|
fbc5579 |
+ g_variant_unref (child);
|
|
|
fbc5579 |
+ }
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
return retval;
|
|
|
fbc5579 |
}
|
|
|
fbc5579 |
|
|
|
069aa90 |
@@ -428,6 +500,7 @@ ibus_engine_desc_copy (IBusEngineDesc *dest,
|
|
|
fbc5579 |
dest->priv->layout = g_strdup (src->priv->layout);
|
|
|
fbc5579 |
dest->priv->rank = src->priv->rank;
|
|
|
fbc5579 |
dest->priv->hotkeys = g_strdup (src->priv->hotkeys);
|
|
|
fbc5579 |
+ dest->priv->requires = src->priv->requires;
|
|
|
fbc5579 |
return TRUE;
|
|
|
fbc5579 |
}
|
|
|
fbc5579 |
|
|
|
069aa90 |
@@ -439,6 +512,52 @@ ibus_engine_desc_copy (IBusEngineDesc *dest,
|
|
|
fbc5579 |
} \
|
|
|
fbc5579 |
}
|
|
|
fbc5579 |
|
|
|
fbc5579 |
+static void
|
|
|
fbc5579 |
+ibus_engine_desc_output_capabilities (guint caps,
|
|
|
fbc5579 |
+ GString *output,
|
|
|
fbc5579 |
+ gint indent)
|
|
|
fbc5579 |
+{
|
|
|
fbc5579 |
+ GFlagsClass *flags_class;
|
|
|
fbc5579 |
+ gint i;
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
+ flags_class = g_type_class_ref (IBUS_TYPE_CAPABILITE);
|
|
|
fbc5579 |
+ g_return_if_fail (G_TYPE_IS_FLAGS (IBUS_TYPE_CAPABILITE));
|
|
|
fbc5579 |
+ for (i = 0; i < flags_class->n_values; i++) {
|
|
|
fbc5579 |
+ GFlagsValue *flags_value = &flags_class->values[i];
|
|
|
fbc5579 |
+ if (caps & flags_value->value) {
|
|
|
fbc5579 |
+ g_string_append_indent (output, indent + 1);
|
|
|
fbc5579 |
+ g_string_append_printf (output, "<capability>%s</capability>\n",
|
|
|
fbc5579 |
+ flags_value->value_nick);
|
|
|
fbc5579 |
+ }
|
|
|
fbc5579 |
+ }
|
|
|
fbc5579 |
+ g_type_class_unref (flags_class);
|
|
|
fbc5579 |
+}
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
+static guint
|
|
|
fbc5579 |
+ibus_engine_desc_parse_capabilities (XMLNode *node)
|
|
|
fbc5579 |
+{
|
|
|
fbc5579 |
+ GFlagsClass *flags_class;
|
|
|
fbc5579 |
+ guint caps = 0;
|
|
|
fbc5579 |
+ GList *p;
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
+ flags_class = g_type_class_ref (IBUS_TYPE_CAPABILITE);
|
|
|
fbc5579 |
+ for (p = node->sub_nodes; p != NULL; p = p->next) {
|
|
|
fbc5579 |
+ XMLNode *sub_node = (XMLNode *) p->data;
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
+ if (g_strcmp0 (sub_node->name, "capability") == 0) {
|
|
|
fbc5579 |
+ gint i;
|
|
|
fbc5579 |
+ for (i = 0; i < flags_class->n_values; i++) {
|
|
|
fbc5579 |
+ GFlagsValue *flags_value = &flags_class->values[i];
|
|
|
fbc5579 |
+ if (g_strcmp0 (flags_value->value_nick, sub_node->text) == 0)
|
|
|
fbc5579 |
+ caps |= flags_value->value;
|
|
|
fbc5579 |
+ }
|
|
|
fbc5579 |
+ }
|
|
|
fbc5579 |
+ }
|
|
|
fbc5579 |
+ g_type_class_unref (flags_class);
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
+ return caps;
|
|
|
fbc5579 |
+}
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
void
|
|
|
fbc5579 |
ibus_engine_desc_output (IBusEngineDesc *desc,
|
|
|
fbc5579 |
GString *output,
|
|
|
069aa90 |
@@ -467,6 +586,13 @@ ibus_engine_desc_output (IBusEngineDesc *desc,
|
|
|
fbc5579 |
OUTPUT_ENTRY_1(hotkeys);
|
|
|
fbc5579 |
g_string_append_indent (output, indent + 1);
|
|
|
fbc5579 |
g_string_append_printf (output, "<rank>%u</rank>\n", desc->priv->rank);
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
+ g_string_append_indent (output, indent + 1);
|
|
|
fbc5579 |
+ g_string_append (output, "<requires>\n");
|
|
|
fbc5579 |
+ ibus_engine_desc_output_capabilities (desc->priv->requires, output,
|
|
|
fbc5579 |
+ indent + 2);
|
|
|
fbc5579 |
+ g_string_append_indent (output, indent + 1);
|
|
|
fbc5579 |
+ g_string_append (output, "</requires>\n");
|
|
|
fbc5579 |
#undef OUTPUT_ENTRY
|
|
|
fbc5579 |
#undef OUTPUT_ENTRY_1
|
|
|
fbc5579 |
g_string_append_indent (output, indent);
|
|
|
069aa90 |
@@ -504,6 +630,11 @@ ibus_engine_desc_parse_xml_node (IBusEngineDesc *desc,
|
|
|
fbc5579 |
desc->priv->rank = atoi (sub_node->text);
|
|
|
fbc5579 |
continue;
|
|
|
fbc5579 |
}
|
|
|
fbc5579 |
+ if (g_strcmp0 (sub_node->name , "requires") == 0) {
|
|
|
fbc5579 |
+ desc->priv->requires =
|
|
|
fbc5579 |
+ ibus_engine_desc_parse_capabilities (sub_node);
|
|
|
fbc5579 |
+ continue;
|
|
|
fbc5579 |
+ }
|
|
|
fbc5579 |
g_warning ("<engines> element contains invalidate element <%s>", sub_node->name);
|
|
|
fbc5579 |
}
|
|
|
fbc5579 |
return TRUE;
|
|
|
069aa90 |
@@ -526,6 +657,7 @@ IBUS_ENGINE_DESC_GET_PROPERTY (icon, const gchar *)
|
|
|
fbc5579 |
IBUS_ENGINE_DESC_GET_PROPERTY (layout, const gchar *)
|
|
|
fbc5579 |
IBUS_ENGINE_DESC_GET_PROPERTY (rank, guint)
|
|
|
fbc5579 |
IBUS_ENGINE_DESC_GET_PROPERTY (hotkeys, const gchar *)
|
|
|
fbc5579 |
+IBUS_ENGINE_DESC_GET_PROPERTY (requires, guint)
|
|
|
fbc5579 |
#undef IBUS_ENGINE_DESC_GET_PROPERTY
|
|
|
fbc5579 |
|
|
|
fbc5579 |
IBusEngineDesc *
|
|
|
fbc5579 |
diff --git a/src/ibusenginedesc.h b/src/ibusenginedesc.h
|
|
|
069aa90 |
index 9718b15..209d460 100644
|
|
|
fbc5579 |
--- a/src/ibusenginedesc.h
|
|
|
fbc5579 |
+++ b/src/ibusenginedesc.h
|
|
|
069aa90 |
@@ -90,6 +90,8 @@ typedef struct _IBusEngineDescClass IBusEngineDescClass;
|
|
|
fbc5579 |
* the front.
|
|
|
fbc5579 |
* hotkeys: One or more hotkeys for switching to this engine, separated by
|
|
|
fbc5579 |
* semi-colon.
|
|
|
fbc5579 |
+ * requires: Capabilities this engine will utilize. The value is the
|
|
|
fbc5579 |
+ * union of the IBusCapability flags.
|
|
|
fbc5579 |
*/
|
|
|
fbc5579 |
struct _IBusEngineDesc {
|
|
|
fbc5579 |
IBusSerializable parent;
|
|
|
069aa90 |
@@ -249,6 +251,15 @@ guint ibus_engine_desc_get_rank (IBusEngineDesc *info);
|
|
|
fbc5579 |
const gchar *ibus_engine_desc_get_hotkeys (IBusEngineDesc *info);
|
|
|
fbc5579 |
|
|
|
fbc5579 |
/**
|
|
|
fbc5579 |
+ * ibus_engine_desc_get_requires:
|
|
|
fbc5579 |
+ * @info: An IBusEngineDesc
|
|
|
fbc5579 |
+ * @returns: request capabilites property in IBusEngineDesc
|
|
|
fbc5579 |
+ *
|
|
|
fbc5579 |
+ * Return the capabilites property in IBusEngineDesc.
|
|
|
fbc5579 |
+ */
|
|
|
fbc5579 |
+guint ibus_engine_desc_get_requires (IBusEngineDesc *info);
|
|
|
fbc5579 |
+
|
|
|
fbc5579 |
+/**
|
|
|
fbc5579 |
* ibus_engine_desc_output:
|
|
|
fbc5579 |
* @info: An IBusEngineDesc
|
|
|
fbc5579 |
* @output: XML-formatted Input method engine description.
|
|
|
069aa90 |
diff --git a/src/ibusinputcontext.c b/src/ibusinputcontext.c
|
|
|
0610dd6 |
index f8f5848..9556df3 100644
|
|
|
069aa90 |
--- a/src/ibusinputcontext.c
|
|
|
069aa90 |
+++ b/src/ibusinputcontext.c
|
|
|
069aa90 |
@@ -28,6 +28,9 @@
|
|
|
069aa90 |
#include "ibuslookuptable.h"
|
|
|
069aa90 |
#include "ibusproplist.h"
|
|
|
069aa90 |
|
|
|
069aa90 |
+#define IBUS_INPUT_CONTEXT_GET_PRIVATE(o) \
|
|
|
069aa90 |
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_INPUT_CONTEXT, IBusInputContextPrivate))
|
|
|
069aa90 |
+
|
|
|
069aa90 |
enum {
|
|
|
069aa90 |
ENABLED,
|
|
|
069aa90 |
DISABLED,
|
|
|
069aa90 |
@@ -49,12 +52,25 @@ enum {
|
|
|
069aa90 |
CURSOR_DOWN_LOOKUP_TABLE,
|
|
|
069aa90 |
REGISTER_PROPERTIES,
|
|
|
069aa90 |
UPDATE_PROPERTY,
|
|
|
069aa90 |
+ ENGINE_CHANGED,
|
|
|
069aa90 |
LAST_SIGNAL,
|
|
|
069aa90 |
};
|
|
|
069aa90 |
|
|
|
069aa90 |
+/* BusInputContextPrivate */
|
|
|
069aa90 |
+struct _IBusInputContextPrivate {
|
|
|
069aa90 |
+ /* surrounding text */
|
|
|
069aa90 |
+ IBusText *surrounding_text;
|
|
|
069aa90 |
+ guint surrounding_cursor_pos;
|
|
|
069aa90 |
+};
|
|
|
069aa90 |
+
|
|
|
069aa90 |
+typedef struct _IBusInputContextPrivate IBusInputContextPrivate;
|
|
|
069aa90 |
+
|
|
|
069aa90 |
static guint context_signals[LAST_SIGNAL] = { 0 };
|
|
|
069aa90 |
|
|
|
069aa90 |
+static IBusText *text_empty = NULL;
|
|
|
069aa90 |
+
|
|
|
069aa90 |
/* functions prototype */
|
|
|
069aa90 |
+static void ibus_input_context_real_destroy (IBusProxy *context);
|
|
|
069aa90 |
static void ibus_input_context_g_signal (GDBusProxy *proxy,
|
|
|
069aa90 |
const gchar *sender_name,
|
|
|
069aa90 |
const gchar *signal_name,
|
|
|
069aa90 |
@@ -65,8 +81,13 @@ G_DEFINE_TYPE (IBusInputContext, ibus_input_context, IBUS_TYPE_PROXY)
|
|
|
069aa90 |
static void
|
|
|
069aa90 |
ibus_input_context_class_init (IBusInputContextClass *class)
|
|
|
069aa90 |
{
|
|
|
069aa90 |
+ IBusProxyClass *ibus_proxy_class = IBUS_PROXY_CLASS (class);
|
|
|
069aa90 |
GDBusProxyClass *g_dbus_proxy_class = G_DBUS_PROXY_CLASS (class);
|
|
|
069aa90 |
|
|
|
069aa90 |
+ g_type_class_add_private (class, sizeof (IBusInputContextPrivate));
|
|
|
069aa90 |
+
|
|
|
069aa90 |
+ ibus_proxy_class->destroy = ibus_input_context_real_destroy;
|
|
|
069aa90 |
+
|
|
|
069aa90 |
g_dbus_proxy_class->g_signal = ibus_input_context_g_signal;
|
|
|
069aa90 |
|
|
|
069aa90 |
/* install signals */
|
|
|
069aa90 |
@@ -101,6 +122,21 @@ ibus_input_context_class_init (IBusInputContextClass *class)
|
|
|
069aa90 |
G_TYPE_NONE, 0);
|
|
|
069aa90 |
|
|
|
069aa90 |
/**
|
|
|
069aa90 |
+ * IBusInputContext::engine-changed:
|
|
|
069aa90 |
+ * @context: An IBusInputContext.
|
|
|
069aa90 |
+ *
|
|
|
069aa90 |
+ * Emitted when an IME is changed.
|
|
|
069aa90 |
+ */
|
|
|
069aa90 |
+ context_signals[ENGINE_CHANGED] =
|
|
|
069aa90 |
+ g_signal_new (I_("engine-changed"),
|
|
|
069aa90 |
+ G_TYPE_FROM_CLASS (class),
|
|
|
069aa90 |
+ G_SIGNAL_RUN_LAST,
|
|
|
069aa90 |
+ 0,
|
|
|
069aa90 |
+ NULL, NULL,
|
|
|
069aa90 |
+ _ibus_marshal_VOID__VOID,
|
|
|
069aa90 |
+ G_TYPE_NONE, 0);
|
|
|
069aa90 |
+
|
|
|
069aa90 |
+ /**
|
|
|
069aa90 |
* IBusInputContext::commit-text:
|
|
|
069aa90 |
* @context: An IBusInputContext.
|
|
|
069aa90 |
* @text: Text to be committed.
|
|
|
069aa90 |
@@ -429,11 +465,33 @@ ibus_input_context_class_init (IBusInputContextClass *class)
|
|
|
069aa90 |
G_TYPE_NONE,
|
|
|
069aa90 |
1,
|
|
|
069aa90 |
IBUS_TYPE_PROPERTY);
|
|
|
069aa90 |
+
|
|
|
069aa90 |
+ text_empty = ibus_text_new_from_static_string ("");
|
|
|
069aa90 |
+ g_object_ref_sink (text_empty);
|
|
|
069aa90 |
}
|
|
|
069aa90 |
|
|
|
069aa90 |
static void
|
|
|
069aa90 |
ibus_input_context_init (IBusInputContext *context)
|
|
|
069aa90 |
{
|
|
|
069aa90 |
+ IBusInputContextPrivate *priv;
|
|
|
069aa90 |
+
|
|
|
069aa90 |
+ priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context);
|
|
|
069aa90 |
+ priv->surrounding_text = g_object_ref_sink (text_empty);
|
|
|
069aa90 |
+ priv->surrounding_cursor_pos = 0;
|
|
|
069aa90 |
+}
|
|
|
069aa90 |
+
|
|
|
069aa90 |
+static void
|
|
|
069aa90 |
+ibus_input_context_real_destroy (IBusProxy *context)
|
|
|
069aa90 |
+{
|
|
|
069aa90 |
+ IBusInputContextPrivate *priv;
|
|
|
069aa90 |
+ priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (IBUS_INPUT_CONTEXT (context));
|
|
|
069aa90 |
+
|
|
|
069aa90 |
+ if (priv->surrounding_text) {
|
|
|
069aa90 |
+ g_object_unref (priv->surrounding_text);
|
|
|
069aa90 |
+ priv->surrounding_text = NULL;
|
|
|
069aa90 |
+ }
|
|
|
069aa90 |
+
|
|
|
069aa90 |
+ IBUS_PROXY_CLASS(ibus_input_context_parent_class)->destroy (context);
|
|
|
069aa90 |
}
|
|
|
069aa90 |
|
|
|
069aa90 |
static void
|
|
|
069aa90 |
@@ -463,6 +521,7 @@ ibus_input_context_g_signal (GDBusProxy *proxy,
|
|
|
069aa90 |
{ "PageDownLookupTable", PAGE_DOWN_LOOKUP_TABLE },
|
|
|
069aa90 |
{ "CursorUpLookupTable", CURSOR_UP_LOOKUP_TABLE },
|
|
|
069aa90 |
{ "CursorDownLookupTable", CURSOR_DOWN_LOOKUP_TABLE },
|
|
|
069aa90 |
+ { "EngineChanged", ENGINE_CHANGED },
|
|
|
069aa90 |
};
|
|
|
069aa90 |
|
|
|
069aa90 |
if (g_strcmp0 (signal_name, "CommitText") == 0) {
|
|
|
0610dd6 |
@@ -848,6 +907,38 @@ ibus_input_context_property_hide (IBusInputContext *context,
|
|
|
069aa90 |
);
|
|
|
069aa90 |
}
|
|
|
069aa90 |
|
|
|
069aa90 |
+void
|
|
|
069aa90 |
+ibus_input_context_set_surrounding_text (IBusInputContext *context,
|
|
|
069aa90 |
+ IBusText *text,
|
|
|
069aa90 |
+ guint32 cursor_pos)
|
|
|
069aa90 |
+{
|
|
|
069aa90 |
+ g_assert (IBUS_IS_INPUT_CONTEXT (context));
|
|
|
069aa90 |
+ g_assert (IBUS_IS_TEXT (text));
|
|
|
069aa90 |
+
|
|
|
069aa90 |
+ IBusInputContextPrivate *priv;
|
|
|
069aa90 |
+ priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context);
|
|
|
069aa90 |
+
|
|
|
069aa90 |
+ if (priv->surrounding_text == NULL ||
|
|
|
069aa90 |
+ g_strcmp0 (text->text, priv->surrounding_text->text) != 0 ||
|
|
|
069aa90 |
+ cursor_pos != priv->surrounding_cursor_pos) {
|
|
|
069aa90 |
+ GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)text);
|
|
|
069aa90 |
+ if (priv->surrounding_text)
|
|
|
069aa90 |
+ g_object_unref (priv->surrounding_text);
|
|
|
069aa90 |
+ priv->surrounding_text = (IBusText *) g_object_ref_sink (text);
|
|
|
069aa90 |
+ priv->surrounding_cursor_pos = cursor_pos;
|
|
|
069aa90 |
+
|
|
|
069aa90 |
+ g_dbus_proxy_call ((GDBusProxy *) context,
|
|
|
069aa90 |
+ "SetSurroundingText", /* method_name */
|
|
|
069aa90 |
+ g_variant_new ("(vu)", variant, cursor_pos), /* parameters */
|
|
|
069aa90 |
+ G_DBUS_CALL_FLAGS_NONE, /* flags */
|
|
|
069aa90 |
+ -1, /* timeout */
|
|
|
069aa90 |
+ NULL, /* cancellable */
|
|
|
069aa90 |
+ NULL, /* callback */
|
|
|
069aa90 |
+ NULL /* user_data */
|
|
|
069aa90 |
+ );
|
|
|
069aa90 |
+ }
|
|
|
069aa90 |
+}
|
|
|
069aa90 |
+
|
|
|
069aa90 |
gboolean
|
|
|
069aa90 |
ibus_input_context_is_enabled (IBusInputContext *context)
|
|
|
069aa90 |
{
|
|
|
069aa90 |
diff --git a/src/ibusinputcontext.h b/src/ibusinputcontext.h
|
|
|
0610dd6 |
index 96fd00e..1f8ae86 100644
|
|
|
069aa90 |
--- a/src/ibusinputcontext.h
|
|
|
069aa90 |
+++ b/src/ibusinputcontext.h
|
|
|
069aa90 |
@@ -41,6 +41,7 @@
|
|
|
069aa90 |
|
|
|
069aa90 |
#include "ibusproxy.h"
|
|
|
069aa90 |
#include "ibusenginedesc.h"
|
|
|
069aa90 |
+#include "ibustext.h"
|
|
|
069aa90 |
|
|
|
069aa90 |
/*
|
|
|
069aa90 |
* Type macros.
|
|
|
0610dd6 |
@@ -324,6 +325,16 @@ IBusEngineDesc
|
|
|
069aa90 |
void ibus_input_context_set_engine (IBusInputContext *context,
|
|
|
069aa90 |
const gchar *name);
|
|
|
069aa90 |
|
|
|
069aa90 |
+/**
|
|
|
069aa90 |
+ * ibus_input_context_set_surrounding_text:
|
|
|
069aa90 |
+ * @context: An IBusInputContext.
|
|
|
069aa90 |
+ * @text: An IBusText surrounding the current cursor on the application.
|
|
|
069aa90 |
+ * @cursor_po: Current cursor position in characters in @text.
|
|
|
069aa90 |
+*/
|
|
|
069aa90 |
+void ibus_input_context_set_surrounding_text
|
|
|
069aa90 |
+ (IBusInputContext *context,
|
|
|
069aa90 |
+ IBusText *text,
|
|
|
069aa90 |
+ guint32 cursor_pos);
|
|
|
069aa90 |
|
|
|
069aa90 |
G_END_DECLS
|
|
|
069aa90 |
#endif
|
|
|
069aa90 |
diff --git a/src/ibusmarshalers.list b/src/ibusmarshalers.list
|
|
|
069aa90 |
index 5184278..5dc7fc2 100644
|
|
|
069aa90 |
--- a/src/ibusmarshalers.list
|
|
|
069aa90 |
+++ b/src/ibusmarshalers.list
|
|
|
069aa90 |
@@ -13,6 +13,7 @@ VOID:INT,INT,INT,INT
|
|
|
069aa90 |
VOID:UINT,UINT
|
|
|
069aa90 |
VOID:INT,UINT
|
|
|
069aa90 |
VOID:UINT,UINT,UINT
|
|
|
069aa90 |
+VOID:OBJECT,UINT
|
|
|
069aa90 |
VOID:OBJECT,UINT,BOOL
|
|
|
069aa90 |
VOID:OBJECT,UINT,BOOL,UINT
|
|
|
069aa90 |
VOID:OBJECT,BOOL
|
|
|
6cc8efa |
--
|
|
|
cf977d1 |
1.7.3.2
|
|
|
6cc8efa |
|