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