x11: Remove destroy listener when X11 window is destroyed
[platform/upstream/weston.git] / compositor / compositor.c
1 /*
2  * Copyright © 2010-2011 Intel Corporation
3  * Copyright © 2008-2011 Kristian Høgsberg
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and
6  * its documentation for any purpose is hereby granted without fee, provided
7  * that the above copyright notice appear in all copies and that both that
8  * copyright notice and this permission notice appear in supporting
9  * documentation, and that the name of the copyright holders not be used in
10  * advertising or publicity pertaining to distribution of the software
11  * without specific, written prior permission.  The copyright holders make
12  * no representations about the suitability of this software for any
13  * purpose.  It is provided "as is" without express or implied warranty.
14  *
15  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
20  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  */
23
24 #define _GNU_SOURCE
25
26 #include "config.h"
27
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <stdint.h>
32 #include <limits.h>
33 #include <stdarg.h>
34 #include <assert.h>
35 #include <sys/ioctl.h>
36 #include <sys/wait.h>
37 #include <sys/types.h>
38 #include <sys/socket.h>
39 #include <fcntl.h>
40 #include <unistd.h>
41 #include <math.h>
42 #include <linux/input.h>
43 #include <dlfcn.h>
44 #include <getopt.h>
45 #include <signal.h>
46
47 #include <wayland-server.h>
48 #include "compositor.h"
49
50 static const char *option_socket_name = NULL;
51
52 static struct wl_list child_process_list;
53
54 static int
55 sigchld_handler(int signal_number, void *data)
56 {
57         struct wlsc_process *p;
58         int status;
59         pid_t pid;
60
61         pid = wait(&status);
62         wl_list_for_each(p, &child_process_list, link) {
63                 if (p->pid == pid)
64                         break;
65         }
66
67         if (&p->link == &child_process_list) {
68                 fprintf(stderr, "unknown child process exited\n");
69                 return 1;
70         }
71
72         wl_list_remove(&p->link);
73         p->cleanup(p, status);
74
75         return 1;
76 }
77
78 WL_EXPORT void
79 wlsc_watch_process(struct wlsc_process *process)
80 {
81         wl_list_insert(&child_process_list, &process->link);
82 }
83
84 static void
85 child_client_exec(int sockfd, const char *path)
86 {
87         int clientfd;
88         char s[32];
89         sigset_t allsigs;
90
91         /* do not give our signal mask to the new process */
92         sigfillset(&allsigs);
93         sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
94
95         /* SOCK_CLOEXEC closes both ends, so we dup the fd to get a
96          * non-CLOEXEC fd to pass through exec. */
97         clientfd = dup(sockfd);
98         if (clientfd == -1) {
99                 fprintf(stderr, "compositor: dup failed: %m\n");
100                 return;
101         }
102
103         snprintf(s, sizeof s, "%d", clientfd);
104         setenv("WAYLAND_SOCKET", s, 1);
105
106         if (execl(path, path, NULL) < 0)
107                 fprintf(stderr, "compositor: executing '%s' failed: %m\n",
108                         path);
109 }
110
111 WL_EXPORT struct wl_client *
112 wlsc_client_launch(struct wlsc_compositor *compositor,
113                    struct wlsc_process *proc,
114                    const char *path,
115                    wlsc_process_cleanup_func_t cleanup)
116 {
117         int sv[2];
118         pid_t pid;
119         struct wl_client *client;
120
121         if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) {
122                 fprintf(stderr, "wlsc_client_launch: "
123                         "socketpair failed while launching '%s': %m\n",
124                         path);
125                 return NULL;
126         }
127
128         pid = fork();
129         if (pid == -1) {
130                 close(sv[0]);
131                 close(sv[1]);
132                 fprintf(stderr,  "wlsc_client_launch: "
133                         "fork failed while launching '%s': %m\n", path);
134                 return NULL;
135         }
136
137         if (pid == 0) {
138                 child_client_exec(sv[1], path);
139                 exit(-1);
140         }
141
142         close(sv[1]);
143
144         client = wl_client_create(compositor->wl_display, sv[0]);
145         if (!client) {
146                 close(sv[0]);
147                 fprintf(stderr, "wlsc_client_launch: "
148                         "wl_client_create failed while launching '%s'.\n",
149                         path);
150                 return NULL;
151         }
152
153         proc->pid = pid;
154         proc->cleanup = cleanup;
155         wlsc_watch_process(proc);
156
157         return client;
158 }
159
160 static void
161 surface_handle_buffer_destroy(struct wl_listener *listener,
162                               struct wl_resource *resource, uint32_t time)
163 {
164         struct wlsc_surface *es = container_of(listener, struct wlsc_surface, 
165                                                buffer_destroy_listener);
166
167         es->buffer = NULL;
168 }
169
170 static void
171 output_handle_scanout_buffer_destroy(struct wl_listener *listener,
172                                      struct wl_resource *resource,
173                                      uint32_t time)
174 {
175         struct wlsc_output *output =
176                 container_of(listener, struct wlsc_output,
177                              scanout_buffer_destroy_listener);
178
179         output->scanout_buffer = NULL;
180
181         if (!output->pending_scanout_buffer)
182                 wlsc_compositor_schedule_repaint(output->compositor);
183 }
184
185 static void
186 output_handle_pending_scanout_buffer_destroy(struct wl_listener *listener,
187                                              struct wl_resource *resource,
188                                              uint32_t time)
189 {
190         struct wlsc_output *output =
191                 container_of(listener, struct wlsc_output,
192                              pending_scanout_buffer_destroy_listener);
193
194         output->pending_scanout_buffer = NULL;
195
196         wlsc_compositor_schedule_repaint(output->compositor);
197 }
198
199
200 WL_EXPORT struct wlsc_surface *
201 wlsc_surface_create(struct wlsc_compositor *compositor,
202                     int32_t x, int32_t y, int32_t width, int32_t height)
203 {
204         struct wlsc_surface *surface;
205
206         surface = calloc(1, sizeof *surface);
207         if (surface == NULL)
208                 return NULL;
209
210         wl_list_init(&surface->link);
211         wl_list_init(&surface->buffer_link);
212
213         glGenTextures(1, &surface->texture);
214         glBindTexture(GL_TEXTURE_2D, surface->texture);
215         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
216         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
217
218         surface->surface.resource.client = NULL;
219
220         surface->compositor = compositor;
221         surface->visual = WLSC_NONE_VISUAL;
222         surface->image = EGL_NO_IMAGE_KHR;
223         surface->saved_texture = 0;
224         surface->x = x;
225         surface->y = y;
226         surface->width = width;
227         surface->height = height;
228         surface->alpha = 255;
229
230         surface->fullscreen_output = NULL;
231         surface->buffer = NULL;
232         surface->output = NULL;
233
234         pixman_region32_init(&surface->damage);
235         pixman_region32_init(&surface->opaque);
236         wl_list_init(&surface->frame_callback_list);
237
238         surface->buffer_destroy_listener.func = surface_handle_buffer_destroy;
239
240         surface->transform = NULL;
241
242         return surface;
243 }
244
245 WL_EXPORT void
246 wlsc_surface_damage_rectangle(struct wlsc_surface *surface,
247                               int32_t x, int32_t y,
248                               int32_t width, int32_t height)
249 {
250         struct wlsc_compositor *compositor = surface->compositor;
251
252         pixman_region32_union_rect(&surface->damage,
253                                    &surface->damage,
254                                    surface->x + x, surface->y + y,
255                                    width, height);
256         wlsc_compositor_schedule_repaint(compositor);
257 }
258
259 WL_EXPORT void
260 wlsc_surface_damage(struct wlsc_surface *surface)
261 {
262         wlsc_surface_damage_rectangle(surface, 0, 0,
263                                       surface->width, surface->height);
264 }
265
266 WL_EXPORT void
267 wlsc_surface_damage_below(struct wlsc_surface *surface)
268 {
269         struct wlsc_surface *below;
270
271         if (surface->output == NULL)
272                 return;
273
274         if (surface->link.next == &surface->compositor->surface_list)
275                 return;
276
277         below = container_of(surface->link.next, struct wlsc_surface, link);
278
279         pixman_region32_union_rect(&below->damage,
280                                    &below->damage,
281                                    surface->x, surface->y,
282                                    surface->width, surface->height);
283         wlsc_compositor_schedule_repaint(surface->compositor);
284 }
285
286 WL_EXPORT void
287 wlsc_surface_configure(struct wlsc_surface *surface,
288                        int x, int y, int width, int height)
289 {
290         wlsc_surface_damage_below(surface);
291
292         surface->x = x;
293         surface->y = y;
294         surface->width = width;
295         surface->height = height;
296
297         wlsc_surface_assign_output(surface);
298         wlsc_surface_damage(surface);
299
300         pixman_region32_fini(&surface->opaque);
301         if (surface->visual == WLSC_RGB_VISUAL)
302                 pixman_region32_init_rect(&surface->opaque,
303                                           surface->x, surface->y,
304                                           surface->width, surface->height);
305         else
306                 pixman_region32_init(&surface->opaque);
307 }
308
309 WL_EXPORT uint32_t
310 wlsc_compositor_get_time(void)
311 {
312         struct timeval tv;
313
314         gettimeofday(&tv, NULL);
315
316         return tv.tv_sec * 1000 + tv.tv_usec / 1000;
317 }
318
319 WL_EXPORT void
320 wlsc_compositor_repick(struct wlsc_compositor *compositor)
321 {
322         struct wlsc_input_device *device;
323         struct wlsc_surface *surface;
324         int32_t sx, sy;
325         uint32_t time;
326
327         if (!compositor->focus)
328                 return;
329
330         time = wlsc_compositor_get_time();
331         wl_list_for_each(device, &compositor->input_device_list, link) {
332                 if (device->input_device.grab)
333                         continue;
334                 surface = pick_surface(&device->input_device, &sx, &sy);
335                 wl_input_device_set_pointer_focus(&device->input_device,
336                                                   &surface->surface,
337                                                   time,
338                                                   device->input_device.x,
339                                                   device->input_device.y,
340                                                   sx, sy);
341         }
342 }
343
344 static void
345 destroy_surface(struct wl_resource *resource)
346 {
347         struct wlsc_surface *surface =
348                 container_of(resource, struct wlsc_surface, surface.resource);
349         struct wlsc_compositor *compositor = surface->compositor;
350
351         wlsc_surface_damage_below(surface);
352
353         wl_list_remove(&surface->link);
354         wlsc_compositor_repick(compositor);
355
356         if (surface->saved_texture == 0)
357                 glDeleteTextures(1, &surface->texture);
358         else
359                 glDeleteTextures(1, &surface->saved_texture);
360
361         if (surface->buffer)
362                 wl_list_remove(&surface->buffer_destroy_listener.link);
363
364         if (surface->image != EGL_NO_IMAGE_KHR)
365                 compositor->destroy_image(compositor->display,
366                                           surface->image);
367
368         wl_list_remove(&surface->buffer_link);
369
370         free(surface);
371 }
372
373 static void
374 wlsc_buffer_attach(struct wl_buffer *buffer, struct wl_surface *surface)
375 {
376         struct wlsc_surface *es = (struct wlsc_surface *) surface;
377         struct wlsc_compositor *ec = es->compositor;
378         struct wl_list *surfaces_attached_to;
379
380         if (es->saved_texture != 0)
381                 es->texture = es->saved_texture;
382
383         glBindTexture(GL_TEXTURE_2D, es->texture);
384
385         if (wl_buffer_is_shm(buffer)) {
386                 /* Unbind any EGLImage texture that may be bound, so we don't
387                  * overwrite it.*/
388                 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
389                              0, 0, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
390                 es->pitch = wl_shm_buffer_get_stride(buffer) / 4;
391                 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
392                              es->pitch, buffer->height, 0,
393                              GL_BGRA_EXT, GL_UNSIGNED_BYTE,
394                              wl_shm_buffer_get_data(buffer));
395
396                 switch (wl_shm_buffer_get_format(buffer)) {
397                 case WL_SHM_FORMAT_ARGB32:
398                         es->visual = WLSC_ARGB_VISUAL;
399                         break;
400                 case WL_SHM_FORMAT_PREMULTIPLIED_ARGB32:
401                         es->visual = WLSC_PREMUL_ARGB_VISUAL;
402                         break;
403                 case WL_SHM_FORMAT_XRGB32:
404                         es->visual = WLSC_RGB_VISUAL;
405                         break;
406                 }
407
408                 surfaces_attached_to = buffer->user_data;
409
410                 wl_list_remove(&es->buffer_link);
411                 wl_list_insert(surfaces_attached_to, &es->buffer_link);
412         } else {
413                 if (es->image != EGL_NO_IMAGE_KHR)
414                         ec->destroy_image(ec->display, es->image);
415                 es->image = ec->create_image(ec->display, NULL,
416                                              EGL_WAYLAND_BUFFER_WL,
417                                              buffer, NULL);
418                 
419                 ec->image_target_texture_2d(GL_TEXTURE_2D, es->image);
420
421                 /* FIXME: we need to get the visual from the wl_buffer */
422                 es->visual = WLSC_PREMUL_ARGB_VISUAL;
423                 es->pitch = es->width;
424         }
425 }
426
427 static int
428 texture_region(struct wlsc_surface *es, pixman_region32_t *region)
429 {
430         struct wlsc_compositor *ec = es->compositor;
431         GLfloat *v, inv_width, inv_height;
432         pixman_box32_t *rectangles;
433         unsigned int *p;
434         int i, n;
435
436         rectangles = pixman_region32_rectangles(region, &n);
437         v = wl_array_add(&ec->vertices, n * 16 * sizeof *v);
438         p = wl_array_add(&ec->indices, n * 6 * sizeof *p);
439         inv_width = 1.0 / es->pitch;
440         inv_height = 1.0 / es->height;
441
442         for (i = 0; i < n; i++, v += 16, p += 6) {
443                 v[ 0] = rectangles[i].x1;
444                 v[ 1] = rectangles[i].y1;
445                 v[ 2] = (GLfloat) (rectangles[i].x1 - es->x) * inv_width;
446                 v[ 3] = (GLfloat) (rectangles[i].y1 - es->y) * inv_height;
447
448                 v[ 4] = rectangles[i].x1;
449                 v[ 5] = rectangles[i].y2;
450                 v[ 6] = v[ 2];
451                 v[ 7] = (GLfloat) (rectangles[i].y2 - es->y) * inv_height;
452
453                 v[ 8] = rectangles[i].x2;
454                 v[ 9] = rectangles[i].y1;
455                 v[10] = (GLfloat) (rectangles[i].x2 - es->x) * inv_width;
456                 v[11] = v[ 3];
457
458                 v[12] = rectangles[i].x2;
459                 v[13] = rectangles[i].y2;
460                 v[14] = v[10];
461                 v[15] = v[ 7];
462
463                 p[0] = i * 4 + 0;
464                 p[1] = i * 4 + 1;
465                 p[2] = i * 4 + 2;
466                 p[3] = i * 4 + 2;
467                 p[4] = i * 4 + 1;
468                 p[5] = i * 4 + 3;
469         }
470
471         return n;
472 }
473
474 static void
475 transform_vertex(struct wlsc_surface *surface,
476                  GLfloat x, GLfloat y, GLfloat u, GLfloat v, GLfloat *r)
477 {
478         struct wlsc_vector t;
479
480         t.f[0] = x;
481         t.f[1] = y;
482         t.f[2] = 0.0;
483         t.f[3] = 1.0;
484
485         wlsc_matrix_transform(&surface->transform->matrix, &t);
486
487         r[ 0] = t.f[0];
488         r[ 1] = t.f[1];
489         r[ 2] = u;
490         r[ 3] = v;
491 }
492
493 static int
494 texture_transformed_surface(struct wlsc_surface *es)
495 {
496         struct wlsc_compositor *ec = es->compositor;
497         GLfloat *v;
498         unsigned int *p;
499
500         v = wl_array_add(&ec->vertices, 16 * sizeof *v);
501         p = wl_array_add(&ec->indices, 6 * sizeof *p);
502
503         transform_vertex(es, es->x, es->y, 0.0, 0.0, &v[0]);
504         transform_vertex(es, es->x, es->y + es->height, 0.0, 1.0, &v[4]);
505         transform_vertex(es, es->x + es->width, es->y, 1.0, 0.0, &v[8]);
506         transform_vertex(es, es->x + es->width, es->y + es->height,
507                          1.0, 1.0, &v[12]);
508
509         p[0] = 0;
510         p[1] = 1;
511         p[2] = 2;
512         p[3] = 2;
513         p[4] = 1;
514         p[5] = 3;
515
516         return 1;
517 }
518
519 static void
520 wlsc_surface_draw(struct wlsc_surface *es,
521                   struct wlsc_output *output, pixman_region32_t *clip)
522 {
523         struct wlsc_compositor *ec = es->compositor;
524         GLfloat *v;
525         pixman_region32_t repaint;
526         GLint filter;
527         int n;
528
529         pixman_region32_init_rect(&repaint,
530                                   es->x, es->y, es->width, es->height);
531         pixman_region32_intersect(&repaint, &repaint, clip);
532         if (!pixman_region32_not_empty(&repaint))
533                 return;
534
535         switch (es->visual) {
536         case WLSC_ARGB_VISUAL:
537                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
538                 glEnable(GL_BLEND);
539                 break;
540         case WLSC_PREMUL_ARGB_VISUAL:
541                 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
542                 glEnable(GL_BLEND);
543                 break;
544         case WLSC_RGB_VISUAL:
545                 glDisable(GL_BLEND);
546                 break;
547         default:
548                 fprintf(stderr, "bogus visual\n");
549                 break;
550         }
551
552         if (es->alpha != ec->current_alpha) {
553                 glUniform1f(ec->texture_shader.alpha_uniform,
554                             es->alpha / 255.0);
555                 ec->current_alpha = es->alpha;
556         }
557
558         if (es->transform == NULL) {
559                 filter = GL_NEAREST;
560                 n = texture_region(es, &repaint);
561         } else {
562                 filter = GL_LINEAR;
563                 n = texture_transformed_surface(es);
564         }
565
566         glBindTexture(GL_TEXTURE_2D, es->texture);
567         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
568         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
569
570         v = ec->vertices.data;
571         glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof *v, &v[0]);
572         glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof *v, &v[2]);
573         glEnableVertexAttribArray(0);
574         glEnableVertexAttribArray(1);
575         glDrawElements(GL_TRIANGLES, n * 6, GL_UNSIGNED_INT, ec->indices.data);
576
577         ec->vertices.size = 0;
578         ec->indices.size = 0;
579         pixman_region32_fini(&repaint);
580 }
581
582 static void
583 wlsc_surface_raise(struct wlsc_surface *surface)
584 {
585         struct wlsc_compositor *compositor = surface->compositor;
586
587         wl_list_remove(&surface->link);
588         wl_list_insert(&compositor->surface_list, &surface->link);
589         wlsc_compositor_repick(compositor);
590         wlsc_surface_damage(surface);
591 }
592
593 WL_EXPORT void
594 wlsc_compositor_damage_all(struct wlsc_compositor *compositor)
595 {
596         struct wlsc_output *output;
597
598         wl_list_for_each(output, &compositor->output_list, link)
599                 wlsc_output_damage(output);
600 }
601
602 static inline void
603 wlsc_buffer_post_release(struct wl_buffer *buffer)
604 {
605         if (--buffer->busy_count > 0)
606                 return;
607
608         assert(buffer->resource.client != NULL);
609         wl_resource_queue_event(&buffer->resource, WL_BUFFER_RELEASE);
610 }
611
612 WL_EXPORT void
613 wlsc_output_damage(struct wlsc_output *output)
614 {
615         struct wlsc_compositor *compositor = output->compositor;
616         struct wlsc_surface *es;
617
618         if (wl_list_empty(&compositor->surface_list))
619                 return;
620
621         es = container_of(compositor->surface_list.next,
622                           struct wlsc_surface, link);
623         pixman_region32_union(&es->damage, &es->damage, &output->region);
624         wlsc_compositor_schedule_repaint(compositor);
625 }
626
627 static void
628 fade_frame(struct wlsc_animation *animation,
629            struct wlsc_output *output, uint32_t msecs)
630 {
631         struct wlsc_compositor *compositor =
632                 container_of(animation,
633                              struct wlsc_compositor, fade.animation);
634
635         wlsc_spring_update(&compositor->fade.spring, msecs);
636         if (wlsc_spring_done(&compositor->fade.spring)) {
637                 compositor->fade.spring.current =
638                         compositor->fade.spring.target;
639                 wl_list_remove(&animation->link);
640                 wl_list_init(&animation->link);
641
642                 if (compositor->fade.spring.current > 0.999) {
643                         compositor->state = WLSC_COMPOSITOR_SLEEPING;
644                         compositor->shell->lock(compositor->shell);
645                 }
646         }
647
648         wlsc_output_damage(output);
649 }
650
651 static void
652 fade_output(struct wlsc_output *output,
653             GLfloat tint, pixman_region32_t *region)
654 {
655         struct wlsc_compositor *compositor = output->compositor;
656         struct wlsc_surface surface;
657         GLfloat color[4] = { 0.0, 0.0, 0.0, tint };
658
659         surface.compositor = compositor;
660         surface.x = output->x;
661         surface.y = output->y;
662         surface.pitch = output->current->width;
663         surface.width = output->current->width;
664         surface.height = output->current->height;
665         surface.texture = GL_NONE;
666         surface.transform = NULL;
667         surface.alpha = compositor->current_alpha;
668
669         if (tint <= 1.0)
670                 surface.visual = WLSC_PREMUL_ARGB_VISUAL;
671         else
672                 surface.visual = WLSC_RGB_VISUAL;
673
674         glUseProgram(compositor->solid_shader.program);
675         glUniformMatrix4fv(compositor->solid_shader.proj_uniform,
676                            1, GL_FALSE, output->matrix.d);
677         glUniform4fv(compositor->solid_shader.color_uniform, 1, color);
678         wlsc_surface_draw(&surface, output, region);
679 }
680
681 static void
682 wlsc_output_set_cursor(struct wlsc_output *output,
683                        struct wl_input_device *dev, int force_sw)
684 {
685         struct wlsc_compositor *ec = output->compositor;
686         struct wlsc_input_device *device = (struct wlsc_input_device *) dev;
687         pixman_region32_t cursor_region;
688         int use_hardware_cursor = 1, prior_was_hardware;
689
690         if (device->sprite == NULL)
691                 return;
692
693         pixman_region32_init_rect(&cursor_region,
694                                   device->sprite->x, device->sprite->y,
695                                   device->sprite->width,
696                                   device->sprite->height);
697
698         pixman_region32_intersect(&cursor_region, &cursor_region, &output->region);
699
700         if (!pixman_region32_not_empty(&cursor_region)) {
701                 output->set_hardware_cursor(output, NULL);
702                 goto out;
703         }
704
705         prior_was_hardware = wl_list_empty(&device->sprite->link);
706         if (force_sw || output->set_hardware_cursor(output, device) < 0) {
707                 if (prior_was_hardware) {
708                         wlsc_surface_damage(device->sprite);
709                         output->set_hardware_cursor(output, NULL);
710                 }
711                 use_hardware_cursor = 0;
712         } else if (!prior_was_hardware) {
713                 wlsc_surface_damage_below(device->sprite);
714         }
715
716         /* Remove always to be on top. */
717         wl_list_remove(&device->sprite->link);
718         if (!use_hardware_cursor && ec->focus) {
719                 wl_list_insert(&ec->surface_list, &device->sprite->link);
720                 device->sprite->output = output;
721         } else {
722                 wl_list_init(&device->sprite->link);
723                 device->sprite->output = NULL;
724         }
725
726 out:
727         pixman_region32_fini(&cursor_region);
728 }
729
730 static int
731 setup_scanout_surface(struct wlsc_output *output, struct wlsc_surface *es)
732 {
733         if (es->visual != WLSC_RGB_VISUAL ||
734             output->prepare_scanout_surface(output, es) != 0)
735                 return -1;
736
737         /* assert output->pending_scanout_buffer == NULL */
738         output->pending_scanout_buffer = es->buffer;
739         output->pending_scanout_buffer->busy_count++;
740
741         wl_list_insert(output->pending_scanout_buffer->resource.destroy_listener_list.prev,
742                        &output->pending_scanout_buffer_destroy_listener.link);
743
744         return 0;
745 }
746
747 static void
748 wlsc_output_repaint(struct wlsc_output *output)
749 {
750         struct wlsc_compositor *ec = output->compositor;
751         struct wlsc_surface *es;
752         pixman_region32_t opaque, new_damage, total_damage, repaint;
753
754         output->prepare_render(output);
755
756         glViewport(0, 0, output->current->width, output->current->height);
757
758         glUseProgram(ec->texture_shader.program);
759         glUniformMatrix4fv(ec->texture_shader.proj_uniform,
760                            1, GL_FALSE, output->matrix.d);
761         glUniform1i(ec->texture_shader.tex_uniform, 0);
762
763         wlsc_output_set_cursor(output, ec->input_device,
764                                ec->fade.spring.current >= 0.001);
765
766         pixman_region32_init(&new_damage);
767         pixman_region32_init(&opaque);
768                                 
769         wl_list_for_each(es, &ec->surface_list, link) {
770                 pixman_region32_subtract(&es->damage, &es->damage, &opaque);
771                 pixman_region32_union(&new_damage, &new_damage, &es->damage);
772                 pixman_region32_union(&opaque, &opaque, &es->opaque);
773         }
774
775         pixman_region32_init(&total_damage);
776         pixman_region32_union(&total_damage, &new_damage,
777                               &output->previous_damage);
778         pixman_region32_intersect(&output->previous_damage,
779                                   &new_damage, &output->region);
780
781         pixman_region32_fini(&opaque);
782         pixman_region32_fini(&new_damage);
783
784         es = container_of(ec->surface_list.next, struct wlsc_surface, link);
785
786         if (setup_scanout_surface(output, es) == 0)
787                 /* We're drawing nothing, just let the damage accumulate */
788                 return;
789
790         if (es->fullscreen_output == output) {
791                 if (es->width < output->current->width ||
792                     es->height < output->current->height)
793                         glClear(GL_COLOR_BUFFER_BIT);
794                 wlsc_surface_draw(es, output, &total_damage);
795         } else {
796                 wl_list_for_each(es, &ec->surface_list, link) {
797                         pixman_region32_copy(&es->damage, &total_damage);
798                         pixman_region32_subtract(&total_damage, &total_damage, &es->opaque);
799                 }
800
801                 wl_list_for_each_reverse(es, &ec->surface_list, link) {
802                         pixman_region32_init(&repaint);
803                         pixman_region32_intersect(&repaint, &output->region,
804                                                   &es->damage);
805                         wlsc_surface_draw(es, output, &repaint);
806                         pixman_region32_subtract(&es->damage,
807                                                  &es->damage, &output->region);
808                 }
809         }
810
811         if (ec->fade.spring.current > 0.001)
812                 fade_output(output, ec->fade.spring.current, &total_damage);
813 }
814
815 struct wlsc_frame_callback {
816         struct wl_resource resource;
817         struct wl_list link;
818 };
819
820 static void
821 repaint(void *data, int msecs)
822 {
823         struct wlsc_output *output = data;
824         struct wlsc_compositor *compositor = output->compositor;
825         struct wlsc_animation *animation, *next;
826         struct wlsc_frame_callback *cb, *cnext;
827
828         wlsc_output_repaint(output);
829         output->repaint_needed = 0;
830         output->repaint_scheduled = 1;
831         output->present(output);
832
833         wl_list_for_each_safe(cb, cnext, &output->frame_callback_list, link) {
834                 wl_resource_post_event(&cb->resource, WL_CALLBACK_DONE, msecs);
835                 wl_resource_destroy(&cb->resource, 0);
836         }
837
838         wl_list_for_each_safe(animation, next,
839                               &compositor->animation_list, link)
840                 animation->frame(animation, output, msecs);
841 }
842
843 static void
844 idle_repaint(void *data)
845 {
846         repaint(data, wlsc_compositor_get_time());
847 }
848
849 WL_EXPORT void
850 wlsc_output_finish_frame(struct wlsc_output *output, int msecs)
851 {
852         if (output->scanout_buffer) {
853                 wlsc_buffer_post_release(output->scanout_buffer);
854                 wl_list_remove(&output->scanout_buffer_destroy_listener.link);
855                 output->scanout_buffer = NULL;
856         }
857
858         if (output->pending_scanout_buffer) {
859                 output->scanout_buffer = output->pending_scanout_buffer;
860                 wl_list_remove(&output->pending_scanout_buffer_destroy_listener.link);
861                 wl_list_insert(output->scanout_buffer->resource.destroy_listener_list.prev,
862                                &output->scanout_buffer_destroy_listener.link);
863                 output->pending_scanout_buffer = NULL;
864         }
865
866         if (output->repaint_needed)
867                 repaint(output, msecs);
868         else
869                 output->repaint_scheduled = 0;
870 }
871
872 WL_EXPORT void
873 wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor)
874 {
875         struct wlsc_output *output;
876         struct wl_event_loop *loop;
877
878         if (compositor->state == WLSC_COMPOSITOR_SLEEPING)
879                 return;
880
881         loop = wl_display_get_event_loop(compositor->wl_display);
882         wl_list_for_each(output, &compositor->output_list, link) {
883                 output->repaint_needed = 1;
884                 if (output->repaint_scheduled)
885                         continue;
886
887                 wl_event_loop_add_idle(loop, idle_repaint, output);
888                 output->repaint_scheduled = 1;
889         }
890 }
891
892 WL_EXPORT void
893 wlsc_compositor_fade(struct wlsc_compositor *compositor, float tint)
894 {
895         int done;
896
897         done = wlsc_spring_done(&compositor->fade.spring);
898         compositor->fade.spring.target = tint;
899         if (wlsc_spring_done(&compositor->fade.spring))
900                 return;
901
902         if (done)
903                 compositor->fade.spring.timestamp =
904                         wlsc_compositor_get_time();
905
906         wlsc_compositor_damage_all(compositor);
907         if (wl_list_empty(&compositor->fade.animation.link))
908                 wl_list_insert(compositor->animation_list.prev,
909                                &compositor->fade.animation.link);
910 }
911
912 static void
913 surface_destroy(struct wl_client *client, struct wl_resource *resource)
914 {
915         wl_resource_destroy(resource, wlsc_compositor_get_time());
916 }
917
918 WL_EXPORT void
919 wlsc_surface_assign_output(struct wlsc_surface *es)
920 {
921         struct wlsc_compositor *ec = es->compositor;
922         struct wlsc_output *output, *new_output;
923         pixman_region32_t region;
924         uint32_t max, area;
925         pixman_box32_t *e;
926
927         new_output = NULL;
928         max = 0;
929         wl_list_for_each(output, &ec->output_list, link) {
930                 pixman_region32_init_rect(&region,
931                                           es->x, es->y, es->width, es->height);
932                 pixman_region32_intersect(&region, &region, &output->region);
933
934                 e = pixman_region32_extents(&region);
935                 area = (e->x2 - e->x1) * (e->y2 - e->y1);
936
937                 if (area >= max) {
938                         new_output = output;
939                         max = area;
940                 }
941         }
942
943         es->output = new_output;
944         if (!wl_list_empty(&es->frame_callback_list)) {
945                 wl_list_insert_list(new_output->frame_callback_list.prev,
946                                     &es->frame_callback_list);
947                 wl_list_init(&es->frame_callback_list);
948         }
949 }
950
951 static void
952 surface_attach(struct wl_client *client,
953                struct wl_resource *resource,
954                struct wl_resource *buffer_resource, int32_t x, int32_t y)
955 {
956         struct wlsc_surface *es = resource->data;
957         struct wlsc_shell *shell = es->compositor->shell;
958         struct wl_buffer *buffer = buffer_resource->data;
959
960         if (es->buffer) {
961                 wlsc_buffer_post_release(es->buffer);
962                 wl_list_remove(&es->buffer_destroy_listener.link);
963         }
964
965         buffer->busy_count++;
966         es->buffer = buffer;
967         wl_list_insert(es->buffer->resource.destroy_listener_list.prev,
968                        &es->buffer_destroy_listener.link);
969
970         if (es->visual == WLSC_NONE_VISUAL) {
971                 shell->map(shell, es, buffer->width, buffer->height);
972         } else if (x != 0 || y != 0 ||
973                    es->width != buffer->width ||
974                    es->height != buffer->height) {
975                 shell->configure(shell, es, es->x + x, es->y + y,
976                                  buffer->width, buffer->height);
977         }
978
979         wlsc_buffer_attach(buffer, &es->surface);
980 }
981
982 static void
983 surface_damage(struct wl_client *client,
984                struct wl_resource *resource,
985                int32_t x, int32_t y, int32_t width, int32_t height)
986 {
987         struct wlsc_surface *es = resource->data;
988
989         wlsc_surface_damage_rectangle(es, x, y, width, height);
990 }
991
992 static void
993 destroy_frame_callback(struct wl_resource *resource)
994 {
995         struct wlsc_frame_callback *cb = resource->data;
996
997         wl_list_remove(&cb->link);
998         free(cb);
999 }
1000
1001 static void
1002 surface_frame(struct wl_client *client,
1003               struct wl_resource *resource, uint32_t callback)
1004 {
1005         struct wlsc_frame_callback *cb;
1006         struct wlsc_surface *es = resource->data;
1007
1008         cb = malloc(sizeof *cb);
1009         if (cb == NULL) {
1010                 wl_resource_post_no_memory(resource);
1011                 return;
1012         }
1013                 
1014         cb->resource.object.interface = &wl_callback_interface;
1015         cb->resource.object.id = callback;
1016         cb->resource.destroy = destroy_frame_callback;
1017         cb->resource.client = client;
1018         cb->resource.data = cb;
1019
1020         wl_client_add_resource(client, &cb->resource);
1021
1022         if (es->output) {
1023                 wl_list_insert(es->output->frame_callback_list.prev,
1024                                &cb->link);
1025         } else {
1026                 wl_list_insert(es->frame_callback_list.prev, &cb->link);
1027         }
1028 }
1029
1030 const static struct wl_surface_interface surface_interface = {
1031         surface_destroy,
1032         surface_attach,
1033         surface_damage,
1034         surface_frame
1035 };
1036
1037 static void
1038 compositor_create_surface(struct wl_client *client,
1039                           struct wl_resource *resource, uint32_t id)
1040 {
1041         struct wlsc_compositor *ec = resource->data;
1042         struct wlsc_surface *surface;
1043
1044         surface = wlsc_surface_create(ec, 0, 0, 0, 0);
1045         if (surface == NULL) {
1046                 wl_resource_post_no_memory(resource);
1047                 return;
1048         }
1049
1050         surface->surface.resource.destroy = destroy_surface;
1051
1052         surface->surface.resource.object.id = id;
1053         surface->surface.resource.object.interface = &wl_surface_interface;
1054         surface->surface.resource.object.implementation =
1055                 (void (**)(void)) &surface_interface;
1056         surface->surface.resource.data = surface;
1057
1058         wl_client_add_resource(client, &surface->surface.resource);
1059 }
1060
1061 const static struct wl_compositor_interface compositor_interface = {
1062         compositor_create_surface,
1063 };
1064
1065 static void
1066 wlsc_surface_transform(struct wlsc_surface *surface,
1067                        int32_t x, int32_t y, int32_t *sx, int32_t *sy)
1068 {
1069         *sx = x - surface->x;
1070         *sy = y - surface->y;
1071 }
1072
1073 static struct wlsc_surface *
1074 wlsc_compositor_pick_surface(struct wlsc_compositor *compositor,
1075                              int32_t x, int32_t y, int32_t *sx, int32_t *sy)
1076 {
1077         struct wlsc_surface *surface;
1078
1079         wl_list_for_each(surface, &compositor->surface_list, link) {
1080                 if (surface->surface.resource.client == NULL)
1081                         continue;
1082                 wlsc_surface_transform(surface, x, y, sx, sy);
1083                 if (0 <= *sx && *sx < surface->width &&
1084                     0 <= *sy && *sy < surface->height)
1085                         return surface;
1086         }
1087
1088         return NULL;
1089 }
1090
1091 WL_EXPORT struct wlsc_surface *
1092 pick_surface(struct wl_input_device *device, int32_t *sx, int32_t *sy)
1093 {
1094         struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
1095
1096         return wlsc_compositor_pick_surface(wd->compositor,
1097                                             device->x, device->y, sx, sy);
1098 }
1099
1100
1101 static void
1102 implicit_grab_motion(struct wl_grab *grab,
1103                      uint32_t time, int32_t x, int32_t y)
1104 {
1105         struct wlsc_input_device *device =
1106                 (struct wlsc_input_device *) grab->input_device;
1107         struct wlsc_surface *es =
1108                 (struct wlsc_surface *) device->input_device.pointer_focus;
1109         int32_t sx, sy;
1110         struct wl_resource *resource;
1111
1112         resource = grab->input_device->pointer_focus_resource;
1113         if (resource) {
1114                 wlsc_surface_transform(es, x, y, &sx, &sy);
1115                 wl_resource_post_event(resource, WL_INPUT_DEVICE_MOTION,
1116                                        time, x, y, sx, sy);
1117         }
1118 }
1119
1120 static void
1121 implicit_grab_button(struct wl_grab *grab,
1122                      uint32_t time, int32_t button, int32_t state)
1123 {
1124         struct wl_resource *resource;
1125
1126         resource = grab->input_device->pointer_focus_resource;
1127         if (resource)
1128                 wl_resource_post_event(resource, WL_INPUT_DEVICE_BUTTON,
1129                                        time, button, state);
1130 }
1131
1132 static void
1133 implicit_grab_end(struct wl_grab *grab, uint32_t time)
1134 {
1135 }
1136
1137 static const struct wl_grab_interface implicit_grab_interface = {
1138         implicit_grab_motion,
1139         implicit_grab_button,
1140         implicit_grab_end
1141 };
1142
1143 WL_EXPORT void
1144 wlsc_compositor_wake(struct wlsc_compositor *compositor)
1145 {
1146         compositor->state = WLSC_COMPOSITOR_ACTIVE;
1147         wlsc_compositor_fade(compositor, 0.0);
1148
1149         wl_event_source_timer_update(compositor->idle_source,
1150                                      compositor->idle_time * 1000);
1151 }
1152
1153 WL_EXPORT void
1154 wlsc_compositor_activity(struct wlsc_compositor *compositor)
1155 {
1156         if (compositor->state == WLSC_COMPOSITOR_ACTIVE) {
1157                 wlsc_compositor_wake(compositor);
1158         } else {
1159                 compositor->shell->unlock(compositor->shell);
1160         }
1161 }
1162
1163 static void
1164 wlsc_compositor_idle_inhibit(struct wlsc_compositor *compositor)
1165 {
1166         wlsc_compositor_activity(compositor);
1167         compositor->idle_inhibit++;
1168 }
1169
1170 static void
1171 wlsc_compositor_idle_release(struct wlsc_compositor *compositor)
1172 {
1173         compositor->idle_inhibit--;
1174         wlsc_compositor_activity(compositor);
1175 }
1176
1177 static int
1178 idle_handler(void *data)
1179 {
1180         struct wlsc_compositor *compositor = data;
1181
1182         if (compositor->idle_inhibit)
1183                 return 1;
1184
1185         wlsc_compositor_fade(compositor, 1.0);
1186
1187         return 1;
1188 }
1189
1190 WL_EXPORT void
1191 notify_motion(struct wl_input_device *device, uint32_t time, int x, int y)
1192 {
1193         struct wlsc_surface *es;
1194         struct wlsc_output *output;
1195         const struct wl_grab_interface *interface;
1196         struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
1197         struct wlsc_compositor *ec = wd->compositor;
1198         int32_t sx, sy;
1199         int x_valid = 0, y_valid = 0;
1200         int min_x = INT_MAX, min_y = INT_MAX, max_x = INT_MIN, max_y = INT_MIN;
1201
1202         wlsc_compositor_activity(ec);
1203
1204         wl_list_for_each(output, &ec->output_list, link) {
1205                 if (output->x <= x && x <= output->x + output->current->width)
1206                         x_valid = 1;
1207
1208                 if (output->y <= y && y <= output->y + output->current->height)
1209                         y_valid = 1;
1210
1211                 /* FIXME: calculate this only on output addition/deletion */
1212                 if (output->x < min_x)
1213                         min_x = output->x;
1214                 if (output->y < min_y)
1215                         min_y = output->y;
1216
1217                 if (output->x + output->current->width > max_x)
1218                         max_x = output->x + output->current->width;
1219                 if (output->y + output->current->height > max_y)
1220                         max_y = output->y + output->current->height;
1221         }
1222         
1223         if (!x_valid) {
1224                 if (x < min_x)
1225                         x = min_x;
1226                 else if (x >= max_x)
1227                         x = max_x;
1228         }
1229         if (!y_valid) {
1230                 if (y < min_y)
1231                         y = min_y;
1232                 else  if (y >= max_y)
1233                         y = max_y;
1234         }
1235
1236         device->x = x;
1237         device->y = y;
1238
1239         if (device->grab) {
1240                 interface = device->grab->interface;
1241                 interface->motion(device->grab, time, x, y);
1242         } else {
1243                 es = pick_surface(device, &sx, &sy);
1244                 wl_input_device_set_pointer_focus(device,
1245                                                   &es->surface,
1246                                                   time, x, y, sx, sy);
1247                 if (device->pointer_focus_resource)
1248                         wl_resource_post_event(device->pointer_focus_resource,
1249                                                WL_INPUT_DEVICE_MOTION,
1250                                                time, x, y, sx, sy);
1251         }
1252
1253         if (wd->sprite) {
1254                 wlsc_surface_damage_below(wd->sprite);
1255
1256                 wd->sprite->x = device->x - wd->hotspot_x;
1257                 wd->sprite->y = device->y - wd->hotspot_y;
1258
1259                 wlsc_surface_damage(wd->sprite);
1260         }
1261 }
1262
1263 WL_EXPORT void
1264 wlsc_surface_activate(struct wlsc_surface *surface,
1265                       struct wlsc_input_device *device, uint32_t time)
1266 {
1267         wlsc_surface_raise(surface);
1268         wl_input_device_set_keyboard_focus(&device->input_device,
1269                                            &surface->surface, time);
1270         wlsc_data_device_set_keyboard_focus(device);
1271 }
1272
1273 WL_EXPORT void
1274 notify_button(struct wl_input_device *device,
1275               uint32_t time, int32_t button, int32_t state)
1276 {
1277         struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
1278         struct wlsc_compositor *compositor = wd->compositor;
1279         struct wlsc_surface *surface =
1280                 (struct wlsc_surface *) device->pointer_focus;
1281         int32_t sx, sy;
1282
1283         if (state)
1284                 wlsc_compositor_idle_inhibit(compositor);
1285         else
1286                 wlsc_compositor_idle_release(compositor);
1287
1288         wlsc_compositor_run_binding(compositor, wd, time, 0, button, state);
1289
1290         if (state && surface && device->grab == NULL) {
1291                 wl_input_device_start_grab(device,
1292                                            &device->implicit_grab,
1293                                            button, time);
1294         }
1295
1296         if (device->grab)
1297                 device->grab->interface->button(device->grab, time,
1298                                                 button, state);
1299
1300         if (!state && device->grab && device->grab_button == button) {
1301                 wl_input_device_end_grab(device, time);
1302                 surface = pick_surface(device, &sx, &sy);
1303                 wl_input_device_set_pointer_focus(device, &surface->surface,
1304                                                   time, device->x, device->y,
1305                                                   sx, sy);
1306         }
1307 }
1308
1309 static void
1310 update_modifier_state(struct wlsc_input_device *device,
1311                       uint32_t key, uint32_t state)
1312 {
1313         uint32_t modifier;
1314
1315         switch (key) {
1316         case KEY_LEFTCTRL:
1317         case KEY_RIGHTCTRL:
1318                 modifier = MODIFIER_CTRL;
1319                 break;
1320
1321         case KEY_LEFTALT:
1322         case KEY_RIGHTALT:
1323                 modifier = MODIFIER_ALT;
1324                 break;
1325
1326         case KEY_LEFTMETA:
1327         case KEY_RIGHTMETA:
1328                 modifier = MODIFIER_SUPER;
1329                 break;
1330
1331         default:
1332                 modifier = 0;
1333                 break;
1334         }
1335
1336         if (state)
1337                 device->modifier_state |= modifier;
1338         else
1339                 device->modifier_state &= ~modifier;
1340 }
1341
1342 WL_EXPORT void
1343 notify_key(struct wl_input_device *device,
1344            uint32_t time, uint32_t key, uint32_t state)
1345 {
1346         struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
1347         struct wlsc_compositor *compositor = wd->compositor;
1348         uint32_t *k, *end;
1349
1350         if (state)
1351                 wlsc_compositor_idle_inhibit(compositor);
1352         else
1353                 wlsc_compositor_idle_release(compositor);
1354
1355         wlsc_compositor_run_binding(compositor, wd, time, key, 0, state);
1356
1357         update_modifier_state(wd, key, state);
1358         end = device->keys.data + device->keys.size;
1359         for (k = device->keys.data; k < end; k++) {
1360                 if (*k == key)
1361                         *k = *--end;
1362         }
1363         device->keys.size = (void *) end - device->keys.data;
1364         if (state) {
1365                 k = wl_array_add(&device->keys, sizeof *k);
1366                 *k = key;
1367         }
1368
1369         if (device->keyboard_focus_resource)
1370                 wl_resource_post_event(device->keyboard_focus_resource,
1371                                        WL_INPUT_DEVICE_KEY, time, key, state);
1372 }
1373
1374 WL_EXPORT void
1375 notify_pointer_focus(struct wl_input_device *device,
1376                      uint32_t time, struct wlsc_output *output,
1377                      int32_t x, int32_t y)
1378 {
1379         struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
1380         struct wlsc_compositor *compositor = wd->compositor;
1381         struct wlsc_surface *es;
1382         int32_t sx, sy;
1383
1384         if (output) {
1385                 device->x = x;
1386                 device->y = y;
1387                 es = pick_surface(device, &sx, &sy);
1388                 wl_input_device_set_pointer_focus(device,
1389                                                   &es->surface,
1390                                                   time, x, y, sx, sy);
1391
1392                 compositor->focus = 1;
1393         } else {
1394                 wl_input_device_set_pointer_focus(device, NULL,
1395                                                   time, 0, 0, 0, 0);
1396                 compositor->focus = 0;
1397         }
1398 }
1399
1400 WL_EXPORT void
1401 notify_keyboard_focus(struct wl_input_device *device,
1402                       uint32_t time, struct wlsc_output *output,
1403                       struct wl_array *keys)
1404 {
1405         struct wlsc_input_device *wd =
1406                 (struct wlsc_input_device *) device;
1407         struct wlsc_compositor *compositor = wd->compositor;
1408         struct wlsc_surface *es;
1409         uint32_t *k, *end;
1410
1411         if (!wl_list_empty(&compositor->surface_list))
1412                 es = container_of(compositor->surface_list.next,
1413                                   struct wlsc_surface, link);
1414         else
1415                 es = NULL;
1416
1417         if (output) {
1418                 wl_array_copy(&wd->input_device.keys, keys);
1419                 wd->modifier_state = 0;
1420                 end = device->keys.data + device->keys.size;
1421                 for (k = device->keys.data; k < end; k++) {
1422                         wlsc_compositor_idle_inhibit(compositor);
1423                         update_modifier_state(wd, *k, 1);
1424                 }
1425
1426                 if (es && es->surface.resource.client)
1427                         wl_input_device_set_keyboard_focus(&wd->input_device,
1428                                                            &es->surface, time);
1429         } else {
1430                 end = device->keys.data + device->keys.size;
1431                 for (k = device->keys.data; k < end; k++)
1432                         wlsc_compositor_idle_release(compositor);
1433
1434                 wd->modifier_state = 0;
1435                 wl_input_device_set_keyboard_focus(&wd->input_device,
1436                                                    NULL, time);
1437         }
1438 }
1439
1440 /* TODO: share this function with wayland-server.c */
1441 static struct wl_resource *
1442 find_resource_for_surface(struct wl_list *list, struct wl_surface *surface)
1443 {
1444         struct wl_resource *r;
1445
1446         if (!surface)
1447                 return NULL;
1448
1449         wl_list_for_each(r, list, link) {
1450                 if (r->client == surface->resource.client)
1451                         return r;
1452         }
1453
1454         return NULL;
1455 }
1456
1457 static void
1458 lose_touch_focus_resource(struct wl_listener *listener,
1459                           struct wl_resource *resource, uint32_t time)
1460 {
1461         struct wlsc_input_device *device =
1462                 container_of(listener, struct wlsc_input_device,
1463                              touch_focus_resource_listener);
1464
1465         device->touch_focus_resource = NULL;
1466 }
1467
1468 static void
1469 lose_touch_focus(struct wl_listener *listener,
1470                  struct wl_resource *resource, uint32_t time)
1471 {
1472         struct wlsc_input_device *device =
1473                 container_of(listener, struct wlsc_input_device,
1474                              touch_focus_listener);
1475
1476         device->touch_focus = NULL;
1477 }
1478
1479 static void
1480 touch_set_focus(struct wlsc_input_device *device,
1481                 struct wl_surface *surface, uint32_t time)
1482 {
1483         struct wl_input_device *input_device = &device->input_device;
1484         struct wl_resource *resource;
1485
1486         if (device->touch_focus == surface)
1487                 return;
1488
1489         if (surface) {
1490                 resource =
1491                         find_resource_for_surface(&input_device->resource_list,
1492                                                   surface);
1493                 if (!resource) {
1494                         fprintf(stderr, "couldn't find resource\n");
1495                         return;
1496                 }
1497
1498                 device->touch_focus_resource_listener.func =
1499                         lose_touch_focus_resource;
1500                 wl_list_insert(resource->destroy_listener_list.prev,
1501                                &device->touch_focus_resource_listener.link);
1502                 device->touch_focus_listener.func = lose_touch_focus;
1503                 wl_list_insert(surface->resource.destroy_listener_list.prev,
1504                                &device->touch_focus_listener.link);
1505
1506                 device->touch_focus = surface;
1507                 device->touch_focus_resource = resource;
1508         } else {
1509                 if (device->touch_focus)
1510                         wl_list_remove(&device->touch_focus_listener.link);
1511                 if (device->touch_focus_resource)
1512                         wl_list_remove(&device->touch_focus_resource_listener.link);
1513                 device->touch_focus = NULL;
1514                 device->touch_focus_resource = NULL;
1515         }
1516 }
1517
1518 /**
1519  * notify_touch - emulates button touches and notifies surfaces accordingly.
1520  *
1521  * It assumes always the correct cycle sequence until it gets here: touch_down
1522  * → touch_update → ... → touch_update → touch_end. The driver is responsible
1523  * for sending along such order.
1524  *
1525  */
1526 WL_EXPORT void
1527 notify_touch(struct wl_input_device *device, uint32_t time, int touch_id,
1528              int x, int y, int touch_type)
1529 {
1530         struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
1531         struct wlsc_compositor *ec = wd->compositor;
1532         struct wlsc_surface *es;
1533         int32_t sx, sy;
1534
1535         switch (touch_type) {
1536         case WL_INPUT_DEVICE_TOUCH_DOWN:
1537                 wlsc_compositor_idle_inhibit(ec);
1538
1539                 wd->num_tp++;
1540
1541                 /* the first finger down picks the surface, and all further go
1542                  * to that surface for the remainder of the touch session i.e.
1543                  * until all touch points are up again. */
1544                 if (wd->num_tp == 1) {
1545                         es = wlsc_compositor_pick_surface(ec, x, y, &sx, &sy);
1546                         touch_set_focus(wd, &es->surface, time);
1547                 } else if (wd->touch_focus) {
1548                         es = (struct wlsc_surface *) wd->touch_focus;
1549                         wlsc_surface_transform(es, x, y, &sx, &sy);
1550                 }
1551
1552                 if (wd->touch_focus_resource && wd->touch_focus)
1553                         wl_resource_post_event(wd->touch_focus_resource,
1554                                                touch_type, time,
1555                                                wd->touch_focus,
1556                                                touch_id, sx, sy);
1557                 break;
1558         case WL_INPUT_DEVICE_TOUCH_MOTION:
1559                 es = (struct wlsc_surface *) wd->touch_focus;
1560                 if (!es)
1561                         break;
1562
1563                 wlsc_surface_transform(es, x, y, &sx, &sy);
1564                 if (wd->touch_focus_resource)
1565                         wl_resource_post_event(wd->touch_focus_resource,
1566                                                touch_type, time,
1567                                                touch_id, sx, sy);
1568                 break;
1569         case WL_INPUT_DEVICE_TOUCH_UP:
1570                 wlsc_compositor_idle_release(ec);
1571                 wd->num_tp--;
1572
1573                 if (wd->touch_focus_resource)
1574                         wl_resource_post_event(wd->touch_focus_resource,
1575                                                touch_type, time, touch_id);
1576                 if (wd->num_tp == 0)
1577                         touch_set_focus(wd, NULL, time);
1578                 break;
1579         }
1580 }
1581
1582 static void
1583 input_device_attach(struct wl_client *client,
1584                     struct wl_resource *resource,
1585                     uint32_t time,
1586                     struct wl_resource *buffer_resource, int32_t x, int32_t y)
1587 {
1588         struct wlsc_input_device *device = resource->data;
1589         struct wlsc_compositor *compositor = device->compositor;
1590         struct wl_buffer *buffer;
1591
1592         if (time < device->input_device.pointer_focus_time)
1593                 return;
1594         if (device->input_device.pointer_focus == NULL)
1595                 return;
1596         if (device->input_device.pointer_focus->resource.client != client)
1597                 return;
1598
1599         if (device->sprite)
1600                 wlsc_surface_damage_below(device->sprite);
1601
1602         if (!buffer_resource) {
1603                 destroy_surface(&device->sprite->surface.resource);
1604                 device->sprite = NULL;
1605                 return;
1606         }
1607
1608         if (!device->sprite) {
1609                 device->sprite =
1610                         wlsc_surface_create(compositor,
1611                                             device->input_device.x,
1612                                             device->input_device.y, 32, 32);
1613                 wl_list_init(&device->sprite->link);
1614         }
1615
1616         buffer = buffer_resource->data;
1617         wlsc_buffer_attach(buffer, &device->sprite->surface);
1618
1619         device->hotspot_x = x;
1620         device->hotspot_y = y;
1621         device->sprite->width = buffer->width;
1622         device->sprite->height = buffer->height;
1623         device->sprite->x = device->input_device.x - device->hotspot_x;
1624         device->sprite->y = device->input_device.y - device->hotspot_y;
1625
1626         wlsc_surface_damage(device->sprite);
1627 }
1628
1629 const static struct wl_input_device_interface input_device_interface = {
1630         input_device_attach,
1631 };
1632
1633 static void unbind_input_device(struct wl_resource *resource)
1634 {
1635         wl_list_remove(&resource->link);
1636         free(resource);
1637 }
1638
1639 static void
1640 bind_input_device(struct wl_client *client,
1641                   void *data, uint32_t version, uint32_t id)
1642 {
1643         struct wl_input_device *device = data;
1644         struct wl_resource *resource;
1645
1646         resource = wl_client_add_object(client, &wl_input_device_interface,
1647                                         &input_device_interface, id, data);
1648         wl_list_insert(&device->resource_list, &resource->link);
1649         resource->destroy = unbind_input_device;
1650 }
1651
1652 WL_EXPORT void
1653 wlsc_input_device_init(struct wlsc_input_device *device,
1654                        struct wlsc_compositor *ec)
1655 {
1656         wl_input_device_init(&device->input_device);
1657         wl_list_init(&device->drag_resource_list);
1658
1659         wl_display_add_global(ec->wl_display, &wl_input_device_interface,
1660                               device, bind_input_device);
1661
1662         device->sprite = NULL;
1663
1664         device->compositor = ec;
1665         device->hotspot_x = 16;
1666         device->hotspot_y = 16;
1667         device->modifier_state = 0;
1668         device->num_tp = 0;
1669
1670         device->input_device.implicit_grab.interface = &implicit_grab_interface;
1671
1672         wl_list_insert(ec->input_device_list.prev, &device->link);
1673
1674         device->selection_data_source = NULL;
1675 }
1676
1677 static void
1678 bind_output(struct wl_client *client,
1679             void *data, uint32_t version, uint32_t id)
1680 {
1681         struct wlsc_output *output = data;
1682         struct wlsc_mode *mode;
1683         struct wl_resource *resource;
1684
1685         resource = wl_client_add_object(client,
1686                                         &wl_output_interface, NULL, id, data);
1687
1688         wl_resource_post_event(resource,
1689                                WL_OUTPUT_GEOMETRY,
1690                                output->x,
1691                                output->y,
1692                                output->mm_width,
1693                                output->mm_height,
1694                                output->subpixel,
1695                                output->make, output->model);
1696
1697         wl_list_for_each (mode, &output->mode_list, link) {
1698                 wl_resource_post_event(resource,
1699                                        WL_OUTPUT_MODE,
1700                                        mode->flags,
1701                                        mode->width,
1702                                        mode->height,
1703                                        mode->refresh);
1704         }
1705 }
1706
1707 static const char vertex_shader[] =
1708         "uniform mat4 proj;\n"
1709         "attribute vec2 position;\n"
1710         "attribute vec2 texcoord;\n"
1711         "varying vec2 v_texcoord;\n"
1712         "void main()\n"
1713         "{\n"
1714         "   gl_Position = proj * vec4(position, 0.0, 1.0);\n"
1715         "   v_texcoord = texcoord;\n"
1716         "}\n";
1717
1718 static const char texture_fragment_shader[] =
1719         "precision mediump float;\n"
1720         "varying vec2 v_texcoord;\n"
1721         "uniform sampler2D tex;\n"
1722         "uniform float alpha;\n"
1723         "void main()\n"
1724         "{\n"
1725         "   gl_FragColor = texture2D(tex, v_texcoord)\n;"
1726         "   gl_FragColor = alpha * gl_FragColor;\n"
1727         "}\n";
1728
1729 static const char solid_fragment_shader[] =
1730         "precision mediump float;\n"
1731         "uniform vec4 color;\n"
1732         "void main()\n"
1733         "{\n"
1734         "   gl_FragColor = color\n;"
1735         "}\n";
1736
1737 static int
1738 compile_shader(GLenum type, const char *source)
1739 {
1740         GLuint s;
1741         char msg[512];
1742         GLint status;
1743
1744         s = glCreateShader(type);
1745         glShaderSource(s, 1, &source, NULL);
1746         glCompileShader(s);
1747         glGetShaderiv(s, GL_COMPILE_STATUS, &status);
1748         if (!status) {
1749                 glGetShaderInfoLog(s, sizeof msg, NULL, msg);
1750                 fprintf(stderr, "shader info: %s\n", msg);
1751                 return GL_NONE;
1752         }
1753
1754         return s;
1755 }
1756
1757 static int
1758 wlsc_shader_init(struct wlsc_shader *shader,
1759                  const char *vertex_source, const char *fragment_source)
1760 {
1761         char msg[512];
1762         GLint status;
1763
1764         shader->vertex_shader =
1765                 compile_shader(GL_VERTEX_SHADER, vertex_source);
1766         shader->fragment_shader =
1767                 compile_shader(GL_FRAGMENT_SHADER, fragment_source);
1768
1769         shader->program = glCreateProgram();
1770         glAttachShader(shader->program, shader->vertex_shader);
1771         glAttachShader(shader->program, shader->fragment_shader);
1772         glBindAttribLocation(shader->program, 0, "position");
1773         glBindAttribLocation(shader->program, 1, "texcoord");
1774
1775         glLinkProgram(shader->program);
1776         glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
1777         if (!status) {
1778                 glGetProgramInfoLog(shader->program, sizeof msg, NULL, msg);
1779                 fprintf(stderr, "link info: %s\n", msg);
1780                 return -1;
1781         }
1782
1783         shader->proj_uniform = glGetUniformLocation(shader->program, "proj");
1784         shader->tex_uniform = glGetUniformLocation(shader->program, "tex");
1785         shader->alpha_uniform = glGetUniformLocation(shader->program, "alpha");
1786
1787         return 0;
1788 }
1789
1790 static int
1791 init_solid_shader(struct wlsc_shader *shader,
1792                   GLuint vertex_shader, const char *fragment_source)
1793 {
1794         GLint status;
1795         char msg[512];
1796
1797         shader->vertex_shader = vertex_shader;
1798         shader->fragment_shader =
1799                 compile_shader(GL_FRAGMENT_SHADER, fragment_source);
1800
1801         shader->program = glCreateProgram();
1802         glAttachShader(shader->program, shader->vertex_shader);
1803         glAttachShader(shader->program, shader->fragment_shader);
1804         glBindAttribLocation(shader->program, 0, "position");
1805         glBindAttribLocation(shader->program, 1, "texcoord");
1806
1807         glLinkProgram(shader->program);
1808         glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
1809         if (!status) {
1810                 glGetProgramInfoLog(shader->program, sizeof msg, NULL, msg);
1811                 fprintf(stderr, "link info: %s\n", msg);
1812                 return -1;
1813         }
1814  
1815         shader->proj_uniform = glGetUniformLocation(shader->program, "proj");
1816         shader->color_uniform = glGetUniformLocation(shader->program, "color");
1817
1818         return 0;
1819 }
1820
1821 WL_EXPORT void
1822 wlsc_output_destroy(struct wlsc_output *output)
1823 {
1824         pixman_region32_fini(&output->region);
1825         pixman_region32_fini(&output->previous_damage);
1826 }
1827
1828 WL_EXPORT void
1829 wlsc_output_move(struct wlsc_output *output, int x, int y)
1830 {
1831         int flip;
1832
1833         output->x = x;
1834         output->y = y;
1835
1836         pixman_region32_init(&output->previous_damage);
1837         pixman_region32_init_rect(&output->region, x, y, 
1838                                   output->current->width,
1839                                   output->current->height);
1840
1841         wlsc_matrix_init(&output->matrix);
1842         wlsc_matrix_translate(&output->matrix,
1843                               -output->x - output->current->width / 2.0,
1844                               -output->y - output->current->height / 2.0, 0);
1845
1846         flip = (output->flags & WL_OUTPUT_FLIPPED) ? -1 : 1;
1847         wlsc_matrix_scale(&output->matrix,
1848                           2.0 / output->current->width,
1849                           flip * 2.0 / output->current->height, 1);
1850
1851         wlsc_output_damage(output);
1852 }
1853
1854 WL_EXPORT void
1855 wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c,
1856                  int x, int y, int width, int height, uint32_t flags)
1857 {
1858         output->compositor = c;
1859         output->x = x;
1860         output->y = y;
1861         output->mm_width = width;
1862         output->mm_height = height;
1863
1864         output->flags = flags;
1865         wlsc_output_move(output, x, y);
1866
1867         output->scanout_buffer_destroy_listener.func =
1868                 output_handle_scanout_buffer_destroy;
1869         output->pending_scanout_buffer_destroy_listener.func =
1870                 output_handle_pending_scanout_buffer_destroy;
1871
1872         wl_list_init(&output->frame_callback_list);
1873
1874         wl_display_add_global(c->wl_display,
1875                               &wl_output_interface, output, bind_output);
1876 }
1877
1878 static void
1879 shm_buffer_created(struct wl_buffer *buffer)
1880 {
1881         struct wl_list *surfaces_attached_to;
1882
1883         surfaces_attached_to = malloc(sizeof *surfaces_attached_to);
1884         if (!surfaces_attached_to) {
1885                 buffer->user_data = NULL;
1886                 return;
1887         }
1888
1889         wl_list_init(surfaces_attached_to);
1890
1891         buffer->user_data = surfaces_attached_to;
1892 }
1893
1894 static void
1895 shm_buffer_damaged(struct wl_buffer *buffer,
1896                    int32_t x, int32_t y, int32_t width, int32_t height)
1897 {
1898         struct wl_list *surfaces_attached_to = buffer->user_data;
1899         struct wlsc_surface *es;
1900         GLsizei tex_width = wl_shm_buffer_get_stride(buffer) / 4;
1901
1902         wl_list_for_each(es, surfaces_attached_to, buffer_link) {
1903                 glBindTexture(GL_TEXTURE_2D, es->texture);
1904                 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
1905                              tex_width, buffer->height, 0,
1906                              GL_BGRA_EXT, GL_UNSIGNED_BYTE,
1907                              wl_shm_buffer_get_data(buffer));
1908                 /* Hmm, should use glTexSubImage2D() here but GLES2 doesn't
1909                  * support any unpack attributes except GL_UNPACK_ALIGNMENT. */
1910         }
1911 }
1912
1913 static void
1914 shm_buffer_destroyed(struct wl_buffer *buffer)
1915 {
1916         struct wl_list *surfaces_attached_to = buffer->user_data;
1917         struct wlsc_surface *es, *next;
1918
1919         wl_list_for_each_safe(es, next, surfaces_attached_to, buffer_link) {
1920                 wl_list_remove(&es->buffer_link);
1921                 wl_list_init(&es->buffer_link);
1922         }
1923
1924         free(surfaces_attached_to);
1925 }
1926
1927 const static struct wl_shm_callbacks shm_callbacks = {
1928         shm_buffer_created,
1929         shm_buffer_damaged,
1930         shm_buffer_destroyed
1931 };
1932
1933 static void
1934 compositor_bind(struct wl_client *client,
1935                 void *data, uint32_t version, uint32_t id)
1936 {
1937         struct wlsc_compositor *compositor = data;
1938
1939         wl_client_add_object(client, &wl_compositor_interface,
1940                              &compositor_interface, id, compositor);
1941 }
1942
1943 WL_EXPORT int
1944 wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display)
1945 {
1946         struct wl_event_loop *loop;
1947         const char *extensions;
1948
1949         ec->wl_display = display;
1950
1951         if (!wl_display_add_global(display, &wl_compositor_interface,
1952                                    ec, compositor_bind))
1953                 return -1;
1954
1955         ec->shm = wl_shm_init(display, &shm_callbacks);
1956
1957         ec->image_target_texture_2d =
1958                 (void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
1959         ec->image_target_renderbuffer_storage = (void *)
1960                 eglGetProcAddress("glEGLImageTargetRenderbufferStorageOES");
1961         ec->create_image = (void *) eglGetProcAddress("eglCreateImageKHR");
1962         ec->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR");
1963         ec->bind_display =
1964                 (void *) eglGetProcAddress("eglBindWaylandDisplayWL");
1965         ec->unbind_display =
1966                 (void *) eglGetProcAddress("eglUnbindWaylandDisplayWL");
1967
1968         extensions = (const char *) glGetString(GL_EXTENSIONS);
1969         if (!strstr(extensions, "GL_EXT_texture_format_BGRA8888")) {
1970                 fprintf(stderr,
1971                         "GL_EXT_texture_format_BGRA8888 not available\n");
1972                 return -1;
1973         }
1974
1975         extensions =
1976                 (const char *) eglQueryString(ec->display, EGL_EXTENSIONS);
1977         if (strstr(extensions, "EGL_WL_bind_wayland_display"))
1978                 ec->has_bind_display = 1;
1979         if (ec->has_bind_display)
1980                 ec->bind_display(ec->display, ec->wl_display);
1981
1982         wl_list_init(&ec->surface_list);
1983         wl_list_init(&ec->input_device_list);
1984         wl_list_init(&ec->output_list);
1985         wl_list_init(&ec->binding_list);
1986         wl_list_init(&ec->animation_list);
1987         wlsc_spring_init(&ec->fade.spring, 30.0, 1.0, 1.0);
1988         ec->fade.animation.frame = fade_frame;
1989         wl_list_init(&ec->fade.animation.link);
1990
1991         screenshooter_create(ec);
1992
1993         wlsc_data_device_manager_init(ec);
1994
1995         glActiveTexture(GL_TEXTURE0);
1996
1997         if (wlsc_shader_init(&ec->texture_shader,
1998                              vertex_shader, texture_fragment_shader) < 0)
1999                 return -1;
2000         if (init_solid_shader(&ec->solid_shader,
2001                               ec->texture_shader.vertex_shader,
2002                               solid_fragment_shader) < 0)
2003                 return -1;
2004
2005         loop = wl_display_get_event_loop(ec->wl_display);
2006         ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
2007         wl_event_source_timer_update(ec->idle_source, ec->idle_time * 1000);
2008
2009         wlsc_compositor_schedule_repaint(ec);
2010
2011         return 0;
2012 }
2013
2014 WL_EXPORT void
2015 wlsc_compositor_shutdown(struct wlsc_compositor *ec)
2016 {
2017         struct wlsc_output *output, *next;
2018
2019         /* Destroy all outputs associated with this compositor */
2020         wl_list_for_each_safe(output, next, &ec->output_list, link)
2021                 output->destroy(output);
2022 }
2023
2024 static int on_term_signal(int signal_number, void *data)
2025 {
2026         struct wl_display *display = data;
2027
2028         fprintf(stderr, "caught signal %d\n", signal_number);
2029         wl_display_terminate(display);
2030
2031         return 1;
2032 }
2033
2034 static void *
2035 load_module(const char *name, const char *entrypoint, void **handle)
2036 {
2037         char path[PATH_MAX];
2038         void *module, *init;
2039
2040         if (name[0] != '/')
2041                 snprintf(path, sizeof path, MODULEDIR "/%s", name);
2042         else
2043                 snprintf(path, sizeof path, "%s", name);
2044
2045         module = dlopen(path, RTLD_LAZY);
2046         if (!module) {
2047                 fprintf(stderr,
2048                         "failed to load module: %s\n", dlerror());
2049                 return NULL;
2050         }
2051
2052         init = dlsym(module, entrypoint);
2053         if (!init) {
2054                 fprintf(stderr,
2055                         "failed to lookup init function: %s\n", dlerror());
2056                 return NULL;
2057         }
2058
2059         return init;
2060 }
2061
2062 int main(int argc, char *argv[])
2063 {
2064         struct wl_display *display;
2065         struct wlsc_compositor *ec;
2066         struct wl_event_loop *loop;
2067         int o, xserver = 0;
2068         void *shell_module, *backend_module;
2069         int (*shell_init)(struct wlsc_compositor *ec);
2070         struct wlsc_compositor
2071                 *(*backend_init)(struct wl_display *display, char *options);
2072         char *backend = NULL;
2073         char *backend_options = "";
2074         char *shell = NULL;
2075         char *p;
2076         int option_idle_time = 300;
2077
2078         static const char opts[] = "B:b:o:S:i:s:x";
2079         static const struct option longopts[ ] = {
2080                 { "backend", 1, NULL, 'B' },
2081                 { "backend-options", 1, NULL, 'o' },
2082                 { "socket", 1, NULL, 'S' },
2083                 { "idle-time", 1, NULL, 'i' },
2084                 { "shell", 1, NULL, 's' },
2085                 { "xserver", 0, NULL, 'x' },
2086                 { NULL, }
2087         };
2088
2089         while (o = getopt_long(argc, argv, opts, longopts, &o), o > 0) {
2090                 switch (o) {
2091                 case 'B':
2092                         backend = optarg;
2093                         break;
2094                 case 'o':
2095                         backend_options = optarg;
2096                         break;
2097                 case 'S':
2098                         option_socket_name = optarg;
2099                         break;
2100                 case 'i':
2101                         option_idle_time = strtol(optarg, &p, 0);
2102                         if (*p != '\0') {
2103                                 fprintf(stderr,
2104                                         "invalid idle time option: %s\n",
2105                                         optarg);
2106                                 exit(EXIT_FAILURE);
2107                         }
2108                         break;
2109                 case 's':
2110                         shell = optarg;
2111                         break;
2112                 case 'x':
2113                         xserver = 1;
2114                         break;
2115                 }
2116         }
2117
2118         display = wl_display_create();
2119
2120         loop = wl_display_get_event_loop(display);
2121         wl_event_loop_add_signal(loop, SIGTERM, on_term_signal, display);
2122         wl_event_loop_add_signal(loop, SIGINT, on_term_signal, display);
2123         wl_event_loop_add_signal(loop, SIGQUIT, on_term_signal, display);
2124
2125         wl_list_init(&child_process_list);
2126         wl_event_loop_add_signal(loop, SIGCHLD, sigchld_handler, NULL);
2127
2128         if (!backend) {
2129                 if (getenv("WAYLAND_DISPLAY"))
2130                         backend = "wayland-backend.so";
2131                 else if (getenv("DISPLAY"))
2132                         backend = "x11-backend.so";
2133                 else if (getenv("OPENWFD"))
2134                         backend = "openwfd-backend.so";
2135                 else
2136                         backend = "drm-backend.so";
2137         }
2138
2139         if (!shell)
2140                 shell = "desktop-shell.so";
2141
2142         backend_init = load_module(backend, "backend_init", &backend_module);
2143         if (!backend_init)
2144                 exit(EXIT_FAILURE);
2145
2146         shell_init = load_module(shell, "shell_init", &shell_module);
2147         if (!shell_init)
2148                 exit(EXIT_FAILURE);
2149
2150         ec = backend_init(display, backend_options);
2151         if (ec == NULL) {
2152                 fprintf(stderr, "failed to create compositor\n");
2153                 exit(EXIT_FAILURE);
2154         }
2155
2156         ec->option_idle_time = option_idle_time;
2157         ec->idle_time = option_idle_time;
2158
2159         if (shell_init(ec) < 0)
2160                 exit(EXIT_FAILURE);
2161
2162         if (xserver)
2163                 wlsc_xserver_init(ec);
2164
2165         if (wl_display_add_socket(display, option_socket_name)) {
2166                 fprintf(stderr, "failed to add socket: %m\n");
2167                 exit(EXIT_FAILURE);
2168         }
2169
2170         wl_display_run(display);
2171
2172         if (xserver)
2173                 wlsc_xserver_destroy(ec);
2174
2175         if (ec->has_bind_display)
2176                 ec->unbind_display(ec->display, display);
2177
2178         ec->destroy(ec);
2179         wl_display_destroy(display);
2180
2181         return 0;
2182 }