~ubuntu-branches/ubuntu/natty/xserver-xorg-input-evdev/natty

« back to all changes in this revision

Viewing changes to test/fakedev.c

Tags: 1:2.3.1-1
* New upstream release.
  + Finalize the middle button emulation when a read error occurs
    (closes: #550970, #552012)
* Replace the fdi file with an udev rule.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright © 2008 Red Hat, Inc.
3
 
 *
4
 
 * Permission to use, copy, modify, distribute, and sell this software
5
 
 * and its documentation for any purpose is hereby granted without
6
 
 * fee, provided that the above copyright notice appear in all copies
7
 
 * and that both that copyright notice and this permission notice
8
 
 * appear in supporting documentation, and that the name of Red Hat
9
 
 * not be used in advertising or publicity pertaining to distribution
10
 
 * of the software without specific, written prior permission.  Red
11
 
 * Hat makes no representations about the suitability of this software
12
 
 * for any purpose.  It is provided "as is" without express or implied
13
 
 * warranty.
14
 
 *
15
 
 * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16
 
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17
 
 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18
 
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19
 
 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20
 
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21
 
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
 
 *
23
 
 * Authors:
24
 
 *      Peter Hutterer (peter.hutterer@redhat.com)
25
 
 */
26
 
 
27
 
#include <stdio.h>
28
 
#include <string.h>
29
 
#include <errno.h>
30
 
#include <fcntl.h>
31
 
#include <signal.h>
32
 
#include <unistd.h>
33
 
#include <linux/input.h>
34
 
#include <linux/uinput.h>
35
 
#include <dlfcn.h>
36
 
 
37
 
#include "fakedev.h"
38
 
 
39
 
/* "public interfaces" */
40
 
 
41
 
void send_event(int fd, int type, int code, int value)
42
 
{
43
 
    struct input_event event;
44
 
 
45
 
    event.type  = type;
46
 
    event.code  = code;
47
 
    event.value = value;
48
 
    gettimeofday(&event.time, NULL);
49
 
 
50
 
    if (write(fd, &event, sizeof(event)) < sizeof(event))
51
 
        perror("Send event failed.");
52
 
}
53
 
 
54
 
 
55
 
void move(int fd, int x, int y)
56
 
{
57
 
    if (!x && !y)
58
 
        return;
59
 
 
60
 
    send_event(fd, EV_REL, REL_X, x);
61
 
    send_event(fd, EV_REL, REL_Y, y);
62
 
    send_event(fd, EV_SYN, SYN_REPORT, 0);
63
 
}
64
 
 
65
 
void absmove(int fd, int x, int y)
66
 
{
67
 
    send_event(fd, EV_ABS, ABS_X, x);
68
 
    send_event(fd, EV_ABS, ABS_Y, y);
69
 
    send_event(fd, EV_SYN, SYN_REPORT, 0);
70
 
}
71
 
 
72
 
void click(int fd, int btn, int down)
73
 
{
74
 
    send_event(fd, EV_KEY, btn, down);
75
 
    send_event(fd, EV_SYN, SYN_REPORT, 0);
76
 
}
77
 
 
78
 
 
79
 
 
80
 
/* end public interfaces */
81
 
 
82
 
static int fd   = -1;
83
 
static int stop = 0;
84
 
 
85
 
static void sighandler(int signum)
86
 
{
87
 
    printf("Stopping.\n");
88
 
    stop = 1;
89
 
}
90
 
 
91
 
static void init_signal(void)
92
 
{
93
 
    struct sigaction action;
94
 
    sigset_t mask;
95
 
 
96
 
    sigfillset(&mask);
97
 
 
98
 
    action.sa_handler = sighandler;
99
 
    action.sa_mask    = mask;
100
 
    action.sa_flags   = 0;
101
 
 
102
 
    sigaction(SIGTERM, &action, NULL);
103
 
    sigaction(SIGINT, &action, NULL);
104
 
    sigprocmask(SIG_UNBLOCK, &mask, 0);
105
 
}
106
 
 
107
 
 
108
 
static int init_uinput(struct test_device* test_dev)
109
 
{
110
 
    struct uinput_user_dev dev;
111
 
 
112
 
    fd = open("/dev/input/uinput", O_RDWR);
113
 
    if (fd < 0)
114
 
        goto error;
115
 
 
116
 
    memset(&dev, 0, sizeof(dev));
117
 
    strcpy(dev.name, test_dev->name);
118
 
    dev.id.bustype = 0;
119
 
    dev.id.vendor  = 0x1F;
120
 
    dev.id.product = 0x1F;
121
 
    dev.id.version = 0;
122
 
 
123
 
 
124
 
    test_dev->setup(&dev, fd);
125
 
 
126
 
    if (write(fd, &dev, sizeof(dev)) < sizeof(dev))
127
 
        goto error;
128
 
    if (ioctl(fd, UI_DEV_CREATE, NULL) == -1) goto error;
129
 
 
130
 
    return 0;
131
 
 
132
 
error:
133
 
    fprintf(stderr, "Error: %s\n", strerror(errno));
134
 
 
135
 
    if (fd != -1)
136
 
        close(fd);
137
 
 
138
 
    return -1;
139
 
}
140
 
 
141
 
static void cleanup_uinput(void)
142
 
{
143
 
    if (fd == -1)
144
 
        return;
145
 
 
146
 
    ioctl(fd, UI_DEV_DESTROY, NULL);
147
 
    close(fd);
148
 
    fd = -1;
149
 
}
150
 
 
151
 
 
152
 
int main (int argc, char **argv)
153
 
{
154
 
    struct test_device *dev;
155
 
    void *dlhandle = NULL;
156
 
    struct test_device* (*get_device)(void);
157
 
 
158
 
    if (argc <= 1)
159
 
    {
160
 
        fprintf(stderr, "Usage: %s test_dev\n", argv[0]);
161
 
        return -1;
162
 
    }
163
 
 
164
 
    printf("Loading %s.\n", argv[1]);
165
 
 
166
 
    dlhandle = dlopen(argv[1], RTLD_NOW | RTLD_GLOBAL);
167
 
    if (!dlhandle)
168
 
    {
169
 
        fprintf(stderr, "Error: %s\n", dlerror());
170
 
        return -1;
171
 
    }
172
 
 
173
 
    *(void**)(&get_device) = dlsym(dlhandle, "get_device");
174
 
    if (!get_device)
175
 
    {
176
 
        fprintf(stderr, "Error getting the symbol: %s.\n", dlerror());
177
 
        return -1;
178
 
    }
179
 
 
180
 
    dev = (*get_device)();
181
 
 
182
 
    if (init_uinput(dev) < 0) {
183
 
        fprintf(stderr, "Failed to initialize /dev/uinput. Exiting.\n");
184
 
        return -1;
185
 
    }
186
 
 
187
 
    init_signal();
188
 
 
189
 
    printf("Device created. Press CTRL+C to terminate.\n");
190
 
    while (!stop) {
191
 
        if (dev->run(fd))
192
 
            break;
193
 
    }
194
 
 
195
 
    cleanup_uinput();
196
 
 
197
 
    return 0;
198
 
}
199