mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-24 19:20:05 +01:00
Add libinput_create_from_path
Hooking libinput up to udev isn't always possible, especially if libinput were to be used in the X server which already has the udev handling built-in. Add an option to create a context from a path. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
3cf9cd9c86
commit
069fc60b8b
4 changed files with 262 additions and 0 deletions
|
|
@ -13,6 +13,8 @@ libinput_la_SOURCES = \
|
|||
evdev-touchpad.c \
|
||||
filter.c \
|
||||
filter.h \
|
||||
path.h \
|
||||
path.c \
|
||||
udev-seat.c \
|
||||
udev-seat.h
|
||||
|
||||
|
|
|
|||
|
|
@ -447,6 +447,25 @@ libinput_create_from_udev(const struct libinput_interface *interface,
|
|||
void *user_data,
|
||||
struct udev *udev,
|
||||
const char *seat_id);
|
||||
/**
|
||||
* @ingroup base
|
||||
*
|
||||
* Create a new libinput context from the given path. This context
|
||||
* represents one single device only, it will not respond to new devices
|
||||
* being added and reading from the device after it was removed will fail.
|
||||
*
|
||||
* @param interface The callback interface
|
||||
* @param user_data Caller-specific data passed to the various callback
|
||||
* interfaces.
|
||||
* @param path Path to an input device
|
||||
*
|
||||
* @return An initialized libinput context, ready to handle events or NULL on
|
||||
* error.
|
||||
*/
|
||||
struct libinput *
|
||||
libinput_create_from_path(const struct libinput_interface *interface,
|
||||
void *user_data,
|
||||
const char *path);
|
||||
|
||||
/**
|
||||
* @ingroup base
|
||||
|
|
|
|||
199
src/path.c
Normal file
199
src/path.c
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* Copyright © 2013 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of the copyright holders not be used in
|
||||
* advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The copyright holders make
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <libudev.h>
|
||||
|
||||
#include "path.h"
|
||||
#include "evdev.h"
|
||||
|
||||
int path_input_process_event(struct libinput_event);
|
||||
static void path_seat_destroy(struct libinput_seat *seat);
|
||||
|
||||
static void
|
||||
path_input_disable(struct libinput *libinput)
|
||||
{
|
||||
struct path_input *input = (struct path_input*)libinput;
|
||||
struct evdev_device *device = input->device;
|
||||
struct path_seat *seat, *tmp;
|
||||
|
||||
if (device) {
|
||||
close_restricted(libinput, device->fd);
|
||||
evdev_device_remove(device);
|
||||
input->device = NULL;
|
||||
}
|
||||
|
||||
/* should only be one seat anyway */
|
||||
list_for_each_safe(seat, tmp, &libinput->seat_list, base.link) {
|
||||
notify_removed_seat(&seat->base);
|
||||
list_remove(&seat->base.link);
|
||||
list_init(&seat->base.link);
|
||||
libinput_seat_unref(&seat->base);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
path_seat_destroy(struct libinput_seat *seat)
|
||||
{
|
||||
struct path_seat *pseat = (struct path_seat*)seat;
|
||||
free(pseat);
|
||||
}
|
||||
|
||||
static struct path_seat*
|
||||
path_seat_create(struct path_input *input)
|
||||
{
|
||||
struct path_seat *seat;
|
||||
|
||||
seat = zalloc(sizeof(*seat));
|
||||
if (!seat)
|
||||
return NULL;
|
||||
|
||||
seat->name = "default";
|
||||
|
||||
libinput_seat_init(&seat->base, &input->base, seat->name, path_seat_destroy);
|
||||
list_insert(&input->base.seat_list, &seat->base.link);
|
||||
notify_added_seat(&seat->base);
|
||||
|
||||
return seat;
|
||||
}
|
||||
|
||||
static char *
|
||||
path_get_sysname(const char *path)
|
||||
{
|
||||
struct udev *udev = NULL;
|
||||
struct udev_device *device = NULL;
|
||||
struct stat st;
|
||||
char *syspath = NULL;
|
||||
|
||||
udev = udev_new();
|
||||
if (!udev)
|
||||
goto out;
|
||||
|
||||
if (stat(path, &st) < 0)
|
||||
goto out;
|
||||
|
||||
device = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
|
||||
if (!device)
|
||||
goto out;
|
||||
|
||||
syspath = strdup(udev_device_get_syspath(device));
|
||||
out:
|
||||
if (device)
|
||||
udev_device_unref(device);
|
||||
if (udev)
|
||||
udev_unref(udev);
|
||||
return syspath;
|
||||
}
|
||||
|
||||
static int
|
||||
path_input_enable(struct libinput *libinput)
|
||||
{
|
||||
struct path_input *input = (struct path_input*)libinput;
|
||||
struct path_seat *seat;
|
||||
struct evdev_device *device;
|
||||
const char *devnode = input->path;
|
||||
char *syspath;
|
||||
int fd;
|
||||
|
||||
if (input->device)
|
||||
return 0;
|
||||
|
||||
fd = open_restricted(libinput, input->path, O_RDWR|O_NONBLOCK);
|
||||
if (fd < 0) {
|
||||
log_info("opening input device '%s' failed.\n", devnode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
syspath = path_get_sysname(devnode);
|
||||
if (!syspath) {
|
||||
close_restricted(libinput, fd);
|
||||
log_info("failed to obtain syspath for device '%s'.\n", devnode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
seat = path_seat_create(input);
|
||||
|
||||
device = evdev_device_create(&seat->base, devnode, syspath, fd);
|
||||
free(syspath);
|
||||
|
||||
if (device == EVDEV_UNHANDLED_DEVICE) {
|
||||
close_restricted(libinput, fd);
|
||||
log_info("not using input device '%s'.\n", devnode);
|
||||
libinput_seat_unref(&seat->base);
|
||||
return -1;
|
||||
} else if (device == NULL) {
|
||||
close_restricted(libinput, fd);
|
||||
log_info("failed to create input device '%s'.\n", devnode);
|
||||
libinput_seat_unref(&seat->base);
|
||||
return -1;
|
||||
}
|
||||
|
||||
input->device = device;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
path_input_destroy(struct libinput *input)
|
||||
{
|
||||
struct path_input *path_input = (struct path_input*)input;
|
||||
free(path_input->path);
|
||||
}
|
||||
|
||||
static const struct libinput_interface_backend interface_backend = {
|
||||
.resume = path_input_enable,
|
||||
.suspend = path_input_disable,
|
||||
.destroy = path_input_destroy,
|
||||
};
|
||||
|
||||
LIBINPUT_EXPORT struct libinput *
|
||||
libinput_create_from_path(const struct libinput_interface *interface,
|
||||
void *user_data,
|
||||
const char *path)
|
||||
{
|
||||
struct path_input *input;
|
||||
|
||||
if (!interface || !path)
|
||||
return NULL;
|
||||
|
||||
input = zalloc(sizeof *input);
|
||||
if (!input)
|
||||
return NULL;
|
||||
|
||||
if (libinput_init(&input->base, interface,
|
||||
&interface_backend, user_data) != 0) {
|
||||
free(input);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
input->path = strdup(path);
|
||||
|
||||
if (path_input_enable(&input->base) < 0) {
|
||||
libinput_destroy(&input->base);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &input->base;
|
||||
}
|
||||
42
src/path.h
Normal file
42
src/path.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright © 2013 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of the copyright holders not be used in
|
||||
* advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The copyright holders make
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _PATH_H_
|
||||
#define _PATH_H_
|
||||
|
||||
#include "config.h"
|
||||
#include "libinput-private.h"
|
||||
|
||||
struct path_input {
|
||||
struct libinput base;
|
||||
char *path;
|
||||
struct evdev_device *device;
|
||||
};
|
||||
|
||||
struct path_seat {
|
||||
struct libinput_seat base;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
int path_input_process_event(struct libinput_event);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue