Use GInitable to define EekXklLayout.

This commit is contained in:
Daiki Ueno
2012-03-16 17:36:20 +09:00
parent 32a1d23c2a
commit a6fe5bd859
9 changed files with 224 additions and 132 deletions

View File

@ -121,8 +121,8 @@ libeek_xkl_sources = \
$(srcdir)/eek-xkl-layout.c $(srcdir)/eek-xkl-layout.c
libeek_xkl_la_SOURCES = $(libeek_xkl_sources) libeek_xkl_la_SOURCES = $(libeek_xkl_sources)
libeek_xkl_la_CFLAGS = -DEEK_COMPILATION=1 $(LIBXKLAVIER_CFLAGS) $(GTK_CFLAGS) libeek_xkl_la_CFLAGS = -DEEK_COMPILATION=1 $(LIBXKLAVIER_CFLAGS)
libeek_xkl_la_LIBADD = libeek.la $(LIBXKLAVIER_LIBS) $(GTK_LIBS) libeek_xkl_la_LIBADD = libeek.la $(LIBXKLAVIER_LIBS)
eekdir = $(includedir)/eek-$(EEK_API_VERSION)/eek eekdir = $(includedir)/eek-$(EEK_API_VERSION)/eek
eek_HEADERS = \ eek_HEADERS = \

View File

@ -128,3 +128,9 @@ eek_color_new (gdouble red,
return color; return color;
} }
GQuark
eek_error_quark (void)
{
return g_quark_from_static_string ("eek-error-quark");
}

View File

@ -253,5 +253,13 @@ typedef enum {
EEK_GRADIENT_RADIAL EEK_GRADIENT_RADIAL
} EekGradientType; } 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 G_END_DECLS
#endif /* EEK_TYPES_H */ #endif /* EEK_TYPES_H */

View File

@ -31,11 +31,12 @@
#include "config.h" #include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <gdk/gdkx.h> #include <X11/keysym.h>
#include <X11/XKBlib.h> #include <X11/XKBlib.h>
#include <X11/extensions/XKBgeom.h> #include <X11/extensions/XKBgeom.h>
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include <gio/gio.h>
#include "eek-xkb-layout.h" #include "eek-xkb-layout.h"
#include "eek-keyboard.h" #include "eek-keyboard.h"
@ -45,13 +46,18 @@
#define noKBDRAW_DEBUG #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) \ #define EEK_XKB_LAYOUT_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKB_LAYOUT, EekXkbLayoutPrivate))
enum { enum {
PROP_0, PROP_0,
PROP_DISPLAY,
PROP_KEYCODES, PROP_KEYCODES,
PROP_GEOMETRY, PROP_GEOMETRY,
PROP_SYMBOLS, PROP_SYMBOLS,
@ -360,10 +366,13 @@ eek_xkb_layout_set_property (GObject *object,
const GValue *value, const GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
EekXkbLayout *layout = EEK_XKB_LAYOUT (object);
const gchar *name; const gchar *name;
switch (prop_id) switch (prop_id) {
{ case PROP_DISPLAY:
layout->priv->display = g_value_get_pointer (value);
break;
case PROP_KEYCODES: case PROP_KEYCODES:
name = g_value_get_string (value); name = g_value_get_string (value);
eek_xkb_layout_set_keycodes (EEK_XKB_LAYOUT(object), name); eek_xkb_layout_set_keycodes (EEK_XKB_LAYOUT(object), name);
@ -377,9 +386,6 @@ eek_xkb_layout_set_property (GObject *object,
eek_xkb_layout_set_symbols (EEK_XKB_LAYOUT(object), name); eek_xkb_layout_set_symbols (EEK_XKB_LAYOUT(object), name);
break; break;
default: default:
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break; break;
} }
} }
@ -390,10 +396,13 @@ eek_xkb_layout_get_property (GObject *object,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
EekXkbLayout *layout = EEK_XKB_LAYOUT (object);
const gchar *name; const gchar *name;
switch (prop_id) switch (prop_id) {
{ case PROP_DISPLAY:
g_value_set_pointer (value, layout->priv->display);
break;
case PROP_KEYCODES: case PROP_KEYCODES:
name = eek_xkb_layout_get_keycodes (EEK_XKB_LAYOUT(object)); name = eek_xkb_layout_get_keycodes (EEK_XKB_LAYOUT(object));
g_value_set_string (value, name); g_value_set_string (value, name);
@ -407,9 +416,6 @@ eek_xkb_layout_get_property (GObject *object,
g_value_set_string (value, name); g_value_set_string (value, name);
break; break;
default: default:
g_object_get_property (object,
g_param_spec_get_name (pspec),
value);
break; break;
} }
} }
@ -429,6 +435,13 @@ eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
gobject_class->set_property = eek_xkb_layout_set_property; gobject_class->set_property = eek_xkb_layout_set_property;
gobject_class->get_property = eek_xkb_layout_get_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", pspec = g_param_spec_string ("keycodes",
"Keycodes", "Keycodes",
"XKB keycodes component name", "XKB keycodes component name",
@ -454,28 +467,7 @@ eek_xkb_layout_class_init (EekXkbLayoutClass *klass)
static void static void
eek_xkb_layout_init (EekXkbLayout *self) eek_xkb_layout_init (EekXkbLayout *self)
{ {
EekXkbLayoutPrivate *priv; self->priv = EEK_XKB_LAYOUT_GET_PRIVATE (self);
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);
} }
static void static void
@ -535,19 +527,14 @@ get_names (EekXkbLayout *layout)
* Create a new #EekXkbLayout. * Create a new #EekXkbLayout.
*/ */
EekLayout * EekLayout *
eek_xkb_layout_new (void) eek_xkb_layout_new (Display *display,
GError **error)
{ {
EekXkbLayout *layout; return (EekLayout *) g_initable_new (EEK_TYPE_XKB_LAYOUT,
NULL,
layout = g_object_new (EEK_TYPE_XKB_LAYOUT, NULL); error,
g_return_val_if_fail (layout, NULL); "display", display,
NULL);
get_keyboard (layout);
if (layout->priv->xkb == NULL) {
g_object_unref (layout);
return NULL;
}
return EEK_LAYOUT(layout);
} }
/** /**
@ -894,3 +881,48 @@ setup_scaling (EekXkbLayout *layout,
priv->scale_denominator = priv->xkb->geom->height_mm; 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;
}

View File

@ -61,34 +61,28 @@ struct _EekXkbLayoutClass
}; };
GType eek_xkb_layout_get_type (void) G_GNUC_CONST; GType eek_xkb_layout_get_type (void) G_GNUC_CONST;
EekLayout *eek_xkb_layout_new (void); EekLayout *eek_xkb_layout_new (Display *display,
GError **error);
gboolean eek_xkb_layout_set_names (EekXkbLayout *layout, gboolean eek_xkb_layout_set_names (EekXkbLayout *layout,
XkbComponentNamesRec *names); XkbComponentNamesRec *names);
gboolean eek_xkb_layout_set_names_full gboolean eek_xkb_layout_set_names_full (EekXkbLayout *layout,
(EekXkbLayout *layout,
...); ...);
gboolean eek_xkb_layout_set_names_full_valist gboolean eek_xkb_layout_set_names_full_valist
(EekXkbLayout *layout, (EekXkbLayout *layout,
va_list var_args); va_list var_args);
gboolean eek_xkb_layout_set_keycodes gboolean eek_xkb_layout_set_keycodes (EekXkbLayout *layout,
(EekXkbLayout *layout,
const gchar *keycodes); const gchar *keycodes);
gboolean eek_xkb_layout_set_geometry gboolean eek_xkb_layout_set_geometry (EekXkbLayout *layout,
(EekXkbLayout *layout,
const gchar *geometry); const gchar *geometry);
gboolean eek_xkb_layout_set_symbols gboolean eek_xkb_layout_set_symbols (EekXkbLayout *layout,
(EekXkbLayout *layout,
const gchar *symbols); const gchar *symbols);
G_CONST_RETURN gchar *eek_xkb_layout_get_keycodes const gchar *eek_xkb_layout_get_keycodes (EekXkbLayout *layout);
(EekXkbLayout *layout); const gchar *eek_xkb_layout_get_geometry (EekXkbLayout *layout);
G_CONST_RETURN gchar *eek_xkb_layout_get_geometry const gchar *eek_xkb_layout_get_symbols (EekXkbLayout *layout);
(EekXkbLayout *layout);
G_CONST_RETURN gchar *eek_xkb_layout_get_symbols
(EekXkbLayout *layout);
G_END_DECLS G_END_DECLS
#endif /* #ifndef EEK_XKB_LAYOUT_H */ #endif /* #ifndef EEK_XKB_LAYOUT_H */

View File

@ -31,14 +31,20 @@
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <libxklavier/xklavier.h> #include <libxklavier/xklavier.h>
#include <gdk/gdkx.h> #include <gio/gio.h>
#include <string.h> #include <string.h>
#include "eek-xkl-layout.h" #include "eek-xkl-layout.h"
#define noKBDRAW_DEBUG #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) \ #define EEK_XKL_LAYOUT_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEK_TYPE_XKL_LAYOUT, EekXklLayoutPrivate)) (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, const GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
EekXklLayout *layout = EEK_XKL_LAYOUT(object);
switch (prop_id) switch (prop_id)
{ {
case PROP_MODEL: case PROP_MODEL:
@ -112,9 +120,6 @@ eek_xkl_layout_set_property (GObject *object,
g_value_get_boxed (value)); g_value_get_boxed (value));
break; break;
default: default:
g_object_set_property (object,
g_param_spec_get_name (pspec),
value);
break; break;
} }
} }
@ -125,6 +130,8 @@ eek_xkl_layout_get_property (GObject *object,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
EekXklLayout *layout = EEK_XKL_LAYOUT(object);
switch (prop_id) switch (prop_id)
{ {
case PROP_MODEL: case PROP_MODEL:
@ -148,9 +155,6 @@ eek_xkl_layout_get_property (GObject *object,
eek_xkl_layout_get_options (EEK_XKL_LAYOUT(object))); eek_xkl_layout_get_options (EEK_XKL_LAYOUT(object)));
break; break;
default: default:
g_object_get_property (object,
g_param_spec_get_name (pspec),
value);
break; break;
} }
} }
@ -219,18 +223,7 @@ eek_xkl_layout_class_init (EekXklLayoutClass *klass)
static void static void
eek_xkl_layout_init (EekXklLayout *self) eek_xkl_layout_init (EekXklLayout *self)
{ {
EekXklLayoutPrivate *priv; self->priv = EEK_XKL_LAYOUT_GET_PRIVATE (self);
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);
} }
/** /**
@ -239,9 +232,13 @@ eek_xkl_layout_init (EekXklLayout *self)
* Create a new #EekXklLayout. * Create a new #EekXklLayout.
*/ */
EekLayout * 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 G_INLINE_FUNC void
@ -627,3 +624,42 @@ eek_xkl_layout_get_option (EekXklLayout *layout,
return TRUE; return TRUE;
return FALSE; 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;
}

View File

@ -61,7 +61,8 @@ struct _EekXklLayoutClass
GType eek_xkl_layout_get_type (void) G_GNUC_CONST; 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, gboolean eek_xkl_layout_set_config (EekXklLayout *layout,
XklConfigRec *config); XklConfigRec *config);

View File

@ -153,6 +153,8 @@ static const GDBusInterfaceVTable interface_vtable =
NULL NULL
}; };
static Display *display = NULL;
static EekKeyboard * static EekKeyboard *
eekboard_context_service_real_create_keyboard (EekboardContextService *self, eekboard_context_service_real_create_keyboard (EekboardContextService *self,
const gchar *keyboard_type) const gchar *keyboard_type)
@ -163,8 +165,19 @@ eekboard_context_service_real_create_keyboard (EekboardContextService *self,
if (g_str_has_prefix (keyboard_type, "xkb:")) { if (g_str_has_prefix (keyboard_type, "xkb:")) {
XklConfigRec *rec = XklConfigRec *rec =
eekboard_xkl_config_rec_from_string (&keyboard_type[4]); 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)) { if (!eek_xkl_layout_set_config (EEK_XKL_LAYOUT(layout), rec)) {
g_object_unref (layout); g_object_unref (layout);
return NULL; return NULL;

View File

@ -35,10 +35,12 @@ test_output_parse (void)
GInputStream *input; GInputStream *input;
EekLayout *layout; EekLayout *layout;
EekKeyboard *keyboard; EekKeyboard *keyboard;
Display *display;
output = g_string_sized_new (8192); 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); keyboard = eek_keyboard_new (layout, 640, 480);
g_object_unref (layout); g_object_unref (layout);