sdk: be C++ friendly
[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 wl_pointer *pointer = seat->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->surface.resource.destroy_signal);
275
276         wl_list_init(&surface->link);
277         wl_list_init(&surface->layer_link);
278
279         surface->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->surface.resource.client;
494
495         es->output_mask = mask;
496         if (es->surface.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->surface.resource, resource);
510                 if (1 << output->id & left)
511                         wl_surface_send_leave(&es->surface.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->surface.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 static 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_device_repick(struct weston_seat *seat)
929 {
930         const struct wl_pointer_grab_interface *interface;
931         struct weston_surface *surface, *focus;
932         struct wl_pointer *pointer = seat->seat.pointer;
933
934         if (!pointer)
935                 return;
936
937         surface = weston_compositor_pick_surface(seat->compositor,
938                                                  pointer->x,
939                                                  pointer->y,
940                                                  &pointer->current_x,
941                                                  &pointer->current_y);
942
943         if (&surface->surface != pointer->current) {
944                 interface = pointer->grab->interface;
945                 pointer->current = &surface->surface;
946                 interface->focus(pointer->grab, &surface->surface,
947                                  pointer->current_x,
948                                  pointer->current_y);
949         }
950
951         focus = (struct weston_surface *) pointer->grab->focus;
952         if (focus)
953                 weston_surface_from_global_fixed(focus,
954                                                  pointer->x,
955                                                  pointer->y,
956                                                  &pointer->grab->x,
957                                                  &pointer->grab->y);
958 }
959
960 static void
961 weston_compositor_repick(struct weston_compositor *compositor)
962 {
963         struct weston_seat *seat;
964
965         if (!compositor->focus)
966                 return;
967
968         wl_list_for_each(seat, &compositor->seat_list, link)
969                 weston_device_repick(seat);
970 }
971
972 WL_EXPORT void
973 weston_surface_unmap(struct weston_surface *surface)
974 {
975         struct weston_seat *seat;
976
977         weston_surface_damage_below(surface);
978         surface->output = NULL;
979         wl_list_remove(&surface->layer_link);
980
981         wl_list_for_each(seat, &surface->compositor->seat_list, link) {
982                 if (seat->seat.keyboard &&
983                     seat->seat.keyboard->focus == &surface->surface)
984                         wl_keyboard_set_focus(seat->seat.keyboard, NULL);
985                 if (seat->seat.pointer &&
986                     seat->seat.pointer->focus == &surface->surface)
987                         wl_pointer_set_focus(seat->seat.pointer,
988                                              NULL,
989                                              wl_fixed_from_int(0),
990                                              wl_fixed_from_int(0));
991         }
992
993         weston_surface_schedule_repaint(surface);
994 }
995
996 struct weston_frame_callback {
997         struct wl_resource resource;
998         struct wl_list link;
999 };
1000
1001 static void
1002 destroy_surface(struct wl_resource *resource)
1003 {
1004         struct weston_surface *surface =
1005                 container_of(resource,
1006                              struct weston_surface, surface.resource);
1007         struct weston_compositor *compositor = surface->compositor;
1008         struct weston_frame_callback *cb, *next;
1009
1010         assert(wl_list_empty(&surface->geometry.child_list));
1011
1012         if (weston_surface_is_mapped(surface))
1013                 weston_surface_unmap(surface);
1014
1015         wl_list_for_each_safe(cb, next,
1016                               &surface->pending.frame_callback_list, link)
1017                 wl_resource_destroy(&cb->resource);
1018
1019         pixman_region32_fini(&surface->pending.input);
1020         pixman_region32_fini(&surface->pending.opaque);
1021         pixman_region32_fini(&surface->pending.damage);
1022
1023         if (surface->pending.buffer)
1024                 wl_list_remove(&surface->pending.buffer_destroy_listener.link);
1025
1026         weston_buffer_reference(&surface->buffer_ref, NULL);
1027
1028         compositor->renderer->destroy_surface(surface);
1029
1030         pixman_region32_fini(&surface->transform.boundingbox);
1031         pixman_region32_fini(&surface->damage);
1032         pixman_region32_fini(&surface->opaque);
1033         pixman_region32_fini(&surface->clip);
1034         pixman_region32_fini(&surface->input);
1035
1036         wl_list_for_each_safe(cb, next, &surface->frame_callback_list, link)
1037                 wl_resource_destroy(&cb->resource);
1038
1039         weston_surface_set_transform_parent(surface, NULL);
1040
1041         free(surface);
1042 }
1043
1044 WL_EXPORT void
1045 weston_surface_destroy(struct weston_surface *surface)
1046 {
1047         /* Not a valid way to destroy a client surface */
1048         assert(surface->surface.resource.client == NULL);
1049
1050         wl_signal_emit(&surface->surface.resource.destroy_signal,
1051                        &surface->surface.resource);
1052         destroy_surface(&surface->surface.resource);
1053 }
1054
1055 static void
1056 weston_buffer_reference_handle_destroy(struct wl_listener *listener,
1057                                        void *data)
1058 {
1059         struct weston_buffer_reference *ref =
1060                 container_of(listener, struct weston_buffer_reference,
1061                              destroy_listener);
1062
1063         assert((struct wl_buffer *)data == ref->buffer);
1064         ref->buffer = NULL;
1065 }
1066
1067 WL_EXPORT void
1068 weston_buffer_reference(struct weston_buffer_reference *ref,
1069                         struct wl_buffer *buffer)
1070 {
1071         if (ref->buffer && buffer != ref->buffer) {
1072                 ref->buffer->busy_count--;
1073                 if (ref->buffer->busy_count == 0) {
1074                         assert(ref->buffer->resource.client != NULL);
1075                         wl_resource_queue_event(&ref->buffer->resource,
1076                                                 WL_BUFFER_RELEASE);
1077                 }
1078                 wl_list_remove(&ref->destroy_listener.link);
1079         }
1080
1081         if (buffer && buffer != ref->buffer) {
1082                 buffer->busy_count++;
1083                 wl_signal_add(&buffer->resource.destroy_signal,
1084                               &ref->destroy_listener);
1085         }
1086
1087         ref->buffer = buffer;
1088         ref->destroy_listener.notify = weston_buffer_reference_handle_destroy;
1089 }
1090
1091 static void
1092 weston_surface_attach(struct weston_surface *surface, struct wl_buffer *buffer)
1093 {
1094         weston_buffer_reference(&surface->buffer_ref, buffer);
1095
1096         if (!buffer) {
1097                 if (weston_surface_is_mapped(surface))
1098                         weston_surface_unmap(surface);
1099         }
1100
1101         surface->compositor->renderer->attach(surface, buffer);
1102 }
1103
1104 WL_EXPORT void
1105 weston_surface_restack(struct weston_surface *surface, struct wl_list *below)
1106 {
1107         wl_list_remove(&surface->layer_link);
1108         wl_list_insert(below, &surface->layer_link);
1109         weston_surface_damage_below(surface);
1110         weston_surface_damage(surface);
1111 }
1112
1113 WL_EXPORT void
1114 weston_compositor_damage_all(struct weston_compositor *compositor)
1115 {
1116         struct weston_output *output;
1117
1118         wl_list_for_each(output, &compositor->output_list, link)
1119                 weston_output_damage(output);
1120 }
1121
1122 WL_EXPORT void
1123 weston_output_damage(struct weston_output *output)
1124 {
1125         struct weston_compositor *compositor = output->compositor;
1126
1127         pixman_region32_union(&compositor->primary_plane.damage,
1128                               &compositor->primary_plane.damage,
1129                               &output->region);
1130         weston_output_schedule_repaint(output);
1131 }
1132
1133 static void
1134 surface_accumulate_damage(struct weston_surface *surface,
1135                           pixman_region32_t *opaque)
1136 {
1137         if (surface->buffer_ref.buffer &&
1138             wl_buffer_is_shm(surface->buffer_ref.buffer))
1139                 surface->compositor->renderer->flush_damage(surface);
1140
1141         if (surface->transform.enabled) {
1142                 pixman_box32_t *extents;
1143
1144                 extents = pixman_region32_extents(&surface->damage);
1145                 surface_compute_bbox(surface, extents->x1, extents->y1,
1146                                      extents->x2 - extents->x1,
1147                                      extents->y2 - extents->y1,
1148                                      &surface->damage);
1149                 pixman_region32_translate(&surface->damage,
1150                                           -surface->plane->x,
1151                                           -surface->plane->y);
1152         } else {
1153                 pixman_region32_translate(&surface->damage,
1154                                           surface->geometry.x - surface->plane->x,
1155                                           surface->geometry.y - surface->plane->y);
1156         }
1157
1158         pixman_region32_subtract(&surface->damage, &surface->damage, opaque);
1159         pixman_region32_union(&surface->plane->damage,
1160                               &surface->plane->damage, &surface->damage);
1161         empty_region(&surface->damage);
1162         pixman_region32_copy(&surface->clip, opaque);
1163         pixman_region32_union(opaque, opaque, &surface->transform.opaque);
1164 }
1165
1166 static void
1167 compositor_accumulate_damage(struct weston_compositor *ec)
1168 {
1169         struct weston_plane *plane;
1170         struct weston_surface *es;
1171         pixman_region32_t opaque, clip;
1172
1173         pixman_region32_init(&clip);
1174
1175         wl_list_for_each(plane, &ec->plane_list, link) {
1176                 pixman_region32_copy(&plane->clip, &clip);
1177
1178                 pixman_region32_init(&opaque);
1179
1180                 wl_list_for_each(es, &ec->surface_list, link) {
1181                         if (es->plane != plane)
1182                                 continue;
1183
1184                         surface_accumulate_damage(es, &opaque);
1185                 }
1186
1187                 pixman_region32_union(&clip, &clip, &opaque);
1188                 pixman_region32_fini(&opaque);
1189         }
1190
1191         pixman_region32_fini(&clip);
1192
1193         wl_list_for_each(es, &ec->surface_list, link) {
1194                 /* Both the renderer and the backend have seen the buffer
1195                  * by now. If renderer needs the buffer, it has its own
1196                  * reference set. If the backend wants to keep the buffer
1197                  * around for migrating the surface into a non-primary plane
1198                  * later, keep_buffer is true. Otherwise, drop the core
1199                  * reference now, and allow early buffer release. This enables
1200                  * clients to use single-buffering.
1201                  */
1202                 if (!es->keep_buffer)
1203                         weston_buffer_reference(&es->buffer_ref, NULL);
1204         }
1205 }
1206
1207 static void
1208 weston_output_repaint(struct weston_output *output, uint32_t msecs)
1209 {
1210         struct weston_compositor *ec = output->compositor;
1211         struct weston_surface *es;
1212         struct weston_layer *layer;
1213         struct weston_animation *animation, *next;
1214         struct weston_frame_callback *cb, *cnext;
1215         struct wl_list frame_callback_list;
1216         pixman_region32_t output_damage;
1217
1218         weston_compositor_update_drag_surfaces(ec);
1219
1220         /* Rebuild the surface list and update surface transforms up front. */
1221         wl_list_init(&ec->surface_list);
1222         wl_list_init(&frame_callback_list);
1223         wl_list_for_each(layer, &ec->layer_list, link) {
1224                 wl_list_for_each(es, &layer->surface_list, layer_link) {
1225                         weston_surface_update_transform(es);
1226                         wl_list_insert(ec->surface_list.prev, &es->link);
1227                         if (es->output == output) {
1228                                 wl_list_insert_list(&frame_callback_list,
1229                                                     &es->frame_callback_list);
1230                                 wl_list_init(&es->frame_callback_list);
1231                         }
1232                 }
1233         }
1234
1235         if (output->assign_planes && !output->disable_planes)
1236                 output->assign_planes(output);
1237         else
1238                 wl_list_for_each(es, &ec->surface_list, link)
1239                         weston_surface_move_to_plane(es, &ec->primary_plane);
1240
1241         compositor_accumulate_damage(ec);
1242
1243         pixman_region32_init(&output_damage);
1244         pixman_region32_intersect(&output_damage,
1245                                   &ec->primary_plane.damage, &output->region);
1246         pixman_region32_subtract(&output_damage,
1247                                  &output_damage, &ec->primary_plane.clip);
1248
1249         if (output->dirty)
1250                 weston_output_update_matrix(output);
1251
1252         output->repaint(output, &output_damage);
1253
1254         pixman_region32_fini(&output_damage);
1255
1256         output->repaint_needed = 0;
1257
1258         weston_compositor_repick(ec);
1259         wl_event_loop_dispatch(ec->input_loop, 0);
1260
1261         wl_list_for_each_safe(cb, cnext, &frame_callback_list, link) {
1262                 wl_callback_send_done(&cb->resource, msecs);
1263                 wl_resource_destroy(&cb->resource);
1264         }
1265
1266         wl_list_for_each_safe(animation, next, &output->animation_list, link) {
1267                 animation->frame_counter++;
1268                 animation->frame(animation, output, msecs);
1269         }
1270 }
1271
1272 static int
1273 weston_compositor_read_input(int fd, uint32_t mask, void *data)
1274 {
1275         struct weston_compositor *compositor = data;
1276
1277         wl_event_loop_dispatch(compositor->input_loop, 0);
1278
1279         return 1;
1280 }
1281
1282 WL_EXPORT void
1283 weston_output_finish_frame(struct weston_output *output, uint32_t msecs)
1284 {
1285         struct weston_compositor *compositor = output->compositor;
1286         struct wl_event_loop *loop =
1287                 wl_display_get_event_loop(compositor->wl_display);
1288         int fd;
1289
1290         output->frame_time = msecs;
1291         if (output->repaint_needed) {
1292                 weston_output_repaint(output, msecs);
1293                 return;
1294         }
1295
1296         output->repaint_scheduled = 0;
1297         if (compositor->input_loop_source)
1298                 return;
1299
1300         fd = wl_event_loop_get_fd(compositor->input_loop);
1301         compositor->input_loop_source =
1302                 wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
1303                                      weston_compositor_read_input, compositor);
1304 }
1305
1306 static void
1307 idle_repaint(void *data)
1308 {
1309         struct weston_output *output = data;
1310
1311         weston_output_finish_frame(output, weston_compositor_get_time());
1312 }
1313
1314 WL_EXPORT void
1315 weston_layer_init(struct weston_layer *layer, struct wl_list *below)
1316 {
1317         wl_list_init(&layer->surface_list);
1318         if (below != NULL)
1319                 wl_list_insert(below, &layer->link);
1320 }
1321
1322 WL_EXPORT void
1323 weston_output_schedule_repaint(struct weston_output *output)
1324 {
1325         struct weston_compositor *compositor = output->compositor;
1326         struct wl_event_loop *loop;
1327
1328         if (compositor->state == WESTON_COMPOSITOR_SLEEPING)
1329                 return;
1330
1331         loop = wl_display_get_event_loop(compositor->wl_display);
1332         output->repaint_needed = 1;
1333         if (output->repaint_scheduled)
1334                 return;
1335
1336         wl_event_loop_add_idle(loop, idle_repaint, output);
1337         output->repaint_scheduled = 1;
1338
1339         if (compositor->input_loop_source) {
1340                 wl_event_source_remove(compositor->input_loop_source);
1341                 compositor->input_loop_source = NULL;
1342         }
1343 }
1344
1345 WL_EXPORT void
1346 weston_compositor_schedule_repaint(struct weston_compositor *compositor)
1347 {
1348         struct weston_output *output;
1349
1350         wl_list_for_each(output, &compositor->output_list, link)
1351                 weston_output_schedule_repaint(output);
1352 }
1353
1354 static void
1355 surface_destroy(struct wl_client *client, struct wl_resource *resource)
1356 {
1357         wl_resource_destroy(resource);
1358 }
1359
1360 static void
1361 surface_attach(struct wl_client *client,
1362                struct wl_resource *resource,
1363                struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
1364 {
1365         struct weston_surface *surface = resource->data;
1366         struct wl_buffer *buffer = NULL;
1367
1368         if (buffer_resource)
1369                 buffer = buffer_resource->data;
1370
1371         /* Attach, attach, without commit in between does not send
1372          * wl_buffer.release. */
1373         if (surface->pending.buffer)
1374                 wl_list_remove(&surface->pending.buffer_destroy_listener.link);
1375
1376         surface->pending.sx = sx;
1377         surface->pending.sy = sy;
1378         surface->pending.buffer = buffer;
1379         surface->pending.newly_attached = 1;
1380         if (buffer) {
1381                 wl_signal_add(&buffer->resource.destroy_signal,
1382                               &surface->pending.buffer_destroy_listener);
1383         }
1384 }
1385
1386 static void
1387 surface_damage(struct wl_client *client,
1388                struct wl_resource *resource,
1389                int32_t x, int32_t y, int32_t width, int32_t height)
1390 {
1391         struct weston_surface *surface = resource->data;
1392
1393         pixman_region32_union_rect(&surface->pending.damage,
1394                                    &surface->pending.damage,
1395                                    x, y, width, height);
1396 }
1397
1398 static void
1399 destroy_frame_callback(struct wl_resource *resource)
1400 {
1401         struct weston_frame_callback *cb = resource->data;
1402
1403         wl_list_remove(&cb->link);
1404         free(cb);
1405 }
1406
1407 static void
1408 surface_frame(struct wl_client *client,
1409               struct wl_resource *resource, uint32_t callback)
1410 {
1411         struct weston_frame_callback *cb;
1412         struct weston_surface *surface = resource->data;
1413
1414         cb = malloc(sizeof *cb);
1415         if (cb == NULL) {
1416                 wl_resource_post_no_memory(resource);
1417                 return;
1418         }
1419
1420         cb->resource.object.interface = &wl_callback_interface;
1421         cb->resource.object.id = callback;
1422         cb->resource.destroy = destroy_frame_callback;
1423         cb->resource.client = client;
1424         cb->resource.data = cb;
1425
1426         wl_client_add_resource(client, &cb->resource);
1427         wl_list_insert(surface->pending.frame_callback_list.prev, &cb->link);
1428 }
1429
1430 static void
1431 surface_set_opaque_region(struct wl_client *client,
1432                           struct wl_resource *resource,
1433                           struct wl_resource *region_resource)
1434 {
1435         struct weston_surface *surface = resource->data;
1436         struct weston_region *region;
1437
1438         if (region_resource) {
1439                 region = region_resource->data;
1440                 pixman_region32_copy(&surface->pending.opaque,
1441                                      &region->region);
1442         } else {
1443                 empty_region(&surface->pending.opaque);
1444         }
1445 }
1446
1447 static void
1448 surface_set_input_region(struct wl_client *client,
1449                          struct wl_resource *resource,
1450                          struct wl_resource *region_resource)
1451 {
1452         struct weston_surface *surface = resource->data;
1453         struct weston_region *region;
1454
1455         if (region_resource) {
1456                 region = region_resource->data;
1457                 pixman_region32_copy(&surface->pending.input,
1458                                      &region->region);
1459         } else {
1460                 pixman_region32_fini(&surface->pending.input);
1461                 region_init_infinite(&surface->pending.input);
1462         }
1463 }
1464
1465 static void
1466 surface_commit(struct wl_client *client, struct wl_resource *resource)
1467 {
1468         struct weston_surface *surface = resource->data;
1469         pixman_region32_t opaque;
1470         int buffer_width = 0;
1471         int buffer_height = 0;
1472
1473         /* wl_surface.set_buffer_rotation */
1474         surface->buffer_transform = surface->pending.buffer_transform;
1475
1476         /* wl_surface.attach */
1477         if (surface->pending.buffer || surface->pending.newly_attached)
1478                 weston_surface_attach(surface, surface->pending.buffer);
1479
1480         if (surface->buffer_ref.buffer) {
1481                 buffer_width = weston_surface_buffer_width(surface);
1482                 buffer_height = weston_surface_buffer_height(surface);
1483         }
1484
1485         if (surface->configure && surface->pending.newly_attached)
1486                 surface->configure(surface,
1487                                    surface->pending.sx, surface->pending.sy,
1488                                    buffer_width, buffer_height);
1489
1490         if (surface->pending.buffer)
1491                 wl_list_remove(&surface->pending.buffer_destroy_listener.link);
1492         surface->pending.buffer = NULL;
1493         surface->pending.sx = 0;
1494         surface->pending.sy = 0;
1495         surface->pending.newly_attached = 0;
1496
1497         /* wl_surface.damage */
1498         pixman_region32_union(&surface->damage, &surface->damage,
1499                               &surface->pending.damage);
1500         pixman_region32_intersect_rect(&surface->damage, &surface->damage,
1501                                        0, 0,
1502                                        surface->geometry.width,
1503                                        surface->geometry.height);
1504         empty_region(&surface->pending.damage);
1505
1506         /* wl_surface.set_opaque_region */
1507         pixman_region32_init_rect(&opaque, 0, 0,
1508                                   surface->geometry.width,
1509                                   surface->geometry.height);
1510         pixman_region32_intersect(&opaque,
1511                                   &opaque, &surface->pending.opaque);
1512
1513         if (!pixman_region32_equal(&opaque, &surface->opaque)) {
1514                 pixman_region32_copy(&surface->opaque, &opaque);
1515                 weston_surface_geometry_dirty(surface);
1516         }
1517
1518         pixman_region32_fini(&opaque);
1519
1520         /* wl_surface.set_input_region */
1521         pixman_region32_fini(&surface->input);
1522         pixman_region32_init_rect(&surface->input, 0, 0,
1523                                   surface->geometry.width,
1524                                   surface->geometry.height);
1525         pixman_region32_intersect(&surface->input,
1526                                   &surface->input, &surface->pending.input);
1527
1528         /* wl_surface.frame */
1529         wl_list_insert_list(&surface->frame_callback_list,
1530                             &surface->pending.frame_callback_list);
1531         wl_list_init(&surface->pending.frame_callback_list);
1532
1533         weston_surface_schedule_repaint(surface);
1534 }
1535
1536 static void
1537 surface_set_buffer_transform(struct wl_client *client,
1538                              struct wl_resource *resource, int transform)
1539 {
1540         struct weston_surface *surface = resource->data;
1541
1542         surface->pending.buffer_transform = transform;
1543 }
1544
1545 static const struct wl_surface_interface surface_interface = {
1546         surface_destroy,
1547         surface_attach,
1548         surface_damage,
1549         surface_frame,
1550         surface_set_opaque_region,
1551         surface_set_input_region,
1552         surface_commit,
1553         surface_set_buffer_transform
1554 };
1555
1556 static void
1557 compositor_create_surface(struct wl_client *client,
1558                           struct wl_resource *resource, uint32_t id)
1559 {
1560         struct weston_compositor *ec = resource->data;
1561         struct weston_surface *surface;
1562
1563         surface = weston_surface_create(ec);
1564         if (surface == NULL) {
1565                 wl_resource_post_no_memory(resource);
1566                 return;
1567         }
1568
1569         surface->surface.resource.destroy = destroy_surface;
1570
1571         surface->surface.resource.object.id = id;
1572         surface->surface.resource.object.interface = &wl_surface_interface;
1573         surface->surface.resource.object.implementation =
1574                 (void (**)(void)) &surface_interface;
1575         surface->surface.resource.data = surface;
1576
1577         wl_client_add_resource(client, &surface->surface.resource);
1578 }
1579
1580 static void
1581 destroy_region(struct wl_resource *resource)
1582 {
1583         struct weston_region *region =
1584                 container_of(resource, struct weston_region, resource);
1585
1586         pixman_region32_fini(&region->region);
1587         free(region);
1588 }
1589
1590 static void
1591 region_destroy(struct wl_client *client, struct wl_resource *resource)
1592 {
1593         wl_resource_destroy(resource);
1594 }
1595
1596 static void
1597 region_add(struct wl_client *client, struct wl_resource *resource,
1598            int32_t x, int32_t y, int32_t width, int32_t height)
1599 {
1600         struct weston_region *region = resource->data;
1601
1602         pixman_region32_union_rect(&region->region, &region->region,
1603                                    x, y, width, height);
1604 }
1605
1606 static void
1607 region_subtract(struct wl_client *client, struct wl_resource *resource,
1608                 int32_t x, int32_t y, int32_t width, int32_t height)
1609 {
1610         struct weston_region *region = resource->data;
1611         pixman_region32_t rect;
1612
1613         pixman_region32_init_rect(&rect, x, y, width, height);
1614         pixman_region32_subtract(&region->region, &region->region, &rect);
1615         pixman_region32_fini(&rect);
1616 }
1617
1618 static const struct wl_region_interface region_interface = {
1619         region_destroy,
1620         region_add,
1621         region_subtract
1622 };
1623
1624 static void
1625 compositor_create_region(struct wl_client *client,
1626                          struct wl_resource *resource, uint32_t id)
1627 {
1628         struct weston_region *region;
1629
1630         region = malloc(sizeof *region);
1631         if (region == NULL) {
1632                 wl_resource_post_no_memory(resource);
1633                 return;
1634         }
1635
1636         region->resource.destroy = destroy_region;
1637
1638         region->resource.object.id = id;
1639         region->resource.object.interface = &wl_region_interface;
1640         region->resource.object.implementation =
1641                 (void (**)(void)) &region_interface;
1642         region->resource.data = region;
1643
1644         pixman_region32_init(&region->region);
1645
1646         wl_client_add_resource(client, &region->resource);
1647 }
1648
1649 static const struct wl_compositor_interface compositor_interface = {
1650         compositor_create_surface,
1651         compositor_create_region
1652 };
1653
1654 static void
1655 weston_compositor_dpms(struct weston_compositor *compositor,
1656                        enum dpms_enum state)
1657 {
1658         struct weston_output *output;
1659
1660         wl_list_for_each(output, &compositor->output_list, link)
1661                 if (output->set_dpms)
1662                         output->set_dpms(output, state);
1663 }
1664
1665 WL_EXPORT void
1666 weston_compositor_wake(struct weston_compositor *compositor)
1667 {
1668         switch (compositor->state) {
1669         case WESTON_COMPOSITOR_SLEEPING:
1670                 weston_compositor_dpms(compositor, WESTON_DPMS_ON);
1671                 /* fall through */
1672         case WESTON_COMPOSITOR_IDLE:
1673                 wl_signal_emit(&compositor->wake_signal, compositor);
1674                 /* fall through */
1675         default:
1676                 compositor->state = WESTON_COMPOSITOR_ACTIVE;
1677                 wl_event_source_timer_update(compositor->idle_source,
1678                                              compositor->idle_time * 1000);
1679         }
1680 }
1681
1682 WL_EXPORT void
1683 weston_compositor_sleep(struct weston_compositor *compositor)
1684 {
1685         if (compositor->state == WESTON_COMPOSITOR_SLEEPING)
1686                 return;
1687
1688         compositor->state = WESTON_COMPOSITOR_SLEEPING;
1689         weston_compositor_dpms(compositor, WESTON_DPMS_OFF);
1690 }
1691
1692 static void
1693 weston_compositor_idle_inhibit(struct weston_compositor *compositor)
1694 {
1695         weston_compositor_wake(compositor);
1696         compositor->idle_inhibit++;
1697 }
1698
1699 static void
1700 weston_compositor_idle_release(struct weston_compositor *compositor)
1701 {
1702         compositor->idle_inhibit--;
1703         weston_compositor_wake(compositor);
1704 }
1705
1706 static int
1707 idle_handler(void *data)
1708 {
1709         struct weston_compositor *compositor = data;
1710
1711         if (compositor->idle_inhibit)
1712                 return 1;
1713
1714         compositor->state = WESTON_COMPOSITOR_IDLE;
1715         wl_signal_emit(&compositor->idle_signal, compositor);
1716
1717         return 1;
1718 }
1719
1720 WL_EXPORT void
1721 weston_plane_init(struct weston_plane *plane, int32_t x, int32_t y)
1722 {
1723         pixman_region32_init(&plane->damage);
1724         pixman_region32_init(&plane->clip);
1725         plane->x = x;
1726         plane->y = y;
1727 }
1728
1729 WL_EXPORT void
1730 weston_plane_release(struct weston_plane *plane)
1731 {
1732         pixman_region32_fini(&plane->damage);
1733         pixman_region32_fini(&plane->clip);
1734 }
1735
1736 WL_EXPORT void
1737 weston_compositor_stack_plane(struct weston_compositor *ec,
1738                               struct weston_plane *plane,
1739                               struct weston_plane *above)
1740 {
1741         if (above)
1742                 wl_list_insert(above->link.prev, &plane->link);
1743         else
1744                 wl_list_insert(&ec->plane_list, &plane->link);
1745 }
1746
1747 static  void
1748 weston_seat_update_drag_surface(struct weston_seat *seat, int dx, int dy);
1749
1750 static void
1751 clip_pointer_motion(struct weston_seat *seat, wl_fixed_t *fx, wl_fixed_t *fy)
1752 {
1753         struct weston_compositor *ec = seat->compositor;
1754         struct weston_output *output, *prev = NULL;
1755         int x, y, old_x, old_y, valid = 0;
1756
1757         x = wl_fixed_to_int(*fx);
1758         y = wl_fixed_to_int(*fy);
1759         old_x = wl_fixed_to_int(seat->seat.pointer->x);
1760         old_y = wl_fixed_to_int(seat->seat.pointer->y);
1761
1762         wl_list_for_each(output, &ec->output_list, link) {
1763                 if (pixman_region32_contains_point(&output->region,
1764                                                    x, y, NULL))
1765                         valid = 1;
1766                 if (pixman_region32_contains_point(&output->region,
1767                                                    old_x, old_y, NULL))
1768                         prev = output;
1769         }
1770
1771         if (!valid) {
1772                 if (x < prev->x)
1773                         *fx = wl_fixed_from_int(prev->x);
1774                 else if (x >= prev->x + prev->width)
1775                         *fx = wl_fixed_from_int(prev->x +
1776                                                 prev->width - 1);
1777                 if (y < prev->y)
1778                         *fy = wl_fixed_from_int(prev->y);
1779                 else if (y >= prev->y + prev->current->height)
1780                         *fy = wl_fixed_from_int(prev->y +
1781                                                 prev->height - 1);
1782         }
1783 }
1784
1785 /* Takes absolute values */
1786 static void
1787 move_pointer(struct weston_seat *seat, wl_fixed_t x, wl_fixed_t y)
1788 {
1789         struct weston_compositor *ec = seat->compositor;
1790         struct wl_pointer *pointer = seat->seat.pointer;
1791         struct weston_output *output;
1792         int32_t ix, iy;
1793
1794         clip_pointer_motion(seat, &x, &y);
1795
1796         weston_seat_update_drag_surface(seat, x - pointer->x, y - pointer->y);
1797
1798         pointer->x = x;
1799         pointer->y = y;
1800
1801         ix = wl_fixed_to_int(x);
1802         iy = wl_fixed_to_int(y);
1803
1804         wl_list_for_each(output, &ec->output_list, link)
1805                 if (output->zoom.active &&
1806                     pixman_region32_contains_point(&output->region,
1807                                                    ix, iy, NULL))
1808                         weston_output_update_zoom(output, ZOOM_FOCUS_POINTER);
1809
1810         weston_device_repick(seat);
1811
1812         if (seat->sprite) {
1813                 weston_surface_set_position(seat->sprite,
1814                                             ix - seat->hotspot_x,
1815                                             iy - seat->hotspot_y);
1816                 weston_surface_schedule_repaint(seat->sprite);
1817         }
1818 }
1819
1820 WL_EXPORT void
1821 notify_motion(struct weston_seat *seat,
1822               uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
1823 {
1824         const struct wl_pointer_grab_interface *interface;
1825         struct weston_compositor *ec = seat->compositor;
1826         struct wl_pointer *pointer = seat->seat.pointer;
1827
1828         weston_compositor_wake(ec);
1829
1830         move_pointer(seat, pointer->x + dx, pointer->y + dy);
1831
1832         interface = pointer->grab->interface;
1833         interface->motion(pointer->grab, time,
1834                           pointer->grab->x, pointer->grab->y);
1835 }
1836
1837 WL_EXPORT void
1838 notify_motion_absolute(struct weston_seat *seat,
1839                        uint32_t time, wl_fixed_t x, wl_fixed_t y)
1840 {
1841         const struct wl_pointer_grab_interface *interface;
1842         struct weston_compositor *ec = seat->compositor;
1843         struct wl_pointer *pointer = seat->seat.pointer;
1844
1845         weston_compositor_wake(ec);
1846
1847         move_pointer(seat, x, y);
1848
1849         interface = pointer->grab->interface;
1850         interface->motion(pointer->grab, time,
1851                           pointer->grab->x, pointer->grab->y);
1852 }
1853
1854 WL_EXPORT void
1855 weston_surface_activate(struct weston_surface *surface,
1856                         struct weston_seat *seat)
1857 {
1858         struct weston_compositor *compositor = seat->compositor;
1859
1860         if (seat->seat.keyboard) {
1861                 wl_keyboard_set_focus(seat->seat.keyboard, &surface->surface);
1862                 wl_data_device_set_keyboard_focus(&seat->seat);
1863         }
1864
1865         wl_signal_emit(&compositor->activate_signal, surface);
1866 }
1867
1868 WL_EXPORT void
1869 notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
1870               enum wl_pointer_button_state state)
1871 {
1872         struct weston_compositor *compositor = seat->compositor;
1873         struct wl_pointer *pointer = seat->seat.pointer;
1874         struct weston_surface *focus =
1875                 (struct weston_surface *) pointer->focus;
1876         uint32_t serial = wl_display_next_serial(compositor->wl_display);
1877
1878         if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
1879                 if (compositor->ping_handler && focus)
1880                         compositor->ping_handler(focus, serial);
1881                 weston_compositor_idle_inhibit(compositor);
1882                 if (pointer->button_count == 0) {
1883                         pointer->grab_button = button;
1884                         pointer->grab_time = time;
1885                         pointer->grab_x = pointer->x;
1886                         pointer->grab_y = pointer->y;
1887                 }
1888                 pointer->button_count++;
1889         } else {
1890                 weston_compositor_idle_release(compositor);
1891                 pointer->button_count--;
1892         }
1893
1894         weston_compositor_run_button_binding(compositor, seat, time, button,
1895                                              state);
1896
1897         pointer->grab->interface->button(pointer->grab, time, button, state);
1898
1899         if (pointer->button_count == 1)
1900                 pointer->grab_serial =
1901                         wl_display_get_serial(compositor->wl_display);
1902 }
1903
1904 WL_EXPORT void
1905 notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
1906             wl_fixed_t value)
1907 {
1908         struct weston_compositor *compositor = seat->compositor;
1909         struct wl_pointer *pointer = seat->seat.pointer;
1910         struct weston_surface *focus =
1911                 (struct weston_surface *) pointer->focus;
1912         uint32_t serial = wl_display_next_serial(compositor->wl_display);
1913
1914         if (compositor->ping_handler && focus)
1915                 compositor->ping_handler(focus, serial);
1916
1917         weston_compositor_wake(compositor);
1918
1919         if (!value)
1920                 return;
1921
1922         if (weston_compositor_run_axis_binding(compositor, seat,
1923                                                    time, axis, value))
1924                 return;
1925
1926         if (pointer->focus_resource)
1927                 wl_pointer_send_axis(pointer->focus_resource, time, axis,
1928                                      value);
1929 }
1930
1931 WL_EXPORT void
1932 notify_modifiers(struct weston_seat *seat, uint32_t serial)
1933 {
1934         struct wl_keyboard *keyboard = &seat->keyboard.keyboard;
1935         struct wl_keyboard_grab *grab = keyboard->grab;
1936         uint32_t mods_depressed, mods_latched, mods_locked, group;
1937         uint32_t mods_lookup;
1938         enum weston_led leds = 0;
1939         int changed = 0;
1940
1941         /* Serialize and update our internal state, checking to see if it's
1942          * different to the previous state. */
1943         mods_depressed = xkb_state_serialize_mods(seat->xkb_state.state,
1944                                                   XKB_STATE_DEPRESSED);
1945         mods_latched = xkb_state_serialize_mods(seat->xkb_state.state,
1946                                                 XKB_STATE_LATCHED);
1947         mods_locked = xkb_state_serialize_mods(seat->xkb_state.state,
1948                                                XKB_STATE_LOCKED);
1949         group = xkb_state_serialize_group(seat->xkb_state.state,
1950                                           XKB_STATE_EFFECTIVE);
1951
1952         if (mods_depressed != seat->seat.keyboard->modifiers.mods_depressed ||
1953             mods_latched != seat->seat.keyboard->modifiers.mods_latched ||
1954             mods_locked != seat->seat.keyboard->modifiers.mods_locked ||
1955             group != seat->seat.keyboard->modifiers.group)
1956                 changed = 1;
1957
1958         seat->seat.keyboard->modifiers.mods_depressed = mods_depressed;
1959         seat->seat.keyboard->modifiers.mods_latched = mods_latched;
1960         seat->seat.keyboard->modifiers.mods_locked = mods_locked;
1961         seat->seat.keyboard->modifiers.group = group;
1962
1963         /* And update the modifier_state for bindings. */
1964         mods_lookup = mods_depressed | mods_latched;
1965         seat->modifier_state = 0;
1966         if (mods_lookup & (1 << seat->xkb_info.ctrl_mod))
1967                 seat->modifier_state |= MODIFIER_CTRL;
1968         if (mods_lookup & (1 << seat->xkb_info.alt_mod))
1969                 seat->modifier_state |= MODIFIER_ALT;
1970         if (mods_lookup & (1 << seat->xkb_info.super_mod))
1971                 seat->modifier_state |= MODIFIER_SUPER;
1972         if (mods_lookup & (1 << seat->xkb_info.shift_mod))
1973                 seat->modifier_state |= MODIFIER_SHIFT;
1974
1975         /* Finally, notify the compositor that LEDs have changed. */
1976         if (xkb_state_led_index_is_active(seat->xkb_state.state,
1977                                           seat->xkb_info.num_led))
1978                 leds |= LED_NUM_LOCK;
1979         if (xkb_state_led_index_is_active(seat->xkb_state.state,
1980                                           seat->xkb_info.caps_led))
1981                 leds |= LED_CAPS_LOCK;
1982         if (xkb_state_led_index_is_active(seat->xkb_state.state,
1983                                           seat->xkb_info.scroll_led))
1984                 leds |= LED_SCROLL_LOCK;
1985         if (leds != seat->xkb_state.leds && seat->led_update)
1986                 seat->led_update(seat, leds);
1987         seat->xkb_state.leds = leds;
1988
1989         if (changed) {
1990                 grab->interface->modifiers(grab,
1991                                            serial,
1992                                            keyboard->modifiers.mods_depressed,
1993                                            keyboard->modifiers.mods_latched,
1994                                            keyboard->modifiers.mods_locked,
1995                                            keyboard->modifiers.group);
1996         }
1997 }
1998
1999 static void
2000 update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
2001                       enum wl_keyboard_key_state state)
2002 {
2003         enum xkb_key_direction direction;
2004
2005         if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
2006                 direction = XKB_KEY_DOWN;
2007         else
2008                 direction = XKB_KEY_UP;
2009
2010         /* Offset the keycode by 8, as the evdev XKB rules reflect X's
2011          * broken keycode system, which starts at 8. */
2012         xkb_state_update_key(seat->xkb_state.state, key + 8, direction);
2013
2014         notify_modifiers(seat, serial);
2015 }
2016
2017 WL_EXPORT void
2018 notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
2019            enum wl_keyboard_key_state state,
2020            enum weston_key_state_update update_state)
2021 {
2022         struct weston_compositor *compositor = seat->compositor;
2023         struct weston_keyboard *keyboard = &seat->keyboard;
2024         struct weston_surface *focus =
2025                 (struct weston_surface *) keyboard->keyboard.focus;
2026         struct wl_keyboard_grab *grab = keyboard->keyboard.grab;
2027         uint32_t serial = wl_display_next_serial(compositor->wl_display);
2028         uint32_t *k, *end;
2029
2030         if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
2031                 if (compositor->ping_handler && focus)
2032                         compositor->ping_handler(focus, serial);
2033
2034                 weston_compositor_idle_inhibit(compositor);
2035                 keyboard->keyboard.grab_key = key;
2036                 keyboard->keyboard.grab_time = time;
2037         } else {
2038                 weston_compositor_idle_release(compositor);
2039         }
2040
2041         end = keyboard->keyboard.keys.data + keyboard->keyboard.keys.size;
2042         for (k = keyboard->keyboard.keys.data; k < end; k++) {
2043                 if (*k == key) {
2044                         /* Ignore server-generated repeats. */
2045                         if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
2046                                 return;
2047                         *k = *--end;
2048                 }
2049         }
2050         keyboard->keyboard.keys.size = (void *) end - keyboard->keyboard.keys.data;
2051         if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
2052                 k = wl_array_add(&keyboard->keyboard.keys, sizeof *k);
2053                 *k = key;
2054         }
2055
2056         if (grab == &keyboard->keyboard.default_grab ||
2057             grab == &keyboard->input_method_grab) {
2058                 weston_compositor_run_key_binding(compositor, seat, time, key,
2059                                                   state);
2060                 grab = keyboard->keyboard.grab;
2061         }
2062
2063         grab->interface->key(grab, time, key, state);
2064
2065         if (update_state == STATE_UPDATE_AUTOMATIC) {
2066                 update_modifier_state(seat,
2067                                       wl_display_get_serial(compositor->wl_display),
2068                                       key,
2069                                       state);
2070         }
2071 }
2072
2073 WL_EXPORT void
2074 notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
2075                      wl_fixed_t x, wl_fixed_t y)
2076 {
2077         struct weston_compositor *compositor = seat->compositor;
2078
2079         if (output) {
2080                 move_pointer(seat, x, y);
2081                 compositor->focus = 1;
2082         } else {
2083                 compositor->focus = 0;
2084                 /* FIXME: We should call wl_pointer_set_focus(seat,
2085                  * NULL) here, but somehow that breaks re-entry... */
2086         }
2087 }
2088
2089 static void
2090 destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
2091 {
2092         struct weston_seat *ws;
2093
2094         ws = container_of(listener, struct weston_seat,
2095                           saved_kbd_focus_listener);
2096
2097         ws->saved_kbd_focus = NULL;
2098 }
2099
2100 WL_EXPORT void
2101 notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
2102                          enum weston_key_state_update update_state)
2103 {
2104         struct weston_compositor *compositor = seat->compositor;
2105         struct wl_keyboard *keyboard = seat->seat.keyboard;
2106         struct wl_surface *surface;
2107         uint32_t *k, serial;
2108
2109         serial = wl_display_next_serial(compositor->wl_display);
2110         wl_array_copy(&keyboard->keys, keys);
2111         wl_array_for_each(k, &keyboard->keys) {
2112                 weston_compositor_idle_inhibit(compositor);
2113                 if (update_state == STATE_UPDATE_AUTOMATIC)
2114                         update_modifier_state(seat, serial, *k,
2115                                               WL_KEYBOARD_KEY_STATE_PRESSED);
2116         }
2117
2118         /* Run key bindings after we've updated the state. */
2119         wl_array_for_each(k, &keyboard->keys) {
2120                 weston_compositor_run_key_binding(compositor, seat, 0, *k,
2121                                                   WL_KEYBOARD_KEY_STATE_PRESSED);
2122         }
2123
2124         surface = seat->saved_kbd_focus;
2125
2126         if (surface) {
2127                 wl_list_remove(&seat->saved_kbd_focus_listener.link);
2128                 wl_keyboard_set_focus(keyboard, surface);
2129                 seat->saved_kbd_focus = NULL;
2130         }
2131 }
2132
2133 WL_EXPORT void
2134 notify_keyboard_focus_out(struct weston_seat *seat)
2135 {
2136         struct weston_compositor *compositor = seat->compositor;
2137         struct wl_keyboard *keyboard = seat->seat.keyboard;
2138         uint32_t *k, serial;
2139
2140         serial = wl_display_next_serial(compositor->wl_display);
2141         wl_array_for_each(k, &keyboard->keys) {
2142                 weston_compositor_idle_release(compositor);
2143                 update_modifier_state(seat, serial, *k,
2144                                       WL_KEYBOARD_KEY_STATE_RELEASED);
2145         }
2146
2147         seat->modifier_state = 0;
2148
2149         if (keyboard->focus) {
2150                 seat->saved_kbd_focus = keyboard->focus;
2151                 seat->saved_kbd_focus_listener.notify =
2152                         destroy_device_saved_kbd_focus;
2153                 wl_signal_add(&keyboard->focus->resource.destroy_signal,
2154                               &seat->saved_kbd_focus_listener);
2155         }
2156
2157         wl_keyboard_set_focus(keyboard, NULL);
2158         /* FIXME: We really need keyboard grab cancel here to
2159          * let the grab shut down properly.  As it is we leak
2160          * the grab data. */
2161         wl_keyboard_end_grab(keyboard);
2162 }
2163
2164 static void
2165 touch_set_focus(struct weston_seat *ws, struct wl_surface *surface)
2166 {
2167         struct wl_seat *seat = &ws->seat;
2168         struct wl_resource *resource;
2169
2170         if (seat->touch->focus == surface)
2171                 return;
2172
2173         if (seat->touch->focus_resource)
2174                 wl_list_remove(&seat->touch->focus_listener.link);
2175         seat->touch->focus = NULL;
2176         seat->touch->focus_resource = NULL;
2177
2178         if (surface) {
2179                 resource =
2180                         find_resource_for_client(&seat->touch->resource_list,
2181                                                  surface->resource.client);
2182                 if (!resource) {
2183                         weston_log("couldn't find resource\n");
2184                         return;
2185                 }
2186
2187                 seat->touch->focus = surface;
2188                 seat->touch->focus_resource = resource;
2189                 wl_signal_add(&resource->destroy_signal,
2190                               &seat->touch->focus_listener);
2191         }
2192 }
2193
2194 /**
2195  * notify_touch - emulates button touches and notifies surfaces accordingly.
2196  *
2197  * It assumes always the correct cycle sequence until it gets here: touch_down
2198  * → touch_update → ... → touch_update → touch_end. The driver is responsible
2199  * for sending along such order.
2200  *
2201  */
2202 WL_EXPORT void
2203 notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
2204              wl_fixed_t x, wl_fixed_t y, int touch_type)
2205 {
2206         struct weston_compositor *ec = seat->compositor;
2207         struct wl_touch *touch = seat->seat.touch;
2208         struct wl_touch_grab *grab = touch->grab;
2209         struct weston_surface *es;
2210         wl_fixed_t sx, sy;
2211
2212         /* Update grab's global coordinates. */
2213         touch->grab_x = x;
2214         touch->grab_y = y;
2215
2216         switch (touch_type) {
2217         case WL_TOUCH_DOWN:
2218                 weston_compositor_idle_inhibit(ec);
2219
2220                 seat->num_tp++;
2221
2222                 /* the first finger down picks the surface, and all further go
2223                  * to that surface for the remainder of the touch session i.e.
2224                  * until all touch points are up again. */
2225                 if (seat->num_tp == 1) {
2226                         es = weston_compositor_pick_surface(ec, x, y, &sx, &sy);
2227                         touch_set_focus(seat, &es->surface);
2228                 } else if (touch->focus) {
2229                         es = (struct weston_surface *) touch->focus;
2230                         weston_surface_from_global_fixed(es, x, y, &sx, &sy);
2231                 } else {
2232                         /* Unexpected condition: We have non-initial touch but
2233                          * there is no focused surface.
2234                          */
2235                         weston_log("touch event received with %d points down"
2236                                    "but no surface focused\n", seat->num_tp);
2237                         return;
2238                 }
2239
2240                 grab->interface->down(grab, time, touch_id, sx, sy);
2241                 break;
2242         case WL_TOUCH_MOTION:
2243                 es = (struct weston_surface *) touch->focus;
2244                 if (!es)
2245                         break;
2246
2247                 weston_surface_from_global_fixed(es, x, y, &sx, &sy);
2248                 grab->interface->motion(grab, time, touch_id, sx, sy);
2249                 break;
2250         case WL_TOUCH_UP:
2251                 weston_compositor_idle_release(ec);
2252                 seat->num_tp--;
2253
2254                 grab->interface->up(grab, time, touch_id);
2255                 if (seat->num_tp == 0)
2256                         touch_set_focus(seat, NULL);
2257                 break;
2258         }
2259 }
2260
2261 static void
2262 pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
2263 {
2264         struct weston_seat *seat = container_of(listener, struct weston_seat,
2265                                                 sprite_destroy_listener);
2266
2267         seat->sprite = NULL;
2268 }
2269
2270 static void
2271 pointer_cursor_surface_configure(struct weston_surface *es,
2272                                  int32_t dx, int32_t dy, int32_t width, int32_t height)
2273 {
2274         struct weston_seat *seat = es->configure_private;
2275         int x, y;
2276
2277         if (width == 0)
2278                 return;
2279
2280         assert(es == seat->sprite);
2281
2282         seat->hotspot_x -= dx;
2283         seat->hotspot_y -= dy;
2284
2285         x = wl_fixed_to_int(seat->seat.pointer->x) - seat->hotspot_x;
2286         y = wl_fixed_to_int(seat->seat.pointer->y) - seat->hotspot_y;
2287
2288         weston_surface_configure(seat->sprite, x, y,
2289                                  width, height);
2290
2291         empty_region(&es->pending.input);
2292
2293         if (!weston_surface_is_mapped(es)) {
2294                 wl_list_insert(&es->compositor->cursor_layer.surface_list,
2295                                &es->layer_link);
2296                 weston_surface_update_transform(es);
2297         }
2298 }
2299
2300 static void
2301 pointer_unmap_sprite(struct weston_seat *seat)
2302 {
2303         if (weston_surface_is_mapped(seat->sprite))
2304                 weston_surface_unmap(seat->sprite);
2305
2306         wl_list_remove(&seat->sprite_destroy_listener.link);
2307         seat->sprite->configure = NULL;
2308         seat->sprite->configure_private = NULL;
2309         seat->sprite = NULL;
2310 }
2311
2312 static void
2313 pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
2314                    uint32_t serial, struct wl_resource *surface_resource,
2315                    int32_t x, int32_t y)
2316 {
2317         struct weston_seat *seat = resource->data;
2318         struct weston_surface *surface = NULL;
2319
2320         if (surface_resource)
2321                 surface = surface_resource->data;
2322
2323         if (seat->seat.pointer->focus == NULL)
2324                 return;
2325         if (seat->seat.pointer->focus->resource.client != client)
2326                 return;
2327         if (seat->seat.pointer->focus_serial - serial > UINT32_MAX / 2)
2328                 return;
2329
2330         if (surface && surface != seat->sprite) {
2331                 if (surface->configure) {
2332                         wl_resource_post_error(&surface->surface.resource,
2333                                                WL_DISPLAY_ERROR_INVALID_OBJECT,
2334                                                "surface->configure already "
2335                                                "set");
2336                         return;
2337                 }
2338         }
2339
2340         if (seat->sprite)
2341                 pointer_unmap_sprite(seat);
2342
2343         if (!surface)
2344                 return;
2345
2346         wl_signal_add(&surface->surface.resource.destroy_signal,
2347                       &seat->sprite_destroy_listener);
2348
2349         surface->configure = pointer_cursor_surface_configure;
2350         surface->configure_private = seat;
2351         seat->sprite = surface;
2352         seat->hotspot_x = x;
2353         seat->hotspot_y = y;
2354
2355         if (surface->buffer_ref.buffer)
2356                 pointer_cursor_surface_configure(surface, 0, 0, weston_surface_buffer_width(surface),
2357                                                                 weston_surface_buffer_height(surface));
2358 }
2359
2360 static const struct wl_pointer_interface pointer_interface = {
2361         pointer_set_cursor
2362 };
2363
2364 static void
2365 handle_drag_surface_destroy(struct wl_listener *listener, void *data)
2366 {
2367         struct weston_seat *seat;
2368
2369         seat = container_of(listener, struct weston_seat,
2370                             drag_surface_destroy_listener);
2371
2372         seat->drag_surface = NULL;
2373 }
2374
2375 static void unbind_resource(struct wl_resource *resource)
2376 {
2377         wl_list_remove(&resource->link);
2378         free(resource);
2379 }
2380
2381 static void
2382 seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
2383                  uint32_t id)
2384 {
2385         struct weston_seat *seat = resource->data;
2386         struct wl_resource *cr;
2387
2388         if (!seat->seat.pointer)
2389                 return;
2390
2391         cr = wl_client_add_object(client, &wl_pointer_interface,
2392                                   &pointer_interface, id, seat);
2393         wl_list_insert(&seat->seat.pointer->resource_list, &cr->link);
2394         cr->destroy = unbind_resource;
2395
2396         if (seat->seat.pointer->focus &&
2397             seat->seat.pointer->focus->resource.client == client) {
2398                 struct weston_surface *surface;
2399                 wl_fixed_t sx, sy;
2400
2401                 surface = (struct weston_surface *) seat->seat.pointer->focus;
2402                 weston_surface_from_global_fixed(surface,
2403                                                  seat->seat.pointer->x,
2404                                                  seat->seat.pointer->y,
2405                                                  &sx,
2406                                                  &sy);
2407                 wl_pointer_set_focus(seat->seat.pointer,
2408                                      seat->seat.pointer->focus,
2409                                      sx,
2410                                      sy);
2411         }
2412 }
2413
2414 static void
2415 seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
2416                   uint32_t id)
2417 {
2418         struct weston_seat *seat = resource->data;
2419         struct wl_resource *cr;
2420
2421         if (!seat->seat.keyboard)
2422                 return;
2423
2424         cr = wl_client_add_object(client, &wl_keyboard_interface, NULL, id,
2425                                   seat);
2426         wl_list_insert(&seat->seat.keyboard->resource_list, &cr->link);
2427         cr->destroy = unbind_resource;
2428
2429         wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
2430                                 seat->xkb_info.keymap_fd,
2431                                 seat->xkb_info.keymap_size);
2432
2433         if (seat->seat.keyboard->focus &&
2434             seat->seat.keyboard->focus->resource.client == client) {
2435                 wl_keyboard_set_focus(seat->seat.keyboard,
2436                                       seat->seat.keyboard->focus);
2437                 wl_data_device_set_keyboard_focus(&seat->seat);
2438         }
2439 }
2440
2441 static void
2442 seat_get_touch(struct wl_client *client, struct wl_resource *resource,
2443                uint32_t id)
2444 {
2445         struct weston_seat *seat = resource->data;
2446         struct wl_resource *cr;
2447
2448         if (!seat->seat.touch)
2449                 return;
2450
2451         cr = wl_client_add_object(client, &wl_touch_interface, NULL, id, seat);
2452         wl_list_insert(&seat->seat.touch->resource_list, &cr->link);
2453         cr->destroy = unbind_resource;
2454 }
2455
2456 static const struct wl_seat_interface seat_interface = {
2457         seat_get_pointer,
2458         seat_get_keyboard,
2459         seat_get_touch,
2460 };
2461
2462 static void
2463 bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
2464 {
2465         struct wl_seat *seat = data;
2466         struct wl_resource *resource;
2467         enum wl_seat_capability caps = 0;
2468
2469         resource = wl_client_add_object(client, &wl_seat_interface,
2470                                         &seat_interface, id, data);
2471         wl_list_insert(&seat->base_resource_list, &resource->link);
2472         resource->destroy = unbind_resource;
2473
2474         if (seat->pointer)
2475                 caps |= WL_SEAT_CAPABILITY_POINTER;
2476         if (seat->keyboard)
2477                 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
2478         if (seat->touch)
2479                 caps |= WL_SEAT_CAPABILITY_TOUCH;
2480
2481         wl_seat_send_capabilities(resource, caps);
2482 }
2483
2484 static void
2485 device_handle_new_drag_icon(struct wl_listener *listener, void *data)
2486 {
2487         struct weston_seat *seat;
2488
2489         seat = container_of(listener, struct weston_seat,
2490                             new_drag_icon_listener);
2491
2492         weston_seat_update_drag_surface(seat, 0, 0);
2493 }
2494
2495 static int
2496 weston_compositor_xkb_init(struct weston_compositor *ec,
2497                            struct xkb_rule_names *names)
2498 {
2499         if (ec->xkb_context == NULL) {
2500                 ec->xkb_context = xkb_context_new(0);
2501                 if (ec->xkb_context == NULL) {
2502                         weston_log("failed to create XKB context\n");
2503                         return -1;
2504                 }
2505         }
2506
2507         if (names)
2508                 ec->xkb_names = *names;
2509         if (!ec->xkb_names.rules)
2510                 ec->xkb_names.rules = strdup("evdev");
2511         if (!ec->xkb_names.model)
2512                 ec->xkb_names.model = strdup("pc105");
2513         if (!ec->xkb_names.layout)
2514                 ec->xkb_names.layout = strdup("us");
2515
2516         return 0;
2517 }
2518
2519 static void xkb_info_destroy(struct weston_xkb_info *xkb_info)
2520 {
2521         if (xkb_info->keymap)
2522                 xkb_map_unref(xkb_info->keymap);
2523
2524         if (xkb_info->keymap_area)
2525                 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
2526         if (xkb_info->keymap_fd >= 0)
2527                 close(xkb_info->keymap_fd);
2528 }
2529
2530 static void weston_compositor_xkb_destroy(struct weston_compositor *ec)
2531 {
2532         free((char *) ec->xkb_names.rules);
2533         free((char *) ec->xkb_names.model);
2534         free((char *) ec->xkb_names.layout);
2535         free((char *) ec->xkb_names.variant);
2536         free((char *) ec->xkb_names.options);
2537
2538         xkb_info_destroy(&ec->xkb_info);
2539         xkb_context_unref(ec->xkb_context);
2540 }
2541
2542 static int
2543 weston_xkb_info_new_keymap(struct weston_xkb_info *xkb_info)
2544 {
2545         char *keymap_str;
2546
2547         xkb_info->shift_mod = xkb_map_mod_get_index(xkb_info->keymap,
2548                                                     XKB_MOD_NAME_SHIFT);
2549         xkb_info->caps_mod = xkb_map_mod_get_index(xkb_info->keymap,
2550                                                    XKB_MOD_NAME_CAPS);
2551         xkb_info->ctrl_mod = xkb_map_mod_get_index(xkb_info->keymap,
2552                                                    XKB_MOD_NAME_CTRL);
2553         xkb_info->alt_mod = xkb_map_mod_get_index(xkb_info->keymap,
2554                                                   XKB_MOD_NAME_ALT);
2555         xkb_info->mod2_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod2");
2556         xkb_info->mod3_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod3");
2557         xkb_info->super_mod = xkb_map_mod_get_index(xkb_info->keymap,
2558                                                     XKB_MOD_NAME_LOGO);
2559         xkb_info->mod5_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod5");
2560
2561         xkb_info->num_led = xkb_map_led_get_index(xkb_info->keymap,
2562                                                   XKB_LED_NAME_NUM);
2563         xkb_info->caps_led = xkb_map_led_get_index(xkb_info->keymap,
2564                                                    XKB_LED_NAME_CAPS);
2565         xkb_info->scroll_led = xkb_map_led_get_index(xkb_info->keymap,
2566                                                      XKB_LED_NAME_SCROLL);
2567
2568         keymap_str = xkb_map_get_as_string(xkb_info->keymap);
2569         if (keymap_str == NULL) {
2570                 weston_log("failed to get string version of keymap\n");
2571                 return -1;
2572         }
2573         xkb_info->keymap_size = strlen(keymap_str) + 1;
2574
2575         xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
2576         if (xkb_info->keymap_fd < 0) {
2577                 weston_log("creating a keymap file for %lu bytes failed: %m\n",
2578                         (unsigned long) xkb_info->keymap_size);
2579                 goto err_keymap_str;
2580         }
2581
2582         xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
2583                                      PROT_READ | PROT_WRITE,
2584                                      MAP_SHARED, xkb_info->keymap_fd, 0);
2585         if (xkb_info->keymap_area == MAP_FAILED) {
2586                 weston_log("failed to mmap() %lu bytes\n",
2587                         (unsigned long) xkb_info->keymap_size);
2588                 goto err_dev_zero;
2589         }
2590         strcpy(xkb_info->keymap_area, keymap_str);
2591         free(keymap_str);
2592
2593         return 0;
2594
2595 err_dev_zero:
2596         close(xkb_info->keymap_fd);
2597         xkb_info->keymap_fd = -1;
2598 err_keymap_str:
2599         free(keymap_str);
2600         return -1;
2601 }
2602
2603 static int
2604 weston_compositor_build_global_keymap(struct weston_compositor *ec)
2605 {
2606         if (ec->xkb_info.keymap != NULL)
2607                 return 0;
2608
2609         ec->xkb_info.keymap = xkb_map_new_from_names(ec->xkb_context,
2610                                                      &ec->xkb_names,
2611                                                      0);
2612         if (ec->xkb_info.keymap == NULL) {
2613                 weston_log("failed to compile global XKB keymap\n");
2614                 weston_log("  tried rules %s, model %s, layout %s, variant %s, "
2615                         "options %s\n",
2616                         ec->xkb_names.rules, ec->xkb_names.model,
2617                         ec->xkb_names.layout, ec->xkb_names.variant,
2618                         ec->xkb_names.options);
2619                 return -1;
2620         }
2621
2622         if (weston_xkb_info_new_keymap(&ec->xkb_info) < 0)
2623                 return -1;
2624
2625         return 0;
2626 }
2627
2628 WL_EXPORT int
2629 weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
2630 {
2631         if (seat->has_keyboard)
2632                 return 0;
2633
2634         if (keymap != NULL) {
2635                 seat->xkb_info.keymap = xkb_map_ref(keymap);
2636                 if (weston_xkb_info_new_keymap(&seat->xkb_info) < 0)
2637                         return -1;
2638         } else {
2639                 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
2640                         return -1;
2641                 seat->xkb_info = seat->compositor->xkb_info;
2642                 seat->xkb_info.keymap = xkb_map_ref(seat->xkb_info.keymap);
2643         }
2644
2645         seat->xkb_state.state = xkb_state_new(seat->xkb_info.keymap);
2646         if (seat->xkb_state.state == NULL) {
2647                 weston_log("failed to initialise XKB state\n");
2648                 return -1;
2649         }
2650
2651         seat->xkb_state.leds = 0;
2652
2653         wl_keyboard_init(&seat->keyboard.keyboard);
2654         wl_seat_set_keyboard(&seat->seat, &seat->keyboard.keyboard);
2655
2656         seat->has_keyboard = 1;
2657
2658         return 0;
2659 }
2660
2661 WL_EXPORT void
2662 weston_seat_init_pointer(struct weston_seat *seat)
2663 {
2664         if (seat->has_pointer)
2665                 return;
2666
2667         wl_pointer_init(&seat->pointer);
2668         wl_seat_set_pointer(&seat->seat, &seat->pointer);
2669
2670         seat->has_pointer = 1;
2671 }
2672
2673 WL_EXPORT void
2674 weston_seat_init_touch(struct weston_seat *seat)
2675 {
2676         if (seat->has_touch)
2677                 return;
2678
2679         wl_touch_init(&seat->touch);
2680         wl_seat_set_touch(&seat->seat, &seat->touch);
2681
2682         seat->has_touch = 1;
2683 }
2684
2685 WL_EXPORT void
2686 weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec)
2687 {
2688         wl_seat_init(&seat->seat);
2689         seat->has_pointer = 0;
2690         seat->has_keyboard = 0;
2691         seat->has_touch = 0;
2692
2693         wl_display_add_global(ec->wl_display, &wl_seat_interface, seat,
2694                               bind_seat);
2695
2696         seat->sprite = NULL;
2697         seat->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
2698
2699         seat->compositor = ec;
2700         seat->hotspot_x = 16;
2701         seat->hotspot_y = 16;
2702         seat->modifier_state = 0;
2703         seat->num_tp = 0;
2704
2705         seat->drag_surface_destroy_listener.notify =
2706                 handle_drag_surface_destroy;
2707
2708         wl_list_insert(ec->seat_list.prev, &seat->link);
2709
2710         seat->new_drag_icon_listener.notify = device_handle_new_drag_icon;
2711         wl_signal_add(&seat->seat.drag_icon_signal,
2712                       &seat->new_drag_icon_listener);
2713
2714         clipboard_create(seat);
2715
2716         wl_signal_init(&seat->destroy_signal);
2717         wl_signal_emit(&ec->seat_created_signal, seat);
2718 }
2719
2720 WL_EXPORT void
2721 weston_seat_release(struct weston_seat *seat)
2722 {
2723         wl_list_remove(&seat->link);
2724         /* The global object is destroyed at wl_display_destroy() time. */
2725
2726         if (seat->sprite)
2727                 pointer_unmap_sprite(seat);
2728
2729         if (seat->xkb_state.state != NULL)
2730                 xkb_state_unref(seat->xkb_state.state);
2731         xkb_info_destroy(&seat->xkb_info);
2732
2733         wl_seat_release(&seat->seat);
2734         wl_signal_emit(&seat->destroy_signal, seat);
2735 }
2736
2737 static void
2738 drag_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
2739 {
2740         empty_region(&es->pending.input);
2741
2742         weston_surface_configure(es,
2743                                  es->geometry.x + sx, es->geometry.y + sy,
2744                                  width, height);
2745 }
2746
2747 static int
2748 device_setup_new_drag_surface(struct weston_seat *ws,
2749                               struct weston_surface *surface)
2750 {
2751         struct wl_seat *seat = &ws->seat;
2752
2753         if (surface->configure) {
2754                 wl_resource_post_error(&surface->surface.resource,
2755                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
2756                                        "surface->configure already set");
2757                 return 0;
2758         }
2759
2760         ws->drag_surface = surface;
2761
2762         weston_surface_set_position(ws->drag_surface,
2763                                     wl_fixed_to_double(seat->pointer->x),
2764                                     wl_fixed_to_double(seat->pointer->y));
2765
2766         surface->configure = drag_surface_configure;
2767
2768         wl_signal_add(&surface->surface.resource.destroy_signal,
2769                        &ws->drag_surface_destroy_listener);
2770
2771         return 1;
2772 }
2773
2774 static void
2775 device_release_drag_surface(struct weston_seat *seat)
2776 {
2777         if (weston_surface_is_mapped(seat->drag_surface))
2778                 weston_surface_unmap(seat->drag_surface);
2779
2780         seat->drag_surface->configure = NULL;
2781         empty_region(&seat->drag_surface->pending.input);
2782         wl_list_remove(&seat->drag_surface_destroy_listener.link);
2783         seat->drag_surface = NULL;
2784 }
2785
2786 static void
2787 device_map_drag_surface(struct weston_seat *seat)
2788 {
2789         struct wl_list *list;
2790
2791         if (weston_surface_is_mapped(seat->drag_surface) ||
2792             !seat->drag_surface->buffer_ref.buffer)
2793                 return;
2794
2795         if (seat->sprite && weston_surface_is_mapped(seat->sprite))
2796                 list = &seat->sprite->layer_link;
2797         else
2798                 list = &seat->compositor->cursor_layer.surface_list;
2799
2800         wl_list_insert(list, &seat->drag_surface->layer_link);
2801         weston_surface_update_transform(seat->drag_surface);
2802         empty_region(&seat->drag_surface->input);
2803 }
2804
2805 static  void
2806 weston_seat_update_drag_surface(struct weston_seat *seat,
2807                                 int dx, int dy)
2808 {
2809         int surface_changed = 0;
2810
2811         if (!seat->drag_surface && !seat->seat.drag_surface)
2812                 return;
2813
2814         if (seat->drag_surface && seat->seat.drag_surface &&
2815             (&seat->drag_surface->surface.resource !=
2816              &seat->seat.drag_surface->resource))
2817                 /* between calls to this funcion we got a new drag_surface */
2818                 surface_changed = 1;
2819
2820         if (!seat->seat.drag_surface || surface_changed) {
2821                 device_release_drag_surface(seat);
2822                 if (!surface_changed)
2823                         return;
2824         }
2825
2826         if (!seat->drag_surface || surface_changed) {
2827                 struct weston_surface *surface = (struct weston_surface *)
2828                         seat->seat.drag_surface;
2829                 if (!device_setup_new_drag_surface(seat, surface))
2830                         return;
2831         }
2832
2833         /* the client may not have attached a buffer to the drag surface
2834          * when we setup it up, so check if map is needed on every update */
2835         device_map_drag_surface(seat);
2836
2837         if (!dx && !dy)
2838                 return;
2839
2840         weston_surface_set_position(seat->drag_surface,
2841                                     seat->drag_surface->geometry.x + wl_fixed_to_double(dx),
2842                                     seat->drag_surface->geometry.y + wl_fixed_to_double(dy));
2843 }
2844
2845 WL_EXPORT void
2846 weston_compositor_update_drag_surfaces(struct weston_compositor *compositor)
2847 {
2848         struct weston_seat *seat;
2849
2850         wl_list_for_each(seat, &compositor->seat_list, link)
2851                 weston_seat_update_drag_surface(seat, 0, 0);
2852 }
2853
2854 static void
2855 bind_output(struct wl_client *client,
2856             void *data, uint32_t version, uint32_t id)
2857 {
2858         struct weston_output *output = data;
2859         struct weston_mode *mode;
2860         struct wl_resource *resource;
2861
2862         resource = wl_client_add_object(client,
2863                                         &wl_output_interface, NULL, id, data);
2864
2865         wl_list_insert(&output->resource_list, &resource->link);
2866         resource->destroy = unbind_resource;
2867
2868         wl_output_send_geometry(resource,
2869                                 output->x,
2870                                 output->y,
2871                                 output->mm_width,
2872                                 output->mm_height,
2873                                 output->subpixel,
2874                                 output->make, output->model,
2875                                 output->transform);
2876
2877         wl_list_for_each (mode, &output->mode_list, link) {
2878                 wl_output_send_mode(resource,
2879                                     mode->flags,
2880                                     mode->width,
2881                                     mode->height,
2882                                     mode->refresh);
2883         }
2884 }
2885
2886 WL_EXPORT void
2887 weston_output_destroy(struct weston_output *output)
2888 {
2889         struct weston_compositor *c = output->compositor;
2890
2891         pixman_region32_fini(&output->region);
2892         pixman_region32_fini(&output->previous_damage);
2893         output->compositor->output_id_pool &= ~(1 << output->id);
2894
2895         wl_display_remove_global(c->wl_display, output->global);
2896 }
2897
2898 static void
2899 weston_output_compute_transform(struct weston_output *output)
2900 {
2901         struct weston_matrix transform;
2902         int flip;
2903
2904         weston_matrix_init(&transform);
2905         transform.type = WESTON_MATRIX_TRANSFORM_ROTATE;
2906
2907         switch(output->transform) {
2908         case WL_OUTPUT_TRANSFORM_FLIPPED:
2909         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2910         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
2911         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2912                 transform.type |= WESTON_MATRIX_TRANSFORM_OTHER;
2913                 flip = -1;
2914                 break;
2915         default:
2916                 flip = 1;
2917                 break;
2918         }
2919
2920         switch(output->transform) {
2921         case WL_OUTPUT_TRANSFORM_NORMAL:
2922         case WL_OUTPUT_TRANSFORM_FLIPPED:
2923                 transform.d[0] = flip;
2924                 transform.d[1] = 0;
2925                 transform.d[4] = 0;
2926                 transform.d[5] = 1;
2927                 break;
2928         case WL_OUTPUT_TRANSFORM_90:
2929         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2930                 transform.d[0] = 0;
2931                 transform.d[1] = -flip;
2932                 transform.d[4] = 1;
2933                 transform.d[5] = 0;
2934                 break;
2935         case WL_OUTPUT_TRANSFORM_180:
2936         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
2937                 transform.d[0] = -flip;
2938                 transform.d[1] = 0;
2939                 transform.d[4] = 0;
2940                 transform.d[5] = -1;
2941                 break;
2942         case WL_OUTPUT_TRANSFORM_270:
2943         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2944                 transform.d[0] = 0;
2945                 transform.d[1] = flip;
2946                 transform.d[4] = -1;
2947                 transform.d[5] = 0;
2948                 break;
2949         default:
2950                 break;
2951         }
2952
2953         weston_matrix_multiply(&output->matrix, &transform);
2954 }
2955
2956 WL_EXPORT void
2957 weston_output_update_matrix(struct weston_output *output)
2958 {
2959         float magnification;
2960         struct weston_matrix camera;
2961         struct weston_matrix modelview;
2962
2963         weston_matrix_init(&output->matrix);
2964         weston_matrix_translate(&output->matrix,
2965                                 -(output->x + (output->border.right + output->width - output->border.left) / 2.0),
2966                                 -(output->y + (output->border.bottom + output->height - output->border.top) / 2.0), 0);
2967
2968         weston_matrix_scale(&output->matrix,
2969                             2.0 / (output->width + output->border.left + output->border.right),
2970                             -2.0 / (output->height + output->border.top + output->border.bottom), 1);
2971
2972         weston_output_compute_transform(output);
2973
2974         if (output->zoom.active) {
2975                 magnification = 1 / (1 - output->zoom.spring_z.current);
2976                 weston_matrix_init(&camera);
2977                 weston_matrix_init(&modelview);
2978                 weston_output_update_zoom(output, output->zoom.type);
2979                 weston_matrix_translate(&camera, output->zoom.trans_x,
2980                                         -output->zoom.trans_y, 0);
2981                 weston_matrix_invert(&modelview, &camera);
2982                 weston_matrix_scale(&modelview, magnification, magnification, 1.0);
2983                 weston_matrix_multiply(&output->matrix, &modelview);
2984         }
2985
2986         output->dirty = 0;
2987 }
2988
2989 static void
2990 weston_output_transform_init(struct weston_output *output, uint32_t transform)
2991 {
2992         output->transform = transform;
2993
2994         switch (transform) {
2995         case WL_OUTPUT_TRANSFORM_90:
2996         case WL_OUTPUT_TRANSFORM_270:
2997         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2998         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2999                 /* Swap width and height */
3000                 output->width = output->current->height;
3001                 output->height = output->current->width;
3002                 break;
3003         case WL_OUTPUT_TRANSFORM_NORMAL:
3004         case WL_OUTPUT_TRANSFORM_180:
3005         case WL_OUTPUT_TRANSFORM_FLIPPED:
3006         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
3007                 output->width = output->current->width;
3008                 output->height = output->current->height;
3009                 break;
3010         default:
3011                 break;
3012         }
3013 }
3014
3015 WL_EXPORT void
3016 weston_output_move(struct weston_output *output, int x, int y)
3017 {
3018         output->x = x;
3019         output->y = y;
3020
3021         pixman_region32_init(&output->previous_damage);
3022         pixman_region32_init_rect(&output->region, x, y,
3023                                   output->width,
3024                                   output->height);
3025 }
3026
3027 WL_EXPORT void
3028 weston_output_init(struct weston_output *output, struct weston_compositor *c,
3029                    int x, int y, int width, int height, uint32_t transform)
3030 {
3031         output->compositor = c;
3032         output->x = x;
3033         output->y = y;
3034         output->border.top = 0;
3035         output->border.bottom = 0;
3036         output->border.left = 0;
3037         output->border.right = 0;
3038         output->mm_width = width;
3039         output->mm_height = height;
3040         output->dirty = 1;
3041
3042         weston_output_transform_init(output, transform);
3043         weston_output_init_zoom(output);
3044
3045         weston_output_move(output, x, y);
3046         weston_output_damage(output);
3047
3048         wl_signal_init(&output->frame_signal);
3049         wl_list_init(&output->animation_list);
3050         wl_list_init(&output->resource_list);
3051
3052         output->id = ffs(~output->compositor->output_id_pool) - 1;
3053         output->compositor->output_id_pool |= 1 << output->id;
3054
3055         output->global =
3056                 wl_display_add_global(c->wl_display, &wl_output_interface,
3057                                       output, bind_output);
3058 }
3059
3060 static void
3061 compositor_bind(struct wl_client *client,
3062                 void *data, uint32_t version, uint32_t id)
3063 {
3064         struct weston_compositor *compositor = data;
3065
3066         wl_client_add_object(client, &wl_compositor_interface,
3067                              &compositor_interface, id, compositor);
3068 }
3069
3070 static void
3071 log_uname(void)
3072 {
3073         struct utsname usys;
3074
3075         uname(&usys);
3076
3077         weston_log("OS: %s, %s, %s, %s\n", usys.sysname, usys.release,
3078                                                 usys.version, usys.machine);
3079 }
3080
3081 WL_EXPORT int
3082 weston_environment_get_fd(const char *env)
3083 {
3084         char *e, *end;
3085         int fd, flags;
3086
3087         e = getenv(env);
3088         if (!e)
3089                 return -1;
3090         fd = strtol(e, &end, 0);
3091         if (*end != '\0')
3092                 return -1;
3093
3094         flags = fcntl(fd, F_GETFD);
3095         if (flags == -1)
3096                 return -1;
3097
3098         fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
3099         unsetenv(env);
3100
3101         return fd;
3102 }
3103
3104 WL_EXPORT int
3105 weston_compositor_init(struct weston_compositor *ec,
3106                        struct wl_display *display,
3107                        int *argc, char *argv[],
3108                        const char *config_file)
3109 {
3110         struct wl_event_loop *loop;
3111         struct xkb_rule_names xkb_names;
3112         const struct config_key keyboard_config_keys[] = {
3113                 { "keymap_rules", CONFIG_KEY_STRING, &xkb_names.rules },
3114                 { "keymap_model", CONFIG_KEY_STRING, &xkb_names.model },
3115                 { "keymap_layout", CONFIG_KEY_STRING, &xkb_names.layout },
3116                 { "keymap_variant", CONFIG_KEY_STRING, &xkb_names.variant },
3117                 { "keymap_options", CONFIG_KEY_STRING, &xkb_names.options },
3118         };
3119         const struct config_section cs[] = {
3120                 { "keyboard",
3121                   keyboard_config_keys, ARRAY_LENGTH(keyboard_config_keys) },
3122         };
3123
3124         memset(&xkb_names, 0, sizeof(xkb_names));
3125         parse_config_file(config_file, cs, ARRAY_LENGTH(cs), ec);
3126
3127         ec->wl_display = display;
3128         wl_signal_init(&ec->destroy_signal);
3129         wl_signal_init(&ec->activate_signal);
3130         wl_signal_init(&ec->kill_signal);
3131         wl_signal_init(&ec->idle_signal);
3132         wl_signal_init(&ec->wake_signal);
3133         wl_signal_init(&ec->show_input_panel_signal);
3134         wl_signal_init(&ec->hide_input_panel_signal);
3135         wl_signal_init(&ec->seat_created_signal);
3136         ec->launcher_sock = weston_environment_get_fd("WESTON_LAUNCHER_SOCK");
3137
3138         ec->output_id_pool = 0;
3139
3140         if (!wl_display_add_global(display, &wl_compositor_interface,
3141                                    ec, compositor_bind))
3142                 return -1;
3143
3144         wl_list_init(&ec->surface_list);
3145         wl_list_init(&ec->plane_list);
3146         wl_list_init(&ec->layer_list);
3147         wl_list_init(&ec->seat_list);
3148         wl_list_init(&ec->output_list);
3149         wl_list_init(&ec->key_binding_list);
3150         wl_list_init(&ec->button_binding_list);
3151         wl_list_init(&ec->axis_binding_list);
3152         wl_list_init(&ec->debug_binding_list);
3153
3154         weston_plane_init(&ec->primary_plane, 0, 0);
3155         weston_compositor_stack_plane(ec, &ec->primary_plane, NULL);
3156
3157         if (weston_compositor_xkb_init(ec, &xkb_names) < 0)
3158                 return -1;
3159
3160         ec->ping_handler = NULL;
3161
3162         screenshooter_create(ec);
3163         text_cursor_position_notifier_create(ec);
3164         text_backend_init(ec);
3165
3166         wl_data_device_manager_init(ec->wl_display);
3167
3168         wl_display_init_shm(display);
3169
3170         loop = wl_display_get_event_loop(ec->wl_display);
3171         ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
3172         wl_event_source_timer_update(ec->idle_source, ec->idle_time * 1000);
3173
3174         ec->input_loop = wl_event_loop_create();
3175
3176         weston_layer_init(&ec->fade_layer, &ec->layer_list);
3177         weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
3178
3179         weston_compositor_schedule_repaint(ec);
3180
3181         return 0;
3182 }
3183
3184 WL_EXPORT void
3185 weston_compositor_shutdown(struct weston_compositor *ec)
3186 {
3187         struct weston_output *output, *next;
3188
3189         wl_event_source_remove(ec->idle_source);
3190         if (ec->input_loop_source)
3191                 wl_event_source_remove(ec->input_loop_source);
3192
3193         /* Destroy all outputs associated with this compositor */
3194         wl_list_for_each_safe(output, next, &ec->output_list, link)
3195                 output->destroy(output);
3196
3197         weston_binding_list_destroy_all(&ec->key_binding_list);
3198         weston_binding_list_destroy_all(&ec->button_binding_list);
3199         weston_binding_list_destroy_all(&ec->axis_binding_list);
3200         weston_binding_list_destroy_all(&ec->debug_binding_list);
3201
3202         weston_plane_release(&ec->primary_plane);
3203
3204         wl_array_release(&ec->vertices);
3205         wl_array_release(&ec->indices);
3206         wl_array_release(&ec->vtxcnt);
3207
3208         wl_event_loop_destroy(ec->input_loop);
3209 }
3210
3211 WL_EXPORT void
3212 weston_version(int *major, int *minor, int *micro)
3213 {
3214         *major = WESTON_VERSION_MAJOR;
3215         *minor = WESTON_VERSION_MINOR;
3216         *micro = WESTON_VERSION_MICRO;
3217 }
3218
3219 static int on_term_signal(int signal_number, void *data)
3220 {
3221         struct wl_display *display = data;
3222
3223         weston_log("caught signal %d\n", signal_number);
3224         wl_display_terminate(display);
3225
3226         return 1;
3227 }
3228
3229 #ifdef HAVE_LIBUNWIND
3230
3231 static void
3232 print_backtrace(void)
3233 {
3234         unw_cursor_t cursor;
3235         unw_context_t context;
3236         unw_word_t off;
3237         unw_proc_info_t pip;
3238         int ret, i = 0;
3239         char procname[256];
3240         const char *filename;
3241         Dl_info dlinfo;
3242
3243         pip.unwind_info = NULL;
3244         ret = unw_getcontext(&context);
3245         if (ret) {
3246                 weston_log("unw_getcontext: %d\n", ret);
3247                 return;
3248         }
3249
3250         ret = unw_init_local(&cursor, &context);
3251         if (ret) {
3252                 weston_log("unw_init_local: %d\n", ret);
3253                 return;
3254         }
3255
3256         ret = unw_step(&cursor);
3257         while (ret > 0) {
3258                 ret = unw_get_proc_info(&cursor, &pip);
3259                 if (ret) {
3260                         weston_log("unw_get_proc_info: %d\n", ret);
3261                         break;
3262                 }
3263
3264                 ret = unw_get_proc_name(&cursor, procname, 256, &off);
3265                 if (ret && ret != -UNW_ENOMEM) {
3266                         if (ret != -UNW_EUNSPEC)
3267                                 weston_log("unw_get_proc_name: %d\n", ret);
3268                         procname[0] = '?';
3269                         procname[1] = 0;
3270                 }
3271
3272                 if (dladdr((void *)(pip.start_ip + off), &dlinfo) && dlinfo.dli_fname &&
3273                     *dlinfo.dli_fname)
3274                         filename = dlinfo.dli_fname;
3275                 else
3276                         filename = "?";
3277                 
3278                 weston_log("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,
3279                            ret == -UNW_ENOMEM ? "..." : "", (int)off, (void *)(pip.start_ip + off));
3280
3281                 ret = unw_step(&cursor);
3282                 if (ret < 0)
3283                         weston_log("unw_step: %d\n", ret);
3284         }
3285 }
3286
3287 #else
3288
3289 static void
3290 print_backtrace(void)
3291 {
3292         void *buffer[32];
3293         int i, count;
3294         Dl_info info;
3295
3296         count = backtrace(buffer, ARRAY_LENGTH(buffer));
3297         for (i = 0; i < count; i++) {
3298                 dladdr(buffer[i], &info);
3299                 weston_log("  [%016lx]  %s  (%s)\n",
3300                         (long) buffer[i],
3301                         info.dli_sname ? info.dli_sname : "--",
3302                         info.dli_fname);
3303         }
3304 }
3305
3306 #endif
3307
3308 static void
3309 on_caught_signal(int s, siginfo_t *siginfo, void *context)
3310 {
3311         /* This signal handler will do a best-effort backtrace, and
3312          * then call the backend restore function, which will switch
3313          * back to the vt we launched from or ungrab X etc and then
3314          * raise SIGTRAP.  If we run weston under gdb from X or a
3315          * different vt, and tell gdb "handle *s* nostop", this
3316          * will allow weston to switch back to gdb on crash and then
3317          * gdb will catch the crash with SIGTRAP.*/
3318
3319         weston_log("caught signal: %d\n", s);
3320
3321         print_backtrace();
3322
3323         segv_compositor->restore(segv_compositor);
3324
3325         raise(SIGTRAP);
3326 }
3327
3328 static void *
3329 load_module(const char *name, const char *entrypoint)
3330 {
3331         char path[PATH_MAX];
3332         void *module, *init;
3333
3334         if (name[0] != '/')
3335                 snprintf(path, sizeof path, "%s/%s", MODULEDIR, name);
3336         else
3337                 snprintf(path, sizeof path, "%s", name);
3338
3339         module = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
3340         if (module) {
3341                 weston_log("Module '%s' already loaded\n", path);
3342                 dlclose(module);
3343                 return NULL;
3344         }
3345
3346         weston_log("Loading module '%s'\n", path);
3347         module = dlopen(path, RTLD_NOW);
3348         if (!module) {
3349                 weston_log("Failed to load module: %s\n", dlerror());
3350                 return NULL;
3351         }
3352
3353         init = dlsym(module, entrypoint);
3354         if (!init) {
3355                 weston_log("Failed to lookup init function: %s\n", dlerror());
3356                 dlclose(module);
3357                 return NULL;
3358         }
3359
3360         return init;
3361 }
3362
3363 static int
3364 load_modules(struct weston_compositor *ec, const char *modules,
3365              int *argc, char *argv[], const char *config_file)
3366 {
3367         const char *p, *end;
3368         char buffer[256];
3369         int (*module_init)(struct weston_compositor *ec,
3370                            int *argc, char *argv[], const char *config_file);
3371
3372         if (modules == NULL)
3373                 return 0;
3374
3375         p = modules;
3376         while (*p) {
3377                 end = strchrnul(p, ',');
3378                 snprintf(buffer, sizeof buffer, "%.*s", (int) (end - p), p);
3379                 module_init = load_module(buffer, "module_init");
3380                 if (module_init)
3381                         module_init(ec, argc, argv, config_file);
3382                 p = end;
3383                 while (*p == ',')
3384                         p++;
3385
3386         }
3387
3388         return 0;
3389 }
3390
3391 static const char xdg_error_message[] =
3392         "fatal: environment variable XDG_RUNTIME_DIR is not set.\n";
3393
3394 static const char xdg_wrong_message[] =
3395         "fatal: environment variable XDG_RUNTIME_DIR\n"
3396         "is set to \"%s\", which is not a directory.\n";
3397
3398 static const char xdg_wrong_mode_message[] =
3399         "warning: XDG_RUNTIME_DIR \"%s\" is not configured\n"
3400         "correctly.  Unix access mode must be 0700 but is %o,\n"
3401         "and XDG_RUNTIME_DIR must be owned by the user, but is\n"
3402         "owned by UID %d.\n";
3403
3404 static const char xdg_detail_message[] =
3405         "Refer to your distribution on how to get it, or\n"
3406         "http://www.freedesktop.org/wiki/Specifications/basedir-spec\n"
3407         "on how to implement it.\n";
3408
3409 static void
3410 verify_xdg_runtime_dir(void)
3411 {
3412         char *dir = getenv("XDG_RUNTIME_DIR");
3413         struct stat s;
3414
3415         if (!dir) {
3416                 weston_log(xdg_error_message);
3417                 weston_log_continue(xdg_detail_message);
3418                 exit(EXIT_FAILURE);
3419         }
3420
3421         if (stat(dir, &s) || !S_ISDIR(s.st_mode)) {
3422                 weston_log(xdg_wrong_message, dir);
3423                 weston_log_continue(xdg_detail_message);
3424                 exit(EXIT_FAILURE);
3425         }
3426
3427         if ((s.st_mode & 0777) != 0700 || s.st_uid != getuid()) {
3428                 weston_log(xdg_wrong_mode_message,
3429                            dir, s.st_mode & 0777, s.st_uid);
3430                 weston_log_continue(xdg_detail_message);
3431         }
3432 }
3433
3434 static int
3435 usage(int error_code)
3436 {
3437         fprintf(stderr,
3438                 "Usage: weston [OPTIONS]\n\n"
3439                 "This is weston version " VERSION ", the Wayland reference compositor.\n"
3440                 "Weston supports multiple backends, and depending on which backend is in use\n"
3441                 "different options will be accepted.\n\n"
3442
3443
3444                 "Core options:\n\n"
3445                 "  --version\t\tPrint weston version\n"
3446                 "  -B, --backend=MODULE\tBackend module, one of drm-backend.so,\n"
3447                 "\t\t\t\tx11-backend.so or wayland-backend.so\n"
3448                 "  -S, --socket=NAME\tName of socket to listen on\n"
3449                 "  -i, --idle-time=SECS\tIdle time in seconds\n"
3450                 "  --modules\t\tLoad the comma-separated list of modules\n"
3451                 "  --log==FILE\t\tLog to the given file\n"
3452                 "  -h, --help\t\tThis help message\n\n");
3453
3454         fprintf(stderr,
3455                 "Options for drm-backend.so:\n\n"
3456                 "  --connector=ID\tBring up only this connector\n"
3457                 "  --seat=SEAT\t\tThe seat that weston should run on\n"
3458                 "  --tty=TTY\t\tThe tty to use\n"
3459                 "  --use-pixman\t\tUse the pixman (CPU) renderer\n"
3460                 "  --current-mode\tPrefer current KMS mode over EDID preferred mode\n\n");
3461
3462         fprintf(stderr,
3463                 "Options for x11-backend.so:\n\n"
3464                 "  --width=WIDTH\t\tWidth of X window\n"
3465                 "  --height=HEIGHT\tHeight of X window\n"
3466                 "  --fullscreen\t\tRun in fullscreen mode\n"
3467                 "  --use-pixman\t\tUse the pixman (CPU) renderer\n"
3468                 "  --output-count=COUNT\tCreate multiple outputs\n"
3469                 "  --no-input\t\tDont create input devices\n\n");
3470
3471         fprintf(stderr,
3472                 "Options for wayland-backend.so:\n\n"
3473                 "  --width=WIDTH\t\tWidth of Wayland surface\n"
3474                 "  --height=HEIGHT\tHeight of Wayland surface\n"
3475                 "  --display=DISPLAY\tWayland display to connect to\n\n");
3476
3477         exit(error_code);
3478 }
3479
3480 static void
3481 catch_signals(void)
3482 {
3483         struct sigaction action;
3484
3485         action.sa_flags = SA_SIGINFO | SA_RESETHAND;
3486         action.sa_sigaction = on_caught_signal;
3487         sigemptyset(&action.sa_mask);
3488         sigaction(SIGSEGV, &action, NULL);
3489         sigaction(SIGABRT, &action, NULL);
3490 }
3491
3492 int main(int argc, char *argv[])
3493 {
3494         int ret = EXIT_SUCCESS;
3495         struct wl_display *display;
3496         struct weston_compositor *ec;
3497         struct wl_event_source *signals[4];
3498         struct wl_event_loop *loop;
3499         struct weston_compositor
3500                 *(*backend_init)(struct wl_display *display,
3501                                  int *argc, char *argv[], const char *config_file);
3502         int i;
3503         char *backend = NULL;
3504         const char *modules = "desktop-shell.so", *option_modules = NULL;
3505         char *log = NULL;
3506         int32_t idle_time = 300;
3507         int32_t help = 0;
3508         char *socket_name = "wayland-0";
3509         int32_t version = 0;
3510         char *config_file;
3511
3512         const struct config_key core_config_keys[] = {
3513                 { "modules", CONFIG_KEY_STRING, &modules },
3514         };
3515
3516         const struct config_section cs[] = {
3517                 { "core",
3518                   core_config_keys, ARRAY_LENGTH(core_config_keys) },
3519         };
3520
3521         const struct weston_option core_options[] = {
3522                 { WESTON_OPTION_STRING, "backend", 'B', &backend },
3523                 { WESTON_OPTION_STRING, "socket", 'S', &socket_name },
3524                 { WESTON_OPTION_INTEGER, "idle-time", 'i', &idle_time },
3525                 { WESTON_OPTION_STRING, "modules", 0, &option_modules },
3526                 { WESTON_OPTION_STRING, "log", 0, &log },
3527                 { WESTON_OPTION_BOOLEAN, "help", 'h', &help },
3528                 { WESTON_OPTION_BOOLEAN, "version", 0, &version },
3529         };
3530
3531         parse_options(core_options, ARRAY_LENGTH(core_options), &argc, argv);
3532
3533         if (help)
3534                 usage(EXIT_SUCCESS);
3535
3536         if (version) {
3537                 printf(PACKAGE_STRING "\n");
3538                 return EXIT_SUCCESS;
3539         }
3540
3541         weston_log_file_open(log);
3542         
3543         weston_log("%s\n"
3544                    STAMP_SPACE "%s\n"
3545                    STAMP_SPACE "Bug reports to: %s\n"
3546                    STAMP_SPACE "Build: %s\n",
3547                    PACKAGE_STRING, PACKAGE_URL, PACKAGE_BUGREPORT,
3548                    BUILD_ID);
3549         log_uname();
3550
3551         verify_xdg_runtime_dir();
3552
3553         display = wl_display_create();
3554
3555         loop = wl_display_get_event_loop(display);
3556         signals[0] = wl_event_loop_add_signal(loop, SIGTERM, on_term_signal,
3557                                               display);
3558         signals[1] = wl_event_loop_add_signal(loop, SIGINT, on_term_signal,
3559                                               display);
3560         signals[2] = wl_event_loop_add_signal(loop, SIGQUIT, on_term_signal,
3561                                               display);
3562
3563         wl_list_init(&child_process_list);
3564         signals[3] = wl_event_loop_add_signal(loop, SIGCHLD, sigchld_handler,
3565                                               NULL);
3566
3567         if (!backend) {
3568                 if (getenv("WAYLAND_DISPLAY"))
3569                         backend = "wayland-backend.so";
3570                 else if (getenv("DISPLAY"))
3571                         backend = "x11-backend.so";
3572                 else
3573                         backend = WESTON_NATIVE_BACKEND;
3574         }
3575
3576         config_file = config_file_path("weston.ini");
3577         parse_config_file(config_file, cs, ARRAY_LENGTH(cs), NULL);
3578
3579         backend_init = load_module(backend, "backend_init");
3580         if (!backend_init)
3581                 exit(EXIT_FAILURE);
3582
3583         ec = backend_init(display, &argc, argv, config_file);
3584         if (ec == NULL) {
3585                 weston_log("fatal: failed to create compositor\n");
3586                 exit(EXIT_FAILURE);
3587         }
3588
3589         catch_signals();
3590         segv_compositor = ec;
3591
3592         ec->idle_time = idle_time;
3593
3594         setenv("WAYLAND_DISPLAY", socket_name, 1);
3595
3596         if (load_modules(ec, modules, &argc, argv, config_file) < 0)
3597                 goto out;
3598         if (load_modules(ec, option_modules, &argc, argv, config_file) < 0)
3599                 goto out;
3600
3601         free(config_file);
3602
3603         for (i = 1; i < argc; i++)
3604                 weston_log("fatal: unhandled option: %s\n", argv[i]);
3605         if (argc > 1) {
3606                 ret = EXIT_FAILURE;
3607                 goto out;
3608         }
3609
3610         if (wl_display_add_socket(display, socket_name)) {
3611                 weston_log("fatal: failed to add socket: %m\n");
3612                 ret = EXIT_FAILURE;
3613                 goto out;
3614         }
3615
3616         weston_compositor_wake(ec);
3617
3618         wl_display_run(display);
3619
3620  out:
3621         /* prevent further rendering while shutting down */
3622         ec->state = WESTON_COMPOSITOR_SLEEPING;
3623
3624         wl_signal_emit(&ec->destroy_signal, ec);
3625
3626         for (i = ARRAY_LENGTH(signals); i;)
3627                 wl_event_source_remove(signals[--i]);
3628
3629         weston_compositor_xkb_destroy(ec);
3630
3631         ec->destroy(ec);
3632         wl_display_destroy(display);
3633
3634         weston_log_file_close();
3635
3636         return ret;
3637 }