59b4a537af8a00392772b9818695cb87e035ef72
[platform/upstream/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 #include "config.h"
26
27 #include <fcntl.h>
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/mman.h>
37 #include <sys/wait.h>
38 #include <sys/socket.h>
39 #include <sys/utsname.h>
40 #include <sys/stat.h>
41 #include <unistd.h>
42 #include <math.h>
43 #include <linux/input.h>
44 #include <dlfcn.h>
45 #include <signal.h>
46 #include <setjmp.h>
47 #include <sys/time.h>
48 #include <time.h>
49
50 #ifdef HAVE_LIBUNWIND
51 #define UNW_LOCAL_ONLY
52 #include <libunwind.h>
53 #endif
54
55 #include "compositor.h"
56 #include "../shared/os-compatibility.h"
57 #include "git-version.h"
58 #include "version.h"
59
60 static struct wl_list child_process_list;
61 static struct weston_compositor *segv_compositor;
62
63 static int
64 sigchld_handler(int signal_number, void *data)
65 {
66         struct weston_process *p;
67         int status;
68         pid_t pid;
69
70         pid = waitpid(-1, &status, WNOHANG);
71         if (!pid)
72                 return 1;
73
74         wl_list_for_each(p, &child_process_list, link) {
75                 if (p->pid == pid)
76                         break;
77         }
78
79         if (&p->link == &child_process_list) {
80                 weston_log("unknown child process exited\n");
81                 return 1;
82         }
83
84         wl_list_remove(&p->link);
85         p->cleanup(p, status);
86
87         return 1;
88 }
89
90 static void
91 weston_output_transform_scale_init(struct weston_output *output,
92                                    uint32_t transform, uint32_t scale);
93
94 static void
95 weston_compositor_build_view_list(struct weston_compositor *compositor);
96
97 WL_EXPORT int
98 weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode,
99                 int32_t scale, enum weston_mode_switch_op op)
100 {
101         struct weston_seat *seat;
102         struct wl_resource *resource;
103         pixman_region32_t old_output_region;
104         int ret, notify_mode_changed, notify_scale_changed;
105         int temporary_mode, temporary_scale;
106
107         if (!output->switch_mode)
108                 return -1;
109
110         temporary_mode = (output->original_mode != 0);
111         temporary_scale = (output->current_scale != output->original_scale);
112         ret = 0;
113
114         notify_mode_changed = 0;
115         notify_scale_changed = 0;
116         switch(op) {
117         case WESTON_MODE_SWITCH_SET_NATIVE:
118                 output->native_mode = mode;
119                 if (!temporary_mode) {
120                         notify_mode_changed = 1;
121                         ret = output->switch_mode(output, mode);
122                         if (ret < 0)
123                                 return ret;
124                 }
125
126                 output->native_scale = scale;
127                 if(!temporary_scale)
128                         notify_scale_changed = 1;
129                 break;
130         case WESTON_MODE_SWITCH_SET_TEMPORARY:
131                 if (!temporary_mode)
132                         output->original_mode = output->native_mode;
133                 if (!temporary_scale)
134                         output->original_scale = output->native_scale;
135
136                 ret = output->switch_mode(output, mode);
137                 if (ret < 0)
138                         return ret;
139
140                 output->current_scale = scale;
141                 break;
142         case WESTON_MODE_SWITCH_RESTORE_NATIVE:
143                 if (!temporary_mode) {
144                         weston_log("already in the native mode\n");
145                         return -1;
146                 }
147
148                 notify_mode_changed = (output->original_mode != output->native_mode);
149
150                 ret = output->switch_mode(output, mode);
151                 if (ret < 0)
152                         return ret;
153
154                 if (output->original_scale != output->native_scale) {
155                         notify_scale_changed = 1;
156                         scale = output->native_scale;
157                         output->original_scale = scale;
158                 }
159                 output->original_mode = 0;
160
161                 output->current_scale = output->native_scale;
162                 break;
163         default:
164                 weston_log("unknown weston_switch_mode_op %d\n", op);
165                 break;
166         }
167
168         pixman_region32_init(&old_output_region);
169         pixman_region32_copy(&old_output_region, &output->region);
170
171         /* Update output region and transformation matrix */
172         weston_output_transform_scale_init(output, output->transform, output->current_scale);
173
174         pixman_region32_init(&output->previous_damage);
175         pixman_region32_init_rect(&output->region, output->x, output->y,
176                                   output->width, output->height);
177
178         weston_output_update_matrix(output);
179
180         /* If a pointer falls outside the outputs new geometry, move it to its
181          * lower-right corner */
182         wl_list_for_each(seat, &output->compositor->seat_list, link) {
183                 struct weston_pointer *pointer = seat->pointer;
184                 int32_t x, y;
185
186                 if (!pointer)
187                         continue;
188
189                 x = wl_fixed_to_int(pointer->x);
190                 y = wl_fixed_to_int(pointer->y);
191
192                 if (!pixman_region32_contains_point(&old_output_region,
193                                                     x, y, NULL) ||
194                     pixman_region32_contains_point(&output->region,
195                                                    x, y, NULL))
196                         continue;
197
198                 if (x >= output->x + output->width)
199                         x = output->x + output->width - 1;
200                 if (y >= output->y + output->height)
201                         y = output->y + output->height - 1;
202
203                 pointer->x = wl_fixed_from_int(x);
204                 pointer->y = wl_fixed_from_int(y);
205         }
206
207         pixman_region32_fini(&old_output_region);
208
209         /* notify clients of the changes */
210         if (notify_mode_changed || notify_scale_changed) {
211                 wl_resource_for_each(resource, &output->resource_list) {
212                         if(notify_mode_changed) {
213                                 wl_output_send_mode(resource,
214                                                 mode->flags | WL_OUTPUT_MODE_CURRENT,
215                                                 mode->width,
216                                                 mode->height,
217                                                 mode->refresh);
218                         }
219
220                         if (notify_scale_changed)
221                                 wl_output_send_scale(resource, scale);
222
223                         if (wl_resource_get_version(resource) >= 2)
224                                    wl_output_send_done(resource);
225                 }
226         }
227
228         return ret;
229 }
230
231 WL_EXPORT void
232 weston_watch_process(struct weston_process *process)
233 {
234         wl_list_insert(&child_process_list, &process->link);
235 }
236
237 static void
238 child_client_exec(int sockfd, const char *path)
239 {
240         int clientfd;
241         char s[32];
242         sigset_t allsigs;
243
244         /* do not give our signal mask to the new process */
245         sigfillset(&allsigs);
246         sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
247
248         /* Launch clients as the user. Do not lauch clients with wrong euid.*/
249         if (seteuid(getuid()) == -1) {
250                 weston_log("compositor: failed seteuid\n");
251                 return;
252         }
253
254         /* SOCK_CLOEXEC closes both ends, so we dup the fd to get a
255          * non-CLOEXEC fd to pass through exec. */
256         clientfd = dup(sockfd);
257         if (clientfd == -1) {
258                 weston_log("compositor: dup failed: %m\n");
259                 return;
260         }
261
262         snprintf(s, sizeof s, "%d", clientfd);
263         setenv("WAYLAND_SOCKET", s, 1);
264
265         if (execl(path, path, NULL) < 0)
266                 weston_log("compositor: executing '%s' failed: %m\n",
267                         path);
268 }
269
270 WL_EXPORT struct wl_client *
271 weston_client_launch(struct weston_compositor *compositor,
272                      struct weston_process *proc,
273                      const char *path,
274                      weston_process_cleanup_func_t cleanup)
275 {
276         int sv[2];
277         pid_t pid;
278         struct wl_client *client;
279
280         weston_log("launching '%s'\n", path);
281
282         if (os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, sv) < 0) {
283                 weston_log("weston_client_launch: "
284                         "socketpair failed while launching '%s': %m\n",
285                         path);
286                 return NULL;
287         }
288
289         pid = fork();
290         if (pid == -1) {
291                 close(sv[0]);
292                 close(sv[1]);
293                 weston_log("weston_client_launch: "
294                         "fork failed while launching '%s': %m\n", path);
295                 return NULL;
296         }
297
298         if (pid == 0) {
299                 child_client_exec(sv[1], path);
300                 _exit(-1);
301         }
302
303         close(sv[1]);
304
305         client = wl_client_create(compositor->wl_display, sv[0]);
306         if (!client) {
307                 close(sv[0]);
308                 weston_log("weston_client_launch: "
309                         "wl_client_create failed while launching '%s'.\n",
310                         path);
311                 return NULL;
312         }
313
314         proc->pid = pid;
315         proc->cleanup = cleanup;
316         weston_watch_process(proc);
317
318         return client;
319 }
320
321 static void
322 surface_handle_pending_buffer_destroy(struct wl_listener *listener, void *data)
323 {
324         struct weston_surface *surface =
325                 container_of(listener, struct weston_surface,
326                              pending.buffer_destroy_listener);
327
328         surface->pending.buffer = NULL;
329 }
330
331 static void
332 empty_region(pixman_region32_t *region)
333 {
334         pixman_region32_fini(region);
335         pixman_region32_init(region);
336 }
337
338 static void
339 region_init_infinite(pixman_region32_t *region)
340 {
341         pixman_region32_init_rect(region, INT32_MIN, INT32_MIN,
342                                   UINT32_MAX, UINT32_MAX);
343 }
344
345 static struct weston_subsurface *
346 weston_surface_to_subsurface(struct weston_surface *surface);
347
348 WL_EXPORT struct weston_view *
349 weston_view_create(struct weston_surface *surface)
350 {
351         struct weston_view *view;
352
353         view = calloc(1, sizeof *view);
354         if (view == NULL)
355                 return NULL;
356
357         view->surface = surface;
358
359         /* Assign to surface */
360         wl_list_insert(&surface->views, &view->surface_link);
361
362         wl_signal_init(&view->destroy_signal);
363         wl_list_init(&view->link);
364         wl_list_init(&view->layer_link);
365
366         view->plane = NULL;
367
368         pixman_region32_init(&view->clip);
369
370         view->alpha = 1.0;
371         pixman_region32_init(&view->transform.opaque);
372
373         wl_list_init(&view->geometry.transformation_list);
374         wl_list_insert(&view->geometry.transformation_list,
375                        &view->transform.position.link);
376         weston_matrix_init(&view->transform.position.matrix);
377         wl_list_init(&view->geometry.child_list);
378         pixman_region32_init(&view->transform.boundingbox);
379         view->transform.dirty = 1;
380
381         view->output = NULL;
382
383         return view;
384 }
385
386 WL_EXPORT struct weston_surface *
387 weston_surface_create(struct weston_compositor *compositor)
388 {
389         struct weston_surface *surface;
390
391         surface = calloc(1, sizeof *surface);
392         if (surface == NULL)
393                 return NULL;
394
395         wl_signal_init(&surface->destroy_signal);
396
397         surface->resource = NULL;
398
399         surface->compositor = compositor;
400         surface->ref_count = 1;
401
402         surface->buffer_viewport.transform = WL_OUTPUT_TRANSFORM_NORMAL;
403         surface->buffer_viewport.scale = 1;
404         surface->pending.buffer_viewport = surface->buffer_viewport;
405         surface->output = NULL;
406         surface->pending.newly_attached = 0;
407
408         pixman_region32_init(&surface->damage);
409         pixman_region32_init(&surface->opaque);
410         region_init_infinite(&surface->input);
411
412         wl_list_init(&surface->views);
413
414         wl_list_init(&surface->frame_callback_list);
415
416         surface->pending.buffer_destroy_listener.notify =
417                 surface_handle_pending_buffer_destroy;
418         pixman_region32_init(&surface->pending.damage);
419         pixman_region32_init(&surface->pending.opaque);
420         region_init_infinite(&surface->pending.input);
421         wl_list_init(&surface->pending.frame_callback_list);
422
423         wl_list_init(&surface->subsurface_list);
424         wl_list_init(&surface->subsurface_list_pending);
425
426         return surface;
427 }
428
429 WL_EXPORT void
430 weston_surface_set_color(struct weston_surface *surface,
431                  float red, float green, float blue, float alpha)
432 {
433         surface->compositor->renderer->surface_set_color(surface, red, green, blue, alpha);
434 }
435
436 WL_EXPORT void
437 weston_view_to_global_float(struct weston_view *view,
438                             float sx, float sy, float *x, float *y)
439 {
440         if (view->transform.enabled) {
441                 struct weston_vector v = { { sx, sy, 0.0f, 1.0f } };
442
443                 weston_matrix_transform(&view->transform.matrix, &v);
444
445                 if (fabsf(v.f[3]) < 1e-6) {
446                         weston_log("warning: numerical instability in "
447                                 "%s(), divisor = %g\n", __func__,
448                                 v.f[3]);
449                         *x = 0;
450                         *y = 0;
451                         return;
452                 }
453
454                 *x = v.f[0] / v.f[3];
455                 *y = v.f[1] / v.f[3];
456         } else {
457                 *x = sx + view->geometry.x;
458                 *y = sy + view->geometry.y;
459         }
460 }
461
462 WL_EXPORT void
463 weston_transformed_coord(int width, int height,
464                          enum wl_output_transform transform,
465                          int32_t scale,
466                          float sx, float sy, float *bx, float *by)
467 {
468         switch (transform) {
469         case WL_OUTPUT_TRANSFORM_NORMAL:
470         default:
471                 *bx = sx;
472                 *by = sy;
473                 break;
474         case WL_OUTPUT_TRANSFORM_FLIPPED:
475                 *bx = width - sx;
476                 *by = sy;
477                 break;
478         case WL_OUTPUT_TRANSFORM_90:
479                 *bx = height - sy;
480                 *by = sx;
481                 break;
482         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
483                 *bx = height - sy;
484                 *by = width - sx;
485                 break;
486         case WL_OUTPUT_TRANSFORM_180:
487                 *bx = width - sx;
488                 *by = height - sy;
489                 break;
490         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
491                 *bx = sx;
492                 *by = height - sy;
493                 break;
494         case WL_OUTPUT_TRANSFORM_270:
495                 *bx = sy;
496                 *by = width - sx;
497                 break;
498         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
499                 *bx = sy;
500                 *by = sx;
501                 break;
502         }
503
504         *bx *= scale;
505         *by *= scale;
506 }
507
508 WL_EXPORT pixman_box32_t
509 weston_transformed_rect(int width, int height,
510                         enum wl_output_transform transform,
511                         int32_t scale,
512                         pixman_box32_t rect)
513 {
514         float x1, x2, y1, y2;
515
516         pixman_box32_t ret;
517
518         weston_transformed_coord(width, height, transform, scale,
519                                  rect.x1, rect.y1, &x1, &y1);
520         weston_transformed_coord(width, height, transform, scale,
521                                  rect.x2, rect.y2, &x2, &y2);
522
523         if (x1 <= x2) {
524                 ret.x1 = x1;
525                 ret.x2 = x2;
526         } else {
527                 ret.x1 = x2;
528                 ret.x2 = x1;
529         }
530
531         if (y1 <= y2) {
532                 ret.y1 = y1;
533                 ret.y2 = y2;
534         } else {
535                 ret.y1 = y2;
536                 ret.y2 = y1;
537         }
538
539         return ret;
540 }
541
542 WL_EXPORT void
543 weston_transformed_region(int width, int height,
544                           enum wl_output_transform transform,
545                           int32_t scale,
546                           pixman_region32_t *src, pixman_region32_t *dest)
547 {
548         pixman_box32_t *src_rects, *dest_rects;
549         int nrects, i;
550
551         if (transform == WL_OUTPUT_TRANSFORM_NORMAL && scale == 1) {
552                 if (src != dest)
553                         pixman_region32_copy(dest, src);
554                 return;
555         }
556
557         src_rects = pixman_region32_rectangles(src, &nrects);
558         dest_rects = malloc(nrects * sizeof(*dest_rects));
559         if (!dest_rects)
560                 return;
561
562         if (transform == WL_OUTPUT_TRANSFORM_NORMAL) {
563                 memcpy(dest_rects, src_rects, nrects * sizeof(*dest_rects));
564         } else {
565                 for (i = 0; i < nrects; i++) {
566                         switch (transform) {
567                         default:
568                         case WL_OUTPUT_TRANSFORM_NORMAL:
569                                 dest_rects[i].x1 = src_rects[i].x1;
570                                 dest_rects[i].y1 = src_rects[i].y1;
571                                 dest_rects[i].x2 = src_rects[i].x2;
572                                 dest_rects[i].y2 = src_rects[i].y2;
573                                 break;
574                         case WL_OUTPUT_TRANSFORM_90:
575                                 dest_rects[i].x1 = height - src_rects[i].y2;
576                                 dest_rects[i].y1 = src_rects[i].x1;
577                                 dest_rects[i].x2 = height - src_rects[i].y1;
578                                 dest_rects[i].y2 = src_rects[i].x2;
579                                 break;
580                         case WL_OUTPUT_TRANSFORM_180:
581                                 dest_rects[i].x1 = width - src_rects[i].x2;
582                                 dest_rects[i].y1 = height - src_rects[i].y2;
583                                 dest_rects[i].x2 = width - src_rects[i].x1;
584                                 dest_rects[i].y2 = height - src_rects[i].y1;
585                                 break;
586                         case WL_OUTPUT_TRANSFORM_270:
587                                 dest_rects[i].x1 = src_rects[i].y1;
588                                 dest_rects[i].y1 = width - src_rects[i].x2;
589                                 dest_rects[i].x2 = src_rects[i].y2;
590                                 dest_rects[i].y2 = width - src_rects[i].x1;
591                                 break;
592                         case WL_OUTPUT_TRANSFORM_FLIPPED:
593                                 dest_rects[i].x1 = width - src_rects[i].x2;
594                                 dest_rects[i].y1 = src_rects[i].y1;
595                                 dest_rects[i].x2 = width - src_rects[i].x1;
596                                 dest_rects[i].y2 = src_rects[i].y2;
597                                 break;
598                         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
599                                 dest_rects[i].x1 = height - src_rects[i].y2;
600                                 dest_rects[i].y1 = width - src_rects[i].x2;
601                                 dest_rects[i].x2 = height - src_rects[i].y1;
602                                 dest_rects[i].y2 = width - src_rects[i].x1;
603                                 break;
604                         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
605                                 dest_rects[i].x1 = src_rects[i].x1;
606                                 dest_rects[i].y1 = height - src_rects[i].y2;
607                                 dest_rects[i].x2 = src_rects[i].x2;
608                                 dest_rects[i].y2 = height - src_rects[i].y1;
609                                 break;
610                         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
611                                 dest_rects[i].x1 = src_rects[i].y1;
612                                 dest_rects[i].y1 = src_rects[i].x1;
613                                 dest_rects[i].x2 = src_rects[i].y2;
614                                 dest_rects[i].y2 = src_rects[i].x2;
615                                 break;
616                         }
617                 }
618         }
619
620         if (scale != 1) {
621                 for (i = 0; i < nrects; i++) {
622                         dest_rects[i].x1 *= scale;
623                         dest_rects[i].x2 *= scale;
624                         dest_rects[i].y1 *= scale;
625                         dest_rects[i].y2 *= scale;
626                 }
627         }
628
629         pixman_region32_clear(dest);
630         pixman_region32_init_rects(dest, dest_rects, nrects);
631         free(dest_rects);
632 }
633
634 WL_EXPORT void
635 weston_surface_to_buffer_float(struct weston_surface *surface,
636                                float sx, float sy, float *bx, float *by)
637 {
638         weston_transformed_coord(surface->width,
639                                  surface->height,
640                                  surface->buffer_viewport.transform,
641                                  surface->buffer_viewport.scale,
642                                  sx, sy, bx, by);
643 }
644
645 WL_EXPORT void
646 weston_surface_to_buffer(struct weston_surface *surface,
647                          int sx, int sy, int *bx, int *by)
648 {
649         float bxf, byf;
650
651         weston_transformed_coord(surface->width,
652                                  surface->height,
653                                  surface->buffer_viewport.transform,
654                                  surface->buffer_viewport.scale,
655                                  sx, sy, &bxf, &byf);
656         *bx = floorf(bxf);
657         *by = floorf(byf);
658 }
659
660 WL_EXPORT pixman_box32_t
661 weston_surface_to_buffer_rect(struct weston_surface *surface,
662                               pixman_box32_t rect)
663 {
664         return weston_transformed_rect(surface->width,
665                                        surface->height,
666                                        surface->buffer_viewport.transform,
667                                        surface->buffer_viewport.scale,
668                                        rect);
669 }
670
671 WL_EXPORT void
672 weston_view_move_to_plane(struct weston_view *view,
673                              struct weston_plane *plane)
674 {
675         if (view->plane == plane)
676                 return;
677
678         weston_view_damage_below(view);
679         view->plane = plane;
680         weston_surface_damage(view->surface);
681 }
682
683 WL_EXPORT void
684 weston_view_damage_below(struct weston_view *view)
685 {
686         pixman_region32_t damage;
687
688         pixman_region32_init(&damage);
689         pixman_region32_subtract(&damage, &view->transform.boundingbox,
690                                  &view->clip);
691         if (view->plane)
692                 pixman_region32_union(&view->plane->damage,
693                                       &view->plane->damage, &damage);
694         pixman_region32_fini(&damage);
695         weston_view_schedule_repaint(view);
696 }
697
698 static void
699 weston_surface_update_output_mask(struct weston_surface *es, uint32_t mask)
700 {
701         uint32_t different = es->output_mask ^ mask;
702         uint32_t entered = mask & different;
703         uint32_t left = es->output_mask & different;
704         struct weston_output *output;
705         struct wl_resource *resource = NULL;
706         struct wl_client *client;
707
708         es->output_mask = mask;
709         if (es->resource == NULL)
710                 return;
711         if (different == 0)
712                 return;
713
714         client = wl_resource_get_client(es->resource);
715
716         wl_list_for_each(output, &es->compositor->output_list, link) {
717                 if (1 << output->id & different)
718                         resource =
719                                 wl_resource_find_for_client(&output->resource_list,
720                                                          client);
721                 if (resource == NULL)
722                         continue;
723                 if (1 << output->id & entered)
724                         wl_surface_send_enter(es->resource, resource);
725                 if (1 << output->id & left)
726                         wl_surface_send_leave(es->resource, resource);
727         }
728 }
729
730 static void
731 weston_surface_assign_output(struct weston_surface *es)
732 {
733         struct weston_output *new_output;
734         struct weston_view *view;
735         pixman_region32_t region;
736         uint32_t max, area, mask;
737         pixman_box32_t *e;
738
739         new_output = NULL;
740         max = 0;
741         mask = 0;
742         pixman_region32_init(&region);
743         wl_list_for_each(view, &es->views, surface_link) {
744                 if (!view->output)
745                         continue;
746
747                 pixman_region32_intersect(&region, &view->transform.boundingbox,
748                                           &view->output->region);
749
750                 e = pixman_region32_extents(&region);
751                 area = (e->x2 - e->x1) * (e->y2 - e->y1);
752
753                 mask |= view->output_mask;
754
755                 if (area >= max) {
756                         new_output = view->output;
757                         max = area;
758                 }
759         }
760         pixman_region32_fini(&region);
761
762         es->output = new_output;
763         weston_surface_update_output_mask(es, mask);
764 }
765
766 static void
767 weston_view_assign_output(struct weston_view *ev)
768 {
769         struct weston_compositor *ec = ev->surface->compositor;
770         struct weston_output *output, *new_output;
771         pixman_region32_t region;
772         uint32_t max, area, mask;
773         pixman_box32_t *e;
774
775         new_output = NULL;
776         max = 0;
777         mask = 0;
778         pixman_region32_init(&region);
779         wl_list_for_each(output, &ec->output_list, link) {
780                 pixman_region32_intersect(&region, &ev->transform.boundingbox,
781                                           &output->region);
782
783                 e = pixman_region32_extents(&region);
784                 area = (e->x2 - e->x1) * (e->y2 - e->y1);
785
786                 if (area > 0)
787                         mask |= 1 << output->id;
788
789                 if (area >= max) {
790                         new_output = output;
791                         max = area;
792                 }
793         }
794         pixman_region32_fini(&region);
795
796         ev->output = new_output;
797         ev->output_mask = mask;
798
799         weston_surface_assign_output(ev->surface);
800 }
801
802 static void
803 view_compute_bbox(struct weston_view *view, int32_t sx, int32_t sy,
804                   int32_t width, int32_t height,
805                   pixman_region32_t *bbox)
806 {
807         float min_x = HUGE_VALF,  min_y = HUGE_VALF;
808         float max_x = -HUGE_VALF, max_y = -HUGE_VALF;
809         int32_t s[4][2] = {
810                 { sx,         sy },
811                 { sx,         sy + height },
812                 { sx + width, sy },
813                 { sx + width, sy + height }
814         };
815         float int_x, int_y;
816         int i;
817
818         if (width == 0 || height == 0) {
819                 /* avoid rounding empty bbox to 1x1 */
820                 pixman_region32_init(bbox);
821                 return;
822         }
823
824         for (i = 0; i < 4; ++i) {
825                 float x, y;
826                 weston_view_to_global_float(view, s[i][0], s[i][1], &x, &y);
827                 if (x < min_x)
828                         min_x = x;
829                 if (x > max_x)
830                         max_x = x;
831                 if (y < min_y)
832                         min_y = y;
833                 if (y > max_y)
834                         max_y = y;
835         }
836
837         int_x = floorf(min_x);
838         int_y = floorf(min_y);
839         pixman_region32_init_rect(bbox, int_x, int_y,
840                                   ceilf(max_x) - int_x, ceilf(max_y) - int_y);
841 }
842
843 static void
844 weston_view_update_transform_disable(struct weston_view *view)
845 {
846         view->transform.enabled = 0;
847
848         /* round off fractions when not transformed */
849         view->geometry.x = roundf(view->geometry.x);
850         view->geometry.y = roundf(view->geometry.y);
851
852         /* Otherwise identity matrix, but with x and y translation. */
853         view->transform.position.matrix.type = WESTON_MATRIX_TRANSFORM_TRANSLATE;
854         view->transform.position.matrix.d[12] = view->geometry.x;
855         view->transform.position.matrix.d[13] = view->geometry.y;
856
857         view->transform.matrix = view->transform.position.matrix;
858
859         view->transform.inverse = view->transform.position.matrix;
860         view->transform.inverse.d[12] = -view->geometry.x;
861         view->transform.inverse.d[13] = -view->geometry.y;
862
863         pixman_region32_init_rect(&view->transform.boundingbox,
864                                   view->geometry.x,
865                                   view->geometry.y,
866                                   view->geometry.width,
867                                   view->geometry.height);
868
869         if (view->alpha == 1.0) {
870                 pixman_region32_copy(&view->transform.opaque,
871                                      &view->surface->opaque);
872                 pixman_region32_translate(&view->transform.opaque,
873                                           view->geometry.x,
874                                           view->geometry.y);
875         }
876 }
877
878 static int
879 weston_view_update_transform_enable(struct weston_view *view)
880 {
881         struct weston_view *parent = view->geometry.parent;
882         struct weston_matrix *matrix = &view->transform.matrix;
883         struct weston_matrix *inverse = &view->transform.inverse;
884         struct weston_transform *tform;
885
886         view->transform.enabled = 1;
887
888         /* Otherwise identity matrix, but with x and y translation. */
889         view->transform.position.matrix.type = WESTON_MATRIX_TRANSFORM_TRANSLATE;
890         view->transform.position.matrix.d[12] = view->geometry.x;
891         view->transform.position.matrix.d[13] = view->geometry.y;
892
893         weston_matrix_init(matrix);
894         wl_list_for_each(tform, &view->geometry.transformation_list, link)
895                 weston_matrix_multiply(matrix, &tform->matrix);
896
897         if (parent)
898                 weston_matrix_multiply(matrix, &parent->transform.matrix);
899
900         if (weston_matrix_invert(inverse, matrix) < 0) {
901                 /* Oops, bad total transformation, not invertible */
902                 weston_log("error: weston_view %p"
903                         " transformation not invertible.\n", view);
904                 return -1;
905         }
906
907         view_compute_bbox(view, 0, 0, view->geometry.width,
908                           view->geometry.height,
909                           &view->transform.boundingbox);
910
911         return 0;
912 }
913
914 WL_EXPORT void
915 weston_view_update_transform(struct weston_view *view)
916 {
917         struct weston_view *parent = view->geometry.parent;
918
919         if (!view->transform.dirty)
920                 return;
921
922         if (parent)
923                 weston_view_update_transform(parent);
924
925         view->transform.dirty = 0;
926
927         weston_view_damage_below(view);
928
929         pixman_region32_fini(&view->transform.boundingbox);
930         pixman_region32_fini(&view->transform.opaque);
931         pixman_region32_init(&view->transform.opaque);
932
933         /* transform.position is always in transformation_list */
934         if (view->geometry.transformation_list.next ==
935             &view->transform.position.link &&
936             view->geometry.transformation_list.prev ==
937             &view->transform.position.link &&
938             !parent) {
939                 weston_view_update_transform_disable(view);
940         } else {
941                 if (weston_view_update_transform_enable(view) < 0)
942                         weston_view_update_transform_disable(view);
943         }
944
945         weston_view_damage_below(view);
946
947         weston_view_assign_output(view);
948
949         wl_signal_emit(&view->surface->compositor->transform_signal,
950                        view->surface);
951 }
952
953 WL_EXPORT void
954 weston_view_geometry_dirty(struct weston_view *view)
955 {
956         struct weston_view *child;
957
958         /*
959          * The invariant: if view->geometry.dirty, then all views
960          * in view->geometry.child_list have geometry.dirty too.
961          * Corollary: if not parent->geometry.dirty, then all ancestors
962          * are not dirty.
963          */
964
965         if (view->transform.dirty)
966                 return;
967
968         view->transform.dirty = 1;
969
970         wl_list_for_each(child, &view->geometry.child_list,
971                          geometry.parent_link)
972                 weston_view_geometry_dirty(child);
973 }
974
975 WL_EXPORT void
976 weston_view_to_global_fixed(struct weston_view *view,
977                             wl_fixed_t vx, wl_fixed_t vy,
978                             wl_fixed_t *x, wl_fixed_t *y)
979 {
980         float xf, yf;
981
982         weston_view_to_global_float(view,
983                                     wl_fixed_to_double(vx),
984                                     wl_fixed_to_double(vy),
985                                     &xf, &yf);
986         *x = wl_fixed_from_double(xf);
987         *y = wl_fixed_from_double(yf);
988 }
989
990 WL_EXPORT void
991 weston_view_from_global_float(struct weston_view *view,
992                               float x, float y, float *vx, float *vy)
993 {
994         if (view->transform.enabled) {
995                 struct weston_vector v = { { x, y, 0.0f, 1.0f } };
996
997                 weston_matrix_transform(&view->transform.inverse, &v);
998
999                 if (fabsf(v.f[3]) < 1e-6) {
1000                         weston_log("warning: numerical instability in "
1001                                 "weston_view_from_global(), divisor = %g\n",
1002                                 v.f[3]);
1003                         *vx = 0;
1004                         *vy = 0;
1005                         return;
1006                 }
1007
1008                 *vx = v.f[0] / v.f[3];
1009                 *vy = v.f[1] / v.f[3];
1010         } else {
1011                 *vx = x - view->geometry.x;
1012                 *vy = y - view->geometry.y;
1013         }
1014 }
1015
1016 WL_EXPORT void
1017 weston_view_from_global_fixed(struct weston_view *view,
1018                               wl_fixed_t x, wl_fixed_t y,
1019                               wl_fixed_t *vx, wl_fixed_t *vy)
1020 {
1021         float vxf, vyf;
1022
1023         weston_view_from_global_float(view,
1024                                       wl_fixed_to_double(x),
1025                                       wl_fixed_to_double(y),
1026                                       &vxf, &vyf);
1027         *vx = wl_fixed_from_double(vxf);
1028         *vy = wl_fixed_from_double(vyf);
1029 }
1030
1031 WL_EXPORT void
1032 weston_view_from_global(struct weston_view *view,
1033                         int32_t x, int32_t y, int32_t *vx, int32_t *vy)
1034 {
1035         float vxf, vyf;
1036
1037         weston_view_from_global_float(view, x, y, &vxf, &vyf);
1038         *vx = floorf(vxf);
1039         *vy = floorf(vyf);
1040 }
1041
1042 WL_EXPORT void
1043 weston_surface_schedule_repaint(struct weston_surface *surface)
1044 {
1045         struct weston_output *output;
1046
1047         wl_list_for_each(output, &surface->compositor->output_list, link)
1048                 if (surface->output_mask & (1 << output->id))
1049                         weston_output_schedule_repaint(output);
1050 }
1051
1052 WL_EXPORT void
1053 weston_view_schedule_repaint(struct weston_view *view)
1054 {
1055         struct weston_output *output;
1056
1057         wl_list_for_each(output, &view->surface->compositor->output_list, link)
1058                 if (view->output_mask & (1 << output->id))
1059                         weston_output_schedule_repaint(output);
1060 }
1061
1062 WL_EXPORT void
1063 weston_surface_damage(struct weston_surface *surface)
1064 {
1065         pixman_region32_union_rect(&surface->damage, &surface->damage,
1066                                    0, 0, surface->width,
1067                                    surface->height);
1068
1069         weston_surface_schedule_repaint(surface);
1070 }
1071
1072 WL_EXPORT void
1073 weston_view_configure(struct weston_view *view,
1074                       float x, float y, int width, int height)
1075 {
1076         view->geometry.x = x;
1077         view->geometry.y = y;
1078         view->geometry.width = width;
1079         view->geometry.height = height;
1080         weston_view_geometry_dirty(view);
1081 }
1082
1083 WL_EXPORT void
1084 weston_view_set_position(struct weston_view *view, float x, float y)
1085 {
1086         view->geometry.x = x;
1087         view->geometry.y = y;
1088         weston_view_geometry_dirty(view);
1089 }
1090
1091 static void
1092 transform_parent_handle_parent_destroy(struct wl_listener *listener,
1093                                        void *data)
1094 {
1095         struct weston_view *view =
1096                 container_of(listener, struct weston_view,
1097                              geometry.parent_destroy_listener);
1098
1099         weston_view_set_transform_parent(view, NULL);
1100 }
1101
1102 WL_EXPORT void
1103 weston_view_set_transform_parent(struct weston_view *view,
1104                                     struct weston_view *parent)
1105 {
1106         if (view->geometry.parent) {
1107                 wl_list_remove(&view->geometry.parent_destroy_listener.link);
1108                 wl_list_remove(&view->geometry.parent_link);
1109         }
1110
1111         view->geometry.parent = parent;
1112
1113         view->geometry.parent_destroy_listener.notify =
1114                 transform_parent_handle_parent_destroy;
1115         if (parent) {
1116                 wl_signal_add(&parent->destroy_signal,
1117                               &view->geometry.parent_destroy_listener);
1118                 wl_list_insert(&parent->geometry.child_list,
1119                                &view->geometry.parent_link);
1120         }
1121
1122         weston_view_geometry_dirty(view);
1123 }
1124
1125 WL_EXPORT int
1126 weston_view_is_mapped(struct weston_view *view)
1127 {
1128         if (view->output)
1129                 return 1;
1130         else
1131                 return 0;
1132 }
1133
1134 WL_EXPORT int
1135 weston_surface_is_mapped(struct weston_surface *surface)
1136 {
1137         if (surface->output)
1138                 return 1;
1139         else
1140                 return 0;
1141 }
1142
1143 WL_EXPORT int32_t
1144 weston_surface_buffer_width(struct weston_surface *surface)
1145 {
1146         int32_t width;
1147         switch (surface->buffer_viewport.transform) {
1148         case WL_OUTPUT_TRANSFORM_90:
1149         case WL_OUTPUT_TRANSFORM_270:
1150         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
1151         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
1152                 width = surface->buffer_ref.buffer->height;
1153                 break;
1154         default:
1155                 width = surface->buffer_ref.buffer->width;
1156                 break;
1157         }
1158         return width / surface->buffer_viewport.scale;
1159 }
1160
1161 WL_EXPORT int32_t
1162 weston_surface_buffer_height(struct weston_surface *surface)
1163 {
1164         int32_t height;
1165         switch (surface->buffer_viewport.transform) {
1166         case WL_OUTPUT_TRANSFORM_90:
1167         case WL_OUTPUT_TRANSFORM_270:
1168         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
1169         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
1170                 height = surface->buffer_ref.buffer->width;
1171                 break;
1172         default:
1173                 height = surface->buffer_ref.buffer->height;
1174                 break;
1175         }
1176         return height / surface->buffer_viewport.scale;
1177 }
1178
1179 WL_EXPORT uint32_t
1180 weston_compositor_get_time(void)
1181 {
1182        struct timeval tv;
1183
1184        gettimeofday(&tv, NULL);
1185
1186        return tv.tv_sec * 1000 + tv.tv_usec / 1000;
1187 }
1188
1189 WL_EXPORT struct weston_view *
1190 weston_compositor_pick_view(struct weston_compositor *compositor,
1191                             wl_fixed_t x, wl_fixed_t y,
1192                             wl_fixed_t *vx, wl_fixed_t *vy)
1193 {
1194         struct weston_view *view;
1195
1196         wl_list_for_each(view, &compositor->view_list, link) {
1197                 weston_view_from_global_fixed(view, x, y, vx, vy);
1198                 if (pixman_region32_contains_point(&view->surface->input,
1199                                                    wl_fixed_to_int(*vx),
1200                                                    wl_fixed_to_int(*vy),
1201                                                    NULL))
1202                         return view;
1203         }
1204
1205         return NULL;
1206 }
1207
1208 static void
1209 weston_compositor_repick(struct weston_compositor *compositor)
1210 {
1211         struct weston_seat *seat;
1212
1213         if (!compositor->session_active)
1214                 return;
1215
1216         wl_list_for_each(seat, &compositor->seat_list, link)
1217                 weston_seat_repick(seat);
1218 }
1219
1220 WL_EXPORT void
1221 weston_view_unmap(struct weston_view *view)
1222 {
1223         struct weston_seat *seat;
1224
1225         if (!weston_view_is_mapped(view))
1226                 return;
1227
1228         weston_view_damage_below(view);
1229         view->output = NULL;
1230         view->plane = NULL;
1231         wl_list_remove(&view->layer_link);
1232         wl_list_init(&view->layer_link);
1233         wl_list_remove(&view->link);
1234         wl_list_init(&view->link);
1235         view->output_mask = 0;
1236         weston_surface_assign_output(view->surface);
1237
1238         if (weston_surface_is_mapped(view->surface))
1239                 return;
1240
1241         wl_list_for_each(seat, &view->surface->compositor->seat_list, link) {
1242                 if (seat->keyboard && seat->keyboard->focus == view->surface)
1243                         weston_keyboard_set_focus(seat->keyboard, NULL);
1244                 if (seat->pointer && seat->pointer->focus == view)
1245                         weston_pointer_set_focus(seat->pointer,
1246                                                  NULL,
1247                                                  wl_fixed_from_int(0),
1248                                                  wl_fixed_from_int(0));
1249                 if (seat->touch && seat->touch->focus == view)
1250                         weston_touch_set_focus(seat, NULL);
1251         }
1252 }
1253
1254 WL_EXPORT void
1255 weston_surface_unmap(struct weston_surface *surface)
1256 {
1257         struct weston_view *view;
1258
1259         wl_list_for_each(view, &surface->views, surface_link)
1260                 weston_view_unmap(view);
1261         surface->output = NULL;
1262 }
1263
1264 struct weston_frame_callback {
1265         struct wl_resource *resource;
1266         struct wl_list link;
1267 };
1268
1269 WL_EXPORT void
1270 weston_view_destroy(struct weston_view *view)
1271 {
1272         wl_signal_emit(&view->destroy_signal, view);
1273
1274         assert(wl_list_empty(&view->geometry.child_list));
1275
1276         if (weston_view_is_mapped(view)) {
1277                 weston_view_unmap(view);
1278                 weston_compositor_build_view_list(view->surface->compositor);
1279         }
1280
1281         wl_list_remove(&view->link);
1282         wl_list_remove(&view->layer_link);
1283
1284         pixman_region32_fini(&view->clip);
1285         pixman_region32_fini(&view->transform.boundingbox);
1286
1287         weston_view_set_transform_parent(view, NULL);
1288
1289         wl_list_remove(&view->surface_link);
1290
1291         free(view);
1292 }
1293
1294 WL_EXPORT void
1295 weston_surface_destroy(struct weston_surface *surface)
1296 {
1297         struct weston_frame_callback *cb, *next;
1298         struct weston_view *ev, *nv;
1299
1300         if (--surface->ref_count > 0)
1301                 return;
1302
1303         wl_signal_emit(&surface->destroy_signal, &surface->resource);
1304
1305         assert(wl_list_empty(&surface->subsurface_list_pending));
1306         assert(wl_list_empty(&surface->subsurface_list));
1307
1308         wl_list_for_each_safe(ev, nv, &surface->views, surface_link)
1309                 weston_view_destroy(ev);
1310
1311         wl_list_for_each_safe(cb, next,
1312                               &surface->pending.frame_callback_list, link)
1313                 wl_resource_destroy(cb->resource);
1314
1315         pixman_region32_fini(&surface->pending.input);
1316         pixman_region32_fini(&surface->pending.opaque);
1317         pixman_region32_fini(&surface->pending.damage);
1318
1319         if (surface->pending.buffer)
1320                 wl_list_remove(&surface->pending.buffer_destroy_listener.link);
1321
1322         weston_buffer_reference(&surface->buffer_ref, NULL);
1323
1324         pixman_region32_fini(&surface->damage);
1325         pixman_region32_fini(&surface->opaque);
1326         pixman_region32_fini(&surface->input);
1327
1328         wl_list_for_each_safe(cb, next, &surface->frame_callback_list, link)
1329                 wl_resource_destroy(cb->resource);
1330
1331         free(surface);
1332 }
1333
1334 static void
1335 destroy_surface(struct wl_resource *resource)
1336 {
1337         struct weston_surface *surface = wl_resource_get_user_data(resource);
1338
1339         /* Set the resource to NULL, since we don't want to leave a
1340          * dangling pointer if the surface was refcounted and survives
1341          * the weston_surface_destroy() call. */
1342         surface->resource = NULL;
1343         weston_surface_destroy(surface);
1344 }
1345
1346 static void
1347 weston_buffer_destroy_handler(struct wl_listener *listener, void *data)
1348 {
1349         struct weston_buffer *buffer =
1350                 container_of(listener, struct weston_buffer, destroy_listener);
1351
1352         wl_signal_emit(&buffer->destroy_signal, buffer);
1353         free(buffer);
1354 }
1355
1356 struct weston_buffer *
1357 weston_buffer_from_resource(struct wl_resource *resource)
1358 {
1359         struct weston_buffer *buffer;
1360         struct wl_listener *listener;
1361         
1362         listener = wl_resource_get_destroy_listener(resource,
1363                                                     weston_buffer_destroy_handler);
1364
1365         if (listener)
1366                 return container_of(listener, struct weston_buffer,
1367                                     destroy_listener);
1368
1369         buffer = zalloc(sizeof *buffer);
1370         if (buffer == NULL)
1371                 return NULL;
1372
1373         buffer->resource = resource;
1374         wl_signal_init(&buffer->destroy_signal);
1375         buffer->destroy_listener.notify = weston_buffer_destroy_handler;
1376         buffer->y_inverted = 1;
1377         wl_resource_add_destroy_listener(resource, &buffer->destroy_listener);
1378         
1379         return buffer;
1380 }
1381
1382 static void
1383 weston_buffer_reference_handle_destroy(struct wl_listener *listener,
1384                                        void *data)
1385 {
1386         struct weston_buffer_reference *ref =
1387                 container_of(listener, struct weston_buffer_reference,
1388                              destroy_listener);
1389
1390         assert((struct weston_buffer *)data == ref->buffer);
1391         ref->buffer = NULL;
1392 }
1393
1394 WL_EXPORT void
1395 weston_buffer_reference(struct weston_buffer_reference *ref,
1396                         struct weston_buffer *buffer)
1397 {
1398         if (ref->buffer && buffer != ref->buffer) {
1399                 ref->buffer->busy_count--;
1400                 if (ref->buffer->busy_count == 0) {
1401                         assert(wl_resource_get_client(ref->buffer->resource));
1402                         wl_resource_queue_event(ref->buffer->resource,
1403                                                 WL_BUFFER_RELEASE);
1404                 }
1405                 wl_list_remove(&ref->destroy_listener.link);
1406         }
1407
1408         if (buffer && buffer != ref->buffer) {
1409                 buffer->busy_count++;
1410                 wl_signal_add(&buffer->destroy_signal,
1411                               &ref->destroy_listener);
1412         }
1413
1414         ref->buffer = buffer;
1415         ref->destroy_listener.notify = weston_buffer_reference_handle_destroy;
1416 }
1417
1418 static void
1419 weston_surface_attach(struct weston_surface *surface,
1420                       struct weston_buffer *buffer)
1421 {
1422         weston_buffer_reference(&surface->buffer_ref, buffer);
1423
1424         if (!buffer) {
1425                 if (weston_surface_is_mapped(surface))
1426                         weston_surface_unmap(surface);
1427         }
1428
1429         surface->compositor->renderer->attach(surface, buffer);
1430 }
1431
1432 WL_EXPORT void
1433 weston_view_restack(struct weston_view *view, struct wl_list *below)
1434 {
1435         wl_list_remove(&view->layer_link);
1436         wl_list_insert(below, &view->layer_link);
1437         weston_view_damage_below(view);
1438         weston_surface_damage(view->surface);
1439 }
1440
1441 WL_EXPORT void
1442 weston_compositor_damage_all(struct weston_compositor *compositor)
1443 {
1444         struct weston_output *output;
1445
1446         wl_list_for_each(output, &compositor->output_list, link)
1447                 weston_output_damage(output);
1448 }
1449
1450 WL_EXPORT void
1451 weston_output_damage(struct weston_output *output)
1452 {
1453         struct weston_compositor *compositor = output->compositor;
1454
1455         pixman_region32_union(&compositor->primary_plane.damage,
1456                               &compositor->primary_plane.damage,
1457                               &output->region);
1458         weston_output_schedule_repaint(output);
1459 }
1460
1461 static void
1462 surface_flush_damage(struct weston_surface *surface)
1463 {
1464         if (surface->buffer_ref.buffer &&
1465             wl_shm_buffer_get(surface->buffer_ref.buffer->resource))
1466                 surface->compositor->renderer->flush_damage(surface);
1467
1468         empty_region(&surface->damage);
1469 }
1470
1471 static void
1472 view_accumulate_damage(struct weston_view *view,
1473                        pixman_region32_t *opaque)
1474 {
1475         pixman_region32_t damage;
1476
1477         pixman_region32_init(&damage);
1478         if (view->transform.enabled) {
1479                 pixman_box32_t *extents;
1480
1481                 extents = pixman_region32_extents(&view->surface->damage);
1482                 view_compute_bbox(view, extents->x1, extents->y1,
1483                                   extents->x2 - extents->x1,
1484                                   extents->y2 - extents->y1,
1485                                   &damage);
1486                 pixman_region32_translate(&damage,
1487                                           -view->plane->x,
1488                                           -view->plane->y);
1489         } else {
1490                 pixman_region32_copy(&damage, &view->surface->damage);
1491                 pixman_region32_translate(&damage,
1492                                           view->geometry.x - view->plane->x,
1493                                           view->geometry.y - view->plane->y);
1494         }
1495
1496         pixman_region32_subtract(&damage, &damage, opaque);
1497         pixman_region32_union(&view->plane->damage,
1498                               &view->plane->damage, &damage);
1499         pixman_region32_fini(&damage);
1500         pixman_region32_copy(&view->clip, opaque);
1501         pixman_region32_union(opaque, opaque, &view->transform.opaque);
1502 }
1503
1504 static void
1505 compositor_accumulate_damage(struct weston_compositor *ec)
1506 {
1507         struct weston_plane *plane;
1508         struct weston_view *ev;
1509         pixman_region32_t opaque, clip;
1510
1511         pixman_region32_init(&clip);
1512
1513         wl_list_for_each(plane, &ec->plane_list, link) {
1514                 pixman_region32_copy(&plane->clip, &clip);
1515
1516                 pixman_region32_init(&opaque);
1517
1518                 wl_list_for_each(ev, &ec->view_list, link) {
1519                         if (ev->plane != plane)
1520                                 continue;
1521
1522                         view_accumulate_damage(ev, &opaque);
1523                 }
1524
1525                 pixman_region32_union(&clip, &clip, &opaque);
1526                 pixman_region32_fini(&opaque);
1527         }
1528
1529         pixman_region32_fini(&clip);
1530
1531         wl_list_for_each(ev, &ec->view_list, link)
1532                 ev->surface->touched = 0;
1533
1534         wl_list_for_each(ev, &ec->view_list, link) {
1535                 if (ev->surface->touched)
1536                         continue;
1537                 ev->surface->touched = 1;
1538
1539                 surface_flush_damage(ev->surface);
1540
1541                 /* Both the renderer and the backend have seen the buffer
1542                  * by now. If renderer needs the buffer, it has its own
1543                  * reference set. If the backend wants to keep the buffer
1544                  * around for migrating the surface into a non-primary plane
1545                  * later, keep_buffer is true. Otherwise, drop the core
1546                  * reference now, and allow early buffer release. This enables
1547                  * clients to use single-buffering.
1548                  */
1549                 if (!ev->surface->keep_buffer)
1550                         weston_buffer_reference(&ev->surface->buffer_ref, NULL);
1551         }
1552 }
1553
1554 static void
1555 surface_stash_subsurface_views(struct weston_surface *surface)
1556 {
1557         struct weston_subsurface *sub;
1558
1559         wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
1560                 if (sub->surface == surface)
1561                         continue;
1562
1563                 wl_list_insert_list(&sub->unused_views, &sub->surface->views);
1564                 wl_list_init(&sub->surface->views);
1565
1566                 surface_stash_subsurface_views(sub->surface);
1567         }
1568 }
1569
1570 static void
1571 surface_free_unused_subsurface_views(struct weston_surface *surface)
1572 {
1573         struct weston_subsurface *sub;
1574         struct weston_view *view, *nv;
1575
1576         wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
1577                 if (sub->surface == surface)
1578                         continue;
1579
1580                 wl_list_for_each_safe(view, nv, &sub->unused_views, surface_link)
1581                         weston_view_destroy(view);
1582
1583                 surface_free_unused_subsurface_views(sub->surface);
1584         }
1585 }
1586
1587 static void
1588 view_list_add_subsurface_view(struct weston_compositor *compositor,
1589                               struct weston_subsurface *sub,
1590                               struct weston_view *parent)
1591 {
1592         struct weston_subsurface *child;
1593         struct weston_view *view = NULL, *iv;
1594
1595         wl_list_for_each(iv, &sub->unused_views, surface_link) {
1596                 if (iv->geometry.parent == parent) {
1597                         view = iv;
1598                         break;
1599                 }
1600         }
1601
1602         if (view) {
1603                 /* Put it back in the surface's list of views */
1604                 wl_list_remove(&view->surface_link);
1605                 wl_list_insert(&sub->surface->views, &view->surface_link);
1606         } else {
1607                 view = weston_view_create(sub->surface);
1608                 weston_view_configure(view,
1609                                       sub->position.x,
1610                                       sub->position.y,
1611                                       sub->surface->width,
1612                                       sub->surface->height);
1613                 weston_view_set_transform_parent(view, parent);
1614         }
1615
1616         weston_view_update_transform(view);
1617
1618         if (wl_list_empty(&sub->surface->subsurface_list)) {
1619                 wl_list_insert(compositor->view_list.prev, &view->link);
1620                 return;
1621         }
1622
1623         wl_list_for_each(child, &sub->surface->subsurface_list, parent_link) {
1624                 if (child->surface == sub->surface)
1625                         wl_list_insert(compositor->view_list.prev, &view->link);
1626                 else
1627                         view_list_add_subsurface_view(compositor, child, view);
1628         }
1629 }
1630
1631 static void
1632 view_list_add(struct weston_compositor *compositor,
1633               struct weston_view *view)
1634 {
1635         struct weston_subsurface *sub;
1636
1637         weston_view_update_transform(view);
1638
1639         if (wl_list_empty(&view->surface->subsurface_list)) {
1640                 wl_list_insert(compositor->view_list.prev, &view->link);
1641                 return;
1642         }
1643
1644         wl_list_for_each(sub, &view->surface->subsurface_list, parent_link) {
1645                 if (sub->surface == view->surface)
1646                         wl_list_insert(compositor->view_list.prev, &view->link);
1647                 else
1648                         view_list_add_subsurface_view(compositor, sub, view);
1649         }
1650 }
1651
1652 static void
1653 weston_compositor_build_view_list(struct weston_compositor *compositor)
1654 {
1655         struct weston_view *view;
1656         struct weston_layer *layer;
1657
1658         wl_list_for_each(layer, &compositor->layer_list, link)
1659                 wl_list_for_each(view, &layer->view_list, layer_link)
1660                         surface_stash_subsurface_views(view->surface);
1661
1662         wl_list_init(&compositor->view_list);
1663         wl_list_for_each(layer, &compositor->layer_list, link) {
1664                 wl_list_for_each(view, &layer->view_list, layer_link) {
1665                         view_list_add(compositor, view);
1666                 }
1667         }
1668
1669         wl_list_for_each(layer, &compositor->layer_list, link)
1670                 wl_list_for_each(view, &layer->view_list, layer_link)
1671                         surface_free_unused_subsurface_views(view->surface);
1672 }
1673
1674 static int
1675 weston_output_repaint(struct weston_output *output, uint32_t msecs)
1676 {
1677         struct weston_compositor *ec = output->compositor;
1678         struct weston_view *ev;
1679         struct weston_animation *animation, *next;
1680         struct weston_frame_callback *cb, *cnext;
1681         struct wl_list frame_callback_list;
1682         pixman_region32_t output_damage;
1683         int r;
1684
1685         /* Rebuild the surface list and update surface transforms up front. */
1686         weston_compositor_build_view_list(ec);
1687
1688         if (output->assign_planes && !output->disable_planes)
1689                 output->assign_planes(output);
1690         else
1691                 wl_list_for_each(ev, &ec->view_list, link)
1692                         weston_view_move_to_plane(ev, &ec->primary_plane);
1693
1694         wl_list_init(&frame_callback_list);
1695         wl_list_for_each(ev, &ec->view_list, link) {
1696                 /* Note: This operation is safe to do multiple times on the
1697                  * same surface.
1698                  */
1699                 if (ev->surface->output == output) {
1700                         wl_list_insert_list(&frame_callback_list,
1701                                             &ev->surface->frame_callback_list);
1702                         wl_list_init(&ev->surface->frame_callback_list);
1703                 }
1704         }
1705
1706         compositor_accumulate_damage(ec);
1707
1708         pixman_region32_init(&output_damage);
1709         pixman_region32_intersect(&output_damage,
1710                                   &ec->primary_plane.damage, &output->region);
1711         pixman_region32_subtract(&output_damage,
1712                                  &output_damage, &ec->primary_plane.clip);
1713
1714         if (output->dirty)
1715                 weston_output_update_matrix(output);
1716
1717         r = output->repaint(output, &output_damage);
1718
1719         pixman_region32_fini(&output_damage);
1720
1721         output->repaint_needed = 0;
1722
1723         weston_compositor_repick(ec);
1724         wl_event_loop_dispatch(ec->input_loop, 0);
1725
1726         wl_list_for_each_safe(cb, cnext, &frame_callback_list, link) {
1727                 wl_callback_send_done(cb->resource, msecs);
1728                 wl_resource_destroy(cb->resource);
1729         }
1730
1731         wl_list_for_each_safe(animation, next, &output->animation_list, link) {
1732                 animation->frame_counter++;
1733                 animation->frame(animation, output, msecs);
1734         }
1735
1736         return r;
1737 }
1738
1739 static int
1740 weston_compositor_read_input(int fd, uint32_t mask, void *data)
1741 {
1742         struct weston_compositor *compositor = data;
1743
1744         wl_event_loop_dispatch(compositor->input_loop, 0);
1745
1746         return 1;
1747 }
1748
1749 WL_EXPORT void
1750 weston_output_finish_frame(struct weston_output *output, uint32_t msecs)
1751 {
1752         struct weston_compositor *compositor = output->compositor;
1753         struct wl_event_loop *loop =
1754                 wl_display_get_event_loop(compositor->wl_display);
1755         int fd, r;
1756
1757         output->frame_time = msecs;
1758
1759         if (output->repaint_needed &&
1760             compositor->state != WESTON_COMPOSITOR_SLEEPING &&
1761             compositor->state != WESTON_COMPOSITOR_OFFSCREEN) {
1762                 r = weston_output_repaint(output, msecs);
1763                 if (!r)
1764                         return;
1765         }
1766
1767         output->repaint_scheduled = 0;
1768         if (compositor->input_loop_source)
1769                 return;
1770
1771         fd = wl_event_loop_get_fd(compositor->input_loop);
1772         compositor->input_loop_source =
1773                 wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
1774                                      weston_compositor_read_input, compositor);
1775 }
1776
1777 static void
1778 idle_repaint(void *data)
1779 {
1780         struct weston_output *output = data;
1781
1782         output->start_repaint_loop(output);
1783 }
1784
1785 WL_EXPORT void
1786 weston_layer_init(struct weston_layer *layer, struct wl_list *below)
1787 {
1788         wl_list_init(&layer->view_list);
1789         if (below != NULL)
1790                 wl_list_insert(below, &layer->link);
1791 }
1792
1793 WL_EXPORT void
1794 weston_output_schedule_repaint(struct weston_output *output)
1795 {
1796         struct weston_compositor *compositor = output->compositor;
1797         struct wl_event_loop *loop;
1798
1799         if (compositor->state == WESTON_COMPOSITOR_SLEEPING ||
1800             compositor->state == WESTON_COMPOSITOR_OFFSCREEN)
1801                 return;
1802
1803         loop = wl_display_get_event_loop(compositor->wl_display);
1804         output->repaint_needed = 1;
1805         if (output->repaint_scheduled)
1806                 return;
1807
1808         wl_event_loop_add_idle(loop, idle_repaint, output);
1809         output->repaint_scheduled = 1;
1810
1811         if (compositor->input_loop_source) {
1812                 wl_event_source_remove(compositor->input_loop_source);
1813                 compositor->input_loop_source = NULL;
1814         }
1815 }
1816
1817 WL_EXPORT void
1818 weston_compositor_schedule_repaint(struct weston_compositor *compositor)
1819 {
1820         struct weston_output *output;
1821
1822         wl_list_for_each(output, &compositor->output_list, link)
1823                 weston_output_schedule_repaint(output);
1824 }
1825
1826 static void
1827 surface_destroy(struct wl_client *client, struct wl_resource *resource)
1828 {
1829         wl_resource_destroy(resource);
1830 }
1831
1832 static void
1833 surface_attach(struct wl_client *client,
1834                struct wl_resource *resource,
1835                struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
1836 {
1837         struct weston_surface *surface = wl_resource_get_user_data(resource);
1838         struct weston_buffer *buffer = NULL;
1839
1840         if (buffer_resource) {
1841                 buffer = weston_buffer_from_resource(buffer_resource);
1842                 if (buffer == NULL) {
1843                         wl_client_post_no_memory(client);
1844                         return;
1845                 }
1846         }
1847
1848         /* Attach, attach, without commit in between does not send
1849          * wl_buffer.release. */
1850         if (surface->pending.buffer)
1851                 wl_list_remove(&surface->pending.buffer_destroy_listener.link);
1852
1853         surface->pending.sx = sx;
1854         surface->pending.sy = sy;
1855         surface->pending.buffer = buffer;
1856         surface->pending.newly_attached = 1;
1857         if (buffer) {
1858                 wl_signal_add(&buffer->destroy_signal,
1859                               &surface->pending.buffer_destroy_listener);
1860         }
1861 }
1862
1863 static void
1864 surface_damage(struct wl_client *client,
1865                struct wl_resource *resource,
1866                int32_t x, int32_t y, int32_t width, int32_t height)
1867 {
1868         struct weston_surface *surface = wl_resource_get_user_data(resource);
1869
1870         pixman_region32_union_rect(&surface->pending.damage,
1871                                    &surface->pending.damage,
1872                                    x, y, width, height);
1873 }
1874
1875 static void
1876 destroy_frame_callback(struct wl_resource *resource)
1877 {
1878         struct weston_frame_callback *cb = wl_resource_get_user_data(resource);
1879
1880         wl_list_remove(&cb->link);
1881         free(cb);
1882 }
1883
1884 static void
1885 surface_frame(struct wl_client *client,
1886               struct wl_resource *resource, uint32_t callback)
1887 {
1888         struct weston_frame_callback *cb;
1889         struct weston_surface *surface = wl_resource_get_user_data(resource);
1890
1891         cb = malloc(sizeof *cb);
1892         if (cb == NULL) {
1893                 wl_resource_post_no_memory(resource);
1894                 return;
1895         }
1896
1897         cb->resource = wl_resource_create(client, &wl_callback_interface, 1,
1898                                           callback);
1899         if (cb->resource == NULL) {
1900                 free(cb);
1901                 wl_resource_post_no_memory(resource);
1902                 return;
1903         }
1904
1905         wl_resource_set_implementation(cb->resource, NULL, cb,
1906                                        destroy_frame_callback);
1907
1908         wl_list_insert(surface->pending.frame_callback_list.prev, &cb->link);
1909 }
1910
1911 static void
1912 surface_set_opaque_region(struct wl_client *client,
1913                           struct wl_resource *resource,
1914                           struct wl_resource *region_resource)
1915 {
1916         struct weston_surface *surface = wl_resource_get_user_data(resource);
1917         struct weston_region *region;
1918
1919         if (region_resource) {
1920                 region = wl_resource_get_user_data(region_resource);
1921                 pixman_region32_copy(&surface->pending.opaque,
1922                                      &region->region);
1923         } else {
1924                 empty_region(&surface->pending.opaque);
1925         }
1926 }
1927
1928 static void
1929 surface_set_input_region(struct wl_client *client,
1930                          struct wl_resource *resource,
1931                          struct wl_resource *region_resource)
1932 {
1933         struct weston_surface *surface = wl_resource_get_user_data(resource);
1934         struct weston_region *region;
1935
1936         if (region_resource) {
1937                 region = wl_resource_get_user_data(region_resource);
1938                 pixman_region32_copy(&surface->pending.input,
1939                                      &region->region);
1940         } else {
1941                 pixman_region32_fini(&surface->pending.input);
1942                 region_init_infinite(&surface->pending.input);
1943         }
1944 }
1945
1946 static void
1947 weston_surface_commit_subsurface_order(struct weston_surface *surface)
1948 {
1949         struct weston_subsurface *sub;
1950
1951         wl_list_for_each_reverse(sub, &surface->subsurface_list_pending,
1952                                  parent_link_pending) {
1953                 wl_list_remove(&sub->parent_link);
1954                 wl_list_insert(&surface->subsurface_list, &sub->parent_link);
1955         }
1956 }
1957
1958 static void
1959 weston_surface_commit(struct weston_surface *surface)
1960 {
1961         struct weston_view *view;
1962         pixman_region32_t opaque;
1963
1964         /* wl_surface.set_buffer_transform */
1965         /* wl_surface.set_buffer_scale */
1966         surface->buffer_viewport = surface->pending.buffer_viewport;
1967
1968         /* wl_surface.attach */
1969         if (surface->pending.buffer || surface->pending.newly_attached)
1970                 weston_surface_attach(surface, surface->pending.buffer);
1971
1972         surface->width = 0;
1973         surface->height = 0;
1974         if (surface->buffer_ref.buffer) {
1975                 /* This already includes the buffer scale */
1976                 surface->width = weston_surface_buffer_width(surface);
1977                 surface->height = weston_surface_buffer_height(surface);
1978         }
1979
1980         if (surface->configure && surface->pending.newly_attached)
1981                 surface->configure(surface,
1982                                    surface->pending.sx, surface->pending.sy,
1983                                    surface->width, surface->height);
1984
1985         if (surface->pending.buffer)
1986                 wl_list_remove(&surface->pending.buffer_destroy_listener.link);
1987         surface->pending.buffer = NULL;
1988         surface->pending.sx = 0;
1989         surface->pending.sy = 0;
1990         surface->pending.newly_attached = 0;
1991
1992         /* wl_surface.damage */
1993         pixman_region32_union(&surface->damage, &surface->damage,
1994                               &surface->pending.damage);
1995         pixman_region32_intersect_rect(&surface->damage, &surface->damage,
1996                                        0, 0,
1997                                        surface->width,
1998                                        surface->height);
1999         empty_region(&surface->pending.damage);
2000
2001         /* wl_surface.set_opaque_region */
2002         pixman_region32_init_rect(&opaque, 0, 0,
2003                                   surface->width,
2004                                   surface->height);
2005         pixman_region32_intersect(&opaque,
2006                                   &opaque, &surface->pending.opaque);
2007
2008         if (!pixman_region32_equal(&opaque, &surface->opaque)) {
2009                 pixman_region32_copy(&surface->opaque, &opaque);
2010                 wl_list_for_each(view, &surface->views, surface_link)
2011                         weston_view_geometry_dirty(view);
2012         }
2013
2014         pixman_region32_fini(&opaque);
2015
2016         /* wl_surface.set_input_region */
2017         pixman_region32_fini(&surface->input);
2018         pixman_region32_init_rect(&surface->input, 0, 0,
2019                                   surface->width,
2020                                   surface->height);
2021         pixman_region32_intersect(&surface->input,
2022                                   &surface->input, &surface->pending.input);
2023
2024         /* wl_surface.frame */
2025         wl_list_insert_list(&surface->frame_callback_list,
2026                             &surface->pending.frame_callback_list);
2027         wl_list_init(&surface->pending.frame_callback_list);
2028
2029         weston_surface_commit_subsurface_order(surface);
2030
2031         weston_surface_schedule_repaint(surface);
2032 }
2033
2034 static void
2035 weston_subsurface_commit(struct weston_subsurface *sub);
2036
2037 static void
2038 weston_subsurface_parent_commit(struct weston_subsurface *sub,
2039                                 int parent_is_synchronized);
2040
2041 static void
2042 surface_commit(struct wl_client *client, struct wl_resource *resource)
2043 {
2044         struct weston_surface *surface = wl_resource_get_user_data(resource);
2045         struct weston_subsurface *sub = weston_surface_to_subsurface(surface);
2046
2047         if (sub) {
2048                 weston_subsurface_commit(sub);
2049                 return;
2050         }
2051
2052         weston_surface_commit(surface);
2053
2054         wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
2055                 if (sub->surface != surface)
2056                         weston_subsurface_parent_commit(sub, 0);
2057         }
2058 }
2059
2060 static void
2061 surface_set_buffer_transform(struct wl_client *client,
2062                              struct wl_resource *resource, int transform)
2063 {
2064         struct weston_surface *surface = wl_resource_get_user_data(resource);
2065
2066         surface->pending.buffer_viewport.transform = transform;
2067 }
2068
2069 static void
2070 surface_set_buffer_scale(struct wl_client *client,
2071                          struct wl_resource *resource,
2072                          int32_t scale)
2073 {
2074         struct weston_surface *surface = wl_resource_get_user_data(resource);
2075
2076         surface->pending.buffer_viewport.scale = scale;
2077 }
2078
2079 static const struct wl_surface_interface surface_interface = {
2080         surface_destroy,
2081         surface_attach,
2082         surface_damage,
2083         surface_frame,
2084         surface_set_opaque_region,
2085         surface_set_input_region,
2086         surface_commit,
2087         surface_set_buffer_transform,
2088         surface_set_buffer_scale
2089 };
2090
2091 static void
2092 compositor_create_surface(struct wl_client *client,
2093                           struct wl_resource *resource, uint32_t id)
2094 {
2095         struct weston_compositor *ec = wl_resource_get_user_data(resource);
2096         struct weston_surface *surface;
2097
2098         surface = weston_surface_create(ec);
2099         if (surface == NULL) {
2100                 wl_resource_post_no_memory(resource);
2101                 return;
2102         }
2103
2104         surface->resource =
2105                 wl_resource_create(client, &wl_surface_interface,
2106                                    wl_resource_get_version(resource), id);
2107         if (surface->resource == NULL) {
2108                 weston_surface_destroy(surface);
2109                 wl_resource_post_no_memory(resource);
2110                 return;
2111         }
2112         wl_resource_set_implementation(surface->resource, &surface_interface,
2113                                        surface, destroy_surface);
2114 }
2115
2116 static void
2117 destroy_region(struct wl_resource *resource)
2118 {
2119         struct weston_region *region = wl_resource_get_user_data(resource);
2120
2121         pixman_region32_fini(&region->region);
2122         free(region);
2123 }
2124
2125 static void
2126 region_destroy(struct wl_client *client, struct wl_resource *resource)
2127 {
2128         wl_resource_destroy(resource);
2129 }
2130
2131 static void
2132 region_add(struct wl_client *client, struct wl_resource *resource,
2133            int32_t x, int32_t y, int32_t width, int32_t height)
2134 {
2135         struct weston_region *region = wl_resource_get_user_data(resource);
2136
2137         pixman_region32_union_rect(&region->region, &region->region,
2138                                    x, y, width, height);
2139 }
2140
2141 static void
2142 region_subtract(struct wl_client *client, struct wl_resource *resource,
2143                 int32_t x, int32_t y, int32_t width, int32_t height)
2144 {
2145         struct weston_region *region = wl_resource_get_user_data(resource);
2146         pixman_region32_t rect;
2147
2148         pixman_region32_init_rect(&rect, x, y, width, height);
2149         pixman_region32_subtract(&region->region, &region->region, &rect);
2150         pixman_region32_fini(&rect);
2151 }
2152
2153 static const struct wl_region_interface region_interface = {
2154         region_destroy,
2155         region_add,
2156         region_subtract
2157 };
2158
2159 static void
2160 compositor_create_region(struct wl_client *client,
2161                          struct wl_resource *resource, uint32_t id)
2162 {
2163         struct weston_region *region;
2164
2165         region = malloc(sizeof *region);
2166         if (region == NULL) {
2167                 wl_resource_post_no_memory(resource);
2168                 return;
2169         }
2170
2171         pixman_region32_init(&region->region);
2172
2173         region->resource =
2174                 wl_resource_create(client, &wl_region_interface, 1, id);
2175         if (region->resource == NULL) {
2176                 free(region);
2177                 wl_resource_post_no_memory(resource);
2178                 return;
2179         }
2180         wl_resource_set_implementation(region->resource, &region_interface,
2181                                        region, destroy_region);
2182 }
2183
2184 static const struct wl_compositor_interface compositor_interface = {
2185         compositor_create_surface,
2186         compositor_create_region
2187 };
2188
2189 static void
2190 weston_subsurface_commit_from_cache(struct weston_subsurface *sub)
2191 {
2192         struct weston_surface *surface = sub->surface;
2193         struct weston_view *view;
2194         pixman_region32_t opaque;
2195
2196         /* wl_surface.set_buffer_transform */
2197         /* wl_surface.set_buffer_scale */
2198         surface->buffer_viewport = sub->cached.buffer_viewport;
2199
2200         /* wl_surface.attach */
2201         if (sub->cached.buffer_ref.buffer || sub->cached.newly_attached)
2202                 weston_surface_attach(surface, sub->cached.buffer_ref.buffer);
2203         weston_buffer_reference(&sub->cached.buffer_ref, NULL);
2204
2205         surface->width = 0;
2206         surface->height = 0;
2207         if (surface->buffer_ref.buffer) {
2208                 surface->width = weston_surface_buffer_width(surface);
2209                 surface->height = weston_surface_buffer_height(surface);
2210         }
2211
2212         if (surface->configure && sub->cached.newly_attached)
2213                 surface->configure(surface, sub->cached.sx, sub->cached.sy,
2214                                    surface->width, surface->height);
2215         sub->cached.sx = 0;
2216         sub->cached.sy = 0;
2217         sub->cached.newly_attached = 0;
2218
2219         /* wl_surface.damage */
2220         pixman_region32_union(&surface->damage, &surface->damage,
2221                               &sub->cached.damage);
2222         pixman_region32_intersect_rect(&surface->damage, &surface->damage,
2223                                        0, 0,
2224                                        surface->width,
2225                                        surface->height);
2226         empty_region(&sub->cached.damage);
2227
2228         /* wl_surface.set_opaque_region */
2229         pixman_region32_init_rect(&opaque, 0, 0,
2230                                   surface->width,
2231                                   surface->height);
2232         pixman_region32_intersect(&opaque,
2233                                   &opaque, &sub->cached.opaque);
2234
2235         if (!pixman_region32_equal(&opaque, &surface->opaque)) {
2236                 pixman_region32_copy(&surface->opaque, &opaque);
2237                 wl_list_for_each(view, &surface->views, surface_link)
2238                         weston_view_geometry_dirty(view);
2239         }
2240
2241         pixman_region32_fini(&opaque);
2242
2243         /* wl_surface.set_input_region */
2244         pixman_region32_fini(&surface->input);
2245         pixman_region32_init_rect(&surface->input, 0, 0,
2246                                   surface->width,
2247                                   surface->height);
2248         pixman_region32_intersect(&surface->input,
2249                                   &surface->input, &sub->cached.input);
2250
2251         /* wl_surface.frame */
2252         wl_list_insert_list(&surface->frame_callback_list,
2253                             &sub->cached.frame_callback_list);
2254         wl_list_init(&sub->cached.frame_callback_list);
2255
2256         weston_surface_commit_subsurface_order(surface);
2257
2258         weston_surface_schedule_repaint(surface);
2259
2260         sub->cached.has_data = 0;
2261 }
2262
2263 static void
2264 weston_subsurface_commit_to_cache(struct weston_subsurface *sub)
2265 {
2266         struct weston_surface *surface = sub->surface;
2267
2268         /*
2269          * If this commit would cause the surface to move by the
2270          * attach(dx, dy) parameters, the old damage region must be
2271          * translated to correspond to the new surface coordinate system
2272          * original_mode.
2273          */
2274         pixman_region32_translate(&sub->cached.damage,
2275                                   -surface->pending.sx, -surface->pending.sy);
2276         pixman_region32_union(&sub->cached.damage, &sub->cached.damage,
2277                               &surface->pending.damage);
2278         empty_region(&surface->pending.damage);
2279
2280         if (surface->pending.newly_attached) {
2281                 sub->cached.newly_attached = 1;
2282                 weston_buffer_reference(&sub->cached.buffer_ref,
2283                                         surface->pending.buffer);
2284         }
2285         sub->cached.sx += surface->pending.sx;
2286         sub->cached.sy += surface->pending.sy;
2287         surface->pending.sx = 0;
2288         surface->pending.sy = 0;
2289         surface->pending.newly_attached = 0;
2290
2291         sub->cached.buffer_viewport = surface->pending.buffer_viewport;
2292
2293         pixman_region32_copy(&sub->cached.opaque, &surface->pending.opaque);
2294
2295         pixman_region32_copy(&sub->cached.input, &surface->pending.input);
2296
2297         wl_list_insert_list(&sub->cached.frame_callback_list,
2298                             &surface->pending.frame_callback_list);
2299         wl_list_init(&surface->pending.frame_callback_list);
2300
2301         sub->cached.has_data = 1;
2302 }
2303
2304 static int
2305 weston_subsurface_is_synchronized(struct weston_subsurface *sub)
2306 {
2307         while (sub) {
2308                 if (sub->synchronized)
2309                         return 1;
2310
2311                 if (!sub->parent)
2312                         return 0;
2313
2314                 sub = weston_surface_to_subsurface(sub->parent);
2315         }
2316
2317         return 0;
2318 }
2319
2320 static void
2321 weston_subsurface_commit(struct weston_subsurface *sub)
2322 {
2323         struct weston_surface *surface = sub->surface;
2324         struct weston_subsurface *tmp;
2325
2326         /* Recursive check for effectively synchronized. */
2327         if (weston_subsurface_is_synchronized(sub)) {
2328                 weston_subsurface_commit_to_cache(sub);
2329         } else {
2330                 if (sub->cached.has_data) {
2331                         /* flush accumulated state from cache */
2332                         weston_subsurface_commit_to_cache(sub);
2333                         weston_subsurface_commit_from_cache(sub);
2334                 } else {
2335                         weston_surface_commit(surface);
2336                 }
2337
2338                 wl_list_for_each(tmp, &surface->subsurface_list, parent_link) {
2339                         if (tmp->surface != surface)
2340                                 weston_subsurface_parent_commit(tmp, 0);
2341                 }
2342         }
2343 }
2344
2345 static void
2346 weston_subsurface_synchronized_commit(struct weston_subsurface *sub)
2347 {
2348         struct weston_surface *surface = sub->surface;
2349         struct weston_subsurface *tmp;
2350
2351         /* From now on, commit_from_cache the whole sub-tree, regardless of
2352          * the synchronized mode of each child. This sub-surface or some
2353          * of its ancestors were synchronized, so we are synchronized
2354          * all the way down.
2355          */
2356
2357         if (sub->cached.has_data)
2358                 weston_subsurface_commit_from_cache(sub);
2359
2360         wl_list_for_each(tmp, &surface->subsurface_list, parent_link) {
2361                 if (tmp->surface != surface)
2362                         weston_subsurface_parent_commit(tmp, 1);
2363         }
2364 }
2365
2366 static void
2367 weston_subsurface_parent_commit(struct weston_subsurface *sub,
2368                                 int parent_is_synchronized)
2369 {
2370         struct weston_view *view;
2371         if (sub->position.set) {
2372                 wl_list_for_each(view, &sub->surface->views, surface_link)
2373                         weston_view_set_position(view,
2374                                                  sub->position.x,
2375                                                  sub->position.y);
2376
2377                 sub->position.set = 0;
2378         }
2379
2380         if (parent_is_synchronized || sub->synchronized)
2381                 weston_subsurface_synchronized_commit(sub);
2382 }
2383
2384 static void
2385 subsurface_configure(struct weston_surface *surface, int32_t dx, int32_t dy,
2386                      int32_t width, int32_t height)
2387 {
2388         struct weston_compositor *compositor = surface->compositor;
2389         struct weston_view *view;
2390
2391         wl_list_for_each(view, &surface->views, surface_link)
2392                 weston_view_configure(view,
2393                                       view->geometry.x + dx,
2394                                       view->geometry.y + dy,
2395                                       width, height);
2396
2397         /* No need to check parent mappedness, because if parent is not
2398          * mapped, parent is not in a visible layer, so this sub-surface
2399          * will not be drawn either.
2400          */
2401         if (!weston_surface_is_mapped(surface)) {
2402                 /* Cannot call weston_surface_update_transform(),
2403                  * because that would call it also for the parent surface,
2404                  * which might not be mapped yet. That would lead to
2405                  * inconsistent state, where the window could never be
2406                  * mapped.
2407                  *
2408                  * Instead just assing any output, to make
2409                  * weston_surface_is_mapped() return true, so that when the
2410                  * parent surface does get mapped, this one will get
2411                  * included, too. See surface_list_add().
2412                  */
2413                 assert(!wl_list_empty(&compositor->output_list));
2414                 surface->output = container_of(compositor->output_list.next,
2415                                                struct weston_output, link);
2416         }
2417 }
2418
2419 static struct weston_subsurface *
2420 weston_surface_to_subsurface(struct weston_surface *surface)
2421 {
2422         if (surface->configure == subsurface_configure)
2423                 return surface->configure_private;
2424
2425         return NULL;
2426 }
2427
2428 WL_EXPORT struct weston_surface *
2429 weston_surface_get_main_surface(struct weston_surface *surface)
2430 {
2431         struct weston_subsurface *sub;
2432
2433         while (surface && (sub = weston_surface_to_subsurface(surface)))
2434                 surface = sub->parent;
2435
2436         return surface;
2437 }
2438
2439 static void
2440 subsurface_set_position(struct wl_client *client,
2441                         struct wl_resource *resource, int32_t x, int32_t y)
2442 {
2443         struct weston_subsurface *sub = wl_resource_get_user_data(resource);
2444
2445         if (!sub)
2446                 return;
2447
2448         sub->position.x = x;
2449         sub->position.y = y;
2450         sub->position.set = 1;
2451 }
2452
2453 static struct weston_subsurface *
2454 subsurface_from_surface(struct weston_surface *surface)
2455 {
2456         struct weston_subsurface *sub;
2457
2458         sub = weston_surface_to_subsurface(surface);
2459         if (sub)
2460                 return sub;
2461
2462         wl_list_for_each(sub, &surface->subsurface_list, parent_link)
2463                 if (sub->surface == surface)
2464                         return sub;
2465
2466         return NULL;
2467 }
2468
2469 static struct weston_subsurface *
2470 subsurface_sibling_check(struct weston_subsurface *sub,
2471                          struct weston_surface *surface,
2472                          const char *request)
2473 {
2474         struct weston_subsurface *sibling;
2475
2476         sibling = subsurface_from_surface(surface);
2477
2478         if (!sibling) {
2479                 wl_resource_post_error(sub->resource,
2480                         WL_SUBSURFACE_ERROR_BAD_SURFACE,
2481                         "%s: wl_surface@%d is not a parent or sibling",
2482                         request, wl_resource_get_id(surface->resource));
2483                 return NULL;
2484         }
2485
2486         if (sibling->parent != sub->parent) {
2487                 wl_resource_post_error(sub->resource,
2488                         WL_SUBSURFACE_ERROR_BAD_SURFACE,
2489                         "%s: wl_surface@%d has a different parent",
2490                         request, wl_resource_get_id(surface->resource));
2491                 return NULL;
2492         }
2493
2494         return sibling;
2495 }
2496
2497 static void
2498 subsurface_place_above(struct wl_client *client,
2499                        struct wl_resource *resource,
2500                        struct wl_resource *sibling_resource)
2501 {
2502         struct weston_subsurface *sub = wl_resource_get_user_data(resource);
2503         struct weston_surface *surface =
2504                 wl_resource_get_user_data(sibling_resource);
2505         struct weston_subsurface *sibling;
2506
2507         if (!sub)
2508                 return;
2509
2510         sibling = subsurface_sibling_check(sub, surface, "place_above");
2511         if (!sibling)
2512                 return;
2513
2514         wl_list_remove(&sub->parent_link_pending);
2515         wl_list_insert(sibling->parent_link_pending.prev,
2516                        &sub->parent_link_pending);
2517 }
2518
2519 static void
2520 subsurface_place_below(struct wl_client *client,
2521                        struct wl_resource *resource,
2522                        struct wl_resource *sibling_resource)
2523 {
2524         struct weston_subsurface *sub = wl_resource_get_user_data(resource);
2525         struct weston_surface *surface =
2526                 wl_resource_get_user_data(sibling_resource);
2527         struct weston_subsurface *sibling;
2528
2529         if (!sub)
2530                 return;
2531
2532         sibling = subsurface_sibling_check(sub, surface, "place_below");
2533         if (!sibling)
2534                 return;
2535
2536         wl_list_remove(&sub->parent_link_pending);
2537         wl_list_insert(&sibling->parent_link_pending,
2538                        &sub->parent_link_pending);
2539 }
2540
2541 static void
2542 subsurface_set_sync(struct wl_client *client, struct wl_resource *resource)
2543 {
2544         struct weston_subsurface *sub = wl_resource_get_user_data(resource);
2545
2546         if (sub)
2547                 sub->synchronized = 1;
2548 }
2549
2550 static void
2551 subsurface_set_desync(struct wl_client *client, struct wl_resource *resource)
2552 {
2553         struct weston_subsurface *sub = wl_resource_get_user_data(resource);
2554
2555         if (sub && sub->synchronized) {
2556                 sub->synchronized = 0;
2557
2558                 /* If sub became effectively desynchronized, flush. */
2559                 if (!weston_subsurface_is_synchronized(sub))
2560                         weston_subsurface_synchronized_commit(sub);
2561         }
2562 }
2563
2564 static void
2565 weston_subsurface_cache_init(struct weston_subsurface *sub)
2566 {
2567         pixman_region32_init(&sub->cached.damage);
2568         pixman_region32_init(&sub->cached.opaque);
2569         pixman_region32_init(&sub->cached.input);
2570         wl_list_init(&sub->cached.frame_callback_list);
2571         sub->cached.buffer_ref.buffer = NULL;
2572 }
2573
2574 static void
2575 weston_subsurface_cache_fini(struct weston_subsurface *sub)
2576 {
2577         struct weston_frame_callback *cb, *tmp;
2578
2579         wl_list_for_each_safe(cb, tmp, &sub->cached.frame_callback_list, link)
2580                 wl_resource_destroy(cb->resource);
2581
2582         weston_buffer_reference(&sub->cached.buffer_ref, NULL);
2583         pixman_region32_fini(&sub->cached.damage);
2584         pixman_region32_fini(&sub->cached.opaque);
2585         pixman_region32_fini(&sub->cached.input);
2586 }
2587
2588 static void
2589 weston_subsurface_unlink_parent(struct weston_subsurface *sub)
2590 {
2591         wl_list_remove(&sub->parent_link);
2592         wl_list_remove(&sub->parent_link_pending);
2593         wl_list_remove(&sub->parent_destroy_listener.link);
2594         sub->parent = NULL;
2595 }
2596
2597 static void
2598 weston_subsurface_destroy(struct weston_subsurface *sub);
2599
2600 static void
2601 subsurface_handle_surface_destroy(struct wl_listener *listener, void *data)
2602 {
2603         struct weston_subsurface *sub =
2604                 container_of(listener, struct weston_subsurface,
2605                              surface_destroy_listener);
2606         assert(data == &sub->surface->resource);
2607
2608         /* The protocol object (wl_resource) is left inert. */
2609         if (sub->resource)
2610                 wl_resource_set_user_data(sub->resource, NULL);
2611
2612         weston_subsurface_destroy(sub);
2613 }
2614
2615 static void
2616 subsurface_handle_parent_destroy(struct wl_listener *listener, void *data)
2617 {
2618         struct weston_subsurface *sub =
2619                 container_of(listener, struct weston_subsurface,
2620                              parent_destroy_listener);
2621         assert(data == &sub->parent->resource);
2622         assert(sub->surface != sub->parent);
2623
2624         if (weston_surface_is_mapped(sub->surface))
2625                 weston_surface_unmap(sub->surface);
2626
2627         weston_subsurface_unlink_parent(sub);
2628 }
2629
2630 static void
2631 subsurface_resource_destroy(struct wl_resource *resource)
2632 {
2633         struct weston_subsurface *sub = wl_resource_get_user_data(resource);
2634
2635         if (sub)
2636                 weston_subsurface_destroy(sub);
2637 }
2638
2639 static void
2640 subsurface_destroy(struct wl_client *client, struct wl_resource *resource)
2641 {
2642         wl_resource_destroy(resource);
2643 }
2644
2645 static void
2646 weston_subsurface_link_parent(struct weston_subsurface *sub,
2647                               struct weston_surface *parent)
2648 {
2649         sub->parent = parent;
2650         sub->parent_destroy_listener.notify = subsurface_handle_parent_destroy;
2651         wl_signal_add(&parent->destroy_signal,
2652                       &sub->parent_destroy_listener);
2653
2654         wl_list_insert(&parent->subsurface_list, &sub->parent_link);
2655         wl_list_insert(&parent->subsurface_list_pending,
2656                        &sub->parent_link_pending);
2657 }
2658
2659 static void
2660 weston_subsurface_link_surface(struct weston_subsurface *sub,
2661                                struct weston_surface *surface)
2662 {
2663         sub->surface = surface;
2664         sub->surface_destroy_listener.notify =
2665                 subsurface_handle_surface_destroy;
2666         wl_signal_add(&surface->destroy_signal,
2667                       &sub->surface_destroy_listener);
2668 }
2669
2670 static void
2671 weston_subsurface_destroy(struct weston_subsurface *sub)
2672 {
2673         struct weston_view *view, *next;
2674
2675         assert(sub->surface);
2676
2677         if (sub->resource) {
2678                 assert(weston_surface_to_subsurface(sub->surface) == sub);
2679                 assert(sub->parent_destroy_listener.notify ==
2680                        subsurface_handle_parent_destroy);
2681
2682                 wl_list_for_each_safe(view, next, &sub->surface->views, surface_link)
2683                         weston_view_destroy(view);
2684
2685                 if (sub->parent)
2686                         weston_subsurface_unlink_parent(sub);
2687
2688                 weston_subsurface_cache_fini(sub);
2689
2690                 sub->surface->configure = NULL;
2691                 sub->surface->configure_private = NULL;
2692         } else {
2693                 /* the dummy weston_subsurface for the parent itself */
2694                 assert(sub->parent_destroy_listener.notify == NULL);
2695                 wl_list_remove(&sub->parent_link);
2696                 wl_list_remove(&sub->parent_link_pending);
2697         }
2698
2699         wl_list_remove(&sub->surface_destroy_listener.link);
2700         free(sub);
2701 }
2702
2703 static const struct wl_subsurface_interface subsurface_implementation = {
2704         subsurface_destroy,
2705         subsurface_set_position,
2706         subsurface_place_above,
2707         subsurface_place_below,
2708         subsurface_set_sync,
2709         subsurface_set_desync
2710 };
2711
2712 static struct weston_subsurface *
2713 weston_subsurface_create(uint32_t id, struct weston_surface *surface,
2714                          struct weston_surface *parent)
2715 {
2716         struct weston_subsurface *sub;
2717         struct wl_client *client = wl_resource_get_client(surface->resource);
2718
2719         sub = calloc(1, sizeof *sub);
2720         if (!sub)
2721                 return NULL;
2722
2723         wl_list_init(&sub->unused_views);
2724
2725         sub->resource =
2726                 wl_resource_create(client, &wl_subsurface_interface, 1, id);
2727         if (!sub->resource) {
2728                 free(sub);
2729                 return NULL;
2730         }
2731
2732         wl_resource_set_implementation(sub->resource,
2733                                        &subsurface_implementation,
2734                                        sub, subsurface_resource_destroy);
2735         weston_subsurface_link_surface(sub, surface);
2736         weston_subsurface_link_parent(sub, parent);
2737         weston_subsurface_cache_init(sub);
2738         sub->synchronized = 1;
2739
2740         return sub;
2741 }
2742
2743 /* Create a dummy subsurface for having the parent itself in its
2744  * sub-surface lists. Makes stacking order manipulation easy.
2745  */
2746 static struct weston_subsurface *
2747 weston_subsurface_create_for_parent(struct weston_surface *parent)
2748 {
2749         struct weston_subsurface *sub;
2750
2751         sub = calloc(1, sizeof *sub);
2752         if (!sub)
2753                 return NULL;
2754
2755         weston_subsurface_link_surface(sub, parent);
2756         sub->parent = parent;
2757         wl_list_insert(&parent->subsurface_list, &sub->parent_link);
2758         wl_list_insert(&parent->subsurface_list_pending,
2759                        &sub->parent_link_pending);
2760
2761         return sub;
2762 }
2763
2764 static void
2765 subcompositor_get_subsurface(struct wl_client *client,
2766                              struct wl_resource *resource,
2767                              uint32_t id,
2768                              struct wl_resource *surface_resource,
2769                              struct wl_resource *parent_resource)
2770 {
2771         struct weston_surface *surface =
2772                 wl_resource_get_user_data(surface_resource);
2773         struct weston_surface *parent =
2774                 wl_resource_get_user_data(parent_resource);
2775         struct weston_subsurface *sub;
2776         static const char where[] = "get_subsurface: wl_subsurface@";
2777
2778         if (surface == parent) {
2779                 wl_resource_post_error(resource,
2780                         WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
2781                         "%s%d: wl_surface@%d cannot be its own parent",
2782                         where, id, wl_resource_get_id(surface_resource));
2783                 return;
2784         }
2785
2786         if (weston_surface_to_subsurface(surface)) {
2787                 wl_resource_post_error(resource,
2788                         WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
2789                         "%s%d: wl_surface@%d is already a sub-surface",
2790                         where, id, wl_resource_get_id(surface_resource));
2791                 return;
2792         }
2793
2794         if (surface->configure) {
2795                 wl_resource_post_error(resource,
2796                         WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
2797                         "%s%d: wl_surface@%d already has a role",
2798                         where, id, wl_resource_get_id(surface_resource));
2799                 return;
2800         }
2801
2802         if (weston_surface_get_main_surface(parent) == surface) {
2803                 wl_resource_post_error(resource,
2804                         WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
2805                         "%s%d: wl_surface@%d is an ancestor of parent",
2806                         where, id, wl_resource_get_id(surface_resource));
2807                 return;
2808         }
2809
2810         /* make sure the parent is in its own list */
2811         if (wl_list_empty(&parent->subsurface_list)) {
2812                 if (!weston_subsurface_create_for_parent(parent)) {
2813                         wl_resource_post_no_memory(resource);
2814                         return;
2815                 }
2816         }
2817
2818         sub = weston_subsurface_create(id, surface, parent);
2819         if (!sub) {
2820                 wl_resource_post_no_memory(resource);
2821                 return;
2822         }
2823
2824         surface->configure = subsurface_configure;
2825         surface->configure_private = sub;
2826 }
2827
2828 static void
2829 subcompositor_destroy(struct wl_client *client, struct wl_resource *resource)
2830 {
2831         wl_resource_destroy(resource);
2832 }
2833
2834 static const struct wl_subcompositor_interface subcompositor_interface = {
2835         subcompositor_destroy,
2836         subcompositor_get_subsurface
2837 };
2838
2839 static void
2840 bind_subcompositor(struct wl_client *client,
2841                    void *data, uint32_t version, uint32_t id)
2842 {
2843         struct weston_compositor *compositor = data;
2844         struct wl_resource *resource;
2845
2846         resource =
2847                 wl_resource_create(client, &wl_subcompositor_interface, 1, id);
2848         if (resource == NULL) {
2849                 wl_client_post_no_memory(client);
2850                 return;
2851         }
2852         wl_resource_set_implementation(resource, &subcompositor_interface,
2853                                        compositor, NULL);
2854 }
2855
2856 static void
2857 weston_compositor_dpms(struct weston_compositor *compositor,
2858                        enum dpms_enum state)
2859 {
2860         struct weston_output *output;
2861
2862         wl_list_for_each(output, &compositor->output_list, link)
2863                 if (output->set_dpms)
2864                         output->set_dpms(output, state);
2865 }
2866
2867 WL_EXPORT void
2868 weston_compositor_wake(struct weston_compositor *compositor)
2869 {
2870         uint32_t old_state = compositor->state;
2871
2872         /* The state needs to be changed before emitting the wake
2873          * signal because that may try to schedule a repaint which
2874          * will not work if the compositor is still sleeping */
2875         compositor->state = WESTON_COMPOSITOR_ACTIVE;
2876
2877         switch (old_state) {
2878         case WESTON_COMPOSITOR_SLEEPING:
2879                 weston_compositor_dpms(compositor, WESTON_DPMS_ON);
2880                 /* fall through */
2881         case WESTON_COMPOSITOR_IDLE:
2882         case WESTON_COMPOSITOR_OFFSCREEN:
2883                 wl_signal_emit(&compositor->wake_signal, compositor);
2884                 /* fall through */
2885         default:
2886                 wl_event_source_timer_update(compositor->idle_source,
2887                                              compositor->idle_time * 1000);
2888         }
2889 }
2890
2891 WL_EXPORT void
2892 weston_compositor_offscreen(struct weston_compositor *compositor)
2893 {
2894         switch (compositor->state) {
2895         case WESTON_COMPOSITOR_OFFSCREEN:
2896                 return;
2897         case WESTON_COMPOSITOR_SLEEPING:
2898                 weston_compositor_dpms(compositor, WESTON_DPMS_ON);
2899                 /* fall through */
2900         default:
2901                 compositor->state = WESTON_COMPOSITOR_OFFSCREEN;
2902                 wl_event_source_timer_update(compositor->idle_source, 0);
2903         }
2904 }
2905
2906 WL_EXPORT void
2907 weston_compositor_sleep(struct weston_compositor *compositor)
2908 {
2909         if (compositor->state == WESTON_COMPOSITOR_SLEEPING)
2910                 return;
2911
2912         wl_event_source_timer_update(compositor->idle_source, 0);
2913         compositor->state = WESTON_COMPOSITOR_SLEEPING;
2914         weston_compositor_dpms(compositor, WESTON_DPMS_OFF);
2915 }
2916
2917 static int
2918 idle_handler(void *data)
2919 {
2920         struct weston_compositor *compositor = data;
2921
2922         if (compositor->idle_inhibit)
2923                 return 1;
2924
2925         compositor->state = WESTON_COMPOSITOR_IDLE;
2926         wl_signal_emit(&compositor->idle_signal, compositor);
2927
2928         return 1;
2929 }
2930
2931 WL_EXPORT void
2932 weston_plane_init(struct weston_plane *plane,
2933                         struct weston_compositor *ec,
2934                         int32_t x, int32_t y)
2935 {
2936         pixman_region32_init(&plane->damage);
2937         pixman_region32_init(&plane->clip);
2938         plane->x = x;
2939         plane->y = y;
2940         plane->compositor = ec;
2941
2942         /* Init the link so that the call to wl_list_remove() when releasing
2943          * the plane without ever stacking doesn't lead to a crash */
2944         wl_list_init(&plane->link);
2945 }
2946
2947 WL_EXPORT void
2948 weston_plane_release(struct weston_plane *plane)
2949 {
2950         struct weston_view *view;
2951
2952         pixman_region32_fini(&plane->damage);
2953         pixman_region32_fini(&plane->clip);
2954
2955         wl_list_for_each(view, &plane->compositor->view_list, link) {
2956                 if (view->plane == plane)
2957                         view->plane = NULL;
2958         }
2959
2960         wl_list_remove(&plane->link);
2961 }
2962
2963 WL_EXPORT void
2964 weston_compositor_stack_plane(struct weston_compositor *ec,
2965                               struct weston_plane *plane,
2966                               struct weston_plane *above)
2967 {
2968         if (above)
2969                 wl_list_insert(above->link.prev, &plane->link);
2970         else
2971                 wl_list_insert(&ec->plane_list, &plane->link);
2972 }
2973
2974 static void unbind_resource(struct wl_resource *resource)
2975 {
2976         wl_list_remove(wl_resource_get_link(resource));
2977 }
2978
2979 static void
2980 bind_output(struct wl_client *client,
2981             void *data, uint32_t version, uint32_t id)
2982 {
2983         struct weston_output *output = data;
2984         struct weston_mode *mode;
2985         struct wl_resource *resource;
2986
2987         resource = wl_resource_create(client, &wl_output_interface,
2988                                       MIN(version, 2), id);
2989         if (resource == NULL) {
2990                 wl_client_post_no_memory(client);
2991                 return;
2992         }
2993
2994         wl_list_insert(&output->resource_list, wl_resource_get_link(resource));
2995         wl_resource_set_implementation(resource, NULL, data, unbind_resource);
2996
2997         wl_output_send_geometry(resource,
2998                                 output->x,
2999                                 output->y,
3000                                 output->mm_width,
3001                                 output->mm_height,
3002                                 output->subpixel,
3003                                 output->make, output->model,
3004                                 output->transform);
3005         if (version >= 2)
3006                 wl_output_send_scale(resource,
3007                                      output->current_scale);
3008
3009         wl_list_for_each (mode, &output->mode_list, link) {
3010                 wl_output_send_mode(resource,
3011                                     mode->flags,
3012                                     mode->width,
3013                                     mode->height,
3014                                     mode->refresh);
3015         }
3016
3017         if (version >= 2)
3018                 wl_output_send_done(resource);
3019 }
3020
3021 WL_EXPORT void
3022 weston_output_destroy(struct weston_output *output)
3023 {
3024         wl_signal_emit(&output->destroy_signal, output);
3025
3026         free(output->name);
3027         pixman_region32_fini(&output->region);
3028         pixman_region32_fini(&output->previous_damage);
3029         output->compositor->output_id_pool &= ~(1 << output->id);
3030
3031         wl_global_destroy(output->global);
3032 }
3033
3034 static void
3035 weston_output_compute_transform(struct weston_output *output)
3036 {
3037         struct weston_matrix transform;
3038         int flip;
3039
3040         weston_matrix_init(&transform);
3041         transform.type = WESTON_MATRIX_TRANSFORM_ROTATE;
3042
3043         switch(output->transform) {
3044         case WL_OUTPUT_TRANSFORM_FLIPPED:
3045         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
3046         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
3047         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
3048                 transform.type |= WESTON_MATRIX_TRANSFORM_OTHER;
3049                 flip = -1;
3050                 break;
3051         default:
3052                 flip = 1;
3053                 break;
3054         }
3055
3056         switch(output->transform) {
3057         case WL_OUTPUT_TRANSFORM_NORMAL:
3058         case WL_OUTPUT_TRANSFORM_FLIPPED:
3059                 transform.d[0] = flip;
3060                 transform.d[1] = 0;
3061                 transform.d[4] = 0;
3062                 transform.d[5] = 1;
3063                 break;
3064         case WL_OUTPUT_TRANSFORM_90:
3065         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
3066                 transform.d[0] = 0;
3067                 transform.d[1] = -flip;
3068                 transform.d[4] = 1;
3069                 transform.d[5] = 0;
3070                 break;
3071         case WL_OUTPUT_TRANSFORM_180:
3072         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
3073                 transform.d[0] = -flip;
3074                 transform.d[1] = 0;
3075                 transform.d[4] = 0;
3076                 transform.d[5] = -1;
3077                 break;
3078         case WL_OUTPUT_TRANSFORM_270:
3079         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
3080                 transform.d[0] = 0;
3081                 transform.d[1] = flip;
3082                 transform.d[4] = -1;
3083                 transform.d[5] = 0;
3084                 break;
3085         default:
3086                 break;
3087         }
3088
3089         weston_matrix_multiply(&output->matrix, &transform);
3090 }
3091
3092 WL_EXPORT void
3093 weston_output_update_matrix(struct weston_output *output)
3094 {
3095         float magnification;
3096         struct weston_matrix camera;
3097         struct weston_matrix modelview;
3098
3099         weston_matrix_init(&output->matrix);
3100         weston_matrix_translate(&output->matrix,
3101                                 -(output->x + output->width / 2.0),
3102                                 -(output->y + output->height / 2.0), 0);
3103
3104         weston_matrix_scale(&output->matrix,
3105                             2.0 / output->width,
3106                             -2.0 / output->height, 1);
3107
3108         weston_output_compute_transform(output);
3109
3110         if (output->zoom.active) {
3111                 magnification = 1 / (1 - output->zoom.spring_z.current);
3112                 weston_matrix_init(&camera);
3113                 weston_matrix_init(&modelview);
3114                 weston_output_update_zoom(output);
3115                 weston_matrix_translate(&camera, output->zoom.trans_x,
3116                                         -output->zoom.trans_y, 0);
3117                 weston_matrix_invert(&modelview, &camera);
3118                 weston_matrix_scale(&modelview, magnification, magnification, 1.0);
3119                 weston_matrix_multiply(&output->matrix, &modelview);
3120         }
3121
3122         output->dirty = 0;
3123 }
3124
3125 static void
3126 weston_output_transform_scale_init(struct weston_output *output, uint32_t transform, uint32_t scale)
3127 {
3128         output->transform = transform;
3129
3130         switch (transform) {
3131         case WL_OUTPUT_TRANSFORM_90:
3132         case WL_OUTPUT_TRANSFORM_270:
3133         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
3134         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
3135                 /* Swap width and height */
3136                 output->width = output->current_mode->height;
3137                 output->height = output->current_mode->width;
3138                 break;
3139         case WL_OUTPUT_TRANSFORM_NORMAL:
3140         case WL_OUTPUT_TRANSFORM_180:
3141         case WL_OUTPUT_TRANSFORM_FLIPPED:
3142         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
3143                 output->width = output->current_mode->width;
3144                 output->height = output->current_mode->height;
3145                 break;
3146         default:
3147                 break;
3148         }
3149
3150         output->native_scale = output->current_scale = scale;
3151         output->width /= scale;
3152         output->height /= scale;
3153 }
3154
3155 WL_EXPORT void
3156 weston_output_move(struct weston_output *output, int x, int y)
3157 {
3158         output->x = x;
3159         output->y = y;
3160
3161         pixman_region32_init(&output->previous_damage);
3162         pixman_region32_init_rect(&output->region, x, y,
3163                                   output->width,
3164                                   output->height);
3165 }
3166
3167 WL_EXPORT void
3168 weston_output_init(struct weston_output *output, struct weston_compositor *c,
3169                    int x, int y, int mm_width, int mm_height, uint32_t transform,
3170                    int32_t scale)
3171 {
3172         output->compositor = c;
3173         output->x = x;
3174         output->y = y;
3175         output->mm_width = mm_width;
3176         output->mm_height = mm_height;
3177         output->dirty = 1;
3178         output->original_scale = scale;
3179
3180         weston_output_transform_scale_init(output, transform, scale);
3181         weston_output_init_zoom(output);
3182
3183         weston_output_move(output, x, y);
3184         weston_output_damage(output);
3185
3186         wl_signal_init(&output->frame_signal);
3187         wl_signal_init(&output->destroy_signal);
3188         wl_list_init(&output->animation_list);
3189         wl_list_init(&output->resource_list);
3190
3191         output->id = ffs(~output->compositor->output_id_pool) - 1;
3192         output->compositor->output_id_pool |= 1 << output->id;
3193
3194         output->global =
3195                 wl_global_create(c->wl_display, &wl_output_interface, 2,
3196                                  output, bind_output);
3197         wl_signal_emit(&c->output_created_signal, output);
3198 }
3199
3200 WL_EXPORT void
3201 weston_output_transform_coordinate(struct weston_output *output,
3202                                    wl_fixed_t device_x, wl_fixed_t device_y,
3203                                    wl_fixed_t *x, wl_fixed_t *y)
3204 {
3205         wl_fixed_t tx, ty;
3206         wl_fixed_t width, height;
3207
3208         width = wl_fixed_from_int(output->width * output->current_scale - 1);
3209         height = wl_fixed_from_int(output->height * output->current_scale - 1);
3210
3211         switch(output->transform) {
3212         case WL_OUTPUT_TRANSFORM_NORMAL:
3213         default:
3214                 tx = device_x;
3215                 ty = device_y;
3216                 break;
3217         case WL_OUTPUT_TRANSFORM_90:
3218                 tx = device_y;
3219                 ty = height - device_x;
3220                 break;
3221         case WL_OUTPUT_TRANSFORM_180:
3222                 tx = width - device_x;
3223                 ty = height - device_y;
3224                 break;
3225         case WL_OUTPUT_TRANSFORM_270:
3226                 tx = width - device_y;
3227                 ty = device_x;
3228                 break;
3229         case WL_OUTPUT_TRANSFORM_FLIPPED:
3230                 tx = width - device_x;
3231                 ty = device_y;
3232                 break;
3233         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
3234                 tx = width - device_y;
3235                 ty = height - device_x;
3236                 break;
3237         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
3238                 tx = device_x;
3239                 ty = height - device_y;
3240                 break;
3241         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
3242                 tx = device_y;
3243                 ty = device_x;
3244                 break;
3245         }
3246
3247         *x = tx / output->current_scale + wl_fixed_from_int(output->x);
3248         *y = ty / output->current_scale + wl_fixed_from_int(output->y);
3249 }
3250
3251 static void
3252 compositor_bind(struct wl_client *client,
3253                 void *data, uint32_t version, uint32_t id)
3254 {
3255         struct weston_compositor *compositor = data;
3256         struct wl_resource *resource;
3257
3258         resource = wl_resource_create(client, &wl_compositor_interface,
3259                                       MIN(version, 3), id);
3260         if (resource == NULL) {
3261                 wl_client_post_no_memory(client);
3262                 return;
3263         }
3264
3265         wl_resource_set_implementation(resource, &compositor_interface,
3266                                        compositor, NULL);
3267 }
3268
3269 static void
3270 log_uname(void)
3271 {
3272         struct utsname usys;
3273
3274         uname(&usys);
3275
3276         weston_log("OS: %s, %s, %s, %s\n", usys.sysname, usys.release,
3277                                                 usys.version, usys.machine);
3278 }
3279
3280 WL_EXPORT int
3281 weston_environment_get_fd(const char *env)
3282 {
3283         char *e, *end;
3284         int fd, flags;
3285
3286         e = getenv(env);
3287         if (!e)
3288                 return -1;
3289         fd = strtol(e, &end, 0);
3290         if (*end != '\0')
3291                 return -1;
3292
3293         flags = fcntl(fd, F_GETFD);
3294         if (flags == -1)
3295                 return -1;
3296
3297         fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
3298         unsetenv(env);
3299
3300         return fd;
3301 }
3302
3303 WL_EXPORT int
3304 weston_compositor_init(struct weston_compositor *ec,
3305                        struct wl_display *display,
3306                        int *argc, char *argv[],
3307                        struct weston_config *config)
3308 {
3309         struct wl_event_loop *loop;
3310         struct xkb_rule_names xkb_names;
3311         struct weston_config_section *s;
3312
3313         ec->config = config;
3314         ec->wl_display = display;
3315         wl_signal_init(&ec->destroy_signal);
3316         wl_signal_init(&ec->activate_signal);
3317         wl_signal_init(&ec->transform_signal);
3318         wl_signal_init(&ec->kill_signal);
3319         wl_signal_init(&ec->idle_signal);
3320         wl_signal_init(&ec->wake_signal);
3321         wl_signal_init(&ec->show_input_panel_signal);
3322         wl_signal_init(&ec->hide_input_panel_signal);
3323         wl_signal_init(&ec->update_input_panel_signal);
3324         wl_signal_init(&ec->seat_created_signal);
3325         wl_signal_init(&ec->output_created_signal);
3326         wl_signal_init(&ec->session_signal);
3327         ec->session_active = 1;
3328
3329         ec->output_id_pool = 0;
3330
3331         if (!wl_global_create(display, &wl_compositor_interface, 3,
3332                               ec, compositor_bind))
3333                 return -1;
3334
3335         if (!wl_global_create(display, &wl_subcompositor_interface, 1,
3336                               ec, bind_subcompositor))
3337                 return -1;
3338
3339         wl_list_init(&ec->view_list);
3340         wl_list_init(&ec->plane_list);
3341         wl_list_init(&ec->layer_list);
3342         wl_list_init(&ec->seat_list);
3343         wl_list_init(&ec->output_list);
3344         wl_list_init(&ec->key_binding_list);
3345         wl_list_init(&ec->modifier_binding_list);
3346         wl_list_init(&ec->button_binding_list);
3347         wl_list_init(&ec->touch_binding_list);
3348         wl_list_init(&ec->axis_binding_list);
3349         wl_list_init(&ec->debug_binding_list);
3350
3351         weston_plane_init(&ec->primary_plane, ec, 0, 0);
3352         weston_compositor_stack_plane(ec, &ec->primary_plane, NULL);
3353
3354         s = weston_config_get_section(ec->config, "keyboard", NULL, NULL);
3355         weston_config_section_get_string(s, "keymap_rules",
3356                                          (char **) &xkb_names.rules, NULL);
3357         weston_config_section_get_string(s, "keymap_model",
3358                                          (char **) &xkb_names.model, NULL);
3359         weston_config_section_get_string(s, "keymap_layout",
3360                                          (char **) &xkb_names.layout, NULL);
3361         weston_config_section_get_string(s, "keymap_variant",
3362                                          (char **) &xkb_names.variant, NULL);
3363         weston_config_section_get_string(s, "keymap_options",
3364                                          (char **) &xkb_names.options, NULL);
3365
3366         if (weston_compositor_xkb_init(ec, &xkb_names) < 0)
3367                 return -1;
3368
3369         ec->ping_handler = NULL;
3370
3371         screenshooter_create(ec);
3372         text_backend_init(ec);
3373
3374         wl_data_device_manager_init(ec->wl_display);
3375
3376         wl_display_init_shm(display);
3377
3378         loop = wl_display_get_event_loop(ec->wl_display);
3379         ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
3380         wl_event_source_timer_update(ec->idle_source, ec->idle_time * 1000);
3381
3382         ec->input_loop = wl_event_loop_create();
3383
3384         weston_layer_init(&ec->fade_layer, &ec->layer_list);
3385         weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
3386
3387         weston_compositor_schedule_repaint(ec);
3388
3389         return 0;
3390 }
3391
3392 WL_EXPORT void
3393 weston_compositor_shutdown(struct weston_compositor *ec)
3394 {
3395         struct weston_output *output, *next;
3396
3397         wl_event_source_remove(ec->idle_source);
3398         if (ec->input_loop_source)
3399                 wl_event_source_remove(ec->input_loop_source);
3400
3401         /* Destroy all outputs associated with this compositor */
3402         wl_list_for_each_safe(output, next, &ec->output_list, link)
3403                 output->destroy(output);
3404
3405         weston_binding_list_destroy_all(&ec->key_binding_list);
3406         weston_binding_list_destroy_all(&ec->button_binding_list);
3407         weston_binding_list_destroy_all(&ec->touch_binding_list);
3408         weston_binding_list_destroy_all(&ec->axis_binding_list);
3409         weston_binding_list_destroy_all(&ec->debug_binding_list);
3410
3411         weston_plane_release(&ec->primary_plane);
3412
3413         wl_event_loop_destroy(ec->input_loop);
3414
3415         weston_config_destroy(ec->config);
3416 }
3417
3418 WL_EXPORT void
3419 weston_compositor_set_default_pointer_grab(struct weston_compositor *ec,
3420                         const struct weston_pointer_grab_interface *interface)
3421 {
3422         struct weston_seat *seat;
3423
3424         ec->default_pointer_grab = interface;
3425         wl_list_for_each(seat, &ec->seat_list, link) {
3426                 if (seat->pointer) {
3427                         weston_pointer_set_default_grab(seat->pointer,
3428                                                         interface);
3429                 }
3430         }
3431 }
3432
3433 WL_EXPORT void
3434 weston_version(int *major, int *minor, int *micro)
3435 {
3436         *major = WESTON_VERSION_MAJOR;
3437         *minor = WESTON_VERSION_MINOR;
3438         *micro = WESTON_VERSION_MICRO;
3439 }
3440
3441 static const struct {
3442         uint32_t bit; /* enum weston_capability */
3443         const char *desc;
3444 } capability_strings[] = {
3445         { WESTON_CAP_ROTATION_ANY, "arbitrary surface rotation:" },
3446         { WESTON_CAP_CAPTURE_YFLIP, "screen capture uses y-flip:" },
3447 };
3448
3449 static void
3450 weston_compositor_log_capabilities(struct weston_compositor *compositor)
3451 {
3452         unsigned i;
3453         int yes;
3454
3455         weston_log("Compositor capabilities:\n");
3456         for (i = 0; i < ARRAY_LENGTH(capability_strings); i++) {
3457                 yes = compositor->capabilities & capability_strings[i].bit;
3458                 weston_log_continue(STAMP_SPACE "%s %s\n",
3459                                     capability_strings[i].desc,
3460                                     yes ? "yes" : "no");
3461         }
3462 }
3463
3464 static int on_term_signal(int signal_number, void *data)
3465 {
3466         struct wl_display *display = data;
3467
3468         weston_log("caught signal %d\n", signal_number);
3469         wl_display_terminate(display);
3470
3471         return 1;
3472 }
3473
3474 #ifdef HAVE_LIBUNWIND
3475
3476 static void
3477 print_backtrace(void)
3478 {
3479         unw_cursor_t cursor;
3480         unw_context_t context;
3481         unw_word_t off;
3482         unw_proc_info_t pip;
3483         int ret, i = 0;
3484         char procname[256];
3485         const char *filename;
3486         Dl_info dlinfo;
3487
3488         pip.unwind_info = NULL;
3489         ret = unw_getcontext(&context);
3490         if (ret) {
3491                 weston_log("unw_getcontext: %d\n", ret);
3492                 return;
3493         }
3494
3495         ret = unw_init_local(&cursor, &context);
3496         if (ret) {
3497                 weston_log("unw_init_local: %d\n", ret);
3498                 return;
3499         }
3500
3501         ret = unw_step(&cursor);
3502         while (ret > 0) {
3503                 ret = unw_get_proc_info(&cursor, &pip);
3504                 if (ret) {
3505                         weston_log("unw_get_proc_info: %d\n", ret);
3506                         break;
3507                 }
3508
3509                 ret = unw_get_proc_name(&cursor, procname, 256, &off);
3510                 if (ret && ret != -UNW_ENOMEM) {
3511                         if (ret != -UNW_EUNSPEC)
3512                                 weston_log("unw_get_proc_name: %d\n", ret);
3513                         procname[0] = '?';
3514                         procname[1] = 0;
3515                 }
3516
3517                 if (dladdr((void *)(pip.start_ip + off), &dlinfo) && dlinfo.dli_fname &&
3518                     *dlinfo.dli_fname)
3519                         filename = dlinfo.dli_fname;
3520                 else
3521                         filename = "?";
3522                 
3523                 weston_log("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,
3524                            ret == -UNW_ENOMEM ? "..." : "", (int)off, (void *)(pip.start_ip + off));
3525
3526                 ret = unw_step(&cursor);
3527                 if (ret < 0)
3528                         weston_log("unw_step: %d\n", ret);
3529         }
3530 }
3531
3532 #else
3533
3534 static void
3535 print_backtrace(void)
3536 {
3537         void *buffer[32];
3538         int i, count;
3539         Dl_info info;
3540
3541         count = backtrace(buffer, ARRAY_LENGTH(buffer));
3542         for (i = 0; i < count; i++) {
3543                 dladdr(buffer[i], &info);
3544                 weston_log("  [%016lx]  %s  (%s)\n",
3545                         (long) buffer[i],
3546                         info.dli_sname ? info.dli_sname : "--",
3547                         info.dli_fname);
3548         }
3549 }
3550
3551 #endif
3552
3553 static void
3554 on_caught_signal(int s, siginfo_t *siginfo, void *context)
3555 {
3556         /* This signal handler will do a best-effort backtrace, and
3557          * then call the backend restore function, which will switch
3558          * back to the vt we launched from or ungrab X etc and then
3559          * raise SIGTRAP.  If we run weston under gdb from X or a
3560          * different vt, and tell gdb "handle *s* nostop", this
3561          * will allow weston to switch back to gdb on crash and then
3562          * gdb will catch the crash with SIGTRAP.*/
3563
3564         weston_log("caught signal: %d\n", s);
3565
3566         print_backtrace();
3567
3568         segv_compositor->restore(segv_compositor);
3569
3570         raise(SIGTRAP);
3571 }
3572
3573 WL_EXPORT void *
3574 weston_load_module(const char *name, const char *entrypoint)
3575 {
3576         char path[PATH_MAX];
3577         void *module, *init;
3578
3579         if (name[0] != '/')
3580                 snprintf(path, sizeof path, "%s/%s", MODULEDIR, name);
3581         else
3582                 snprintf(path, sizeof path, "%s", name);
3583
3584         module = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
3585         if (module) {
3586                 weston_log("Module '%s' already loaded\n", path);
3587                 dlclose(module);
3588                 return NULL;
3589         }
3590
3591         weston_log("Loading module '%s'\n", path);
3592         module = dlopen(path, RTLD_NOW);
3593         if (!module) {
3594                 weston_log("Failed to load module: %s\n", dlerror());
3595                 return NULL;
3596         }
3597
3598         init = dlsym(module, entrypoint);
3599         if (!init) {
3600                 weston_log("Failed to lookup init function: %s\n", dlerror());
3601                 dlclose(module);
3602                 return NULL;
3603         }
3604
3605         return init;
3606 }
3607
3608 static int
3609 load_modules(struct weston_compositor *ec, const char *modules,
3610              int *argc, char *argv[])
3611 {
3612         const char *p, *end;
3613         char buffer[256];
3614         int (*module_init)(struct weston_compositor *ec,
3615                            int *argc, char *argv[]);
3616
3617         if (modules == NULL)
3618                 return 0;
3619
3620         p = modules;
3621         while (*p) {
3622                 end = strchrnul(p, ',');
3623                 snprintf(buffer, sizeof buffer, "%.*s", (int) (end - p), p);
3624                 module_init = weston_load_module(buffer, "module_init");
3625                 if (module_init)
3626                         module_init(ec, argc, argv);
3627                 p = end;
3628                 while (*p == ',')
3629                         p++;
3630
3631         }
3632
3633         return 0;
3634 }
3635
3636 static const char xdg_error_message[] =
3637         "fatal: environment variable XDG_RUNTIME_DIR is not set.\n";
3638
3639 static const char xdg_wrong_message[] =
3640         "fatal: environment variable XDG_RUNTIME_DIR\n"
3641         "is set to \"%s\", which is not a directory.\n";
3642
3643 static const char xdg_wrong_mode_message[] =
3644         "warning: XDG_RUNTIME_DIR \"%s\" is not configured\n"
3645         "correctly.  Unix access mode must be 0700 but is %o,\n"
3646         "and XDG_RUNTIME_DIR must be owned by the user, but is\n"
3647         "owned by UID %d.\n";
3648
3649 static const char xdg_detail_message[] =
3650         "Refer to your distribution on how to get it, or\n"
3651         "http://www.freedesktop.org/wiki/Specifications/basedir-spec\n"
3652         "on how to implement it.\n";
3653
3654 static void
3655 verify_xdg_runtime_dir(void)
3656 {
3657         char *dir = getenv("XDG_RUNTIME_DIR");
3658         struct stat s;
3659
3660         if (!dir) {
3661                 weston_log(xdg_error_message);
3662                 weston_log_continue(xdg_detail_message);
3663                 exit(EXIT_FAILURE);
3664         }
3665
3666         if (stat(dir, &s) || !S_ISDIR(s.st_mode)) {
3667                 weston_log(xdg_wrong_message, dir);
3668                 weston_log_continue(xdg_detail_message);
3669                 exit(EXIT_FAILURE);
3670         }
3671
3672         if ((s.st_mode & 0777) != 0700 || s.st_uid != getuid()) {
3673                 weston_log(xdg_wrong_mode_message,
3674                            dir, s.st_mode & 0777, s.st_uid);
3675                 weston_log_continue(xdg_detail_message);
3676         }
3677 }
3678
3679 static int
3680 usage(int error_code)
3681 {
3682         fprintf(stderr,
3683                 "Usage: weston [OPTIONS]\n\n"
3684                 "This is weston version " VERSION ", the Wayland reference compositor.\n"
3685                 "Weston supports multiple backends, and depending on which backend is in use\n"
3686                 "different options will be accepted.\n\n"
3687
3688
3689                 "Core options:\n\n"
3690                 "  --version\t\tPrint weston version\n"
3691                 "  -B, --backend=MODULE\tBackend module, one of drm-backend.so,\n"
3692                 "\t\t\t\tfbdev-backend.so, x11-backend.so or\n"
3693                 "\t\t\t\twayland-backend.so\n"
3694                 "  --shell=MODULE\tShell module, defaults to desktop-shell.so\n"
3695                 "  -S, --socket=NAME\tName of socket to listen on\n"
3696                 "  -i, --idle-time=SECS\tIdle time in seconds\n"
3697                 "  --modules\t\tLoad the comma-separated list of modules\n"
3698                 "  --log==FILE\t\tLog to the given file\n"
3699                 "  -h, --help\t\tThis help message\n\n");
3700
3701         fprintf(stderr,
3702                 "Options for drm-backend.so:\n\n"
3703                 "  --connector=ID\tBring up only this connector\n"
3704                 "  --seat=SEAT\t\tThe seat that weston should run on\n"
3705                 "  --tty=TTY\t\tThe tty to use\n"
3706                 "  --use-pixman\t\tUse the pixman (CPU) renderer\n"
3707                 "  --current-mode\tPrefer current KMS mode over EDID preferred mode\n\n");
3708
3709         fprintf(stderr,
3710                 "Options for fbdev-backend.so:\n\n"
3711                 "  --tty=TTY\t\tThe tty to use\n"
3712                 "  --device=DEVICE\tThe framebuffer device to use\n\n");
3713
3714         fprintf(stderr,
3715                 "Options for x11-backend.so:\n\n"
3716                 "  --width=WIDTH\t\tWidth of X window\n"
3717                 "  --height=HEIGHT\tHeight of X window\n"
3718                 "  --fullscreen\t\tRun in fullscreen mode\n"
3719                 "  --use-pixman\t\tUse the pixman (CPU) renderer\n"
3720                 "  --output-count=COUNT\tCreate multiple outputs\n"
3721                 "  --no-input\t\tDont create input devices\n\n");
3722
3723         fprintf(stderr,
3724                 "Options for wayland-backend.so:\n\n"
3725                 "  --width=WIDTH\t\tWidth of Wayland surface\n"
3726                 "  --height=HEIGHT\tHeight of Wayland surface\n"
3727                 "  --scale=SCALE\tScale factor of ouput\n"
3728                 "  --fullscreen\t\tRun in fullscreen mode\n"
3729                 "  --use-pixman\t\tUse the pixman (CPU) renderer\n"
3730                 "  --output-count=COUNT\tCreate multiple outputs\n"
3731                 "  --display=DISPLAY\tWayland display to connect to\n\n");
3732
3733 #if defined(BUILD_RPI_COMPOSITOR) && defined(HAVE_BCM_HOST)
3734         fprintf(stderr,
3735                 "Options for rpi-backend.so:\n\n"
3736                 "  --tty=TTY\t\tThe tty to use\n"
3737                 "  --single-buffer\tUse single-buffered Dispmanx elements.\n"
3738                 "  --transform=TR\tThe output transformation, TR is one of:\n"
3739                 "\tnormal 90 180 270 flipped flipped-90 flipped-180 flipped-270\n"
3740                 "\n");
3741 #endif
3742
3743 #if defined(BUILD_RDP_COMPOSITOR)
3744     fprintf(stderr,
3745        "Options for rdp-backend.so:\n\n"
3746        "  --width=WIDTH\t\tWidth of desktop\n"
3747        "  --height=HEIGHT\tHeight of desktop\n"
3748        "  --extra-modes=MODES\t\n"
3749        "  --env-socket=SOCKET\tUse that socket as peer connection\n"
3750        "  --address=ADDR\tThe address to bind\n"
3751        "  --port=PORT\tThe port to listen on\n"
3752        "  --rdp4-key=FILE\tThe file containing the key for RDP4 encryption\n"
3753        "  --rdp-tls-cert=FILE\tThe file containing the certificate for TLS encryption\n"
3754        "  --rdp-tls-key=FILE\tThe file containing the private key for TLS encryption\n"
3755        "\n");
3756 #endif
3757
3758         exit(error_code);
3759 }
3760
3761 static void
3762 catch_signals(void)
3763 {
3764         struct sigaction action;
3765
3766         action.sa_flags = SA_SIGINFO | SA_RESETHAND;
3767         action.sa_sigaction = on_caught_signal;
3768         sigemptyset(&action.sa_mask);
3769         sigaction(SIGSEGV, &action, NULL);
3770         sigaction(SIGABRT, &action, NULL);
3771 }
3772
3773 int main(int argc, char *argv[])
3774 {
3775         int ret = EXIT_SUCCESS;
3776         struct wl_display *display;
3777         struct weston_compositor *ec;
3778         struct wl_event_source *signals[4];
3779         struct wl_event_loop *loop;
3780         struct weston_compositor
3781                 *(*backend_init)(struct wl_display *display,
3782                                  int *argc, char *argv[],
3783                                  struct weston_config *config);
3784         int i;
3785         char *backend = NULL;
3786         char *option_backend = NULL;
3787         char *shell = NULL;
3788         char *modules, *option_modules = NULL;
3789         char *log = NULL;
3790         int32_t idle_time = 300;
3791         int32_t help = 0;
3792         char *socket_name = "wayland-0";
3793         int32_t version = 0;
3794         struct weston_config *config;
3795         struct weston_config_section *section;
3796
3797         const struct weston_option core_options[] = {
3798                 { WESTON_OPTION_STRING, "backend", 'B', &option_backend },
3799                 { WESTON_OPTION_STRING, "shell", 0, &shell },
3800                 { WESTON_OPTION_STRING, "socket", 'S', &socket_name },
3801                 { WESTON_OPTION_INTEGER, "idle-time", 'i', &idle_time },
3802                 { WESTON_OPTION_STRING, "modules", 0, &option_modules },
3803                 { WESTON_OPTION_STRING, "log", 0, &log },
3804                 { WESTON_OPTION_BOOLEAN, "help", 'h', &help },
3805                 { WESTON_OPTION_BOOLEAN, "version", 0, &version },
3806         };
3807
3808         parse_options(core_options, ARRAY_LENGTH(core_options), &argc, argv);
3809
3810         if (help)
3811                 usage(EXIT_SUCCESS);
3812
3813         if (version) {
3814                 printf(PACKAGE_STRING "\n");
3815                 return EXIT_SUCCESS;
3816         }
3817
3818         weston_log_file_open(log);
3819         
3820         weston_log("%s\n"
3821                    STAMP_SPACE "%s\n"
3822                    STAMP_SPACE "Bug reports to: %s\n"
3823                    STAMP_SPACE "Build: %s\n",
3824                    PACKAGE_STRING, PACKAGE_URL, PACKAGE_BUGREPORT,
3825                    BUILD_ID);
3826         log_uname();
3827
3828         verify_xdg_runtime_dir();
3829
3830         display = wl_display_create();
3831
3832         loop = wl_display_get_event_loop(display);
3833         signals[0] = wl_event_loop_add_signal(loop, SIGTERM, on_term_signal,
3834                                               display);
3835         signals[1] = wl_event_loop_add_signal(loop, SIGINT, on_term_signal,
3836                                               display);
3837         signals[2] = wl_event_loop_add_signal(loop, SIGQUIT, on_term_signal,
3838                                               display);
3839
3840         wl_list_init(&child_process_list);
3841         signals[3] = wl_event_loop_add_signal(loop, SIGCHLD, sigchld_handler,
3842                                               NULL);
3843
3844         config = weston_config_parse("weston.ini");
3845         if (config != NULL) {
3846                 weston_log("Using config file '%s'\n",
3847                            weston_config_get_full_path(config));
3848         } else {
3849                 weston_log("Starting with no config file.\n");
3850         }
3851         section = weston_config_get_section(config, "core", NULL, NULL);
3852
3853         weston_config_section_get_string(section, "backend", &backend, NULL);
3854         if (option_backend) {
3855                 backend = option_backend;
3856         }
3857         if (!backend) {
3858                 if (getenv("WAYLAND_DISPLAY"))
3859                         backend = "wayland-backend.so";
3860                 else if (getenv("DISPLAY"))
3861                         backend = "x11-backend.so";
3862                 else
3863                         backend = WESTON_NATIVE_BACKEND;
3864         }
3865
3866         weston_config_section_get_string(section, "modules", &modules, "");
3867
3868         backend_init = weston_load_module(backend, "backend_init");
3869         if (!backend_init)
3870                 exit(EXIT_FAILURE);
3871
3872         ec = backend_init(display, &argc, argv, config);
3873         if (ec == NULL) {
3874                 weston_log("fatal: failed to create compositor\n");
3875                 exit(EXIT_FAILURE);
3876         }
3877
3878         catch_signals();
3879         segv_compositor = ec;
3880
3881         ec->idle_time = idle_time;
3882         ec->default_pointer_grab = NULL;
3883
3884         setenv("WAYLAND_DISPLAY", socket_name, 1);
3885
3886         if (!shell)
3887                 weston_config_section_get_string(section, "shell", &shell,
3888                                                  "desktop-shell.so");
3889         if (load_modules(ec, shell, &argc, argv) < 0)
3890                 goto out;
3891
3892         if (load_modules(ec, modules, &argc, argv) < 0)
3893                 goto out;
3894         if (load_modules(ec, option_modules, &argc, argv) < 0)
3895                 goto out;
3896
3897         for (i = 1; i < argc; i++)
3898                 weston_log("fatal: unhandled option: %s\n", argv[i]);
3899         if (argc > 1) {
3900                 ret = EXIT_FAILURE;
3901                 goto out;
3902         }
3903
3904         weston_compositor_log_capabilities(ec);
3905
3906         if (wl_display_add_socket(display, socket_name)) {
3907                 weston_log("fatal: failed to add socket: %m\n");
3908                 ret = EXIT_FAILURE;
3909                 goto out;
3910         }
3911
3912         weston_compositor_wake(ec);
3913
3914         wl_display_run(display);
3915
3916  out:
3917         /* prevent further rendering while shutting down */
3918         ec->state = WESTON_COMPOSITOR_OFFSCREEN;
3919
3920         wl_signal_emit(&ec->destroy_signal, ec);
3921
3922         for (i = ARRAY_LENGTH(signals); i;)
3923                 wl_event_source_remove(signals[--i]);
3924
3925         weston_compositor_xkb_destroy(ec);
3926
3927         ec->destroy(ec);
3928         wl_display_destroy(display);
3929
3930         weston_log_file_close();
3931
3932         return ret;
3933 }