Change API from using listeners to using an event queue
[platform/upstream/libinput.git] / src / libinput.c
1 /*
2  * Copyright © 2013 Jonas Ådahl
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and
5  * its documentation for any purpose is hereby granted without fee, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of the copyright holders not be used in
9  * advertising or publicity pertaining to distribution of the software
10  * without specific, written prior permission.  The copyright holders make
11  * no representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22
23 #include "config.h"
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "libinput.h"
30 #include "evdev.h"
31 #include "libinput-private.h"
32
33 static void
34 post_event(struct libinput_device *device,
35            enum libinput_event_type type,
36            struct libinput_event *event);
37
38 void
39 keyboard_notify_key(struct libinput_device *device,
40                     uint32_t time,
41                     uint32_t key,
42                     enum libinput_keyboard_key_state state)
43 {
44         struct libinput_event_keyboard_key *key_event;
45
46         key_event = malloc(sizeof *key_event);
47         if (!key_event)
48                 return;
49
50         *key_event = (struct libinput_event_keyboard_key) {
51                 .time = time,
52                 .key = key,
53                 .state = state,
54         };
55
56         post_event(device, LIBINPUT_EVENT_KEYBOARD_KEY, &key_event->base);
57 }
58
59 void
60 pointer_notify_motion(struct libinput_device *device,
61                       uint32_t time,
62                       li_fixed_t dx,
63                       li_fixed_t dy)
64 {
65         struct libinput_event_pointer_motion *motion_event;
66
67         motion_event = malloc(sizeof *motion_event);
68         if (!motion_event)
69                 return;
70
71         *motion_event = (struct libinput_event_pointer_motion) {
72                 .time = time,
73                 .dx = dx,
74                 .dy = dy,
75         };
76
77         post_event(device, LIBINPUT_EVENT_POINTER_MOTION, &motion_event->base);
78 }
79
80 void
81 pointer_notify_motion_absolute(struct libinput_device *device,
82                                uint32_t time,
83                                li_fixed_t x,
84                                li_fixed_t y)
85 {
86         struct libinput_event_pointer_motion_absolute *motion_absolute_event;
87
88         motion_absolute_event = malloc(sizeof *motion_absolute_event);
89         if (!motion_absolute_event)
90                 return;
91
92         *motion_absolute_event = (struct libinput_event_pointer_motion_absolute) {
93                 .time = time,
94                 .x = x,
95                 .y = y,
96         };
97
98         post_event(device,
99                    LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
100                    &motion_absolute_event->base);
101 }
102
103 void
104 pointer_notify_button(struct libinput_device *device,
105                       uint32_t time,
106                       int32_t button,
107                       enum libinput_pointer_button_state state)
108 {
109         struct libinput_event_pointer_button *button_event;
110
111         button_event = malloc(sizeof *button_event);
112         if (!button_event)
113                 return;
114
115         *button_event = (struct libinput_event_pointer_button) {
116                 .time = time,
117                 .button = button,
118                 .state = state,
119         };
120
121         post_event(device, LIBINPUT_EVENT_POINTER_BUTTON, &button_event->base);
122 }
123
124 void
125 pointer_notify_axis(struct libinput_device *device,
126                     uint32_t time,
127                     enum libinput_pointer_axis axis,
128                     li_fixed_t value)
129 {
130         struct libinput_event_pointer_axis *axis_event;
131
132         axis_event = malloc(sizeof *axis_event);
133         if (!axis_event)
134                 return;
135
136         *axis_event = (struct libinput_event_pointer_axis) {
137                 .time = time,
138                 .axis = axis,
139                 .value = value,
140         };
141
142         post_event(device, LIBINPUT_EVENT_POINTER_AXIS, &axis_event->base);
143 }
144
145 void
146 touch_notify_touch(struct libinput_device *device,
147                    uint32_t time,
148                    int32_t slot,
149                    li_fixed_t x,
150                    li_fixed_t y,
151                    enum libinput_touch_type touch_type)
152 {
153         struct libinput_event_touch_touch *touch_event;
154
155         touch_event = malloc(sizeof *touch_event);
156         if (!touch_event)
157                 return;
158
159         *touch_event = (struct libinput_event_touch_touch) {
160                 .time = time,
161                 .slot = slot,
162                 .x = x,
163                 .y = y,
164                 .touch_type = touch_type,
165         };
166
167         post_event(device, LIBINPUT_EVENT_TOUCH_TOUCH, &touch_event->base);
168 }
169
170 static void
171 init_event_base(struct libinput_event *event, enum libinput_event_type type)
172 {
173         event->type = type;
174 }
175
176 static void
177 post_event(struct libinput_device *device,
178            enum libinput_event_type type,
179            struct libinput_event *event)
180 {
181         struct libinput_event **events = device->events;
182         size_t events_len = device->events_len;
183         size_t events_count = device->events_count;
184         size_t move_len;
185         size_t new_out;
186
187         events_count++;
188         if (events_count > events_len) {
189                 if (events_len == 0)
190                         events_len = 4;
191                 else
192                         events_len *= 2;
193                 events = realloc(events, events_len * sizeof *events);
194                 if (!events) {
195                         fprintf(stderr, "Failed to reallocate event ring "
196                                 "buffer");
197                         return;
198                 }
199
200                 if (device->events_count > 0 && device->events_in == 0) {
201                         device->events_in = device->events_len;
202                 } else if (device->events_count > 0 &&
203                            device->events_out >= device->events_in) {
204                         move_len = device->events_len - device->events_out;
205                         new_out = events_len - move_len;
206                         memmove(events + new_out,
207                                 device->events + device->events_out,
208                                 move_len * sizeof *events);
209                         device->events_out = new_out;
210                 }
211
212                 device->events = events;
213                 device->events_len = events_len;
214         }
215
216         init_event_base(event, type);
217
218         device->events_count = events_count;
219         events[device->events_in] = event;
220         device->events_in = (device->events_in + 1) % device->events_len;
221 }
222
223 LIBINPUT_EXPORT struct libinput_event *
224 libinput_device_get_event(struct libinput_device *device)
225 {
226         struct libinput_event *event;
227
228         if (device->events_count == 0)
229                 return NULL;
230
231         event = device->events[device->events_out];
232         device->events_out = (device->events_out + 1) % device->events_len;
233         device->events_count--;
234
235         return event;
236 }
237
238 LIBINPUT_EXPORT int
239 libinput_device_dispatch(struct libinput_device *device)
240 {
241         return evdev_device_dispatch((struct evdev_device *) device);
242 }
243
244 LIBINPUT_EXPORT void
245 libinput_device_destroy(struct libinput_device *device)
246 {
247         struct libinput_event *event;
248
249         while ((event = libinput_device_get_event(device)))
250                free(event);
251         free(device->events);
252
253         evdev_device_destroy((struct evdev_device *) device);
254 }
255
256 LIBINPUT_EXPORT void
257 libinput_device_led_update(struct libinput_device *device,
258                            enum libinput_led leds)
259 {
260         evdev_device_led_update((struct evdev_device *) device, leds);
261 }
262
263 LIBINPUT_EXPORT int
264 libinput_device_get_keys(struct libinput_device *device,
265                          char *keys, size_t size)
266 {
267         return evdev_device_get_keys((struct evdev_device *) device,
268                                      keys,
269                                      size);
270 }
271
272 LIBINPUT_EXPORT void
273 libinput_device_calibrate(struct libinput_device *device,
274                           float calibration[6])
275 {
276         evdev_device_calibrate((struct evdev_device *) device, calibration);
277 }