Add README for the adventurous, allow evdev override from getenv().
[profile/ivi/wayland.git] / input.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <linux/input.h>
4 #include <fcntl.h>
5 #include <unistd.h>
6
7 #include <linux/input.h>
8
9 #include "wayland.h"
10
11 struct wl_input_device {
12         struct wl_object base;
13         struct wl_event_source *source;
14         struct wl_display *display;
15         int fd;
16         int tool;
17         int32_t x, y;
18 };
19
20 static const struct wl_method input_device_methods[] = {
21 };
22
23 static const struct wl_interface input_device_interface = {
24         "input_device", 1,
25         ARRAY_LENGTH(input_device_methods),
26         input_device_methods,
27 };
28
29 static void wl_input_device_data(int fd, uint32_t mask, void *data)
30 {
31         struct wl_input_device *device = data;
32         struct input_event ev[8], *e, *end;
33         int len, value, dx, dy, absolute_event;
34
35         dx = 0;
36         dy = 0;
37         absolute_event = 0;
38
39         len = read(fd, &ev, sizeof ev);
40         if (len < 0 || len % sizeof e[0] != 0) {
41                 /* FIXME: handle error... reopen device? */;
42                 return;
43         }
44
45         e = ev;
46         end = (void *) ev + len;
47         for (e = ev; e < end; e++) {
48                 /* Get the signed value, earlier kernels had this as unsigned */
49                 value = e->value;
50
51                 switch (e->type) {
52                 case EV_REL:
53                         switch (e->code) {
54                         case REL_X:
55                                 dx += value;
56                                 break;
57
58                         case REL_Y:
59                                 dy += value;
60                                 break;
61                         }
62
63                 case EV_ABS:
64                         absolute_event = 1;
65                         switch (e->code) {
66                         case ABS_X:
67                                 device->x = value;
68                                 break;
69                         case ABS_Y:
70                                 device->y = value;
71                                 break;
72                         }
73
74                 case EV_KEY:
75                         if (value == 2)
76                                 break;
77
78                         switch (e->code) {
79                         case BTN_TOUCH:
80                         case BTN_TOOL_PEN:
81                         case BTN_TOOL_RUBBER:
82                         case BTN_TOOL_BRUSH:
83                         case BTN_TOOL_PENCIL:
84                         case BTN_TOOL_AIRBRUSH:
85                         case BTN_TOOL_FINGER:
86                         case BTN_TOOL_MOUSE:
87                         case BTN_TOOL_LENS:
88                                 device->tool = value ? e->code : 0;
89                                 break;
90
91                         case BTN_LEFT:
92                                 wl_display_post_button_event(device->display,
93                                                              &device->base, 0, value);
94                                 break;
95
96                         case BTN_RIGHT:
97                                 wl_display_post_button_event(device->display,
98                                                              &device->base, 2, value);
99                                 break;
100
101                         case BTN_MIDDLE:
102                                 wl_display_post_button_event(device->display,
103                                                              &device->base, 1, value);
104                                 break;
105                         }
106                 }
107         }
108
109         if (dx != 0 || dy != 0)
110                 wl_display_post_relative_event(device->display,
111                                                &device->base, dx, dy);
112         if (absolute_event && device->tool)
113                 wl_display_post_absolute_event(device->display,
114                                                &device->base,
115                                                device->x, device->y);
116 }
117
118 struct wl_object *
119 wl_input_device_create(struct wl_display *display,
120                        const char *path, uint32_t id)
121 {
122         struct wl_input_device *device;
123         struct wl_event_loop *loop;
124
125         device = malloc(sizeof *device);
126         if (device == NULL)
127                 return NULL;
128
129         device->base.id = id;
130         device->base.interface = &input_device_interface;
131         device->display = display;
132         device->tool = 1;
133
134         device->fd = open(path, O_RDONLY);
135         if (device->fd < 0) {
136                 free(device);
137                 fprintf(stderr, "couldn't create pointer for %s: %m\n", path);
138                 return NULL;
139         }
140
141         loop = wl_display_get_event_loop(display);
142         device->source = wl_event_loop_add_fd(loop, device->fd,
143                                               WL_EVENT_READABLE,
144                                               wl_input_device_data, device);
145         if (device->source == NULL) {
146                 close(device->fd);
147                 free(device);
148                 return NULL;
149         }
150
151         return &device->base;
152 }