/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
- * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2010 Red Hat, Inc.
+ * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
g_assert (IBUS_IS_ENGINE_DESC (desc));
g_assert (G_IS_DBUS_CONNECTION (connection));
- GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
+ GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
BusEngineProxy *engine =
(BusEngineProxy *) g_initable_new (BUS_TYPE_ENGINE_PROXY,
NULL,
}
}
+void
+bus_engine_proxy_set_content_type (BusEngineProxy *engine,
+ guint purpose,
+ guint hints)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+
+ GVariant *cached_content_type =
+ g_dbus_proxy_get_cached_property ((GDBusProxy *) engine,
+ "ContentType");
+ GVariant *content_type = g_variant_new ("(uu)", purpose, hints);
+
+ g_variant_ref_sink (content_type);
+ if (cached_content_type == NULL ||
+ !g_variant_equal (content_type, cached_content_type)) {
+ g_dbus_proxy_call ((GDBusProxy *) engine,
+ "org.freedesktop.DBus.Properties.Set",
+ g_variant_new ("(ssv)",
+ IBUS_INTERFACE_ENGINE,
+ "ContentType",
+ content_type),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+ }
+
+ if (cached_content_type != NULL)
+ g_variant_unref (cached_content_type);
+ g_variant_unref (content_type);
+}
+
/* a macro to generate a function to call a nullary D-Bus method. */
#define DEFINE_FUNCTION(Name, name) \
void \
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
- * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2010 Red Hat, Inc.
+ * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
typedef struct _BusEngineProxy BusEngineProxy;
typedef struct _BusEngineProxyClass BusEngineProxyClass;
-GType bus_engine_proxy_get_type (void);
+GType bus_engine_proxy_get_type (void);
/**
* bus_engine_proxy_new:
* @callback: a function to be called when the method invocation is done.
* @user_data: a pointer that will be passed to the callback.
*/
-void bus_engine_proxy_new (IBusEngineDesc *desc,
- gint timeout,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
+void bus_engine_proxy_new (IBusEngineDesc *desc,
+ gint timeout,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
/**
* bus_engine_proxy_new_finish:
- * @returns: On success, return an engine object. On error, return NULL.
+ * @res: A #GAsyncResult.
+ * @error: Return location for error or %NULL.
+ * @returns: On success, return an engine object. On error, return %NULL.
*
- * Get the result of bus_engine_proxy_new call. You have to call this function in the GAsyncReadyCallback function.
+ * Get the result of bus_engine_proxy_new() call. You have to call this
+ * function in the #GAsyncReadyCallback function.
*/
-BusEngineProxy *bus_engine_proxy_new_finish (GAsyncResult *res,
- GError **error);
+BusEngineProxy *bus_engine_proxy_new_finish (GAsyncResult *res,
+ GError **error);
/**
* bus_engine_proxy_get_desc:
+ * @engine: A #BusEngineProxy.
*
- * Get an IBusEngineDesc object associated with the engine.
+ * Get an #IBusEngineDesc object associated with the engine.
*/
-IBusEngineDesc *bus_engine_proxy_get_desc (BusEngineProxy *engine);
+IBusEngineDesc *bus_engine_proxy_get_desc (BusEngineProxy *engine);
/**
* bus_engine_proxy_process_key_event:
- * @callback: a function to be called when the method invocation is done.
+ * @engine: A #BusEngineProxy.
+ * @keyval: Key symbol of the key press.
+ * @keycode: KeyCode of the key press.
+ * @state: Key modifier flags.
+ * @callback: A function to be called when the method invocation is done.
+ * @user_data: Data supplied to @callback.
*
* Call "ProcessKeyEvent" method of an engine asynchronously.
*/
-void bus_engine_proxy_process_key_event (BusEngineProxy *engine,
- guint keyval,
- guint keycode,
- guint state,
- GAsyncReadyCallback callback,
- gpointer user_data);
+void bus_engine_proxy_process_key_event
+ (BusEngineProxy *engine,
+ guint keyval,
+ guint keycode,
+ guint state,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
/**
* bus_engine_proxy_set_cursor_location:
+ * @engine: A #BusEngineProxy.
+ * @x: X coordinate of the cursor.
+ * @y: Y coordinate of the cursor.
+ * @w: Width of the cursor.
+ * @h: Height of the cursor.
*
- * Call "SetCursorLocation" method of an engine asynchronously. Unlike bus_engine_proxy_process_key_event, there's no way to know the
- * result of the method invocation. If the same coordinate is given twice or more, the function does nothing from the second time.
+ * Call "SetCursorLocation" method of an engine asynchronously. Unlike
+ * bus_engine_proxy_process_key_event(), there's no way to know the
+ * result of the method invocation. If the same coordinate is given
+ * twice or more, the function does nothing from the second time.
*/
-void bus_engine_proxy_set_cursor_location
- (BusEngineProxy *engine,
- gint x,
- gint y,
- gint w,
- gint h);
+void bus_engine_proxy_set_cursor_location
+ (BusEngineProxy *engine,
+ gint x,
+ gint y,
+ gint w,
+ gint h);
/**
* bus_engine_proxy_focus_in:
+ * @engine: A #BusEngineProxy.
*
- * Call "FocusIn" method of an engine asynchronously. Do nothing if the engine already has a focus.
+ * Call "FocusIn" method of an engine asynchronously. Do nothing if
+ * the engine already has a focus.
*/
-void bus_engine_proxy_focus_in (BusEngineProxy *engine);
+void bus_engine_proxy_focus_in (BusEngineProxy *engine);
/**
* bus_engine_proxy_focus_out:
+ * @engine: A #BusEngineProxy.
*
- * Call "FocusOut" method of an engine asynchronously. Do nothing if the engine does not have a focus.
+ * Call "FocusOut" method of an engine asynchronously. Do nothing if
+ * the engine does not have a focus.
*/
-void bus_engine_proxy_focus_out (BusEngineProxy *engine);
+void bus_engine_proxy_focus_out (BusEngineProxy *engine);
/**
* bus_engine_proxy_reset:
+ * @engine: A #BusEngineProxy.
*
* Call "Reset" method of an engine asynchronously.
*/
-void bus_engine_proxy_reset (BusEngineProxy *engine);
+void bus_engine_proxy_reset (BusEngineProxy *engine);
/**
* bus_engine_proxy_set_capabilities:
+ * @engine: A #BusEngineProxy.
+ * @caps: Capabilities flags of IBusEngine, see #IBusCapabilite.
*
* Call "SetCapabilities" method of an engine asynchronously.
*/
-void bus_engine_proxy_set_capabilities (BusEngineProxy *engine,
- guint caps);
+void bus_engine_proxy_set_capabilities
+ (BusEngineProxy *engine,
+ guint caps);
/**
* bus_engine_proxy_page_up:
+ * @engine: A #BusEngineProxy.
*
* Call "PageUp" method of an engine asynchronously.
*/
-void bus_engine_proxy_page_up (BusEngineProxy *engine);
+void bus_engine_proxy_page_up (BusEngineProxy *engine);
/**
* bus_engine_proxy_page_down:
+ * @engine: A #BusEngineProxy.
*
* Call "PageDown" method of an engine asynchronously.
*/
-void bus_engine_proxy_page_down (BusEngineProxy *engine);
+void bus_engine_proxy_page_down (BusEngineProxy *engine);
/**
* bus_engine_proxy_cursor_up:
+ * @engine: A #BusEngineProxy.
*
* Call "CursorUp" method of an engine asynchronously.
*/
-void bus_engine_proxy_cursor_up (BusEngineProxy *engine);
+void bus_engine_proxy_cursor_up (BusEngineProxy *engine);
/**
* bus_engine_proxy_cursor_down:
+ * @engine: A #BusEngineProxy.
*
* Call "CursorDown" method of an engine asynchronously.
*/
-void bus_engine_proxy_cursor_down (BusEngineProxy *engine);
+void bus_engine_proxy_cursor_down (BusEngineProxy *engine);
/**
* bus_engine_proxy_candidate_clicked:
+ * @engine: A #BusEngineProxy.
+ * @index: Index of candidate be clicked.
+ * @button: Mouse button.
+ * @state: Keyboard state.
*
* Call "CandidateClicked" method of an engine asynchronously.
*/
-void bus_engine_proxy_candidate_clicked (BusEngineProxy *engine,
- guint index,
- guint button,
- guint state);
+void bus_engine_proxy_candidate_clicked
+ (BusEngineProxy *engine,
+ guint index,
+ guint button,
+ guint state);
/**
* bus_engine_proxy_enable:
+ * @engine: A #BusEngineProxy.
*
- * Call "Enable" method of an engine asynchronously. Do nothing if the engine is already enabled.
+ * Call "Enable" method of an engine asynchronously. Do nothing if the
+ * engine is already enabled.
*/
-void bus_engine_proxy_enable (BusEngineProxy *engine);
+void bus_engine_proxy_enable (BusEngineProxy *engine);
/**
* bus_engine_proxy_disable:
+ * @engine: A #BusEngineProxy.
*
- * Call "Disable" method of an engine asynchronously. Do nothing if the engine is already disabled.
+ * Call "Disable" method of an engine asynchronously. Do nothing if
+ * the engine is already disabled.
*/
-void bus_engine_proxy_disable (BusEngineProxy *engine);
+void bus_engine_proxy_disable (BusEngineProxy *engine);
/**
* bus_engine_proxy_property_activate:
+ * @engine: A #BusEngineProxy.
+ * @name: Property name.
+ * @state: Property state.
*
* Call "PropertyActivate" method of an engine asynchronously.
*/
-void bus_engine_proxy_property_activate (BusEngineProxy *engine,
- const gchar *prop_name,
- guint state);
+void bus_engine_proxy_property_activate
+ (BusEngineProxy *engine,
+ const gchar *prop_name,
+ guint state);
/**
* bus_engine_proxy_property_show:
+ * @engine: A #BusEngineProxy.
+ * @prop_name: Property name.
*
* Call "PropertyShow" method of an engine asynchronously.
*/
-void bus_engine_proxy_property_show (BusEngineProxy *engine,
- const gchar *prop_name);
+void bus_engine_proxy_property_show
+ (BusEngineProxy *engine,
+ const gchar *prop_name);
/**
* bus_engine_proxy_property_hide:
+ * @engine: A #BusEngineProxy.
+ * @prop_name: Property name.
*
* Call "PropertyHide" method of an engine asynchronously.
*/
-void bus_engine_proxy_property_hide (BusEngineProxy *engine,
- const gchar *prop_name);
+void bus_engine_proxy_property_hide
+ (BusEngineProxy *engine,
+ const gchar *prop_name);
/**
* bus_engine_proxy_is_enabled:
- * @returns: TRUE if the engine is enabled.
+ * @engine: A #BusEngineProxy.
+ * @returns: %TRUE if the engine is enabled.
*/
-gboolean bus_engine_proxy_is_enabled (BusEngineProxy *engine);
+gboolean bus_engine_proxy_is_enabled (BusEngineProxy *engine);
/**
* bus_engine_proxy_set_surrounding_text:
+ * @engine: A #BusEngineProxy.
+ * @text: The surrounding text.
+ * @cursor_pos: The cursor position on surrounding text.
+ * @anchor_pos: The anchor position on selection area.
*
* Call "SetSurroundingText" method of an engine asynchronously.
*/
-void bus_engine_proxy_set_surrounding_text
- (BusEngineProxy *engine,
- IBusText *text,
- guint cursor_pos,
- guint anchor_pos);
+void bus_engine_proxy_set_surrounding_text
+ (BusEngineProxy *engine,
+ IBusText *text,
+ guint cursor_pos,
+ guint anchor_pos);
/**
* bus_engine_proxy_process_hand_writing_event:
+ * @engine: A #BusEngineProxy.
+ * @coordinates: A #GVariant containing an array of coordinates.
*
- * Call "ProcessHandWritingEvent" method of an engine asynchronously. The type of the GVariant should be "(ad)".
- * See ibus_input_context_process_hand_writing_event for details.
+ * Call "ProcessHandWritingEvent" method of an engine
+ * asynchronously. The type of the GVariant should be "(ad)". See
+ * ibus_input_context_process_hand_writing_event() for details.
*/
-void bus_engine_proxy_process_hand_writing_event
- (BusEngineProxy *engine,
- GVariant *coordinates);
+void bus_engine_proxy_process_hand_writing_event
+ (BusEngineProxy *engine,
+ GVariant *coordinates);
/**
* bus_engine_proxy_cancel_hand_writing:
+ * @engine: A #BusEngineProxy.
+ * @n_strokes: The number of strokes to be removed. 0 means "remove all".
*
* Call "CancelHandWriting" method of an engine asynchronously.
- * See ibus_input_context_cancel_hand_writing for details.
+ * See ibus_input_context_cancel_hand_writing() for details.
+ */
+void bus_engine_proxy_cancel_hand_writing
+ (BusEngineProxy *engine,
+ guint n_strokes);
+
+/**
+ * bus_engine_proxy_set_content_type:
+ * @engine: A #BusEngineProxy.
+ * @purpose: Primary purpose of the input context, as an #IBusInputPurpose.
+ * @hints: Hints that augment @purpose, as an #IBusInputHints.
+ *
+ * Call "SetContentType" method of an engine asynchronously.
+ * See ibus_input_context_set_content_type() for details.
*/
-void bus_engine_proxy_cancel_hand_writing
- (BusEngineProxy *engine,
- guint n_strokes);
+void bus_engine_proxy_set_content_type
+ (BusEngineProxy *engine,
+ guint purpose,
+ guint hints);
/**
* bus_engine_proxy_get_properties:
+ * @engine: A #BusEngineProxy.
+ * @returns: An #IBusPropList.
*
- * Get an IBusPropList object associated with the engine.
+ * Get an #IBusPropList object associated with the engine.
*/
-IBusPropList *bus_engine_proxy_get_properties (BusEngineProxy *engine);
+IBusPropList *bus_engine_proxy_get_properties
+ (BusEngineProxy *engine);
G_END_DECLS
#endif
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
- * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2010 Red Hat, Inc.
+ * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
/* incompleted set engine by desc request */
SetEngineByDescData *data;
+
+ /* content-type (primary purpose and hints) */
+ guint purpose;
+ guint hints;
};
struct _BusInputContextClass {
static guint context_signals[LAST_SIGNAL] = { 0 };
/* functions prototype */
-static void bus_input_context_destroy (BusInputContext *context);
+static void bus_input_context_destroy
+ (BusInputContext *context);
static void bus_input_context_service_method_call
- (IBusService *service,
- GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *method_name,
- GVariant *parameters,
- GDBusMethodInvocation *invocation);
-static void bus_input_context_unset_engine (BusInputContext *context);
-static void bus_input_context_commit_text (BusInputContext *context,
- IBusText *text);
+ (IBusService *service,
+ GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation);
+static gboolean bus_input_context_service_set_property
+ (IBusService *service,
+ GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *property_name,
+ GVariant *value,
+ GError **error);
+static void bus_input_context_unset_engine
+ (BusInputContext *context);
+static void bus_input_context_commit_text
+ (BusInputContext *context,
+ IBusText *text);
static void bus_input_context_update_preedit_text
- (BusInputContext *context,
- IBusText *text,
- guint cursor_pos,
- gboolean visible,
- guint mode);
+ (BusInputContext *context,
+ IBusText *text,
+ guint cursor_pos,
+ gboolean visible,
+ guint mode);
static void bus_input_context_show_preedit_text
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_hide_preedit_text
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_update_auxiliary_text
- (BusInputContext *context,
- IBusText *text,
- gboolean visible);
+ (BusInputContext *context,
+ IBusText *text,
+ gboolean visible);
static void bus_input_context_show_auxiliary_text
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_hide_auxiliary_text
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_update_lookup_table
- (BusInputContext *context,
- IBusLookupTable *table,
- gboolean visible);
+ (BusInputContext *context,
+ IBusLookupTable *table,
+ gboolean visible);
static void bus_input_context_show_lookup_table
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_hide_lookup_table
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_page_up_lookup_table
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_page_down_lookup_table
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_cursor_up_lookup_table
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_cursor_down_lookup_table
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_register_properties
- (BusInputContext *context,
- IBusPropList *props);
+ (BusInputContext *context,
+ IBusPropList *props);
static void bus_input_context_update_property
- (BusInputContext *context,
- IBusProperty *prop);
-static void _engine_destroy_cb (BusEngineProxy *factory,
- BusInputContext *context);
+ (BusInputContext *context,
+ IBusProperty *prop);
+static void _engine_destroy_cb (BusEngineProxy *factory,
+ BusInputContext *context);
static IBusText *text_empty = NULL;
static IBusLookupTable *lookup_table_empty = NULL;
static IBusPropList *props_empty = NULL;
-/* The interfaces available in this class, which consists of a list of methods this class implements and
- * a list of signals this class may emit. Method calls to the interface that are not defined in this XML
- * will be automatically rejected by the GDBus library (see src/ibusservice.c for details.) */
+/* The interfaces available in this class, which consists of a list of
+ * methods this class implements and a list of signals this class may
+ * emit. Method calls to the interface that are not defined in this
+ * XML will be automatically rejected by the GDBus library (see
+ * src/ibusservice.c for details.) */
static const gchar introspection_xml[] =
"<node>"
" <interface name='org.freedesktop.IBus.InputContext'>"
" <signal name='UpdateProperty'>"
" <arg type='v' name='prop' />"
" </signal>"
+
+ /* properties */
+ " <property name='ContentType' type='(uu)' access='write' />"
" </interface>"
"</node>";
ibus_object_class->destroy = (IBusObjectDestroyFunc) bus_input_context_destroy;
/* override the parent class's implementation. */
- IBUS_SERVICE_CLASS (class)->service_method_call = bus_input_context_service_method_call;
+ IBUS_SERVICE_CLASS (class)->service_method_call =
+ bus_input_context_service_method_call;
+ IBUS_SERVICE_CLASS (class)->service_set_property =
+ bus_input_context_service_set_property;
/* register the xml so that bus_ibus_impl_service_method_call will be called on a method call defined in the xml (e.g. 'FocusIn'.) */
ibus_service_class_add_interfaces (IBUS_SERVICE_CLASS (class), introspection_xml);
IBUS_OBJECT_CLASS (bus_input_context_parent_class)->destroy (IBUS_OBJECT (context));
}
-/**
- * bus_input_context_emit_signal:
- * @signal_name: The D-Bus signal name to emit which is in the introspection_xml.
- *
- * Emit the D-Bus signal.
- */
static gboolean
-bus_input_context_emit_signal (BusInputContext *context,
+bus_input_context_send_signal (BusInputContext *context,
+ const gchar *interface_name,
const gchar *signal_name,
GVariant *parameters,
GError **error)
return TRUE;
GDBusMessage *message = g_dbus_message_new_signal (ibus_service_get_object_path ((IBusService *)context),
- "org.freedesktop.IBus.InputContext",
+ interface_name,
signal_name);
g_dbus_message_set_sender (message, "org.freedesktop.IBus");
g_dbus_message_set_destination (message, bus_connection_get_unique_name (context->connection));
}
/**
+ * bus_input_context_emit_signal:
+ * @signal_name: The D-Bus signal name to emit which is in the introspection_xml.
+ *
+ * Emit the D-Bus signal.
+ */
+static gboolean
+bus_input_context_emit_signal (BusInputContext *context,
+ const gchar *signal_name,
+ GVariant *parameters,
+ GError **error)
+{
+ if (context->connection == NULL)
+ return TRUE;
+
+ return bus_input_context_send_signal (context,
+ "org.freedesktop.IBus.InputContext",
+ signal_name,
+ parameters,
+ error);
+}
+
+/**
+ * bus_input_context_property_changed:
+ * @context: a #BusInputContext
+ * @property_name: The D-Bus property name which has changed
+ * @value: The new value of the property
+ *
+ * Emit the D-Bus "PropertiesChanged" signal for a property.
+ * Returns: %TRUE on success, %FALSE on failure
+ */
+static gboolean
+bus_input_context_property_changed (BusInputContext *context,
+ const gchar *property_name,
+ GVariant *value,
+ GError **error)
+{
+ if (context->connection == NULL)
+ return TRUE;
+
+ GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add (builder, "{sv}", property_name, value);
+ return bus_input_context_send_signal (context,
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ g_variant_new ("(sa{sv}as)",
+ "org.freedesktop.IBus",
+ builder,
+ NULL),
+ error);
+}
+
+/**
* _ic_process_key_event_reply_cb:
*
* A GAsyncReadyCallback function to be called when bus_engine_proxy_process_key_event() is finished.
g_variant_new ("(v)", ibus_serializable_serialize ((IBusSerializable *)desc)));
}
-/**
- * bus_input_context_service_method_call:
- *
- * Handle a D-Bus method call whose destination and interface name are both "org.freedesktop.IBus.InputContext"
- */
static void
_ic_set_surrounding_text (BusInputContext *context,
GVariant *parameters,
g_dbus_method_invocation_return_value (invocation, NULL);
}
+/**
+ * bus_input_context_service_method_call:
+ *
+ * Handle a D-Bus method call whose destination and interface name are both "org.freedesktop.IBus.InputContext"
+ */
static void
bus_input_context_service_method_call (IBusService *service,
GDBusConnection *connection,
{ "PropertyActivate", _ic_property_activate },
{ "SetEngine", _ic_set_engine },
{ "GetEngine", _ic_get_engine },
- { "SetSurroundingText", _ic_set_surrounding_text},
+ { "SetSurroundingText", _ic_set_surrounding_text }
};
gint i;
g_return_if_reached ();
}
+static gboolean
+bus_input_context_service_set_property (IBusService *service,
+ GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *property_name,
+ GVariant *value,
+ GError **error)
+{
+ if (g_strcmp0 (interface_name, IBUS_INTERFACE_INPUT_CONTEXT) != 0) {
+ return IBUS_SERVICE_CLASS (bus_input_context_parent_class)->
+ service_set_property (service,
+ connection,
+ sender,
+ object_path,
+ interface_name,
+ property_name,
+ value,
+ error);
+ }
+
+ if (g_strcmp0 (property_name, "ContentType") == 0) {
+ BusInputContext *context = (BusInputContext *) service;
+ guint purpose = 0;
+ guint hints = 0;
+
+ g_variant_get (value, "(uu)", &purpose, &hints);
+ if (purpose != context->purpose || hints != context->hints) {
+ GError *error;
+ gboolean retval;
+
+ context->purpose = purpose;
+ context->hints = hints;
+
+ if (context->has_focus && context->engine)
+ bus_engine_proxy_set_content_type (context->engine,
+ purpose,
+ hints);
+
+ error = NULL;
+ retval = bus_input_context_property_changed (context,
+ "ContentType",
+ value,
+ &error);
+ if (!retval) {
+ g_warning ("Failed to emit PropertiesChanged signal: %s",
+ error->message);
+ g_error_free (error);
+ }
+ }
+ return TRUE;
+ }
+
+ g_return_val_if_reached (FALSE);
+}
+
gboolean
bus_input_context_has_focus (BusInputContext *context)
{
bus_engine_proxy_enable (context->engine);
bus_engine_proxy_set_capabilities (context->engine, context->capabilities);
bus_engine_proxy_set_cursor_location (context->engine, context->x, context->y, context->w, context->h);
+ bus_engine_proxy_set_content_type (context->engine, context->purpose, context->hints);
}
if (context->capabilities & IBUS_CAP_FOCUS) {
bus_engine_proxy_enable (context->engine);
bus_engine_proxy_set_capabilities (context->engine, context->capabilities);
bus_engine_proxy_set_cursor_location (context->engine, context->x, context->y, context->w, context->h);
+ bus_engine_proxy_set_content_type (context->engine, context->purpose, context->hints);
}
void
bus_engine_proxy_enable (context->engine);
bus_engine_proxy_set_capabilities (context->engine, context->capabilities);
bus_engine_proxy_set_cursor_location (context->engine, context->x, context->y, context->w, context->h);
+ bus_engine_proxy_set_content_type (context->engine, context->purpose, context->hints);
}
}
g_signal_emit (context,
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
- * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2010 Red Hat, Inc.
+ * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
static void ibus_im_context_class_init (IBusIMContextClass *class);
static void ibus_im_context_class_fini (IBusIMContextClass *class);
static void ibus_im_context_init (GObject *obj);
+static void ibus_im_context_notify (GObject *obj,
+ GParamSpec *pspec);
static void ibus_im_context_finalize (GObject *obj);
static void ibus_im_context_reset (GtkIMContext *context);
static gboolean ibus_im_context_filter_keypress
IBusIMContext *context);
static void _request_surrounding_text (IBusIMContext *context);
static void _create_fake_input_context (void);
+static void _set_content_type (IBusIMContext *context);
}
}
+static void
+_set_content_type (IBusIMContext *context)
+{
+#if GTK_CHECK_VERSION (3, 6, 0)
+ if (context->ibuscontext != NULL) {
+ GtkInputPurpose purpose;
+ GtkInputHints hints;
+
+ g_object_get (G_OBJECT (context),
+ "input-purpose", &purpose,
+ "input-hints", &hints,
+ NULL);
+
+ ibus_input_context_set_content_type (context->ibuscontext,
+ purpose,
+ hints);
+ }
+#endif
+}
+
static gint
_key_snooper_cb (GtkWidget *widget,
im_context_class->set_cursor_location = ibus_im_context_set_cursor_location;
im_context_class->set_use_preedit = ibus_im_context_set_use_preedit;
im_context_class->set_surrounding = ibus_im_context_set_surrounding;
+ gobject_class->notify = ibus_im_context_notify;
gobject_class->finalize = ibus_im_context_finalize;
_signal_commit_id =
}
static void
+ibus_im_context_notify (GObject *obj,
+ GParamSpec *pspec)
+{
+ IDEBUG ("%s", __FUNCTION__);
+
+ if (g_strcmp0 (pspec->name, "input-purpose") == 0 ||
+ g_strcmp0 (pspec->name, "input-hints") == 0) {
+ _set_content_type (IBUS_IM_CONTEXT (obj));
+ }
+}
+
+static void
ibus_im_context_finalize (GObject *obj)
{
IDEBUG ("%s", __FUNCTION__);
return;
/* don't set focus on password entry */
-#if GTK_CHECK_VERSION (3, 6, 0)
- {
- GtkInputPurpose purpose;
-
- g_object_get (G_OBJECT (context),
- "input-purpose", &purpose,
- NULL);
-
- if (purpose == GTK_INPUT_PURPOSE_PASSWORD)
- return;
- }
-#endif
if (ibusimcontext->client_window != NULL) {
GtkWidget *widget;
gtk_im_context_focus_in (ibusimcontext->slave);
+ _set_content_type (ibusimcontext);
+
/* set_cursor_location_internal() will get origin from X server,
* it blocks UI. So delay it to idle callback. */
gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE,
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
- * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2010 Red Hat, Inc.
+ * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
SET_SURROUNDING_TEXT,
PROCESS_HAND_WRITING_EVENT,
CANCEL_HAND_WRITING,
+ SET_CONTENT_TYPE,
LAST_SIGNAL,
};
IBusText *surrounding_text;
guint surrounding_cursor_pos;
guint selection_anchor_pos;
+
+ /* cached content-type */
+ guint content_purpose;
+ guint content_hints;
};
static guint engine_signals[LAST_SIGNAL] = { 0 };
static void ibus_engine_cancel_hand_writing
(IBusEngine *engine,
guint n_strokes);
+static void ibus_engine_set_content_type
+ (IBusEngine *engine,
+ guint purpose,
+ guint hints);
static void ibus_engine_emit_signal (IBusEngine *engine,
const gchar *signal_name,
GVariant *parameters);
+static void ibus_engine_dbus_property_changed
+ (IBusEngine *engine,
+ const gchar *property_name,
+ GVariant *value);
G_DEFINE_TYPE (IBusEngine, ibus_engine, IBUS_TYPE_SERVICE)
" <arg type='u' name='keycode' />"
" <arg type='u' name='state' />"
" </signal>"
+ /* FIXME properties */
+ " <property name='ContentType' type='(uu)' access='write' />"
" </interface>"
"</node>";
class->process_hand_writing_event
= ibus_engine_process_hand_writing_event;
class->cancel_hand_writing = ibus_engine_cancel_hand_writing;
+ class->set_content_type = ibus_engine_set_content_type;
/* install properties */
/**
1,
G_TYPE_UINT);
- g_type_class_add_private (class, sizeof (IBusEnginePrivate));
-
/**
* IBusEngine::set-surrounding-text:
* @engine: An IBusEngine.
G_TYPE_UINT,
G_TYPE_UINT);
+ /**
+ * IBusEngine::set-content-type:
+ * @engine: An #IBusEngine.
+ * @purpose: Primary purpose of the input context, as an #IBusInputPurpose.
+ * @hints: Hints that augment @purpose, as an #IBusInputHints.
+ *
+ * Emitted when the client application content-type (primary
+ * purpose and hints) is set. The engine could change the
+ * behavior according to the content-type. Implement the member
+ * function set_content_type() in extended class to receive this
+ * signal.
+ *
+ * For example, if the client application wants to restrict input
+ * to numbers, this signal will be emitted with @purpose set to
+ * #IBUS_INPUT_PURPOSE_NUMBER, so the engine can switch the input
+ * mode to latin.
+ *
+ * <note><para>Argument @user_data is ignored in this
+ * function.</para></note>
+ */
+ engine_signals[SET_CONTENT_TYPE] =
+ g_signal_new (I_("set-content-type"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IBusEngineClass, set_content_type),
+ NULL, NULL,
+ _ibus_marshal_VOID__UINT_UINT,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_UINT,
+ G_TYPE_UINT);
+
+ g_type_class_add_private (class, sizeof (IBusEnginePrivate));
+
text_empty = ibus_text_new_from_static_string ("");
g_object_ref_sink (text_empty);
}
GVariant *value,
GError **error)
{
- return IBUS_SERVICE_CLASS (ibus_engine_parent_class)->
- service_set_property (service,
- connection,
- sender,
- object_path,
- interface_name,
- property_name,
- value,
- error);
+ IBusEngine *engine = IBUS_ENGINE (service);
+
+ if (g_strcmp0 (interface_name, IBUS_INTERFACE_ENGINE) != 0) {
+ return IBUS_SERVICE_CLASS (ibus_engine_parent_class)->
+ service_set_property (service,
+ connection,
+ sender,
+ object_path,
+ interface_name,
+ property_name,
+ value,
+ error);
+ }
+
+ if (g_strcmp0 (property_name, "ContentType") == 0) {
+ guint purpose = 0;
+ guint hints = 0;
+
+ g_variant_get (value, "(uu)", &purpose, &hints);
+ if (purpose != engine->priv->content_purpose ||
+ hints != engine->priv->content_hints) {
+ engine->priv->content_purpose = purpose;
+ engine->priv->content_hints = hints;
+
+ g_signal_emit (engine,
+ engine_signals[SET_CONTENT_TYPE],
+ 0,
+ purpose,
+ hints);
+
+ ibus_engine_dbus_property_changed (engine, "ContentType", value);
+ }
+
+ return TRUE;
+ }
+
+ g_return_val_if_reached (FALSE);
}
static gboolean
}
static void
+ibus_engine_set_content_type (IBusEngine *engine,
+ guint purpose,
+ guint hints)
+{
+ // g_debug ("set-content-type (%u %u)", purpose, hints);
+}
+
+static void
ibus_engine_emit_signal (IBusEngine *engine,
const gchar *signal_name,
GVariant *parameters)
NULL);
}
+static void
+ibus_engine_dbus_property_changed (IBusEngine *engine,
+ const gchar *property_name,
+ GVariant *value)
+{
+ const gchar *object_path;
+ GDBusConnection *connection;
+ GDBusMessage *message;
+ GVariantBuilder *builder;
+ gboolean retval;
+ GError *error;
+
+ /* we cannot use ibus_service_emit_signal() here, since we need to
+ set sender of the signal so that GDBusProxy can properly track
+ the property change. */
+ object_path = ibus_service_get_object_path ((IBusService *)engine);
+ message = g_dbus_message_new_signal (object_path,
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged");
+
+ g_dbus_message_set_sender (message, "org.freedesktop.IBus");
+
+ builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add (builder, "{sv}", property_name, value);
+ g_dbus_message_set_body (message,
+ g_variant_new ("(sa{sv}as)",
+ IBUS_INTERFACE_ENGINE,
+ builder,
+ NULL));
+
+ error = NULL;
+ connection = ibus_service_get_connection ((IBusService *)engine);
+ retval = g_dbus_connection_send_message (connection,
+ message,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+ NULL,
+ &error);
+ if (!retval) {
+ g_warning ("Failed to emit PropertiesChanged signal: %s",
+ error->message);
+ g_error_free (error);
+ }
+ g_object_unref (message);
+ return retval;
+}
+
IBusEngine *
ibus_engine_new (const gchar *engine_name,
const gchar *object_path,
}
void
+ibus_engine_get_content_type (IBusEngine *engine,
+ guint *purpose,
+ guint *hints)
+{
+ g_return_if_fail (IBUS_IS_ENGINE (engine));
+
+ *purpose = engine->priv->content_purpose;
+ *hints = engine->priv->content_hints;
+}
+
+void
ibus_engine_register_properties (IBusEngine *engine,
IBusPropList *prop_list)
{
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
- * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2010 Red Hat, Inc.
+ * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* @has_focus: Whether the engine has focus.
* @cursor_area: Area of cursor.
* @client_capabilities: IBusCapabilite (client capabilities) flags.
+ * @client_purpose: IBusInputPurpose (client input purpose).
+ * @client_hints: IBusInputHints (client input hints) flags.
*
* IBusEngine properties.
*/
void (* cancel_hand_writing)
(IBusEngine *engine,
guint n_strokes);
+ void (* set_content_type)
+ (IBusEngine *engine,
+ guint purpose,
+ guint hints);
/*< private >*/
/* padding */
- gpointer pdummy[5];
+ gpointer pdummy[4];
};
GType ibus_engine_get_type (void);
* #IBusEngine::enable handler, with both @text and @cursor set to
* %NULL.
*
- * see_also #IBusEngine::set-surrounding-text
+ * See also: #IBusEngine::set-surrounding-text
*/
-void ibus_engine_get_surrounding_text(IBusEngine *engine,
- IBusText **text,
- guint *cursor_pos,
- guint *anchor_pos);
+void ibus_engine_get_surrounding_text (IBusEngine *engine,
+ IBusText **text,
+ guint *cursor_pos,
+ guint *anchor_pos);
+
+/**
+ * ibus_engine_get_content_type:
+ * @engine: An #IBusEngine.
+ * @purpose: (out) (allow-none): Primary purpose of the input context.
+ * @hints: (out) (allow-none): Hints that augument @purpose.
+ *
+ * Get content-type (primary purpose and hints) of the current input
+ * context.
+ *
+ * See also: #IBusEngine::set-content-type
+ */
+void ibus_engine_get_content_type (IBusEngine *engine,
+ guint *purpose,
+ guint *hints);
/**
* ibus_engine_get_name:
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
- * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2010 Red Hat, Inc.
+ * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
GInitable *initable;
- GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
+ GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
initable = g_initable_new (IBUS_TYPE_INPUT_CONTEXT,
cancellable,
g_assert (G_IS_DBUS_CONNECTION (connection));
g_assert (callback != NULL);
- GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
+ GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
g_async_initable_new_async (IBUS_TYPE_INPUT_CONTEXT,
G_PRIORITY_DEFAULT,
}
void
+ibus_input_context_set_content_type (IBusInputContext *context,
+ guint purpose,
+ guint hints)
+{
+ g_assert (IBUS_IS_INPUT_CONTEXT (context));
+
+ GVariant *cached_content_type =
+ g_dbus_proxy_get_cached_property ((GDBusProxy *) context,
+ "ContentType");
+ GVariant *content_type = g_variant_new ("(uu)", purpose, hints);
+
+ g_variant_ref_sink (content_type);
+ if (cached_content_type == NULL ||
+ !g_variant_equal (content_type, cached_content_type)) {
+ g_dbus_proxy_call ((GDBusProxy *) context,
+ "org.freedesktop.DBus.Properties.Set",
+ g_variant_new ("(ssv)",
+ IBUS_INTERFACE_INPUT_CONTEXT,
+ "ContentType",
+ content_type),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL, /* cancellable */
+ NULL, /* callback */
+ NULL /* user_data */
+ );
+ }
+
+ if (cached_content_type != NULL)
+ g_variant_unref (cached_content_type);
+ g_variant_unref (content_type);
+}
+
+void
ibus_input_context_get_engine_async (IBusInputContext *context,
gint timeout_msec,
GCancellable *cancellable,
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
- * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2010 Red Hat, Inc.
+ * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
gboolean ibus_input_context_needs_surrounding_text
(IBusInputContext *context);
+/**
+ * ibus_input_context_set_content_type:
+ * @context: An #IBusInputContext.
+ * @purpose: Primary purpose of the input context, as an #IBusInputPurpose.
+ * @hints: Hints that augment @purpose, as an #IBusInputHints.
+ *
+ * Set content-type (primary purpose and hints) of the context. This
+ * information is particularly useful to implement intelligent
+ * behavior in engines, such as automatic input-mode switch and text
+ * prediction. For example, to restrict input to numbers, the client
+ * can call this function with @purpose set to
+ * #IBUS_INPUT_PURPOSE_NUMBER.
+ *
+ * See also: #IBusEngine::set-content-type
+ */
+void ibus_input_context_set_content_type
+ (IBusInputContext *context,
+ guint purpose,
+ guint hints);
+
G_END_DECLS
#endif
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
- * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2010 Red Hat, Inc.
+ * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
*/
typedef void (* IBusFreeFunc) (gpointer object);
+/**
+ * IBusInputPurpose:
+ * @IBUS_INPUT_PURPOSE_FREE_FORM: Allow any character
+ * @IBUS_INPUT_PURPOSE_ALPHA: Allow only alphabetic characters
+ * @IBUS_INPUT_PURPOSE_DIGITS: Allow only digits
+ * @IBUS_INPUT_PURPOSE_NUMBER: Edited field expects numbers
+ * @IBUS_INPUT_PURPOSE_PHONE: Edited field expects phone number
+ * @IBUS_INPUT_PURPOSE_URL: Edited field expects URL
+ * @IBUS_INPUT_PURPOSE_EMAIL: Edited field expects email address
+ * @IBUS_INPUT_PURPOSE_NAME: Edited field expects the name of a person
+ * @IBUS_INPUT_PURPOSE_PASSWORD: Like @IBUS_INPUT_PURPOSE_FREE_FORM,
+ * but characters are hidden
+ * @IBUS_INPUT_PURPOSE_PIN: Like @IBUS_INPUT_PURPOSE_DIGITS, but
+ * characters are hidden
+ *
+ * Describes primary purpose of the input context. This information
+ * is particularly useful to implement intelligent behavior in
+ * engines, such as automatic input-mode switch and text prediction.
+ *
+ * This enumeration may be extended in the future; engines should
+ * interpret unknown values as 'free form'.
+ */
+typedef enum
+{
+ IBUS_INPUT_PURPOSE_FREE_FORM,
+ IBUS_INPUT_PURPOSE_ALPHA,
+ IBUS_INPUT_PURPOSE_DIGITS,
+ IBUS_INPUT_PURPOSE_NUMBER,
+ IBUS_INPUT_PURPOSE_PHONE,
+ IBUS_INPUT_PURPOSE_URL,
+ IBUS_INPUT_PURPOSE_EMAIL,
+ IBUS_INPUT_PURPOSE_NAME,
+ IBUS_INPUT_PURPOSE_PASSWORD,
+ IBUS_INPUT_PURPOSE_PIN
+} IBusInputPurpose;
+
+/**
+ * IBusInputHints:
+ * @IBUS_INPUT_HINT_NONE: No special behaviour suggested
+ * @IBUS_INPUT_HINT_SPELLCHECK: Suggest checking for typos
+ * @IBUS_INPUT_HINT_NO_SPELLCHECK: Suggest not checking for typos
+ * @IBUS_INPUT_HINT_WORD_COMPLETION: Suggest word completion
+ * @IBUS_INPUT_HINT_LOWERCASE: Suggest to convert all text to lowercase
+ * @IBUS_INPUT_HINT_UPPERCASE_CHARS: Suggest to capitalize all text
+ * @IBUS_INPUT_HINT_UPPERCASE_WORDS: Suggest to capitalize the first
+ * character of each word
+ * @IBUS_INPUT_HINT_UPPERCASE_SENTENCES: Suggest to capitalize the
+ * first word of each sentence
+ * @IBUS_INPUT_HINT_INHIBIT_OSK: Suggest to not show an onscreen keyboard
+ * (e.g for a calculator that already has all the keys).
+ *
+ * Describes hints that might be taken into account by engines. Note
+ * that engines may already tailor their behaviour according to the
+ * #IBusInputPurpose of the entry.
+ */
+typedef enum
+{
+ IBUS_INPUT_HINT_NONE = 0,
+ IBUS_INPUT_HINT_SPELLCHECK = 1 << 0,
+ IBUS_INPUT_HINT_NO_SPELLCHECK = 1 << 1,
+ IBUS_INPUT_HINT_WORD_COMPLETION = 1 << 2,
+ IBUS_INPUT_HINT_LOWERCASE = 1 << 3,
+ IBUS_INPUT_HINT_UPPERCASE_CHARS = 1 << 4,
+ IBUS_INPUT_HINT_UPPERCASE_WORDS = 1 << 5,
+ IBUS_INPUT_HINT_UPPERCASE_SENTENCES = 1 << 6,
+ IBUS_INPUT_HINT_INHIBIT_OSK = 1 << 7
+} IBusInputHints;
+
#endif