compositor: Move gl-renderer vertex arrays into gl-renderer.c
[platform/upstream/weston.git] / src / compositor.c
1 /*
2  * Copyright © 2010-2011 Intel Corporation
3  * Copyright © 2008-2011 Kristian Høgsberg
4  * Copyright © 2012 Collabora, Ltd.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and
7  * its documentation for any purpose is hereby granted without fee, provided
8  * that the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of the copyright holders not be used in
11  * advertising or publicity pertaining to distribution of the software
12  * without specific, written prior permission.  The copyright holders make
13  * no representations about the suitability of this software for any
14  * purpose.  It is provided "as is" without express or implied warranty.
15  *
16  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
17  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
20  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
21  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23  */
24
25 #define _GNU_SOURCE
26
27 #include "config.h"
28
29 #include <fcntl.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <stdint.h>
34 #include <limits.h>
35 #include <stdarg.h>
36 #include <assert.h>
37 #include <sys/ioctl.h>
38 #include <sys/mman.h>
39 #include <sys/wait.h>
40 #include <sys/socket.h>
41 #include <sys/utsname.h>
42 #include <sys/stat.h>
43 #include <unistd.h>
44 #include <math.h>
45 #include <linux/input.h>
46 #include <dlfcn.h>
47 #include <signal.h>
48 #include <setjmp.h>
49 #include <sys/time.h>
50 #include <time.h>
51
52 #ifdef HAVE_LIBUNWIND
53 #define UNW_LOCAL_ONLY
54 #include <libunwind.h>
55 #endif
56
57 #include <wayland-server.h>
58 #include "compositor.h"
59 #include "../shared/os-compatibility.h"
60 #include "git-version.h"
61 #include "version.h"
62
63 static struct wl_list child_process_list;
64 static struct weston_compositor *segv_compositor;
65
66 static int
67 sigchld_handler(int signal_number, void *data)
68 {
69         struct weston_process *p;
70         int status;
71         pid_t pid;
72
73         pid = waitpid(-1, &status, WNOHANG);
74         if (!pid)
75                 return 1;
76
77         wl_list_for_each(p, &child_process_list, link) {
78                 if (p->pid == pid)
79                         break;
80         }
81
82         if (&p->link == &child_process_list) {
83                 weston_log("unknown child process exited\n");
84                 return 1;
85         }
86
87         wl_list_remove(&p->link);
88         p->cleanup(p, status);
89
90         return 1;
91 }
92
93 static void
94 weston_output_transform_init(struct weston_output *output, uint32_t transform);
95
96 WL_EXPORT int
97 weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode)
98 {
99         struct weston_seat *seat;
100         pixman_region32_t old_output_region;
101         int ret;
102
103         if (!output->switch_mode)
104                 return -1;
105
106         ret = output->switch_mode(output, mode);
107         if (ret < 0)
108                 return ret;
109
110         pixman_region32_init(&old_output_region);
111         pixman_region32_copy(&old_output_region, &output->region);
112
113         /* Update output region and transformation matrix */
114         weston_output_transform_init(output, output->transform);
115
116         pixman_region32_init(&output->previous_damage);
117         pixman_region32_init_rect(&output->region, output->x, output->y,
118                                   output->width, output->height);
119
120         weston_output_update_matrix(output);
121
122         /* If a pointer falls outside the outputs new geometry, move it to its
123          * lower-right corner */
124         wl_list_for_each(seat, &output->compositor->seat_list, link) {
125                 struct weston_pointer *pointer = seat->pointer;
126                 int32_t x, y;
127
128                 if (!pointer)
129                         continue;
130
131                 x = wl_fixed_to_int(pointer->x);
132                 y = wl_fixed_to_int(pointer->y);
133
134                 if (!pixman_region32_contains_point(&old_output_region,
135                                                     x, y, NULL) ||
136                     pixman_region32_contains_point(&output->region,
137                                                    x, y, NULL))
138                         continue;
139
140                 if (x >= output->x + output->width)
141                         x = output->x + output->width - 1;
142                 if (y >= output->y + output->height)
143                         y = output->y + output->height - 1;
144
145                 pointer->x = wl_fixed_from_int(x);
146                 pointer->y = wl_fixed_from_int(y);
147         }
148
149         pixman_region32_fini(&old_output_region);
150
151         return ret;
152 }
153
154 WL_EXPORT void
155 weston_watch_process(struct weston_process *process)
156 {
157         wl_list_insert(&child_process_list, &process->link);
158 }
159
160 static void
161 child_client_exec(int sockfd, const char *path)
162 {
163         int clientfd;
164         char s[32];
165         sigset_t allsigs;
166
167         /* do not give our signal mask to the new process */
168         sigfillset(&allsigs);
169         sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
170
171         /* Launch clients as the user. */
172         seteuid(getuid());
173
174         /* SOCK_CLOEXEC closes both ends, so we dup the fd to get a
175          * non-CLOEXEC fd to pass through exec. */
176         clientfd = dup(sockfd);
177         if (clientfd == -1) {
178                 weston_log("compositor: dup failed: %m\n");
179                 return;
180         }
181
182         snprintf(s, sizeof s, "%d", clientfd);
183         setenv("WAYLAND_SOCKET", s, 1);
184
185         if (execl(path, path, NULL) < 0)
186                 weston_log("compositor: executing '%s' failed: %m\n",
187                         path);
188 }
189
190 WL_EXPORT struct wl_client *
191 weston_client_launch(struct weston_compositor *compositor,
192                      struct weston_process *proc,
193                      const char *path,
194                      weston_process_cleanup_func_t cleanup)
195 {
196         int sv[2];
197         pid_t pid;
198         struct wl_client *client;
199
200         weston_log("launching '%s'\n", path);
201
202         if (os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, sv) < 0) {
203                 weston_log("weston_client_launch: "
204                         "socketpair failed while launching '%s': %m\n",
205                         path);
206                 return NULL;
207         }
208
209         pid = fork();
210         if (pid == -1) {
211                 close(sv[0]);
212                 close(sv[1]);
213                 weston_log("weston_client_launch: "
214                         "fork failed while launching '%s': %m\n", path);
215                 return NULL;
216         }
217
218         if (pid == 0) {
219                 child_client_exec(sv[1], path);
220                 exit(-1);
221         }
222
223         close(sv[1]);
224
225         client = wl_client_create(compositor->wl_display, sv[0]);
226         if (!client) {
227                 close(sv[0]);
228                 weston_log("weston_client_launch: "
229                         "wl_client_create failed while launching '%s'.\n",
230                         path);
231                 return NULL;
232         }
233
234         proc->pid = pid;
235         proc->cleanup = cleanup;
236         weston_watch_process(proc);
237
238         return client;
239 }
240
241 static void
242 surface_handle_pending_buffer_destroy(struct wl_listener *listener, void *data)
243 {
244         struct weston_surface *surface =
245                 container_of(listener, struct weston_surface,
246                              pending.buffer_destroy_listener);
247
248         surface->pending.buffer = NULL;
249 }
250
251 static void
252 empty_region(pixman_region32_t *region)
253 {
254         pixman_region32_fini(region);
255         pixman_region32_init(region);
256 }
257
258 static void
259 region_init_infinite(pixman_region32_t *region)
260 {
261         pixman_region32_init_rect(region, INT32_MIN, INT32_MIN,
262                                   UINT32_MAX, UINT32_MAX);
263 }
264
265 WL_EXPORT struct weston_surface *
266 weston_surface_create(struct weston_compositor *compositor)
267 {
268         struct weston_surface *surface;
269
270         surface = calloc(1, sizeof *surface);
271         if (surface == NULL)
272                 return NULL;
273
274         wl_signal_init(&surface->resource.destroy_signal);
275
276         wl_list_init(&surface->link);
277         wl_list_init(&surface->layer_link);
278
279         surface->resource.client = NULL;
280
281         surface->compositor = compositor;
282         surface->alpha = 1.0;
283
284         if (compositor->renderer->create_surface(surface) < 0) {
285                 free(surface);
286                 return NULL;
287         }
288
289         surface->buffer_transform = WL_OUTPUT_TRANSFORM_NORMAL;
290         surface->pending.buffer_transform = surface->buffer_transform;
291         surface->output = NULL;
292         surface->plane = &compositor->primary_plane;
293         surface->pending.newly_attached = 0;
294
295         pixman_region32_init(&surface->damage);
296         pixman_region32_init(&surface->opaque);
297         pixman_region32_init(&surface->clip);
298         region_init_infinite(&surface->input);
299         pixman_region32_init(&surface->transform.opaque);
300         wl_list_init(&surface->frame_callback_list);
301
302         wl_list_init(&surface->geometry.transformation_list);
303         wl_list_insert(&surface->geometry.transformation_list,
304                        &surface->transform.position.link);
305         weston_matrix_init(&surface->transform.position.matrix);
306         wl_list_init(&surface->geometry.child_list);
307         pixman_region32_init(&surface->transform.boundingbox);
308         surface->transform.dirty = 1;
309
310         surface->pending.buffer_destroy_listener.notify =
311                 surface_handle_pending_buffer_destroy;
312         pixman_region32_init(&surface->pending.damage);
313         pixman_region32_init(&surface->pending.opaque);
314         region_init_infinite(&surface->pending.input);
315         wl_list_init(&surface->pending.frame_callback_list);
316
317         return surface;
318 }
319
320 WL_EXPORT void
321 weston_surface_set_color(struct weston_surface *surface,
322                  float red, float green, float blue, float alpha)
323 {
324         surface->compositor->renderer->surface_set_color(surface, red, green, blue, alpha);
325 }
326
327 WL_EXPORT void
328 weston_surface_to_global_float(struct weston_surface *surface,
329                                float sx, float sy, float *x, float *y)
330 {
331         if (surface->transform.enabled) {
332                 struct weston_vector v = { { sx, sy, 0.0f, 1.0f } };
333
334                 weston_matrix_transform(&surface->transform.matrix, &v);
335
336                 if (fabsf(v.f[3]) < 1e-6) {
337                         weston_log("warning: numerical instability in "
338                                 "%s(), divisor = %g\n", __func__,
339                                 v.f[3]);
340                         *x = 0;
341                         *y = 0;
342                         return;
343                 }
344
345                 *x = v.f[0] / v.f[3];
346                 *y = v.f[1] / v.f[3];
347         } else {
348                 *x = sx + surface->geometry.x;
349                 *y = sy + surface->geometry.y;
350         }
351 }
352
353 WL_EXPORT void
354 weston_transformed_coord(int width, int height,
355                          enum wl_output_transform transform,
356                          float sx, float sy, float *bx, float *by)
357 {
358         switch (transform) {
359         case WL_OUTPUT_TRANSFORM_NORMAL:
360         default:
361                 *bx = sx;
362                 *by = sy;
363                 break;
364         case WL_OUTPUT_TRANSFORM_FLIPPED:
365                 *bx = width - sx;
366                 *by = sy;
367                 break;
368         case WL_OUTPUT_TRANSFORM_90:
369                 *bx = height - sy;
370                 *by = sx;
371                 break;
372         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
373                 *bx = height - sy;
374                 *by = width - sx;
375                 break;
376         case WL_OUTPUT_TRANSFORM_180:
377                 *bx = width - sx;
378                 *by = height - sy;
379                 break;
380         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
381                 *bx = sx;
382                 *by = height - sy;
383                 break;
384         case WL_OUTPUT_TRANSFORM_270:
385                 *bx = sy;
386                 *by = width - sx;
387                 break;
388         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
389                 *bx = sy;
390                 *by = sx;
391                 break;
392         }
393 }
394
395 WL_EXPORT pixman_box32_t
396 weston_transformed_rect(int width, int height,
397                         enum wl_output_transform transform,
398                         pixman_box32_t rect)
399 {
400         float x1, x2, y1, y2;
401
402         pixman_box32_t ret;
403
404         weston_transformed_coord(width, height, transform,
405                                  rect.x1, rect.y1, &x1, &y1);
406         weston_transformed_coord(width, height, transform,
407                                  rect.x2, rect.y2, &x2, &y2);
408
409         if (x1 <= x2) {
410                 ret.x1 = x1;
411                 ret.x2 = x2;
412         } else {
413                 ret.x1 = x2;
414                 ret.x2 = x1;
415         }
416
417         if (y1 <= y2) {
418                 ret.y1 = y1;
419                 ret.y2 = y2;
420         } else {
421                 ret.y1 = y2;
422                 ret.y2 = y1;
423         }
424
425         return ret;
426 }
427
428 WL_EXPORT void
429 weston_surface_to_buffer_float(struct weston_surface *surface,
430                                float sx, float sy, float *bx, float *by)
431 {
432         weston_transformed_coord(surface->geometry.width,
433                                  surface->geometry.height,
434                                  surface->buffer_transform,
435                                  sx, sy, bx, by);
436 }
437
438 WL_EXPORT pixman_box32_t
439 weston_surface_to_buffer_rect(struct weston_surface *surface,
440                               pixman_box32_t rect)
441 {
442         return weston_transformed_rect(surface->geometry.width,
443                                        surface->geometry.height,
444                                        surface->buffer_transform, rect);
445 }
446
447 WL_EXPORT void
448 weston_surface_move_to_plane(struct weston_surface *surface,
449                              struct weston_plane *plane)
450 {
451         if (surface->plane == plane)
452                 return;
453
454         weston_surface_damage_below(surface);
455         surface->plane = plane;
456         weston_surface_damage(surface);
457 }
458
459 WL_EXPORT void
460 weston_surface_damage_below(struct weston_surface *surface)
461 {
462         pixman_region32_t damage;
463
464         pixman_region32_init(&damage);
465         pixman_region32_subtract(&damage, &surface->transform.boundingbox,
466                                  &surface->clip);
467         pixman_region32_union(&surface->plane->damage,
468                               &surface->plane->damage, &damage);
469         pixman_region32_fini(&damage);
470 }
471
472 static struct wl_resource *
473 find_resource_for_client(struct wl_list *list, struct wl_client *client)
474 {
475         struct wl_resource *r;
476
477         wl_list_for_each(r, list, link) {
478                 if (r->client == client)
479                         return r;
480         }
481
482         return NULL;
483 }
484
485 static void
486 weston_surface_update_output_mask(struct weston_surface *es, uint32_t mask)
487 {
488         uint32_t different = es->output_mask ^ mask;
489         uint32_t entered = mask & different;
490         uint32_t left = es->output_mask & different;
491         struct weston_output *output;
492         struct wl_resource *resource = NULL;
493         struct wl_client *client = es->resource.client;
494
495         es->output_mask = mask;
496         if (es->resource.client == NULL)
497                 return;
498         if (different == 0)
499                 return;
500
501         wl_list_for_each(output, &es->compositor->output_list, link) {
502                 if (1 << output->id & different)
503                         resource =
504                                 find_resource_for_client(&output->resource_list,
505                                                          client);
506                 if (resource == NULL)
507                         continue;
508                 if (1 << output->id & entered)
509                         wl_surface_send_enter(&es->resource, resource);
510                 if (1 << output->id & left)
511                         wl_surface_send_leave(&es->resource, resource);
512         }
513 }
514
515 static void
516 weston_surface_assign_output(struct weston_surface *es)
517 {
518         struct weston_compositor *ec = es->compositor;
519         struct weston_output *output, *new_output;
520         pixman_region32_t region;
521         uint32_t max, area, mask;
522         pixman_box32_t *e;
523
524         new_output = NULL;
525         max = 0;
526         mask = 0;
527         pixman_region32_init(&region);
528         wl_list_for_each(output, &ec->output_list, link) {
529                 pixman_region32_intersect(&region, &es->transform.boundingbox,
530                                           &output->region);
531
532                 e = pixman_region32_extents(&region);
533                 area = (e->x2 - e->x1) * (e->y2 - e->y1);
534
535                 if (area > 0)
536                         mask |= 1 << output->id;
537
538                 if (area >= max) {
539                         new_output = output;
540                         max = area;
541                 }
542         }
543         pixman_region32_fini(&region);
544
545         es->output = new_output;
546         weston_surface_update_output_mask(es, mask);
547 }
548
549 static void
550 surface_compute_bbox(struct weston_surface *surface, int32_t sx, int32_t sy,
551                      int32_t width, int32_t height,
552                      pixman_region32_t *bbox)
553 {
554         float min_x = HUGE_VALF,  min_y = HUGE_VALF;
555         float max_x = -HUGE_VALF, max_y = -HUGE_VALF;
556         int32_t s[4][2] = {
557                 { sx,         sy },
558                 { sx,         sy + height },
559                 { sx + width, sy },
560                 { sx + width, sy + height }
561         };
562         float int_x, int_y;
563         int i;
564
565         if (width == 0 || height == 0) {
566                 /* avoid rounding empty bbox to 1x1 */
567                 pixman_region32_init(bbox);
568                 return;
569         }
570
571         for (i = 0; i < 4; ++i) {
572                 float x, y;
573                 weston_surface_to_global_float(surface,
574                                                s[i][0], s[i][1], &x, &y);
575                 if (x < min_x)
576                         min_x = x;
577                 if (x > max_x)
578                         max_x = x;
579                 if (y < min_y)
580                         min_y = y;
581                 if (y > max_y)
582                         max_y = y;
583         }
584
585         int_x = floorf(min_x);
586         int_y = floorf(min_y);
587         pixman_region32_init_rect(bbox, int_x, int_y,
588                                   ceilf(max_x) - int_x, ceilf(max_y) - int_y);
589 }
590
591 static void
592 weston_surface_update_transform_disable(struct weston_surface *surface)
593 {
594         surface->transform.enabled = 0;
595
596         /* round off fractions when not transformed */
597         surface->geometry.x = roundf(surface->geometry.x);
598         surface->geometry.y = roundf(surface->geometry.y);
599
600         /* Otherwise identity matrix, but with x and y translation. */
601         surface->transform.position.matrix.type = WESTON_MATRIX_TRANSFORM_TRANSLATE;
602         surface->transform.position.matrix.d[12] = surface->geometry.x;
603         surface->transform.position.matrix.d[13] = surface->geometry.y;
604
605         surface->transform.matrix = surface->transform.position.matrix;
606
607         surface->transform.inverse = surface->transform.position.matrix;
608         surface->transform.inverse.d[12] = -surface->geometry.x;
609         surface->transform.inverse.d[13] = -surface->geometry.y;
610
611         pixman_region32_init_rect(&surface->transform.boundingbox,
612                                   surface->geometry.x,
613                                   surface->geometry.y,
614                                   surface->geometry.width,
615                                   surface->geometry.height);
616
617         if (surface->alpha == 1.0) {
618                 pixman_region32_copy(&surface->transform.opaque,
619                                      &surface->opaque);
620                 pixman_region32_translate(&surface->transform.opaque,
621                                           surface->geometry.x,
622                                           surface->geometry.y);
623         }
624 }
625
626 static int
627 weston_surface_update_transform_enable(struct weston_surface *surface)
628 {
629         struct weston_surface *parent = surface->geometry.parent;
630         struct weston_matrix *matrix = &surface->transform.matrix;
631         struct weston_matrix *inverse = &surface->transform.inverse;
632         struct weston_transform *tform;
633
634         surface->transform.enabled = 1;
635
636         /* Otherwise identity matrix, but with x and y translation. */
637         surface->transform.position.matrix.type = WESTON_MATRIX_TRANSFORM_TRANSLATE;
638         surface->transform.position.matrix.d[12] = surface->geometry.x;
639         surface->transform.position.matrix.d[13] = surface->geometry.y;
640
641         weston_matrix_init(matrix);
642         wl_list_for_each(tform, &surface->geometry.transformation_list, link)
643                 weston_matrix_multiply(matrix, &tform->matrix);
644
645         if (parent)
646                 weston_matrix_multiply(matrix, &parent->transform.matrix);
647
648         if (weston_matrix_invert(inverse, matrix) < 0) {
649                 /* Oops, bad total transformation, not invertible */
650                 weston_log("error: weston_surface %p"
651                         " transformation not invertible.\n", surface);
652                 return -1;
653         }
654
655         surface_compute_bbox(surface, 0, 0, surface->geometry.width,
656                              surface->geometry.height,
657                              &surface->transform.boundingbox);
658
659         return 0;
660 }
661
662 WL_EXPORT void
663 weston_surface_update_transform(struct weston_surface *surface)
664 {
665         struct weston_surface *parent = surface->geometry.parent;
666
667         if (!surface->transform.dirty)
668                 return;
669
670         if (parent)
671                 weston_surface_update_transform(parent);
672
673         surface->transform.dirty = 0;
674
675         weston_surface_damage_below(surface);
676
677         pixman_region32_fini(&surface->transform.boundingbox);
678         pixman_region32_fini(&surface->transform.opaque);
679         pixman_region32_init(&surface->transform.opaque);
680
681         /* transform.position is always in transformation_list */
682         if (surface->geometry.transformation_list.next ==
683             &surface->transform.position.link &&
684             surface->geometry.transformation_list.prev ==
685             &surface->transform.position.link &&
686             !parent) {
687                 weston_surface_update_transform_disable(surface);
688         } else {
689                 if (weston_surface_update_transform_enable(surface) < 0)
690                         weston_surface_update_transform_disable(surface);
691         }
692
693         weston_surface_damage_below(surface);
694
695         weston_surface_assign_output(surface);
696 }
697
698 WL_EXPORT void
699 weston_surface_geometry_dirty(struct weston_surface *surface)
700 {
701         struct weston_surface *child;
702
703         /*
704          * The invariant: if surface->geometry.dirty, then all surfaces
705          * in surface->geometry.child_list have geometry.dirty too.
706          * Corollary: if not parent->geometry.dirty, then all ancestors
707          * are not dirty.
708          */
709
710         if (surface->transform.dirty)
711                 return;
712
713         surface->transform.dirty = 1;
714
715         wl_list_for_each(child, &surface->geometry.child_list,
716                          geometry.parent_link)
717                 weston_surface_geometry_dirty(child);
718 }
719
720 WL_EXPORT void
721 weston_surface_to_global_fixed(struct weston_surface *surface,
722                                wl_fixed_t sx, wl_fixed_t sy,
723                                wl_fixed_t *x, wl_fixed_t *y)
724 {
725         float xf, yf;
726
727         weston_surface_to_global_float(surface,
728                                        wl_fixed_to_double(sx),
729                                        wl_fixed_to_double(sy),
730                                        &xf, &yf);
731         *x = wl_fixed_from_double(xf);
732         *y = wl_fixed_from_double(yf);
733 }
734
735 WL_EXPORT void
736 weston_surface_from_global_float(struct weston_surface *surface,
737                                  float x, float y, float *sx, float *sy)
738 {
739         if (surface->transform.enabled) {
740                 struct weston_vector v = { { x, y, 0.0f, 1.0f } };
741
742                 weston_matrix_transform(&surface->transform.inverse, &v);
743
744                 if (fabsf(v.f[3]) < 1e-6) {
745                         weston_log("warning: numerical instability in "
746                                 "weston_surface_from_global(), divisor = %g\n",
747                                 v.f[3]);
748                         *sx = 0;
749                         *sy = 0;
750                         return;
751                 }
752
753                 *sx = v.f[0] / v.f[3];
754                 *sy = v.f[1] / v.f[3];
755         } else {
756                 *sx = x - surface->geometry.x;
757                 *sy = y - surface->geometry.y;
758         }
759 }
760
761 WL_EXPORT void
762 weston_surface_from_global_fixed(struct weston_surface *surface,
763                                  wl_fixed_t x, wl_fixed_t y,
764                                  wl_fixed_t *sx, wl_fixed_t *sy)
765 {
766         float sxf, syf;
767
768         weston_surface_from_global_float(surface,
769                                          wl_fixed_to_double(x),
770                                          wl_fixed_to_double(y),
771                                          &sxf, &syf);
772         *sx = wl_fixed_from_double(sxf);
773         *sy = wl_fixed_from_double(syf);
774 }
775
776 WL_EXPORT void
777 weston_surface_from_global(struct weston_surface *surface,
778                            int32_t x, int32_t y, int32_t *sx, int32_t *sy)
779 {
780         float sxf, syf;
781
782         weston_surface_from_global_float(surface, x, y, &sxf, &syf);
783         *sx = floorf(sxf);
784         *sy = floorf(syf);
785 }
786
787 WL_EXPORT void
788 weston_surface_schedule_repaint(struct weston_surface *surface)
789 {
790         struct weston_output *output;
791
792         wl_list_for_each(output, &surface->compositor->output_list, link)
793                 if (surface->output_mask & (1 << output->id))
794                         weston_output_schedule_repaint(output);
795 }
796
797 WL_EXPORT void
798 weston_surface_damage(struct weston_surface *surface)
799 {
800         pixman_region32_union_rect(&surface->damage, &surface->damage,
801                                    0, 0, surface->geometry.width,
802                                    surface->geometry.height);
803
804         weston_surface_schedule_repaint(surface);
805 }
806
807 WL_EXPORT void
808 weston_surface_configure(struct weston_surface *surface,
809                          float x, float y, int width, int height)
810 {
811         surface->geometry.x = x;
812         surface->geometry.y = y;
813         surface->geometry.width = width;
814         surface->geometry.height = height;
815         weston_surface_geometry_dirty(surface);
816 }
817
818 WL_EXPORT void
819 weston_surface_set_position(struct weston_surface *surface,
820                             float x, float y)
821 {
822         surface->geometry.x = x;
823         surface->geometry.y = y;
824         weston_surface_geometry_dirty(surface);
825 }
826
827 static void
828 transform_parent_handle_parent_destroy(struct wl_listener *listener,
829                                        void *data)
830 {
831         struct weston_surface *surface =
832                 container_of(listener, struct weston_surface,
833                              geometry.parent_destroy_listener);
834
835         weston_surface_set_transform_parent(surface, NULL);
836 }
837
838 WL_EXPORT void
839 weston_surface_set_transform_parent(struct weston_surface *surface,
840                                     struct weston_surface *parent)
841 {
842         if (surface->geometry.parent) {
843                 wl_list_remove(&surface->geometry.parent_destroy_listener.link);
844                 wl_list_remove(&surface->geometry.parent_link);
845         }
846
847         surface->geometry.parent = parent;
848
849         surface->geometry.parent_destroy_listener.notify =
850                 transform_parent_handle_parent_destroy;
851         if (parent) {
852                 wl_signal_add(&parent->resource.destroy_signal,
853                               &surface->geometry.parent_destroy_listener);
854                 wl_list_insert(&parent->geometry.child_list,
855                                &surface->geometry.parent_link);
856         }
857
858         weston_surface_geometry_dirty(surface);
859 }
860
861 WL_EXPORT int
862 weston_surface_is_mapped(struct weston_surface *surface)
863 {
864         if (surface->output)
865                 return 1;
866         else
867                 return 0;
868 }
869
870 WL_EXPORT int32_t
871 weston_surface_buffer_width(struct weston_surface *surface)
872 {
873         switch (surface->buffer_transform) {
874         case WL_OUTPUT_TRANSFORM_90:
875         case WL_OUTPUT_TRANSFORM_270:
876         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
877         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
878                 return surface->buffer_ref.buffer->height;
879         default:
880                 return surface->buffer_ref.buffer->width;
881         }
882 }
883
884 WL_EXPORT int32_t
885 weston_surface_buffer_height(struct weston_surface *surface)
886 {
887         switch (surface->buffer_transform) {
888         case WL_OUTPUT_TRANSFORM_90:
889         case WL_OUTPUT_TRANSFORM_270:
890         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
891         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
892                 return surface->buffer_ref.buffer->width;
893         default:
894                 return surface->buffer_ref.buffer->height;
895         }
896 }
897
898 WL_EXPORT uint32_t
899 weston_compositor_get_time(void)
900 {
901        struct timeval tv;
902
903        gettimeofday(&tv, NULL);
904
905        return tv.tv_sec * 1000 + tv.tv_usec / 1000;
906 }
907
908 WL_EXPORT struct weston_surface *
909 weston_compositor_pick_surface(struct weston_compositor *compositor,
910                                wl_fixed_t x, wl_fixed_t y,
911                                wl_fixed_t *sx, wl_fixed_t *sy)
912 {
913         struct weston_surface *surface;
914
915         wl_list_for_each(surface, &compositor->surface_list, link) {
916                 weston_surface_from_global_fixed(surface, x, y, sx, sy);
917                 if (pixman_region32_contains_point(&surface->input,
918                                                    wl_fixed_to_int(*sx),
919                                                    wl_fixed_to_int(*sy),
920                                                    NULL))
921                         return surface;
922         }
923
924         return NULL;
925 }
926
927 static void
928 weston_compositor_repick(struct weston_compositor *compositor)
929 {
930         struct weston_seat *seat;
931
932         if (!compositor->focus)
933                 return;
934
935         wl_list_for_each(seat, &compositor->seat_list, link)
936                 weston_seat_repick(seat);
937 }
938
939 WL_EXPORT void
940 weston_surface_unmap(struct weston_surface *surface)
941 {
942         struct weston_seat *seat;
943
944         weston_surface_damage_below(surface);
945         surface->output = NULL;
946         wl_list_remove(&surface->layer_link);
947
948         wl_list_for_each(seat, &surface->compositor->seat_list, link) {
949                 if (seat->keyboard && seat->keyboard->focus == surface)
950                         weston_keyboard_set_focus(seat->keyboard, NULL);
951                 if (seat->pointer && seat->pointer->focus == surface)
952                         weston_pointer_set_focus(seat->pointer,
953                                                  NULL,
954                                                  wl_fixed_from_int(0),
955                                                  wl_fixed_from_int(0));
956         }
957
958         weston_surface_schedule_repaint(surface);
959 }
960
961 struct weston_frame_callback {
962         struct wl_resource resource;
963         struct wl_list link;
964 };
965
966 static void
967 destroy_surface(struct wl_resource *resource)
968 {
969         struct weston_surface *surface =
970                 container_of(resource, struct weston_surface, resource);
971         struct weston_compositor *compositor = surface->compositor;
972         struct weston_frame_callback *cb, *next;
973
974         assert(wl_list_empty(&surface->geometry.child_list));
975
976         if (weston_surface_is_mapped(surface))
977                 weston_surface_unmap(surface);
978
979         wl_list_for_each_safe(cb, next,
980                               &surface->pending.frame_callback_list, link)
981                 wl_resource_destroy(&cb->resource);
982
983         pixman_region32_fini(&surface->pending.input);
984         pixman_region32_fini(&surface->pending.opaque);
985         pixman_region32_fini(&surface->pending.damage);
986
987         if (surface->pending.buffer)
988                 wl_list_remove(&surface->pending.buffer_destroy_listener.link);
989
990         weston_buffer_reference(&surface->buffer_ref, NULL);
991
992         compositor->renderer->destroy_surface(surface);
993
994         pixman_region32_fini(&surface->transform.boundingbox);
995         pixman_region32_fini(&surface->damage);
996         pixman_region32_fini(&surface->opaque);
997         pixman_region32_fini(&surface->clip);
998         pixman_region32_fini(&surface->input);
999
1000         wl_list_for_each_safe(cb, next, &surface->frame_callback_list, link)
1001                 wl_resource_destroy(&cb->resource);
1002
1003         weston_surface_set_transform_parent(surface, NULL);
1004
1005         free(surface);
1006 }
1007
1008 WL_EXPORT void
1009 weston_surface_destroy(struct weston_surface *surface)
1010 {
1011         /* Not a valid way to destroy a client surface */
1012         assert(surface->resource.client == NULL);
1013
1014         wl_signal_emit(&surface->resource.destroy_signal, &surface->resource);
1015         destroy_surface(&surface->resource);
1016 }
1017
1018 static void
1019 weston_buffer_reference_handle_destroy(struct wl_listener *listener,
1020                                        void *data)
1021 {
1022         struct weston_buffer_reference *ref =
1023                 container_of(listener, struct weston_buffer_reference,
1024                              destroy_listener);
1025
1026         assert((struct wl_buffer *)data == ref->buffer);
1027         ref->buffer = NULL;
1028 }
1029
1030 WL_EXPORT void
1031 weston_buffer_reference(struct weston_buffer_reference *ref,
1032                         struct wl_buffer *buffer)
1033 {
1034         if (ref->buffer && buffer != ref->buffer) {
1035                 ref->buffer->busy_count--;
1036                 if (ref->buffer->busy_count == 0) {
1037                         assert(ref->buffer->resource.client != NULL);
1038                         wl_resource_queue_event(&ref->buffer->resource,
1039                                                 WL_BUFFER_RELEASE);
1040                 }
1041                 wl_list_remove(&ref->destroy_listener.link);
1042         }
1043
1044         if (buffer && buffer != ref->buffer) {
1045                 buffer->busy_count++;
1046                 wl_signal_add(&buffer->resource.destroy_signal,
1047                               &ref->destroy_listener);
1048         }
1049
1050         ref->buffer = buffer;
1051         ref->destroy_listener.notify = weston_buffer_reference_handle_destroy;
1052 }
1053
1054 static void
1055 weston_surface_attach(struct weston_surface *surface, struct wl_buffer *buffer)
1056 {
1057         weston_buffer_reference(&surface->buffer_ref, buffer);
1058
1059         if (!buffer) {
1060                 if (weston_surface_is_mapped(surface))
1061                         weston_surface_unmap(surface);
1062         }
1063
1064         surface->compositor->renderer->attach(surface, buffer);
1065 }
1066
1067 WL_EXPORT void
1068 weston_surface_restack(struct weston_surface *surface, struct wl_list *below)
1069 {
1070         wl_list_remove(&surface->layer_link);
1071         wl_list_insert(below, &surface->layer_link);
1072         weston_surface_damage_below(surface);
1073         weston_surface_damage(surface);
1074 }
1075
1076 WL_EXPORT void
1077 weston_compositor_damage_all(struct weston_compositor *compositor)
1078 {
1079         struct weston_output *output;
1080
1081         wl_list_for_each(output, &compositor->output_list, link)
1082                 weston_output_damage(output);
1083 }
1084
1085 WL_EXPORT void
1086 weston_output_damage(struct weston_output *output)
1087 {
1088         struct weston_compositor *compositor = output->compositor;
1089
1090         pixman_region32_union(&compositor->primary_plane.damage,
1091                               &compositor->primary_plane.damage,
1092                               &output->region);
1093         weston_output_schedule_repaint(output);
1094 }
1095
1096 static void
1097 surface_accumulate_damage(struct weston_surface *surface,
1098                           pixman_region32_t *opaque)
1099 {
1100         if (surface->buffer_ref.buffer &&
1101             wl_buffer_is_shm(surface->buffer_ref.buffer))
1102                 surface->compositor->renderer->flush_damage(surface);
1103
1104         if (surface->transform.enabled) {
1105                 pixman_box32_t *extents;
1106
1107                 extents = pixman_region32_extents(&surface->damage);
1108                 surface_compute_bbox(surface, extents->x1, extents->y1,
1109                                      extents->x2 - extents->x1,
1110                                      extents->y2 - extents->y1,
1111                                      &surface->damage);
1112                 pixman_region32_translate(&surface->damage,
1113                                           -surface->plane->x,
1114                                           -surface->plane->y);
1115         } else {
1116                 pixman_region32_translate(&surface->damage,
1117                                           surface->geometry.x - surface->plane->x,
1118                                           surface->geometry.y - surface->plane->y);
1119         }
1120
1121         pixman_region32_subtract(&surface->damage, &surface->damage, opaque);
1122         pixman_region32_union(&surface->plane->damage,
1123                               &surface->plane->damage, &surface->damage);
1124         empty_region(&surface->damage);
1125         pixman_region32_copy(&surface->clip, opaque);
1126         pixman_region32_union(opaque, opaque, &surface->transform.opaque);
1127 }
1128
1129 static void
1130 compositor_accumulate_damage(struct weston_compositor *ec)
1131 {
1132         struct weston_plane *plane;
1133         struct weston_surface *es;
1134         pixman_region32_t opaque, clip;
1135
1136         pixman_region32_init(&clip);
1137
1138         wl_list_for_each(plane, &ec->plane_list, link) {
1139                 pixman_region32_copy(&plane->clip, &clip);
1140
1141                 pixman_region32_init(&opaque);
1142
1143                 wl_list_for_each(es, &ec->surface_list, link) {
1144                         if (es->plane != plane)
1145                                 continue;
1146
1147                         surface_accumulate_damage(es, &opaque);
1148                 }
1149
1150                 pixman_region32_union(&clip, &clip, &opaque);
1151                 pixman_region32_fini(&opaque);
1152         }
1153
1154         pixman_region32_fini(&clip);
1155
1156         wl_list_for_each(es, &ec->surface_list, link) {
1157                 /* Both the renderer and the backend have seen the buffer
1158                  * by now. If renderer needs the buffer, it has its own
1159                  * reference set. If the backend wants to keep the buffer
1160                  * around for migrating the surface into a non-primary plane
1161                  * later, keep_buffer is true. Otherwise, drop the core
1162                  * reference now, and allow early buffer release. This enables
1163                  * clients to use single-buffering.
1164                  */
1165                 if (!es->keep_buffer)
1166                         weston_buffer_reference(&es->buffer_ref, NULL);
1167         }
1168 }
1169
1170 static void
1171 weston_output_repaint(struct weston_output *output, uint32_t msecs)
1172 {
1173         struct weston_compositor *ec = output->compositor;
1174         struct weston_surface *es;
1175         struct weston_layer *layer;
1176         struct weston_animation *animation, *next;
1177         struct weston_frame_callback *cb, *cnext;
1178         struct wl_list frame_callback_list;
1179         pixman_region32_t output_damage;
1180
1181         /* Rebuild the surface list and update surface transforms up front. */
1182         wl_list_init(&ec->surface_list);
1183         wl_list_init(&frame_callback_list);
1184         wl_list_for_each(layer, &ec->layer_list, link) {
1185                 wl_list_for_each(es, &layer->surface_list, layer_link) {
1186                         weston_surface_update_transform(es);
1187                         wl_list_insert(ec->surface_list.prev, &es->link);
1188                         if (es->output == output) {
1189                                 wl_list_insert_list(&frame_callback_list,
1190                                                     &es->frame_callback_list);
1191                                 wl_list_init(&es->frame_callback_list);
1192                         }
1193                 }
1194         }
1195
1196         if (output->assign_planes && !output->disable_planes)
1197                 output->assign_planes(output);
1198         else
1199                 wl_list_for_each(es, &ec->surface_list, link)
1200                         weston_surface_move_to_plane(es, &ec->primary_plane);
1201
1202         compositor_accumulate_damage(ec);
1203
1204         pixman_region32_init(&output_damage);
1205         pixman_region32_intersect(&output_damage,
1206                                   &ec->primary_plane.damage, &output->region);
1207         pixman_region32_subtract(&output_damage,
1208                                  &output_damage, &ec->primary_plane.clip);
1209
1210         if (output->dirty)
1211                 weston_output_update_matrix(output);
1212
1213         output->repaint(output, &output_damage);
1214
1215         pixman_region32_fini(&output_damage);
1216
1217         output->repaint_needed = 0;
1218
1219         weston_compositor_repick(ec);
1220         wl_event_loop_dispatch(ec->input_loop, 0);
1221
1222         wl_list_for_each_safe(cb, cnext, &frame_callback_list, link) {
1223                 wl_callback_send_done(&cb->resource, msecs);
1224                 wl_resource_destroy(&cb->resource);
1225         }
1226
1227         wl_list_for_each_safe(animation, next, &output->animation_list, link) {
1228                 animation->frame_counter++;
1229                 animation->frame(animation, output, msecs);
1230         }
1231 }
1232
1233 static int
1234 weston_compositor_read_input(int fd, uint32_t mask, void *data)
1235 {
1236         struct weston_compositor *compositor = data;
1237
1238         wl_event_loop_dispatch(compositor->input_loop, 0);
1239
1240         return 1;
1241 }
1242
1243 WL_EXPORT void
1244 weston_output_finish_frame(struct weston_output *output, uint32_t msecs)
1245 {
1246         struct weston_compositor *compositor = output->compositor;
1247         struct wl_event_loop *loop =
1248                 wl_display_get_event_loop(compositor->wl_display);
1249         int fd;
1250
1251         output->frame_time = msecs;
1252         if (output->repaint_needed) {
1253                 weston_output_repaint(output, msecs);
1254                 return;
1255         }
1256
1257         output->repaint_scheduled = 0;
1258         if (compositor->input_loop_source)
1259                 return;
1260
1261         fd = wl_event_loop_get_fd(compositor->input_loop);
1262         compositor->input_loop_source =
1263                 wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
1264                                      weston_compositor_read_input, compositor);
1265 }
1266
1267 static void
1268 idle_repaint(void *data)
1269 {
1270         struct weston_output *output = data;
1271
1272         output->start_repaint_loop(output);
1273 }
1274
1275 WL_EXPORT void
1276 weston_layer_init(struct weston_layer *layer, struct wl_list *below)
1277 {
1278         wl_list_init(&layer->surface_list);
1279         if (below != NULL)
1280                 wl_list_insert(below, &layer->link);
1281 }
1282
1283 WL_EXPORT void
1284 weston_output_schedule_repaint(struct weston_output *output)
1285 {
1286         struct weston_compositor *compositor = output->compositor;
1287         struct wl_event_loop *loop;
1288
1289         if (compositor->state == WESTON_COMPOSITOR_SLEEPING ||
1290             compositor->state == WESTON_COMPOSITOR_OFFSCREEN)
1291                 return;
1292
1293         loop = wl_display_get_event_loop(compositor->wl_display);
1294         output->repaint_needed = 1;
1295         if (output->repaint_scheduled)
1296                 return;
1297
1298         wl_event_loop_add_idle(loop, idle_repaint, output);
1299         output->repaint_scheduled = 1;
1300
1301         if (compositor->input_loop_source) {
1302                 wl_event_source_remove(compositor->input_loop_source);
1303                 compositor->input_loop_source = NULL;
1304         }
1305 }
1306
1307 WL_EXPORT void
1308 weston_compositor_schedule_repaint(struct weston_compositor *compositor)
1309 {
1310         struct weston_output *output;
1311
1312         wl_list_for_each(output, &compositor->output_list, link)
1313                 weston_output_schedule_repaint(output);
1314 }
1315
1316 static void
1317 surface_destroy(struct wl_client *client, struct wl_resource *resource)
1318 {
1319         wl_resource_destroy(resource);
1320 }
1321
1322 static void
1323 surface_attach(struct wl_client *client,
1324                struct wl_resource *resource,
1325                struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
1326 {
1327         struct weston_surface *surface = resource->data;
1328         struct wl_buffer *buffer = NULL;
1329
1330         if (buffer_resource)
1331                 buffer = buffer_resource->data;
1332
1333         /* Attach, attach, without commit in between does not send
1334          * wl_buffer.release. */
1335         if (surface->pending.buffer)
1336                 wl_list_remove(&surface->pending.buffer_destroy_listener.link);
1337
1338         surface->pending.sx = sx;
1339         surface->pending.sy = sy;
1340         surface->pending.buffer = buffer;
1341         surface->pending.newly_attached = 1;
1342         if (buffer) {
1343                 wl_signal_add(&buffer->resource.destroy_signal,
1344                               &surface->pending.buffer_destroy_listener);
1345         }
1346 }
1347
1348 static void
1349 surface_damage(struct wl_client *client,
1350                struct wl_resource *resource,
1351                int32_t x, int32_t y, int32_t width, int32_t height)
1352 {
1353         struct weston_surface *surface = resource->data;
1354
1355         pixman_region32_union_rect(&surface->pending.damage,
1356                                    &surface->pending.damage,
1357                                    x, y, width, height);
1358 }
1359
1360 static void
1361 destroy_frame_callback(struct wl_resource *resource)
1362 {
1363         struct weston_frame_callback *cb = resource->data;
1364
1365         wl_list_remove(&cb->link);
1366         free(cb);
1367 }
1368
1369 static void
1370 surface_frame(struct wl_client *client,
1371               struct wl_resource *resource, uint32_t callback)
1372 {
1373         struct weston_frame_callback *cb;
1374         struct weston_surface *surface = resource->data;
1375
1376         cb = malloc(sizeof *cb);
1377         if (cb == NULL) {
1378                 wl_resource_post_no_memory(resource);
1379                 return;
1380         }
1381
1382         cb->resource.object.interface = &wl_callback_interface;
1383         cb->resource.object.id = callback;
1384         cb->resource.destroy = destroy_frame_callback;
1385         cb->resource.client = client;
1386         cb->resource.data = cb;
1387
1388         wl_client_add_resource(client, &cb->resource);
1389         wl_list_insert(surface->pending.frame_callback_list.prev, &cb->link);
1390 }
1391
1392 static void
1393 surface_set_opaque_region(struct wl_client *client,
1394                           struct wl_resource *resource,
1395                           struct wl_resource *region_resource)
1396 {
1397         struct weston_surface *surface = resource->data;
1398         struct weston_region *region;
1399
1400         if (region_resource) {
1401                 region = region_resource->data;
1402                 pixman_region32_copy(&surface->pending.opaque,
1403                                      &region->region);
1404         } else {
1405                 empty_region(&surface->pending.opaque);
1406         }
1407 }
1408
1409 static void
1410 surface_set_input_region(struct wl_client *client,
1411                          struct wl_resource *resource,
1412                          struct wl_resource *region_resource)
1413 {
1414         struct weston_surface *surface = resource->data;
1415         struct weston_region *region;
1416
1417         if (region_resource) {
1418                 region = region_resource->data;
1419                 pixman_region32_copy(&surface->pending.input,
1420                                      &region->region);
1421         } else {
1422                 pixman_region32_fini(&surface->pending.input);
1423                 region_init_infinite(&surface->pending.input);
1424         }
1425 }
1426
1427 static void
1428 surface_commit(struct wl_client *client, struct wl_resource *resource)
1429 {
1430         struct weston_surface *surface = resource->data;
1431         pixman_region32_t opaque;
1432         int buffer_width = 0;
1433         int buffer_height = 0;
1434
1435         /* wl_surface.set_buffer_rotation */
1436         surface->buffer_transform = surface->pending.buffer_transform;
1437
1438         /* wl_surface.attach */
1439         if (surface->pending.buffer || surface->pending.newly_attached)
1440                 weston_surface_attach(surface, surface->pending.buffer);
1441
1442         if (surface->buffer_ref.buffer) {
1443                 buffer_width = weston_surface_buffer_width(surface);
1444                 buffer_height = weston_surface_buffer_height(surface);
1445         }
1446
1447         if (surface->configure && surface->pending.newly_attached)
1448                 surface->configure(surface,
1449                                    surface->pending.sx, surface->pending.sy,
1450                                    buffer_width, buffer_height);
1451
1452         if (surface->pending.buffer)
1453                 wl_list_remove(&surface->pending.buffer_destroy_listener.link);
1454         surface->pending.buffer = NULL;
1455         surface->pending.sx = 0;
1456         surface->pending.sy = 0;
1457         surface->pending.newly_attached = 0;
1458
1459         /* wl_surface.damage */
1460         pixman_region32_union(&surface->damage, &surface->damage,
1461                               &surface->pending.damage);
1462         pixman_region32_intersect_rect(&surface->damage, &surface->damage,
1463                                        0, 0,
1464                                        surface->geometry.width,
1465                                        surface->geometry.height);
1466         empty_region(&surface->pending.damage);
1467
1468         /* wl_surface.set_opaque_region */
1469         pixman_region32_init_rect(&opaque, 0, 0,
1470                                   surface->geometry.width,
1471                                   surface->geometry.height);
1472         pixman_region32_intersect(&opaque,
1473                                   &opaque, &surface->pending.opaque);
1474
1475         if (!pixman_region32_equal(&opaque, &surface->opaque)) {
1476                 pixman_region32_copy(&surface->opaque, &opaque);
1477                 weston_surface_geometry_dirty(surface);
1478         }
1479
1480         pixman_region32_fini(&opaque);
1481
1482         /* wl_surface.set_input_region */
1483         pixman_region32_fini(&surface->input);
1484         pixman_region32_init_rect(&surface->input, 0, 0,
1485                                   surface->geometry.width,
1486                                   surface->geometry.height);
1487         pixman_region32_intersect(&surface->input,
1488                                   &surface->input, &surface->pending.input);
1489
1490         /* wl_surface.frame */
1491         wl_list_insert_list(&surface->frame_callback_list,
1492                             &surface->pending.frame_callback_list);
1493         wl_list_init(&surface->pending.frame_callback_list);
1494
1495         weston_surface_schedule_repaint(surface);
1496 }
1497
1498 static void
1499 surface_set_buffer_transform(struct wl_client *client,
1500                              struct wl_resource *resource, int transform)
1501 {
1502         struct weston_surface *surface = resource->data;
1503
1504         surface->pending.buffer_transform = transform;
1505 }
1506
1507 static const struct wl_surface_interface surface_interface = {
1508         surface_destroy,
1509         surface_attach,
1510         surface_damage,
1511         surface_frame,
1512         surface_set_opaque_region,
1513         surface_set_input_region,
1514         surface_commit,
1515         surface_set_buffer_transform
1516 };
1517
1518 static void
1519 compositor_create_surface(struct wl_client *client,
1520                           struct wl_resource *resource, uint32_t id)
1521 {
1522         struct weston_compositor *ec = resource->data;
1523         struct weston_surface *surface;
1524
1525         surface = weston_surface_create(ec);
1526         if (surface == NULL) {
1527                 wl_resource_post_no_memory(resource);
1528                 return;
1529         }
1530
1531         surface->resource.destroy = destroy_surface;
1532
1533         surface->resource.object.id = id;
1534         surface->resource.object.interface = &wl_surface_interface;
1535         surface->resource.object.implementation =
1536                 (void (**)(void)) &surface_interface;
1537         surface->resource.data = surface;
1538
1539         wl_client_add_resource(client, &surface->resource);
1540 }
1541
1542 static void
1543 destroy_region(struct wl_resource *resource)
1544 {
1545         struct weston_region *region =
1546                 container_of(resource, struct weston_region, resource);
1547
1548         pixman_region32_fini(&region->region);
1549         free(region);
1550 }
1551
1552 static void
1553 region_destroy(struct wl_client *client, struct wl_resource *resource)
1554 {
1555         wl_resource_destroy(resource);
1556 }
1557
1558 static void
1559 region_add(struct wl_client *client, struct wl_resource *resource,
1560            int32_t x, int32_t y, int32_t width, int32_t height)
1561 {
1562         struct weston_region *region = resource->data;
1563
1564         pixman_region32_union_rect(&region->region, &region->region,
1565                                    x, y, width, height);
1566 }
1567
1568 static void
1569 region_subtract(struct wl_client *client, struct wl_resource *resource,
1570                 int32_t x, int32_t y, int32_t width, int32_t height)
1571 {
1572         struct weston_region *region = resource->data;
1573         pixman_region32_t rect;
1574
1575         pixman_region32_init_rect(&rect, x, y, width, height);
1576         pixman_region32_subtract(&region->region, &region->region, &rect);
1577         pixman_region32_fini(&rect);
1578 }
1579
1580 static const struct wl_region_interface region_interface = {
1581         region_destroy,
1582         region_add,
1583         region_subtract
1584 };
1585
1586 static void
1587 compositor_create_region(struct wl_client *client,
1588                          struct wl_resource *resource, uint32_t id)
1589 {
1590         struct weston_region *region;
1591
1592         region = malloc(sizeof *region);
1593         if (region == NULL) {
1594                 wl_resource_post_no_memory(resource);
1595                 return;
1596         }
1597
1598         region->resource.destroy = destroy_region;
1599
1600         region->resource.object.id = id;
1601         region->resource.object.interface = &wl_region_interface;
1602         region->resource.object.implementation =
1603                 (void (**)(void)) &region_interface;
1604         region->resource.data = region;
1605
1606         pixman_region32_init(&region->region);
1607
1608         wl_client_add_resource(client, &region->resource);
1609 }
1610
1611 static const struct wl_compositor_interface compositor_interface = {
1612         compositor_create_surface,
1613         compositor_create_region
1614 };
1615
1616 static void
1617 weston_compositor_dpms(struct weston_compositor *compositor,
1618                        enum dpms_enum state)
1619 {
1620         struct weston_output *output;
1621
1622         wl_list_for_each(output, &compositor->output_list, link)
1623                 if (output->set_dpms)
1624                         output->set_dpms(output, state);
1625 }
1626
1627 WL_EXPORT void
1628 weston_compositor_wake(struct weston_compositor *compositor)
1629 {
1630         switch (compositor->state) {
1631         case WESTON_COMPOSITOR_SLEEPING:
1632                 weston_compositor_dpms(compositor, WESTON_DPMS_ON);
1633                 /* fall through */
1634         case WESTON_COMPOSITOR_IDLE:
1635         case WESTON_COMPOSITOR_OFFSCREEN:
1636                 wl_signal_emit(&compositor->wake_signal, compositor);
1637                 /* fall through */
1638         default:
1639                 compositor->state = WESTON_COMPOSITOR_ACTIVE;
1640                 wl_event_source_timer_update(compositor->idle_source,
1641                                              compositor->idle_time * 1000);
1642         }
1643 }
1644
1645 WL_EXPORT void
1646 weston_compositor_offscreen(struct weston_compositor *compositor)
1647 {
1648         switch (compositor->state) {
1649         case WESTON_COMPOSITOR_OFFSCREEN:
1650                 return;
1651         case WESTON_COMPOSITOR_SLEEPING:
1652                 weston_compositor_dpms(compositor, WESTON_DPMS_ON);
1653                 /* fall through */
1654         default:
1655                 compositor->state = WESTON_COMPOSITOR_OFFSCREEN;
1656                 wl_event_source_timer_update(compositor->idle_source, 0);
1657         }
1658 }
1659
1660 WL_EXPORT void
1661 weston_compositor_sleep(struct weston_compositor *compositor)
1662 {
1663         if (compositor->state == WESTON_COMPOSITOR_SLEEPING)
1664                 return;
1665
1666         wl_event_source_timer_update(compositor->idle_source, 0);
1667         compositor->state = WESTON_COMPOSITOR_SLEEPING;
1668         weston_compositor_dpms(compositor, WESTON_DPMS_OFF);
1669 }
1670
1671 static int
1672 idle_handler(void *data)
1673 {
1674         struct weston_compositor *compositor = data;
1675
1676         if (compositor->idle_inhibit)
1677                 return 1;
1678
1679         compositor->state = WESTON_COMPOSITOR_IDLE;
1680         wl_signal_emit(&compositor->idle_signal, compositor);
1681
1682         return 1;
1683 }
1684
1685 WL_EXPORT void
1686 weston_plane_init(struct weston_plane *plane, int32_t x, int32_t y)
1687 {
1688         pixman_region32_init(&plane->damage);
1689         pixman_region32_init(&plane->clip);
1690         plane->x = x;
1691         plane->y = y;
1692 }
1693
1694 WL_EXPORT void
1695 weston_plane_release(struct weston_plane *plane)
1696 {
1697         pixman_region32_fini(&plane->damage);
1698         pixman_region32_fini(&plane->clip);
1699 }
1700
1701 WL_EXPORT void
1702 weston_compositor_stack_plane(struct weston_compositor *ec,
1703                               struct weston_plane *plane,
1704                               struct weston_plane *above)
1705 {
1706         if (above)
1707                 wl_list_insert(above->link.prev, &plane->link);
1708         else
1709                 wl_list_insert(&ec->plane_list, &plane->link);
1710 }
1711
1712 static void unbind_resource(struct wl_resource *resource)
1713 {
1714         wl_list_remove(&resource->link);
1715         free(resource);
1716 }
1717
1718 static void
1719 bind_output(struct wl_client *client,
1720             void *data, uint32_t version, uint32_t id)
1721 {
1722         struct weston_output *output = data;
1723         struct weston_mode *mode;
1724         struct wl_resource *resource;
1725
1726         resource = wl_client_add_object(client,
1727                                         &wl_output_interface, NULL, id, data);
1728
1729         wl_list_insert(&output->resource_list, &resource->link);
1730         resource->destroy = unbind_resource;
1731
1732         wl_output_send_geometry(resource,
1733                                 output->x,
1734                                 output->y,
1735                                 output->mm_width,
1736                                 output->mm_height,
1737                                 output->subpixel,
1738                                 output->make, output->model,
1739                                 output->transform);
1740
1741         wl_list_for_each (mode, &output->mode_list, link) {
1742                 wl_output_send_mode(resource,
1743                                     mode->flags,
1744                                     mode->width,
1745                                     mode->height,
1746                                     mode->refresh);
1747         }
1748 }
1749
1750 WL_EXPORT void
1751 weston_output_destroy(struct weston_output *output)
1752 {
1753         struct weston_compositor *c = output->compositor;
1754
1755         wl_signal_emit(&output->destroy_signal, output);
1756
1757         free(output->name);
1758         pixman_region32_fini(&output->region);
1759         pixman_region32_fini(&output->previous_damage);
1760         output->compositor->output_id_pool &= ~(1 << output->id);
1761
1762         wl_display_remove_global(c->wl_display, output->global);
1763 }
1764
1765 static void
1766 weston_output_compute_transform(struct weston_output *output)
1767 {
1768         struct weston_matrix transform;
1769         int flip;
1770
1771         weston_matrix_init(&transform);
1772         transform.type = WESTON_MATRIX_TRANSFORM_ROTATE;
1773
1774         switch(output->transform) {
1775         case WL_OUTPUT_TRANSFORM_FLIPPED:
1776         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
1777         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
1778         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
1779                 transform.type |= WESTON_MATRIX_TRANSFORM_OTHER;
1780                 flip = -1;
1781                 break;
1782         default:
1783                 flip = 1;
1784                 break;
1785         }
1786
1787         switch(output->transform) {
1788         case WL_OUTPUT_TRANSFORM_NORMAL:
1789         case WL_OUTPUT_TRANSFORM_FLIPPED:
1790                 transform.d[0] = flip;
1791                 transform.d[1] = 0;
1792                 transform.d[4] = 0;
1793                 transform.d[5] = 1;
1794                 break;
1795         case WL_OUTPUT_TRANSFORM_90:
1796         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
1797                 transform.d[0] = 0;
1798                 transform.d[1] = -flip;
1799                 transform.d[4] = 1;
1800                 transform.d[5] = 0;
1801                 break;
1802         case WL_OUTPUT_TRANSFORM_180:
1803         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
1804                 transform.d[0] = -flip;
1805                 transform.d[1] = 0;
1806                 transform.d[4] = 0;
1807                 transform.d[5] = -1;
1808                 break;
1809         case WL_OUTPUT_TRANSFORM_270:
1810         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
1811                 transform.d[0] = 0;
1812                 transform.d[1] = flip;
1813                 transform.d[4] = -1;
1814                 transform.d[5] = 0;
1815                 break;
1816         default:
1817                 break;
1818         }
1819
1820         weston_matrix_multiply(&output->matrix, &transform);
1821 }
1822
1823 WL_EXPORT void
1824 weston_output_update_matrix(struct weston_output *output)
1825 {
1826         float magnification;
1827         struct weston_matrix camera;
1828         struct weston_matrix modelview;
1829
1830         weston_matrix_init(&output->matrix);
1831         weston_matrix_translate(&output->matrix,
1832                                 -(output->x + (output->border.right + output->width - output->border.left) / 2.0),
1833                                 -(output->y + (output->border.bottom + output->height - output->border.top) / 2.0), 0);
1834
1835         weston_matrix_scale(&output->matrix,
1836                             2.0 / (output->width + output->border.left + output->border.right),
1837                             -2.0 / (output->height + output->border.top + output->border.bottom), 1);
1838
1839         weston_output_compute_transform(output);
1840
1841         if (output->zoom.active) {
1842                 magnification = 1 / (1 - output->zoom.spring_z.current);
1843                 weston_matrix_init(&camera);
1844                 weston_matrix_init(&modelview);
1845                 weston_output_update_zoom(output, output->zoom.type);
1846                 weston_matrix_translate(&camera, output->zoom.trans_x,
1847                                         -output->zoom.trans_y, 0);
1848                 weston_matrix_invert(&modelview, &camera);
1849                 weston_matrix_scale(&modelview, magnification, magnification, 1.0);
1850                 weston_matrix_multiply(&output->matrix, &modelview);
1851         }
1852
1853         output->dirty = 0;
1854 }
1855
1856 static void
1857 weston_output_transform_init(struct weston_output *output, uint32_t transform)
1858 {
1859         output->transform = transform;
1860
1861         switch (transform) {
1862         case WL_OUTPUT_TRANSFORM_90:
1863         case WL_OUTPUT_TRANSFORM_270:
1864         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
1865         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
1866                 /* Swap width and height */
1867                 output->width = output->current->height;
1868                 output->height = output->current->width;
1869                 break;
1870         case WL_OUTPUT_TRANSFORM_NORMAL:
1871         case WL_OUTPUT_TRANSFORM_180:
1872         case WL_OUTPUT_TRANSFORM_FLIPPED:
1873         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
1874                 output->width = output->current->width;
1875                 output->height = output->current->height;
1876                 break;
1877         default:
1878                 break;
1879         }
1880 }
1881
1882 WL_EXPORT void
1883 weston_output_move(struct weston_output *output, int x, int y)
1884 {
1885         output->x = x;
1886         output->y = y;
1887
1888         pixman_region32_init(&output->previous_damage);
1889         pixman_region32_init_rect(&output->region, x, y,
1890                                   output->width,
1891                                   output->height);
1892 }
1893
1894 WL_EXPORT void
1895 weston_output_init(struct weston_output *output, struct weston_compositor *c,
1896                    int x, int y, int width, int height, uint32_t transform)
1897 {
1898         output->compositor = c;
1899         output->x = x;
1900         output->y = y;
1901         output->border.top = 0;
1902         output->border.bottom = 0;
1903         output->border.left = 0;
1904         output->border.right = 0;
1905         output->mm_width = width;
1906         output->mm_height = height;
1907         output->dirty = 1;
1908
1909         weston_output_transform_init(output, transform);
1910         weston_output_init_zoom(output);
1911
1912         weston_output_move(output, x, y);
1913         weston_output_damage(output);
1914
1915         wl_signal_init(&output->frame_signal);
1916         wl_signal_init(&output->destroy_signal);
1917         wl_list_init(&output->animation_list);
1918         wl_list_init(&output->resource_list);
1919
1920         output->id = ffs(~output->compositor->output_id_pool) - 1;
1921         output->compositor->output_id_pool |= 1 << output->id;
1922
1923         output->global =
1924                 wl_display_add_global(c->wl_display, &wl_output_interface,
1925                                       output, bind_output);
1926         wl_signal_emit(&c->output_created_signal, output);
1927 }
1928
1929 static void
1930 compositor_bind(struct wl_client *client,
1931                 void *data, uint32_t version, uint32_t id)
1932 {
1933         struct weston_compositor *compositor = data;
1934
1935         wl_client_add_object(client, &wl_compositor_interface,
1936                              &compositor_interface, id, compositor);
1937 }
1938
1939 static void
1940 log_uname(void)
1941 {
1942         struct utsname usys;
1943
1944         uname(&usys);
1945
1946         weston_log("OS: %s, %s, %s, %s\n", usys.sysname, usys.release,
1947                                                 usys.version, usys.machine);
1948 }
1949
1950 WL_EXPORT int
1951 weston_environment_get_fd(const char *env)
1952 {
1953         char *e, *end;
1954         int fd, flags;
1955
1956         e = getenv(env);
1957         if (!e)
1958                 return -1;
1959         fd = strtol(e, &end, 0);
1960         if (*end != '\0')
1961                 return -1;
1962
1963         flags = fcntl(fd, F_GETFD);
1964         if (flags == -1)
1965                 return -1;
1966
1967         fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
1968         unsetenv(env);
1969
1970         return fd;
1971 }
1972
1973 WL_EXPORT int
1974 weston_compositor_init(struct weston_compositor *ec,
1975                        struct wl_display *display,
1976                        int *argc, char *argv[],
1977                        const char *config_file)
1978 {
1979         struct wl_event_loop *loop;
1980         struct xkb_rule_names xkb_names;
1981         const struct config_key keyboard_config_keys[] = {
1982                 { "keymap_rules", CONFIG_KEY_STRING, &xkb_names.rules },
1983                 { "keymap_model", CONFIG_KEY_STRING, &xkb_names.model },
1984                 { "keymap_layout", CONFIG_KEY_STRING, &xkb_names.layout },
1985                 { "keymap_variant", CONFIG_KEY_STRING, &xkb_names.variant },
1986                 { "keymap_options", CONFIG_KEY_STRING, &xkb_names.options },
1987         };
1988         const struct config_section cs[] = {
1989                 { "keyboard",
1990                   keyboard_config_keys, ARRAY_LENGTH(keyboard_config_keys) },
1991         };
1992
1993         memset(&xkb_names, 0, sizeof(xkb_names));
1994         parse_config_file(config_file, cs, ARRAY_LENGTH(cs), ec);
1995
1996         ec->wl_display = display;
1997         wl_signal_init(&ec->destroy_signal);
1998         wl_signal_init(&ec->activate_signal);
1999         wl_signal_init(&ec->kill_signal);
2000         wl_signal_init(&ec->idle_signal);
2001         wl_signal_init(&ec->wake_signal);
2002         wl_signal_init(&ec->show_input_panel_signal);
2003         wl_signal_init(&ec->hide_input_panel_signal);
2004         wl_signal_init(&ec->update_input_panel_signal);
2005         wl_signal_init(&ec->seat_created_signal);
2006         wl_signal_init(&ec->output_created_signal);
2007         ec->launcher_sock = weston_environment_get_fd("WESTON_LAUNCHER_SOCK");
2008
2009         ec->output_id_pool = 0;
2010
2011         if (!wl_display_add_global(display, &wl_compositor_interface,
2012                                    ec, compositor_bind))
2013                 return -1;
2014
2015         wl_list_init(&ec->surface_list);
2016         wl_list_init(&ec->plane_list);
2017         wl_list_init(&ec->layer_list);
2018         wl_list_init(&ec->seat_list);
2019         wl_list_init(&ec->output_list);
2020         wl_list_init(&ec->key_binding_list);
2021         wl_list_init(&ec->button_binding_list);
2022         wl_list_init(&ec->axis_binding_list);
2023         wl_list_init(&ec->debug_binding_list);
2024
2025         weston_plane_init(&ec->primary_plane, 0, 0);
2026         weston_compositor_stack_plane(ec, &ec->primary_plane, NULL);
2027
2028         if (weston_compositor_xkb_init(ec, &xkb_names) < 0)
2029                 return -1;
2030
2031         ec->ping_handler = NULL;
2032
2033         screenshooter_create(ec);
2034         text_cursor_position_notifier_create(ec);
2035         text_backend_init(ec);
2036
2037         wl_data_device_manager_init(ec->wl_display);
2038
2039         wl_display_init_shm(display);
2040
2041         loop = wl_display_get_event_loop(ec->wl_display);
2042         ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
2043         wl_event_source_timer_update(ec->idle_source, ec->idle_time * 1000);
2044
2045         ec->input_loop = wl_event_loop_create();
2046
2047         weston_layer_init(&ec->fade_layer, &ec->layer_list);
2048         weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
2049
2050         weston_compositor_schedule_repaint(ec);
2051
2052         return 0;
2053 }
2054
2055 WL_EXPORT void
2056 weston_compositor_shutdown(struct weston_compositor *ec)
2057 {
2058         struct weston_output *output, *next;
2059
2060         wl_event_source_remove(ec->idle_source);
2061         if (ec->input_loop_source)
2062                 wl_event_source_remove(ec->input_loop_source);
2063
2064         /* Destroy all outputs associated with this compositor */
2065         wl_list_for_each_safe(output, next, &ec->output_list, link)
2066                 output->destroy(output);
2067
2068         weston_binding_list_destroy_all(&ec->key_binding_list);
2069         weston_binding_list_destroy_all(&ec->button_binding_list);
2070         weston_binding_list_destroy_all(&ec->axis_binding_list);
2071         weston_binding_list_destroy_all(&ec->debug_binding_list);
2072
2073         weston_plane_release(&ec->primary_plane);
2074
2075         wl_event_loop_destroy(ec->input_loop);
2076 }
2077
2078 WL_EXPORT void
2079 weston_version(int *major, int *minor, int *micro)
2080 {
2081         *major = WESTON_VERSION_MAJOR;
2082         *minor = WESTON_VERSION_MINOR;
2083         *micro = WESTON_VERSION_MICRO;
2084 }
2085
2086 static int on_term_signal(int signal_number, void *data)
2087 {
2088         struct wl_display *display = data;
2089
2090         weston_log("caught signal %d\n", signal_number);
2091         wl_display_terminate(display);
2092
2093         return 1;
2094 }
2095
2096 #ifdef HAVE_LIBUNWIND
2097
2098 static void
2099 print_backtrace(void)
2100 {
2101         unw_cursor_t cursor;
2102         unw_context_t context;
2103         unw_word_t off;
2104         unw_proc_info_t pip;
2105         int ret, i = 0;
2106         char procname[256];
2107         const char *filename;
2108         Dl_info dlinfo;
2109
2110         pip.unwind_info = NULL;
2111         ret = unw_getcontext(&context);
2112         if (ret) {
2113                 weston_log("unw_getcontext: %d\n", ret);
2114                 return;
2115         }
2116
2117         ret = unw_init_local(&cursor, &context);
2118         if (ret) {
2119                 weston_log("unw_init_local: %d\n", ret);
2120                 return;
2121         }
2122
2123         ret = unw_step(&cursor);
2124         while (ret > 0) {
2125                 ret = unw_get_proc_info(&cursor, &pip);
2126                 if (ret) {
2127                         weston_log("unw_get_proc_info: %d\n", ret);
2128                         break;
2129                 }
2130
2131                 ret = unw_get_proc_name(&cursor, procname, 256, &off);
2132                 if (ret && ret != -UNW_ENOMEM) {
2133                         if (ret != -UNW_EUNSPEC)
2134                                 weston_log("unw_get_proc_name: %d\n", ret);
2135                         procname[0] = '?';
2136                         procname[1] = 0;
2137                 }
2138
2139                 if (dladdr((void *)(pip.start_ip + off), &dlinfo) && dlinfo.dli_fname &&
2140                     *dlinfo.dli_fname)
2141                         filename = dlinfo.dli_fname;
2142                 else
2143                         filename = "?";
2144                 
2145                 weston_log("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,
2146                            ret == -UNW_ENOMEM ? "..." : "", (int)off, (void *)(pip.start_ip + off));
2147
2148                 ret = unw_step(&cursor);
2149                 if (ret < 0)
2150                         weston_log("unw_step: %d\n", ret);
2151         }
2152 }
2153
2154 #else
2155
2156 static void
2157 print_backtrace(void)
2158 {
2159         void *buffer[32];
2160         int i, count;
2161         Dl_info info;
2162
2163         count = backtrace(buffer, ARRAY_LENGTH(buffer));
2164         for (i = 0; i < count; i++) {
2165                 dladdr(buffer[i], &info);
2166                 weston_log("  [%016lx]  %s  (%s)\n",
2167                         (long) buffer[i],
2168                         info.dli_sname ? info.dli_sname : "--",
2169                         info.dli_fname);
2170         }
2171 }
2172
2173 #endif
2174
2175 static void
2176 on_caught_signal(int s, siginfo_t *siginfo, void *context)
2177 {
2178         /* This signal handler will do a best-effort backtrace, and
2179          * then call the backend restore function, which will switch
2180          * back to the vt we launched from or ungrab X etc and then
2181          * raise SIGTRAP.  If we run weston under gdb from X or a
2182          * different vt, and tell gdb "handle *s* nostop", this
2183          * will allow weston to switch back to gdb on crash and then
2184          * gdb will catch the crash with SIGTRAP.*/
2185
2186         weston_log("caught signal: %d\n", s);
2187
2188         print_backtrace();
2189
2190         segv_compositor->restore(segv_compositor);
2191
2192         raise(SIGTRAP);
2193 }
2194
2195 static void *
2196 load_module(const char *name, const char *entrypoint)
2197 {
2198         char path[PATH_MAX];
2199         void *module, *init;
2200
2201         if (name[0] != '/')
2202                 snprintf(path, sizeof path, "%s/%s", MODULEDIR, name);
2203         else
2204                 snprintf(path, sizeof path, "%s", name);
2205
2206         module = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
2207         if (module) {
2208                 weston_log("Module '%s' already loaded\n", path);
2209                 dlclose(module);
2210                 return NULL;
2211         }
2212
2213         weston_log("Loading module '%s'\n", path);
2214         module = dlopen(path, RTLD_NOW);
2215         if (!module) {
2216                 weston_log("Failed to load module: %s\n", dlerror());
2217                 return NULL;
2218         }
2219
2220         init = dlsym(module, entrypoint);
2221         if (!init) {
2222                 weston_log("Failed to lookup init function: %s\n", dlerror());
2223                 dlclose(module);
2224                 return NULL;
2225         }
2226
2227         return init;
2228 }
2229
2230 static int
2231 load_modules(struct weston_compositor *ec, const char *modules,
2232              int *argc, char *argv[], const char *config_file)
2233 {
2234         const char *p, *end;
2235         char buffer[256];
2236         int (*module_init)(struct weston_compositor *ec,
2237                            int *argc, char *argv[], const char *config_file);
2238
2239         if (modules == NULL)
2240                 return 0;
2241
2242         p = modules;
2243         while (*p) {
2244                 end = strchrnul(p, ',');
2245                 snprintf(buffer, sizeof buffer, "%.*s", (int) (end - p), p);
2246                 module_init = load_module(buffer, "module_init");
2247                 if (module_init)
2248                         module_init(ec, argc, argv, config_file);
2249                 p = end;
2250                 while (*p == ',')
2251                         p++;
2252
2253         }
2254
2255         return 0;
2256 }
2257
2258 static const char xdg_error_message[] =
2259         "fatal: environment variable XDG_RUNTIME_DIR is not set.\n";
2260
2261 static const char xdg_wrong_message[] =
2262         "fatal: environment variable XDG_RUNTIME_DIR\n"
2263         "is set to \"%s\", which is not a directory.\n";
2264
2265 static const char xdg_wrong_mode_message[] =
2266         "warning: XDG_RUNTIME_DIR \"%s\" is not configured\n"
2267         "correctly.  Unix access mode must be 0700 but is %o,\n"
2268         "and XDG_RUNTIME_DIR must be owned by the user, but is\n"
2269         "owned by UID %d.\n";
2270
2271 static const char xdg_detail_message[] =
2272         "Refer to your distribution on how to get it, or\n"
2273         "http://www.freedesktop.org/wiki/Specifications/basedir-spec\n"
2274         "on how to implement it.\n";
2275
2276 static void
2277 verify_xdg_runtime_dir(void)
2278 {
2279         char *dir = getenv("XDG_RUNTIME_DIR");
2280         struct stat s;
2281
2282         if (!dir) {
2283                 weston_log(xdg_error_message);
2284                 weston_log_continue(xdg_detail_message);
2285                 exit(EXIT_FAILURE);
2286         }
2287
2288         if (stat(dir, &s) || !S_ISDIR(s.st_mode)) {
2289                 weston_log(xdg_wrong_message, dir);
2290                 weston_log_continue(xdg_detail_message);
2291                 exit(EXIT_FAILURE);
2292         }
2293
2294         if ((s.st_mode & 0777) != 0700 || s.st_uid != getuid()) {
2295                 weston_log(xdg_wrong_mode_message,
2296                            dir, s.st_mode & 0777, s.st_uid);
2297                 weston_log_continue(xdg_detail_message);
2298         }
2299 }
2300
2301 static int
2302 usage(int error_code)
2303 {
2304         fprintf(stderr,
2305                 "Usage: weston [OPTIONS]\n\n"
2306                 "This is weston version " VERSION ", the Wayland reference compositor.\n"
2307                 "Weston supports multiple backends, and depending on which backend is in use\n"
2308                 "different options will be accepted.\n\n"
2309
2310
2311                 "Core options:\n\n"
2312                 "  --version\t\tPrint weston version\n"
2313                 "  -B, --backend=MODULE\tBackend module, one of drm-backend.so,\n"
2314                 "\t\t\t\tfbdev-backend.so, x11-backend.so or\n"
2315                 "\t\t\t\twayland-backend.so\n"
2316                 "  -S, --socket=NAME\tName of socket to listen on\n"
2317                 "  -i, --idle-time=SECS\tIdle time in seconds\n"
2318                 "  --modules\t\tLoad the comma-separated list of modules\n"
2319                 "  --log==FILE\t\tLog to the given file\n"
2320                 "  -h, --help\t\tThis help message\n\n");
2321
2322         fprintf(stderr,
2323                 "Options for drm-backend.so:\n\n"
2324                 "  --connector=ID\tBring up only this connector\n"
2325                 "  --seat=SEAT\t\tThe seat that weston should run on\n"
2326                 "  --tty=TTY\t\tThe tty to use\n"
2327                 "  --use-pixman\t\tUse the pixman (CPU) renderer\n"
2328                 "  --current-mode\tPrefer current KMS mode over EDID preferred mode\n\n");
2329
2330         fprintf(stderr,
2331                 "Options for fbdev-backend.so:\n\n"
2332                 "  --tty=TTY\t\tThe tty to use\n"
2333                 "  --device=DEVICE\tThe framebuffer device to use\n\n");
2334
2335         fprintf(stderr,
2336                 "Options for x11-backend.so:\n\n"
2337                 "  --width=WIDTH\t\tWidth of X window\n"
2338                 "  --height=HEIGHT\tHeight of X window\n"
2339                 "  --fullscreen\t\tRun in fullscreen mode\n"
2340                 "  --use-pixman\t\tUse the pixman (CPU) renderer\n"
2341                 "  --output-count=COUNT\tCreate multiple outputs\n"
2342                 "  --no-input\t\tDont create input devices\n\n");
2343
2344         fprintf(stderr,
2345                 "Options for wayland-backend.so:\n\n"
2346                 "  --width=WIDTH\t\tWidth of Wayland surface\n"
2347                 "  --height=HEIGHT\tHeight of Wayland surface\n"
2348                 "  --display=DISPLAY\tWayland display to connect to\n\n");
2349
2350         exit(error_code);
2351 }
2352
2353 static void
2354 catch_signals(void)
2355 {
2356         struct sigaction action;
2357
2358         action.sa_flags = SA_SIGINFO | SA_RESETHAND;
2359         action.sa_sigaction = on_caught_signal;
2360         sigemptyset(&action.sa_mask);
2361         sigaction(SIGSEGV, &action, NULL);
2362         sigaction(SIGABRT, &action, NULL);
2363 }
2364
2365 int main(int argc, char *argv[])
2366 {
2367         int ret = EXIT_SUCCESS;
2368         struct wl_display *display;
2369         struct weston_compositor *ec;
2370         struct wl_event_source *signals[4];
2371         struct wl_event_loop *loop;
2372         struct weston_compositor
2373                 *(*backend_init)(struct wl_display *display,
2374                                  int *argc, char *argv[], const char *config_file);
2375         int i;
2376         char *backend = NULL;
2377         const char *modules = "desktop-shell.so", *option_modules = NULL;
2378         char *log = NULL;
2379         int32_t idle_time = 300;
2380         int32_t help = 0;
2381         char *socket_name = "wayland-0";
2382         int32_t version = 0;
2383         char *config_file;
2384
2385         const struct config_key core_config_keys[] = {
2386                 { "modules", CONFIG_KEY_STRING, &modules },
2387         };
2388
2389         const struct config_section cs[] = {
2390                 { "core",
2391                   core_config_keys, ARRAY_LENGTH(core_config_keys) },
2392         };
2393
2394         const struct weston_option core_options[] = {
2395                 { WESTON_OPTION_STRING, "backend", 'B', &backend },
2396                 { WESTON_OPTION_STRING, "socket", 'S', &socket_name },
2397                 { WESTON_OPTION_INTEGER, "idle-time", 'i', &idle_time },
2398                 { WESTON_OPTION_STRING, "modules", 0, &option_modules },
2399                 { WESTON_OPTION_STRING, "log", 0, &log },
2400                 { WESTON_OPTION_BOOLEAN, "help", 'h', &help },
2401                 { WESTON_OPTION_BOOLEAN, "version", 0, &version },
2402         };
2403
2404         parse_options(core_options, ARRAY_LENGTH(core_options), &argc, argv);
2405
2406         if (help)
2407                 usage(EXIT_SUCCESS);
2408
2409         if (version) {
2410                 printf(PACKAGE_STRING "\n");
2411                 return EXIT_SUCCESS;
2412         }
2413
2414         weston_log_file_open(log);
2415         
2416         weston_log("%s\n"
2417                    STAMP_SPACE "%s\n"
2418                    STAMP_SPACE "Bug reports to: %s\n"
2419                    STAMP_SPACE "Build: %s\n",
2420                    PACKAGE_STRING, PACKAGE_URL, PACKAGE_BUGREPORT,
2421                    BUILD_ID);
2422         log_uname();
2423
2424         verify_xdg_runtime_dir();
2425
2426         display = wl_display_create();
2427
2428         loop = wl_display_get_event_loop(display);
2429         signals[0] = wl_event_loop_add_signal(loop, SIGTERM, on_term_signal,
2430                                               display);
2431         signals[1] = wl_event_loop_add_signal(loop, SIGINT, on_term_signal,
2432                                               display);
2433         signals[2] = wl_event_loop_add_signal(loop, SIGQUIT, on_term_signal,
2434                                               display);
2435
2436         wl_list_init(&child_process_list);
2437         signals[3] = wl_event_loop_add_signal(loop, SIGCHLD, sigchld_handler,
2438                                               NULL);
2439
2440         if (!backend) {
2441                 if (getenv("WAYLAND_DISPLAY"))
2442                         backend = "wayland-backend.so";
2443                 else if (getenv("DISPLAY"))
2444                         backend = "x11-backend.so";
2445                 else
2446                         backend = WESTON_NATIVE_BACKEND;
2447         }
2448
2449         config_file = config_file_path("weston.ini");
2450         parse_config_file(config_file, cs, ARRAY_LENGTH(cs), NULL);
2451
2452         backend_init = load_module(backend, "backend_init");
2453         if (!backend_init)
2454                 exit(EXIT_FAILURE);
2455
2456         ec = backend_init(display, &argc, argv, config_file);
2457         if (ec == NULL) {
2458                 weston_log("fatal: failed to create compositor\n");
2459                 exit(EXIT_FAILURE);
2460         }
2461
2462         catch_signals();
2463         segv_compositor = ec;
2464
2465         ec->idle_time = idle_time;
2466
2467         setenv("WAYLAND_DISPLAY", socket_name, 1);
2468
2469         if (load_modules(ec, modules, &argc, argv, config_file) < 0)
2470                 goto out;
2471         if (load_modules(ec, option_modules, &argc, argv, config_file) < 0)
2472                 goto out;
2473
2474         free(config_file);
2475
2476         for (i = 1; i < argc; i++)
2477                 weston_log("fatal: unhandled option: %s\n", argv[i]);
2478         if (argc > 1) {
2479                 ret = EXIT_FAILURE;
2480                 goto out;
2481         }
2482
2483         if (wl_display_add_socket(display, socket_name)) {
2484                 weston_log("fatal: failed to add socket: %m\n");
2485                 ret = EXIT_FAILURE;
2486                 goto out;
2487         }
2488
2489         weston_compositor_wake(ec);
2490
2491         wl_display_run(display);
2492
2493  out:
2494         /* prevent further rendering while shutting down */
2495         ec->state = WESTON_COMPOSITOR_OFFSCREEN;
2496
2497         wl_signal_emit(&ec->destroy_signal, ec);
2498
2499         for (i = ARRAY_LENGTH(signals); i;)
2500                 wl_event_source_remove(signals[--i]);
2501
2502         weston_compositor_xkb_destroy(ec);
2503
2504         ec->destroy(ec);
2505         wl_display_destroy(display);
2506
2507         weston_log_file_close();
2508
2509         return ret;
2510 }