blob: f4fa5ce87e1b5f09476104e48d86480c4eeadf55 [file] [log] [blame]
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -08001/*
2 * Copyright © 2012 Intel Corporation
3 *
Bryce Harrington2cc92972015-06-11 15:39:40 -07004 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -080011 *
Bryce Harrington2cc92972015-06-11 15:39:40 -070012 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -080024 */
25
Neil Roberts40c0c3f2013-10-29 20:13:45 +000026#include "config.h"
27
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -080028#include <stdlib.h>
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -080029#include <assert.h>
30#include <signal.h>
31#include <unistd.h>
Marek Chalupac8daf772015-03-30 06:37:55 -040032#include <string.h>
Bryce Harringtona7680262014-11-19 17:18:34 -080033
Jon Cruz4678bab2015-06-15 15:37:07 -070034#include "src/compositor.h"
Derek Foremanf6a65922015-02-24 09:32:14 -060035#include "weston-test-server-protocol.h"
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -080036
Neil Roberts40c0c3f2013-10-29 20:13:45 +000037#ifdef ENABLE_EGL
38#include <EGL/egl.h>
39#include <EGL/eglext.h>
Jon Cruz4678bab2015-06-15 15:37:07 -070040#include "src/weston-egl-ext.h"
Neil Roberts40c0c3f2013-10-29 20:13:45 +000041#endif /* ENABLE_EGL */
42
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -080043struct weston_test {
44 struct weston_compositor *compositor;
45 struct weston_layer layer;
46 struct weston_process process;
Marek Chalupac3c3fc42015-03-30 09:17:40 -040047 struct weston_seat seat;
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -080048};
49
50struct weston_test_surface {
51 struct weston_surface *surface;
Jason Ekstranda7af7042013-10-12 22:38:11 -050052 struct weston_view *view;
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -080053 int32_t x, y;
54 struct weston_test *test;
55};
56
57static void
58test_client_sigchld(struct weston_process *process, int status)
59{
60 struct weston_test *test =
61 container_of(process, struct weston_test, process);
62
Emilio Pozuelo Monfortdae8a4b2014-02-07 09:34:48 +010063 /* Chain up from weston-test-runner's exit code so that automake
64 * knows the exit status and can report e.g. skipped tests. */
65 if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
66 exit(WEXITSTATUS(status));
67
68 /* In case the child aborted or segfaulted... */
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -080069 assert(status == 0);
70
71 wl_display_terminate(test->compositor->wl_display);
72}
73
74static struct weston_seat *
75get_seat(struct weston_test *test)
76{
Marek Chalupac3c3fc42015-03-30 09:17:40 -040077 return &test->seat;
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -080078}
79
80static void
81notify_pointer_position(struct weston_test *test, struct wl_resource *resource)
82{
83 struct weston_seat *seat = get_seat(test);
Kristian Høgsberge3148752013-05-06 23:19:49 -040084 struct weston_pointer *pointer = seat->pointer;
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -080085
Derek Foremanf6a65922015-02-24 09:32:14 -060086 weston_test_send_pointer_position(resource, pointer->x, pointer->y);
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -080087}
88
89static void
Jason Ekstrand918f2dd2013-12-02 21:01:53 -060090test_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -080091{
Giulio Camuffo7fe01b12013-03-28 18:02:42 +010092 struct weston_test_surface *test_surface = surface->configure_private;
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -080093 struct weston_test *test = test_surface->test;
94
Giulio Camuffo412e6a52014-07-09 22:12:56 +030095 if (wl_list_empty(&test_surface->view->layer_link.link))
96 weston_layer_entry_insert(&test->layer.view_list,
97 &test_surface->view->layer_link);
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -080098
Jason Ekstrand918f2dd2013-12-02 21:01:53 -060099 weston_view_set_position(test_surface->view,
100 test_surface->x, test_surface->y);
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800101
Kristian Høgsbergace0a392013-11-13 21:55:57 -0800102 weston_view_update_transform(test_surface->view);
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800103}
104
105static void
106move_surface(struct wl_client *client, struct wl_resource *resource,
107 struct wl_resource *surface_resource,
108 int32_t x, int32_t y)
109{
Kristian Høgsberg8f7f4832013-06-25 16:18:35 -0400110 struct weston_surface *surface =
111 wl_resource_get_user_data(surface_resource);
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800112 struct weston_test_surface *test_surface;
113
Giulio Camuffo7fe01b12013-03-28 18:02:42 +0100114 test_surface = surface->configure_private;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500115 if (!test_surface) {
116 test_surface = malloc(sizeof *test_surface);
117 if (!test_surface) {
118 wl_resource_post_no_memory(resource);
119 return;
120 }
121
122 test_surface->view = weston_view_create(surface);
123 if (!test_surface->view) {
124 wl_resource_post_no_memory(resource);
125 free(test_surface);
126 return;
127 }
128
129 surface->configure_private = test_surface;
130 surface->configure = test_surface_configure;
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800131 }
132
133 test_surface->surface = surface;
Kristian Høgsberg8f7f4832013-06-25 16:18:35 -0400134 test_surface->test = wl_resource_get_user_data(resource);
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800135 test_surface->x = x;
136 test_surface->y = y;
137}
138
139static void
140move_pointer(struct wl_client *client, struct wl_resource *resource,
141 int32_t x, int32_t y)
142{
Kristian Høgsberg8f7f4832013-06-25 16:18:35 -0400143 struct weston_test *test = wl_resource_get_user_data(resource);
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800144 struct weston_seat *seat = get_seat(test);
Kristian Høgsberge3148752013-05-06 23:19:49 -0400145 struct weston_pointer *pointer = seat->pointer;
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800146
Kristian Høgsberg068b61c2013-02-25 17:04:47 -0500147 notify_motion(seat, 100,
148 wl_fixed_from_int(x) - pointer->x,
149 wl_fixed_from_int(y) - pointer->y);
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800150
151 notify_pointer_position(test, resource);
152}
153
154static void
155send_button(struct wl_client *client, struct wl_resource *resource,
156 int32_t button, uint32_t state)
157{
Kristian Høgsberg8f7f4832013-06-25 16:18:35 -0400158 struct weston_test *test = wl_resource_get_user_data(resource);
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800159 struct weston_seat *seat = get_seat(test);
160
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800161 notify_button(seat, 100, button, state);
162}
163
164static void
165activate_surface(struct wl_client *client, struct wl_resource *resource,
166 struct wl_resource *surface_resource)
167{
168 struct weston_surface *surface = surface_resource ?
Kristian Høgsberg8f7f4832013-06-25 16:18:35 -0400169 wl_resource_get_user_data(surface_resource) : NULL;
170 struct weston_test *test = wl_resource_get_user_data(resource);
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800171 struct weston_seat *seat;
172
173 seat = get_seat(test);
174
175 if (surface) {
176 weston_surface_activate(surface, seat);
Kristian Høgsberge3148752013-05-06 23:19:49 -0400177 notify_keyboard_focus_in(seat, &seat->keyboard->keys,
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800178 STATE_UPDATE_AUTOMATIC);
179 }
180 else {
181 notify_keyboard_focus_out(seat);
182 weston_surface_activate(surface, seat);
183 }
184}
185
186static void
187send_key(struct wl_client *client, struct wl_resource *resource,
188 uint32_t key, enum wl_keyboard_key_state state)
189{
Kristian Høgsberg8f7f4832013-06-25 16:18:35 -0400190 struct weston_test *test = wl_resource_get_user_data(resource);
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800191 struct weston_seat *seat = get_seat(test);
192
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800193 notify_key(seat, 100, key, state, STATE_UPDATE_AUTOMATIC);
194}
195
Marek Chalupac8daf772015-03-30 06:37:55 -0400196static void
197device_release(struct wl_client *client,
198 struct wl_resource *resource, const char *device)
199{
200 struct weston_test *test = wl_resource_get_user_data(resource);
201 struct weston_seat *seat = get_seat(test);
202
203 if (strcmp(device, "pointer") == 0) {
204 weston_seat_release_pointer(seat);
205 } else if (strcmp(device, "keyboard") == 0) {
206 weston_seat_release_keyboard(seat);
207 } else if (strcmp(device, "touch") == 0) {
208 weston_seat_release_touch(seat);
209 } else if (strcmp(device, "seat") == 0) {
210 weston_seat_release(seat);
211 } else {
212 assert(0 && "Unsupported device");
213 }
214}
215
216static void
217device_add(struct wl_client *client,
218 struct wl_resource *resource, const char *device)
219{
220 struct weston_test *test = wl_resource_get_user_data(resource);
221 struct weston_seat *seat = get_seat(test);
222
223 if (strcmp(device, "pointer") == 0) {
224 weston_seat_init_pointer(seat);
225 } else if (strcmp(device, "keyboard") == 0) {
226 weston_seat_init_keyboard(seat, NULL);
227 } else if (strcmp(device, "touch") == 0) {
228 weston_seat_init_touch(seat);
229 } else {
230 assert(0 && "Unsupported device");
231 }
232}
233
Neil Roberts40c0c3f2013-10-29 20:13:45 +0000234#ifdef ENABLE_EGL
235static int
236is_egl_buffer(struct wl_resource *resource)
237{
238 PFNEGLQUERYWAYLANDBUFFERWL query_buffer =
239 (void *) eglGetProcAddress("eglQueryWaylandBufferWL");
240 EGLint format;
241
242 if (query_buffer(eglGetCurrentDisplay(),
243 resource,
244 EGL_TEXTURE_FORMAT,
245 &format))
246 return 1;
247
248 return 0;
249}
250#endif /* ENABLE_EGL */
251
252static void
253get_n_buffers(struct wl_client *client, struct wl_resource *resource)
254{
255 int n_buffers = 0;
256
257#ifdef ENABLE_EGL
258 struct wl_resource *buffer_resource;
259 int i;
260
261 for (i = 0; i < 1000; i++) {
262 buffer_resource = wl_client_get_object(client, i);
263
264 if (buffer_resource == NULL)
265 continue;
266
267 if (is_egl_buffer(buffer_resource))
268 n_buffers++;
269 }
270#endif /* ENABLE_EGL */
271
Derek Foremanf6a65922015-02-24 09:32:14 -0600272 weston_test_send_n_egl_buffers(resource, n_buffers);
Neil Roberts40c0c3f2013-10-29 20:13:45 +0000273}
274
Bryce Harringtonf280d112015-05-05 15:13:20 -0700275enum weston_test_screenshot_outcome {
276 WESTON_TEST_SCREENSHOT_SUCCESS,
277 WESTON_TEST_SCREENSHOT_NO_MEMORY,
278 WESTON_TEST_SCREENSHOT_BAD_BUFFER
279 };
280
281typedef void (*weston_test_screenshot_done_func_t)(void *data,
282 enum weston_test_screenshot_outcome outcome);
283
284struct test_screenshot {
285 struct weston_compositor *compositor;
286 struct wl_global *global;
287 struct wl_client *client;
288 struct weston_process process;
289 struct wl_listener destroy_listener;
290};
291
292struct test_screenshot_frame_listener {
293 struct wl_listener listener;
294 struct weston_buffer *buffer;
295 weston_test_screenshot_done_func_t done;
296 void *data;
297};
298
299static void
300copy_bgra_yflip(uint8_t *dst, uint8_t *src, int height, int stride)
301{
302 uint8_t *end;
303
304 end = dst + height * stride;
305 while (dst < end) {
306 memcpy(dst, src, stride);
307 dst += stride;
308 src -= stride;
309 }
310}
311
312
313static void
314copy_bgra(uint8_t *dst, uint8_t *src, int height, int stride)
315{
316 /* TODO: optimize this out */
317 memcpy(dst, src, height * stride);
318}
319
320static void
321copy_row_swap_RB(void *vdst, void *vsrc, int bytes)
322{
323 uint32_t *dst = vdst;
324 uint32_t *src = vsrc;
325 uint32_t *end = dst + bytes / 4;
326
327 while (dst < end) {
328 uint32_t v = *src++;
329 /* A R G B */
330 uint32_t tmp = v & 0xff00ff00;
331 tmp |= (v >> 16) & 0x000000ff;
332 tmp |= (v << 16) & 0x00ff0000;
333 *dst++ = tmp;
334 }
335}
336
337static void
338copy_rgba_yflip(uint8_t *dst, uint8_t *src, int height, int stride)
339{
340 uint8_t *end;
341
342 end = dst + height * stride;
343 while (dst < end) {
344 copy_row_swap_RB(dst, src, stride);
345 dst += stride;
346 src -= stride;
347 }
348}
349
350static void
351copy_rgba(uint8_t *dst, uint8_t *src, int height, int stride)
352{
353 uint8_t *end;
354
355 end = dst + height * stride;
356 while (dst < end) {
357 copy_row_swap_RB(dst, src, stride);
358 dst += stride;
359 src += stride;
360 }
361}
362
363static void
364test_screenshot_frame_notify(struct wl_listener *listener, void *data)
365{
366 struct test_screenshot_frame_listener *l =
367 container_of(listener,
368 struct test_screenshot_frame_listener, listener);
369 struct weston_output *output = data;
370 struct weston_compositor *compositor = output->compositor;
371 int32_t stride;
372 uint8_t *pixels, *d, *s;
373
374 output->disable_planes--;
375 wl_list_remove(&listener->link);
376 stride = l->buffer->width * (PIXMAN_FORMAT_BPP(compositor->read_format) / 8);
377 pixels = malloc(stride * l->buffer->height);
378
379 if (pixels == NULL) {
380 l->done(l->data, WESTON_TEST_SCREENSHOT_NO_MEMORY);
381 free(l);
382 return;
383 }
384
385 // FIXME: Needs to handle output transformations
386
387 compositor->renderer->read_pixels(output,
388 compositor->read_format,
389 pixels,
390 0, 0,
391 output->current_mode->width,
392 output->current_mode->height);
393
394 stride = wl_shm_buffer_get_stride(l->buffer->shm_buffer);
395
396 d = wl_shm_buffer_get_data(l->buffer->shm_buffer);
397 s = pixels + stride * (l->buffer->height - 1);
398
399 wl_shm_buffer_begin_access(l->buffer->shm_buffer);
400
401 /* XXX: It would be nice if we used Pixman to do all this rather
402 * than our own implementation
403 */
404 switch (compositor->read_format) {
405 case PIXMAN_a8r8g8b8:
406 case PIXMAN_x8r8g8b8:
407 if (compositor->capabilities & WESTON_CAP_CAPTURE_YFLIP)
408 copy_bgra_yflip(d, s, output->current_mode->height, stride);
409 else
410 copy_bgra(d, pixels, output->current_mode->height, stride);
411 break;
412 case PIXMAN_x8b8g8r8:
413 case PIXMAN_a8b8g8r8:
414 if (compositor->capabilities & WESTON_CAP_CAPTURE_YFLIP)
415 copy_rgba_yflip(d, s, output->current_mode->height, stride);
416 else
417 copy_rgba(d, pixels, output->current_mode->height, stride);
418 break;
419 default:
420 break;
421 }
422
423 wl_shm_buffer_end_access(l->buffer->shm_buffer);
424
425 l->done(l->data, WESTON_TEST_SCREENSHOT_SUCCESS);
426 free(pixels);
427 free(l);
428}
429
430static bool
431weston_test_screenshot_shoot(struct weston_output *output,
432 struct weston_buffer *buffer,
433 weston_test_screenshot_done_func_t done,
434 void *data)
435{
436 struct test_screenshot_frame_listener *l;
437
438 /* Get the shm buffer resource the client created */
439 if (!wl_shm_buffer_get(buffer->resource)) {
440 done(data, WESTON_TEST_SCREENSHOT_BAD_BUFFER);
441 return false;
442 }
443
444 buffer->shm_buffer = wl_shm_buffer_get(buffer->resource);
445 buffer->width = wl_shm_buffer_get_width(buffer->shm_buffer);
446 buffer->height = wl_shm_buffer_get_height(buffer->shm_buffer);
447
448 /* Verify buffer is big enough */
449 if (buffer->width < output->current_mode->width ||
450 buffer->height < output->current_mode->height) {
451 done(data, WESTON_TEST_SCREENSHOT_BAD_BUFFER);
452 return false;
453 }
454
455 /* allocate the frame listener */
456 l = malloc(sizeof *l);
457 if (l == NULL) {
458 done(data, WESTON_TEST_SCREENSHOT_NO_MEMORY);
459 return false;
460 }
461
462 /* Set up the listener */
463 l->buffer = buffer;
464 l->done = done;
465 l->data = data;
466 l->listener.notify = test_screenshot_frame_notify;
467 wl_signal_add(&output->frame_signal, &l->listener);
468
469 /* Fire off a repaint */
470 output->disable_planes++;
471 weston_output_schedule_repaint(output);
472
473 return true;
474}
475
476static void
477capture_screenshot_done(void *data, enum weston_test_screenshot_outcome outcome)
478{
479 struct wl_resource *resource = data;
480
481 switch (outcome) {
482 case WESTON_TEST_SCREENSHOT_SUCCESS:
483 weston_test_send_capture_screenshot_done(resource);
484 break;
485 case WESTON_TEST_SCREENSHOT_NO_MEMORY:
486 wl_resource_post_no_memory(resource);
487 break;
488 default:
489 break;
490 }
491}
492
493
494/**
495 * Grabs a snapshot of the screen.
496 */
497static void
498capture_screenshot(struct wl_client *client,
499 struct wl_resource *resource,
500 struct wl_resource *output_resource,
501 struct wl_resource *buffer_resource)
502{
503 struct weston_output *output =
504 wl_resource_get_user_data(output_resource);
505 struct weston_buffer *buffer =
506 weston_buffer_from_resource(buffer_resource);
507
508 if (buffer == NULL) {
509 wl_resource_post_no_memory(resource);
510 return;
511 }
512
513 weston_test_screenshot_shoot(output, buffer,
514 capture_screenshot_done, resource);
515}
516
Derek Foremanf6a65922015-02-24 09:32:14 -0600517static const struct weston_test_interface test_implementation = {
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800518 move_surface,
519 move_pointer,
520 send_button,
521 activate_surface,
Neil Roberts40c0c3f2013-10-29 20:13:45 +0000522 send_key,
Marek Chalupac8daf772015-03-30 06:37:55 -0400523 device_release,
524 device_add,
Neil Roberts40c0c3f2013-10-29 20:13:45 +0000525 get_n_buffers,
Bryce Harringtonf280d112015-05-05 15:13:20 -0700526 capture_screenshot,
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800527};
528
529static void
530bind_test(struct wl_client *client, void *data, uint32_t version, uint32_t id)
531{
532 struct weston_test *test = data;
533 struct wl_resource *resource;
534
Derek Foremanf6a65922015-02-24 09:32:14 -0600535 resource = wl_resource_create(client, &weston_test_interface, 1, id);
Marek Chalupa42ebdda2014-07-11 12:33:02 +0200536 if (!resource) {
537 wl_client_post_no_memory(client);
538 return;
539 }
540
Kristian Høgsberg442a5fa2013-07-03 18:13:33 -0400541 wl_resource_set_implementation(resource,
542 &test_implementation, test, NULL);
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800543
544 notify_pointer_position(test, resource);
545}
546
547static void
548idle_launch_client(void *data)
549{
550 struct weston_test *test = data;
551 pid_t pid;
552 sigset_t allsigs;
553 char *path;
554
555 path = getenv("WESTON_TEST_CLIENT_PATH");
556 if (path == NULL)
Pekka Paalanenf72e4792013-11-21 16:23:57 +0200557 return;
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800558 pid = fork();
559 if (pid == -1)
560 exit(EXIT_FAILURE);
561 if (pid == 0) {
562 sigfillset(&allsigs);
563 sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
564 execl(path, path, NULL);
565 weston_log("compositor: executing '%s' failed: %m\n", path);
566 exit(EXIT_FAILURE);
567 }
568
569 test->process.pid = pid;
570 test->process.cleanup = test_client_sigchld;
571 weston_watch_process(&test->process);
572}
573
574WL_EXPORT int
Kristian Høgsbergcb4685b2013-02-20 15:37:49 -0500575module_init(struct weston_compositor *ec,
Ossama Othmana50e6e42013-05-14 09:48:26 -0700576 int *argc, char *argv[])
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800577{
578 struct weston_test *test;
579 struct wl_event_loop *loop;
580
Peter Huttererf3d62272013-08-08 11:57:05 +1000581 test = zalloc(sizeof *test);
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800582 if (test == NULL)
583 return -1;
584
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800585 test->compositor = ec;
586 weston_layer_init(&test->layer, &ec->cursor_layer.link);
587
Derek Foremanf6a65922015-02-24 09:32:14 -0600588 if (wl_global_create(ec->wl_display, &weston_test_interface, 1,
Kristian Høgsberg919cddb2013-07-08 19:03:57 -0400589 test, bind_test) == NULL)
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800590 return -1;
591
Marek Chalupac3c3fc42015-03-30 09:17:40 -0400592 /* create our own seat */
593 weston_seat_init(&test->seat, ec, "test-seat");
594
595 /* add devices */
596 weston_seat_init_pointer(&test->seat);
597 weston_seat_init_keyboard(&test->seat, NULL);
598 weston_seat_init_touch(&test->seat);
599
U. Artie Eoff65e7e7a2012-12-07 13:50:29 -0800600 loop = wl_display_get_event_loop(ec->wl_display);
601 wl_event_loop_add_idle(loop, idle_launch_client, test);
602
603 return 0;
604}