summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2009-03-26 09:47:20 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2009-03-26 09:54:18 +1000
commit7deae7788f41113aa8d8e335ebcb390e9b0b1d5b (patch)
treececcfb341fa2f9ff06da34922956a4ba7261b98e
Initial set of testdevices.
-rw-r--r--.gitignore27
-rw-r--r--Makefile.am1
-rwxr-xr-xautogen.sh12
-rw-r--r--configure.ac49
-rw-r--r--src/Makefile.am39
-rw-r--r--src/abs.c84
-rw-r--r--src/absrel.c91
-rw-r--r--src/btn0.c87
-rw-r--r--src/dummy.c77
-rw-r--r--src/fakedev.c199
-rw-r--r--src/fakedev.h51
11 files changed, 717 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..812f547
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,27 @@
+*.patch
+ChangeLog
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache
+config.guess
+config.h
+config.h.in
+config.log
+config.status
+config.sub
+configure
+depcomp
+install-sh
+libtool
+ltmain.sh
+missing
+.deps
+.libs
+*.lo
+*.la
+stamp-h1
+*.pc
+*~
+tags
+*.o
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..af437a6
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = src
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..904cd67
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+$srcdir/configure --enable-maintainer-mode "$@"
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..f4e6784
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,49 @@
+# Copyright 2009 Red Hat, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# on the rights to use, copy, modify, merge, publish, distribute, sub
+# license, and/or sell copies of the Software, and to permit persons to whom
+# the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Process this file with autoconf to produce a configure script
+
+AC_PREREQ(2.57)
+AC_INIT([uinput-devices],
+ 0.1,
+ [],
+ test-devices)
+
+AC_CONFIG_SRCDIR([Makefile.am])
+AC_CONFIG_AUX_DIR(.)
+AM_INIT_AUTOMAKE([dist-bzip2 foreign])
+
+AM_MAINTAINER_MODE
+
+AM_CONFIG_HEADER([config.h])
+
+# Checks for programs.
+AC_PROG_CC
+
+# Checks for libraries.
+AC_CHECK_FUNC([dlopen], [],
+ AC_CHECK_LIB([dl], [dlopen], DLOPEN_LIBS="-ldl"))
+AC_SUBST([DLOPEN_LIBS])
+
+# Checks for header files.
+AC_HEADER_STDC
+
+AC_OUTPUT([Makefile
+ src/Makefile])
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..bde735e
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,39 @@
+# Copyright 2009 Red Hat, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# on the rights to use, copy, modify, merge, publish, distribute, sub
+# license, and/or sell copies of the Software, and to permit persons to whom
+# the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+AM_CFLAGS = $(XORG_CFLAGS)
+
+noinst_PROGRAMS=fakedev btn0 absrel abs dummy
+
+fakedev_SOURCES=fakedev.c fakedev.h
+fakedev_LDFLAGS=$(DLOPEN_LIBS) -rdynamic
+
+LFLAGS=-shared -fPIC
+
+btn0_SOURCES=btn0.c
+btn0_LDFLAGS=$(LFLAGS)
+
+absrel_SOURCES=absrel.c
+absrel_LDFLAGS=$(LFLAGS)
+
+abs_SOURCES=abs.c
+abs_LDFLAGS=$(LFLAGS)
+
+dummy_SOURCES=dummy.c
+dummy_LDFLAGS=$(LFLAGS)
diff --git a/src/abs.c b/src/abs.c
new file mode 100644
index 0000000..8529190
--- /dev/null
+++ b/src/abs.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright © 2008 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 Red Hat
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission. Red
+ * Hat makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL THE AUTHORS 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.
+ *
+ * Authors:
+ * Peter Hutterer (peter.hutterer@redhat.com)
+ */
+
+
+/* creates a device with ABS_X, ABS_Y, BTN_LEFT, BTN_MIDDLE, BTN_RIGHT. */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <linux/input.h>
+#include <linux/uinput.h>
+
+#include "fakedev.h"
+
+int abs_setup(struct uinput_user_dev* dev, int fd)
+{
+ if (ioctl(fd, UI_SET_EVBIT, EV_ABS) == -1) goto error;
+ if (ioctl(fd, UI_SET_EVBIT, EV_SYN) == -1) goto error;
+
+ /* buttons */
+ if (ioctl(fd, UI_SET_KEYBIT, BTN_LEFT) == -1) goto error;
+ if (ioctl(fd, UI_SET_KEYBIT, BTN_MIDDLE) == -1) goto error;
+ if (ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT) == -1) goto error;
+
+ /* axes */
+ if (ioctl(fd, UI_SET_ABSBIT, ABS_X) == -1) goto error;
+ if (ioctl(fd, UI_SET_ABSBIT, ABS_Y) == -1) goto error;
+
+
+ dev->absmin[ABS_X] = 0;
+ dev->absmax[ABS_X] = 120;
+
+ dev->absmin[ABS_Y] = 0;
+ dev->absmax[ABS_Y] = 120;
+
+ return 0;
+
+error:
+ perror("ioctl failed.");
+ return -1;
+}
+
+int abs_run(int fd)
+{
+ absmove(fd, 100, 100);
+ sleep(1);
+ absmove(fd, 120, 120);
+ sleep(1);
+ return 0;
+}
+
+struct test_device abs_dev = {
+ .name = "Abs test device",
+ .setup = abs_setup,
+ .run = abs_run,
+};
+
+
+struct test_device* get_device()
+{
+ return &abs_dev;
+}
diff --git a/src/absrel.c b/src/absrel.c
new file mode 100644
index 0000000..3ae2a1c
--- /dev/null
+++ b/src/absrel.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright © 2008 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 Red Hat
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission. Red
+ * Hat makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL THE AUTHORS 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.
+ *
+ * Authors:
+ * Peter Hutterer (peter.hutterer@redhat.com)
+ */
+
+
+/* creates a device with ABS_X, ABS_Y, REL_X, REL_Y, BTN_LEFT, BTN_MIDDLE,
+ BTN_RIGHT. */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <linux/input.h>
+#include <linux/uinput.h>
+
+#include "fakedev.h"
+
+int absrel_setup(struct uinput_user_dev* dev, int fd)
+{
+ if (ioctl(fd, UI_SET_EVBIT, EV_REL) == -1) goto error;
+ if (ioctl(fd, UI_SET_EVBIT, EV_ABS) == -1) goto error;
+ if (ioctl(fd, UI_SET_EVBIT, EV_SYN) == -1) goto error;
+
+ /* buttons */
+ if (ioctl(fd, UI_SET_KEYBIT, BTN_LEFT) == -1) goto error;
+ if (ioctl(fd, UI_SET_KEYBIT, BTN_MIDDLE) == -1) goto error;
+ if (ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT) == -1) goto error;
+
+ /* axes */
+ if (ioctl(fd, UI_SET_RELBIT, REL_X) == -1) goto error;
+ if (ioctl(fd, UI_SET_RELBIT, REL_Y) == -1) goto error;
+
+ if (ioctl(fd, UI_SET_ABSBIT, ABS_X) == -1) goto error;
+ if (ioctl(fd, UI_SET_ABSBIT, ABS_Y) == -1) goto error;
+
+
+ dev->absmin[ABS_X] = 0;
+ dev->absmax[ABS_X] = 1000;
+
+ dev->absmin[ABS_Y] = 0;
+ dev->absmax[ABS_Y] = 1000;
+
+ return 0;
+
+error:
+ perror("ioctl failed.");
+ return -1;
+}
+
+int absrel_run(int fd)
+{
+ absmove(fd, 100, 100);
+ sleep(1);
+ absmove(fd, 120, 120);
+ sleep(1);
+ move(fd, 10, 10);
+ return 0;
+}
+
+struct test_device absrel_dev = {
+ .name = "Abs/Rel test device",
+ .setup = absrel_setup,
+ .run = absrel_run,
+};
+
+
+struct test_device* get_device()
+{
+ return &absrel_dev;
+}
+
diff --git a/src/btn0.c b/src/btn0.c
new file mode 100644
index 0000000..f6572a5
--- /dev/null
+++ b/src/btn0.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2008 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 Red Hat
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission. Red
+ * Hat makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL THE AUTHORS 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.
+ *
+ * Authors:
+ * Peter Hutterer (peter.hutterer@redhat.com)
+ */
+
+/* Creates a device that has REL_X REL_Y BTN_0 BTN_1 BTN_2
+ *
+ * Moves the device around in a 10px square and clicks after each completed
+ * circle.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <linux/input.h>
+#include <linux/uinput.h>
+
+#include "fakedev.h"
+
+int btn0_setup(struct uinput_user_dev *dev, int fd)
+{
+ if (ioctl(fd, UI_SET_EVBIT, EV_KEY) == -1) goto error;
+ if (ioctl(fd, UI_SET_EVBIT, EV_REL) == -1) goto error;
+ if (ioctl(fd, UI_SET_EVBIT, EV_SYN) == -1) goto error;
+
+ /* buttons */
+ if (ioctl(fd, UI_SET_KEYBIT, BTN_0) == -1) goto error;
+ if (ioctl(fd, UI_SET_KEYBIT, BTN_1) == -1) goto error;
+ if (ioctl(fd, UI_SET_KEYBIT, BTN_2) == -1) goto error;
+
+ /* axes */
+ if (ioctl(fd, UI_SET_RELBIT, REL_X) == -1) goto error;
+ if (ioctl(fd, UI_SET_RELBIT, REL_Y) == -1) goto error;
+
+ return 0;
+error:
+ perror("ioctl failed.");
+ return -1;
+}
+
+int btn0_run(int fd)
+{
+ move(fd, -10, 0);
+ usleep(1000);
+ move(fd, 0, -10);
+ usleep(1000);
+ move(fd, 10, 0);
+ usleep(1000);
+ move(fd, 0, 10);
+ usleep(1000);
+ click(fd, BTN_0, 1);
+ usleep(1000);
+ click(fd, BTN_0, 0);
+ return 0;
+}
+
+struct test_device btn0_dev = {
+ .name = "BTN_0 test device",
+ .setup = btn0_setup,
+ .run = btn0_run,
+};
+
+
+struct test_device* get_device()
+{
+ return &btn0_dev;
+}
diff --git a/src/dummy.c b/src/dummy.c
new file mode 100644
index 0000000..ffb5fe5
--- /dev/null
+++ b/src/dummy.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2008 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 Red Hat
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission. Red
+ * Hat makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL THE AUTHORS 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.
+ *
+ * Authors:
+ * Peter Hutterer (peter.hutterer@redhat.com)
+ */
+
+/* dummy device, looks like a mouse but doesn't do anything.
+ * Good for filling up the device list.
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <linux/input.h>
+#include <linux/uinput.h>
+
+#include "fakedev.h"
+
+int dummy_setup(struct uinput_user_dev *dev, int fd)
+{
+ if (ioctl(fd, UI_SET_EVBIT, EV_KEY) == -1) goto error;
+ if (ioctl(fd, UI_SET_EVBIT, EV_REL) == -1) goto error;
+ if (ioctl(fd, UI_SET_EVBIT, EV_SYN) == -1) goto error;
+
+ /* buttons */
+ if (ioctl(fd, UI_SET_KEYBIT, BTN_LEFT) == -1) goto error;
+ if (ioctl(fd, UI_SET_KEYBIT, BTN_MIDDLE) == -1) goto error;
+ if (ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT) == -1) goto error;
+
+ /* axes */
+ if (ioctl(fd, UI_SET_RELBIT, REL_X) == -1) goto error;
+ if (ioctl(fd, UI_SET_RELBIT, REL_Y) == -1) goto error;
+
+ return 0;
+error:
+ perror("ioctl failed.");
+ return -1;
+}
+
+int dummy_run(int fd)
+{
+ usleep(1000);
+ return 0;
+}
+
+struct test_device dummy_dev = {
+ .name = "dummy_ test device",
+ .setup = dummy_setup,
+ .run = dummy_run,
+};
+
+
+struct test_device* get_device()
+{
+ return &dummy_dev;
+}
+
diff --git a/src/fakedev.c b/src/fakedev.c
new file mode 100644
index 0000000..a3a1b81
--- /dev/null
+++ b/src/fakedev.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright © 2008 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 Red Hat
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission. Red
+ * Hat makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL THE AUTHORS 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.
+ *
+ * Authors:
+ * Peter Hutterer (peter.hutterer@redhat.com)
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+#include <linux/input.h>
+#include <linux/uinput.h>
+#include <dlfcn.h>
+
+#include "fakedev.h"
+
+/* "public interfaces" */
+
+void send_event(int fd, int type, int code, int value)
+{
+ struct input_event event;
+
+ event.type = type;
+ event.code = code;
+ event.value = value;
+ gettimeofday(&event.time, NULL);
+
+ if (write(fd, &event, sizeof(event)) < sizeof(event))
+ perror("Send event failed.");
+}
+
+
+void move(int fd, int x, int y)
+{
+ if (!x && !y)
+ return;
+
+ send_event(fd, EV_REL, REL_X, x);
+ send_event(fd, EV_REL, REL_Y, y);
+ send_event(fd, EV_SYN, SYN_REPORT, 0);
+}
+
+void absmove(int fd, int x, int y)
+{
+ send_event(fd, EV_ABS, ABS_X, x);
+ send_event(fd, EV_ABS, ABS_Y, y);
+ send_event(fd, EV_SYN, SYN_REPORT, 0);
+}
+
+void click(int fd, int btn, int down)
+{
+ send_event(fd, EV_KEY, btn, down);
+ send_event(fd, EV_SYN, SYN_REPORT, 0);
+}
+
+
+
+/* end public interfaces */
+
+static int fd = -1;
+static int stop = 0;
+
+static void sighandler(int signum)
+{
+ printf("Stopping.\n");
+ stop = 1;
+}
+
+static void init_signal(void)
+{
+ struct sigaction action;
+ sigset_t mask;
+
+ sigfillset(&mask);
+
+ action.sa_handler = sighandler;
+ action.sa_mask = mask;
+ action.sa_flags = 0;
+
+ sigaction(SIGTERM, &action, NULL);
+ sigaction(SIGINT, &action, NULL);
+ sigprocmask(SIG_UNBLOCK, &mask, 0);
+}
+
+
+static int init_uinput(struct test_device* test_dev)
+{
+ struct uinput_user_dev dev;
+
+ fd = open("/dev/input/uinput", O_RDWR);
+ if (fd < 0)
+ goto error;
+
+ memset(&dev, 0, sizeof(dev));
+ strcpy(dev.name, test_dev->name);
+ dev.id.bustype = 0;
+ dev.id.vendor = 0x1F;
+ dev.id.product = 0x1F;
+ dev.id.version = 0;
+
+
+ test_dev->setup(&dev, fd);
+
+ if (write(fd, &dev, sizeof(dev)) < sizeof(dev))
+ goto error;
+ if (ioctl(fd, UI_DEV_CREATE, NULL) == -1) goto error;
+
+ return 0;
+
+error:
+ fprintf(stderr, "Error: %s\n", strerror(errno));
+
+ if (fd != -1)
+ close(fd);
+
+ return -1;
+}
+
+static void cleanup_uinput(void)
+{
+ if (fd == -1)
+ return;
+
+ ioctl(fd, UI_DEV_DESTROY, NULL);
+ close(fd);
+ fd = -1;
+}
+
+
+int main (int argc, char **argv)
+{
+ struct test_device *dev;
+ void *dlhandle = NULL;
+ struct test_device* (*get_device)(void);
+
+ if (argc <= 1)
+ {
+ fprintf(stderr, "Usage: %s test_dev\n", argv[0]);
+ return -1;
+ }
+
+ printf("Loading %s.\n", argv[1]);
+
+ dlhandle = dlopen(argv[1], RTLD_NOW | RTLD_GLOBAL);
+ if (!dlhandle)
+ {
+ fprintf(stderr, "Error: %s\n", dlerror());
+ return -1;
+ }
+
+ *(void**)(&get_device) = dlsym(dlhandle, "get_device");
+ if (!get_device)
+ {
+ fprintf(stderr, "Error getting the symbol: %s.\n", dlerror());
+ return -1;
+ }
+
+ dev = (*get_device)();
+
+ if (init_uinput(dev) < 0) {
+ fprintf(stderr, "Failed to initialize /dev/uinput. Exiting.\n");
+ return -1;
+ }
+
+ init_signal();
+
+ printf("Device created. Press CTRL+C to terminate.\n");
+ while (!stop) {
+ if (dev->run(fd))
+ break;
+ }
+
+ cleanup_uinput();
+
+ return 0;
+}
+
diff --git a/src/fakedev.h b/src/fakedev.h
new file mode 100644
index 0000000..465722a
--- /dev/null
+++ b/src/fakedev.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright © 2008 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 Red Hat
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission. Red
+ * Hat makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL THE AUTHORS 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.
+ *
+ * Authors:
+ * Peter Hutterer (peter.hutterer@redhat.com)
+ */
+
+#ifndef _EVDEV_TEST_H
+#define _EVDEV_TEST_H
+#include <linux/uinput.h>
+
+struct test_device {
+ char *name; /* device name */
+ /**
+ * Called to setup the device. Call ioctls to set your EVBITs, KEYBITs,
+ * etc. here. Return 0 on success or non-zero to exit.
+ */
+ int (*setup)(struct uinput_user_dev* dev, int fd);
+
+ /**
+ * Called during each run of the main loop. Generate events by calling
+ * move(), click(), etc.
+ * Return 0 on success, or non-zero to stop the main loop.
+ */
+ int (*run)(int fd);
+};
+
+extern void move (int fd, int x, int y);
+extern void absmove (int fd, int x, int y);
+extern void click (int fd, int btn, int down);
+
+#endif