Check errors when retrieving XKB layout information.
This commit is contained in:
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 */
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user