Exemplo n.º 1
0
static void
wscons_add_pointer(const char *path, const char *driver, int flags)
{
    InputAttributes attrs = { };
    DeviceIntPtr dev = NULL;
    InputOption *input_options = NULL;
    char *config_info = NULL;
    int rc;

    config_info = Xprintf("wscons:%s", path);
    if (!config_info)
        return;

    input_options = input_option_new(input_options, "_source", "server/wscons");
    if (input_options == NULL)
        return;

    input_options = input_option_new(input_options, "name", strdup(path));
    input_options = input_option_new(input_options, "driver", strdup(driver));
    input_options = input_option_new(input_options, "device", strdup(path));
    LogMessage(X_INFO, "config/wscons: checking input device %s\n", path);
    attrs.flags |= flags;
    rc = NewInputDeviceRequest(input_options, &attrs, &dev);
    if (rc != Success)
        goto unwind;

    for (; dev; dev = dev->next) {
        free(dev->config_info);
        dev->config_info = strdup(config_info);
    }
 unwind:
    input_option_free_list(&input_options);
}
Exemplo n.º 2
0
/**
 * Initialize all supported input devices present and referenced in the
 * xorg.conf.
 */
void
InitInput(int argc, char **argv)
{
    InputInfoPtr *pInfo;
    DeviceIntPtr dev;

    xf86Info.vtRequestsPending = FALSE;

    /* Enable threaded input */
    InputThreadPreInit();

    mieqInit();

    /* Initialize all configured input devices */
    for (pInfo = xf86ConfigLayout.inputs; pInfo && *pInfo; pInfo++) {
        (*pInfo)->options =
            xf86AddNewOption((*pInfo)->options, "driver", (*pInfo)->driver);
        (*pInfo)->options =
            xf86AddNewOption((*pInfo)->options, "identifier", (*pInfo)->name);
        /* If one fails, the others will too */
        if (NewInputDeviceRequest((*pInfo)->options, NULL, &dev) == BadAlloc)
            break;
    }

    config_init();
}
Exemplo n.º 3
0
/**
 * Initialize all supported input devices present and referenced in the
 * xorg.conf.
 */
void
InitInput(int argc, char **argv)
{
    InputInfoPtr* pInfo;
    DeviceIntPtr dev;

    xf86Info.vtRequestsPending = FALSE;

    mieqInit();

    /* Initialize all configured input devices */
    for (pInfo = xf86ConfigLayout.inputs; pInfo && *pInfo; pInfo++) {
        /* If one fails, the others will too */
        if (NewInputDeviceRequest((*pInfo)->options, NULL, &dev) == BadAlloc)
            break;
    }

    config_init();
}
Exemplo n.º 4
0
static void
device_added(LibHalContext *hal_ctx, const char *udi)
{
    char *path = NULL, *driver = NULL, *name = NULL, *config_info = NULL;
    InputOption *options = NULL, *tmpo = NULL;
    DeviceIntPtr dev = NULL;
    DBusError error;
    struct xkb_options xkb_opts = {0};
    int rc;

    LibHalPropertySet *set = NULL;
	LibHalPropertySetIterator set_iter;
    char *psi_key = NULL, *tmp_val;


    dbus_error_init(&error);

    driver = get_prop_string(hal_ctx, udi, "input.x11_driver");
    if (!driver){
        /* verbose, don't tell the user unless they _want_ to see it */
        LogMessageVerb(X_INFO,7,"config/hal: no driver specified for device %s\n", udi);
        goto unwind;
    }

    path = get_prop_string(hal_ctx, udi, "input.device");
    if (!path) {
        LogMessage(X_WARNING,"config/hal: no driver or path specified for %s\n", udi);
        goto unwind;
    }

    name = get_prop_string(hal_ctx, udi, "info.product");
    if (!name)
        name = xstrdup("(unnamed)");

    options = xcalloc(sizeof(*options), 1);
    if (!options){
        LogMessage(X_ERROR, "config/hal: couldn't allocate space for input options!\n");
        goto unwind;
    }

    options->key = xstrdup("_source");
    options->value = xstrdup("server/hal");
    if (!options->key || !options->value) {
        LogMessage(X_ERROR, "config/hal: couldn't allocate first key/value pair\n");
        goto unwind;
    }

    /* most drivers use device.. not path. evdev uses both however, but the
     * path version isn't documented apparently. support both for now. */
    add_option(&options, "path", path);
    add_option(&options, "device", path);

    add_option(&options, "driver", driver);
    add_option(&options, "name", name);

    config_info = xalloc(strlen(udi) + 5); /* "hal:" and NULL */
    if (!config_info) {
        LogMessage(X_ERROR, "config/hal: couldn't allocate name\n");
        goto unwind;
    }
    sprintf(config_info, "hal:%s", udi);

    /* Check for duplicate devices */
    if (device_is_duplicate(config_info))
    {
        LogMessage(X_WARNING, "config/hal: device %s already added. Ignoring.\n", name);
        goto unwind;
    }

    /* ok, grab options from hal.. iterate through all properties
    * and lets see if any of them are options that we can add */
    set = libhal_device_get_all_properties(hal_ctx, udi, &error);

    if (!set) {
        LogMessage(X_ERROR, "config/hal: couldn't get property list for %s: %s (%s)\n",
               udi, error.name, error.message);
        goto unwind;
    }

    libhal_psi_init(&set_iter,set);
    while (libhal_psi_has_more(&set_iter)) {
        /* we are looking for supported keys.. extract and add to options */
        psi_key = libhal_psi_get_key(&set_iter);

        if (psi_key){

            /* normal options first (input.x11_options.<propname>) */
            if (!strncasecmp(psi_key, LIBHAL_PROP_KEY, sizeof(LIBHAL_PROP_KEY)-1)){
                char* tmp;

                /* only support strings for all values */
                tmp_val = get_prop_string(hal_ctx, udi, psi_key);

                if (tmp_val){

                    /* 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")) && strlen(tmp) >= 4)
                    {
                        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 if (!strcasecmp(&tmp[3], "options"))
                        {
                            if (xkb_opts.options)
                                xfree(xkb_opts.options);
                            xkb_opts.options = strdup(tmp_val);
                        }
                    } else
                    {
                        /* all others */
                        add_option(&options, psi_key + sizeof(LIBHAL_PROP_KEY)-1, tmp_val);
                        xfree(tmp_val);
                    }
                } else
                {
                    /* server 1.4 had xkb_options as strlist. */
                    if ((tmp = strcasestr(psi_key, "xkb")) &&
                        (strlen(tmp) >= 4) &&
                        (!strcasecmp(&tmp[3], "options")) &&
                        (tmp_val = get_prop_string_array(hal_ctx, udi, psi_key)))
                    {
                        if (xkb_opts.options)
                            xfree(xkb_opts.options);
                        xkb_opts.options = strdup(tmp_val);
                    }
                }
            } else if (!strncasecmp(psi_key, LIBHAL_XKB_PROP_KEY, sizeof(LIBHAL_XKB_PROP_KEY)-1)){
                char* tmp;

                /* only support strings for all values */
                tmp_val = get_prop_string(hal_ctx, udi, psi_key);

                if (tmp_val && strlen(psi_key) >= sizeof(LIBHAL_XKB_PROP_KEY)) {

                    tmp = &psi_key[sizeof(LIBHAL_XKB_PROP_KEY) - 1];

                    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);
                    } else if (!strcasecmp(tmp, "options"))
                    {
                        if (!xkb_opts.options)
                            xkb_opts.options = strdup(tmp_val);
                    }
                    xfree(tmp_val);
                } else
                {
                    /* server 1.4 had xkb options as strlist */
                    tmp_val = get_prop_string_array(hal_ctx, udi, psi_key);
                    if (tmp_val && strlen(psi_key) >= sizeof(LIBHAL_XKB_PROP_KEY))
                    {
                        tmp = &psi_key[sizeof(LIBHAL_XKB_PROP_KEY) - 1];
                        if (!strcasecmp(tmp, ".options") && (!xkb_opts.options))
                            xkb_opts.options = strdup(tmp_val);
                    }
                }
            }
        }

        /* psi_key doesn't need to be freed */
        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);
    if (xkb_opts.options)
        add_option(&options, "xkb_options", xkb_opts.options);

    /* 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);
    if ((rc = NewInputDeviceRequest(options, &dev)) != Success) {
        LogMessage(X_ERROR, "config/hal: NewInputDeviceRequest failed (%d)\n", rc);
        dev = NULL;
        goto unwind;
    }

    for (; dev; dev = dev->next){
        if (dev->config_info)
            xfree(dev->config_info);
        dev->config_info = xstrdup(config_info);
    }

unwind:
    if (set)
        libhal_free_property_set(set);
    if (path)
        xfree(path);
    if (driver)
        xfree(driver);
    if (name)
        xfree(name);
    if (config_info)
        xfree(config_info);
    while (!dev && (tmpo = options)) {
        options = tmpo->next;
        xfree(tmpo->key);
        xfree(tmpo->value);
        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);
    if (xkb_opts.options)
        xfree(xkb_opts.options);

    dbus_error_free(&error);

    return;
}
Exemplo n.º 5
0
static void
wscons_add_keyboard(void)
{
    InputAttributes attrs = { };
    DeviceIntPtr dev = NULL;
    InputOption *input_options = NULL;
    char *config_info = NULL;
    int fd, i, rc;
    unsigned int type;
    kbd_t wsenc = 0;

    /* Find keyboard configuration */
    fd = priv_open_device(WSCONS_KBD_DEVICE);
    if (fd == -1) {
        LogMessage(X_ERROR, "wskbd: open %s: %s\n",
                   WSCONS_KBD_DEVICE, strerror(errno));
        return;
    }
    if (ioctl(fd, WSKBDIO_GETENCODING, &wsenc) == -1) {
        LogMessage(X_WARNING, "wskbd: ioctl(WSKBDIO_GETENCODING) "
                   "failed: %s\n", strerror(errno));
        close(fd);
        return;
    }
    if (ioctl(fd, WSKBDIO_GTYPE, &type) == -1) {
        LogMessage(X_WARNING, "wskbd: ioctl(WSKBDIO_GTYPE) "
                   "failed: %s\n", strerror(errno));
        close(fd);
        return;
    }
    close (fd);

    input_options = input_option_new(input_options, "_source", "server/wscons");
    if (input_options == NULL)
        return;

    LogMessage(X_INFO, "config/wscons: checking input device %s\n",
               WSCONS_KBD_DEVICE);
    input_options = input_option_new(input_options, "name", WSCONS_KBD_DEVICE);
    input_options = input_option_new(input_options, "driver", "kbd");

    config_info = Xprintf("wscons:%s", WSCONS_KBD_DEVICE);
    if (!config_info)
        goto unwind;
    if (KB_ENCODING(wsenc) == KB_USER) {
        /* Ignore wscons "user" layout */
        LogMessageVerb(X_INFO, 3, "wskbd: ignoring \"user\" layout\n");
        goto kbd_config_done;
    }
    for (i = 0; kbdenc[i].val; i++)
        if (KB_ENCODING(wsenc) == kbdenc[i].val) {
            LogMessageVerb(X_INFO, 3, "wskbd: using layout %s\n",
                           kbdenc[i].name);
            input_options = input_option_new(input_options,
                                             "xkb_layout", kbdenc[i].name);
            break;
        }
    for (i = 0; kbdvar[i].val; i++)
        if (wsenc == kbdvar[i].val || KB_VARIANT(wsenc) == kbdvar[i].val) {
            LogMessageVerb(X_INFO, 3, "wskbd: using variant %s\n",
                           kbdvar[i].name);
            input_options = input_option_new(input_options,
                                             "xkb_variant", kbdvar[i].name);
            break;
        }
    for (i = 0; kbdopt[i].val; i++)
        if (KB_VARIANT(wsenc) == kbdopt[i].val) {
            LogMessageVerb(X_INFO, 3, "wskbd: using option %s\n",
                           kbdopt[i].name);
            input_options = input_option_new(input_options,
                                             "xkb_options", kbdopt[i].name);
            break;
        }
    for (i = 0; kbdmodel[i].val; i++)
        if (type == kbdmodel[i].val) {
            LogMessageVerb(X_INFO, 3, "wskbd: using model %s\n",
                           kbdmodel[i].name);
            input_options = input_option_new(input_options,
                                             "xkb_model", kbdmodel[i].name);
            break;
        }

 kbd_config_done:
    attrs.flags |= ATTR_KEYBOARD;
    rc = NewInputDeviceRequest(input_options, &attrs, &dev);
    if (rc != Success)
        goto unwind;

    for (; dev; dev = dev->next) {
        free(dev->config_info);
        dev->config_info = strdup(config_info);
    }
 unwind:
    input_option_free_list(&input_options);
}
Exemplo n.º 6
0
            LOG_PROPERTY(path, key, value);
            attrs.flags |= ATTR_TABLET;
        } else if (!strcmp(key, "ID_INPUT_TOUCHPAD")) {
            LOG_PROPERTY(path, key, value);
            attrs.flags |= ATTR_TOUCHPAD;
        } else if (!strcmp(key, "ID_INPUT_TOUCHSCREEN")) {
            LOG_PROPERTY(path, key, value);
            attrs.flags |= ATTR_TOUCHSCREEN;
        }
    }

    add_option(&options, "config_info", config_info);

    LogMessage(X_INFO, "config/udev: Adding input device %s (%s)\n",
               name, path);
    rc = NewInputDeviceRequest(options, &attrs, &dev);
    if (rc != Success)
        goto unwind;

 unwind:
    free(config_info);
    while ((tmpo = options)) {
        options = tmpo->next;
        free(tmpo->key);        /* NULL if dev != NULL */
        free(tmpo->value);      /* NULL if dev != NULL */
        free(tmpo);
    }

    free(attrs.usb_id);
    free(attrs.pnp_id);
    free(attrs.product);
Exemplo n.º 7
0
static int
add_device(DBusMessage *message, DBusMessage *reply, DBusError *error)
{
    DBusMessageIter iter, reply_iter, subiter;
    InputOption *tmpo = NULL, *options = NULL;
    char *tmp = NULL;
    int ret, err;
    DeviceIntPtr dev = NULL;

    dbus_message_iter_init_append(reply, &reply_iter);

    if (!dbus_message_iter_init(message, &iter)) {
        ErrorF("[config/dbus] couldn't initialise iterator\n");
        MALFORMED_MESSAGE();
    }

    options = xcalloc(sizeof(*options), 1);
    if (!options) {
        ErrorF("[config/dbus] couldn't allocate option\n");
        return BadAlloc;
    }

    options->key = xstrdup("_source");
    options->value = xstrdup("client/dbus");
    if (!options->key || !options->value) {
        ErrorF("[config/dbus] couldn't allocate first key/value pair\n");
        ret = BadAlloc;
        goto unwind;
    }

    /* signature should be [ss][ss]... */
    while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_ARRAY) {
        tmpo = xcalloc(sizeof(*tmpo), 1);
        if (!tmpo) {
            ErrorF("[config/dbus] couldn't allocate option\n");
            ret = BadAlloc;
            goto unwind;
        }
        tmpo->next = options;
        options = tmpo;

        dbus_message_iter_recurse(&iter, &subiter);

        if (dbus_message_iter_get_arg_type(&subiter) != DBUS_TYPE_STRING)
            MALFORMED_MESSAGE();

        dbus_message_iter_get_basic(&subiter, &tmp);
        if (!tmp)
            MALFORMED_MESSAGE();
        /* The _ prefix refers to internal settings, and may not be given by
         * the client. */
        if (tmp[0] == '_') {
            ErrorF("[config/dbus] attempted subterfuge: option name %s given\n",
                   tmp);
            MALFORMED_MESSAGE();
        }
        options->key = xstrdup(tmp);
        if (!options->key) {
            ErrorF("[config/dbus] couldn't duplicate key!\n");
            ret = BadAlloc;
            goto unwind;
        }

        if (!dbus_message_iter_has_next(&subiter))
            MALFORMED_MESSAGE();
        dbus_message_iter_next(&subiter);
        if (dbus_message_iter_get_arg_type(&subiter) != DBUS_TYPE_STRING)
            MALFORMED_MESSAGE();

        dbus_message_iter_get_basic(&subiter, &tmp);
        if (!tmp)
            MALFORMED_MESSAGE();
        options->value = xstrdup(tmp);
        if (!options->value) {
            ErrorF("[config/dbus] couldn't duplicate option!\n");
            ret = BadAlloc;
            goto unwind;
        }

        dbus_message_iter_next(&iter);
    }

    ret = NewInputDeviceRequest(options, &dev);
    if (ret != Success) {
        DebugF("[config/dbus] NewInputDeviceRequest failed\n");
        goto unwind;
    }

    if (!dev) {
        DebugF("[config/dbus] NewInputDeviceRequest provided no device\n");
        ret = BadImplementation;
        goto unwind;
    }

    /* XXX: If we fail halfway through, we don't seem to have any way to
     *      empty the iterator, so you'll end up with some device IDs,
     *      plus an error.  This seems to be a shortcoming in the D-Bus
     *      API. */
    for (; dev; dev = dev->next) {
        if (!dbus_message_iter_append_basic(&reply_iter, DBUS_TYPE_INT32,
                                            &dev->id)) {
            ErrorF("[config/dbus] couldn't append to iterator\n");
            ret = BadAlloc;
            goto unwind;
        }
    }

unwind:
    if (ret != Success) {
        if (dev)
            RemoveDevice(dev);

        err = -ret;
        dbus_message_iter_append_basic(&reply_iter, DBUS_TYPE_INT32, &err);
    }

    while (options) {
        tmpo = options;
        options = options->next;
        if (tmpo->key)
            xfree(tmpo->key);
        if (tmpo->value)
            xfree(tmpo->value);
        xfree(tmpo);
    }

    return ret;
}
Exemplo n.º 8
0
static void
device_added(LibHalContext *hal_ctx, const char *udi)
{
    char **props;
    /* Cleverly, these are currently all leaked. */
    char *path = NULL, *driver = NULL, *name = NULL, *xkb_rules = NULL;
    char *xkb_model = NULL, *xkb_layout = NULL, *xkb_variant = NULL;
    char **xkb_options = NULL;
    DBusError error;
    struct xserver_option *options = NULL;
    int type = TYPE_NONE;
    int i;
    DeviceIntPtr dev = NULL;

    dbus_error_init(&error);

    props = libhal_device_get_property_strlist(hal_ctx, udi,
                                               "info.capabilities", &error);
    if (!props) {
        DebugF("[config/hal] couldn't get capabilities for %s: %s (%s)\n",
               udi, error.name, error.message);
        goto out_error;
    }
    for (i = 0; props[i]; i++) {
        /* input.keys is the new, of which input.keyboard is a subset, but
         * input.keyboard is the old 'we have keys', so we have to keep it
         * around. */
        if (strcmp(props[i], "input.keys") == 0 ||
            strcmp(props[i], "input.keyboard") == 0)
            type |= TYPE_KEYS;
        if (strcmp(props[i], "input.mouse") == 0)
            type |= TYPE_POINTER;
    }
    libhal_free_string_array(props);

    if (!type)
        goto out_error;

    driver = get_prop_string(hal_ctx, udi, "input.x11_driver");
    path = get_prop_string(hal_ctx, udi, "input.device");
    if (!driver || !path) {
        DebugF("[config/hal] no driver or path specified for %s\n", udi);
        goto unwind;
    }
    name = get_prop_string(hal_ctx, udi, "info.product");
    if (!name)
        name = xstrdup("(unnamed)");

    if (type & TYPE_KEYS) {
        xkb_rules = get_prop_string(hal_ctx, udi, "input.xkb.rules");
        xkb_model = get_prop_string(hal_ctx, udi, "input.xkb.model");
        xkb_layout = get_prop_string(hal_ctx, udi, "input.xkb.layout");
        xkb_variant = get_prop_string(hal_ctx, udi, "input.xkb.variant");
        xkb_options = get_prop_string_array(hal_ctx, udi, "input.xkb.options");
    }

    options = xcalloc(sizeof(*options), 1);
    options->key = xstrdup("_source");
    options->value = xstrdup("server/hal");
    if (!options->key || !options->value) {
        ErrorF("[config] couldn't allocate first key/value pair\n");
        goto unwind;
    }

    add_option(&options, "path", path);
    add_option(&options, "driver", driver);
    add_option(&options, "name", name);
    add_option(&options, "hal_udi", udi);

    if (xkb_model)
        add_option(&options, "xkb_model", xkb_model);
    if (xkb_layout)
        add_option(&options, "xkb_layout", xkb_layout);
    if (xkb_variant)
        add_option(&options, "xkb_variant", xkb_variant);
#if 0
    if (xkb_options)
        add_option(&options, "xkb_options", xkb_options);
#endif

    /* Maemo-specific hack.  Ugh. */
    if (type & TYPE_KEYS)
        add_option(&options, "type", "keyboard");
    else
        add_option(&options, "type", "pointer");

    if (NewInputDeviceRequest(options, &dev) != Success) {
        DebugF("[config/hal] NewInputDeviceRequest failed\n");
        goto unwind;
    }

    dbus_error_free(&error);

    return;

unwind:
    if (path)
        xfree(path);
    if (driver)
        xfree(driver);
    if (name)
        xfree(name);
    if (xkb_rules)
        xfree(xkb_rules);
    if (xkb_model)
        xfree(xkb_model);
    if (xkb_layout)
        xfree(xkb_layout);
    if (xkb_options) {
        for (i = 0; xkb_options[i]; i++)
            xfree(xkb_options[i]);
        xfree(xkb_options);
    }

out_error:
    dbus_error_free(&error);

    return;
}