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