config: override xkb_{r,m,l,v} with Xkb{r,m,l,v} if the latter is set.
The HAL spec says that input.xkb.{rmlv}* can be sent, but if the user
specifies a X-specific {rmlv}, then this is overridden through the use of
input.x11_options.Xkb{RMLV}.
However, the way how the server parses options--by ignoring capitalisation,
underscores and spaces--the HAL and the x11_options would override each other.
So we simply filter the options, letting Xkb{RMLV} override xkb_{rmlv} and
only actually add them to the device after parsing _all_ options.
* rmlv ... rules, model, layout, variant
See Bug 13037 <http://bugs.freedesktop.org/show_bug.cgi?id=13037>
(cherry picked from commit fc35d1e3be
)
This commit is contained in:
parent
901978ebe0
commit
ff013b0da4
100
config/hal.c
100
config/hal.c
|
@ -48,6 +48,15 @@ struct config_hal_info {
|
||||||
LibHalContext *hal_ctx;
|
LibHalContext *hal_ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Used for special handling of xkb options. */
|
||||||
|
struct xkb_options {
|
||||||
|
char* layout;
|
||||||
|
char* model;
|
||||||
|
char* rules;
|
||||||
|
char* variant;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remove_device(DeviceIntPtr dev)
|
remove_device(DeviceIntPtr dev)
|
||||||
{
|
{
|
||||||
|
@ -164,10 +173,11 @@ device_added(LibHalContext *hal_ctx, const char *udi)
|
||||||
InputOption *options = NULL, *tmpo = NULL;
|
InputOption *options = NULL, *tmpo = NULL;
|
||||||
DeviceIntPtr dev;
|
DeviceIntPtr dev;
|
||||||
DBusError error;
|
DBusError error;
|
||||||
|
struct xkb_options xkb_opts = {0};
|
||||||
|
|
||||||
LibHalPropertySet *set = NULL;
|
LibHalPropertySet *set = NULL;
|
||||||
LibHalPropertySetIterator set_iter;
|
LibHalPropertySetIterator set_iter;
|
||||||
char *psi_key = NULL, *tmp_val, *tmp_key;
|
char *psi_key = NULL, *tmp_val;
|
||||||
|
|
||||||
|
|
||||||
dbus_error_init(&error);
|
dbus_error_init(&error);
|
||||||
|
@ -241,27 +251,71 @@ device_added(LibHalContext *hal_ctx, const char *udi)
|
||||||
tmp_val = get_prop_string(hal_ctx, udi, psi_key);
|
tmp_val = get_prop_string(hal_ctx, udi, psi_key);
|
||||||
|
|
||||||
if (tmp_val){
|
if (tmp_val){
|
||||||
add_option(&options, psi_key + sizeof(LIBHAL_PROP_KEY)-1, tmp_val);
|
char* tmp;
|
||||||
xfree(tmp_val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* evdev's XKB options... we should probably depreciate this usage */
|
/* xkb needs special handling. HAL specs include
|
||||||
|
* input.xkb.xyz options, but the x11-input.fdi specifies
|
||||||
|
* input.x11_options.Xkbxyz options. By default, we use
|
||||||
|
* the former, unless the specific X11 ones are specified.
|
||||||
|
* Since we can't predict the order in which the keys
|
||||||
|
* arrive, we need to store them.
|
||||||
|
*/
|
||||||
|
if ((tmp = strcasestr(psi_key, "xkb")))
|
||||||
|
{
|
||||||
|
if (!strcasecmp(&tmp[3], "layout"))
|
||||||
|
{
|
||||||
|
if (xkb_opts.layout)
|
||||||
|
xfree(xkb_opts.layout);
|
||||||
|
xkb_opts.layout = strdup(tmp_val);
|
||||||
|
} else if (!strcasecmp(&tmp[3], "model"))
|
||||||
|
{
|
||||||
|
if (xkb_opts.model)
|
||||||
|
xfree(xkb_opts.model);
|
||||||
|
xkb_opts.model = strdup(tmp_val);
|
||||||
|
} else if (!strcasecmp(&tmp[3], "rules"))
|
||||||
|
{
|
||||||
|
if (xkb_opts.rules)
|
||||||
|
xfree(xkb_opts.rules);
|
||||||
|
xkb_opts.rules = strdup(tmp_val);
|
||||||
|
} else if (!strcasecmp(&tmp[3], "variant"))
|
||||||
|
{
|
||||||
|
if (xkb_opts.variant)
|
||||||
|
xfree(xkb_opts.variant);
|
||||||
|
xkb_opts.variant = strdup(tmp_val);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
/* all others */
|
||||||
|
add_option(&options, psi_key + sizeof(LIBHAL_PROP_KEY)-1, tmp_val);
|
||||||
|
xfree(tmp_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (!strncasecmp(psi_key, LIBHAL_XKB_PROP_KEY, sizeof(LIBHAL_XKB_PROP_KEY)-1)){
|
} else if (!strncasecmp(psi_key, LIBHAL_XKB_PROP_KEY, sizeof(LIBHAL_XKB_PROP_KEY)-1)){
|
||||||
|
|
||||||
/* only support strings for all values */
|
/* only support strings for all values */
|
||||||
tmp_val = get_prop_string(hal_ctx, udi, psi_key);
|
tmp_val = get_prop_string(hal_ctx, udi, psi_key);
|
||||||
|
|
||||||
if (tmp_val){
|
if (tmp_val){
|
||||||
/* add "xkb_" + NULL */
|
char* tmp;
|
||||||
tmp_key = xalloc(strlen(psi_key) - ( sizeof(LIBHAL_XKB_PROP_KEY) - 1) + 5);
|
|
||||||
|
|
||||||
if (!tmp_key){
|
tmp = &psi_key[sizeof(LIBHAL_XKB_PROP_KEY) - 1];
|
||||||
LogMessage(X_ERROR, "config/hal: couldn't allocate memory for option %s\n", psi_key);
|
|
||||||
} else {
|
|
||||||
sprintf(tmp_key, "xkb_%s", psi_key + sizeof(LIBHAL_XKB_PROP_KEY)-1);
|
|
||||||
add_option(&options, tmp_key, tmp_val);
|
|
||||||
|
|
||||||
xfree(tmp_key);
|
if (!strcasecmp(tmp, "layout"))
|
||||||
|
{
|
||||||
|
if (!xkb_opts.layout)
|
||||||
|
xkb_opts.layout = strdup(tmp_val);
|
||||||
|
} else if (!strcasecmp(tmp, "rules"))
|
||||||
|
{
|
||||||
|
if (!xkb_opts.rules)
|
||||||
|
xkb_opts.rules = strdup(tmp_val);
|
||||||
|
} else if (!strcasecmp(tmp, "variant"))
|
||||||
|
{
|
||||||
|
if (!xkb_opts.variant)
|
||||||
|
xkb_opts.variant = strdup(tmp_val);
|
||||||
|
} else if (!strcasecmp(tmp, "model"))
|
||||||
|
{
|
||||||
|
if (!xkb_opts.model)
|
||||||
|
xkb_opts.model = strdup(tmp_val);
|
||||||
}
|
}
|
||||||
xfree(tmp_val);
|
xfree(tmp_val);
|
||||||
}
|
}
|
||||||
|
@ -272,6 +326,17 @@ device_added(LibHalContext *hal_ctx, const char *udi)
|
||||||
libhal_psi_next(&set_iter);
|
libhal_psi_next(&set_iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Now add xkb options */
|
||||||
|
if (xkb_opts.layout)
|
||||||
|
add_option(&options, "xkb_layout", xkb_opts.layout);
|
||||||
|
if (xkb_opts.rules)
|
||||||
|
add_option(&options, "xkb_rules", xkb_opts.rules);
|
||||||
|
if (xkb_opts.variant)
|
||||||
|
add_option(&options, "xkb_variant", xkb_opts.variant);
|
||||||
|
if (xkb_opts.model)
|
||||||
|
add_option(&options, "xkb_model", xkb_opts.model);
|
||||||
|
|
||||||
/* this isn't an error, but how else do you output something that the user can see? */
|
/* this isn't an error, but how else do you output something that the user can see? */
|
||||||
LogMessage(X_INFO, "config/hal: Adding input device %s\n", name);
|
LogMessage(X_INFO, "config/hal: Adding input device %s\n", name);
|
||||||
if (NewInputDeviceRequest(options, &dev) != Success) {
|
if (NewInputDeviceRequest(options, &dev) != Success) {
|
||||||
|
@ -304,6 +369,15 @@ unwind:
|
||||||
xfree(tmpo);
|
xfree(tmpo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (xkb_opts.layout)
|
||||||
|
xfree(xkb_opts.layout);
|
||||||
|
if (xkb_opts.rules)
|
||||||
|
xfree(xkb_opts.rules);
|
||||||
|
if (xkb_opts.model)
|
||||||
|
xfree(xkb_opts.model);
|
||||||
|
if (xkb_opts.variant)
|
||||||
|
xfree(xkb_opts.variant);
|
||||||
|
|
||||||
dbus_error_free(&error);
|
dbus_error_free(&error);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user