Hook up axis events.
[profile/ivi/weston.git] / clients / simple-touch.c
1 /*
2  * Copyright © 2011 Benjamin Franzke
3  * Copyright © 2011 Intel Corporation
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and its
6  * documentation for any purpose is hereby granted without fee, provided that
7  * the above copyright notice appear in all copies and that both that copyright
8  * notice and this permission notice appear in supporting documentation, and
9  * that the name of the copyright holders not be used in advertising or
10  * publicity pertaining to distribution of the software without specific,
11  * written prior permission.  The copyright holders make no representations
12  * about the suitability of this software for any purpose.  It is provided "as
13  * is" without express or implied warranty.
14  *
15  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21  * OF THIS SOFTWARE.
22  */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdbool.h>
28 #include <assert.h>
29 #include <unistd.h>
30 #include <sys/mman.h>
31
32 #include <wayland-client.h>
33 #include <wayland-egl.h>
34
35 struct touch {
36         struct wl_display *display;
37         struct wl_compositor *compositor;
38         struct wl_shell *shell;
39         struct wl_shm *shm;
40         struct wl_input_device *input_device;
41         struct wl_surface *surface;
42         struct wl_shell_surface *shell_surface;
43         struct wl_buffer *buffer;
44         int has_argb;
45         uint32_t mask;
46         int width, height;
47         void *data;
48 };
49
50 static void
51 create_shm_buffer(struct touch *touch)
52 {
53         char filename[] = "/tmp/wayland-shm-XXXXXX";
54         int fd, size, stride;
55
56         fd = mkstemp(filename);
57         if (fd < 0) {
58                 fprintf(stderr, "open %s failed: %m\n", filename);
59                 exit(1);
60         }
61         stride = touch->width * 4;
62         size = stride * touch->height;
63         if (ftruncate(fd, size) < 0) {
64                 fprintf(stderr, "ftruncate failed: %m\n");
65                 close(fd);
66                 exit(1);
67         }
68
69         touch->data =
70                 mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
71         unlink(filename);
72
73         if (touch->data == MAP_FAILED) {
74                 fprintf(stderr, "mmap failed: %m\n");
75                 close(fd);
76                 exit(1);
77         }
78
79         touch->buffer =
80                 wl_shm_create_buffer(touch->shm, fd,
81                                      touch->width, touch->height, stride,
82                                      WL_SHM_FORMAT_ARGB8888);
83
84         close(fd);
85 }
86
87 static void
88 shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
89 {
90         struct touch *touch = data;
91
92         if (format == WL_SHM_FORMAT_ARGB8888)
93                 touch->has_argb = 1;
94 }
95
96 struct wl_shm_listener shm_listenter = {
97         shm_format
98 };
99
100
101 static void
102 input_device_handle_motion(void *data, struct wl_input_device *input_device,
103                            uint32_t time, int32_t sx, int32_t sy)
104 {
105 }
106
107 static void
108 input_device_handle_button(void *data,
109                            struct wl_input_device *input_device,
110                            uint32_t time, uint32_t button, uint32_t state)
111 {
112 }
113
114 static void
115 input_device_handle_axis(void *data, struct wl_input_device *input_device,
116                         uint32_t time, uint32_t axis, int32_t value)
117 {
118 }
119
120 static void
121 input_device_handle_key(void *data, struct wl_input_device *input_device,
122                         uint32_t time, uint32_t key, uint32_t state)
123 {
124 }
125
126 static void
127 input_device_handle_pointer_enter(void *data,
128                                   struct wl_input_device *input_device,
129                                   uint32_t time, struct wl_surface *surface,
130                                   int32_t sx, int32_t sy)
131 {
132 }
133
134 static void
135 input_device_handle_pointer_leave(void *data,
136                                   struct wl_input_device *input_device,
137                                   uint32_t time, struct wl_surface *surface)
138 {
139 }
140
141 static void
142 input_device_handle_keyboard_enter(void *data,
143                                    struct wl_input_device *input_device,
144                                    uint32_t time,
145                                    struct wl_surface *surface,
146                                    struct wl_array *keys)
147 {
148 }
149
150 static void
151 input_device_handle_keyboard_leave(void *data,
152                                    struct wl_input_device *input_device,
153                                    uint32_t time,
154                                    struct wl_surface *surface)
155 {
156 }
157
158 static void
159 touch_paint(struct touch *touch, int32_t x, int32_t y, int32_t id)
160 {
161         uint32_t *p, c;
162         static const uint32_t colors[] = {
163                 0xffff0000,
164                 0xffffff00,
165                 0xff0000ff,
166                 0xffff00ff,
167         };
168
169         if (id < ARRAY_LENGTH(colors))
170                 c = colors[id];
171         else
172                 c = 0xffffffff;
173
174         if (x < 1 || touch->width - 1 < x ||
175             y < 1 || touch->height - 1 < y)
176                 return;
177
178         p = (uint32_t *) touch->data + (x - 1) + (y -1 ) * touch->width;
179         p[1] = c;
180         p += touch->width;
181         p[0] = c;
182         p[1] = c;
183         p[2] = c;
184         p += touch->width;
185         p[1] = c;
186
187         wl_buffer_damage(touch->buffer, 0, 0, touch->width, touch->height);
188         wl_surface_damage(touch->surface,
189                           0, 0, touch->width, touch->height);
190 }
191
192 static void
193 input_device_handle_touch_down(void *data,
194                                struct wl_input_device *wl_input_device,
195                                uint32_t time, struct wl_surface *surface,
196                                int32_t id, int32_t x, int32_t y)
197 {
198         struct touch *touch = data;
199
200         touch_paint(touch, x, y, id);
201 }
202
203 static void
204 input_device_handle_touch_up(void *data,
205                              struct wl_input_device *wl_input_device,
206                              uint32_t time, int32_t id)
207 {
208 }
209
210 static void
211 input_device_handle_touch_motion(void *data,
212                                  struct wl_input_device *wl_input_device,
213                                  uint32_t time,
214                                  int32_t id, int32_t x, int32_t y)
215 {
216         struct touch *touch = data;
217
218         touch_paint(touch, x, y, id);
219 }
220
221 static void
222 input_device_handle_touch_frame(void *data,
223                                 struct wl_input_device *wl_input_device)
224 {
225 }
226
227 static void
228 input_device_handle_touch_cancel(void *data,
229                                  struct wl_input_device *wl_input_device)
230 {
231 }
232
233 static const struct wl_input_device_listener input_device_listener = {
234         input_device_handle_motion,
235         input_device_handle_button,
236         input_device_handle_axis,
237         input_device_handle_key,
238         input_device_handle_pointer_enter,
239         input_device_handle_pointer_leave,
240         input_device_handle_keyboard_enter,
241         input_device_handle_keyboard_leave,
242         input_device_handle_touch_down,
243         input_device_handle_touch_up,
244         input_device_handle_touch_motion,
245         input_device_handle_touch_frame,
246         input_device_handle_touch_cancel,
247 };
248
249 static void
250 handle_global(struct wl_display *display, uint32_t id,
251               const char *interface, uint32_t version, void *data)
252 {
253         struct touch *touch = data;
254
255         if (strcmp(interface, "wl_compositor") == 0) {
256                 touch->compositor =
257                         wl_display_bind(display, id, &wl_compositor_interface);
258         } else if (strcmp(interface, "wl_shell") == 0) {
259                 touch->shell =
260                         wl_display_bind(display, id, &wl_shell_interface);
261         } else if (strcmp(interface, "wl_shm") == 0) {
262                 touch->shm = wl_display_bind(display, id, &wl_shm_interface);
263                 wl_shm_add_listener(touch->shm, &shm_listenter, touch);
264         } else if (strcmp(interface, "wl_input_device") == 0) {
265                 touch->input_device =
266                         wl_display_bind(display, id,
267                                         &wl_input_device_interface);
268                 wl_input_device_add_listener(touch->input_device,
269                                              &input_device_listener, touch);
270         }
271 }
272
273 static int
274 event_mask_update(uint32_t mask, void *data)
275 {
276         struct touch *touch = data;
277
278         touch->mask = mask;
279
280         return 0;
281 }
282
283 static struct touch *
284 touch_create(int width, int height)
285 {
286         struct touch *touch;
287
288         touch = malloc(sizeof *touch);
289         touch->display = wl_display_connect(NULL);
290         assert(touch->display);
291
292         touch->has_argb = 0;
293         wl_display_add_global_listener(touch->display, handle_global, touch);
294         wl_display_iterate(touch->display, WL_DISPLAY_READABLE);
295         wl_display_roundtrip(touch->display);
296
297         if (!touch->has_argb) {
298                 fprintf(stderr, "WL_SHM_FORMAT_ARGB32 not available\n");
299                 exit(1);
300         }
301
302         wl_display_get_fd(touch->display, event_mask_update, touch);
303         
304         touch->width = width;
305         touch->height = height;
306         touch->surface = wl_compositor_create_surface(touch->compositor);
307         touch->shell_surface = wl_shell_get_shell_surface(touch->shell,
308                                                           touch->surface);
309         create_shm_buffer(touch);
310
311         wl_shell_surface_set_toplevel(touch->shell_surface);
312         wl_surface_set_user_data(touch->surface, touch);
313
314         memset(touch->data, 64, width * height * 4);
315         wl_buffer_damage(touch->buffer, 0, 0, width, height);
316         wl_surface_attach(touch->surface, touch->buffer, 0, 0);
317         wl_surface_damage(touch->surface, 0, 0, width, height);
318
319         return touch;
320 }
321
322 int
323 main(int argc, char **argv)
324 {
325         struct touch *touch;
326
327         touch = touch_create(600, 500);
328
329         while (true)
330                 wl_display_iterate(touch->display, touch->mask);
331
332         return 0;
333 }