Check errors when retrieving XKB layout information.

This commit is contained in:
Daiki Ueno
2012-04-24 11:50:00 +09:00
parent cce883808e
commit b5b59e77d6
3 changed files with 76 additions and 100 deletions

View File

@ -44,7 +44,11 @@
#include "eek-key.h" #include "eek-key.h"
#include "eek-keysym.h" #include "eek-keysym.h"
#define noKBDRAW_DEBUG #define XKB_COMPONENT_MASK (XkbGBN_GeometryMask | \
XkbGBN_KeyNamesMask | \
XkbGBN_OtherNamesMask | \
XkbGBN_SymbolsMask | \
XkbGBN_IndicatorMapMask)
static void initable_iface_init (GInitableIface *initable_iface); static void initable_iface_init (GInitableIface *initable_iface);
@ -80,19 +84,18 @@ struct _EekXkbLayoutPrivate
gint scale_denominator; gint scale_denominator;
}; };
static guint static guint find_keycode (EekXkbLayout *layout,
find_keycode (EekXkbLayout *layout, gchar *key_name); gchar *key_name);
static void static gboolean get_keyboard_from_server (EekXkbLayout *layout,
get_keyboard (EekXkbLayout *layout); GError **error);
static void static gboolean get_names_from_server (EekXkbLayout *layout,
get_names (EekXkbLayout *layout); GError **error);
static void static void setup_scaling (EekXkbLayout *layout,
setup_scaling (EekXkbLayout *layout, gdouble width,
gdouble width, gdouble height);
gdouble height);
G_INLINE_FUNC gint G_INLINE_FUNC gint
xkb_to_pixmap_coord (EekXkbLayout *layout, xkb_to_pixmap_coord (EekXkbLayout *layout,
@ -146,7 +149,8 @@ create_key (EekXkbLayout *layout,
xkbshape->primary; xkbshape->primary;
outline = g_slice_new (EekOutline); outline = g_slice_new (EekOutline);
outline->corner_radius = xkb_to_pixmap_coord(layout, xkboutline->corner_radius); outline->corner_radius = xkb_to_pixmap_coord(layout,
xkboutline->corner_radius);
if (xkboutline->num_points <= 2) { /* rectangular */ if (xkboutline->num_points <= 2) { /* rectangular */
gdouble x1, y1, x2, y2; gdouble x1, y1, x2, y2;
@ -425,8 +429,9 @@ eek_xkb_layout_init (EekXkbLayout *self)
self->priv = EEK_XKB_LAYOUT_GET_PRIVATE (self); self->priv = EEK_XKB_LAYOUT_GET_PRIVATE (self);
} }
static void static gboolean
get_names (EekXkbLayout *layout) get_names_from_server (EekXkbLayout *layout,
GError **error)
{ {
EekXkbLayoutPrivate *priv = layout->priv; EekXkbLayoutPrivate *priv = layout->priv;
gchar *name; gchar *name;
@ -474,6 +479,8 @@ get_names (EekXkbLayout *layout)
XFree (name); XFree (name);
} }
} }
return TRUE;
} }
/** /**
@ -496,78 +503,76 @@ eek_xkb_layout_new (Display *display,
* eek_xkb_layout_set_names: (skip) * eek_xkb_layout_set_names: (skip)
* @layout: an #EekXkbLayout * @layout: an #EekXkbLayout
* @names: XKB component names * @names: XKB component names
* @error: a #GError
* *
* Set the XKB component names to @layout. * Set the XKB component names to @layout.
* Returns: %TRUE if any of the component names changed, %FALSE otherwise * Returns: %TRUE if the component names are successfully set, %FALSE otherwise
*/ */
gboolean gboolean
eek_xkb_layout_set_names (EekXkbLayout *layout, XkbComponentNamesRec *names) eek_xkb_layout_set_names (EekXkbLayout *layout,
XkbComponentNamesRec *names,
GError **error)
{ {
EekXkbLayoutPrivate *priv = EEK_XKB_LAYOUT_GET_PRIVATE (layout); if (g_strcmp0 (names->keycodes, layout->priv->names.keycodes)) {
gboolean retval; g_free (layout->priv->names.keycodes);
layout->priv->names.keycodes = g_strdup (names->keycodes);
if (g_strcmp0 (names->keycodes, priv->names.keycodes)) {
g_free (priv->names.keycodes);
priv->names.keycodes = g_strdup (names->keycodes);
retval = TRUE;
} }
if (g_strcmp0 (names->geometry, priv->names.geometry)) { if (g_strcmp0 (names->geometry, layout->priv->names.geometry)) {
g_free (priv->names.geometry); g_free (layout->priv->names.geometry);
priv->names.geometry = g_strdup (names->geometry); layout->priv->names.geometry = g_strdup (names->geometry);
retval = TRUE;
} }
if (g_strcmp0 (names->symbols, priv->names.symbols)) { if (g_strcmp0 (names->symbols, layout->priv->names.symbols)) {
g_free (priv->names.symbols); g_free (layout->priv->names.symbols);
priv->names.symbols = g_strdup (names->symbols); layout->priv->names.symbols = g_strdup (names->symbols);
retval = TRUE;
} }
get_keyboard (layout); return get_keyboard_from_server (layout, error);
g_assert (priv->xkb);
return retval;
} }
static void static gboolean
get_keyboard (EekXkbLayout *layout) get_keyboard_from_server (EekXkbLayout *layout,
GError **error)
{ {
EekXkbLayoutPrivate *priv = layout->priv; EekXkbLayoutPrivate *priv = layout->priv;
if (priv->xkb) if (priv->xkb) {
XkbFreeKeyboard (priv->xkb, 0, TRUE); /* free_all = TRUE */ XkbFreeKeyboard (priv->xkb, 0, True);
priv->xkb = NULL; priv->xkb = NULL;
}
if (priv->names.keycodes && if (priv->names.keycodes && priv->names.geometry && priv->names.symbols) {
priv->names.geometry && priv->xkb = XkbGetKeyboardByName (priv->display,
priv->names.symbols) { XkbUseCoreKbd,
priv->xkb = XkbGetKeyboardByName (priv->display, XkbUseCoreKbd, &priv->names,
&priv->names, 0, 0,
XkbGBN_GeometryMask | XKB_COMPONENT_MASK,
XkbGBN_KeyNamesMask | False);
XkbGBN_OtherNamesMask |
XkbGBN_ClientSymbolsMask |
XkbGBN_IndicatorMapMask, FALSE);
} else { } else {
priv->xkb = XkbGetKeyboard (priv->display, priv->xkb = XkbGetKeyboard (priv->display,
XkbGBN_GeometryMask | XKB_COMPONENT_MASK,
XkbGBN_KeyNamesMask |
XkbGBN_OtherNamesMask |
XkbGBN_SymbolsMask |
XkbGBN_IndicatorMapMask,
XkbUseCoreKbd); XkbUseCoreKbd);
get_names (layout); if (!get_names_from_server (layout, error)) {
XkbFreeKeyboard (priv->xkb, 0, True);
priv->xkb = NULL;
}
} }
if (priv->xkb == NULL) { if (priv->xkb == NULL) {
g_set_error (error,
EEK_ERROR,
EEK_ERROR_LAYOUT_ERROR,
"can't get keyboard from server");
g_free (priv->names.keycodes); g_free (priv->names.keycodes);
priv->names.keycodes = NULL; priv->names.keycodes = NULL;
g_free (priv->names.geometry); g_free (priv->names.geometry);
priv->names.geometry = NULL; priv->names.geometry = NULL;
g_free (priv->names.symbols); g_free (priv->names.symbols);
priv->names.symbols = NULL; priv->names.symbols = NULL;
return FALSE;
} }
return TRUE;
} }
@ -586,11 +591,6 @@ find_keycode (EekXkbLayout *layout, gchar *key_name)
if (!priv->xkb) if (!priv->xkb)
return EEK_INVALID_KEYCODE; return EEK_INVALID_KEYCODE;
#ifdef KBDRAW_DEBUG
printf (" looking for keycode for (%c%c%c%c)\n",
key_name[0], key_name[1], key_name[2], key_name[3]);
#endif
pkey = priv->xkb->names->keys + priv->xkb->min_key_code; pkey = priv->xkb->names->keys + priv->xkb->min_key_code;
for (keycode = priv->xkb->min_key_code; for (keycode = priv->xkb->min_key_code;
keycode <= priv->xkb->max_key_code; keycode++) { keycode <= priv->xkb->max_key_code; keycode++) {
@ -605,12 +605,8 @@ find_keycode (EekXkbLayout *layout, gchar *key_name)
break; break;
} }
} }
if (is_name_matched) { if (is_name_matched)
#ifdef KBDRAW_DEBUG
printf (" found keycode %u\n", keycode);
#endif
return keycode; return keycode;
}
pkey++; pkey++;
} }
@ -630,9 +626,6 @@ find_keycode (EekXkbLayout *layout, gchar *key_name)
if (is_name_matched) { if (is_name_matched) {
keycode = find_keycode (layout, palias->real); keycode = find_keycode (layout, palias->real);
#ifdef KBDRAW_DEBUG
printf ("found alias keycode %u\n", keycode);
#endif
return keycode; return keycode;
} }
palias++; palias++;
@ -670,34 +663,11 @@ initable_init (GInitable *initable,
{ {
EekXkbLayout *layout = EEK_XKB_LAYOUT (initable); EekXkbLayout *layout = EEK_XKB_LAYOUT (initable);
/* XXX: XkbClientMapMask | XkbIndicatorMapMask | XkbNamesMask | if (!get_keyboard_from_server (layout, error))
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; return FALSE;
}
get_names (layout); if (!get_names_from_server (layout, error))
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 FALSE;
}
return TRUE; return TRUE;
} }

View File

@ -60,12 +60,13 @@ struct _EekXkbLayoutClass
gpointer pdummy[24]; gpointer pdummy[24];
}; };
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 (Display *display, EekLayout *eek_xkb_layout_new (Display *display,
GError **error); GError **error);
gboolean eek_xkb_layout_set_names (EekXkbLayout *layout, gboolean eek_xkb_layout_set_names (EekXkbLayout *layout,
XkbComponentNamesRec *names); XkbComponentNamesRec *names,
GError **error);
G_END_DECLS G_END_DECLS
#endif /* #ifndef EEK_XKB_LAYOUT_H */ #endif /* #ifndef EEK_XKB_LAYOUT_H */

View File

@ -589,7 +589,12 @@ set_xkb_component_names (EekXklLayout *layout, XklConfigRec *config)
#endif #endif
if (xkl_xkb_config_native_prepare (priv->engine, config, &names)) { if (xkl_xkb_config_native_prepare (priv->engine, config, &names)) {
retval = eek_xkb_layout_set_names (EEK_XKB_LAYOUT(layout), &names); GError *error = NULL;
retval = eek_xkb_layout_set_names (EEK_XKB_LAYOUT(layout),
&names,
&error);
if (!retval)
g_warning ("can't set XKB layout");
xkl_xkb_config_native_cleanup (priv->engine, &names); xkl_xkb_config_native_cleanup (priv->engine, &names);
} }
return retval; return retval;