Make server responsible for loading keyboard files.
This commit is contained in:
@ -1,2 +1,2 @@
|
||||
keyboarddir = $(pkgdatadir)/keyboards
|
||||
dist_keyboard_DATA = us-qwerty.xml
|
||||
dist_keyboard_DATA = us.xml
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -84,11 +84,6 @@ eek_xkl_layout_dispose (GObject *object)
|
||||
priv->config = NULL;
|
||||
}
|
||||
|
||||
if (priv->engine) {
|
||||
g_object_unref (priv->engine);
|
||||
priv->engine = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (eek_xkl_layout_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
|
||||
@ -22,11 +22,23 @@ libeekboard_headers = \
|
||||
eekboard.h \
|
||||
eekboard-eekboard.h \
|
||||
eekboard-context.h
|
||||
libeekboard_private_headers = \
|
||||
eekboard-marshalers.h
|
||||
libeekboard_sources = \
|
||||
eekboard-eekboard.c \
|
||||
eekboard-context.c
|
||||
|
||||
libeekboard_la_SOURCES = $(libeekboard_sources)
|
||||
libeekboard_marshalers_sources = \
|
||||
eekboard-marshalers.c \
|
||||
eekboard-marshalers.h
|
||||
|
||||
BUILT_SOURCES = \
|
||||
$(libeekboard_marshalers_sources)
|
||||
|
||||
libeekboard_la_SOURCES = \
|
||||
$(libeekboard_sources) \
|
||||
eekboard-marshalers.c
|
||||
|
||||
libeekboard_la_CFLAGS = -DEEKBOARD_COMPILATION=1 -I$(top_srcdir) $(GIO2_CFLAGS)
|
||||
libeekboard_la_LIBADD = $(top_builddir)/eek/libeek.la $(GIO2_LIBS)
|
||||
|
||||
@ -37,10 +49,23 @@ pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = \
|
||||
eekboard-$(EEK_API_VERSION).pc
|
||||
DISTCLEANFILES = \
|
||||
$(BUILT_SOURCES) \
|
||||
$(pkgconfig_DATA)
|
||||
|
||||
CLEANFILES =
|
||||
|
||||
EXTRA_DIST = eekboard-marshalers.list
|
||||
|
||||
# gen marshal
|
||||
eekboard-marshalers.h: eekboard-marshalers.list
|
||||
$(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix=_eekboard_marshal $(srcdir)/eekboard-marshalers.list --header --internal > $@.tmp && \
|
||||
mv $@.tmp $@
|
||||
|
||||
eekboard-marshalers.c: eekboard-marshalers.list eekboard-marshalers.h
|
||||
$(AM_V_GEN) (echo "#include \"eekboard-marshalers.h\""; \
|
||||
$(GLIB_GENMARSHAL) --prefix=_eekboard_marshal $(srcdir)/eekboard-marshalers.list --body --internal) > $@.tmp && \
|
||||
mv $@.tmp $@
|
||||
|
||||
-include $(INTROSPECTION_MAKEFILE)
|
||||
INTROSPECTION_GIRS =
|
||||
INTROSPECTION_SCANNER_ARGS = --add-include-path=$(builddir) --add-include-path=$(top_builddir)/eek
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include "eekboard/eekboard-context.h"
|
||||
#include "eekboard/eekboard-marshalers.h"
|
||||
|
||||
#define I_(string) g_intern_static_string (string)
|
||||
|
||||
@ -36,7 +37,6 @@ enum {
|
||||
ENABLED,
|
||||
DISABLED,
|
||||
KEY_PRESSED,
|
||||
KEY_RELEASED,
|
||||
DESTROYED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
@ -56,11 +56,10 @@ G_DEFINE_TYPE (EekboardContext, eekboard_context, G_TYPE_DBUS_PROXY);
|
||||
|
||||
struct _EekboardContextPrivate
|
||||
{
|
||||
EekKeyboard *keyboard;
|
||||
GHashTable *keyboard_hash;
|
||||
gboolean keyboard_visible;
|
||||
gboolean enabled;
|
||||
gboolean fullscreen;
|
||||
gint group;
|
||||
};
|
||||
|
||||
static void
|
||||
@ -83,21 +82,24 @@ eekboard_context_real_g_signal (GDBusProxy *self,
|
||||
}
|
||||
|
||||
if (g_strcmp0 (signal_name, "KeyPressed") == 0) {
|
||||
guint keycode;
|
||||
g_variant_get (parameters, "(u)", &keycode);
|
||||
g_signal_emit_by_name (context, "key-pressed", keycode);
|
||||
return;
|
||||
}
|
||||
guint keycode = 0;
|
||||
GVariant *variant = NULL;
|
||||
guint modifiers = 0;
|
||||
EekSerializable *serializable;
|
||||
|
||||
if (g_strcmp0 (signal_name, "KeyReleased") == 0) {
|
||||
guint keycode;
|
||||
g_variant_get (parameters, "(u)", &keycode);
|
||||
g_signal_emit_by_name (context, "key-released", keycode);
|
||||
g_variant_get (parameters, "(uvu)", &keycode, &variant, &modifiers);
|
||||
g_return_if_fail (variant != NULL);
|
||||
|
||||
serializable = eek_serializable_deserialize (variant);
|
||||
g_return_if_fail (EEK_IS_SYMBOL(serializable));
|
||||
|
||||
g_signal_emit_by_name (context, "key-pressed",
|
||||
keycode, EEK_SYMBOL(serializable), modifiers);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (signal_name, "KeyboardVisibilityChanged") == 0) {
|
||||
gboolean keyboard_visible;
|
||||
gboolean keyboard_visible = FALSE;
|
||||
|
||||
g_variant_get (parameters, "(b)", &keyboard_visible);
|
||||
if (keyboard_visible != priv->keyboard_visible) {
|
||||
@ -107,6 +109,17 @@ eekboard_context_real_g_signal (GDBusProxy *self,
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (signal_name, "GroupChanged") == 0) {
|
||||
gint group = 0;
|
||||
|
||||
g_variant_get (parameters, "(i)", &group);
|
||||
if (group != priv->group) {
|
||||
priv->group = group;
|
||||
//g_object_notify (G_OBJECT(context), "group");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
@ -126,32 +139,15 @@ eekboard_context_real_disabled (EekboardContext *self)
|
||||
|
||||
static void
|
||||
eekboard_context_real_key_pressed (EekboardContext *self,
|
||||
guint keycode)
|
||||
guint keycode,
|
||||
EekSymbol *symbol,
|
||||
guint modifiers)
|
||||
{
|
||||
EekboardContextPrivate *priv = EEKBOARD_CONTEXT_GET_PRIVATE(self);
|
||||
if (priv->keyboard) {
|
||||
EekKey *key = eek_keyboard_find_key_by_keycode (priv->keyboard,
|
||||
keycode);
|
||||
g_signal_emit_by_name (key, "pressed");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_context_real_key_released (EekboardContext *self,
|
||||
guint keycode)
|
||||
{
|
||||
EekboardContextPrivate *priv = EEKBOARD_CONTEXT_GET_PRIVATE(self);
|
||||
if (priv->keyboard) {
|
||||
EekKey *key = eek_keyboard_find_key_by_keycode (priv->keyboard,
|
||||
keycode);
|
||||
g_signal_emit_by_name (key, "released");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_context_real_destroyed (EekboardContext *self)
|
||||
{
|
||||
// g_debug ("eekboard_context_real_destroyed");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -173,22 +169,6 @@ eekboard_context_get_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_context_dispose (GObject *self)
|
||||
{
|
||||
EekboardContextPrivate *priv = EEKBOARD_CONTEXT_GET_PRIVATE (self);
|
||||
|
||||
if (priv->keyboard) {
|
||||
g_object_unref (priv->keyboard);
|
||||
priv->keyboard = NULL;
|
||||
}
|
||||
|
||||
if (priv->keyboard_hash) {
|
||||
g_hash_table_destroy (priv->keyboard_hash);
|
||||
priv->keyboard_hash = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eekboard_context_class_init (EekboardContextClass *klass)
|
||||
{
|
||||
@ -202,13 +182,11 @@ eekboard_context_class_init (EekboardContextClass *klass)
|
||||
klass->enabled = eekboard_context_real_enabled;
|
||||
klass->disabled = eekboard_context_real_disabled;
|
||||
klass->key_pressed = eekboard_context_real_key_pressed;
|
||||
klass->key_released = eekboard_context_real_key_released;
|
||||
klass->destroyed = eekboard_context_real_destroyed;
|
||||
|
||||
proxy_class->g_signal = eekboard_context_real_g_signal;
|
||||
|
||||
gobject_class->get_property = eekboard_context_get_property;
|
||||
gobject_class->dispose = eekboard_context_dispose;
|
||||
|
||||
/**
|
||||
* EekboardContext:keyboard-visible:
|
||||
@ -262,6 +240,8 @@ eekboard_context_class_init (EekboardContextClass *klass)
|
||||
* EekboardContext::key-pressed:
|
||||
* @context: an #EekboardContext
|
||||
* @keycode: keycode
|
||||
* @symbol: an #EekSymbol
|
||||
* @modifiers: modifiers
|
||||
*
|
||||
* The ::key-pressed signal is emitted each time a key is pressed
|
||||
* in @context.
|
||||
@ -273,29 +253,11 @@ eekboard_context_class_init (EekboardContextClass *klass)
|
||||
G_STRUCT_OFFSET(EekboardContextClass, key_pressed),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__UINT,
|
||||
_eekboard_marshal_VOID__UINT_OBJECT_UINT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_UINT);
|
||||
|
||||
/**
|
||||
* EekboardContext::key-released:
|
||||
* @context: an #EekboardContext
|
||||
* @keycode: keycode
|
||||
*
|
||||
* The ::key-released signal is emitted each time a key is released
|
||||
* in @context.
|
||||
*/
|
||||
signals[KEY_RELEASED] =
|
||||
g_signal_new (I_("key-released"),
|
||||
G_TYPE_FROM_CLASS(gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(EekboardContextClass, key_released),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__UINT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
3,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_OBJECT,
|
||||
G_TYPE_UINT);
|
||||
|
||||
/**
|
||||
@ -320,17 +282,7 @@ eekboard_context_class_init (EekboardContextClass *klass)
|
||||
static void
|
||||
eekboard_context_init (EekboardContext *self)
|
||||
{
|
||||
EekboardContextPrivate *priv;
|
||||
|
||||
priv = self->priv = EEKBOARD_CONTEXT_GET_PRIVATE(self);
|
||||
priv->keyboard = NULL;
|
||||
priv->keyboard_visible = FALSE;
|
||||
priv->enabled = FALSE;
|
||||
priv->keyboard_hash =
|
||||
g_hash_table_new_full (g_direct_hash,
|
||||
g_direct_equal,
|
||||
NULL,
|
||||
(GDestroyNotify)g_object_unref);
|
||||
self->priv = EEKBOARD_CONTEXT_GET_PRIVATE(self);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -415,38 +367,29 @@ context_async_ready_callback (GObject *source_object,
|
||||
/**
|
||||
* eekboard_context_add_keyboard:
|
||||
* @context: an #EekboardContext
|
||||
* @keyboard: an #EekKeyboard
|
||||
* @keyboard: a string representing keyboard
|
||||
* @cancellable: a #GCancellable
|
||||
*
|
||||
* Register @keyboard in @context.
|
||||
*/
|
||||
guint
|
||||
eekboard_context_add_keyboard (EekboardContext *context,
|
||||
EekKeyboard *keyboard,
|
||||
const gchar *keyboard,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
EekboardContextPrivate *priv;
|
||||
GVariant *variant, *result;
|
||||
GVariant *result;
|
||||
GError *error;
|
||||
|
||||
g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), 0);
|
||||
g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), 0);
|
||||
|
||||
priv = EEKBOARD_CONTEXT_GET_PRIVATE (context);
|
||||
|
||||
variant = eek_serializable_serialize (EEK_SERIALIZABLE(keyboard));
|
||||
if (g_variant_is_floating (variant))
|
||||
g_variant_ref_sink (variant);
|
||||
|
||||
error = NULL;
|
||||
result = g_dbus_proxy_call_sync (G_DBUS_PROXY(context),
|
||||
"AddKeyboard",
|
||||
g_variant_new ("(v)", variant),
|
||||
g_variant_new ("(s)", keyboard),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cancellable,
|
||||
&error);
|
||||
g_variant_unref (variant);
|
||||
|
||||
if (result) {
|
||||
guint keyboard_id;
|
||||
@ -454,11 +397,6 @@ eekboard_context_add_keyboard (EekboardContext *context,
|
||||
g_variant_get (result, "(u)", &keyboard_id);
|
||||
g_variant_unref (result);
|
||||
|
||||
if (keyboard_id != 0) {
|
||||
g_hash_table_insert (priv->keyboard_hash,
|
||||
GUINT_TO_POINTER(keyboard_id),
|
||||
g_object_ref (keyboard));
|
||||
}
|
||||
return keyboard_id;
|
||||
}
|
||||
return 0;
|
||||
@ -477,20 +415,8 @@ eekboard_context_remove_keyboard (EekboardContext *context,
|
||||
guint keyboard_id,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
EekboardContextPrivate *priv;
|
||||
EekKeyboard *keyboard;
|
||||
|
||||
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
|
||||
|
||||
priv = EEKBOARD_CONTEXT_GET_PRIVATE (context);
|
||||
|
||||
keyboard = g_hash_table_lookup (priv->keyboard_hash,
|
||||
GUINT_TO_POINTER(keyboard_id));
|
||||
if (keyboard == priv->keyboard)
|
||||
priv->keyboard = NULL;
|
||||
|
||||
g_hash_table_remove (priv->keyboard_hash, GUINT_TO_POINTER(keyboard_id));
|
||||
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(context),
|
||||
"RemoveKeyboard",
|
||||
g_variant_new ("(u)", keyboard_id),
|
||||
@ -514,20 +440,8 @@ eekboard_context_set_keyboard (EekboardContext *context,
|
||||
guint keyboard_id,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
EekboardContextPrivate *priv;
|
||||
EekKeyboard *keyboard;
|
||||
|
||||
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
|
||||
|
||||
priv = EEKBOARD_CONTEXT_GET_PRIVATE (context);
|
||||
|
||||
keyboard = g_hash_table_lookup (priv->keyboard_hash,
|
||||
GUINT_TO_POINTER(keyboard_id));
|
||||
if (!keyboard || keyboard == priv->keyboard)
|
||||
return;
|
||||
|
||||
priv->keyboard = keyboard;
|
||||
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(context),
|
||||
"SetKeyboard",
|
||||
g_variant_new ("(u)", keyboard_id),
|
||||
@ -557,10 +471,7 @@ eekboard_context_set_group (EekboardContext *context,
|
||||
|
||||
priv = EEKBOARD_CONTEXT_GET_PRIVATE (context);
|
||||
|
||||
g_return_if_fail (priv->keyboard);
|
||||
|
||||
if (eek_element_get_group (EEK_ELEMENT(priv->keyboard)) != group) {
|
||||
eek_element_set_group (EEK_ELEMENT(priv->keyboard), group);
|
||||
if (priv->group != group) {
|
||||
g_dbus_proxy_call (G_DBUS_PROXY(context),
|
||||
"SetGroup",
|
||||
g_variant_new ("(i)", group),
|
||||
@ -572,6 +483,25 @@ eekboard_context_set_group (EekboardContext *context,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* eekboard_context_get_group:
|
||||
* @context: an #EekboardContext
|
||||
* @cancellable: a #GCancellable
|
||||
*
|
||||
* Get the keyboard group of @context.
|
||||
*/
|
||||
gint
|
||||
eekboard_context_get_group (EekboardContext *context,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
EekboardContextPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), 0);
|
||||
|
||||
priv = EEKBOARD_CONTEXT_GET_PRIVATE (context);
|
||||
return priv->group;
|
||||
}
|
||||
|
||||
/**
|
||||
* eekboard_context_show_keyboard:
|
||||
* @context: an #EekboardContext
|
||||
|
||||
@ -57,7 +57,6 @@ struct _EekboardContext {
|
||||
* @enabled: class handler for #EekboardContext::enabled signal
|
||||
* @disabled: class handler for #EekboardContext::disabled signal
|
||||
* @key_pressed: class handler for #EekboardContext::key-pressed signal
|
||||
* @key_released: class handler for #EekboardContext::key-released signal
|
||||
*/
|
||||
struct _EekboardContextClass {
|
||||
/*< private >*/
|
||||
@ -68,14 +67,14 @@ struct _EekboardContextClass {
|
||||
void (*enabled) (EekboardContext *self);
|
||||
void (*disabled) (EekboardContext *self);
|
||||
void (*key_pressed) (EekboardContext *self,
|
||||
guint keycode);
|
||||
void (*key_released) (EekboardContext *self,
|
||||
guint keycode);
|
||||
guint keycode,
|
||||
EekSymbol *symbol,
|
||||
guint modifiers);
|
||||
void (*destroyed) (EekboardContext *self);
|
||||
|
||||
/*< private >*/
|
||||
/* padding */
|
||||
gpointer pdummy[23];
|
||||
gpointer pdummy[24];
|
||||
};
|
||||
|
||||
GType eekboard_context_get_type (void) G_GNUC_CONST;
|
||||
@ -84,7 +83,7 @@ EekboardContext *eekboard_context_new (GDBusConnection *connection,
|
||||
const gchar *object_path,
|
||||
GCancellable *cancellable);
|
||||
guint eekboard_context_add_keyboard (EekboardContext *context,
|
||||
EekKeyboard *keyboard,
|
||||
const gchar *keyboard,
|
||||
GCancellable *cancellable);
|
||||
void eekboard_context_remove_keyboard (EekboardContext *context,
|
||||
guint keyboard_id,
|
||||
|
||||
1
eekboard/eekboard-marshalers.list
Normal file
1
eekboard/eekboard-marshalers.list
Normal file
@ -0,0 +1 @@
|
||||
VOID:UINT,OBJECT,UINT
|
||||
@ -69,14 +69,19 @@ eekboard_server_CFLAGS = \
|
||||
-I$(top_srcdir) \
|
||||
$(GIO2_CFLAGS) \
|
||||
$(GTK_CFLAGS) \
|
||||
-DTHEMEDIR=\"$(pkgdatadir)/themes\"
|
||||
$(LIBXKLAVIER_CFLAGS) \
|
||||
-DTHEMEDIR=\"$(pkgdatadir)/themes\" \
|
||||
-DKEYBOARDDIR=\"$(pkgdatadir)/keyboards\"
|
||||
|
||||
eekboard_server_LDADD = \
|
||||
$(builddir)/libxklutil.la \
|
||||
$(top_builddir)/eekboard/libeekboard.la \
|
||||
$(top_builddir)/eek/libeek.la \
|
||||
$(top_builddir)/eek/libeek-gtk.la \
|
||||
$(top_builddir)/eek/libeek-xkl.la \
|
||||
$(GIO2_LIBS) \
|
||||
$(GTK_LIBS)
|
||||
$(GTK_LIBS) \
|
||||
$(LIBXKLAVIER_LIBS)
|
||||
|
||||
if ENABLE_CLUTTER_GTK
|
||||
eekboard_server_CFLAGS += $(CLUTTER_GTK_CFLAGS)
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
#include "eekboard/eekboard.h"
|
||||
#include "client.h"
|
||||
|
||||
#define DEFAULT_LAYOUT "us-qwerty"
|
||||
#define DEFAULT_KEYBOARD "us"
|
||||
|
||||
static gboolean opt_system = FALSE;
|
||||
static gboolean opt_session = FALSE;
|
||||
@ -44,10 +44,6 @@ static gboolean opt_keystroke = FALSE;
|
||||
|
||||
static gchar *opt_keyboard = NULL;
|
||||
|
||||
static gchar *opt_model = NULL;
|
||||
static gchar *opt_layouts = NULL;
|
||||
static gchar *opt_options = NULL;
|
||||
|
||||
static gboolean opt_fullscreen = FALSE;
|
||||
|
||||
static const GOptionEntry options[] = {
|
||||
@ -69,12 +65,6 @@ static const GOptionEntry options[] = {
|
||||
#endif /* HAVE_ATSPI */
|
||||
{"keyboard", 'k', 0, G_OPTION_ARG_STRING, &opt_keyboard,
|
||||
N_("Specify keyboard")},
|
||||
{"model", '\0', 0, G_OPTION_ARG_STRING, &opt_model,
|
||||
N_("Specify model")},
|
||||
{"layouts", '\0', 0, G_OPTION_ARG_STRING, &opt_layouts,
|
||||
N_("Specify layouts")},
|
||||
{"options", '\0', 0, G_OPTION_ARG_STRING, &opt_options,
|
||||
N_("Specify options")},
|
||||
{"fullscreen", 'F', 0, G_OPTION_ARG_NONE, &opt_fullscreen,
|
||||
N_("Create window in fullscreen mode")},
|
||||
{NULL}
|
||||
@ -138,6 +128,13 @@ main (int argc, char **argv)
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* preload Eek* types for EekKeyboard deserialization */
|
||||
g_type_class_ref (EEK_TYPE_KEYBOARD);
|
||||
g_type_class_ref (EEK_TYPE_SECTION);
|
||||
g_type_class_ref (EEK_TYPE_KEY);
|
||||
g_type_class_ref (EEK_TYPE_SYMBOL);
|
||||
g_type_class_ref (EEK_TYPE_KEYSYM);
|
||||
|
||||
option_context = g_option_context_new ("eekboard-desktop-client");
|
||||
g_option_context_add_main_entries (option_context, options, NULL);
|
||||
g_option_context_parse (option_context, &argc, &argv, NULL);
|
||||
@ -254,7 +251,7 @@ main (int argc, char **argv)
|
||||
}
|
||||
#endif /* HAVE_IBUS */
|
||||
|
||||
if (opt_use_system_layout && (opt_keyboard || opt_model || opt_layouts || opt_options)) {
|
||||
if (opt_use_system_layout && opt_keyboard) {
|
||||
g_printerr ("Can't use --use-system-layout option with keyboard options\n");
|
||||
g_object_unref (client);
|
||||
exit (1);
|
||||
@ -266,35 +263,6 @@ main (int argc, char **argv)
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (opt_use_system_layout || opt_model || opt_layouts || opt_options) {
|
||||
if (!eekboard_client_load_keyboard_from_xkl (client,
|
||||
opt_model,
|
||||
opt_layouts,
|
||||
opt_options)) {
|
||||
g_printerr ("Can't load keyboard from xklavier config\n");
|
||||
g_object_unref (client);
|
||||
exit (1);
|
||||
}
|
||||
} else {
|
||||
gchar *file;
|
||||
gboolean success;
|
||||
|
||||
if (!opt_keyboard)
|
||||
opt_keyboard = DEFAULT_LAYOUT;
|
||||
|
||||
if (g_str_has_suffix (opt_keyboard, ".xml"))
|
||||
file = g_strdup (opt_keyboard);
|
||||
else
|
||||
file = g_strdup_printf ("%s/%s.xml", KEYBOARDDIR, opt_keyboard);
|
||||
success = eekboard_client_load_keyboard_from_file (client, file);
|
||||
g_free (file);
|
||||
if (!success) {
|
||||
g_printerr ("Can't load keyboard file %s\n", file);
|
||||
g_object_unref (client);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_XTEST
|
||||
if (!eekboard_client_enable_xtest (client)) {
|
||||
g_printerr ("Can't init xtest\n");
|
||||
@ -303,6 +271,8 @@ main (int argc, char **argv)
|
||||
}
|
||||
#endif /* HAVE_XTEST */
|
||||
|
||||
eekboard_client_set_keyboard (client, opt_keyboard ? opt_keyboard : DEFAULT_KEYBOARD);
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
if (!opt_focus) {
|
||||
g_object_get (client, "context", &context, NULL);
|
||||
|
||||
261
src/client.c
261
src/client.c
@ -68,7 +68,6 @@ struct _EekboardClient {
|
||||
XklEngine *xkl_engine;
|
||||
XklConfigRegistry *xkl_config_registry;
|
||||
gboolean use_xkl_layout;
|
||||
gint group;
|
||||
|
||||
gulong xkl_config_changed_handler;
|
||||
gulong xkl_state_changed_handler;
|
||||
@ -123,13 +122,7 @@ static gboolean keystroke_listener_cb (const AtspiDeviceEvent *stroke,
|
||||
void *user_data);
|
||||
#endif /* HAVE_ATSPI */
|
||||
static gboolean set_keyboard (EekboardClient *client,
|
||||
gboolean show,
|
||||
EekLayout *layout);
|
||||
static gboolean set_keyboard_from_xkl (EekboardClient *client,
|
||||
gboolean show,
|
||||
const gchar *model,
|
||||
const gchar *layouts,
|
||||
const gchar *options);
|
||||
const gchar *keyboard);
|
||||
#ifdef HAVE_XTEST
|
||||
static void update_modifier_keycodes
|
||||
(EekboardClient *client);
|
||||
@ -232,11 +225,6 @@ eekboard_client_dispose (GObject *object)
|
||||
client->eekboard = NULL;
|
||||
}
|
||||
|
||||
if (client->keyboard) {
|
||||
g_object_unref (client->keyboard);
|
||||
client->keyboard = NULL;
|
||||
}
|
||||
|
||||
if (client->settings) {
|
||||
g_object_unref (client->settings);
|
||||
client->settings = NULL;
|
||||
@ -286,50 +274,25 @@ eekboard_client_class_init (EekboardClientClass *klass)
|
||||
static void
|
||||
eekboard_client_init (EekboardClient *client)
|
||||
{
|
||||
client->eekboard = NULL;
|
||||
client->context = NULL;
|
||||
client->xkl_engine = NULL;
|
||||
client->xkl_config_registry = NULL;
|
||||
client->keyboard = NULL;
|
||||
client->key_pressed_handler = 0;
|
||||
client->key_released_handler = 0;
|
||||
client->xkl_config_changed_handler = 0;
|
||||
client->xkl_state_changed_handler = 0;
|
||||
#if ENABLE_FOCUS_LISTENER
|
||||
client->follows_focus = FALSE;
|
||||
client->hide_keyboard_timeout_id = 0;
|
||||
#endif /* ENABLE_FOCUS_LISTENER */
|
||||
#ifdef HAVE_ATSPI
|
||||
client->keystroke_listener = NULL;
|
||||
#endif /* HAVE_ATSPI */
|
||||
#ifdef HAVE_IBUS
|
||||
client->ibus_bus = NULL;
|
||||
client->ibus_focus_message_filter = 0;
|
||||
#endif /* HAVE_IBUS */
|
||||
client->settings = g_settings_new ("org.fedorahosted.eekboard");
|
||||
}
|
||||
|
||||
gboolean
|
||||
eekboard_client_load_keyboard_from_xkl (EekboardClient *client,
|
||||
const gchar *model,
|
||||
const gchar *layouts,
|
||||
const gchar *options)
|
||||
{
|
||||
client->use_xkl_layout = TRUE;
|
||||
|
||||
#if ENABLE_FOCUS_LISTENER
|
||||
return set_keyboard_from_xkl (client,
|
||||
!client->follows_focus,
|
||||
model,
|
||||
layouts,
|
||||
options);
|
||||
#define IS_KEYBOARD_VISIBLE(client) (!client->follows_focus)
|
||||
#else /* ENABLE_FOCUS_LISTENER */
|
||||
return set_keyboard_from_xkl (client,
|
||||
TRUE,
|
||||
model,
|
||||
layouts,
|
||||
options);
|
||||
#define IS_KEYBOARD_VISIBLE(client) TRUE
|
||||
#endif /* !ENABLE_FOCUS_LISTENER */
|
||||
|
||||
gboolean
|
||||
eekboard_client_set_keyboard (EekboardClient *client,
|
||||
const gchar *keyboard)
|
||||
{
|
||||
gboolean retval;
|
||||
|
||||
retval = set_keyboard (client, keyboard);
|
||||
if (IS_KEYBOARD_VISIBLE (client))
|
||||
eekboard_context_show_keyboard (client->context, NULL);
|
||||
return retval;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -550,24 +513,17 @@ keystroke_listener_cb (const AtspiDeviceEvent *stroke,
|
||||
void *user_data)
|
||||
{
|
||||
EekboardClient *client = user_data;
|
||||
EekKey *key;
|
||||
|
||||
/* Ignore modifiers since the keystroke listener does not called
|
||||
when a modifier key is released. */
|
||||
key = eek_keyboard_find_key_by_keycode (client->keyboard,
|
||||
stroke->hw_code);
|
||||
if (key) {
|
||||
EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||
if (symbol && eek_symbol_is_modifier (symbol))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (stroke->type == ATSPI_KEY_PRESSED) {
|
||||
switch (stroke->type) {
|
||||
case ATSPI_KEY_PRESSED:
|
||||
eekboard_context_press_key (client->context, stroke->hw_code, NULL);
|
||||
} else {
|
||||
break;
|
||||
case ATSPI_KEY_RELEASED:
|
||||
eekboard_context_release_key (client->context, stroke->hw_code, NULL);
|
||||
break;
|
||||
default:
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* HAVE_ATSPI */
|
||||
@ -725,7 +681,19 @@ on_xkl_config_changed (XklEngine *xklengine,
|
||||
gboolean retval;
|
||||
|
||||
if (client->use_xkl_layout) {
|
||||
retval = set_keyboard_from_xkl (client, FALSE, NULL, NULL, NULL);
|
||||
XklConfigRec *rec;
|
||||
gchar *layout, *keyboard;
|
||||
|
||||
rec = xkl_config_rec_new ();
|
||||
xkl_config_rec_get_from_server (rec, client->xkl_engine);
|
||||
layout = eekboard_xkl_config_rec_to_string (rec);
|
||||
g_object_unref (rec);
|
||||
|
||||
keyboard = g_strdup_printf ("xkl:%s", layout);
|
||||
g_free (layout);
|
||||
retval = set_keyboard (client, keyboard);
|
||||
g_free (keyboard);
|
||||
|
||||
g_return_if_fail (retval);
|
||||
}
|
||||
|
||||
@ -736,88 +704,17 @@ on_xkl_config_changed (XklEngine *xklengine,
|
||||
|
||||
static gboolean
|
||||
set_keyboard (EekboardClient *client,
|
||||
gboolean show,
|
||||
EekLayout *layout)
|
||||
const gchar *keyboard)
|
||||
{
|
||||
gchar *keyboard_name;
|
||||
static gint keyboard_serial = 0;
|
||||
guint keyboard_id;
|
||||
|
||||
client->keyboard = eek_keyboard_new (layout, CSW, CSH);
|
||||
eek_keyboard_set_modifier_behavior (client->keyboard,
|
||||
EEK_MODIFIER_BEHAVIOR_LATCH);
|
||||
|
||||
keyboard_name = g_strdup_printf ("keyboard%d", keyboard_serial++);
|
||||
eek_element_set_name (EEK_ELEMENT(client->keyboard), keyboard_name);
|
||||
g_free (keyboard_name);
|
||||
|
||||
keyboard_id = eekboard_context_add_keyboard (client->context,
|
||||
client->keyboard,
|
||||
keyboard,
|
||||
NULL);
|
||||
eekboard_context_set_keyboard (client->context, keyboard_id, NULL);
|
||||
if (show)
|
||||
eekboard_context_show_keyboard (client->context, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_keyboard_from_xkl (EekboardClient *client,
|
||||
gboolean show,
|
||||
const gchar *model,
|
||||
const gchar *layouts,
|
||||
const gchar *options)
|
||||
{
|
||||
EekLayout *layout;
|
||||
gboolean retval;
|
||||
|
||||
if (client->keyboard)
|
||||
g_object_unref (client->keyboard);
|
||||
layout = eek_xkl_layout_new ();
|
||||
|
||||
if (model) {
|
||||
if (!eek_xkl_layout_set_model (EEK_XKL_LAYOUT(layout), model)) {
|
||||
g_object_unref (layout);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (layouts) {
|
||||
XklConfigRec *rec;
|
||||
|
||||
rec = eekboard_xkl_config_rec_new_from_string (layouts);
|
||||
if (!eek_xkl_layout_set_layouts (EEK_XKL_LAYOUT(layout),
|
||||
rec->layouts)) {
|
||||
g_object_unref (rec);
|
||||
g_object_unref (layout);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!eek_xkl_layout_set_variants (EEK_XKL_LAYOUT(layout),
|
||||
rec->variants)) {
|
||||
g_object_unref (rec);
|
||||
g_object_unref (layout);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_object_unref (rec);
|
||||
}
|
||||
|
||||
if (options) {
|
||||
gchar **_options;
|
||||
|
||||
_options = g_strsplit (options, ",", -1);
|
||||
if (!eek_xkl_layout_set_options (EEK_XKL_LAYOUT(layout), _options)) {
|
||||
g_strfreev (_options);
|
||||
g_object_unref (layout);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
retval = set_keyboard (client, show, layout);
|
||||
g_object_unref (layout);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
on_xkl_state_changed (XklEngine *xklengine,
|
||||
XklEngineStateChange type,
|
||||
@ -827,14 +724,9 @@ on_xkl_state_changed (XklEngine *xklengine,
|
||||
{
|
||||
EekboardClient *client = user_data;
|
||||
|
||||
if (type == GROUP_CHANGED && client->keyboard) {
|
||||
if (client->use_xkl_layout) {
|
||||
gint group = eek_element_get_group (EEK_ELEMENT(client->keyboard));
|
||||
if (group != value) {
|
||||
eekboard_context_set_group (client->context, value, NULL);
|
||||
}
|
||||
}
|
||||
client->group = value;
|
||||
if (type == GROUP_CHANGED) {
|
||||
if (client->use_xkl_layout)
|
||||
eekboard_context_set_group (client->context, value, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -918,7 +810,7 @@ get_keycode_from_gdk_keymap (EekboardClient *client,
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < n_keys; i++)
|
||||
if (keys[i].group == client->group)
|
||||
if (keys[i].group == eekboard_context_get_group (client->context))
|
||||
best_match = &keys[i];
|
||||
|
||||
*keycode = best_match->keycode;
|
||||
@ -953,17 +845,15 @@ send_fake_modifier_key_event (EekboardClient *client,
|
||||
|
||||
static void
|
||||
send_fake_key_event (EekboardClient *client,
|
||||
EekKey *key,
|
||||
EekSymbol *symbol,
|
||||
guint keyboard_modifiers,
|
||||
gboolean is_pressed)
|
||||
{
|
||||
GdkDisplay *display = gdk_display_get_default ();
|
||||
EekSymbol *symbol;
|
||||
EekModifierType keyboard_modifiers, modifiers;
|
||||
EekModifierType modifiers;
|
||||
guint xkeysym;
|
||||
guint keycode, replaced_keysym = 0;
|
||||
|
||||
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||
|
||||
/* Ignore special keys and modifiers */
|
||||
if (!EEK_IS_KEYSYM(symbol) || eek_symbol_is_modifier (symbol))
|
||||
return;
|
||||
@ -982,10 +872,9 @@ send_fake_key_event (EekboardClient *client,
|
||||
}
|
||||
|
||||
/* Clear level shift modifiers */
|
||||
keyboard_modifiers = eek_keyboard_get_modifiers (client->keyboard);
|
||||
keyboard_modifiers &= ~EEK_SHIFT_MASK;
|
||||
keyboard_modifiers &= ~EEK_LOCK_MASK;
|
||||
keyboard_modifiers &= ~eek_keyboard_get_alt_gr_mask (client->keyboard);
|
||||
//keyboard_modifiers &= ~eek_keyboard_get_alt_gr_mask (client->keyboard);
|
||||
|
||||
modifiers |= keyboard_modifiers;
|
||||
|
||||
@ -1007,20 +896,15 @@ send_fake_key_event (EekboardClient *client,
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_pressed (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data)
|
||||
on_key_pressed (EekboardContext *context,
|
||||
guint keycode,
|
||||
EekSymbol *symbol,
|
||||
guint modifiers,
|
||||
gpointer user_data)
|
||||
{
|
||||
EekboardClient *client = user_data;
|
||||
send_fake_key_event (client, key, TRUE);
|
||||
send_fake_key_event (client, key, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
on_key_released (EekKeyboard *keyboard,
|
||||
EekKey *key,
|
||||
gpointer user_data)
|
||||
{
|
||||
send_fake_key_event (client, symbol, modifiers, TRUE);
|
||||
send_fake_key_event (client, symbol, modifiers, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1074,11 +958,8 @@ eekboard_client_enable_xtest (EekboardClient *client)
|
||||
update_modifier_keycodes (client);
|
||||
|
||||
client->key_pressed_handler =
|
||||
g_signal_connect (client->keyboard, "key-pressed",
|
||||
g_signal_connect (client->context, "key-pressed",
|
||||
G_CALLBACK(on_key_pressed), client);
|
||||
client->key_released_handler =
|
||||
g_signal_connect (client->keyboard, "key-released",
|
||||
G_CALLBACK(on_key_released), client);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1090,43 +971,5 @@ eekboard_client_disable_xtest (EekboardClient *client)
|
||||
XkbFreeKeyboard (client->xkb, 0, TRUE); /* free_all = TRUE */
|
||||
client->xkb = NULL;
|
||||
}
|
||||
|
||||
if (g_signal_handler_is_connected (client->keyboard,
|
||||
client->key_pressed_handler))
|
||||
g_signal_handler_disconnect (client->keyboard,
|
||||
client->key_pressed_handler);
|
||||
if (g_signal_handler_is_connected (client->keyboard,
|
||||
client->key_released_handler))
|
||||
g_signal_handler_disconnect (client->keyboard,
|
||||
client->key_released_handler);
|
||||
}
|
||||
|
||||
gboolean
|
||||
eekboard_client_load_keyboard_from_file (EekboardClient *client,
|
||||
const gchar *keyboard_file)
|
||||
{
|
||||
GFile *file;
|
||||
GFileInputStream *input;
|
||||
GError *error;
|
||||
EekLayout *layout;
|
||||
gboolean retval;
|
||||
|
||||
file = g_file_new_for_path (keyboard_file);
|
||||
|
||||
error = NULL;
|
||||
input = g_file_read (file, NULL, &error);
|
||||
if (input == NULL)
|
||||
return FALSE;
|
||||
|
||||
layout = eek_xml_layout_new (G_INPUT_STREAM(input));
|
||||
g_object_unref (input);
|
||||
#if ENABLE_FOCUS_LISTENER
|
||||
retval = set_keyboard (client, !client->follows_focus, layout);
|
||||
#else /* ENABLE_FOCUS_LISTENER */
|
||||
retval = set_keyboard (client, TRUE, layout);
|
||||
#endif /* !ENABLE_FOCUS_LISTENER */
|
||||
g_object_unref (layout);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* HAVE_XTEST */
|
||||
|
||||
10
src/client.h
10
src/client.h
@ -33,15 +33,9 @@ typedef struct _EekboardClient EekboardClient;
|
||||
|
||||
EekboardClient * eekboard_client_new (GDBusConnection *connection);
|
||||
|
||||
gboolean eekboard_client_load_keyboard_from_file
|
||||
gboolean eekboard_client_set_keyboard
|
||||
(EekboardClient *client,
|
||||
const gchar *file);
|
||||
|
||||
gboolean eekboard_client_load_keyboard_from_xkl
|
||||
(EekboardClient *client,
|
||||
const gchar *model,
|
||||
const gchar *layouts,
|
||||
const gchar *options);
|
||||
const gchar *keyboard);
|
||||
|
||||
gboolean eekboard_client_enable_xkl (EekboardClient *client);
|
||||
void eekboard_client_disable_xkl (EekboardClient *client);
|
||||
|
||||
@ -32,8 +32,10 @@
|
||||
#include "eek/eek-clutter.h"
|
||||
#endif
|
||||
#include "eek/eek-gtk.h"
|
||||
#include "eek/eek-xkl.h"
|
||||
|
||||
#include "server-context.h"
|
||||
#include "xklutil.h"
|
||||
|
||||
#define CSW 640
|
||||
#define CSH 480
|
||||
@ -51,7 +53,7 @@ static const gchar introspection_xml[] =
|
||||
"<node>"
|
||||
" <interface name='org.fedorahosted.Eekboard.Context'>"
|
||||
" <method name='AddKeyboard'>"
|
||||
" <arg direction='in' type='v' name='keyboard'/>"
|
||||
" <arg direction='in' type='s' name='keyboard'/>"
|
||||
" <arg direction='out' type='u' name='keyboard_id'/>"
|
||||
" </method>"
|
||||
" <method name='RemoveKeyboard'>"
|
||||
@ -79,13 +81,18 @@ static const gchar introspection_xml[] =
|
||||
" <signal name='Disabled'/>"
|
||||
" <signal name='KeyPressed'>"
|
||||
" <arg type='u' name='keycode'/>"
|
||||
" </signal>"
|
||||
" <signal name='KeyReleased'>"
|
||||
" <arg type='u' name='keycode'/>"
|
||||
" <arg type='v' name='symbol'/>"
|
||||
" <arg type='u' name='modifiers'/>"
|
||||
" </signal>"
|
||||
" <signal name='KeyboardVisibilityChanged'>"
|
||||
" <arg type='b' name='visible'/>"
|
||||
" </signal>"
|
||||
" <signal name='KeyboardChanged'>"
|
||||
" <arg type='u' name='keyboard_id'/>"
|
||||
" </signal>"
|
||||
" <signal name='GroupChanged'>"
|
||||
" <arg type='i' name='group'/>"
|
||||
" </signal>"
|
||||
" </interface>"
|
||||
"</node>";
|
||||
|
||||
@ -206,8 +213,7 @@ on_realize_set_dock (GtkWidget *widget,
|
||||
{
|
||||
#ifdef HAVE_XDOCK
|
||||
GdkWindow *window = gtk_widget_get_window (widget);
|
||||
Atom atoms[2] = { None, None };
|
||||
gint x, y, width, height, depth;
|
||||
gint x, y, width, height;
|
||||
long vals[12];
|
||||
|
||||
/* set window type to dock */
|
||||
@ -599,30 +605,29 @@ server_context_init (ServerContext *context)
|
||||
static gboolean on_repeat_timeout (ServerContext *context);
|
||||
|
||||
static void
|
||||
emit_press_release_dbus_signal (ServerContext *context)
|
||||
emit_key_pressed_dbus_signal (ServerContext *context, EekKey *key)
|
||||
{
|
||||
if (context->connection && context->enabled) {
|
||||
guint keycode = eek_key_get_keycode (context->repeat_key);
|
||||
guint keycode = eek_key_get_keycode (key);
|
||||
EekSymbol *symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
|
||||
guint modifiers = eek_keyboard_get_modifiers (context->keyboard);
|
||||
GVariant *variant;
|
||||
GError *error;
|
||||
|
||||
variant = eek_serializable_serialize (EEK_SERIALIZABLE(symbol));
|
||||
|
||||
error = NULL;
|
||||
g_dbus_connection_emit_signal (context->connection,
|
||||
NULL,
|
||||
context->object_path,
|
||||
SERVER_CONTEXT_INTERFACE,
|
||||
"KeyPressed",
|
||||
g_variant_new ("(u)", keycode),
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
error = NULL;
|
||||
g_dbus_connection_emit_signal (context->connection,
|
||||
NULL,
|
||||
context->object_path,
|
||||
SERVER_CONTEXT_INTERFACE,
|
||||
"KeyReleased",
|
||||
g_variant_new ("(u)", keycode),
|
||||
g_variant_new ("(uvu)",
|
||||
keycode,
|
||||
variant,
|
||||
modifiers),
|
||||
&error);
|
||||
g_variant_unref (variant);
|
||||
g_assert_no_error (error);
|
||||
}
|
||||
}
|
||||
@ -632,7 +637,7 @@ on_repeat_timeout (ServerContext *context)
|
||||
{
|
||||
gint delay = g_settings_get_int (context->settings, "repeat-interval");
|
||||
|
||||
emit_press_release_dbus_signal (context);
|
||||
emit_key_pressed_dbus_signal (context, context->repeat_key);
|
||||
|
||||
context->repeat_timeout_id =
|
||||
g_timeout_add (delay,
|
||||
@ -645,7 +650,7 @@ on_repeat_timeout (ServerContext *context)
|
||||
static gboolean
|
||||
on_repeat_timeout_init (ServerContext *context)
|
||||
{
|
||||
emit_press_release_dbus_signal (context);
|
||||
emit_key_pressed_dbus_signal (context, context->repeat_key);
|
||||
|
||||
/* FIXME: clear modifiers for further key repeat; better not
|
||||
depend on modifier behavior is LATCH */
|
||||
@ -690,39 +695,13 @@ on_key_released (EekKeyboard *keyboard,
|
||||
gpointer user_data)
|
||||
{
|
||||
ServerContext *context = user_data;
|
||||
gboolean need_key_press = FALSE;
|
||||
|
||||
if (context->repeat_timeout_id > 0) {
|
||||
g_source_remove (context->repeat_timeout_id);
|
||||
context->repeat_timeout_id = 0;
|
||||
need_key_press = TRUE;
|
||||
}
|
||||
|
||||
if (context->connection && context->enabled) {
|
||||
guint keycode = eek_key_get_keycode (key);
|
||||
GError *error;
|
||||
|
||||
if (need_key_press) {
|
||||
error = NULL;
|
||||
g_dbus_connection_emit_signal (context->connection,
|
||||
NULL,
|
||||
context->object_path,
|
||||
SERVER_CONTEXT_INTERFACE,
|
||||
"KeyPressed",
|
||||
g_variant_new ("(u)", keycode),
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
}
|
||||
|
||||
error = NULL;
|
||||
g_dbus_connection_emit_signal (context->connection,
|
||||
NULL,
|
||||
context->object_path,
|
||||
SERVER_CONTEXT_INTERFACE,
|
||||
"KeyReleased",
|
||||
g_variant_new ("(u)", keycode),
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
/* KeyPressed signal has not been emitted in repeat handler */
|
||||
emit_key_pressed_dbus_signal (context, context->repeat_key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -739,6 +718,60 @@ disconnect_keyboard_signals (ServerContext *context)
|
||||
context->key_released_handler);
|
||||
}
|
||||
|
||||
static EekKeyboard *
|
||||
create_keyboard_from_string (const gchar *string)
|
||||
{
|
||||
EekKeyboard *keyboard;
|
||||
EekLayout *layout;
|
||||
|
||||
if (g_str_has_prefix (string, "xkl:")) {
|
||||
XklConfigRec *rec = eekboard_xkl_config_rec_from_string (&string[4]);
|
||||
|
||||
layout = eek_xkl_layout_new ();
|
||||
if (!eek_xkl_layout_set_config (EEK_XKL_LAYOUT(layout), rec)) {
|
||||
g_object_unref (layout);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
gchar *path;
|
||||
GFile *file;
|
||||
GFileInputStream *input;
|
||||
GError *error;
|
||||
|
||||
path = g_strdup_printf ("%s/%s.xml", KEYBOARDDIR, string);
|
||||
file = g_file_new_for_path (path);
|
||||
g_free (path);
|
||||
|
||||
error = NULL;
|
||||
input = g_file_read (file, NULL, &error);
|
||||
if (input == NULL) {
|
||||
g_object_unref (file);
|
||||
return NULL;
|
||||
}
|
||||
layout = eek_xml_layout_new (G_INPUT_STREAM(input));
|
||||
}
|
||||
keyboard = eek_keyboard_new (layout, CSW, CSH);
|
||||
g_object_unref (layout);
|
||||
|
||||
return keyboard;
|
||||
}
|
||||
|
||||
static void
|
||||
emit_group_changed_signal (ServerContext *context, int group)
|
||||
{
|
||||
GError *error;
|
||||
|
||||
error = NULL;
|
||||
g_dbus_connection_emit_signal (context->connection,
|
||||
NULL,
|
||||
context->object_path,
|
||||
SERVER_CONTEXT_INTERFACE,
|
||||
"GroupChanged",
|
||||
g_variant_new ("(i)", group),
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_method_call (GDBusConnection *connection,
|
||||
const gchar *sender,
|
||||
@ -752,26 +785,27 @@ handle_method_call (GDBusConnection *connection,
|
||||
ServerContext *context = user_data;
|
||||
|
||||
if (g_strcmp0 (method_name, "AddKeyboard") == 0) {
|
||||
GVariant *variant;
|
||||
EekSerializable *serializable;
|
||||
const gchar *name;
|
||||
static guint keyboard_id = 0;
|
||||
EekKeyboard *keyboard;
|
||||
|
||||
g_variant_get (parameters, "(v)", &variant);
|
||||
g_variant_get (parameters, "(&s)", &name);
|
||||
keyboard = create_keyboard_from_string (name);
|
||||
|
||||
serializable = eek_serializable_deserialize (variant);
|
||||
if (!EEK_IS_KEYBOARD(serializable)) {
|
||||
if (keyboard == NULL) {
|
||||
g_dbus_method_invocation_return_error (invocation,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED_HANDLED,
|
||||
"not a keyboard");
|
||||
"can't create a keyboard");
|
||||
return;
|
||||
}
|
||||
eek_keyboard_set_modifier_behavior (EEK_KEYBOARD(serializable),
|
||||
|
||||
eek_keyboard_set_modifier_behavior (keyboard,
|
||||
EEK_MODIFIER_BEHAVIOR_LATCH);
|
||||
|
||||
g_hash_table_insert (context->keyboard_hash,
|
||||
GUINT_TO_POINTER(++keyboard_id),
|
||||
serializable);
|
||||
keyboard);
|
||||
g_dbus_method_invocation_return_value (invocation,
|
||||
g_variant_new ("(u)",
|
||||
keyboard_id));
|
||||
@ -802,6 +836,7 @@ handle_method_call (GDBusConnection *connection,
|
||||
if (g_strcmp0 (method_name, "SetKeyboard") == 0) {
|
||||
EekKeyboard *keyboard;
|
||||
guint keyboard_id;
|
||||
gint group;
|
||||
|
||||
g_variant_get (parameters, "(u)", &keyboard_id);
|
||||
|
||||
@ -847,6 +882,10 @@ handle_method_call (GDBusConnection *connection,
|
||||
}
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||
|
||||
eek_element_get_group (EEK_ELEMENT(context->keyboard));
|
||||
emit_group_changed_signal (context, group);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -895,6 +934,9 @@ handle_method_call (GDBusConnection *connection,
|
||||
}
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||
|
||||
emit_group_changed_signal (context, group);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -21,13 +21,13 @@
|
||||
#include "xklutil.h"
|
||||
|
||||
XklConfigRec *
|
||||
eekboard_xkl_config_rec_new_from_string (const gchar *layouts)
|
||||
eekboard_xkl_config_rec_from_string (const gchar *layouts)
|
||||
{
|
||||
XklConfigRec *rec;
|
||||
gchar **l, **v;
|
||||
gint i;
|
||||
|
||||
l = g_strsplit (layouts, ",", -1);
|
||||
l = g_strsplit (layouts, ":", -1);
|
||||
v = g_strdupv (l);
|
||||
for (i = 0; l[i]; i++) {
|
||||
gchar *layout = l[i], *variant = v[i],
|
||||
@ -50,6 +50,36 @@ eekboard_xkl_config_rec_new_from_string (const gchar *layouts)
|
||||
return rec;
|
||||
}
|
||||
|
||||
gchar *
|
||||
eekboard_xkl_config_rec_to_string (XklConfigRec *rec)
|
||||
{
|
||||
gchar **strv, **sp, **lp, **vp, *p;
|
||||
gint n_layouts;
|
||||
GString *str;
|
||||
|
||||
n_layouts = g_strv_length (rec->layouts);
|
||||
strv = g_malloc0_n (n_layouts + 2, sizeof (gchar *));
|
||||
for (sp = strv, lp = rec->layouts, vp = rec->variants; *lp; sp++, lp++) {
|
||||
if (*vp != NULL)
|
||||
*sp = g_strdup_printf ("%s(%s)", *lp, *vp++);
|
||||
else
|
||||
*sp = g_strdup_printf ("%s", *lp);
|
||||
}
|
||||
|
||||
str = g_string_new ("");
|
||||
p = g_strjoinv (":", strv);
|
||||
g_strfreev (strv);
|
||||
g_string_append (str, p);
|
||||
g_free (p);
|
||||
|
||||
g_string_append_c (str, ':');
|
||||
p = g_strjoinv ("+", rec->options);
|
||||
g_string_append (str, p);
|
||||
g_free (p);
|
||||
|
||||
return g_string_free (str,FALSE);
|
||||
}
|
||||
|
||||
static XklConfigItem *
|
||||
xkl_config_item_copy (const XklConfigItem *item)
|
||||
{
|
||||
|
||||
@ -24,16 +24,16 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
XklConfigRec *eekboard_xkl_config_rec_new_from_string
|
||||
(const gchar *layouts);
|
||||
XklConfigRec *eekboard_xkl_config_rec_from_string (const gchar *layouts);
|
||||
gchar *eekboard_xkl_config_rec_to_string (XklConfigRec *rec);
|
||||
|
||||
GSList *eekboard_xkl_list_models (XklConfigRegistry *registry);
|
||||
GSList *eekboard_xkl_list_layouts (XklConfigRegistry *registry);
|
||||
GSList *eekboard_xkl_list_option_groups (XklConfigRegistry *registry);
|
||||
GSList *eekboard_xkl_list_layout_variants (XklConfigRegistry *registry,
|
||||
const gchar *layout);
|
||||
GSList *eekboard_xkl_list_options (XklConfigRegistry *registry,
|
||||
const gchar *group);
|
||||
GSList *eekboard_xkl_list_models (XklConfigRegistry *registry);
|
||||
GSList *eekboard_xkl_list_layouts (XklConfigRegistry *registry);
|
||||
GSList *eekboard_xkl_list_option_groups (XklConfigRegistry *registry);
|
||||
GSList *eekboard_xkl_list_layout_variants (XklConfigRegistry *registry,
|
||||
const gchar *layout);
|
||||
GSList *eekboard_xkl_list_options (XklConfigRegistry *registry,
|
||||
const gchar *group);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* EEKBOARD_XKLUTIL_H */
|
||||
|
||||
@ -201,7 +201,7 @@ main (int argc, char **argv)
|
||||
if (opt_layouts) {
|
||||
XklConfigRec *rec;
|
||||
|
||||
rec = eekboard_xkl_config_rec_new_from_string (opt_layouts);
|
||||
rec = eekboard_xkl_config_rec_from_string (opt_layouts);
|
||||
eek_xkl_layout_set_layouts (EEK_XKL_LAYOUT(layout), rec->layouts);
|
||||
eek_xkl_layout_set_variants (EEK_XKL_LAYOUT(layout), rec->variants);
|
||||
g_object_unref (rec);
|
||||
|
||||
Reference in New Issue
Block a user