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