libweston: Rename weston_surface::configure to ::committed
[platform/upstream/weston.git] / libweston / compositor.c
1 /*
2  * Copyright © 2010-2011 Intel Corporation
3  * Copyright © 2008-2011 Kristian Høgsberg
4  * Copyright © 2012-2015 Collabora, Ltd.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial
16  * portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  */
27
28 #include "config.h"
29
30 #include <fcntl.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <stdint.h>
35 #include <limits.h>
36 #include <stdarg.h>
37 #include <assert.h>
38 #include <sys/ioctl.h>
39 #include <sys/mman.h>
40 #include <sys/wait.h>
41 #include <sys/socket.h>
42 #include <sys/utsname.h>
43 #include <sys/stat.h>
44 #include <unistd.h>
45 #include <math.h>
46 #include <linux/input.h>
47 #include <dlfcn.h>
48 #include <signal.h>
49 #include <setjmp.h>
50 #include <sys/time.h>
51 #include <time.h>
52 #include <errno.h>
53
54 #include "timeline.h"
55
56 #include "compositor.h"
57 #include "viewporter-server-protocol.h"
58 #include "presentation-time-server-protocol.h"
59 #include "shared/helpers.h"
60 #include "shared/os-compatibility.h"
61 #include "shared/string-helpers.h"
62 #include "shared/timespec-util.h"
63 #include "git-version.h"
64 #include "version.h"
65 #include "plugin-registry.h"
66
67 #define DEFAULT_REPAINT_WINDOW 7 /* milliseconds */
68
69 static void
70 weston_output_transform_scale_init(struct weston_output *output,
71                                    uint32_t transform, uint32_t scale);
72
73 static void
74 weston_compositor_build_view_list(struct weston_compositor *compositor);
75
76 static void weston_mode_switch_finish(struct weston_output *output,
77                                       int mode_changed,
78                                       int scale_changed)
79 {
80         struct weston_seat *seat;
81         struct wl_resource *resource;
82         pixman_region32_t old_output_region;
83         int version;
84
85         pixman_region32_init(&old_output_region);
86         pixman_region32_copy(&old_output_region, &output->region);
87
88         /* Update output region and transformation matrix */
89         weston_output_transform_scale_init(output, output->transform, output->current_scale);
90
91         pixman_region32_init(&output->previous_damage);
92         pixman_region32_init_rect(&output->region, output->x, output->y,
93                                   output->width, output->height);
94
95         weston_output_update_matrix(output);
96
97         /* If a pointer falls outside the outputs new geometry, move it to its
98          * lower-right corner */
99         wl_list_for_each(seat, &output->compositor->seat_list, link) {
100                 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
101                 int32_t x, y;
102
103                 if (!pointer)
104                         continue;
105
106                 x = wl_fixed_to_int(pointer->x);
107                 y = wl_fixed_to_int(pointer->y);
108
109                 if (!pixman_region32_contains_point(&old_output_region,
110                                                     x, y, NULL) ||
111                     pixman_region32_contains_point(&output->region,
112                                                    x, y, NULL))
113                         continue;
114
115                 if (x >= output->x + output->width)
116                         x = output->x + output->width - 1;
117                 if (y >= output->y + output->height)
118                         y = output->y + output->height - 1;
119
120                 pointer->x = wl_fixed_from_int(x);
121                 pointer->y = wl_fixed_from_int(y);
122         }
123
124         pixman_region32_fini(&old_output_region);
125
126         if (!mode_changed && !scale_changed)
127                 return;
128
129         /* notify clients of the changes */
130         wl_resource_for_each(resource, &output->resource_list) {
131                 if (mode_changed) {
132                         wl_output_send_mode(resource,
133                                             output->current_mode->flags,
134                                             output->current_mode->width,
135                                             output->current_mode->height,
136                                             output->current_mode->refresh);
137                 }
138
139                 version = wl_resource_get_version(resource);
140                 if (version >= WL_OUTPUT_SCALE_SINCE_VERSION && scale_changed)
141                         wl_output_send_scale(resource, output->current_scale);
142
143                 if (version >= WL_OUTPUT_DONE_SINCE_VERSION)
144                         wl_output_send_done(resource);
145         }
146 }
147
148
149 static void
150 weston_compositor_reflow_outputs(struct weston_compositor *compositor,
151                                 struct weston_output *resized_output, int delta_width);
152
153 WL_EXPORT int
154 weston_output_mode_set_native(struct weston_output *output,
155                               struct weston_mode *mode,
156                               int32_t scale)
157 {
158         int ret;
159         int mode_changed = 0, scale_changed = 0;
160         int32_t old_width;
161
162         if (!output->switch_mode)
163                 return -1;
164
165         if (!output->original_mode) {
166                 mode_changed = 1;
167                 ret = output->switch_mode(output, mode);
168                 if (ret < 0)
169                         return ret;
170                 if (output->current_scale != scale) {
171                         scale_changed = 1;
172                         output->current_scale = scale;
173                 }
174         }
175
176         old_width = output->width;
177         output->native_mode = mode;
178         output->native_scale = scale;
179
180         weston_mode_switch_finish(output, mode_changed, scale_changed);
181
182         if (mode_changed || scale_changed) {
183                 weston_compositor_reflow_outputs(output->compositor, output, output->width - old_width);
184
185                 wl_signal_emit(&output->compositor->output_resized_signal, output);
186         }
187         return 0;
188 }
189
190 WL_EXPORT int
191 weston_output_mode_switch_to_native(struct weston_output *output)
192 {
193         int ret;
194         int mode_changed = 0, scale_changed = 0;
195
196         if (!output->switch_mode)
197                 return -1;
198
199         if (!output->original_mode) {
200                 weston_log("already in the native mode\n");
201                 return -1;
202         }
203         /* the non fullscreen clients haven't seen a mode set since we
204          * switched into a temporary, so we need to notify them if the
205          * mode at that time is different from the native mode now.
206          */
207         mode_changed = (output->original_mode != output->native_mode);
208         scale_changed = (output->original_scale != output->native_scale);
209
210         ret = output->switch_mode(output, output->native_mode);
211         if (ret < 0)
212                 return ret;
213
214         output->current_scale = output->native_scale;
215
216         output->original_mode = NULL;
217         output->original_scale = 0;
218
219         weston_mode_switch_finish(output, mode_changed, scale_changed);
220
221         return 0;
222 }
223
224 WL_EXPORT int
225 weston_output_mode_switch_to_temporary(struct weston_output *output,
226                                        struct weston_mode *mode,
227                                        int32_t scale)
228 {
229         int ret;
230
231         if (!output->switch_mode)
232                 return -1;
233
234         /* original_mode is the last mode non full screen clients have seen,
235          * so we shouldn't change it if we already have one set.
236          */
237         if (!output->original_mode) {
238                 output->original_mode = output->native_mode;
239                 output->original_scale = output->native_scale;
240         }
241         ret = output->switch_mode(output, mode);
242         if (ret < 0)
243                 return ret;
244
245         output->current_scale = scale;
246
247         weston_mode_switch_finish(output, 0, 0);
248
249         return 0;
250 }
251
252 static void
253 region_init_infinite(pixman_region32_t *region)
254 {
255         pixman_region32_init_rect(region, INT32_MIN, INT32_MIN,
256                                   UINT32_MAX, UINT32_MAX);
257 }
258
259 static struct weston_subsurface *
260 weston_surface_to_subsurface(struct weston_surface *surface);
261
262 WL_EXPORT struct weston_view *
263 weston_view_create(struct weston_surface *surface)
264 {
265         struct weston_view *view;
266
267         view = zalloc(sizeof *view);
268         if (view == NULL)
269                 return NULL;
270
271         view->surface = surface;
272
273         /* Assign to surface */
274         wl_list_insert(&surface->views, &view->surface_link);
275
276         wl_signal_init(&view->destroy_signal);
277         wl_list_init(&view->link);
278         wl_list_init(&view->layer_link.link);
279
280         pixman_region32_init(&view->clip);
281
282         view->alpha = 1.0;
283         pixman_region32_init(&view->transform.opaque);
284
285         wl_list_init(&view->geometry.transformation_list);
286         wl_list_insert(&view->geometry.transformation_list,
287                        &view->transform.position.link);
288         weston_matrix_init(&view->transform.position.matrix);
289         wl_list_init(&view->geometry.child_list);
290         pixman_region32_init(&view->geometry.scissor);
291         pixman_region32_init(&view->transform.boundingbox);
292         view->transform.dirty = 1;
293
294         return view;
295 }
296
297 struct weston_frame_callback {
298         struct wl_resource *resource;
299         struct wl_list link;
300 };
301
302 struct weston_presentation_feedback {
303         struct wl_resource *resource;
304
305         /* XXX: could use just wl_resource_get_link() instead */
306         struct wl_list link;
307
308         /* The per-surface feedback flags */
309         uint32_t psf_flags;
310 };
311
312 static void
313 weston_presentation_feedback_discard(
314                 struct weston_presentation_feedback *feedback)
315 {
316         wp_presentation_feedback_send_discarded(feedback->resource);
317         wl_resource_destroy(feedback->resource);
318 }
319
320 static void
321 weston_presentation_feedback_discard_list(struct wl_list *list)
322 {
323         struct weston_presentation_feedback *feedback, *tmp;
324
325         wl_list_for_each_safe(feedback, tmp, list, link)
326                 weston_presentation_feedback_discard(feedback);
327 }
328
329 static void
330 weston_presentation_feedback_present(
331                 struct weston_presentation_feedback *feedback,
332                 struct weston_output *output,
333                 uint32_t refresh_nsec,
334                 const struct timespec *ts,
335                 uint64_t seq,
336                 uint32_t flags)
337 {
338         struct wl_client *client = wl_resource_get_client(feedback->resource);
339         struct wl_resource *o;
340         uint64_t secs;
341
342         wl_resource_for_each(o, &output->resource_list) {
343                 if (wl_resource_get_client(o) != client)
344                         continue;
345
346                 wp_presentation_feedback_send_sync_output(feedback->resource, o);
347         }
348
349         secs = ts->tv_sec;
350         wp_presentation_feedback_send_presented(feedback->resource,
351                                                 secs >> 32, secs & 0xffffffff,
352                                                 ts->tv_nsec,
353                                                 refresh_nsec,
354                                                 seq >> 32, seq & 0xffffffff,
355                                                 flags | feedback->psf_flags);
356         wl_resource_destroy(feedback->resource);
357 }
358
359 static void
360 weston_presentation_feedback_present_list(struct wl_list *list,
361                                           struct weston_output *output,
362                                           uint32_t refresh_nsec,
363                                           const struct timespec *ts,
364                                           uint64_t seq,
365                                           uint32_t flags)
366 {
367         struct weston_presentation_feedback *feedback, *tmp;
368
369         assert(!(flags & WP_PRESENTATION_FEEDBACK_INVALID) ||
370                wl_list_empty(list));
371
372         wl_list_for_each_safe(feedback, tmp, list, link)
373                 weston_presentation_feedback_present(feedback, output,
374                                                      refresh_nsec, ts, seq,
375                                                      flags);
376 }
377
378 static void
379 surface_state_handle_buffer_destroy(struct wl_listener *listener, void *data)
380 {
381         struct weston_surface_state *state =
382                 container_of(listener, struct weston_surface_state,
383                              buffer_destroy_listener);
384
385         state->buffer = NULL;
386 }
387
388 static void
389 weston_surface_state_init(struct weston_surface_state *state)
390 {
391         state->newly_attached = 0;
392         state->buffer = NULL;
393         state->buffer_destroy_listener.notify =
394                 surface_state_handle_buffer_destroy;
395         state->sx = 0;
396         state->sy = 0;
397
398         pixman_region32_init(&state->damage_surface);
399         pixman_region32_init(&state->damage_buffer);
400         pixman_region32_init(&state->opaque);
401         region_init_infinite(&state->input);
402
403         wl_list_init(&state->frame_callback_list);
404         wl_list_init(&state->feedback_list);
405
406         state->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
407         state->buffer_viewport.buffer.scale = 1;
408         state->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
409         state->buffer_viewport.surface.width = -1;
410         state->buffer_viewport.changed = 0;
411 }
412
413 static void
414 weston_surface_state_fini(struct weston_surface_state *state)
415 {
416         struct weston_frame_callback *cb, *next;
417
418         wl_list_for_each_safe(cb, next,
419                               &state->frame_callback_list, link)
420                 wl_resource_destroy(cb->resource);
421
422         weston_presentation_feedback_discard_list(&state->feedback_list);
423
424         pixman_region32_fini(&state->input);
425         pixman_region32_fini(&state->opaque);
426         pixman_region32_fini(&state->damage_surface);
427         pixman_region32_fini(&state->damage_buffer);
428
429         if (state->buffer)
430                 wl_list_remove(&state->buffer_destroy_listener.link);
431         state->buffer = NULL;
432 }
433
434 static void
435 weston_surface_state_set_buffer(struct weston_surface_state *state,
436                                 struct weston_buffer *buffer)
437 {
438         if (state->buffer == buffer)
439                 return;
440
441         if (state->buffer)
442                 wl_list_remove(&state->buffer_destroy_listener.link);
443         state->buffer = buffer;
444         if (state->buffer)
445                 wl_signal_add(&state->buffer->destroy_signal,
446                               &state->buffer_destroy_listener);
447 }
448
449 WL_EXPORT struct weston_surface *
450 weston_surface_create(struct weston_compositor *compositor)
451 {
452         struct weston_surface *surface;
453
454         surface = zalloc(sizeof *surface);
455         if (surface == NULL)
456                 return NULL;
457
458         wl_signal_init(&surface->destroy_signal);
459         wl_signal_init(&surface->commit_signal);
460
461         surface->compositor = compositor;
462         surface->ref_count = 1;
463
464         surface->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
465         surface->buffer_viewport.buffer.scale = 1;
466         surface->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
467         surface->buffer_viewport.surface.width = -1;
468
469         weston_surface_state_init(&surface->pending);
470
471         pixman_region32_init(&surface->damage);
472         pixman_region32_init(&surface->opaque);
473         region_init_infinite(&surface->input);
474
475         wl_list_init(&surface->views);
476
477         wl_list_init(&surface->frame_callback_list);
478         wl_list_init(&surface->feedback_list);
479
480         wl_list_init(&surface->subsurface_list);
481         wl_list_init(&surface->subsurface_list_pending);
482
483         weston_matrix_init(&surface->buffer_to_surface_matrix);
484         weston_matrix_init(&surface->surface_to_buffer_matrix);
485
486         wl_list_init(&surface->pointer_constraints);
487
488         return surface;
489 }
490
491 WL_EXPORT void
492 weston_surface_set_color(struct weston_surface *surface,
493                  float red, float green, float blue, float alpha)
494 {
495         surface->compositor->renderer->surface_set_color(surface, red, green, blue, alpha);
496 }
497
498 WL_EXPORT void
499 weston_view_to_global_float(struct weston_view *view,
500                             float sx, float sy, float *x, float *y)
501 {
502         if (view->transform.enabled) {
503                 struct weston_vector v = { { sx, sy, 0.0f, 1.0f } };
504
505                 weston_matrix_transform(&view->transform.matrix, &v);
506
507                 if (fabsf(v.f[3]) < 1e-6) {
508                         weston_log("warning: numerical instability in "
509                                 "%s(), divisor = %g\n", __func__,
510                                 v.f[3]);
511                         *x = 0;
512                         *y = 0;
513                         return;
514                 }
515
516                 *x = v.f[0] / v.f[3];
517                 *y = v.f[1] / v.f[3];
518         } else {
519                 *x = sx + view->geometry.x;
520                 *y = sy + view->geometry.y;
521         }
522 }
523
524 WL_EXPORT void
525 weston_transformed_coord(int width, int height,
526                          enum wl_output_transform transform,
527                          int32_t scale,
528                          float sx, float sy, float *bx, float *by)
529 {
530         switch (transform) {
531         case WL_OUTPUT_TRANSFORM_NORMAL:
532         default:
533                 *bx = sx;
534                 *by = sy;
535                 break;
536         case WL_OUTPUT_TRANSFORM_FLIPPED:
537                 *bx = width - sx;
538                 *by = sy;
539                 break;
540         case WL_OUTPUT_TRANSFORM_90:
541                 *bx = height - sy;
542                 *by = sx;
543                 break;
544         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
545                 *bx = height - sy;
546                 *by = width - sx;
547                 break;
548         case WL_OUTPUT_TRANSFORM_180:
549                 *bx = width - sx;
550                 *by = height - sy;
551                 break;
552         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
553                 *bx = sx;
554                 *by = height - sy;
555                 break;
556         case WL_OUTPUT_TRANSFORM_270:
557                 *bx = sy;
558                 *by = width - sx;
559                 break;
560         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
561                 *bx = sy;
562                 *by = sx;
563                 break;
564         }
565
566         *bx *= scale;
567         *by *= scale;
568 }
569
570 WL_EXPORT pixman_box32_t
571 weston_transformed_rect(int width, int height,
572                         enum wl_output_transform transform,
573                         int32_t scale,
574                         pixman_box32_t rect)
575 {
576         float x1, x2, y1, y2;
577
578         pixman_box32_t ret;
579
580         weston_transformed_coord(width, height, transform, scale,
581                                  rect.x1, rect.y1, &x1, &y1);
582         weston_transformed_coord(width, height, transform, scale,
583                                  rect.x2, rect.y2, &x2, &y2);
584
585         if (x1 <= x2) {
586                 ret.x1 = x1;
587                 ret.x2 = x2;
588         } else {
589                 ret.x1 = x2;
590                 ret.x2 = x1;
591         }
592
593         if (y1 <= y2) {
594                 ret.y1 = y1;
595                 ret.y2 = y2;
596         } else {
597                 ret.y1 = y2;
598                 ret.y2 = y1;
599         }
600
601         return ret;
602 }
603
604 /** Transform a region by a matrix, restricted to axis-aligned transformations
605  *
606  * Warning: This function does not work for projective, affine, or matrices
607  * that encode arbitrary rotations. Only 90-degree step rotations are
608  * supported.
609  */
610 WL_EXPORT void
611 weston_matrix_transform_region(pixman_region32_t *dest,
612                                struct weston_matrix *matrix,
613                                pixman_region32_t *src)
614 {
615         pixman_box32_t *src_rects, *dest_rects;
616         int nrects, i;
617
618         src_rects = pixman_region32_rectangles(src, &nrects);
619         dest_rects = malloc(nrects * sizeof(*dest_rects));
620         if (!dest_rects)
621                 return;
622
623         for (i = 0; i < nrects; i++) {
624                 struct weston_vector vec1 = {{
625                         src_rects[i].x1, src_rects[i].y1, 0, 1
626                 }};
627                 weston_matrix_transform(matrix, &vec1);
628                 vec1.f[0] /= vec1.f[3];
629                 vec1.f[1] /= vec1.f[3];
630
631                 struct weston_vector vec2 = {{
632                         src_rects[i].x2, src_rects[i].y2, 0, 1
633                 }};
634                 weston_matrix_transform(matrix, &vec2);
635                 vec2.f[0] /= vec2.f[3];
636                 vec2.f[1] /= vec2.f[3];
637
638                 if (vec1.f[0] < vec2.f[0]) {
639                         dest_rects[i].x1 = floor(vec1.f[0]);
640                         dest_rects[i].x2 = ceil(vec2.f[0]);
641                 } else {
642                         dest_rects[i].x1 = floor(vec2.f[0]);
643                         dest_rects[i].x2 = ceil(vec1.f[0]);
644                 }
645
646                 if (vec1.f[1] < vec2.f[1]) {
647                         dest_rects[i].y1 = floor(vec1.f[1]);
648                         dest_rects[i].y2 = ceil(vec2.f[1]);
649                 } else {
650                         dest_rects[i].y1 = floor(vec2.f[1]);
651                         dest_rects[i].y2 = ceil(vec1.f[1]);
652                 }
653         }
654
655         pixman_region32_clear(dest);
656         pixman_region32_init_rects(dest, dest_rects, nrects);
657         free(dest_rects);
658 }
659
660 WL_EXPORT void
661 weston_transformed_region(int width, int height,
662                           enum wl_output_transform transform,
663                           int32_t scale,
664                           pixman_region32_t *src, pixman_region32_t *dest)
665 {
666         pixman_box32_t *src_rects, *dest_rects;
667         int nrects, i;
668
669         if (transform == WL_OUTPUT_TRANSFORM_NORMAL && scale == 1) {
670                 if (src != dest)
671                         pixman_region32_copy(dest, src);
672                 return;
673         }
674
675         src_rects = pixman_region32_rectangles(src, &nrects);
676         dest_rects = malloc(nrects * sizeof(*dest_rects));
677         if (!dest_rects)
678                 return;
679
680         if (transform == WL_OUTPUT_TRANSFORM_NORMAL) {
681                 memcpy(dest_rects, src_rects, nrects * sizeof(*dest_rects));
682         } else {
683                 for (i = 0; i < nrects; i++) {
684                         switch (transform) {
685                         default:
686                         case WL_OUTPUT_TRANSFORM_NORMAL:
687                                 dest_rects[i].x1 = src_rects[i].x1;
688                                 dest_rects[i].y1 = src_rects[i].y1;
689                                 dest_rects[i].x2 = src_rects[i].x2;
690                                 dest_rects[i].y2 = src_rects[i].y2;
691                                 break;
692                         case WL_OUTPUT_TRANSFORM_90:
693                                 dest_rects[i].x1 = height - src_rects[i].y2;
694                                 dest_rects[i].y1 = src_rects[i].x1;
695                                 dest_rects[i].x2 = height - src_rects[i].y1;
696                                 dest_rects[i].y2 = src_rects[i].x2;
697                                 break;
698                         case WL_OUTPUT_TRANSFORM_180:
699                                 dest_rects[i].x1 = width - src_rects[i].x2;
700                                 dest_rects[i].y1 = height - src_rects[i].y2;
701                                 dest_rects[i].x2 = width - src_rects[i].x1;
702                                 dest_rects[i].y2 = height - src_rects[i].y1;
703                                 break;
704                         case WL_OUTPUT_TRANSFORM_270:
705                                 dest_rects[i].x1 = src_rects[i].y1;
706                                 dest_rects[i].y1 = width - src_rects[i].x2;
707                                 dest_rects[i].x2 = src_rects[i].y2;
708                                 dest_rects[i].y2 = width - src_rects[i].x1;
709                                 break;
710                         case WL_OUTPUT_TRANSFORM_FLIPPED:
711                                 dest_rects[i].x1 = width - src_rects[i].x2;
712                                 dest_rects[i].y1 = src_rects[i].y1;
713                                 dest_rects[i].x2 = width - src_rects[i].x1;
714                                 dest_rects[i].y2 = src_rects[i].y2;
715                                 break;
716                         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
717                                 dest_rects[i].x1 = height - src_rects[i].y2;
718                                 dest_rects[i].y1 = width - src_rects[i].x2;
719                                 dest_rects[i].x2 = height - src_rects[i].y1;
720                                 dest_rects[i].y2 = width - src_rects[i].x1;
721                                 break;
722                         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
723                                 dest_rects[i].x1 = src_rects[i].x1;
724                                 dest_rects[i].y1 = height - src_rects[i].y2;
725                                 dest_rects[i].x2 = src_rects[i].x2;
726                                 dest_rects[i].y2 = height - src_rects[i].y1;
727                                 break;
728                         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
729                                 dest_rects[i].x1 = src_rects[i].y1;
730                                 dest_rects[i].y1 = src_rects[i].x1;
731                                 dest_rects[i].x2 = src_rects[i].y2;
732                                 dest_rects[i].y2 = src_rects[i].x2;
733                                 break;
734                         }
735                 }
736         }
737
738         if (scale != 1) {
739                 for (i = 0; i < nrects; i++) {
740                         dest_rects[i].x1 *= scale;
741                         dest_rects[i].x2 *= scale;
742                         dest_rects[i].y1 *= scale;
743                         dest_rects[i].y2 *= scale;
744                 }
745         }
746
747         pixman_region32_clear(dest);
748         pixman_region32_init_rects(dest, dest_rects, nrects);
749         free(dest_rects);
750 }
751
752 static void
753 viewport_surface_to_buffer(struct weston_surface *surface,
754                            float sx, float sy, float *bx, float *by)
755 {
756         struct weston_buffer_viewport *vp = &surface->buffer_viewport;
757         double src_width, src_height;
758         double src_x, src_y;
759
760         if (vp->buffer.src_width == wl_fixed_from_int(-1)) {
761                 if (vp->surface.width == -1) {
762                         *bx = sx;
763                         *by = sy;
764                         return;
765                 }
766
767                 src_x = 0.0;
768                 src_y = 0.0;
769                 src_width = surface->width_from_buffer;
770                 src_height = surface->height_from_buffer;
771         } else {
772                 src_x = wl_fixed_to_double(vp->buffer.src_x);
773                 src_y = wl_fixed_to_double(vp->buffer.src_y);
774                 src_width = wl_fixed_to_double(vp->buffer.src_width);
775                 src_height = wl_fixed_to_double(vp->buffer.src_height);
776         }
777
778         *bx = sx * src_width / surface->width + src_x;
779         *by = sy * src_height / surface->height + src_y;
780 }
781
782 WL_EXPORT void
783 weston_surface_to_buffer_float(struct weston_surface *surface,
784                                float sx, float sy, float *bx, float *by)
785 {
786         struct weston_buffer_viewport *vp = &surface->buffer_viewport;
787
788         /* first transform coordinates if the viewport is set */
789         viewport_surface_to_buffer(surface, sx, sy, bx, by);
790
791         weston_transformed_coord(surface->width_from_buffer,
792                                  surface->height_from_buffer,
793                                  vp->buffer.transform, vp->buffer.scale,
794                                  *bx, *by, bx, by);
795 }
796
797 /** Transform a rectangle from surface coordinates to buffer coordinates
798  *
799  * \param surface The surface to fetch wp_viewport and buffer transformation
800  * from.
801  * \param rect The rectangle to transform.
802  * \return The transformed rectangle.
803  *
804  * Viewport and buffer transformations can only do translation, scaling,
805  * and rotations in 90-degree steps. Therefore the only loss in the
806  * conversion is coordinate rounding.
807  *
808  * However, some coordinate rounding takes place as an intermediate
809  * step before the buffer scale factor is applied, so the rectangle
810  * boundary may not be exactly as expected.
811  *
812  * This is OK for damage tracking since a little extra coverage is
813  * not a problem.
814  */
815 WL_EXPORT pixman_box32_t
816 weston_surface_to_buffer_rect(struct weston_surface *surface,
817                               pixman_box32_t rect)
818 {
819         struct weston_buffer_viewport *vp = &surface->buffer_viewport;
820         float xf, yf;
821
822         /* first transform box coordinates if the viewport is set */
823         viewport_surface_to_buffer(surface, rect.x1, rect.y1, &xf, &yf);
824         rect.x1 = floorf(xf);
825         rect.y1 = floorf(yf);
826
827         viewport_surface_to_buffer(surface, rect.x2, rect.y2, &xf, &yf);
828         rect.x2 = ceilf(xf);
829         rect.y2 = ceilf(yf);
830
831         return weston_transformed_rect(surface->width_from_buffer,
832                                        surface->height_from_buffer,
833                                        vp->buffer.transform, vp->buffer.scale,
834                                        rect);
835 }
836
837 /** Transform a region from surface coordinates to buffer coordinates
838  *
839  * \param surface The surface to fetch wp_viewport and buffer transformation
840  * from.
841  * \param surface_region[in] The region in surface coordinates.
842  * \param buffer_region[out] The region converted to buffer coordinates.
843  *
844  * Buffer_region must be init'd, but will be completely overwritten.
845  *
846  * Viewport and buffer transformations can only do translation, scaling,
847  * and rotations in 90-degree steps. Therefore the only loss in the
848  * conversion is from the coordinate rounding that takes place in
849  * \ref weston_surface_to_buffer_rect.
850  */
851 WL_EXPORT void
852 weston_surface_to_buffer_region(struct weston_surface *surface,
853                                 pixman_region32_t *surface_region,
854                                 pixman_region32_t *buffer_region)
855 {
856         pixman_box32_t *src_rects, *dest_rects;
857         int nrects, i;
858
859         src_rects = pixman_region32_rectangles(surface_region, &nrects);
860         dest_rects = malloc(nrects * sizeof(*dest_rects));
861         if (!dest_rects)
862                 return;
863
864         for (i = 0; i < nrects; i++) {
865                 dest_rects[i] = weston_surface_to_buffer_rect(surface,
866                                                               src_rects[i]);
867         }
868
869         pixman_region32_fini(buffer_region);
870         pixman_region32_init_rects(buffer_region, dest_rects, nrects);
871         free(dest_rects);
872 }
873
874 WL_EXPORT void
875 weston_view_move_to_plane(struct weston_view *view,
876                              struct weston_plane *plane)
877 {
878         if (view->plane == plane)
879                 return;
880
881         weston_view_damage_below(view);
882         view->plane = plane;
883         weston_surface_damage(view->surface);
884 }
885
886 /** Inflict damage on the plane where the view is visible.
887  *
888  * \param view The view that causes the damage.
889  *
890  * If the view is currently on a plane (including the primary plane),
891  * take the view's boundingbox, subtract all the opaque views that cover it,
892  * and add the remaining region as damage to the plane. This corresponds
893  * to the damage inflicted to the plane if this view disappeared.
894  *
895  * A repaint is scheduled for this view.
896  *
897  * The region of all opaque views covering this view is stored in
898  * weston_view::clip and updated by view_accumulate_damage() during
899  * weston_output_repaint(). Specifically, that region matches the
900  * scenegraph as it was last painted.
901  */
902 WL_EXPORT void
903 weston_view_damage_below(struct weston_view *view)
904 {
905         pixman_region32_t damage;
906
907         pixman_region32_init(&damage);
908         pixman_region32_subtract(&damage, &view->transform.boundingbox,
909                                  &view->clip);
910         if (view->plane)
911                 pixman_region32_union(&view->plane->damage,
912                                       &view->plane->damage, &damage);
913         pixman_region32_fini(&damage);
914         weston_view_schedule_repaint(view);
915 }
916
917 /**
918  * \param es    The surface
919  * \param mask  The new set of outputs for the surface
920  *
921  * Sets the surface's set of outputs to the ones specified by
922  * the new output mask provided.  Identifies the outputs that
923  * have changed, the posts enter and leave events for these
924  * outputs as appropriate.
925  */
926 static void
927 weston_surface_update_output_mask(struct weston_surface *es, uint32_t mask)
928 {
929         uint32_t different = es->output_mask ^ mask;
930         uint32_t entered = mask & different;
931         uint32_t left = es->output_mask & different;
932         struct weston_output *output;
933         struct wl_resource *resource = NULL;
934         struct wl_client *client;
935
936         es->output_mask = mask;
937         if (es->resource == NULL)
938                 return;
939         if (different == 0)
940                 return;
941
942         client = wl_resource_get_client(es->resource);
943
944         wl_list_for_each(output, &es->compositor->output_list, link) {
945                 if (1u << output->id & different)
946                         resource =
947                                 wl_resource_find_for_client(&output->resource_list,
948                                                          client);
949                 if (resource == NULL)
950                         continue;
951                 if (1u << output->id & entered)
952                         wl_surface_send_enter(es->resource, resource);
953                 if (1u << output->id & left)
954                         wl_surface_send_leave(es->resource, resource);
955         }
956 }
957
958 /** Recalculate which output(s) the surface has views displayed on
959  *
960  * \param es  The surface to remap to outputs
961  *
962  * Finds the output that is showing the largest amount of one
963  * of the surface's various views.  This output becomes the
964  * surface's primary output for vsync and frame callback purposes.
965  *
966  * Also notes all outputs of all of the surface's views
967  * in the output_mask for the surface.
968  */
969 static void
970 weston_surface_assign_output(struct weston_surface *es)
971 {
972         struct weston_output *new_output;
973         struct weston_view *view;
974         pixman_region32_t region;
975         uint32_t max, area, mask;
976         pixman_box32_t *e;
977
978         new_output = NULL;
979         max = 0;
980         mask = 0;
981         pixman_region32_init(&region);
982         wl_list_for_each(view, &es->views, surface_link) {
983                 if (!view->output)
984                         continue;
985
986                 pixman_region32_intersect(&region, &view->transform.boundingbox,
987                                           &view->output->region);
988
989                 e = pixman_region32_extents(&region);
990                 area = (e->x2 - e->x1) * (e->y2 - e->y1);
991
992                 mask |= view->output_mask;
993
994                 if (area >= max) {
995                         new_output = view->output;
996                         max = area;
997                 }
998         }
999         pixman_region32_fini(&region);
1000
1001         es->output = new_output;
1002         weston_surface_update_output_mask(es, mask);
1003 }
1004
1005 /** Recalculate which output(s) the view is displayed on
1006  *
1007  * \param ev  The view to remap to outputs
1008  *
1009  * Identifies the set of outputs that the view is visible on,
1010  * noting them into the output_mask.  The output that the view
1011  * is most visible on is set as the view's primary output.
1012  *
1013  * Also does the same for the view's surface.  See
1014  * weston_surface_assign_output().
1015  */
1016 static void
1017 weston_view_assign_output(struct weston_view *ev)
1018 {
1019         struct weston_compositor *ec = ev->surface->compositor;
1020         struct weston_output *output, *new_output;
1021         pixman_region32_t region;
1022         uint32_t max, area, mask;
1023         pixman_box32_t *e;
1024
1025         new_output = NULL;
1026         max = 0;
1027         mask = 0;
1028         pixman_region32_init(&region);
1029         wl_list_for_each(output, &ec->output_list, link) {
1030                 if (output->destroying)
1031                         continue;
1032
1033                 pixman_region32_intersect(&region, &ev->transform.boundingbox,
1034                                           &output->region);
1035
1036                 e = pixman_region32_extents(&region);
1037                 area = (e->x2 - e->x1) * (e->y2 - e->y1);
1038
1039                 if (area > 0)
1040                         mask |= 1u << output->id;
1041
1042                 if (area >= max) {
1043                         new_output = output;
1044                         max = area;
1045                 }
1046         }
1047         pixman_region32_fini(&region);
1048
1049         ev->output = new_output;
1050         ev->output_mask = mask;
1051
1052         weston_surface_assign_output(ev->surface);
1053 }
1054
1055 static void
1056 weston_view_to_view_map(struct weston_view *from, struct weston_view *to,
1057                         int from_x, int from_y, int *to_x, int *to_y)
1058 {
1059         float x, y;
1060
1061         weston_view_to_global_float(from, from_x, from_y, &x, &y);
1062         weston_view_from_global_float(to, x, y, &x, &y);
1063
1064         *to_x = round(x);
1065         *to_y = round(y);
1066 }
1067
1068 static void
1069 weston_view_transfer_scissor(struct weston_view *from, struct weston_view *to)
1070 {
1071         pixman_box32_t *a;
1072         pixman_box32_t b;
1073
1074         a = pixman_region32_extents(&from->geometry.scissor);
1075
1076         weston_view_to_view_map(from, to, a->x1, a->y1, &b.x1, &b.y1);
1077         weston_view_to_view_map(from, to, a->x2, a->y2, &b.x2, &b.y2);
1078
1079         pixman_region32_fini(&to->geometry.scissor);
1080         pixman_region32_init_with_extents(&to->geometry.scissor, &b);
1081 }
1082
1083 static void
1084 view_compute_bbox(struct weston_view *view, const pixman_box32_t *inbox,
1085                   pixman_region32_t *bbox)
1086 {
1087         float min_x = HUGE_VALF,  min_y = HUGE_VALF;
1088         float max_x = -HUGE_VALF, max_y = -HUGE_VALF;
1089         int32_t s[4][2] = {
1090                 { inbox->x1, inbox->y1 },
1091                 { inbox->x1, inbox->y2 },
1092                 { inbox->x2, inbox->y1 },
1093                 { inbox->x2, inbox->y2 },
1094         };
1095         float int_x, int_y;
1096         int i;
1097
1098         if (inbox->x1 == inbox->x2 || inbox->y1 == inbox->y2) {
1099                 /* avoid rounding empty bbox to 1x1 */
1100                 pixman_region32_init(bbox);
1101                 return;
1102         }
1103
1104         for (i = 0; i < 4; ++i) {
1105                 float x, y;
1106                 weston_view_to_global_float(view, s[i][0], s[i][1], &x, &y);
1107                 if (x < min_x)
1108                         min_x = x;
1109                 if (x > max_x)
1110                         max_x = x;
1111                 if (y < min_y)
1112                         min_y = y;
1113                 if (y > max_y)
1114                         max_y = y;
1115         }
1116
1117         int_x = floorf(min_x);
1118         int_y = floorf(min_y);
1119         pixman_region32_init_rect(bbox, int_x, int_y,
1120                                   ceilf(max_x) - int_x, ceilf(max_y) - int_y);
1121 }
1122
1123 static void
1124 weston_view_update_transform_disable(struct weston_view *view)
1125 {
1126         view->transform.enabled = 0;
1127
1128         /* round off fractions when not transformed */
1129         view->geometry.x = roundf(view->geometry.x);
1130         view->geometry.y = roundf(view->geometry.y);
1131
1132         /* Otherwise identity matrix, but with x and y translation. */
1133         view->transform.position.matrix.type = WESTON_MATRIX_TRANSFORM_TRANSLATE;
1134         view->transform.position.matrix.d[12] = view->geometry.x;
1135         view->transform.position.matrix.d[13] = view->geometry.y;
1136
1137         view->transform.matrix = view->transform.position.matrix;
1138
1139         view->transform.inverse = view->transform.position.matrix;
1140         view->transform.inverse.d[12] = -view->geometry.x;
1141         view->transform.inverse.d[13] = -view->geometry.y;
1142
1143         pixman_region32_init_rect(&view->transform.boundingbox,
1144                                   0, 0,
1145                                   view->surface->width,
1146                                   view->surface->height);
1147         if (view->geometry.scissor_enabled)
1148                 pixman_region32_intersect(&view->transform.boundingbox,
1149                                           &view->transform.boundingbox,
1150                                           &view->geometry.scissor);
1151
1152         pixman_region32_translate(&view->transform.boundingbox,
1153                                   view->geometry.x, view->geometry.y);
1154
1155         if (view->alpha == 1.0) {
1156                 pixman_region32_copy(&view->transform.opaque,
1157                                      &view->surface->opaque);
1158                 pixman_region32_translate(&view->transform.opaque,
1159                                           view->geometry.x,
1160                                           view->geometry.y);
1161         }
1162 }
1163
1164 static int
1165 weston_view_update_transform_enable(struct weston_view *view)
1166 {
1167         struct weston_view *parent = view->geometry.parent;
1168         struct weston_matrix *matrix = &view->transform.matrix;
1169         struct weston_matrix *inverse = &view->transform.inverse;
1170         struct weston_transform *tform;
1171         pixman_region32_t surfregion;
1172         const pixman_box32_t *surfbox;
1173
1174         view->transform.enabled = 1;
1175
1176         /* Otherwise identity matrix, but with x and y translation. */
1177         view->transform.position.matrix.type = WESTON_MATRIX_TRANSFORM_TRANSLATE;
1178         view->transform.position.matrix.d[12] = view->geometry.x;
1179         view->transform.position.matrix.d[13] = view->geometry.y;
1180
1181         weston_matrix_init(matrix);
1182         wl_list_for_each(tform, &view->geometry.transformation_list, link)
1183                 weston_matrix_multiply(matrix, &tform->matrix);
1184
1185         if (parent)
1186                 weston_matrix_multiply(matrix, &parent->transform.matrix);
1187
1188         if (weston_matrix_invert(inverse, matrix) < 0) {
1189                 /* Oops, bad total transformation, not invertible */
1190                 weston_log("error: weston_view %p"
1191                         " transformation not invertible.\n", view);
1192                 return -1;
1193         }
1194
1195         pixman_region32_init_rect(&surfregion, 0, 0,
1196                                   view->surface->width, view->surface->height);
1197         if (view->geometry.scissor_enabled)
1198                 pixman_region32_intersect(&surfregion, &surfregion,
1199                                           &view->geometry.scissor);
1200         surfbox = pixman_region32_extents(&surfregion);
1201
1202         view_compute_bbox(view, surfbox, &view->transform.boundingbox);
1203         pixman_region32_fini(&surfregion);
1204
1205         return 0;
1206 }
1207
1208 static struct weston_layer *
1209 get_view_layer(struct weston_view *view)
1210 {
1211         if (view->parent_view)
1212                 return get_view_layer(view->parent_view);
1213         return view->layer_link.layer;
1214 }
1215
1216 WL_EXPORT void
1217 weston_view_update_transform(struct weston_view *view)
1218 {
1219         struct weston_view *parent = view->geometry.parent;
1220         struct weston_layer *layer;
1221         pixman_region32_t mask;
1222
1223         if (!view->transform.dirty)
1224                 return;
1225
1226         if (parent)
1227                 weston_view_update_transform(parent);
1228
1229         view->transform.dirty = 0;
1230
1231         weston_view_damage_below(view);
1232
1233         pixman_region32_fini(&view->transform.boundingbox);
1234         pixman_region32_fini(&view->transform.opaque);
1235         pixman_region32_init(&view->transform.opaque);
1236
1237         /* transform.position is always in transformation_list */
1238         if (view->geometry.transformation_list.next ==
1239             &view->transform.position.link &&
1240             view->geometry.transformation_list.prev ==
1241             &view->transform.position.link &&
1242             !parent) {
1243                 weston_view_update_transform_disable(view);
1244         } else {
1245                 if (weston_view_update_transform_enable(view) < 0)
1246                         weston_view_update_transform_disable(view);
1247         }
1248
1249         layer = get_view_layer(view);
1250         if (layer) {
1251                 pixman_region32_init_with_extents(&mask, &layer->mask);
1252                 pixman_region32_intersect(&view->transform.boundingbox,
1253                                           &view->transform.boundingbox, &mask);
1254                 pixman_region32_intersect(&view->transform.opaque,
1255                                           &view->transform.opaque, &mask);
1256                 pixman_region32_fini(&mask);
1257         }
1258
1259         if (parent) {
1260                 if (parent->geometry.scissor_enabled) {
1261                         view->geometry.scissor_enabled = true;
1262                         weston_view_transfer_scissor(parent, view);
1263                 } else {
1264                         view->geometry.scissor_enabled = false;
1265                 }
1266         }
1267
1268         weston_view_damage_below(view);
1269
1270         weston_view_assign_output(view);
1271
1272         wl_signal_emit(&view->surface->compositor->transform_signal,
1273                        view->surface);
1274 }
1275
1276 WL_EXPORT void
1277 weston_view_geometry_dirty(struct weston_view *view)
1278 {
1279         struct weston_view *child;
1280
1281         /*
1282          * The invariant: if view->geometry.dirty, then all views
1283          * in view->geometry.child_list have geometry.dirty too.
1284          * Corollary: if not parent->geometry.dirty, then all ancestors
1285          * are not dirty.
1286          */
1287
1288         if (view->transform.dirty)
1289                 return;
1290
1291         view->transform.dirty = 1;
1292
1293         wl_list_for_each(child, &view->geometry.child_list,
1294                          geometry.parent_link)
1295                 weston_view_geometry_dirty(child);
1296 }
1297
1298 WL_EXPORT void
1299 weston_view_to_global_fixed(struct weston_view *view,
1300                             wl_fixed_t vx, wl_fixed_t vy,
1301                             wl_fixed_t *x, wl_fixed_t *y)
1302 {
1303         float xf, yf;
1304
1305         weston_view_to_global_float(view,
1306                                     wl_fixed_to_double(vx),
1307                                     wl_fixed_to_double(vy),
1308                                     &xf, &yf);
1309         *x = wl_fixed_from_double(xf);
1310         *y = wl_fixed_from_double(yf);
1311 }
1312
1313 WL_EXPORT void
1314 weston_view_from_global_float(struct weston_view *view,
1315                               float x, float y, float *vx, float *vy)
1316 {
1317         if (view->transform.enabled) {
1318                 struct weston_vector v = { { x, y, 0.0f, 1.0f } };
1319
1320                 weston_matrix_transform(&view->transform.inverse, &v);
1321
1322                 if (fabsf(v.f[3]) < 1e-6) {
1323                         weston_log("warning: numerical instability in "
1324                                 "weston_view_from_global(), divisor = %g\n",
1325                                 v.f[3]);
1326                         *vx = 0;
1327                         *vy = 0;
1328                         return;
1329                 }
1330
1331                 *vx = v.f[0] / v.f[3];
1332                 *vy = v.f[1] / v.f[3];
1333         } else {
1334                 *vx = x - view->geometry.x;
1335                 *vy = y - view->geometry.y;
1336         }
1337 }
1338
1339 WL_EXPORT void
1340 weston_view_from_global_fixed(struct weston_view *view,
1341                               wl_fixed_t x, wl_fixed_t y,
1342                               wl_fixed_t *vx, wl_fixed_t *vy)
1343 {
1344         float vxf, vyf;
1345
1346         weston_view_from_global_float(view,
1347                                       wl_fixed_to_double(x),
1348                                       wl_fixed_to_double(y),
1349                                       &vxf, &vyf);
1350         *vx = wl_fixed_from_double(vxf);
1351         *vy = wl_fixed_from_double(vyf);
1352 }
1353
1354 WL_EXPORT void
1355 weston_view_from_global(struct weston_view *view,
1356                         int32_t x, int32_t y, int32_t *vx, int32_t *vy)
1357 {
1358         float vxf, vyf;
1359
1360         weston_view_from_global_float(view, x, y, &vxf, &vyf);
1361         *vx = floorf(vxf);
1362         *vy = floorf(vyf);
1363 }
1364
1365 /**
1366  * \param surface  The surface to be repainted
1367  *
1368  * Marks the output(s) that the surface is shown on as needing to be
1369  * repainted.  See weston_output_schedule_repaint().
1370  */
1371 WL_EXPORT void
1372 weston_surface_schedule_repaint(struct weston_surface *surface)
1373 {
1374         struct weston_output *output;
1375
1376         wl_list_for_each(output, &surface->compositor->output_list, link)
1377                 if (surface->output_mask & (1u << output->id))
1378                         weston_output_schedule_repaint(output);
1379 }
1380
1381 /**
1382  * \param view  The view to be repainted
1383  *
1384  * Marks the output(s) that the view is shown on as needing to be
1385  * repainted.  See weston_output_schedule_repaint().
1386  */
1387 WL_EXPORT void
1388 weston_view_schedule_repaint(struct weston_view *view)
1389 {
1390         struct weston_output *output;
1391
1392         wl_list_for_each(output, &view->surface->compositor->output_list, link)
1393                 if (view->output_mask & (1u << output->id))
1394                         weston_output_schedule_repaint(output);
1395 }
1396
1397 /**
1398  * XXX: This function does it the wrong way.
1399  * surface->damage is the damage from the client, and causes
1400  * surface_flush_damage() to copy pixels. No window management action can
1401  * cause damage to the client-provided content, warranting re-upload!
1402  *
1403  * Instead of surface->damage, this function should record the damage
1404  * with all the views for this surface to avoid extraneous texture
1405  * uploads.
1406  */
1407 WL_EXPORT void
1408 weston_surface_damage(struct weston_surface *surface)
1409 {
1410         pixman_region32_union_rect(&surface->damage, &surface->damage,
1411                                    0, 0, surface->width,
1412                                    surface->height);
1413
1414         weston_surface_schedule_repaint(surface);
1415 }
1416
1417 WL_EXPORT void
1418 weston_view_set_position(struct weston_view *view, float x, float y)
1419 {
1420         if (view->geometry.x == x && view->geometry.y == y)
1421                 return;
1422
1423         view->geometry.x = x;
1424         view->geometry.y = y;
1425         weston_view_geometry_dirty(view);
1426 }
1427
1428 static void
1429 transform_parent_handle_parent_destroy(struct wl_listener *listener,
1430                                        void *data)
1431 {
1432         struct weston_view *view =
1433                 container_of(listener, struct weston_view,
1434                              geometry.parent_destroy_listener);
1435
1436         weston_view_set_transform_parent(view, NULL);
1437 }
1438
1439 WL_EXPORT void
1440 weston_view_set_transform_parent(struct weston_view *view,
1441                                  struct weston_view *parent)
1442 {
1443         if (view->geometry.parent) {
1444                 wl_list_remove(&view->geometry.parent_destroy_listener.link);
1445                 wl_list_remove(&view->geometry.parent_link);
1446
1447                 if (!parent)
1448                         view->geometry.scissor_enabled = false;
1449         }
1450
1451         view->geometry.parent = parent;
1452
1453         view->geometry.parent_destroy_listener.notify =
1454                 transform_parent_handle_parent_destroy;
1455         if (parent) {
1456                 wl_signal_add(&parent->destroy_signal,
1457                               &view->geometry.parent_destroy_listener);
1458                 wl_list_insert(&parent->geometry.child_list,
1459                                &view->geometry.parent_link);
1460         }
1461
1462         weston_view_geometry_dirty(view);
1463 }
1464
1465 /** Set a clip mask rectangle on a view
1466  *
1467  * \param view The view to set the clip mask on.
1468  * \param x Top-left corner X coordinate of the clip rectangle.
1469  * \param y Top-left corner Y coordinate of the clip rectangle.
1470  * \param width Width of the clip rectangle, non-negative.
1471  * \param height Height of the clip rectangle, non-negative.
1472  *
1473  * A shell may set a clip mask rectangle on a view. Everything outside
1474  * the rectangle is cut away for input and output purposes: it is
1475  * not drawn and cannot be hit by hit-test based input like pointer
1476  * motion or touch-downs. Everything inside the rectangle will behave
1477  * normally. Clients are unaware of clipping.
1478  *
1479  * The rectangle is set in surface-local coordinates. Setting a clip
1480  * mask rectangle does not affect the view position, the view is positioned
1481  * as it would be without a clip. The clip also does not change
1482  * weston_surface::width,height.
1483  *
1484  * The clip mask rectangle is part of transformation inheritance
1485  * (weston_view_set_transform_parent()). A clip set in the root of the
1486  * transformation inheritance tree will affect all views in the tree.
1487  * A clip can be set only on the root view. Attempting to set a clip
1488  * on view that has a transformation parent will fail. Assigning a parent
1489  * to a view that has a clip set will cause the clip to be forgotten.
1490  *
1491  * Because the clip mask is an axis-aligned rectangle, it poses restrictions
1492  * on the additional transformations in the child views. These transformations
1493  * may not rotate the coordinate axes, i.e., only translation and scaling
1494  * are allowed. Violating this restriction causes the clipping to malfunction.
1495  * Furthermore, using scaling may cause rounding errors in child clipping.
1496  *
1497  * The clip mask rectangle is not automatically adjusted based on
1498  * wl_surface.attach dx and dy arguments.
1499  *
1500  * A clip mask rectangle can be set only if the compositor capability
1501  * WESTON_CAP_VIEW_CLIP_MASK is present.
1502  *
1503  * This function sets the clip mask rectangle and schedules a repaint for
1504  * the view.
1505  */
1506 WL_EXPORT void
1507 weston_view_set_mask(struct weston_view *view,
1508                      int x, int y, int width, int height)
1509 {
1510         struct weston_compositor *compositor = view->surface->compositor;
1511
1512         if (!(compositor->capabilities & WESTON_CAP_VIEW_CLIP_MASK)) {
1513                 weston_log("%s not allowed without capability!\n", __func__);
1514                 return;
1515         }
1516
1517         if (view->geometry.parent) {
1518                 weston_log("view %p has a parent, clip forbidden!\n", view);
1519                 return;
1520         }
1521
1522         if (width < 0 || height < 0) {
1523                 weston_log("%s: illegal args %d, %d, %d, %d\n", __func__,
1524                            x, y, width, height);
1525                 return;
1526         }
1527
1528         pixman_region32_fini(&view->geometry.scissor);
1529         pixman_region32_init_rect(&view->geometry.scissor, x, y, width, height);
1530         view->geometry.scissor_enabled = true;
1531         weston_view_geometry_dirty(view);
1532         weston_view_schedule_repaint(view);
1533 }
1534
1535 /** Remove the clip mask from a view
1536  *
1537  * \param view The view to remove the clip mask from.
1538  *
1539  * Removed the clip mask rectangle and schedules a repaint.
1540  *
1541  * \sa weston_view_set_mask
1542  */
1543 WL_EXPORT void
1544 weston_view_set_mask_infinite(struct weston_view *view)
1545 {
1546         view->geometry.scissor_enabled = false;
1547         weston_view_geometry_dirty(view);
1548         weston_view_schedule_repaint(view);
1549 }
1550
1551 /* Check if view should be displayed
1552  *
1553  * The indicator is set manually when assigning
1554  * a view to a surface.
1555  *
1556  * This needs reworking. See the thread starting at:
1557  *
1558  * https://lists.freedesktop.org/archives/wayland-devel/2016-June/029656.html
1559  */
1560 WL_EXPORT bool
1561 weston_view_is_mapped(struct weston_view *view)
1562 {
1563         return view->is_mapped;
1564 }
1565
1566 /* Check if a surface has a view assigned to it
1567  *
1568  * The indicator is set manually when mapping
1569  * a surface and creating a view for it.
1570  *
1571  * This needs to go. See the thread starting at:
1572  *
1573  * https://lists.freedesktop.org/archives/wayland-devel/2016-June/029656.html
1574  *
1575  */
1576 WL_EXPORT bool
1577 weston_surface_is_mapped(struct weston_surface *surface)
1578 {
1579         return surface->is_mapped;
1580 }
1581
1582 static void
1583 surface_set_size(struct weston_surface *surface, int32_t width, int32_t height)
1584 {
1585         struct weston_view *view;
1586
1587         if (surface->width == width && surface->height == height)
1588                 return;
1589
1590         surface->width = width;
1591         surface->height = height;
1592
1593         wl_list_for_each(view, &surface->views, surface_link)
1594                 weston_view_geometry_dirty(view);
1595 }
1596
1597 WL_EXPORT void
1598 weston_surface_set_size(struct weston_surface *surface,
1599                         int32_t width, int32_t height)
1600 {
1601         assert(!surface->resource);
1602         surface_set_size(surface, width, height);
1603 }
1604
1605 static int
1606 fixed_round_up_to_int(wl_fixed_t f)
1607 {
1608         return wl_fixed_to_int(wl_fixed_from_int(1) - 1 + f);
1609 }
1610
1611 static void
1612 convert_size_by_transform_scale(int32_t *width_out, int32_t *height_out,
1613                                 int32_t width, int32_t height,
1614                                 uint32_t transform,
1615                                 int32_t scale)
1616 {
1617         assert(scale > 0);
1618
1619         switch (transform) {
1620         case WL_OUTPUT_TRANSFORM_NORMAL:
1621         case WL_OUTPUT_TRANSFORM_180:
1622         case WL_OUTPUT_TRANSFORM_FLIPPED:
1623         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
1624                 *width_out = width / scale;
1625                 *height_out = height / scale;
1626                 break;
1627         case WL_OUTPUT_TRANSFORM_90:
1628         case WL_OUTPUT_TRANSFORM_270:
1629         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
1630         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
1631                 *width_out = height / scale;
1632                 *height_out = width / scale;
1633                 break;
1634         default:
1635                 assert(0 && "invalid transform");
1636         }
1637 }
1638
1639 static void
1640 weston_surface_calculate_size_from_buffer(struct weston_surface *surface)
1641 {
1642         struct weston_buffer_viewport *vp = &surface->buffer_viewport;
1643
1644         if (!surface->buffer_ref.buffer) {
1645                 surface->width_from_buffer = 0;
1646                 surface->height_from_buffer = 0;
1647                 return;
1648         }
1649
1650         convert_size_by_transform_scale(&surface->width_from_buffer,
1651                                         &surface->height_from_buffer,
1652                                         surface->buffer_ref.buffer->width,
1653                                         surface->buffer_ref.buffer->height,
1654                                         vp->buffer.transform,
1655                                         vp->buffer.scale);
1656 }
1657
1658 static void
1659 weston_surface_update_size(struct weston_surface *surface)
1660 {
1661         struct weston_buffer_viewport *vp = &surface->buffer_viewport;
1662         int32_t width, height;
1663
1664         width = surface->width_from_buffer;
1665         height = surface->height_from_buffer;
1666
1667         if (width != 0 && vp->surface.width != -1) {
1668                 surface_set_size(surface,
1669                                  vp->surface.width, vp->surface.height);
1670                 return;
1671         }
1672
1673         if (width != 0 && vp->buffer.src_width != wl_fixed_from_int(-1)) {
1674                 int32_t w = fixed_round_up_to_int(vp->buffer.src_width);
1675                 int32_t h = fixed_round_up_to_int(vp->buffer.src_height);
1676
1677                 surface_set_size(surface, w ?: 1, h ?: 1);
1678                 return;
1679         }
1680
1681         surface_set_size(surface, width, height);
1682 }
1683
1684 WL_EXPORT uint32_t
1685 weston_compositor_get_time(void)
1686 {
1687        struct timeval tv;
1688
1689        gettimeofday(&tv, NULL);
1690
1691        return tv.tv_sec * 1000 + tv.tv_usec / 1000;
1692 }
1693
1694 WL_EXPORT struct weston_view *
1695 weston_compositor_pick_view(struct weston_compositor *compositor,
1696                             wl_fixed_t x, wl_fixed_t y,
1697                             wl_fixed_t *vx, wl_fixed_t *vy)
1698 {
1699         struct weston_view *view;
1700         wl_fixed_t view_x, view_y;
1701         int view_ix, view_iy;
1702         int ix = wl_fixed_to_int(x);
1703         int iy = wl_fixed_to_int(y);
1704
1705         wl_list_for_each(view, &compositor->view_list, link) {
1706                 if (!pixman_region32_contains_point(
1707                                 &view->transform.boundingbox, ix, iy, NULL))
1708                         continue;
1709
1710                 weston_view_from_global_fixed(view, x, y, &view_x, &view_y);
1711                 view_ix = wl_fixed_to_int(view_x);
1712                 view_iy = wl_fixed_to_int(view_y);
1713
1714                 if (!pixman_region32_contains_point(&view->surface->input,
1715                                                     view_ix, view_iy, NULL))
1716                         continue;
1717
1718                 if (view->geometry.scissor_enabled &&
1719                     !pixman_region32_contains_point(&view->geometry.scissor,
1720                                                     view_ix, view_iy, NULL))
1721                         continue;
1722
1723                 *vx = view_x;
1724                 *vy = view_y;
1725                 return view;
1726         }
1727
1728         *vx = wl_fixed_from_int(-1000000);
1729         *vy = wl_fixed_from_int(-1000000);
1730         return NULL;
1731 }
1732
1733 static void
1734 weston_compositor_repick(struct weston_compositor *compositor)
1735 {
1736         struct weston_seat *seat;
1737
1738         if (!compositor->session_active)
1739                 return;
1740
1741         wl_list_for_each(seat, &compositor->seat_list, link)
1742                 weston_seat_repick(seat);
1743 }
1744
1745 WL_EXPORT void
1746 weston_view_unmap(struct weston_view *view)
1747 {
1748         struct weston_seat *seat;
1749
1750         if (!weston_view_is_mapped(view))
1751                 return;
1752
1753         weston_view_damage_below(view);
1754         view->output = NULL;
1755         view->plane = NULL;
1756         view->is_mapped = false;
1757         weston_layer_entry_remove(&view->layer_link);
1758         wl_list_remove(&view->link);
1759         wl_list_init(&view->link);
1760         view->output_mask = 0;
1761         weston_surface_assign_output(view->surface);
1762
1763         if (weston_surface_is_mapped(view->surface))
1764                 return;
1765
1766         wl_list_for_each(seat, &view->surface->compositor->seat_list, link) {
1767                 struct weston_touch *touch = weston_seat_get_touch(seat);
1768                 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1769                 struct weston_keyboard *keyboard =
1770                         weston_seat_get_keyboard(seat);
1771
1772                 if (keyboard && keyboard->focus == view->surface)
1773                         weston_keyboard_set_focus(keyboard, NULL);
1774                 if (pointer && pointer->focus == view)
1775                         weston_pointer_clear_focus(pointer);
1776                 if (touch && touch->focus == view)
1777                         weston_touch_set_focus(touch, NULL);
1778         }
1779 }
1780
1781 WL_EXPORT void
1782 weston_surface_unmap(struct weston_surface *surface)
1783 {
1784         struct weston_view *view;
1785
1786         surface->is_mapped = false;
1787         wl_list_for_each(view, &surface->views, surface_link)
1788                 weston_view_unmap(view);
1789         surface->output = NULL;
1790 }
1791
1792 static void
1793 weston_surface_reset_pending_buffer(struct weston_surface *surface)
1794 {
1795         weston_surface_state_set_buffer(&surface->pending, NULL);
1796         surface->pending.sx = 0;
1797         surface->pending.sy = 0;
1798         surface->pending.newly_attached = 0;
1799         surface->pending.buffer_viewport.changed = 0;
1800 }
1801
1802 WL_EXPORT void
1803 weston_view_destroy(struct weston_view *view)
1804 {
1805         wl_signal_emit(&view->destroy_signal, view);
1806
1807         assert(wl_list_empty(&view->geometry.child_list));
1808
1809         if (weston_view_is_mapped(view)) {
1810                 weston_view_unmap(view);
1811                 weston_compositor_build_view_list(view->surface->compositor);
1812         }
1813
1814         wl_list_remove(&view->link);
1815         weston_layer_entry_remove(&view->layer_link);
1816
1817         pixman_region32_fini(&view->clip);
1818         pixman_region32_fini(&view->geometry.scissor);
1819         pixman_region32_fini(&view->transform.boundingbox);
1820         pixman_region32_fini(&view->transform.opaque);
1821
1822         weston_view_set_transform_parent(view, NULL);
1823
1824         wl_list_remove(&view->surface_link);
1825
1826         free(view);
1827 }
1828
1829 WL_EXPORT void
1830 weston_surface_destroy(struct weston_surface *surface)
1831 {
1832         struct weston_frame_callback *cb, *next;
1833         struct weston_view *ev, *nv;
1834         struct weston_pointer_constraint *constraint, *next_constraint;
1835
1836         if (--surface->ref_count > 0)
1837                 return;
1838
1839         assert(surface->resource == NULL);
1840
1841         wl_signal_emit(&surface->destroy_signal, surface);
1842
1843         assert(wl_list_empty(&surface->subsurface_list_pending));
1844         assert(wl_list_empty(&surface->subsurface_list));
1845
1846         wl_list_for_each_safe(ev, nv, &surface->views, surface_link)
1847                 weston_view_destroy(ev);
1848
1849         weston_surface_state_fini(&surface->pending);
1850
1851         weston_buffer_reference(&surface->buffer_ref, NULL);
1852
1853         pixman_region32_fini(&surface->damage);
1854         pixman_region32_fini(&surface->opaque);
1855         pixman_region32_fini(&surface->input);
1856
1857         wl_list_for_each_safe(cb, next, &surface->frame_callback_list, link)
1858                 wl_resource_destroy(cb->resource);
1859
1860         weston_presentation_feedback_discard_list(&surface->feedback_list);
1861
1862         wl_list_for_each_safe(constraint, next_constraint,
1863                               &surface->pointer_constraints,
1864                               link)
1865                 weston_pointer_constraint_destroy(constraint);
1866
1867         free(surface);
1868 }
1869
1870 static void
1871 destroy_surface(struct wl_resource *resource)
1872 {
1873         struct weston_surface *surface = wl_resource_get_user_data(resource);
1874
1875         assert(surface);
1876
1877         /* Set the resource to NULL, since we don't want to leave a
1878          * dangling pointer if the surface was refcounted and survives
1879          * the weston_surface_destroy() call. */
1880         surface->resource = NULL;
1881
1882         if (surface->viewport_resource)
1883                 wl_resource_set_user_data(surface->viewport_resource, NULL);
1884
1885         weston_surface_destroy(surface);
1886 }
1887
1888 static void
1889 weston_buffer_destroy_handler(struct wl_listener *listener, void *data)
1890 {
1891         struct weston_buffer *buffer =
1892                 container_of(listener, struct weston_buffer, destroy_listener);
1893
1894         wl_signal_emit(&buffer->destroy_signal, buffer);
1895         free(buffer);
1896 }
1897
1898 WL_EXPORT struct weston_buffer *
1899 weston_buffer_from_resource(struct wl_resource *resource)
1900 {
1901         struct weston_buffer *buffer;
1902         struct wl_listener *listener;
1903
1904         listener = wl_resource_get_destroy_listener(resource,
1905                                                     weston_buffer_destroy_handler);
1906
1907         if (listener)
1908                 return container_of(listener, struct weston_buffer,
1909                                     destroy_listener);
1910
1911         buffer = zalloc(sizeof *buffer);
1912         if (buffer == NULL)
1913                 return NULL;
1914
1915         buffer->resource = resource;
1916         wl_signal_init(&buffer->destroy_signal);
1917         buffer->destroy_listener.notify = weston_buffer_destroy_handler;
1918         buffer->y_inverted = 1;
1919         wl_resource_add_destroy_listener(resource, &buffer->destroy_listener);
1920
1921         return buffer;
1922 }
1923
1924 static void
1925 weston_buffer_reference_handle_destroy(struct wl_listener *listener,
1926                                        void *data)
1927 {
1928         struct weston_buffer_reference *ref =
1929                 container_of(listener, struct weston_buffer_reference,
1930                              destroy_listener);
1931
1932         assert((struct weston_buffer *)data == ref->buffer);
1933         ref->buffer = NULL;
1934 }
1935
1936 WL_EXPORT void
1937 weston_buffer_reference(struct weston_buffer_reference *ref,
1938                         struct weston_buffer *buffer)
1939 {
1940         if (ref->buffer && buffer != ref->buffer) {
1941                 ref->buffer->busy_count--;
1942                 if (ref->buffer->busy_count == 0) {
1943                         assert(wl_resource_get_client(ref->buffer->resource));
1944                         wl_resource_queue_event(ref->buffer->resource,
1945                                                 WL_BUFFER_RELEASE);
1946                 }
1947                 wl_list_remove(&ref->destroy_listener.link);
1948         }
1949
1950         if (buffer && buffer != ref->buffer) {
1951                 buffer->busy_count++;
1952                 wl_signal_add(&buffer->destroy_signal,
1953                               &ref->destroy_listener);
1954         }
1955
1956         ref->buffer = buffer;
1957         ref->destroy_listener.notify = weston_buffer_reference_handle_destroy;
1958 }
1959
1960 static void
1961 weston_surface_attach(struct weston_surface *surface,
1962                       struct weston_buffer *buffer)
1963 {
1964         weston_buffer_reference(&surface->buffer_ref, buffer);
1965
1966         if (!buffer) {
1967                 if (weston_surface_is_mapped(surface))
1968                         weston_surface_unmap(surface);
1969         }
1970
1971         surface->compositor->renderer->attach(surface, buffer);
1972
1973         weston_surface_calculate_size_from_buffer(surface);
1974         weston_presentation_feedback_discard_list(&surface->feedback_list);
1975 }
1976
1977 WL_EXPORT void
1978 weston_compositor_damage_all(struct weston_compositor *compositor)
1979 {
1980         struct weston_output *output;
1981
1982         wl_list_for_each(output, &compositor->output_list, link)
1983                 weston_output_damage(output);
1984 }
1985
1986 WL_EXPORT void
1987 weston_output_damage(struct weston_output *output)
1988 {
1989         struct weston_compositor *compositor = output->compositor;
1990
1991         pixman_region32_union(&compositor->primary_plane.damage,
1992                               &compositor->primary_plane.damage,
1993                               &output->region);
1994         weston_output_schedule_repaint(output);
1995 }
1996
1997 static void
1998 surface_flush_damage(struct weston_surface *surface)
1999 {
2000         if (surface->buffer_ref.buffer &&
2001             wl_shm_buffer_get(surface->buffer_ref.buffer->resource))
2002                 surface->compositor->renderer->flush_damage(surface);
2003
2004         if (weston_timeline_enabled_ &&
2005             pixman_region32_not_empty(&surface->damage))
2006                 TL_POINT("core_flush_damage", TLP_SURFACE(surface),
2007                          TLP_OUTPUT(surface->output), TLP_END);
2008
2009         pixman_region32_clear(&surface->damage);
2010 }
2011
2012 static void
2013 view_accumulate_damage(struct weston_view *view,
2014                        pixman_region32_t *opaque)
2015 {
2016         pixman_region32_t damage;
2017
2018         pixman_region32_init(&damage);
2019         if (view->transform.enabled) {
2020                 pixman_box32_t *extents;
2021
2022                 extents = pixman_region32_extents(&view->surface->damage);
2023                 view_compute_bbox(view, extents, &damage);
2024         } else {
2025                 pixman_region32_copy(&damage, &view->surface->damage);
2026                 pixman_region32_translate(&damage,
2027                                           view->geometry.x, view->geometry.y);
2028         }
2029
2030         pixman_region32_intersect(&damage, &damage,
2031                                   &view->transform.boundingbox);
2032         pixman_region32_subtract(&damage, &damage, opaque);
2033         pixman_region32_union(&view->plane->damage,
2034                               &view->plane->damage, &damage);
2035         pixman_region32_fini(&damage);
2036         pixman_region32_copy(&view->clip, opaque);
2037         pixman_region32_union(opaque, opaque, &view->transform.opaque);
2038 }
2039
2040 static void
2041 compositor_accumulate_damage(struct weston_compositor *ec)
2042 {
2043         struct weston_plane *plane;
2044         struct weston_view *ev;
2045         pixman_region32_t opaque, clip;
2046
2047         pixman_region32_init(&clip);
2048
2049         wl_list_for_each(plane, &ec->plane_list, link) {
2050                 pixman_region32_copy(&plane->clip, &clip);
2051
2052                 pixman_region32_init(&opaque);
2053
2054                 wl_list_for_each(ev, &ec->view_list, link) {
2055                         if (ev->plane != plane)
2056                                 continue;
2057
2058                         view_accumulate_damage(ev, &opaque);
2059                 }
2060
2061                 pixman_region32_union(&clip, &clip, &opaque);
2062                 pixman_region32_fini(&opaque);
2063         }
2064
2065         pixman_region32_fini(&clip);
2066
2067         wl_list_for_each(ev, &ec->view_list, link)
2068                 ev->surface->touched = false;
2069
2070         wl_list_for_each(ev, &ec->view_list, link) {
2071                 if (ev->surface->touched)
2072                         continue;
2073                 ev->surface->touched = true;
2074
2075                 surface_flush_damage(ev->surface);
2076
2077                 /* Both the renderer and the backend have seen the buffer
2078                  * by now. If renderer needs the buffer, it has its own
2079                  * reference set. If the backend wants to keep the buffer
2080                  * around for migrating the surface into a non-primary plane
2081                  * later, keep_buffer is true. Otherwise, drop the core
2082                  * reference now, and allow early buffer release. This enables
2083                  * clients to use single-buffering.
2084                  */
2085                 if (!ev->surface->keep_buffer)
2086                         weston_buffer_reference(&ev->surface->buffer_ref, NULL);
2087         }
2088 }
2089
2090 static void
2091 surface_stash_subsurface_views(struct weston_surface *surface)
2092 {
2093         struct weston_subsurface *sub;
2094
2095         wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
2096                 if (sub->surface == surface)
2097                         continue;
2098
2099                 wl_list_insert_list(&sub->unused_views, &sub->surface->views);
2100                 wl_list_init(&sub->surface->views);
2101
2102                 surface_stash_subsurface_views(sub->surface);
2103         }
2104 }
2105
2106 static void
2107 surface_free_unused_subsurface_views(struct weston_surface *surface)
2108 {
2109         struct weston_subsurface *sub;
2110         struct weston_view *view, *nv;
2111
2112         wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
2113                 if (sub->surface == surface)
2114                         continue;
2115
2116                 wl_list_for_each_safe(view, nv, &sub->unused_views, surface_link) {
2117                         weston_view_unmap (view);
2118                         weston_view_destroy(view);
2119                 }
2120
2121                 surface_free_unused_subsurface_views(sub->surface);
2122         }
2123 }
2124
2125 static void
2126 view_list_add_subsurface_view(struct weston_compositor *compositor,
2127                               struct weston_subsurface *sub,
2128                               struct weston_view *parent)
2129 {
2130         struct weston_subsurface *child;
2131         struct weston_view *view = NULL, *iv;
2132
2133         if (!weston_surface_is_mapped(sub->surface))
2134                 return;
2135
2136         wl_list_for_each(iv, &sub->unused_views, surface_link) {
2137                 if (iv->geometry.parent == parent) {
2138                         view = iv;
2139                         break;
2140                 }
2141         }
2142
2143         if (view) {
2144                 /* Put it back in the surface's list of views */
2145                 wl_list_remove(&view->surface_link);
2146                 wl_list_insert(&sub->surface->views, &view->surface_link);
2147         } else {
2148                 view = weston_view_create(sub->surface);
2149                 weston_view_set_position(view,
2150                                          sub->position.x,
2151                                          sub->position.y);
2152                 weston_view_set_transform_parent(view, parent);
2153         }
2154
2155         view->parent_view = parent;
2156         weston_view_update_transform(view);
2157         view->is_mapped = true;
2158
2159         if (wl_list_empty(&sub->surface->subsurface_list)) {
2160                 wl_list_insert(compositor->view_list.prev, &view->link);
2161                 return;
2162         }
2163
2164         wl_list_for_each(child, &sub->surface->subsurface_list, parent_link) {
2165                 if (child->surface == sub->surface)
2166                         wl_list_insert(compositor->view_list.prev, &view->link);
2167                 else
2168                         view_list_add_subsurface_view(compositor, child, view);
2169         }
2170 }
2171
2172 static void
2173 view_list_add(struct weston_compositor *compositor,
2174               struct weston_view *view)
2175 {
2176         struct weston_subsurface *sub;
2177
2178         weston_view_update_transform(view);
2179
2180         if (wl_list_empty(&view->surface->subsurface_list)) {
2181                 wl_list_insert(compositor->view_list.prev, &view->link);
2182                 return;
2183         }
2184
2185         wl_list_for_each(sub, &view->surface->subsurface_list, parent_link) {
2186                 if (sub->surface == view->surface)
2187                         wl_list_insert(compositor->view_list.prev, &view->link);
2188                 else
2189                         view_list_add_subsurface_view(compositor, sub, view);
2190         }
2191 }
2192
2193 static void
2194 weston_compositor_build_view_list(struct weston_compositor *compositor)
2195 {
2196         struct weston_view *view;
2197         struct weston_layer *layer;
2198
2199         wl_list_for_each(layer, &compositor->layer_list, link)
2200                 wl_list_for_each(view, &layer->view_list.link, layer_link.link)
2201                         surface_stash_subsurface_views(view->surface);
2202
2203         wl_list_init(&compositor->view_list);
2204         wl_list_for_each(layer, &compositor->layer_list, link) {
2205                 wl_list_for_each(view, &layer->view_list.link, layer_link.link) {
2206                         view_list_add(compositor, view);
2207                 }
2208         }
2209
2210         wl_list_for_each(layer, &compositor->layer_list, link)
2211                 wl_list_for_each(view, &layer->view_list.link, layer_link.link)
2212                         surface_free_unused_subsurface_views(view->surface);
2213 }
2214
2215 static void
2216 weston_output_take_feedback_list(struct weston_output *output,
2217                                  struct weston_surface *surface)
2218 {
2219         struct weston_view *view;
2220         struct weston_presentation_feedback *feedback;
2221         uint32_t flags = 0xffffffff;
2222
2223         if (wl_list_empty(&surface->feedback_list))
2224                 return;
2225
2226         /* All views must have the flag for the flag to survive. */
2227         wl_list_for_each(view, &surface->views, surface_link) {
2228                 /* ignore views that are not on this output at all */
2229                 if (view->output_mask & (1u << output->id))
2230                         flags &= view->psf_flags;
2231         }
2232
2233         wl_list_for_each(feedback, &surface->feedback_list, link)
2234                 feedback->psf_flags = flags;
2235
2236         wl_list_insert_list(&output->feedback_list, &surface->feedback_list);
2237         wl_list_init(&surface->feedback_list);
2238 }
2239
2240 static int
2241 weston_output_repaint(struct weston_output *output)
2242 {
2243         struct weston_compositor *ec = output->compositor;
2244         struct weston_view *ev;
2245         struct weston_animation *animation, *next;
2246         struct weston_frame_callback *cb, *cnext;
2247         struct wl_list frame_callback_list;
2248         pixman_region32_t output_damage;
2249         int r;
2250
2251         if (output->destroying)
2252                 return 0;
2253
2254         TL_POINT("core_repaint_begin", TLP_OUTPUT(output), TLP_END);
2255
2256         /* Rebuild the surface list and update surface transforms up front. */
2257         weston_compositor_build_view_list(ec);
2258
2259         if (output->assign_planes && !output->disable_planes) {
2260                 output->assign_planes(output);
2261         } else {
2262                 wl_list_for_each(ev, &ec->view_list, link) {
2263                         weston_view_move_to_plane(ev, &ec->primary_plane);
2264                         ev->psf_flags = 0;
2265                 }
2266         }
2267
2268         wl_list_init(&frame_callback_list);
2269         wl_list_for_each(ev, &ec->view_list, link) {
2270                 /* Note: This operation is safe to do multiple times on the
2271                  * same surface.
2272                  */
2273                 if (ev->surface->output == output) {
2274                         wl_list_insert_list(&frame_callback_list,
2275                                             &ev->surface->frame_callback_list);
2276                         wl_list_init(&ev->surface->frame_callback_list);
2277
2278                         weston_output_take_feedback_list(output, ev->surface);
2279                 }
2280         }
2281
2282         compositor_accumulate_damage(ec);
2283
2284         pixman_region32_init(&output_damage);
2285         pixman_region32_intersect(&output_damage,
2286                                   &ec->primary_plane.damage, &output->region);
2287         pixman_region32_subtract(&output_damage,
2288                                  &output_damage, &ec->primary_plane.clip);
2289
2290         if (output->dirty)
2291                 weston_output_update_matrix(output);
2292
2293         r = output->repaint(output, &output_damage);
2294
2295         pixman_region32_fini(&output_damage);
2296
2297         output->repaint_needed = 0;
2298
2299         weston_compositor_repick(ec);
2300
2301         wl_list_for_each_safe(cb, cnext, &frame_callback_list, link) {
2302                 wl_callback_send_done(cb->resource, output->frame_time);
2303                 wl_resource_destroy(cb->resource);
2304         }
2305
2306         wl_list_for_each_safe(animation, next, &output->animation_list, link) {
2307                 animation->frame_counter++;
2308                 animation->frame(animation, output, output->frame_time);
2309         }
2310
2311         TL_POINT("core_repaint_posted", TLP_OUTPUT(output), TLP_END);
2312
2313         return r;
2314 }
2315
2316 static void
2317 weston_output_schedule_repaint_reset(struct weston_output *output)
2318 {
2319         output->repaint_scheduled = 0;
2320         TL_POINT("core_repaint_exit_loop", TLP_OUTPUT(output), TLP_END);
2321 }
2322
2323 static int
2324 output_repaint_timer_handler(void *data)
2325 {
2326         struct weston_output *output = data;
2327         struct weston_compositor *compositor = output->compositor;
2328
2329         if (output->repaint_needed &&
2330             compositor->state != WESTON_COMPOSITOR_SLEEPING &&
2331             compositor->state != WESTON_COMPOSITOR_OFFSCREEN &&
2332             weston_output_repaint(output) == 0)
2333                 return 0;
2334
2335         weston_output_schedule_repaint_reset(output);
2336
2337         return 0;
2338 }
2339
2340 WL_EXPORT void
2341 weston_output_finish_frame(struct weston_output *output,
2342                            const struct timespec *stamp,
2343                            uint32_t presented_flags)
2344 {
2345         struct weston_compositor *compositor = output->compositor;
2346         int32_t refresh_nsec;
2347         struct timespec now;
2348         struct timespec gone;
2349         int msec;
2350
2351         TL_POINT("core_repaint_finished", TLP_OUTPUT(output),
2352                  TLP_VBLANK(stamp), TLP_END);
2353
2354         refresh_nsec = millihz_to_nsec(output->current_mode->refresh);
2355         weston_presentation_feedback_present_list(&output->feedback_list,
2356                                                   output, refresh_nsec, stamp,
2357                                                   output->msc,
2358                                                   presented_flags);
2359
2360         output->frame_time = stamp->tv_sec * 1000 + stamp->tv_nsec / 1000000;
2361
2362         weston_compositor_read_presentation_clock(compositor, &now);
2363         timespec_sub(&gone, &now, stamp);
2364         msec = (refresh_nsec - timespec_to_nsec(&gone)) / 1000000; /* floor */
2365         msec -= compositor->repaint_msec;
2366
2367         if (msec < -1000 || msec > 1000) {
2368                 static bool warned;
2369
2370                 if (!warned)
2371                         weston_log("Warning: computed repaint delay is "
2372                                    "insane: %d msec\n", msec);
2373                 warned = true;
2374
2375                 msec = 0;
2376         }
2377
2378         /* Called from restart_repaint_loop and restart happens already after
2379          * the deadline given by repaint_msec? In that case we delay until
2380          * the deadline of the next frame, to give clients a more predictable
2381          * timing of the repaint cycle to lock on. */
2382         if (presented_flags == WP_PRESENTATION_FEEDBACK_INVALID && msec < 0)
2383                 msec += refresh_nsec / 1000000;
2384
2385         if (msec < 1)
2386                 output_repaint_timer_handler(output);
2387         else
2388                 wl_event_source_timer_update(output->repaint_timer, msec);
2389 }
2390
2391 static void
2392 idle_repaint(void *data)
2393 {
2394         struct weston_output *output = data;
2395
2396         output->start_repaint_loop(output);
2397 }
2398
2399 WL_EXPORT void
2400 weston_layer_entry_insert(struct weston_layer_entry *list,
2401                           struct weston_layer_entry *entry)
2402 {
2403         wl_list_insert(&list->link, &entry->link);
2404         entry->layer = list->layer;
2405 }
2406
2407 WL_EXPORT void
2408 weston_layer_entry_remove(struct weston_layer_entry *entry)
2409 {
2410         wl_list_remove(&entry->link);
2411         wl_list_init(&entry->link);
2412         entry->layer = NULL;
2413 }
2414
2415 WL_EXPORT void
2416 weston_layer_init(struct weston_layer *layer, struct wl_list *below)
2417 {
2418         wl_list_init(&layer->view_list.link);
2419         layer->view_list.layer = layer;
2420         weston_layer_set_mask_infinite(layer);
2421         if (below != NULL)
2422                 wl_list_insert(below, &layer->link);
2423 }
2424
2425 WL_EXPORT void
2426 weston_layer_set_mask(struct weston_layer *layer,
2427                       int x, int y, int width, int height)
2428 {
2429         struct weston_view *view;
2430
2431         layer->mask.x1 = x;
2432         layer->mask.x2 = x + width;
2433         layer->mask.y1 = y;
2434         layer->mask.y2 = y + height;
2435
2436         wl_list_for_each(view, &layer->view_list.link, layer_link.link) {
2437                 weston_view_geometry_dirty(view);
2438         }
2439 }
2440
2441 WL_EXPORT void
2442 weston_layer_set_mask_infinite(struct weston_layer *layer)
2443 {
2444         weston_layer_set_mask(layer, INT32_MIN, INT32_MIN,
2445                                      UINT32_MAX, UINT32_MAX);
2446 }
2447
2448 WL_EXPORT void
2449 weston_output_schedule_repaint(struct weston_output *output)
2450 {
2451         struct weston_compositor *compositor = output->compositor;
2452         struct wl_event_loop *loop;
2453
2454         if (compositor->state == WESTON_COMPOSITOR_SLEEPING ||
2455             compositor->state == WESTON_COMPOSITOR_OFFSCREEN)
2456                 return;
2457
2458         if (!output->repaint_needed)
2459                 TL_POINT("core_repaint_req", TLP_OUTPUT(output), TLP_END);
2460
2461         loop = wl_display_get_event_loop(compositor->wl_display);
2462         output->repaint_needed = 1;
2463         if (output->repaint_scheduled)
2464                 return;
2465
2466         wl_event_loop_add_idle(loop, idle_repaint, output);
2467         output->repaint_scheduled = 1;
2468         TL_POINT("core_repaint_enter_loop", TLP_OUTPUT(output), TLP_END);
2469 }
2470
2471 WL_EXPORT void
2472 weston_compositor_schedule_repaint(struct weston_compositor *compositor)
2473 {
2474         struct weston_output *output;
2475
2476         wl_list_for_each(output, &compositor->output_list, link)
2477                 weston_output_schedule_repaint(output);
2478 }
2479
2480 static void
2481 surface_destroy(struct wl_client *client, struct wl_resource *resource)
2482 {
2483         wl_resource_destroy(resource);
2484 }
2485
2486 static void
2487 surface_attach(struct wl_client *client,
2488                struct wl_resource *resource,
2489                struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
2490 {
2491         struct weston_surface *surface = wl_resource_get_user_data(resource);
2492         struct weston_buffer *buffer = NULL;
2493
2494         if (buffer_resource) {
2495                 buffer = weston_buffer_from_resource(buffer_resource);
2496                 if (buffer == NULL) {
2497                         wl_client_post_no_memory(client);
2498                         return;
2499                 }
2500         }
2501
2502         /* Attach, attach, without commit in between does not send
2503          * wl_buffer.release. */
2504         weston_surface_state_set_buffer(&surface->pending, buffer);
2505
2506         surface->pending.sx = sx;
2507         surface->pending.sy = sy;
2508         surface->pending.newly_attached = 1;
2509 }
2510
2511 static void
2512 surface_damage(struct wl_client *client,
2513                struct wl_resource *resource,
2514                int32_t x, int32_t y, int32_t width, int32_t height)
2515 {
2516         struct weston_surface *surface = wl_resource_get_user_data(resource);
2517
2518         if (width <= 0 || height <= 0)
2519                 return;
2520
2521         pixman_region32_union_rect(&surface->pending.damage_surface,
2522                                    &surface->pending.damage_surface,
2523                                    x, y, width, height);
2524 }
2525
2526 static void
2527 surface_damage_buffer(struct wl_client *client,
2528                       struct wl_resource *resource,
2529                       int32_t x, int32_t y, int32_t width, int32_t height)
2530 {
2531         struct weston_surface *surface = wl_resource_get_user_data(resource);
2532
2533         if (width <= 0 || height <= 0)
2534                 return;
2535
2536         pixman_region32_union_rect(&surface->pending.damage_buffer,
2537                                    &surface->pending.damage_buffer,
2538                                    x, y, width, height);
2539 }
2540
2541 static void
2542 destroy_frame_callback(struct wl_resource *resource)
2543 {
2544         struct weston_frame_callback *cb = wl_resource_get_user_data(resource);
2545
2546         wl_list_remove(&cb->link);
2547         free(cb);
2548 }
2549
2550 static void
2551 surface_frame(struct wl_client *client,
2552               struct wl_resource *resource, uint32_t callback)
2553 {
2554         struct weston_frame_callback *cb;
2555         struct weston_surface *surface = wl_resource_get_user_data(resource);
2556
2557         cb = malloc(sizeof *cb);
2558         if (cb == NULL) {
2559                 wl_resource_post_no_memory(resource);
2560                 return;
2561         }
2562
2563         cb->resource = wl_resource_create(client, &wl_callback_interface, 1,
2564                                           callback);
2565         if (cb->resource == NULL) {
2566                 free(cb);
2567                 wl_resource_post_no_memory(resource);
2568                 return;
2569         }
2570
2571         wl_resource_set_implementation(cb->resource, NULL, cb,
2572                                        destroy_frame_callback);
2573
2574         wl_list_insert(surface->pending.frame_callback_list.prev, &cb->link);
2575 }
2576
2577 static void
2578 surface_set_opaque_region(struct wl_client *client,
2579                           struct wl_resource *resource,
2580                           struct wl_resource *region_resource)
2581 {
2582         struct weston_surface *surface = wl_resource_get_user_data(resource);
2583         struct weston_region *region;
2584
2585         if (region_resource) {
2586                 region = wl_resource_get_user_data(region_resource);
2587                 pixman_region32_copy(&surface->pending.opaque,
2588                                      &region->region);
2589         } else {
2590                 pixman_region32_clear(&surface->pending.opaque);
2591         }
2592 }
2593
2594 static void
2595 surface_set_input_region(struct wl_client *client,
2596                          struct wl_resource *resource,
2597                          struct wl_resource *region_resource)
2598 {
2599         struct weston_surface *surface = wl_resource_get_user_data(resource);
2600         struct weston_region *region;
2601
2602         if (region_resource) {
2603                 region = wl_resource_get_user_data(region_resource);
2604                 pixman_region32_copy(&surface->pending.input,
2605                                      &region->region);
2606         } else {
2607                 pixman_region32_fini(&surface->pending.input);
2608                 region_init_infinite(&surface->pending.input);
2609         }
2610 }
2611
2612 static void
2613 weston_surface_commit_subsurface_order(struct weston_surface *surface)
2614 {
2615         struct weston_subsurface *sub;
2616
2617         wl_list_for_each_reverse(sub, &surface->subsurface_list_pending,
2618                                  parent_link_pending) {
2619                 wl_list_remove(&sub->parent_link);
2620                 wl_list_insert(&surface->subsurface_list, &sub->parent_link);
2621         }
2622 }
2623
2624 static void
2625 weston_surface_build_buffer_matrix(const struct weston_surface *surface,
2626                                    struct weston_matrix *matrix)
2627 {
2628         const struct weston_buffer_viewport *vp = &surface->buffer_viewport;
2629         double src_width, src_height, dest_width, dest_height;
2630
2631         weston_matrix_init(matrix);
2632
2633         if (vp->buffer.src_width == wl_fixed_from_int(-1)) {
2634                 src_width = surface->width_from_buffer;
2635                 src_height = surface->height_from_buffer;
2636         } else {
2637                 src_width = wl_fixed_to_double(vp->buffer.src_width);
2638                 src_height = wl_fixed_to_double(vp->buffer.src_height);
2639         }
2640
2641         if (vp->surface.width == -1) {
2642                 dest_width = src_width;
2643                 dest_height = src_height;
2644         } else {
2645                 dest_width = vp->surface.width;
2646                 dest_height = vp->surface.height;
2647         }
2648
2649         if (src_width != dest_width || src_height != dest_height)
2650                 weston_matrix_scale(matrix,
2651                                     src_width / dest_width,
2652                                     src_height / dest_height, 1);
2653
2654         if (vp->buffer.src_width != wl_fixed_from_int(-1))
2655                 weston_matrix_translate(matrix,
2656                                         wl_fixed_to_double(vp->buffer.src_x),
2657                                         wl_fixed_to_double(vp->buffer.src_y),
2658                                         0);
2659
2660         switch (vp->buffer.transform) {
2661         case WL_OUTPUT_TRANSFORM_FLIPPED:
2662         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2663         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
2664         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2665                 weston_matrix_scale(matrix, -1, 1, 1);
2666                 weston_matrix_translate(matrix,
2667                                         surface->width_from_buffer, 0, 0);
2668                 break;
2669         }
2670
2671         switch (vp->buffer.transform) {
2672         default:
2673         case WL_OUTPUT_TRANSFORM_NORMAL:
2674         case WL_OUTPUT_TRANSFORM_FLIPPED:
2675                 break;
2676         case WL_OUTPUT_TRANSFORM_90:
2677         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2678                 weston_matrix_rotate_xy(matrix, 0, 1);
2679                 weston_matrix_translate(matrix,
2680                                         surface->height_from_buffer, 0, 0);
2681                 break;
2682         case WL_OUTPUT_TRANSFORM_180:
2683         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
2684                 weston_matrix_rotate_xy(matrix, -1, 0);
2685                 weston_matrix_translate(matrix,
2686                                         surface->width_from_buffer,
2687                                         surface->height_from_buffer, 0);
2688                 break;
2689         case WL_OUTPUT_TRANSFORM_270:
2690         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2691                 weston_matrix_rotate_xy(matrix, 0, -1);
2692                 weston_matrix_translate(matrix,
2693                                         0, surface->width_from_buffer, 0);
2694                 break;
2695         }
2696
2697         weston_matrix_scale(matrix, vp->buffer.scale, vp->buffer.scale, 1);
2698 }
2699
2700 /**
2701  * Compute a + b > c while being safe to overflows.
2702  */
2703 static bool
2704 fixed_sum_gt(wl_fixed_t a, wl_fixed_t b, wl_fixed_t c)
2705 {
2706         return (int64_t)a + (int64_t)b > (int64_t)c;
2707 }
2708
2709 static bool
2710 weston_surface_is_pending_viewport_source_valid(
2711         const struct weston_surface *surface)
2712 {
2713         const struct weston_surface_state *pend = &surface->pending;
2714         const struct weston_buffer_viewport *vp = &pend->buffer_viewport;
2715         int width_from_buffer = 0;
2716         int height_from_buffer = 0;
2717         wl_fixed_t w;
2718         wl_fixed_t h;
2719
2720         /* If viewport source rect is not set, it is always ok. */
2721         if (vp->buffer.src_width == wl_fixed_from_int(-1))
2722                 return true;
2723
2724         if (pend->newly_attached) {
2725                 if (pend->buffer) {
2726                         convert_size_by_transform_scale(&width_from_buffer,
2727                                                         &height_from_buffer,
2728                                                         pend->buffer->width,
2729                                                         pend->buffer->height,
2730                                                         vp->buffer.transform,
2731                                                         vp->buffer.scale);
2732                 } else {
2733                         /* No buffer: viewport is irrelevant. */
2734                         return true;
2735                 }
2736         } else {
2737                 width_from_buffer = surface->width_from_buffer;
2738                 height_from_buffer = surface->height_from_buffer;
2739         }
2740
2741         assert((width_from_buffer == 0) == (height_from_buffer == 0));
2742         assert(width_from_buffer >= 0 && height_from_buffer >= 0);
2743
2744         /* No buffer: viewport is irrelevant. */
2745         if (width_from_buffer == 0 || height_from_buffer == 0)
2746                 return true;
2747
2748         /* overflow checks for wl_fixed_from_int() */
2749         if (width_from_buffer > wl_fixed_to_int(INT32_MAX))
2750                 return false;
2751         if (height_from_buffer > wl_fixed_to_int(INT32_MAX))
2752                 return false;
2753
2754         w = wl_fixed_from_int(width_from_buffer);
2755         h = wl_fixed_from_int(height_from_buffer);
2756
2757         if (fixed_sum_gt(vp->buffer.src_x, vp->buffer.src_width, w))
2758                 return false;
2759         if (fixed_sum_gt(vp->buffer.src_y, vp->buffer.src_height, h))
2760                 return false;
2761
2762         return true;
2763 }
2764
2765 static bool
2766 fixed_is_integer(wl_fixed_t v)
2767 {
2768         return (v & 0xff) == 0;
2769 }
2770
2771 static bool
2772 weston_surface_is_pending_viewport_dst_size_int(
2773         const struct weston_surface *surface)
2774 {
2775         const struct weston_buffer_viewport *vp =
2776                 &surface->pending.buffer_viewport;
2777
2778         if (vp->surface.width != -1) {
2779                 assert(vp->surface.width > 0 && vp->surface.height > 0);
2780                 return true;
2781         }
2782
2783         return fixed_is_integer(vp->buffer.src_width) &&
2784                fixed_is_integer(vp->buffer.src_height);
2785 }
2786
2787 /* Translate pending damage in buffer co-ordinates to surface
2788  * co-ordinates and union it with a pixman_region32_t.
2789  * This should only be called after the buffer is attached.
2790  */
2791 static void
2792 apply_damage_buffer(pixman_region32_t *dest,
2793                     struct weston_surface *surface,
2794                     struct weston_surface_state *state)
2795 {
2796         struct weston_buffer *buffer = surface->buffer_ref.buffer;
2797
2798         /* wl_surface.damage_buffer needs to be clipped to the buffer,
2799          * translated into surface co-ordinates and unioned with
2800          * any other surface damage.
2801          * None of this makes sense if there is no buffer though.
2802          */
2803         if (buffer && pixman_region32_not_empty(&state->damage_buffer)) {
2804                 pixman_region32_t buffer_damage;
2805
2806                 pixman_region32_intersect_rect(&state->damage_buffer,
2807                                                &state->damage_buffer,
2808                                                0, 0, buffer->width,
2809                                                buffer->height);
2810                 pixman_region32_init(&buffer_damage);
2811                 weston_matrix_transform_region(&buffer_damage,
2812                                                &surface->buffer_to_surface_matrix,
2813                                                &state->damage_buffer);
2814                 pixman_region32_union(dest, dest, &buffer_damage);
2815                 pixman_region32_fini(&buffer_damage);
2816         }
2817         /* We should clear this on commit even if there was no buffer */
2818         pixman_region32_clear(&state->damage_buffer);
2819 }
2820
2821 static void
2822 weston_surface_commit_state(struct weston_surface *surface,
2823                             struct weston_surface_state *state)
2824 {
2825         struct weston_view *view;
2826         pixman_region32_t opaque;
2827
2828         /* wl_surface.set_buffer_transform */
2829         /* wl_surface.set_buffer_scale */
2830         /* wp_viewport.set_source */
2831         /* wp_viewport.set_destination */
2832         surface->buffer_viewport = state->buffer_viewport;
2833
2834         /* wl_surface.attach */
2835         if (state->newly_attached)
2836                 weston_surface_attach(surface, state->buffer);
2837         weston_surface_state_set_buffer(state, NULL);
2838
2839         weston_surface_build_buffer_matrix(surface,
2840                                            &surface->surface_to_buffer_matrix);
2841         weston_matrix_invert(&surface->buffer_to_surface_matrix,
2842                              &surface->surface_to_buffer_matrix);
2843
2844         if (state->newly_attached || state->buffer_viewport.changed) {
2845                 weston_surface_update_size(surface);
2846                 if (surface->committed)
2847                         surface->committed(surface, state->sx, state->sy);
2848         }
2849
2850         state->sx = 0;
2851         state->sy = 0;
2852         state->newly_attached = 0;
2853         state->buffer_viewport.changed = 0;
2854
2855         /* wl_surface.damage and wl_surface.damage_buffer */
2856         if (weston_timeline_enabled_ &&
2857             (pixman_region32_not_empty(&state->damage_surface) ||
2858              pixman_region32_not_empty(&state->damage_buffer)))
2859                 TL_POINT("core_commit_damage", TLP_SURFACE(surface), TLP_END);
2860
2861         pixman_region32_union(&surface->damage, &surface->damage,
2862                               &state->damage_surface);
2863
2864         apply_damage_buffer(&surface->damage, surface, state);
2865
2866         pixman_region32_intersect_rect(&surface->damage, &surface->damage,
2867                                        0, 0, surface->width, surface->height);
2868         pixman_region32_clear(&state->damage_surface);
2869
2870         /* wl_surface.set_opaque_region */
2871         pixman_region32_init(&opaque);
2872         pixman_region32_intersect_rect(&opaque, &state->opaque,
2873                                        0, 0, surface->width, surface->height);
2874
2875         if (!pixman_region32_equal(&opaque, &surface->opaque)) {
2876                 pixman_region32_copy(&surface->opaque, &opaque);
2877                 wl_list_for_each(view, &surface->views, surface_link)
2878                         weston_view_geometry_dirty(view);
2879         }
2880
2881         pixman_region32_fini(&opaque);
2882
2883         /* wl_surface.set_input_region */
2884         pixman_region32_intersect_rect(&surface->input, &state->input,
2885                                        0, 0, surface->width, surface->height);
2886
2887         /* wl_surface.frame */
2888         wl_list_insert_list(&surface->frame_callback_list,
2889                             &state->frame_callback_list);
2890         wl_list_init(&state->frame_callback_list);
2891
2892         /* XXX:
2893          * What should happen with a feedback request, if there
2894          * is no wl_buffer attached for this commit?
2895          */
2896
2897         /* presentation.feedback */
2898         wl_list_insert_list(&surface->feedback_list,
2899                             &state->feedback_list);
2900         wl_list_init(&state->feedback_list);
2901
2902         wl_signal_emit(&surface->commit_signal, surface);
2903 }
2904
2905 static void
2906 weston_surface_commit(struct weston_surface *surface)
2907 {
2908         weston_surface_commit_state(surface, &surface->pending);
2909
2910         weston_surface_commit_subsurface_order(surface);
2911
2912         weston_surface_schedule_repaint(surface);
2913 }
2914
2915 static void
2916 weston_subsurface_commit(struct weston_subsurface *sub);
2917
2918 static void
2919 weston_subsurface_parent_commit(struct weston_subsurface *sub,
2920                                 int parent_is_synchronized);
2921
2922 static void
2923 surface_commit(struct wl_client *client, struct wl_resource *resource)
2924 {
2925         struct weston_surface *surface = wl_resource_get_user_data(resource);
2926         struct weston_subsurface *sub = weston_surface_to_subsurface(surface);
2927
2928         if (!weston_surface_is_pending_viewport_source_valid(surface)) {
2929                 assert(surface->viewport_resource);
2930
2931                 wl_resource_post_error(surface->viewport_resource,
2932                         WP_VIEWPORT_ERROR_OUT_OF_BUFFER,
2933                         "wl_surface@%d has viewport source outside buffer",
2934                         wl_resource_get_id(resource));
2935                 return;
2936         }
2937
2938         if (!weston_surface_is_pending_viewport_dst_size_int(surface)) {
2939                 assert(surface->viewport_resource);
2940
2941                 wl_resource_post_error(surface->viewport_resource,
2942                         WP_VIEWPORT_ERROR_BAD_SIZE,
2943                         "wl_surface@%d viewport dst size not integer",
2944                         wl_resource_get_id(resource));
2945                 return;
2946         }
2947
2948         if (sub) {
2949                 weston_subsurface_commit(sub);
2950                 return;
2951         }
2952
2953         weston_surface_commit(surface);
2954
2955         wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
2956                 if (sub->surface != surface)
2957                         weston_subsurface_parent_commit(sub, 0);
2958         }
2959 }
2960
2961 static void
2962 surface_set_buffer_transform(struct wl_client *client,
2963                              struct wl_resource *resource, int transform)
2964 {
2965         struct weston_surface *surface = wl_resource_get_user_data(resource);
2966
2967         /* if wl_output.transform grows more members this will need to be updated. */
2968         if (transform < 0 ||
2969             transform > WL_OUTPUT_TRANSFORM_FLIPPED_270) {
2970                 wl_resource_post_error(resource,
2971                         WL_SURFACE_ERROR_INVALID_TRANSFORM,
2972                         "buffer transform must be a valid transform "
2973                         "('%d' specified)", transform);
2974                 return;
2975         }
2976
2977         surface->pending.buffer_viewport.buffer.transform = transform;
2978         surface->pending.buffer_viewport.changed = 1;
2979 }
2980
2981 static void
2982 surface_set_buffer_scale(struct wl_client *client,
2983                          struct wl_resource *resource,
2984                          int32_t scale)
2985 {
2986         struct weston_surface *surface = wl_resource_get_user_data(resource);
2987
2988         if (scale < 1) {
2989                 wl_resource_post_error(resource,
2990                         WL_SURFACE_ERROR_INVALID_SCALE,
2991                         "buffer scale must be at least one "
2992                         "('%d' specified)", scale);
2993                 return;
2994         }
2995
2996         surface->pending.buffer_viewport.buffer.scale = scale;
2997         surface->pending.buffer_viewport.changed = 1;
2998 }
2999
3000 static const struct wl_surface_interface surface_interface = {
3001         surface_destroy,
3002         surface_attach,
3003         surface_damage,
3004         surface_frame,
3005         surface_set_opaque_region,
3006         surface_set_input_region,
3007         surface_commit,
3008         surface_set_buffer_transform,
3009         surface_set_buffer_scale,
3010         surface_damage_buffer
3011 };
3012
3013 static void
3014 compositor_create_surface(struct wl_client *client,
3015                           struct wl_resource *resource, uint32_t id)
3016 {
3017         struct weston_compositor *ec = wl_resource_get_user_data(resource);
3018         struct weston_surface *surface;
3019
3020         surface = weston_surface_create(ec);
3021         if (surface == NULL) {
3022                 wl_resource_post_no_memory(resource);
3023                 return;
3024         }
3025
3026         surface->resource =
3027                 wl_resource_create(client, &wl_surface_interface,
3028                                    wl_resource_get_version(resource), id);
3029         if (surface->resource == NULL) {
3030                 weston_surface_destroy(surface);
3031                 wl_resource_post_no_memory(resource);
3032                 return;
3033         }
3034         wl_resource_set_implementation(surface->resource, &surface_interface,
3035                                        surface, destroy_surface);
3036
3037         wl_signal_emit(&ec->create_surface_signal, surface);
3038 }
3039
3040 static void
3041 destroy_region(struct wl_resource *resource)
3042 {
3043         struct weston_region *region = wl_resource_get_user_data(resource);
3044
3045         pixman_region32_fini(&region->region);
3046         free(region);
3047 }
3048
3049 static void
3050 region_destroy(struct wl_client *client, struct wl_resource *resource)
3051 {
3052         wl_resource_destroy(resource);
3053 }
3054
3055 static void
3056 region_add(struct wl_client *client, struct wl_resource *resource,
3057            int32_t x, int32_t y, int32_t width, int32_t height)
3058 {
3059         struct weston_region *region = wl_resource_get_user_data(resource);
3060
3061         pixman_region32_union_rect(&region->region, &region->region,
3062                                    x, y, width, height);
3063 }
3064
3065 static void
3066 region_subtract(struct wl_client *client, struct wl_resource *resource,
3067                 int32_t x, int32_t y, int32_t width, int32_t height)
3068 {
3069         struct weston_region *region = wl_resource_get_user_data(resource);
3070         pixman_region32_t rect;
3071
3072         pixman_region32_init_rect(&rect, x, y, width, height);
3073         pixman_region32_subtract(&region->region, &region->region, &rect);
3074         pixman_region32_fini(&rect);
3075 }
3076
3077 static const struct wl_region_interface region_interface = {
3078         region_destroy,
3079         region_add,
3080         region_subtract
3081 };
3082
3083 static void
3084 compositor_create_region(struct wl_client *client,
3085                          struct wl_resource *resource, uint32_t id)
3086 {
3087         struct weston_region *region;
3088
3089         region = malloc(sizeof *region);
3090         if (region == NULL) {
3091                 wl_resource_post_no_memory(resource);
3092                 return;
3093         }
3094
3095         pixman_region32_init(&region->region);
3096
3097         region->resource =
3098                 wl_resource_create(client, &wl_region_interface, 1, id);
3099         if (region->resource == NULL) {
3100                 free(region);
3101                 wl_resource_post_no_memory(resource);
3102                 return;
3103         }
3104         wl_resource_set_implementation(region->resource, &region_interface,
3105                                        region, destroy_region);
3106 }
3107
3108 static const struct wl_compositor_interface compositor_interface = {
3109         compositor_create_surface,
3110         compositor_create_region
3111 };
3112
3113 static void
3114 weston_subsurface_commit_from_cache(struct weston_subsurface *sub)
3115 {
3116         struct weston_surface *surface = sub->surface;
3117
3118         weston_surface_commit_state(surface, &sub->cached);
3119         weston_buffer_reference(&sub->cached_buffer_ref, NULL);
3120
3121         weston_surface_commit_subsurface_order(surface);
3122
3123         weston_surface_schedule_repaint(surface);
3124
3125         sub->has_cached_data = 0;
3126 }
3127
3128 static void
3129 weston_subsurface_commit_to_cache(struct weston_subsurface *sub)
3130 {
3131         struct weston_surface *surface = sub->surface;
3132
3133         /*
3134          * If this commit would cause the surface to move by the
3135          * attach(dx, dy) parameters, the old damage region must be
3136          * translated to correspond to the new surface coordinate system
3137          * origin.
3138          */
3139         pixman_region32_translate(&sub->cached.damage_surface,
3140                                   -surface->pending.sx, -surface->pending.sy);
3141         pixman_region32_union(&sub->cached.damage_surface,
3142                               &sub->cached.damage_surface,
3143                               &surface->pending.damage_surface);
3144         pixman_region32_clear(&surface->pending.damage_surface);
3145
3146         if (surface->pending.newly_attached) {
3147                 sub->cached.newly_attached = 1;
3148                 weston_surface_state_set_buffer(&sub->cached,
3149                                                 surface->pending.buffer);
3150                 weston_buffer_reference(&sub->cached_buffer_ref,
3151                                         surface->pending.buffer);
3152                 weston_presentation_feedback_discard_list(
3153                                         &sub->cached.feedback_list);
3154         }
3155         sub->cached.sx += surface->pending.sx;
3156         sub->cached.sy += surface->pending.sy;
3157
3158         apply_damage_buffer(&sub->cached.damage_surface, surface, &surface->pending);
3159
3160         sub->cached.buffer_viewport.changed |=
3161                 surface->pending.buffer_viewport.changed;
3162         sub->cached.buffer_viewport.buffer =
3163                 surface->pending.buffer_viewport.buffer;
3164         sub->cached.buffer_viewport.surface =
3165                 surface->pending.buffer_viewport.surface;
3166
3167         weston_surface_reset_pending_buffer(surface);
3168
3169         pixman_region32_copy(&sub->cached.opaque, &surface->pending.opaque);
3170
3171         pixman_region32_copy(&sub->cached.input, &surface->pending.input);
3172
3173         wl_list_insert_list(&sub->cached.frame_callback_list,
3174                             &surface->pending.frame_callback_list);
3175         wl_list_init(&surface->pending.frame_callback_list);
3176
3177         wl_list_insert_list(&sub->cached.feedback_list,
3178                             &surface->pending.feedback_list);
3179         wl_list_init(&surface->pending.feedback_list);
3180
3181         sub->has_cached_data = 1;
3182 }
3183
3184 static bool
3185 weston_subsurface_is_synchronized(struct weston_subsurface *sub)
3186 {
3187         while (sub) {
3188                 if (sub->synchronized)
3189                         return true;
3190
3191                 if (!sub->parent)
3192                         return false;
3193
3194                 sub = weston_surface_to_subsurface(sub->parent);
3195         }
3196
3197         return false;
3198 }
3199
3200 static void
3201 weston_subsurface_commit(struct weston_subsurface *sub)
3202 {
3203         struct weston_surface *surface = sub->surface;
3204         struct weston_subsurface *tmp;
3205
3206         /* Recursive check for effectively synchronized. */
3207         if (weston_subsurface_is_synchronized(sub)) {
3208                 weston_subsurface_commit_to_cache(sub);
3209         } else {
3210                 if (sub->has_cached_data) {
3211                         /* flush accumulated state from cache */
3212                         weston_subsurface_commit_to_cache(sub);
3213                         weston_subsurface_commit_from_cache(sub);
3214                 } else {
3215                         weston_surface_commit(surface);
3216                 }
3217
3218                 wl_list_for_each(tmp, &surface->subsurface_list, parent_link) {
3219                         if (tmp->surface != surface)
3220                                 weston_subsurface_parent_commit(tmp, 0);
3221                 }
3222         }
3223 }
3224
3225 static void
3226 weston_subsurface_synchronized_commit(struct weston_subsurface *sub)
3227 {
3228         struct weston_surface *surface = sub->surface;
3229         struct weston_subsurface *tmp;
3230
3231         /* From now on, commit_from_cache the whole sub-tree, regardless of
3232          * the synchronized mode of each child. This sub-surface or some
3233          * of its ancestors were synchronized, so we are synchronized
3234          * all the way down.
3235          */
3236
3237         if (sub->has_cached_data)
3238                 weston_subsurface_commit_from_cache(sub);
3239
3240         wl_list_for_each(tmp, &surface->subsurface_list, parent_link) {
3241                 if (tmp->surface != surface)
3242                         weston_subsurface_parent_commit(tmp, 1);
3243         }
3244 }
3245
3246 static void
3247 weston_subsurface_parent_commit(struct weston_subsurface *sub,
3248                                 int parent_is_synchronized)
3249 {
3250         struct weston_view *view;
3251         if (sub->position.set) {
3252                 wl_list_for_each(view, &sub->surface->views, surface_link)
3253                         weston_view_set_position(view,
3254                                                  sub->position.x,
3255                                                  sub->position.y);
3256
3257                 sub->position.set = 0;
3258         }
3259
3260         if (parent_is_synchronized || sub->synchronized)
3261                 weston_subsurface_synchronized_commit(sub);
3262 }
3263
3264 static int
3265 subsurface_get_label(struct weston_surface *surface, char *buf, size_t len)
3266 {
3267         return snprintf(buf, len, "sub-surface");
3268 }
3269
3270 static void
3271 subsurface_committed(struct weston_surface *surface, int32_t dx, int32_t dy)
3272 {
3273         struct weston_view *view;
3274
3275         wl_list_for_each(view, &surface->views, surface_link)
3276                 weston_view_set_position(view,
3277                                          view->geometry.x + dx,
3278                                          view->geometry.y + dy);
3279
3280         /* No need to check parent mappedness, because if parent is not
3281          * mapped, parent is not in a visible layer, so this sub-surface
3282          * will not be drawn either.
3283          */
3284
3285         if (!weston_surface_is_mapped(surface)) {
3286                 surface->is_mapped = true;
3287
3288                 /* Cannot call weston_view_update_transform(),
3289                  * because that would call it also for the parent surface,
3290                  * which might not be mapped yet. That would lead to
3291                  * inconsistent state, where the window could never be
3292                  * mapped.
3293                  *
3294                  * Instead just force the is_mapped flag on, to make
3295                  * weston_surface_is_mapped() return true, so that when the
3296                  * parent surface does get mapped, this one will get
3297                  * included, too. See view_list_add().
3298                  */
3299         }
3300 }
3301
3302 static struct weston_subsurface *
3303 weston_surface_to_subsurface(struct weston_surface *surface)
3304 {
3305         if (surface->committed == subsurface_committed)
3306                 return surface->committed_private;
3307
3308         return NULL;
3309 }
3310
3311 WL_EXPORT struct weston_surface *
3312 weston_surface_get_main_surface(struct weston_surface *surface)
3313 {
3314         struct weston_subsurface *sub;
3315
3316         while (surface && (sub = weston_surface_to_subsurface(surface)))
3317                 surface = sub->parent;
3318
3319         return surface;
3320 }
3321
3322 WL_EXPORT int
3323 weston_surface_set_role(struct weston_surface *surface,
3324                         const char *role_name,
3325                         struct wl_resource *error_resource,
3326                         uint32_t error_code)
3327 {
3328         assert(role_name);
3329
3330         if (surface->role_name == NULL ||
3331             surface->role_name == role_name ||
3332             strcmp(surface->role_name, role_name) == 0) {
3333                 surface->role_name = role_name;
3334
3335                 return 0;
3336         }
3337
3338         wl_resource_post_error(error_resource, error_code,
3339                                "Cannot assign role %s to wl_surface@%d,"
3340                                " already has role %s\n",
3341                                role_name,
3342                                wl_resource_get_id(surface->resource),
3343                                surface->role_name);
3344         return -1;
3345 }
3346
3347 WL_EXPORT void
3348 weston_surface_set_label_func(struct weston_surface *surface,
3349                               int (*desc)(struct weston_surface *,
3350                                           char *, size_t))
3351 {
3352         surface->get_label = desc;
3353         surface->timeline.force_refresh = 1;
3354 }
3355
3356 /** Get the size of surface contents
3357  *
3358  * \param surface The surface to query.
3359  * \param width Returns the width of raw contents.
3360  * \param height Returns the height of raw contents.
3361  *
3362  * Retrieves the raw surface content size in pixels for the given surface.
3363  * This is the whole content size in buffer pixels. If the surface
3364  * has no content or the renderer does not implement this feature,
3365  * zeroes are returned.
3366  *
3367  * This function is used to determine the buffer size needed for
3368  * a weston_surface_copy_content() call.
3369  */
3370 WL_EXPORT void
3371 weston_surface_get_content_size(struct weston_surface *surface,
3372                                 int *width, int *height)
3373 {
3374         struct weston_renderer *rer = surface->compositor->renderer;
3375
3376         if (!rer->surface_get_content_size) {
3377                 *width = 0;
3378                 *height = 0;
3379                 return;
3380         }
3381
3382         rer->surface_get_content_size(surface, width, height);
3383 }
3384
3385 /** Copy surface contents to system memory.
3386  *
3387  * \param surface The surface to copy from.
3388  * \param target Pointer to the target memory buffer.
3389  * \param size Size of the target buffer in bytes.
3390  * \param src_x X location on contents to copy from.
3391  * \param src_y Y location on contents to copy from.
3392  * \param width Width in pixels of the area to copy.
3393  * \param height Height in pixels of the area to copy.
3394  * \return 0 for success, -1 for failure.
3395  *
3396  * Surface contents are maintained by the renderer. They can be in a
3397  * reserved weston_buffer or as a copy, e.g. a GL texture, or something
3398  * else.
3399  *
3400  * Surface contents are copied into memory pointed to by target,
3401  * which has size bytes of space available. The target memory
3402  * may be larger than needed, but being smaller returns an error.
3403  * The extra bytes in target may or may not be written; their content is
3404  * unspecified. Size must be large enough to hold the image.
3405  *
3406  * The image in the target memory will be arranged in rows from
3407  * top to bottom, and pixels on a row from left to right. The pixel
3408  * format is PIXMAN_a8b8g8r8, 4 bytes per pixel, and stride is exactly
3409  * width * 4.
3410  *
3411  * Parameters src_x and src_y define the upper-left corner in buffer
3412  * coordinates (pixels) to copy from. Parameters width and height
3413  * define the size of the area to copy in pixels.
3414  *
3415  * The rectangle defined by src_x, src_y, width, height must fit in
3416  * the surface contents. Otherwise an error is returned.
3417  *
3418  * Use surface_get_data_size to determine the content size; the
3419  * needed target buffer size and rectangle limits.
3420  *
3421  * CURRENT IMPLEMENTATION RESTRICTIONS:
3422  * - the machine must be little-endian due to Pixman formats.
3423  *
3424  * NOTE: Pixman formats are premultiplied.
3425  */
3426 WL_EXPORT int
3427 weston_surface_copy_content(struct weston_surface *surface,
3428                             void *target, size_t size,
3429                             int src_x, int src_y,
3430                             int width, int height)
3431 {
3432         struct weston_renderer *rer = surface->compositor->renderer;
3433         int cw, ch;
3434         const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
3435
3436         if (!rer->surface_copy_content)
3437                 return -1;
3438
3439         weston_surface_get_content_size(surface, &cw, &ch);
3440
3441         if (src_x < 0 || src_y < 0)
3442                 return -1;
3443
3444         if (width <= 0 || height <= 0)
3445                 return -1;
3446
3447         if (src_x + width > cw || src_y + height > ch)
3448                 return -1;
3449
3450         if (width * bytespp * height > size)
3451                 return -1;
3452
3453         return rer->surface_copy_content(surface, target, size,
3454                                          src_x, src_y, width, height);
3455 }
3456
3457 static void
3458 subsurface_set_position(struct wl_client *client,
3459                         struct wl_resource *resource, int32_t x, int32_t y)
3460 {
3461         struct weston_subsurface *sub = wl_resource_get_user_data(resource);
3462
3463         if (!sub)
3464                 return;
3465
3466         sub->position.x = x;
3467         sub->position.y = y;
3468         sub->position.set = 1;
3469 }
3470
3471 static struct weston_subsurface *
3472 subsurface_from_surface(struct weston_surface *surface)
3473 {
3474         struct weston_subsurface *sub;
3475
3476         sub = weston_surface_to_subsurface(surface);
3477         if (sub)
3478                 return sub;
3479
3480         wl_list_for_each(sub, &surface->subsurface_list, parent_link)
3481                 if (sub->surface == surface)
3482                         return sub;
3483
3484         return NULL;
3485 }
3486
3487 static struct weston_subsurface *
3488 subsurface_sibling_check(struct weston_subsurface *sub,
3489                          struct weston_surface *surface,
3490                          const char *request)
3491 {
3492         struct weston_subsurface *sibling;
3493
3494         sibling = subsurface_from_surface(surface);
3495
3496         if (!sibling) {
3497                 wl_resource_post_error(sub->resource,
3498                         WL_SUBSURFACE_ERROR_BAD_SURFACE,
3499                         "%s: wl_surface@%d is not a parent or sibling",
3500                         request, wl_resource_get_id(surface->resource));
3501                 return NULL;
3502         }
3503
3504         if (sibling->parent != sub->parent) {
3505                 wl_resource_post_error(sub->resource,
3506                         WL_SUBSURFACE_ERROR_BAD_SURFACE,
3507                         "%s: wl_surface@%d has a different parent",
3508                         request, wl_resource_get_id(surface->resource));
3509                 return NULL;
3510         }
3511
3512         return sibling;
3513 }
3514
3515 static void
3516 subsurface_place_above(struct wl_client *client,
3517                        struct wl_resource *resource,
3518                        struct wl_resource *sibling_resource)
3519 {
3520         struct weston_subsurface *sub = wl_resource_get_user_data(resource);
3521         struct weston_surface *surface =
3522                 wl_resource_get_user_data(sibling_resource);
3523         struct weston_subsurface *sibling;
3524
3525         if (!sub)
3526                 return;
3527
3528         sibling = subsurface_sibling_check(sub, surface, "place_above");
3529         if (!sibling)
3530                 return;
3531
3532         wl_list_remove(&sub->parent_link_pending);
3533         wl_list_insert(sibling->parent_link_pending.prev,
3534                        &sub->parent_link_pending);
3535 }
3536
3537 static void
3538 subsurface_place_below(struct wl_client *client,
3539                        struct wl_resource *resource,
3540                        struct wl_resource *sibling_resource)
3541 {
3542         struct weston_subsurface *sub = wl_resource_get_user_data(resource);
3543         struct weston_surface *surface =
3544                 wl_resource_get_user_data(sibling_resource);
3545         struct weston_subsurface *sibling;
3546
3547         if (!sub)
3548                 return;
3549
3550         sibling = subsurface_sibling_check(sub, surface, "place_below");
3551         if (!sibling)
3552                 return;
3553
3554         wl_list_remove(&sub->parent_link_pending);
3555         wl_list_insert(&sibling->parent_link_pending,
3556                        &sub->parent_link_pending);
3557 }
3558
3559 static void
3560 subsurface_set_sync(struct wl_client *client, struct wl_resource *resource)
3561 {
3562         struct weston_subsurface *sub = wl_resource_get_user_data(resource);
3563
3564         if (sub)
3565                 sub->synchronized = 1;
3566 }
3567
3568 static void
3569 subsurface_set_desync(struct wl_client *client, struct wl_resource *resource)
3570 {
3571         struct weston_subsurface *sub = wl_resource_get_user_data(resource);
3572
3573         if (sub && sub->synchronized) {
3574                 sub->synchronized = 0;
3575
3576                 /* If sub became effectively desynchronized, flush. */
3577                 if (!weston_subsurface_is_synchronized(sub))
3578                         weston_subsurface_synchronized_commit(sub);
3579         }
3580 }
3581
3582 static void
3583 weston_subsurface_unlink_parent(struct weston_subsurface *sub)
3584 {
3585         wl_list_remove(&sub->parent_link);
3586         wl_list_remove(&sub->parent_link_pending);
3587         wl_list_remove(&sub->parent_destroy_listener.link);
3588         sub->parent = NULL;
3589 }
3590
3591 static void
3592 weston_subsurface_destroy(struct weston_subsurface *sub);
3593
3594 static void
3595 subsurface_handle_surface_destroy(struct wl_listener *listener, void *data)
3596 {
3597         struct weston_subsurface *sub =
3598                 container_of(listener, struct weston_subsurface,
3599                              surface_destroy_listener);
3600         assert(data == sub->surface);
3601
3602         /* The protocol object (wl_resource) is left inert. */
3603         if (sub->resource)
3604                 wl_resource_set_user_data(sub->resource, NULL);
3605
3606         weston_subsurface_destroy(sub);
3607 }
3608
3609 static void
3610 subsurface_handle_parent_destroy(struct wl_listener *listener, void *data)
3611 {
3612         struct weston_subsurface *sub =
3613                 container_of(listener, struct weston_subsurface,
3614                              parent_destroy_listener);
3615         assert(data == sub->parent);
3616         assert(sub->surface != sub->parent);
3617
3618         if (weston_surface_is_mapped(sub->surface))
3619                 weston_surface_unmap(sub->surface);
3620
3621         weston_subsurface_unlink_parent(sub);
3622 }
3623
3624 static void
3625 subsurface_resource_destroy(struct wl_resource *resource)
3626 {
3627         struct weston_subsurface *sub = wl_resource_get_user_data(resource);
3628
3629         if (sub)
3630                 weston_subsurface_destroy(sub);
3631 }
3632
3633 static void
3634 subsurface_destroy(struct wl_client *client, struct wl_resource *resource)
3635 {
3636         wl_resource_destroy(resource);
3637 }
3638
3639 static void
3640 weston_subsurface_link_parent(struct weston_subsurface *sub,
3641                               struct weston_surface *parent)
3642 {
3643         sub->parent = parent;
3644         sub->parent_destroy_listener.notify = subsurface_handle_parent_destroy;
3645         wl_signal_add(&parent->destroy_signal,
3646                       &sub->parent_destroy_listener);
3647
3648         wl_list_insert(&parent->subsurface_list, &sub->parent_link);
3649         wl_list_insert(&parent->subsurface_list_pending,
3650                        &sub->parent_link_pending);
3651 }
3652
3653 static void
3654 weston_subsurface_link_surface(struct weston_subsurface *sub,
3655                                struct weston_surface *surface)
3656 {
3657         sub->surface = surface;
3658         sub->surface_destroy_listener.notify =
3659                 subsurface_handle_surface_destroy;
3660         wl_signal_add(&surface->destroy_signal,
3661                       &sub->surface_destroy_listener);
3662 }
3663
3664 static void
3665 weston_subsurface_destroy(struct weston_subsurface *sub)
3666 {
3667         struct weston_view *view, *next;
3668
3669         assert(sub->surface);
3670
3671         if (sub->resource) {
3672                 assert(weston_surface_to_subsurface(sub->surface) == sub);
3673                 assert(sub->parent_destroy_listener.notify ==
3674                        subsurface_handle_parent_destroy);
3675
3676                 wl_list_for_each_safe(view, next, &sub->surface->views, surface_link) {
3677                         weston_view_unmap(view);
3678                         weston_view_destroy(view);
3679                 }
3680
3681                 if (sub->parent)
3682                         weston_subsurface_unlink_parent(sub);
3683
3684                 weston_surface_state_fini(&sub->cached);
3685                 weston_buffer_reference(&sub->cached_buffer_ref, NULL);
3686
3687                 sub->surface->committed = NULL;
3688                 sub->surface->committed_private = NULL;
3689                 weston_surface_set_label_func(sub->surface, NULL);
3690         } else {
3691                 /* the dummy weston_subsurface for the parent itself */
3692                 assert(sub->parent_destroy_listener.notify == NULL);
3693                 wl_list_remove(&sub->parent_link);
3694                 wl_list_remove(&sub->parent_link_pending);
3695         }
3696
3697         wl_list_remove(&sub->surface_destroy_listener.link);
3698         free(sub);
3699 }
3700
3701 static const struct wl_subsurface_interface subsurface_implementation = {
3702         subsurface_destroy,
3703         subsurface_set_position,
3704         subsurface_place_above,
3705         subsurface_place_below,
3706         subsurface_set_sync,
3707         subsurface_set_desync
3708 };
3709
3710 static struct weston_subsurface *
3711 weston_subsurface_create(uint32_t id, struct weston_surface *surface,
3712                          struct weston_surface *parent)
3713 {
3714         struct weston_subsurface *sub;
3715         struct wl_client *client = wl_resource_get_client(surface->resource);
3716
3717         sub = zalloc(sizeof *sub);
3718         if (sub == NULL)
3719                 return NULL;
3720
3721         wl_list_init(&sub->unused_views);
3722
3723         sub->resource =
3724                 wl_resource_create(client, &wl_subsurface_interface, 1, id);
3725         if (!sub->resource) {
3726                 free(sub);
3727                 return NULL;
3728         }
3729
3730         wl_resource_set_implementation(sub->resource,
3731                                        &subsurface_implementation,
3732                                        sub, subsurface_resource_destroy);
3733         weston_subsurface_link_surface(sub, surface);
3734         weston_subsurface_link_parent(sub, parent);
3735         weston_surface_state_init(&sub->cached);
3736         sub->cached_buffer_ref.buffer = NULL;
3737         sub->synchronized = 1;
3738
3739         return sub;
3740 }
3741
3742 /* Create a dummy subsurface for having the parent itself in its
3743  * sub-surface lists. Makes stacking order manipulation easy.
3744  */
3745 static struct weston_subsurface *
3746 weston_subsurface_create_for_parent(struct weston_surface *parent)
3747 {
3748         struct weston_subsurface *sub;
3749
3750         sub = zalloc(sizeof *sub);
3751         if (sub == NULL)
3752                 return NULL;
3753
3754         weston_subsurface_link_surface(sub, parent);
3755         sub->parent = parent;
3756         wl_list_insert(&parent->subsurface_list, &sub->parent_link);
3757         wl_list_insert(&parent->subsurface_list_pending,
3758                        &sub->parent_link_pending);
3759
3760         return sub;
3761 }
3762
3763 static void
3764 subcompositor_get_subsurface(struct wl_client *client,
3765                              struct wl_resource *resource,
3766                              uint32_t id,
3767                              struct wl_resource *surface_resource,
3768                              struct wl_resource *parent_resource)
3769 {
3770         struct weston_surface *surface =
3771                 wl_resource_get_user_data(surface_resource);
3772         struct weston_surface *parent =
3773                 wl_resource_get_user_data(parent_resource);
3774         struct weston_subsurface *sub;
3775         static const char where[] = "get_subsurface: wl_subsurface@";
3776
3777         if (surface == parent) {
3778                 wl_resource_post_error(resource,
3779                         WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
3780                         "%s%d: wl_surface@%d cannot be its own parent",
3781                         where, id, wl_resource_get_id(surface_resource));
3782                 return;
3783         }
3784
3785         if (weston_surface_to_subsurface(surface)) {
3786                 wl_resource_post_error(resource,
3787                         WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
3788                         "%s%d: wl_surface@%d is already a sub-surface",
3789                         where, id, wl_resource_get_id(surface_resource));
3790                 return;
3791         }
3792
3793         if (weston_surface_set_role(surface, "wl_subsurface", resource,
3794                                     WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE) < 0)
3795                 return;
3796
3797         if (weston_surface_get_main_surface(parent) == surface) {
3798                 wl_resource_post_error(resource,
3799                         WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
3800                         "%s%d: wl_surface@%d is an ancestor of parent",
3801                         where, id, wl_resource_get_id(surface_resource));
3802                 return;
3803         }
3804
3805         /* make sure the parent is in its own list */
3806         if (wl_list_empty(&parent->subsurface_list)) {
3807                 if (!weston_subsurface_create_for_parent(parent)) {
3808                         wl_resource_post_no_memory(resource);
3809                         return;
3810                 }
3811         }
3812
3813         sub = weston_subsurface_create(id, surface, parent);
3814         if (!sub) {
3815                 wl_resource_post_no_memory(resource);
3816                 return;
3817         }
3818
3819         surface->committed = subsurface_committed;
3820         surface->committed_private = sub;
3821         weston_surface_set_label_func(surface, subsurface_get_label);
3822 }
3823
3824 static void
3825 subcompositor_destroy(struct wl_client *client, struct wl_resource *resource)
3826 {
3827         wl_resource_destroy(resource);
3828 }
3829
3830 static const struct wl_subcompositor_interface subcompositor_interface = {
3831         subcompositor_destroy,
3832         subcompositor_get_subsurface
3833 };
3834
3835 static void
3836 bind_subcompositor(struct wl_client *client,
3837                    void *data, uint32_t version, uint32_t id)
3838 {
3839         struct weston_compositor *compositor = data;
3840         struct wl_resource *resource;
3841
3842         resource =
3843                 wl_resource_create(client, &wl_subcompositor_interface, 1, id);
3844         if (resource == NULL) {
3845                 wl_client_post_no_memory(client);
3846                 return;
3847         }
3848         wl_resource_set_implementation(resource, &subcompositor_interface,
3849                                        compositor, NULL);
3850 }
3851
3852 /** Set a DPMS mode on all of the compositor's outputs
3853  *
3854  * \param compositor The compositor instance
3855  * \param state The DPMS state the outputs will be set to
3856  */
3857 static void
3858 weston_compositor_dpms(struct weston_compositor *compositor,
3859                        enum dpms_enum state)
3860 {
3861         struct weston_output *output;
3862
3863         wl_list_for_each(output, &compositor->output_list, link)
3864                 if (output->set_dpms)
3865                         output->set_dpms(output, state);
3866 }
3867
3868 /** Restores the compositor to active status
3869  *
3870  * \param compositor The compositor instance
3871  *
3872  * If the compositor was in a sleeping mode, all outputs are powered
3873  * back on via DPMS.  Otherwise if the compositor was inactive
3874  * (idle/locked, offscreen, or sleeping) then the compositor's wake
3875  * signal will fire.
3876  *
3877  * Restarts the idle timer.
3878  */
3879 WL_EXPORT void
3880 weston_compositor_wake(struct weston_compositor *compositor)
3881 {
3882         uint32_t old_state = compositor->state;
3883
3884         /* The state needs to be changed before emitting the wake
3885          * signal because that may try to schedule a repaint which
3886          * will not work if the compositor is still sleeping */
3887         compositor->state = WESTON_COMPOSITOR_ACTIVE;
3888
3889         switch (old_state) {
3890         case WESTON_COMPOSITOR_SLEEPING:
3891                 weston_compositor_dpms(compositor, WESTON_DPMS_ON);
3892                 /* fall through */
3893         case WESTON_COMPOSITOR_IDLE:
3894         case WESTON_COMPOSITOR_OFFSCREEN:
3895                 wl_signal_emit(&compositor->wake_signal, compositor);
3896                 /* fall through */
3897         default:
3898                 wl_event_source_timer_update(compositor->idle_source,
3899                                              compositor->idle_time * 1000);
3900         }
3901 }
3902
3903 /** Turns off rendering and frame events for the compositor.
3904  *
3905  * \param compositor The compositor instance
3906  *
3907  * This is used for example to prevent further rendering while the
3908  * compositor is shutting down.
3909  *
3910  * \note When offscreen state is entered, outputs will be powered
3911  * back on if they were sleeping (in DPMS off mode), even though
3912  * no rendering will be performed.
3913  *
3914  * Stops the idle timer.
3915  */
3916 WL_EXPORT void
3917 weston_compositor_offscreen(struct weston_compositor *compositor)
3918 {
3919         switch (compositor->state) {
3920         case WESTON_COMPOSITOR_OFFSCREEN:
3921                 return;
3922         case WESTON_COMPOSITOR_SLEEPING:
3923                 weston_compositor_dpms(compositor, WESTON_DPMS_ON);
3924                 /* fall through */
3925         default:
3926                 compositor->state = WESTON_COMPOSITOR_OFFSCREEN;
3927                 wl_event_source_timer_update(compositor->idle_source, 0);
3928         }
3929 }
3930
3931 /** Powers down all attached output devices
3932  *
3933  * \param compositor The compositor instance
3934  *
3935  * Causes rendering to the outputs to cease, and no frame events to be
3936  * sent.  Only powers down the outputs if the compositor is not already
3937  * in sleep mode.
3938  *
3939  * Stops the idle timer.
3940  */
3941 WL_EXPORT void
3942 weston_compositor_sleep(struct weston_compositor *compositor)
3943 {
3944         if (compositor->state == WESTON_COMPOSITOR_SLEEPING)
3945                 return;
3946
3947         wl_event_source_timer_update(compositor->idle_source, 0);
3948         compositor->state = WESTON_COMPOSITOR_SLEEPING;
3949         weston_compositor_dpms(compositor, WESTON_DPMS_OFF);
3950 }
3951
3952 /** Sets compositor to idle mode
3953  *
3954  * \param data The compositor instance
3955  *
3956  * This is called when the idle timer fires.  Once the compositor is in
3957  * idle mode it requires a wake action (e.g. via
3958  * weston_compositor_wake()) to restore it.  The compositor's
3959  * idle_signal will be triggered when the idle event occurs.
3960  *
3961  * Idleness can be inhibited by setting the compositor's idle_inhibit
3962  * property.
3963  */
3964 static int
3965 idle_handler(void *data)
3966 {
3967         struct weston_compositor *compositor = data;
3968
3969         if (compositor->idle_inhibit)
3970                 return 1;
3971
3972         compositor->state = WESTON_COMPOSITOR_IDLE;
3973         wl_signal_emit(&compositor->idle_signal, compositor);
3974
3975         return 1;
3976 }
3977
3978 WL_EXPORT void
3979 weston_plane_init(struct weston_plane *plane,
3980                         struct weston_compositor *ec,
3981                         int32_t x, int32_t y)
3982 {
3983         pixman_region32_init(&plane->damage);
3984         pixman_region32_init(&plane->clip);
3985         plane->x = x;
3986         plane->y = y;
3987         plane->compositor = ec;
3988
3989         /* Init the link so that the call to wl_list_remove() when releasing
3990          * the plane without ever stacking doesn't lead to a crash */
3991         wl_list_init(&plane->link);
3992 }
3993
3994 WL_EXPORT void
3995 weston_plane_release(struct weston_plane *plane)
3996 {
3997         struct weston_view *view;
3998
3999         pixman_region32_fini(&plane->damage);
4000         pixman_region32_fini(&plane->clip);
4001
4002         wl_list_for_each(view, &plane->compositor->view_list, link) {
4003                 if (view->plane == plane)
4004                         view->plane = NULL;
4005         }
4006
4007         wl_list_remove(&plane->link);
4008 }
4009
4010 WL_EXPORT void
4011 weston_compositor_stack_plane(struct weston_compositor *ec,
4012                               struct weston_plane *plane,
4013                               struct weston_plane *above)
4014 {
4015         if (above)
4016                 wl_list_insert(above->link.prev, &plane->link);
4017         else
4018                 wl_list_insert(&ec->plane_list, &plane->link);
4019 }
4020
4021 static void
4022 output_release(struct wl_client *client, struct wl_resource *resource)
4023 {
4024         wl_resource_destroy(resource);
4025 }
4026
4027 static const struct wl_output_interface output_interface = {
4028         output_release,
4029 };
4030
4031
4032 static void unbind_resource(struct wl_resource *resource)
4033 {
4034         wl_list_remove(wl_resource_get_link(resource));
4035 }
4036
4037 static void
4038 bind_output(struct wl_client *client,
4039             void *data, uint32_t version, uint32_t id)
4040 {
4041         struct weston_output *output = data;
4042         struct weston_mode *mode;
4043         struct wl_resource *resource;
4044
4045         resource = wl_resource_create(client, &wl_output_interface,
4046                                       version, id);
4047         if (resource == NULL) {
4048                 wl_client_post_no_memory(client);
4049                 return;
4050         }
4051
4052         wl_list_insert(&output->resource_list, wl_resource_get_link(resource));
4053         wl_resource_set_implementation(resource, &output_interface, data, unbind_resource);
4054
4055         wl_output_send_geometry(resource,
4056                                 output->x,
4057                                 output->y,
4058                                 output->mm_width,
4059                                 output->mm_height,
4060                                 output->subpixel,
4061                                 output->make, output->model,
4062                                 output->transform);
4063         if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
4064                 wl_output_send_scale(resource,
4065                                      output->current_scale);
4066
4067         wl_list_for_each (mode, &output->mode_list, link) {
4068                 wl_output_send_mode(resource,
4069                                     mode->flags,
4070                                     mode->width,
4071                                     mode->height,
4072                                     mode->refresh);
4073         }
4074
4075         if (version >= WL_OUTPUT_DONE_SINCE_VERSION)
4076                 wl_output_send_done(resource);
4077 }
4078
4079 /* Move other outputs when one is resized so the space remains contiguous. */
4080 static void
4081 weston_compositor_reflow_outputs(struct weston_compositor *compositor,
4082                                 struct weston_output *resized_output, int delta_width)
4083 {
4084         struct weston_output *output;
4085         bool start_resizing = false;
4086
4087         if (!delta_width)
4088                 return;
4089
4090         wl_list_for_each(output, &compositor->output_list, link) {
4091                 if (output == resized_output) {
4092                         start_resizing = true;
4093                         continue;
4094                 }
4095
4096                 if (start_resizing) {
4097                         weston_output_move(output, output->x + delta_width, output->y);
4098                         output->dirty = 1;
4099                 }
4100         }
4101 }
4102
4103 WL_EXPORT void
4104 weston_output_destroy(struct weston_output *output)
4105 {
4106         struct wl_resource *resource;
4107         struct weston_view *view;
4108
4109         output->destroying = 1;
4110
4111         wl_list_for_each(view, &output->compositor->view_list, link) {
4112                 if (view->output_mask & (1u << output->id))
4113                         weston_view_assign_output(view);
4114         }
4115
4116         wl_event_source_remove(output->repaint_timer);
4117
4118         weston_presentation_feedback_discard_list(&output->feedback_list);
4119
4120         weston_compositor_reflow_outputs(output->compositor, output, output->width);
4121         wl_list_remove(&output->link);
4122
4123         wl_signal_emit(&output->compositor->output_destroyed_signal, output);
4124         wl_signal_emit(&output->destroy_signal, output);
4125
4126         free(output->name);
4127         pixman_region32_fini(&output->region);
4128         pixman_region32_fini(&output->previous_damage);
4129         output->compositor->output_id_pool &= ~(1u << output->id);
4130
4131         wl_resource_for_each(resource, &output->resource_list) {
4132                 wl_resource_set_destructor(resource, NULL);
4133         }
4134
4135         wl_global_destroy(output->global);
4136 }
4137
4138 WL_EXPORT void
4139 weston_output_update_matrix(struct weston_output *output)
4140 {
4141         float magnification;
4142
4143         weston_matrix_init(&output->matrix);
4144         weston_matrix_translate(&output->matrix, -output->x, -output->y, 0);
4145
4146         if (output->zoom.active) {
4147                 magnification = 1 / (1 - output->zoom.spring_z.current);
4148                 weston_output_update_zoom(output);
4149                 weston_matrix_translate(&output->matrix, -output->zoom.trans_x,
4150                                         -output->zoom.trans_y, 0);
4151                 weston_matrix_scale(&output->matrix, magnification,
4152                                     magnification, 1.0);
4153         }
4154
4155         switch (output->transform) {
4156         case WL_OUTPUT_TRANSFORM_FLIPPED:
4157         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
4158         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
4159         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
4160                 weston_matrix_translate(&output->matrix, -output->width, 0, 0);
4161                 weston_matrix_scale(&output->matrix, -1, 1, 1);
4162                 break;
4163         }
4164
4165         switch (output->transform) {
4166         default:
4167         case WL_OUTPUT_TRANSFORM_NORMAL:
4168         case WL_OUTPUT_TRANSFORM_FLIPPED:
4169                 break;
4170         case WL_OUTPUT_TRANSFORM_90:
4171         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
4172                 weston_matrix_translate(&output->matrix, 0, -output->height, 0);
4173                 weston_matrix_rotate_xy(&output->matrix, 0, 1);
4174                 break;
4175         case WL_OUTPUT_TRANSFORM_180:
4176         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
4177                 weston_matrix_translate(&output->matrix,
4178                                         -output->width, -output->height, 0);
4179                 weston_matrix_rotate_xy(&output->matrix, -1, 0);
4180                 break;
4181         case WL_OUTPUT_TRANSFORM_270:
4182         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
4183                 weston_matrix_translate(&output->matrix, -output->width, 0, 0);
4184                 weston_matrix_rotate_xy(&output->matrix, 0, -1);
4185                 break;
4186         }
4187
4188         if (output->current_scale != 1)
4189                 weston_matrix_scale(&output->matrix,
4190                                     output->current_scale,
4191                                     output->current_scale, 1);
4192
4193         output->dirty = 0;
4194
4195         weston_matrix_invert(&output->inverse_matrix, &output->matrix);
4196 }
4197
4198 static void
4199 weston_output_transform_scale_init(struct weston_output *output, uint32_t transform, uint32_t scale)
4200 {
4201         output->transform = transform;
4202         output->native_scale = scale;
4203         output->current_scale = scale;
4204
4205         convert_size_by_transform_scale(&output->width, &output->height,
4206                                         output->current_mode->width,
4207                                         output->current_mode->height,
4208                                         transform, scale);
4209 }
4210
4211 static void
4212 weston_output_init_geometry(struct weston_output *output, int x, int y)
4213 {
4214         output->x = x;
4215         output->y = y;
4216
4217         pixman_region32_init(&output->previous_damage);
4218         pixman_region32_init_rect(&output->region, x, y,
4219                                   output->width,
4220                                   output->height);
4221 }
4222
4223 WL_EXPORT void
4224 weston_output_move(struct weston_output *output, int x, int y)
4225 {
4226         struct wl_resource *resource;
4227
4228         output->move_x = x - output->x;
4229         output->move_y = y - output->y;
4230
4231         if (output->move_x == 0 && output->move_y == 0)
4232                 return;
4233
4234         weston_output_init_geometry(output, x, y);
4235
4236         output->dirty = 1;
4237
4238         /* Move views on this output. */
4239         wl_signal_emit(&output->compositor->output_moved_signal, output);
4240
4241         /* Notify clients of the change for output position. */
4242         wl_resource_for_each(resource, &output->resource_list) {
4243                 wl_output_send_geometry(resource,
4244                                         output->x,
4245                                         output->y,
4246                                         output->mm_width,
4247                                         output->mm_height,
4248                                         output->subpixel,
4249                                         output->make,
4250                                         output->model,
4251                                         output->transform);
4252
4253                 if (wl_resource_get_version(resource) >= WL_OUTPUT_DONE_SINCE_VERSION)
4254                         wl_output_send_done(resource);
4255         }
4256 }
4257
4258 /** Initialize a weston_output object's parameters
4259  *
4260  * \param output     The weston_output object to initialize
4261  * \param c          The output's compositor
4262  * \param x          x coordinate for the output in global coordinate space
4263  * \param y          y coordinate for the output in global coordinate space
4264  * \param mm_width   Physical width of the output as reported by the backend
4265  * \param mm_height  Physical height of the output as reported by the backend
4266  * \param transform  Rotation of the output
4267  * \param scale      Native scaling factor for the output
4268  *
4269  * Sets up the transformation, zoom, and geometry of the output using
4270  * the input properties.
4271  *
4272  * Establishes a repaint timer for the output with the relevant display
4273  * object's event loop.  See output_repaint_timer_handler().
4274  *
4275  * The output is assigned an ID.  Weston can support up to 32 distinct
4276  * outputs, with IDs numbered from 0-31; the compositor's output_id_pool
4277  * is referred to and used to find the first available ID number, and
4278  * then this ID is marked as used in output_id_pool.
4279  *
4280  * The output is also assigned a Wayland global with the wl_output
4281  * external interface.
4282  */
4283 WL_EXPORT void
4284 weston_output_init(struct weston_output *output, struct weston_compositor *c,
4285                    int x, int y, int mm_width, int mm_height, uint32_t transform,
4286                    int32_t scale)
4287 {
4288         struct wl_event_loop *loop;
4289
4290         /* Verify we haven't reached the limit of 32 available output IDs */
4291         assert(ffs(~c->output_id_pool) > 0);
4292
4293         output->compositor = c;
4294         output->x = x;
4295         output->y = y;
4296         output->mm_width = mm_width;
4297         output->mm_height = mm_height;
4298         output->dirty = 1;
4299         output->original_scale = scale;
4300
4301         weston_output_transform_scale_init(output, transform, scale);
4302         weston_output_init_zoom(output);
4303
4304         weston_output_init_geometry(output, x, y);
4305         weston_output_damage(output);
4306
4307         wl_signal_init(&output->frame_signal);
4308         wl_signal_init(&output->destroy_signal);
4309         wl_list_init(&output->animation_list);
4310         wl_list_init(&output->resource_list);
4311         wl_list_init(&output->feedback_list);
4312         wl_list_init(&output->link);
4313
4314         loop = wl_display_get_event_loop(c->wl_display);
4315         output->repaint_timer = wl_event_loop_add_timer(loop,
4316                                         output_repaint_timer_handler, output);
4317
4318         /* Invert the output id pool and look for the lowest numbered
4319          * switch (the least significant bit).  Take that bit's position
4320          * as our ID, and mark it used in the compositor's output_id_pool.
4321          */
4322         output->id = ffs(~output->compositor->output_id_pool) - 1;
4323         output->compositor->output_id_pool |= 1u << output->id;
4324
4325         output->global =
4326                 wl_global_create(c->wl_display, &wl_output_interface, 3,
4327                                  output, bind_output);
4328 }
4329
4330 /** Adds an output to the compositor's output list and
4331  *  send the compositor's output_created signal.
4332  *
4333  * \param compositor The compositor instance.
4334  * \param output The output to be added.
4335  */
4336 WL_EXPORT void
4337 weston_compositor_add_output(struct weston_compositor *compositor,
4338                              struct weston_output *output)
4339 {
4340         struct weston_view *view, *next;
4341
4342         wl_list_insert(compositor->output_list.prev, &output->link);
4343         wl_signal_emit(&compositor->output_created_signal, output);
4344
4345         wl_list_for_each_safe(view, next, &compositor->view_list, link)
4346                 weston_view_geometry_dirty(view);
4347 }
4348
4349 WL_EXPORT void
4350 weston_output_transform_coordinate(struct weston_output *output,
4351                                    double device_x, double device_y,
4352                                    double *x, double *y)
4353 {
4354         struct weston_vector p = { {
4355                 device_x,
4356                 device_y,
4357                 0.0,
4358                 1.0 } };
4359
4360         weston_matrix_transform(&output->inverse_matrix, &p);
4361
4362         *x = p.f[0] / p.f[3];
4363         *y = p.f[1] / p.f[3];
4364 }
4365
4366 static void
4367 destroy_viewport(struct wl_resource *resource)
4368 {
4369         struct weston_surface *surface =
4370                 wl_resource_get_user_data(resource);
4371
4372         if (!surface)
4373                 return;
4374
4375         surface->viewport_resource = NULL;
4376         surface->pending.buffer_viewport.buffer.src_width =
4377                 wl_fixed_from_int(-1);
4378         surface->pending.buffer_viewport.surface.width = -1;
4379         surface->pending.buffer_viewport.changed = 1;
4380 }
4381
4382 static void
4383 viewport_destroy(struct wl_client *client,
4384                  struct wl_resource *resource)
4385 {
4386         wl_resource_destroy(resource);
4387 }
4388
4389 static void
4390 viewport_set_source(struct wl_client *client,
4391                     struct wl_resource *resource,
4392                     wl_fixed_t src_x,
4393                     wl_fixed_t src_y,
4394                     wl_fixed_t src_width,
4395                     wl_fixed_t src_height)
4396 {
4397         struct weston_surface *surface =
4398                 wl_resource_get_user_data(resource);
4399
4400         if (!surface) {
4401                 wl_resource_post_error(resource,
4402                         WP_VIEWPORT_ERROR_NO_SURFACE,
4403                         "wl_surface for this viewport is no longer exists");
4404                 return;
4405         }
4406
4407         assert(surface->viewport_resource == resource);
4408         assert(surface->resource);
4409
4410         if (src_width == wl_fixed_from_int(-1) &&
4411             src_height == wl_fixed_from_int(-1) &&
4412             src_x == wl_fixed_from_int(-1) &&
4413             src_y == wl_fixed_from_int(-1)) {
4414                 /* unset source rect */
4415                 surface->pending.buffer_viewport.buffer.src_width =
4416                         wl_fixed_from_int(-1);
4417                 surface->pending.buffer_viewport.changed = 1;
4418                 return;
4419         }
4420
4421         if (src_width <= 0 || src_height <= 0 || src_x < 0 || src_y < 0) {
4422                 wl_resource_post_error(resource,
4423                         WP_VIEWPORT_ERROR_BAD_VALUE,
4424                         "wl_surface@%d viewport source "
4425                         "w=%f <= 0, h=%f <= 0, x=%f < 0, or y=%f < 0",
4426                         wl_resource_get_id(surface->resource),
4427                         wl_fixed_to_double(src_width),
4428                         wl_fixed_to_double(src_height),
4429                         wl_fixed_to_double(src_x),
4430                         wl_fixed_to_double(src_y));
4431                 return;
4432         }
4433
4434         surface->pending.buffer_viewport.buffer.src_x = src_x;
4435         surface->pending.buffer_viewport.buffer.src_y = src_y;
4436         surface->pending.buffer_viewport.buffer.src_width = src_width;
4437         surface->pending.buffer_viewport.buffer.src_height = src_height;
4438         surface->pending.buffer_viewport.changed = 1;
4439 }
4440
4441 static void
4442 viewport_set_destination(struct wl_client *client,
4443                          struct wl_resource *resource,
4444                          int32_t dst_width,
4445                          int32_t dst_height)
4446 {
4447         struct weston_surface *surface =
4448                 wl_resource_get_user_data(resource);
4449
4450         if (!surface) {
4451                 wl_resource_post_error(resource,
4452                         WP_VIEWPORT_ERROR_NO_SURFACE,
4453                         "wl_surface for this viewport no longer exists");
4454                 return;
4455         }
4456
4457         assert(surface->viewport_resource == resource);
4458
4459         if (dst_width == -1 && dst_height == -1) {
4460                 /* unset destination size */
4461                 surface->pending.buffer_viewport.surface.width = -1;
4462                 surface->pending.buffer_viewport.changed = 1;
4463                 return;
4464         }
4465
4466         if (dst_width <= 0 || dst_height <= 0) {
4467                 wl_resource_post_error(resource,
4468                         WP_VIEWPORT_ERROR_BAD_VALUE,
4469                         "destination size must be positive (%dx%d)",
4470                         dst_width, dst_height);
4471                 return;
4472         }
4473
4474         surface->pending.buffer_viewport.surface.width = dst_width;
4475         surface->pending.buffer_viewport.surface.height = dst_height;
4476         surface->pending.buffer_viewport.changed = 1;
4477 }
4478
4479 static const struct wp_viewport_interface viewport_interface = {
4480         viewport_destroy,
4481         viewport_set_source,
4482         viewport_set_destination
4483 };
4484
4485 static void
4486 viewporter_destroy(struct wl_client *client,
4487                    struct wl_resource *resource)
4488 {
4489         wl_resource_destroy(resource);
4490 }
4491
4492 static void
4493 viewporter_get_viewport(struct wl_client *client,
4494                         struct wl_resource *viewporter,
4495                         uint32_t id,
4496                         struct wl_resource *surface_resource)
4497 {
4498         int version = wl_resource_get_version(viewporter);
4499         struct weston_surface *surface =
4500                 wl_resource_get_user_data(surface_resource);
4501         struct wl_resource *resource;
4502
4503         if (surface->viewport_resource) {
4504                 wl_resource_post_error(viewporter,
4505                         WP_VIEWPORTER_ERROR_VIEWPORT_EXISTS,
4506                         "a viewport for that surface already exists");
4507                 return;
4508         }
4509
4510         resource = wl_resource_create(client, &wp_viewport_interface,
4511                                       version, id);
4512         if (resource == NULL) {
4513                 wl_client_post_no_memory(client);
4514                 return;
4515         }
4516
4517         wl_resource_set_implementation(resource, &viewport_interface,
4518                                        surface, destroy_viewport);
4519
4520         surface->viewport_resource = resource;
4521 }
4522
4523 static const struct wp_viewporter_interface viewporter_interface = {
4524         viewporter_destroy,
4525         viewporter_get_viewport
4526 };
4527
4528 static void
4529 bind_viewporter(struct wl_client *client,
4530                 void *data, uint32_t version, uint32_t id)
4531 {
4532         struct wl_resource *resource;
4533
4534         resource = wl_resource_create(client, &wp_viewporter_interface,
4535                                       version, id);
4536         if (resource == NULL) {
4537                 wl_client_post_no_memory(client);
4538                 return;
4539         }
4540
4541         wl_resource_set_implementation(resource, &viewporter_interface,
4542                                        NULL, NULL);
4543 }
4544
4545 static void
4546 destroy_presentation_feedback(struct wl_resource *feedback_resource)
4547 {
4548         struct weston_presentation_feedback *feedback;
4549
4550         feedback = wl_resource_get_user_data(feedback_resource);
4551
4552         wl_list_remove(&feedback->link);
4553         free(feedback);
4554 }
4555
4556 static void
4557 presentation_destroy(struct wl_client *client, struct wl_resource *resource)
4558 {
4559         wl_resource_destroy(resource);
4560 }
4561
4562 static void
4563 presentation_feedback(struct wl_client *client,
4564                       struct wl_resource *presentation_resource,
4565                       struct wl_resource *surface_resource,
4566                       uint32_t callback)
4567 {
4568         struct weston_surface *surface;
4569         struct weston_presentation_feedback *feedback;
4570
4571         surface = wl_resource_get_user_data(surface_resource);
4572
4573         feedback = zalloc(sizeof *feedback);
4574         if (feedback == NULL)
4575                 goto err_calloc;
4576
4577         feedback->resource = wl_resource_create(client,
4578                                         &wp_presentation_feedback_interface,
4579                                         1, callback);
4580         if (!feedback->resource)
4581                 goto err_create;
4582
4583         wl_resource_set_implementation(feedback->resource, NULL, feedback,
4584                                        destroy_presentation_feedback);
4585
4586         wl_list_insert(&surface->pending.feedback_list, &feedback->link);
4587
4588         return;
4589
4590 err_create:
4591         free(feedback);
4592
4593 err_calloc:
4594         wl_client_post_no_memory(client);
4595 }
4596
4597 static const struct wp_presentation_interface presentation_implementation = {
4598         presentation_destroy,
4599         presentation_feedback
4600 };
4601
4602 static void
4603 bind_presentation(struct wl_client *client,
4604                   void *data, uint32_t version, uint32_t id)
4605 {
4606         struct weston_compositor *compositor = data;
4607         struct wl_resource *resource;
4608
4609         resource = wl_resource_create(client, &wp_presentation_interface,
4610                                       version, id);
4611         if (resource == NULL) {
4612                 wl_client_post_no_memory(client);
4613                 return;
4614         }
4615
4616         wl_resource_set_implementation(resource, &presentation_implementation,
4617                                        compositor, NULL);
4618         wp_presentation_send_clock_id(resource, compositor->presentation_clock);
4619 }
4620
4621 static void
4622 compositor_bind(struct wl_client *client,
4623                 void *data, uint32_t version, uint32_t id)
4624 {
4625         struct weston_compositor *compositor = data;
4626         struct wl_resource *resource;
4627
4628         resource = wl_resource_create(client, &wl_compositor_interface,
4629                                       version, id);
4630         if (resource == NULL) {
4631                 wl_client_post_no_memory(client);
4632                 return;
4633         }
4634
4635         wl_resource_set_implementation(resource, &compositor_interface,
4636                                        compositor, NULL);
4637 }
4638
4639 WL_EXPORT int
4640 weston_environment_get_fd(const char *env)
4641 {
4642         char *e;
4643         int fd, flags;
4644
4645         e = getenv(env);
4646         if (!e || !safe_strtoint(e, &fd))
4647                 return -1;
4648
4649         flags = fcntl(fd, F_GETFD);
4650         if (flags == -1)
4651                 return -1;
4652
4653         fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
4654         unsetenv(env);
4655
4656         return fd;
4657 }
4658
4659 static void
4660 timeline_key_binding_handler(struct weston_keyboard *keyboard, uint32_t time,
4661                              uint32_t key, void *data)
4662 {
4663         struct weston_compositor *compositor = data;
4664
4665         if (weston_timeline_enabled_)
4666                 weston_timeline_close();
4667         else
4668                 weston_timeline_open(compositor);
4669 }
4670
4671 /** Create the compositor.
4672  *
4673  * This functions creates and initializes a compositor instance.
4674  *
4675  * \param display The Wayland display to be used.
4676  * \param user_data A pointer to an object that can later be retrieved
4677  * using the \ref weston_compositor_get_user_data function.
4678  * \return The compositor instance on success or NULL on failure.
4679  */
4680 WL_EXPORT struct weston_compositor *
4681 weston_compositor_create(struct wl_display *display, void *user_data)
4682 {
4683         struct weston_compositor *ec;
4684         struct wl_event_loop *loop;
4685
4686         ec = zalloc(sizeof *ec);
4687         if (!ec)
4688                 return NULL;
4689
4690         ec->wl_display = display;
4691         ec->user_data = user_data;
4692         wl_signal_init(&ec->destroy_signal);
4693         wl_signal_init(&ec->create_surface_signal);
4694         wl_signal_init(&ec->activate_signal);
4695         wl_signal_init(&ec->transform_signal);
4696         wl_signal_init(&ec->kill_signal);
4697         wl_signal_init(&ec->idle_signal);
4698         wl_signal_init(&ec->wake_signal);
4699         wl_signal_init(&ec->show_input_panel_signal);
4700         wl_signal_init(&ec->hide_input_panel_signal);
4701         wl_signal_init(&ec->update_input_panel_signal);
4702         wl_signal_init(&ec->seat_created_signal);
4703         wl_signal_init(&ec->output_created_signal);
4704         wl_signal_init(&ec->output_destroyed_signal);
4705         wl_signal_init(&ec->output_moved_signal);
4706         wl_signal_init(&ec->output_resized_signal);
4707         wl_signal_init(&ec->session_signal);
4708         ec->session_active = 1;
4709
4710         ec->output_id_pool = 0;
4711         ec->repaint_msec = DEFAULT_REPAINT_WINDOW;
4712
4713         ec->activate_serial = 1;
4714
4715         if (!wl_global_create(ec->wl_display, &wl_compositor_interface, 4,
4716                               ec, compositor_bind))
4717                 goto fail;
4718
4719         if (!wl_global_create(ec->wl_display, &wl_subcompositor_interface, 1,
4720                               ec, bind_subcompositor))
4721                 goto fail;
4722
4723         if (!wl_global_create(ec->wl_display, &wp_viewporter_interface, 1,
4724                               ec, bind_viewporter))
4725                 goto fail;
4726
4727         if (!wl_global_create(ec->wl_display, &wp_presentation_interface, 1,
4728                               ec, bind_presentation))
4729                 goto fail;
4730
4731         if (weston_input_init(ec) != 0)
4732                 goto fail;
4733
4734         wl_list_init(&ec->view_list);
4735         wl_list_init(&ec->plane_list);
4736         wl_list_init(&ec->layer_list);
4737         wl_list_init(&ec->seat_list);
4738         wl_list_init(&ec->output_list);
4739         wl_list_init(&ec->key_binding_list);
4740         wl_list_init(&ec->modifier_binding_list);
4741         wl_list_init(&ec->button_binding_list);
4742         wl_list_init(&ec->touch_binding_list);
4743         wl_list_init(&ec->axis_binding_list);
4744         wl_list_init(&ec->debug_binding_list);
4745
4746         wl_list_init(&ec->plugin_api_list);
4747
4748         weston_plane_init(&ec->primary_plane, ec, 0, 0);
4749         weston_compositor_stack_plane(ec, &ec->primary_plane, NULL);
4750
4751         wl_data_device_manager_init(ec->wl_display);
4752
4753         wl_display_init_shm(ec->wl_display);
4754
4755         loop = wl_display_get_event_loop(ec->wl_display);
4756         ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
4757
4758         weston_layer_init(&ec->fade_layer, &ec->layer_list);
4759         weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
4760
4761         weston_compositor_add_debug_binding(ec, KEY_T,
4762                                             timeline_key_binding_handler, ec);
4763
4764         return ec;
4765
4766 fail:
4767         free(ec);
4768         return NULL;
4769 }
4770
4771 WL_EXPORT void
4772 weston_compositor_shutdown(struct weston_compositor *ec)
4773 {
4774         struct weston_output *output, *next;
4775
4776         wl_event_source_remove(ec->idle_source);
4777
4778         /* Destroy all outputs associated with this compositor */
4779         wl_list_for_each_safe(output, next, &ec->output_list, link)
4780                 output->destroy(output);
4781
4782         if (ec->renderer)
4783                 ec->renderer->destroy(ec);
4784
4785         weston_binding_list_destroy_all(&ec->key_binding_list);
4786         weston_binding_list_destroy_all(&ec->modifier_binding_list);
4787         weston_binding_list_destroy_all(&ec->button_binding_list);
4788         weston_binding_list_destroy_all(&ec->touch_binding_list);
4789         weston_binding_list_destroy_all(&ec->axis_binding_list);
4790         weston_binding_list_destroy_all(&ec->debug_binding_list);
4791
4792         weston_plane_release(&ec->primary_plane);
4793 }
4794
4795 WL_EXPORT void
4796 weston_compositor_exit_with_code(struct weston_compositor *compositor,
4797                                  int exit_code)
4798 {
4799         if (compositor->exit_code == EXIT_SUCCESS)
4800                 compositor->exit_code = exit_code;
4801
4802         weston_compositor_exit(compositor);
4803 }
4804
4805 WL_EXPORT void
4806 weston_compositor_set_default_pointer_grab(struct weston_compositor *ec,
4807                         const struct weston_pointer_grab_interface *interface)
4808 {
4809         struct weston_seat *seat;
4810
4811         ec->default_pointer_grab = interface;
4812         wl_list_for_each(seat, &ec->seat_list, link) {
4813                 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
4814
4815                 if (pointer)
4816                         weston_pointer_set_default_grab(pointer, interface);
4817         }
4818 }
4819
4820 WL_EXPORT int
4821 weston_compositor_set_presentation_clock(struct weston_compositor *compositor,
4822                                          clockid_t clk_id)
4823 {
4824         struct timespec ts;
4825
4826         if (clock_gettime(clk_id, &ts) < 0)
4827                 return -1;
4828
4829         compositor->presentation_clock = clk_id;
4830
4831         return 0;
4832 }
4833
4834 /*
4835  * For choosing the software clock, when the display hardware or API
4836  * does not expose a compatible presentation timestamp.
4837  */
4838 WL_EXPORT int
4839 weston_compositor_set_presentation_clock_software(
4840                                         struct weston_compositor *compositor)
4841 {
4842         /* In order of preference */
4843         static const clockid_t clocks[] = {
4844                 CLOCK_MONOTONIC_RAW,    /* no jumps, no crawling */
4845                 CLOCK_MONOTONIC_COARSE, /* no jumps, may crawl, fast & coarse */
4846                 CLOCK_MONOTONIC,        /* no jumps, may crawl */
4847                 CLOCK_REALTIME_COARSE,  /* may jump and crawl, fast & coarse */
4848                 CLOCK_REALTIME          /* may jump and crawl */
4849         };
4850         unsigned i;
4851
4852         for (i = 0; i < ARRAY_LENGTH(clocks); i++)
4853                 if (weston_compositor_set_presentation_clock(compositor,
4854                                                              clocks[i]) == 0)
4855                         return 0;
4856
4857         weston_log("Error: no suitable presentation clock available.\n");
4858
4859         return -1;
4860 }
4861
4862 /** Read the current time from the Presentation clock
4863  *
4864  * \param compositor
4865  * \param ts[out] The current time.
4866  *
4867  * \note Reading the current time in user space is always imprecise to some
4868  * degree.
4869  *
4870  * This function is never meant to fail. If reading the clock does fail,
4871  * an error message is logged and a zero time is returned. Callers are not
4872  * supposed to detect or react to failures.
4873  */
4874 WL_EXPORT void
4875 weston_compositor_read_presentation_clock(
4876                         const struct weston_compositor *compositor,
4877                         struct timespec *ts)
4878 {
4879         static bool warned;
4880         int ret;
4881
4882         ret = clock_gettime(compositor->presentation_clock, ts);
4883         if (ret < 0) {
4884                 ts->tv_sec = 0;
4885                 ts->tv_nsec = 0;
4886
4887                 if (!warned)
4888                         weston_log("Error: failure to read "
4889                                    "the presentation clock %#x: '%m' (%d)\n",
4890                                    compositor->presentation_clock, errno);
4891                 warned = true;
4892         }
4893 }
4894
4895 /** Import dmabuf buffer into current renderer
4896  *
4897  * \param compositor
4898  * \param buffer the dmabuf buffer to import
4899  * \return true on usable buffers, false otherwise
4900  *
4901  * This function tests that the linux_dmabuf_buffer is usable
4902  * for the current renderer. Returns false on unusable buffers. Usually
4903  * usability is tested by importing the dmabufs for composition.
4904  *
4905  * This hook is also used for detecting if the renderer supports
4906  * dmabufs at all. If the renderer hook is NULL, dmabufs are not
4907  * supported.
4908  * */
4909 WL_EXPORT bool
4910 weston_compositor_import_dmabuf(struct weston_compositor *compositor,
4911                                 struct linux_dmabuf_buffer *buffer)
4912 {
4913         struct weston_renderer *renderer;
4914
4915         renderer = compositor->renderer;
4916
4917         if (renderer->import_dmabuf == NULL)
4918                 return false;
4919
4920         return renderer->import_dmabuf(compositor, buffer);
4921 }
4922
4923 WL_EXPORT void
4924 weston_version(int *major, int *minor, int *micro)
4925 {
4926         *major = WESTON_VERSION_MAJOR;
4927         *minor = WESTON_VERSION_MINOR;
4928         *micro = WESTON_VERSION_MICRO;
4929 }
4930
4931 WL_EXPORT void *
4932 weston_load_module(const char *name, const char *entrypoint)
4933 {
4934         const char *builddir = getenv("WESTON_BUILD_DIR");
4935         char path[PATH_MAX];
4936         void *module, *init;
4937
4938         if (name == NULL)
4939                 return NULL;
4940
4941         if (name[0] != '/') {
4942                 if (builddir)
4943                         snprintf(path, sizeof path, "%s/.libs/%s", builddir, name);
4944                 else
4945                         snprintf(path, sizeof path, "%s/%s", LIBWESTON_MODULEDIR, name);
4946         } else {
4947                 snprintf(path, sizeof path, "%s", name);
4948         }
4949
4950         module = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
4951         if (module) {
4952                 weston_log("Module '%s' already loaded\n", path);
4953                 dlclose(module);
4954                 return NULL;
4955         }
4956
4957         weston_log("Loading module '%s'\n", path);
4958         module = dlopen(path, RTLD_NOW);
4959         if (!module) {
4960                 weston_log("Failed to load module: %s\n", dlerror());
4961                 return NULL;
4962         }
4963
4964         init = dlsym(module, entrypoint);
4965         if (!init) {
4966                 weston_log("Failed to lookup init function: %s\n", dlerror());
4967                 dlclose(module);
4968                 return NULL;
4969         }
4970
4971         return init;
4972 }
4973
4974
4975 /** Destroys the compositor.
4976  *
4977  * This function cleans up the compositor state and destroys it.
4978  *
4979  * \param compositor The compositor to be destroyed.
4980  */
4981 WL_EXPORT void
4982 weston_compositor_destroy(struct weston_compositor *compositor)
4983 {
4984         /* prevent further rendering while shutting down */
4985         compositor->state = WESTON_COMPOSITOR_OFFSCREEN;
4986
4987         wl_signal_emit(&compositor->destroy_signal, compositor);
4988
4989         weston_compositor_xkb_destroy(compositor);
4990
4991         if (compositor->backend)
4992                 compositor->backend->destroy(compositor);
4993
4994         weston_plugin_api_destroy_list(compositor);
4995
4996         free(compositor);
4997 }
4998
4999 /** Instruct the compositor to exit.
5000  *
5001  * This functions does not directly destroy the compositor object, it merely
5002  * command it to start the tear down process. It is not guaranteed that the
5003  * tear down will happen immediately.
5004  *
5005  * \param compositor The compositor to tear down.
5006  */
5007 WL_EXPORT void
5008 weston_compositor_exit(struct weston_compositor *compositor)
5009 {
5010         compositor->exit(compositor);
5011 }
5012
5013 /** Return the user data stored in the compositor.
5014  *
5015  * This function returns the user data pointer set with user_data parameter
5016  * to the \ref weston_compositor_create function.
5017  */
5018 WL_EXPORT void *
5019 weston_compositor_get_user_data(struct weston_compositor *compositor)
5020 {
5021         return compositor->user_data;
5022 }
5023
5024 static const char * const backend_map[] = {
5025         [WESTON_BACKEND_DRM] =          "drm-backend.so",
5026         [WESTON_BACKEND_FBDEV] =        "fbdev-backend.so",
5027         [WESTON_BACKEND_HEADLESS] =     "headless-backend.so",
5028         [WESTON_BACKEND_RDP] =          "rdp-backend.so",
5029         [WESTON_BACKEND_WAYLAND] =      "wayland-backend.so",
5030         [WESTON_BACKEND_X11] =          "x11-backend.so",
5031 };
5032
5033 /** Load a backend into a weston_compositor
5034  *
5035  * A backend must be loaded to make a weston_compositor work. A backend
5036  * provides input and output capabilities, and determines the renderer to use.
5037  *
5038  * \param compositor A compositor that has not had a backend loaded yet.
5039  * \param backend Name of the backend file.
5040  * \param config_base A pointer to a backend-specific configuration
5041  * structure's 'base' member.
5042  *
5043  * \return 0 on success, or -1 on error.
5044  */
5045 WL_EXPORT int
5046 weston_compositor_load_backend(struct weston_compositor *compositor,
5047                                enum weston_compositor_backend backend,
5048                                struct weston_backend_config *config_base)
5049 {
5050         int (*backend_init)(struct weston_compositor *c,
5051                             struct weston_backend_config *config_base);
5052
5053         if (backend < 0 || backend >= ARRAY_LENGTH(backend_map))
5054                 return -1;
5055
5056         backend_init = weston_load_module(backend_map[backend], "backend_init");
5057         if (!backend_init)
5058                 return -1;
5059
5060         return backend_init(compositor, config_base);
5061 }
5062
5063 WL_EXPORT int
5064 weston_compositor_load_xwayland(struct weston_compositor *compositor)
5065 {
5066         int (*module_init)(struct weston_compositor *ec,
5067                            int *argc, char *argv[]);
5068         int argc = 0;
5069
5070         module_init = weston_load_module("xwayland.so", "module_init");
5071         if (!module_init)
5072                 return -1;
5073         if (module_init(compositor, &argc, NULL) < 0)
5074                 return -1;
5075         return 0;
5076 }