From a6fe5bd859ef138e47fe4d97d10c9deff90c2a41 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Fri, 16 Mar 2012 17:36:20 +0900 Subject: [PATCH] Use GInitable to define EekXklLayout. --- eek/Makefile.am | 4 +- eek/eek-types.c | 6 + eek/eek-types.h | 8 ++ eek/eek-xkb-layout.c | 192 ++++++++++++++++------------ eek/eek-xkb-layout.h | 44 +++---- eek/eek-xkl-layout.c | 80 ++++++++---- eek/eek-xkl-layout.h | 3 +- eekboard/eekboard-context-service.c | 15 ++- tests/eek-xml-test.c | 4 +- 9 files changed, 224 insertions(+), 132 deletions(-) diff --git a/eek/Makefile.am b/eek/Makefile.am index aec12fdc..885cdd62 100644 --- a/eek/Makefile.am +++ b/eek/Makefile.am @@ -121,8 +121,8 @@ libeek_xkl_sources = \ $(srcdir)/eek-xkl-layout.c libeek_xkl_la_SOURCES = $(libeek_xkl_sources) -libeek_xkl_la_CFLAGS = -DEEK_COMPILATION=1 $(LIBXKLAVIER_CFLAGS) $(GTK_CFLAGS) -libeek_xkl_la_LIBADD = libeek.la $(LIBXKLAVIER_LIBS) $(GTK_LIBS) +libeek_xkl_la_CFLAGS = -DEEK_COMPILATION=1 $(LIBXKLAVIER_CFLAGS) +libeek_xkl_la_LIBADD = libeek.la $(LIBXKLAVIER_LIBS) eekdir = $(includedir)/eek-$(EEK_API_VERSION)/eek eek_HEADERS = \ diff --git a/eek/eek-types.c b/eek/eek-types.c index e59c1aef..a757bb7d 100644 --- a/eek/eek-types.c +++ b/eek/eek-types.c @@ -128,3 +128,9 @@ eek_color_new (gdouble red, return color; } + +GQuark +eek_error_quark (void) +{ + return g_quark_from_static_string ("eek-error-quark"); +} diff --git a/eek/eek-types.h b/eek/eek-types.h index 15dad0ce..749c2614 100644 --- a/eek/eek-types.h +++ b/eek/eek-types.h @@ -253,5 +253,13 @@ typedef enum { EEK_GRADIENT_RADIAL } EekGradientType; +GQuark eek_error_quark (void); + +#define EEK_ERROR eek_error_quark () +typedef enum { + EEK_ERROR_LAYOUT_ERROR, + EEK_ERROR_FAILED +} EekErrorEnum; + G_END_DECLS #endif /* EEK_TYPES_H */ diff --git a/eek/eek-xkb-layout.c b/eek/eek-xkb-layout.c index 73479661..fa2fff4d 100644 --- a/eek/eek-xkb-layout.c +++ b/eek/eek-xkb-layout.c @@ -31,11 +31,12 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ -#include +#include #include #include #include #include +#include #include "eek-xkb-layout.h" #include "eek-keyboard.h" @@ -45,13 +46,18 @@ #define noKBDRAW_DEBUG -G_DEFINE_TYPE (EekXkbLayout, eek_xkb_layout, EEK_TYPE_LAYOUT); +static void initable_iface_init (GInitableIface *initable_iface); + +G_DEFINE_TYPE_WITH_CODE (EekXkbLayout, eek_xkb_layout, EEK_TYPE_LAYOUT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + initable_iface_init)); #define EEK_XKB_LAYOUT_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutPrivate)) enum { PROP_0, + PROP_DISPLAY, PROP_KEYCODES, PROP_GEOMETRY, PROP_SYMBOLS, @@ -355,33 +361,33 @@ eek_xkb_layout_finalize (GObject *object) } static void -eek_xkb_layout_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +eek_xkb_layout_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { + EekXkbLayout *layout = EEK_XKB_LAYOUT (object); const gchar *name; - switch (prop_id) - { - case PROP_KEYCODES: - name = g_value_get_string (value); - eek_xkb_layout_set_keycodes (EEK_XKB_LAYOUT(object), name); - break; - case PROP_GEOMETRY: - name = g_value_get_string (value); - eek_xkb_layout_set_geometry (EEK_XKB_LAYOUT(object), name); - break; - case PROP_SYMBOLS: - name = g_value_get_string (value); - eek_xkb_layout_set_symbols (EEK_XKB_LAYOUT(object), name); - break; - default: - g_object_set_property (object, - g_param_spec_get_name (pspec), - value); - break; - } + switch (prop_id) { + case PROP_DISPLAY: + layout->priv->display = g_value_get_pointer (value); + break; + case PROP_KEYCODES: + name = g_value_get_string (value); + eek_xkb_layout_set_keycodes (EEK_XKB_LAYOUT(object), name); + break; + case PROP_GEOMETRY: + name = g_value_get_string (value); + eek_xkb_layout_set_geometry (EEK_XKB_LAYOUT(object), name); + break; + case PROP_SYMBOLS: + name = g_value_get_string (value); + eek_xkb_layout_set_symbols (EEK_XKB_LAYOUT(object), name); + break; + default: + break; + } } static void @@ -390,28 +396,28 @@ eek_xkb_layout_get_property (GObject *object, GValue *value, GParamSpec *pspec) { + EekXkbLayout *layout = EEK_XKB_LAYOUT (object); const gchar *name; - switch (prop_id) - { - case PROP_KEYCODES: - name = eek_xkb_layout_get_keycodes (EEK_XKB_LAYOUT(object)); - g_value_set_string (value, name); - break; - case PROP_GEOMETRY: - name = eek_xkb_layout_get_geometry (EEK_XKB_LAYOUT(object)); - g_value_set_string (value, name); - break; - case PROP_SYMBOLS: - name = eek_xkb_layout_get_symbols (EEK_XKB_LAYOUT(object)); - g_value_set_string (value, name); - break; - default: - g_object_get_property (object, - g_param_spec_get_name (pspec), - value); - break; - } + switch (prop_id) { + case PROP_DISPLAY: + g_value_set_pointer (value, layout->priv->display); + break; + case PROP_KEYCODES: + name = eek_xkb_layout_get_keycodes (EEK_XKB_LAYOUT(object)); + g_value_set_string (value, name); + break; + case PROP_GEOMETRY: + name = eek_xkb_layout_get_geometry (EEK_XKB_LAYOUT(object)); + g_value_set_string (value, name); + break; + case PROP_SYMBOLS: + name = eek_xkb_layout_get_symbols (EEK_XKB_LAYOUT(object)); + g_value_set_string (value, name); + break; + default: + break; + } } static void @@ -429,6 +435,13 @@ eek_xkb_layout_class_init (EekXkbLayoutClass *klass) gobject_class->set_property = eek_xkb_layout_set_property; gobject_class->get_property = eek_xkb_layout_get_property; + pspec = g_param_spec_pointer ("display", + "Display", + "X Display", + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (gobject_class, PROP_DISPLAY, pspec); + pspec = g_param_spec_string ("keycodes", "Keycodes", "XKB keycodes component name", @@ -454,28 +467,7 @@ eek_xkb_layout_class_init (EekXkbLayoutClass *klass) static void eek_xkb_layout_init (EekXkbLayout *self) { - EekXkbLayoutPrivate *priv; - - priv = self->priv = EEK_XKB_LAYOUT_GET_PRIVATE (self); - - priv->display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - g_return_if_fail (priv->display); - - /* XXX: XkbClientMapMask | XkbIndicatorMapMask | XkbNamesMask | - XkbGeometryMask */ - priv->xkb = XkbGetKeyboard (priv->display, - XkbGBN_GeometryMask | - XkbGBN_KeyNamesMask | - XkbGBN_OtherNamesMask | - XkbGBN_SymbolsMask | - XkbGBN_IndicatorMapMask, - XkbUseCoreKbd); - - if (priv->xkb == NULL) { - g_critical ("XkbGetKeyboard failed to get keyboard from the server!"); - return; - } - get_names (self); + self->priv = EEK_XKB_LAYOUT_GET_PRIVATE (self); } static void @@ -535,19 +527,14 @@ get_names (EekXkbLayout *layout) * Create a new #EekXkbLayout. */ EekLayout * -eek_xkb_layout_new (void) +eek_xkb_layout_new (Display *display, + GError **error) { - EekXkbLayout *layout; - - layout = g_object_new (EEK_TYPE_XKB_LAYOUT, NULL); - g_return_val_if_fail (layout, NULL); - - get_keyboard (layout); - if (layout->priv->xkb == NULL) { - g_object_unref (layout); - return NULL; - } - return EEK_LAYOUT(layout); + return (EekLayout *) g_initable_new (EEK_TYPE_XKB_LAYOUT, + NULL, + error, + "display", display, + NULL); } /** @@ -894,3 +881,48 @@ setup_scaling (EekXkbLayout *layout, priv->scale_denominator = priv->xkb->geom->height_mm; } } + +static gboolean +initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + EekXkbLayout *layout = EEK_XKB_LAYOUT (initable); + + /* XXX: XkbClientMapMask | XkbIndicatorMapMask | XkbNamesMask | + XkbGeometryMask */ + layout->priv->xkb = XkbGetKeyboard (layout->priv->display, + XkbGBN_GeometryMask | + XkbGBN_KeyNamesMask | + XkbGBN_OtherNamesMask | + XkbGBN_SymbolsMask | + XkbGBN_IndicatorMapMask, + XkbUseCoreKbd); + + if (layout->priv->xkb == NULL) { + g_set_error (error, + EEK_ERROR, + EEK_ERROR_LAYOUT_ERROR, + "can't get initial XKB keyboard configuration"); + return FALSE; + } + + get_names (layout); + get_keyboard (layout); + + if (layout->priv->xkb == NULL) { + g_set_error (error, + EEK_ERROR, + EEK_ERROR_LAYOUT_ERROR, + "can't get XKB keyboard configuration"); + return FALSE; + } + + return TRUE; +} + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + initable_iface->init = initable_init; +} diff --git a/eek/eek-xkb-layout.h b/eek/eek-xkb-layout.h index fe9dbb84..2b2791fb 100644 --- a/eek/eek-xkb-layout.h +++ b/eek/eek-xkb-layout.h @@ -60,35 +60,29 @@ struct _EekXkbLayoutClass gpointer pdummy[24]; }; -GType eek_xkb_layout_get_type (void) G_GNUC_CONST; -EekLayout *eek_xkb_layout_new (void); +GType eek_xkb_layout_get_type (void) G_GNUC_CONST; +EekLayout *eek_xkb_layout_new (Display *display, + GError **error); -gboolean eek_xkb_layout_set_names (EekXkbLayout *layout, - XkbComponentNamesRec *names); +gboolean eek_xkb_layout_set_names (EekXkbLayout *layout, + XkbComponentNamesRec *names); -gboolean eek_xkb_layout_set_names_full - (EekXkbLayout *layout, - ...); -gboolean eek_xkb_layout_set_names_full_valist - (EekXkbLayout *layout, - va_list var_args); +gboolean eek_xkb_layout_set_names_full (EekXkbLayout *layout, + ...); +gboolean eek_xkb_layout_set_names_full_valist + (EekXkbLayout *layout, + va_list var_args); -gboolean eek_xkb_layout_set_keycodes - (EekXkbLayout *layout, - const gchar *keycodes); -gboolean eek_xkb_layout_set_geometry - (EekXkbLayout *layout, - const gchar *geometry); -gboolean eek_xkb_layout_set_symbols - (EekXkbLayout *layout, - const gchar *symbols); +gboolean eek_xkb_layout_set_keycodes (EekXkbLayout *layout, + const gchar *keycodes); +gboolean eek_xkb_layout_set_geometry (EekXkbLayout *layout, + const gchar *geometry); +gboolean eek_xkb_layout_set_symbols (EekXkbLayout *layout, + const gchar *symbols); -G_CONST_RETURN gchar *eek_xkb_layout_get_keycodes - (EekXkbLayout *layout); -G_CONST_RETURN gchar *eek_xkb_layout_get_geometry - (EekXkbLayout *layout); -G_CONST_RETURN gchar *eek_xkb_layout_get_symbols - (EekXkbLayout *layout); +const gchar *eek_xkb_layout_get_keycodes (EekXkbLayout *layout); +const gchar *eek_xkb_layout_get_geometry (EekXkbLayout *layout); +const gchar *eek_xkb_layout_get_symbols (EekXkbLayout *layout); G_END_DECLS #endif /* #ifndef EEK_XKB_LAYOUT_H */ diff --git a/eek/eek-xkl-layout.c b/eek/eek-xkl-layout.c index 8bbc4053..57725e9a 100644 --- a/eek/eek-xkl-layout.c +++ b/eek/eek-xkl-layout.c @@ -31,14 +31,20 @@ #endif /* HAVE_CONFIG_H */ #include -#include +#include #include #include "eek-xkl-layout.h" #define noKBDRAW_DEBUG -G_DEFINE_TYPE (EekXklLayout, eek_xkl_layout, EEK_TYPE_XKB_LAYOUT); +static GInitableIface *parent_initable_iface; + +static void initable_iface_init (GInitableIface *initable_iface); + +G_DEFINE_TYPE_WITH_CODE (EekXklLayout, eek_xkl_layout, EEK_TYPE_XKB_LAYOUT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + initable_iface_init)); #define EEK_XKL_LAYOUT_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayoutPrivate)) @@ -93,6 +99,8 @@ eek_xkl_layout_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { + EekXklLayout *layout = EEK_XKL_LAYOUT(object); + switch (prop_id) { case PROP_MODEL: @@ -112,9 +120,6 @@ eek_xkl_layout_set_property (GObject *object, g_value_get_boxed (value)); break; default: - g_object_set_property (object, - g_param_spec_get_name (pspec), - value); break; } } @@ -125,6 +130,8 @@ eek_xkl_layout_get_property (GObject *object, GValue *value, GParamSpec *pspec) { + EekXklLayout *layout = EEK_XKL_LAYOUT(object); + switch (prop_id) { case PROP_MODEL: @@ -148,9 +155,6 @@ eek_xkl_layout_get_property (GObject *object, eek_xkl_layout_get_options (EEK_XKL_LAYOUT(object))); break; default: - g_object_get_property (object, - g_param_spec_get_name (pspec), - value); break; } } @@ -219,18 +223,7 @@ eek_xkl_layout_class_init (EekXklLayoutClass *klass) static void eek_xkl_layout_init (EekXklLayout *self) { - EekXklLayoutPrivate *priv; - Display *display; - - priv = self->priv = EEK_XKL_LAYOUT_GET_PRIVATE (self); - priv->config = xkl_config_rec_new (); - - display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - g_return_if_fail (display); - - priv->engine = xkl_engine_get_instance (display); - xkl_config_rec_get_from_server (priv->config, priv->engine); - set_xkb_component_names (self, priv->config); + self->priv = EEK_XKL_LAYOUT_GET_PRIVATE (self); } /** @@ -239,9 +232,13 @@ eek_xkl_layout_init (EekXklLayout *self) * Create a new #EekXklLayout. */ EekLayout * -eek_xkl_layout_new (void) +eek_xkl_layout_new (Display *display, GError **error) { - return g_object_new (EEK_TYPE_XKL_LAYOUT, NULL); + return (EekLayout *) g_initable_new (EEK_TYPE_XKL_LAYOUT, + NULL, + error, + "display", display, + NULL); } G_INLINE_FUNC void @@ -627,3 +624,42 @@ eek_xkl_layout_get_option (EekXklLayout *layout, return TRUE; return FALSE; } + +static gboolean +initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + EekXklLayout *layout = EEK_XKL_LAYOUT (initable); + Display *display; + + if (!parent_initable_iface->init (initable, cancellable, error)) + return FALSE; + + layout->priv->config = xkl_config_rec_new (); + + g_object_get (G_OBJECT (initable), + "display", &display, + NULL); + + layout->priv->engine = xkl_engine_get_instance (display); + + if (!xkl_config_rec_get_from_server (layout->priv->config, + layout->priv->engine)) { + g_set_error (error, + EEK_ERROR, + EEK_ERROR_LAYOUT_ERROR, + "can't load libxklavier configuration"); + return FALSE; + } + + return set_xkb_component_names (layout, layout->priv->config); +} + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + parent_initable_iface = g_type_interface_peek_parent (initable_iface); + initable_iface->init = initable_init; +} + diff --git a/eek/eek-xkl-layout.h b/eek/eek-xkl-layout.h index c402a2b8..966b2918 100644 --- a/eek/eek-xkl-layout.h +++ b/eek/eek-xkl-layout.h @@ -61,7 +61,8 @@ struct _EekXklLayoutClass GType eek_xkl_layout_get_type (void) G_GNUC_CONST; -EekLayout *eek_xkl_layout_new (void); +EekLayout *eek_xkl_layout_new (Display *display, + GError **error); gboolean eek_xkl_layout_set_config (EekXklLayout *layout, XklConfigRec *config); diff --git a/eekboard/eekboard-context-service.c b/eekboard/eekboard-context-service.c index 83b61021..f833b670 100644 --- a/eekboard/eekboard-context-service.c +++ b/eekboard/eekboard-context-service.c @@ -153,6 +153,8 @@ static const GDBusInterfaceVTable interface_vtable = NULL }; +static Display *display = NULL; + static EekKeyboard * eekboard_context_service_real_create_keyboard (EekboardContextService *self, const gchar *keyboard_type) @@ -163,8 +165,19 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self, if (g_str_has_prefix (keyboard_type, "xkb:")) { XklConfigRec *rec = eekboard_xkl_config_rec_from_string (&keyboard_type[4]); + GError *error; + + if (display == NULL) + display = XOpenDisplay (NULL); + + error = NULL; + layout = eek_xkl_layout_new (display, &error); + if (layout == NULL) { + g_warning ("can't create keyboard: %s", error->message); + g_error_free (error); + return NULL; + } - layout = eek_xkl_layout_new (); if (!eek_xkl_layout_set_config (EEK_XKL_LAYOUT(layout), rec)) { g_object_unref (layout); return NULL; diff --git a/tests/eek-xml-test.c b/tests/eek-xml-test.c index 49d7e059..ae2debe6 100644 --- a/tests/eek-xml-test.c +++ b/tests/eek-xml-test.c @@ -35,10 +35,12 @@ test_output_parse (void) GInputStream *input; EekLayout *layout; EekKeyboard *keyboard; + Display *display; output = g_string_sized_new (8192); - layout = eek_xkl_layout_new (); + display = XOpenDisplay (NULL); + layout = eek_xkl_layout_new (display, NULL); keyboard = eek_keyboard_new (layout, 640, 480); g_object_unref (layout);