compositor, shell: surface transform inheritance
[profile/ivi/weston-ivi-shell.git] / src / compositor.c
1 /*
2  * Copyright © 2010-2011 Intel Corporation
3  * Copyright © 2008-2011 Kristian Høgsberg
4  * Copyright © 2012 Collabora, Ltd.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and
7  * its documentation for any purpose is hereby granted without fee, provided
8  * that the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of the copyright holders not be used in
11  * advertising or publicity pertaining to distribution of the software
12  * without specific, written prior permission.  The copyright holders make
13  * no representations about the suitability of this software for any
14  * purpose.  It is provided "as is" without express or implied warranty.
15  *
16  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
17  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
20  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
21  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23  */
24
25 #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 static void
1786 move_pointer(struct weston_seat *seat, wl_fixed_t dx, wl_fixed_t dy)
1787 {
1788         struct weston_compositor *ec = seat->compositor;
1789         struct wl_pointer *pointer = seat->seat.pointer;
1790         struct weston_output *output;
1791         wl_fixed_t x, y;
1792         int32_t ix, iy;
1793
1794         x = pointer->x + dx;
1795         y = pointer->y + dy;
1796         clip_pointer_motion(seat, &x, &y);
1797
1798         weston_seat_update_drag_surface(seat, x - pointer->x, y - pointer->y);
1799
1800         pointer->x = x;
1801         pointer->y = y;
1802
1803         ix = wl_fixed_to_int(x);
1804         iy = wl_fixed_to_int(y);
1805
1806         wl_list_for_each(output, &ec->output_list, link)
1807                 if (output->zoom.active &&
1808                     pixman_region32_contains_point(&output->region,
1809                                                    ix, iy, NULL))
1810                         weston_output_update_zoom(output, ZOOM_FOCUS_POINTER);
1811
1812         weston_device_repick(seat);
1813
1814         if (seat->sprite) {
1815                 weston_surface_set_position(seat->sprite,
1816                                             ix - seat->hotspot_x,
1817                                             iy - seat->hotspot_y);
1818                 weston_surface_schedule_repaint(seat->sprite);
1819         }
1820 }
1821
1822 WL_EXPORT void
1823 notify_motion(struct weston_seat *seat,
1824               uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
1825 {
1826         const struct wl_pointer_grab_interface *interface;
1827         struct weston_compositor *ec = seat->compositor;
1828         struct wl_pointer *pointer = seat->seat.pointer;
1829
1830         weston_compositor_wake(ec);
1831
1832         move_pointer(seat, dx, dy);
1833
1834         interface = pointer->grab->interface;
1835         interface->motion(pointer->grab, time,
1836                           pointer->grab->x, pointer->grab->y);
1837 }
1838
1839 WL_EXPORT void
1840 weston_surface_activate(struct weston_surface *surface,
1841                         struct weston_seat *seat)
1842 {
1843         struct weston_compositor *compositor = seat->compositor;
1844
1845         if (seat->seat.keyboard) {
1846                 wl_keyboard_set_focus(seat->seat.keyboard, &surface->surface);
1847                 wl_data_device_set_keyboard_focus(&seat->seat);
1848         }
1849
1850         wl_signal_emit(&compositor->activate_signal, surface);
1851 }
1852
1853 WL_EXPORT void
1854 notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
1855               enum wl_pointer_button_state state)
1856 {
1857         struct weston_compositor *compositor = seat->compositor;
1858         struct wl_pointer *pointer = seat->seat.pointer;
1859         struct weston_surface *focus =
1860                 (struct weston_surface *) pointer->focus;
1861         uint32_t serial = wl_display_next_serial(compositor->wl_display);
1862
1863         if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
1864                 if (compositor->ping_handler && focus)
1865                         compositor->ping_handler(focus, serial);
1866                 weston_compositor_idle_inhibit(compositor);
1867                 if (pointer->button_count == 0) {
1868                         pointer->grab_button = button;
1869                         pointer->grab_time = time;
1870                         pointer->grab_x = pointer->x;
1871                         pointer->grab_y = pointer->y;
1872                 }
1873                 pointer->button_count++;
1874         } else {
1875                 weston_compositor_idle_release(compositor);
1876                 pointer->button_count--;
1877         }
1878
1879         weston_compositor_run_button_binding(compositor, seat, time, button,
1880                                              state);
1881
1882         pointer->grab->interface->button(pointer->grab, time, button, state);
1883
1884         if (pointer->button_count == 1)
1885                 pointer->grab_serial =
1886                         wl_display_get_serial(compositor->wl_display);
1887 }
1888
1889 WL_EXPORT void
1890 notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
1891             wl_fixed_t value)
1892 {
1893         struct weston_compositor *compositor = seat->compositor;
1894         struct wl_pointer *pointer = seat->seat.pointer;
1895         struct weston_surface *focus =
1896                 (struct weston_surface *) pointer->focus;
1897         uint32_t serial = wl_display_next_serial(compositor->wl_display);
1898
1899         if (compositor->ping_handler && focus)
1900                 compositor->ping_handler(focus, serial);
1901
1902         weston_compositor_wake(compositor);
1903
1904         if (!value)
1905                 return;
1906
1907         if (weston_compositor_run_axis_binding(compositor, seat,
1908                                                    time, axis, value))
1909                 return;
1910
1911         if (pointer->focus_resource)
1912                 wl_pointer_send_axis(pointer->focus_resource, time, axis,
1913                                      value);
1914 }
1915
1916 WL_EXPORT void
1917 notify_modifiers(struct weston_seat *seat, uint32_t serial)
1918 {
1919         struct wl_keyboard *keyboard = &seat->keyboard.keyboard;
1920         struct wl_keyboard_grab *grab = keyboard->grab;
1921         uint32_t mods_depressed, mods_latched, mods_locked, group;
1922         uint32_t mods_lookup;
1923         enum weston_led leds = 0;
1924         int changed = 0;
1925
1926         /* Serialize and update our internal state, checking to see if it's
1927          * different to the previous state. */
1928         mods_depressed = xkb_state_serialize_mods(seat->xkb_state.state,
1929                                                   XKB_STATE_DEPRESSED);
1930         mods_latched = xkb_state_serialize_mods(seat->xkb_state.state,
1931                                                 XKB_STATE_LATCHED);
1932         mods_locked = xkb_state_serialize_mods(seat->xkb_state.state,
1933                                                XKB_STATE_LOCKED);
1934         group = xkb_state_serialize_group(seat->xkb_state.state,
1935                                           XKB_STATE_EFFECTIVE);
1936
1937         if (mods_depressed != seat->seat.keyboard->modifiers.mods_depressed ||
1938             mods_latched != seat->seat.keyboard->modifiers.mods_latched ||
1939             mods_locked != seat->seat.keyboard->modifiers.mods_locked ||
1940             group != seat->seat.keyboard->modifiers.group)
1941                 changed = 1;
1942
1943         seat->seat.keyboard->modifiers.mods_depressed = mods_depressed;
1944         seat->seat.keyboard->modifiers.mods_latched = mods_latched;
1945         seat->seat.keyboard->modifiers.mods_locked = mods_locked;
1946         seat->seat.keyboard->modifiers.group = group;
1947
1948         /* And update the modifier_state for bindings. */
1949         mods_lookup = mods_depressed | mods_latched;
1950         seat->modifier_state = 0;
1951         if (mods_lookup & (1 << seat->xkb_info.ctrl_mod))
1952                 seat->modifier_state |= MODIFIER_CTRL;
1953         if (mods_lookup & (1 << seat->xkb_info.alt_mod))
1954                 seat->modifier_state |= MODIFIER_ALT;
1955         if (mods_lookup & (1 << seat->xkb_info.super_mod))
1956                 seat->modifier_state |= MODIFIER_SUPER;
1957         if (mods_lookup & (1 << seat->xkb_info.shift_mod))
1958                 seat->modifier_state |= MODIFIER_SHIFT;
1959
1960         /* Finally, notify the compositor that LEDs have changed. */
1961         if (xkb_state_led_index_is_active(seat->xkb_state.state,
1962                                           seat->xkb_info.num_led))
1963                 leds |= LED_NUM_LOCK;
1964         if (xkb_state_led_index_is_active(seat->xkb_state.state,
1965                                           seat->xkb_info.caps_led))
1966                 leds |= LED_CAPS_LOCK;
1967         if (xkb_state_led_index_is_active(seat->xkb_state.state,
1968                                           seat->xkb_info.scroll_led))
1969                 leds |= LED_SCROLL_LOCK;
1970         if (leds != seat->xkb_state.leds && seat->led_update)
1971                 seat->led_update(seat, leds);
1972         seat->xkb_state.leds = leds;
1973
1974         if (changed) {
1975                 grab->interface->modifiers(grab,
1976                                            serial,
1977                                            keyboard->modifiers.mods_depressed,
1978                                            keyboard->modifiers.mods_latched,
1979                                            keyboard->modifiers.mods_locked,
1980                                            keyboard->modifiers.group);
1981         }
1982 }
1983
1984 static void
1985 update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1986                       enum wl_keyboard_key_state state)
1987 {
1988         enum xkb_key_direction direction;
1989
1990         if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1991                 direction = XKB_KEY_DOWN;
1992         else
1993                 direction = XKB_KEY_UP;
1994
1995         /* Offset the keycode by 8, as the evdev XKB rules reflect X's
1996          * broken keycode system, which starts at 8. */
1997         xkb_state_update_key(seat->xkb_state.state, key + 8, direction);
1998
1999         notify_modifiers(seat, serial);
2000 }
2001
2002 WL_EXPORT void
2003 notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
2004            enum wl_keyboard_key_state state,
2005            enum weston_key_state_update update_state)
2006 {
2007         struct weston_compositor *compositor = seat->compositor;
2008         struct weston_keyboard *keyboard = &seat->keyboard;
2009         struct weston_surface *focus =
2010                 (struct weston_surface *) keyboard->keyboard.focus;
2011         struct wl_keyboard_grab *grab = keyboard->keyboard.grab;
2012         uint32_t serial = wl_display_next_serial(compositor->wl_display);
2013         uint32_t *k, *end;
2014
2015         if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
2016                 if (compositor->ping_handler && focus)
2017                         compositor->ping_handler(focus, serial);
2018
2019                 weston_compositor_idle_inhibit(compositor);
2020                 keyboard->keyboard.grab_key = key;
2021                 keyboard->keyboard.grab_time = time;
2022         } else {
2023                 weston_compositor_idle_release(compositor);
2024         }
2025
2026         end = keyboard->keyboard.keys.data + keyboard->keyboard.keys.size;
2027         for (k = keyboard->keyboard.keys.data; k < end; k++) {
2028                 if (*k == key) {
2029                         /* Ignore server-generated repeats. */
2030                         if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
2031                                 return;
2032                         *k = *--end;
2033                 }
2034         }
2035         keyboard->keyboard.keys.size = (void *) end - keyboard->keyboard.keys.data;
2036         if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
2037                 k = wl_array_add(&keyboard->keyboard.keys, sizeof *k);
2038                 *k = key;
2039         }
2040
2041         if (grab == &keyboard->keyboard.default_grab ||
2042             grab == &keyboard->input_method_grab) {
2043                 weston_compositor_run_key_binding(compositor, seat, time, key,
2044                                                   state);
2045                 grab = keyboard->keyboard.grab;
2046         }
2047
2048         grab->interface->key(grab, time, key, state);
2049
2050         if (update_state == STATE_UPDATE_AUTOMATIC) {
2051                 update_modifier_state(seat,
2052                                       wl_display_get_serial(compositor->wl_display),
2053                                       key,
2054                                       state);
2055         }
2056 }
2057
2058 WL_EXPORT void
2059 notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
2060                      wl_fixed_t x, wl_fixed_t y)
2061 {
2062         struct weston_compositor *compositor = seat->compositor;
2063         struct wl_pointer *pointer = seat->seat.pointer;
2064
2065         if (output) {
2066                 clip_pointer_motion(seat, &x, &y);
2067                 weston_seat_update_drag_surface(seat,
2068                                                 x - pointer->x,
2069                                                 y - pointer->y);
2070
2071                 pointer->x = x;
2072                 pointer->y = y;
2073                 compositor->focus = 1;
2074                 weston_compositor_repick(compositor);
2075         } else {
2076                 compositor->focus = 0;
2077                 /* FIXME: We should call wl_pointer_set_focus(seat,
2078                  * NULL) here, but somehow that breaks re-entry... */
2079         }
2080 }
2081
2082 static void
2083 destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
2084 {
2085         struct weston_seat *ws;
2086
2087         ws = container_of(listener, struct weston_seat,
2088                           saved_kbd_focus_listener);
2089
2090         ws->saved_kbd_focus = NULL;
2091 }
2092
2093 WL_EXPORT void
2094 notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
2095                          enum weston_key_state_update update_state)
2096 {
2097         struct weston_compositor *compositor = seat->compositor;
2098         struct wl_keyboard *keyboard = seat->seat.keyboard;
2099         struct wl_surface *surface;
2100         uint32_t *k, serial;
2101
2102         serial = wl_display_next_serial(compositor->wl_display);
2103         wl_array_copy(&keyboard->keys, keys);
2104         wl_array_for_each(k, &keyboard->keys) {
2105                 weston_compositor_idle_inhibit(compositor);
2106                 if (update_state == STATE_UPDATE_AUTOMATIC)
2107                         update_modifier_state(seat, serial, *k,
2108                                               WL_KEYBOARD_KEY_STATE_PRESSED);
2109         }
2110
2111         /* Run key bindings after we've updated the state. */
2112         wl_array_for_each(k, &keyboard->keys) {
2113                 weston_compositor_run_key_binding(compositor, seat, 0, *k,
2114                                                   WL_KEYBOARD_KEY_STATE_PRESSED);
2115         }
2116
2117         surface = seat->saved_kbd_focus;
2118
2119         if (surface) {
2120                 wl_list_remove(&seat->saved_kbd_focus_listener.link);
2121                 wl_keyboard_set_focus(keyboard, surface);
2122                 seat->saved_kbd_focus = NULL;
2123         }
2124 }
2125
2126 WL_EXPORT void
2127 notify_keyboard_focus_out(struct weston_seat *seat)
2128 {
2129         struct weston_compositor *compositor = seat->compositor;
2130         struct wl_keyboard *keyboard = seat->seat.keyboard;
2131         uint32_t *k, serial;
2132
2133         serial = wl_display_next_serial(compositor->wl_display);
2134         wl_array_for_each(k, &keyboard->keys) {
2135                 weston_compositor_idle_release(compositor);
2136                 update_modifier_state(seat, serial, *k,
2137                                       WL_KEYBOARD_KEY_STATE_RELEASED);
2138         }
2139
2140         seat->modifier_state = 0;
2141
2142         if (keyboard->focus) {
2143                 seat->saved_kbd_focus = keyboard->focus;
2144                 seat->saved_kbd_focus_listener.notify =
2145                         destroy_device_saved_kbd_focus;
2146                 wl_signal_add(&keyboard->focus->resource.destroy_signal,
2147                               &seat->saved_kbd_focus_listener);
2148         }
2149
2150         wl_keyboard_set_focus(keyboard, NULL);
2151         /* FIXME: We really need keyboard grab cancel here to
2152          * let the grab shut down properly.  As it is we leak
2153          * the grab data. */
2154         wl_keyboard_end_grab(keyboard);
2155 }
2156
2157 static void
2158 touch_set_focus(struct weston_seat *ws, struct wl_surface *surface)
2159 {
2160         struct wl_seat *seat = &ws->seat;
2161         struct wl_resource *resource;
2162
2163         if (seat->touch->focus == surface)
2164                 return;
2165
2166         if (seat->touch->focus_resource)
2167                 wl_list_remove(&seat->touch->focus_listener.link);
2168         seat->touch->focus = NULL;
2169         seat->touch->focus_resource = NULL;
2170
2171         if (surface) {
2172                 resource =
2173                         find_resource_for_client(&seat->touch->resource_list,
2174                                                  surface->resource.client);
2175                 if (!resource) {
2176                         weston_log("couldn't find resource\n");
2177                         return;
2178                 }
2179
2180                 seat->touch->focus = surface;
2181                 seat->touch->focus_resource = resource;
2182                 wl_signal_add(&resource->destroy_signal,
2183                               &seat->touch->focus_listener);
2184         }
2185 }
2186
2187 /**
2188  * notify_touch - emulates button touches and notifies surfaces accordingly.
2189  *
2190  * It assumes always the correct cycle sequence until it gets here: touch_down
2191  * → touch_update → ... → touch_update → touch_end. The driver is responsible
2192  * for sending along such order.
2193  *
2194  */
2195 WL_EXPORT void
2196 notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
2197              wl_fixed_t x, wl_fixed_t y, int touch_type)
2198 {
2199         struct weston_compositor *ec = seat->compositor;
2200         struct wl_touch *touch = seat->seat.touch;
2201         struct wl_touch_grab *grab = touch->grab;
2202         struct weston_surface *es;
2203         wl_fixed_t sx, sy;
2204
2205         /* Update grab's global coordinates. */
2206         touch->grab_x = x;
2207         touch->grab_y = y;
2208
2209         switch (touch_type) {
2210         case WL_TOUCH_DOWN:
2211                 weston_compositor_idle_inhibit(ec);
2212
2213                 seat->num_tp++;
2214
2215                 /* the first finger down picks the surface, and all further go
2216                  * to that surface for the remainder of the touch session i.e.
2217                  * until all touch points are up again. */
2218                 if (seat->num_tp == 1) {
2219                         es = weston_compositor_pick_surface(ec, x, y, &sx, &sy);
2220                         touch_set_focus(seat, &es->surface);
2221                 } else if (touch->focus) {
2222                         es = (struct weston_surface *) touch->focus;
2223                         weston_surface_from_global_fixed(es, x, y, &sx, &sy);
2224                 } else {
2225                         /* Unexpected condition: We have non-initial touch but
2226                          * there is no focused surface.
2227                          */
2228                         weston_log("touch event received with %d points down"
2229                                    "but no surface focused\n", seat->num_tp);
2230                         return;
2231                 }
2232
2233                 grab->interface->down(grab, time, touch_id, sx, sy);
2234                 break;
2235         case WL_TOUCH_MOTION:
2236                 es = (struct weston_surface *) touch->focus;
2237                 if (!es)
2238                         break;
2239
2240                 weston_surface_from_global_fixed(es, x, y, &sx, &sy);
2241                 grab->interface->motion(grab, time, touch_id, sx, sy);
2242                 break;
2243         case WL_TOUCH_UP:
2244                 weston_compositor_idle_release(ec);
2245                 seat->num_tp--;
2246
2247                 grab->interface->up(grab, time, touch_id);
2248                 if (seat->num_tp == 0)
2249                         touch_set_focus(seat, NULL);
2250                 break;
2251         }
2252 }
2253
2254 static void
2255 pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
2256 {
2257         struct weston_seat *seat = container_of(listener, struct weston_seat,
2258                                                 sprite_destroy_listener);
2259
2260         seat->sprite = NULL;
2261 }
2262
2263 static void
2264 pointer_cursor_surface_configure(struct weston_surface *es,
2265                                  int32_t dx, int32_t dy, int32_t width, int32_t height)
2266 {
2267         struct weston_seat *seat = es->private;
2268         int x, y;
2269
2270         if (width == 0)
2271                 return;
2272
2273         assert(es == seat->sprite);
2274
2275         seat->hotspot_x -= dx;
2276         seat->hotspot_y -= dy;
2277
2278         x = wl_fixed_to_int(seat->seat.pointer->x) - seat->hotspot_x;
2279         y = wl_fixed_to_int(seat->seat.pointer->y) - seat->hotspot_y;
2280
2281         weston_surface_configure(seat->sprite, x, y,
2282                                  width, height);
2283
2284         empty_region(&es->pending.input);
2285
2286         if (!weston_surface_is_mapped(es)) {
2287                 wl_list_insert(&es->compositor->cursor_layer.surface_list,
2288                                &es->layer_link);
2289                 weston_surface_update_transform(es);
2290         }
2291 }
2292
2293 static void
2294 pointer_unmap_sprite(struct weston_seat *seat)
2295 {
2296         if (weston_surface_is_mapped(seat->sprite))
2297                 weston_surface_unmap(seat->sprite);
2298
2299         wl_list_remove(&seat->sprite_destroy_listener.link);
2300         seat->sprite->configure = NULL;
2301         seat->sprite->private = NULL;
2302         seat->sprite = NULL;
2303 }
2304
2305 static void
2306 pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
2307                    uint32_t serial, struct wl_resource *surface_resource,
2308                    int32_t x, int32_t y)
2309 {
2310         struct weston_seat *seat = resource->data;
2311         struct weston_surface *surface = NULL;
2312
2313         if (surface_resource)
2314                 surface = surface_resource->data;
2315
2316         if (seat->seat.pointer->focus == NULL)
2317                 return;
2318         if (seat->seat.pointer->focus->resource.client != client)
2319                 return;
2320         if (seat->seat.pointer->focus_serial - serial > UINT32_MAX / 2)
2321                 return;
2322
2323         if (surface && surface != seat->sprite) {
2324                 if (surface->configure) {
2325                         wl_resource_post_error(&surface->surface.resource,
2326                                                WL_DISPLAY_ERROR_INVALID_OBJECT,
2327                                                "surface->configure already "
2328                                                "set");
2329                         return;
2330                 }
2331         }
2332
2333         if (seat->sprite)
2334                 pointer_unmap_sprite(seat);
2335
2336         if (!surface)
2337                 return;
2338
2339         wl_signal_add(&surface->surface.resource.destroy_signal,
2340                       &seat->sprite_destroy_listener);
2341
2342         surface->configure = pointer_cursor_surface_configure;
2343         surface->private = seat;
2344         seat->sprite = surface;
2345         seat->hotspot_x = x;
2346         seat->hotspot_y = y;
2347
2348         if (surface->buffer_ref.buffer)
2349                 pointer_cursor_surface_configure(surface, 0, 0, weston_surface_buffer_width(surface),
2350                                                                 weston_surface_buffer_height(surface));
2351 }
2352
2353 static const struct wl_pointer_interface pointer_interface = {
2354         pointer_set_cursor
2355 };
2356
2357 static void
2358 handle_drag_surface_destroy(struct wl_listener *listener, void *data)
2359 {
2360         struct weston_seat *seat;
2361
2362         seat = container_of(listener, struct weston_seat,
2363                             drag_surface_destroy_listener);
2364
2365         seat->drag_surface = NULL;
2366 }
2367
2368 static void unbind_resource(struct wl_resource *resource)
2369 {
2370         wl_list_remove(&resource->link);
2371         free(resource);
2372 }
2373
2374 static void
2375 seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
2376                  uint32_t id)
2377 {
2378         struct weston_seat *seat = resource->data;
2379         struct wl_resource *cr;
2380
2381         if (!seat->seat.pointer)
2382                 return;
2383
2384         cr = wl_client_add_object(client, &wl_pointer_interface,
2385                                   &pointer_interface, id, seat);
2386         wl_list_insert(&seat->seat.pointer->resource_list, &cr->link);
2387         cr->destroy = unbind_resource;
2388
2389         if (seat->seat.pointer->focus &&
2390             seat->seat.pointer->focus->resource.client == client) {
2391                 struct weston_surface *surface;
2392                 wl_fixed_t sx, sy;
2393
2394                 surface = (struct weston_surface *) seat->seat.pointer->focus;
2395                 weston_surface_from_global_fixed(surface,
2396                                                  seat->seat.pointer->x,
2397                                                  seat->seat.pointer->y,
2398                                                  &sx,
2399                                                  &sy);
2400                 wl_pointer_set_focus(seat->seat.pointer,
2401                                      seat->seat.pointer->focus,
2402                                      sx,
2403                                      sy);
2404         }
2405 }
2406
2407 static void
2408 seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
2409                   uint32_t id)
2410 {
2411         struct weston_seat *seat = resource->data;
2412         struct wl_resource *cr;
2413
2414         if (!seat->seat.keyboard)
2415                 return;
2416
2417         cr = wl_client_add_object(client, &wl_keyboard_interface, NULL, id,
2418                                   seat);
2419         wl_list_insert(&seat->seat.keyboard->resource_list, &cr->link);
2420         cr->destroy = unbind_resource;
2421
2422         wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
2423                                 seat->xkb_info.keymap_fd,
2424                                 seat->xkb_info.keymap_size);
2425
2426         if (seat->seat.keyboard->focus &&
2427             seat->seat.keyboard->focus->resource.client == client) {
2428                 wl_keyboard_set_focus(seat->seat.keyboard,
2429                                       seat->seat.keyboard->focus);
2430                 wl_data_device_set_keyboard_focus(&seat->seat);
2431         }
2432 }
2433
2434 static void
2435 seat_get_touch(struct wl_client *client, struct wl_resource *resource,
2436                uint32_t id)
2437 {
2438         struct weston_seat *seat = resource->data;
2439         struct wl_resource *cr;
2440
2441         if (!seat->seat.touch)
2442                 return;
2443
2444         cr = wl_client_add_object(client, &wl_touch_interface, NULL, id, seat);
2445         wl_list_insert(&seat->seat.touch->resource_list, &cr->link);
2446         cr->destroy = unbind_resource;
2447 }
2448
2449 static const struct wl_seat_interface seat_interface = {
2450         seat_get_pointer,
2451         seat_get_keyboard,
2452         seat_get_touch,
2453 };
2454
2455 static void
2456 bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
2457 {
2458         struct wl_seat *seat = data;
2459         struct wl_resource *resource;
2460         enum wl_seat_capability caps = 0;
2461
2462         resource = wl_client_add_object(client, &wl_seat_interface,
2463                                         &seat_interface, id, data);
2464         wl_list_insert(&seat->base_resource_list, &resource->link);
2465         resource->destroy = unbind_resource;
2466
2467         if (seat->pointer)
2468                 caps |= WL_SEAT_CAPABILITY_POINTER;
2469         if (seat->keyboard)
2470                 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
2471         if (seat->touch)
2472                 caps |= WL_SEAT_CAPABILITY_TOUCH;
2473
2474         wl_seat_send_capabilities(resource, caps);
2475 }
2476
2477 static void
2478 device_handle_new_drag_icon(struct wl_listener *listener, void *data)
2479 {
2480         struct weston_seat *seat;
2481
2482         seat = container_of(listener, struct weston_seat,
2483                             new_drag_icon_listener);
2484
2485         weston_seat_update_drag_surface(seat, 0, 0);
2486 }
2487
2488 static int
2489 weston_compositor_xkb_init(struct weston_compositor *ec,
2490                            struct xkb_rule_names *names)
2491 {
2492         if (ec->xkb_context == NULL) {
2493                 ec->xkb_context = xkb_context_new(0);
2494                 if (ec->xkb_context == NULL) {
2495                         weston_log("failed to create XKB context\n");
2496                         return -1;
2497                 }
2498         }
2499
2500         if (names)
2501                 ec->xkb_names = *names;
2502         if (!ec->xkb_names.rules)
2503                 ec->xkb_names.rules = strdup("evdev");
2504         if (!ec->xkb_names.model)
2505                 ec->xkb_names.model = strdup("pc105");
2506         if (!ec->xkb_names.layout)
2507                 ec->xkb_names.layout = strdup("us");
2508
2509         return 0;
2510 }
2511
2512 static void xkb_info_destroy(struct weston_xkb_info *xkb_info)
2513 {
2514         if (xkb_info->keymap)
2515                 xkb_map_unref(xkb_info->keymap);
2516
2517         if (xkb_info->keymap_area)
2518                 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
2519         if (xkb_info->keymap_fd >= 0)
2520                 close(xkb_info->keymap_fd);
2521 }
2522
2523 static void weston_compositor_xkb_destroy(struct weston_compositor *ec)
2524 {
2525         free((char *) ec->xkb_names.rules);
2526         free((char *) ec->xkb_names.model);
2527         free((char *) ec->xkb_names.layout);
2528         free((char *) ec->xkb_names.variant);
2529         free((char *) ec->xkb_names.options);
2530
2531         xkb_info_destroy(&ec->xkb_info);
2532         xkb_context_unref(ec->xkb_context);
2533 }
2534
2535 static int
2536 weston_xkb_info_new_keymap(struct weston_xkb_info *xkb_info)
2537 {
2538         char *keymap_str;
2539
2540         xkb_info->shift_mod = xkb_map_mod_get_index(xkb_info->keymap,
2541                                                     XKB_MOD_NAME_SHIFT);
2542         xkb_info->caps_mod = xkb_map_mod_get_index(xkb_info->keymap,
2543                                                    XKB_MOD_NAME_CAPS);
2544         xkb_info->ctrl_mod = xkb_map_mod_get_index(xkb_info->keymap,
2545                                                    XKB_MOD_NAME_CTRL);
2546         xkb_info->alt_mod = xkb_map_mod_get_index(xkb_info->keymap,
2547                                                   XKB_MOD_NAME_ALT);
2548         xkb_info->mod2_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod2");
2549         xkb_info->mod3_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod3");
2550         xkb_info->super_mod = xkb_map_mod_get_index(xkb_info->keymap,
2551                                                     XKB_MOD_NAME_LOGO);
2552         xkb_info->mod5_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod5");
2553
2554         xkb_info->num_led = xkb_map_led_get_index(xkb_info->keymap,
2555                                                   XKB_LED_NAME_NUM);
2556         xkb_info->caps_led = xkb_map_led_get_index(xkb_info->keymap,
2557                                                    XKB_LED_NAME_CAPS);
2558         xkb_info->scroll_led = xkb_map_led_get_index(xkb_info->keymap,
2559                                                      XKB_LED_NAME_SCROLL);
2560
2561         keymap_str = xkb_map_get_as_string(xkb_info->keymap);
2562         if (keymap_str == NULL) {
2563                 weston_log("failed to get string version of keymap\n");
2564                 return -1;
2565         }
2566         xkb_info->keymap_size = strlen(keymap_str) + 1;
2567
2568         xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
2569         if (xkb_info->keymap_fd < 0) {
2570                 weston_log("creating a keymap file for %lu bytes failed: %m\n",
2571                         (unsigned long) xkb_info->keymap_size);
2572                 goto err_keymap_str;
2573         }
2574
2575         xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
2576                                      PROT_READ | PROT_WRITE,
2577                                      MAP_SHARED, xkb_info->keymap_fd, 0);
2578         if (xkb_info->keymap_area == MAP_FAILED) {
2579                 weston_log("failed to mmap() %lu bytes\n",
2580                         (unsigned long) xkb_info->keymap_size);
2581                 goto err_dev_zero;
2582         }
2583         strcpy(xkb_info->keymap_area, keymap_str);
2584         free(keymap_str);
2585
2586         return 0;
2587
2588 err_dev_zero:
2589         close(xkb_info->keymap_fd);
2590         xkb_info->keymap_fd = -1;
2591 err_keymap_str:
2592         free(keymap_str);
2593         return -1;
2594 }
2595
2596 static int
2597 weston_compositor_build_global_keymap(struct weston_compositor *ec)
2598 {
2599         if (ec->xkb_info.keymap != NULL)
2600                 return 0;
2601
2602         ec->xkb_info.keymap = xkb_map_new_from_names(ec->xkb_context,
2603                                                      &ec->xkb_names,
2604                                                      0);
2605         if (ec->xkb_info.keymap == NULL) {
2606                 weston_log("failed to compile global XKB keymap\n");
2607                 weston_log("  tried rules %s, model %s, layout %s, variant %s, "
2608                         "options %s\n",
2609                         ec->xkb_names.rules, ec->xkb_names.model,
2610                         ec->xkb_names.layout, ec->xkb_names.variant,
2611                         ec->xkb_names.options);
2612                 return -1;
2613         }
2614
2615         if (weston_xkb_info_new_keymap(&ec->xkb_info) < 0)
2616                 return -1;
2617
2618         return 0;
2619 }
2620
2621 WL_EXPORT int
2622 weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
2623 {
2624         if (seat->has_keyboard)
2625                 return 0;
2626
2627         if (keymap != NULL) {
2628                 seat->xkb_info.keymap = xkb_map_ref(keymap);
2629                 if (weston_xkb_info_new_keymap(&seat->xkb_info) < 0)
2630                         return -1;
2631         } else {
2632                 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
2633                         return -1;
2634                 seat->xkb_info = seat->compositor->xkb_info;
2635                 seat->xkb_info.keymap = xkb_map_ref(seat->xkb_info.keymap);
2636         }
2637
2638         seat->xkb_state.state = xkb_state_new(seat->xkb_info.keymap);
2639         if (seat->xkb_state.state == NULL) {
2640                 weston_log("failed to initialise XKB state\n");
2641                 return -1;
2642         }
2643
2644         seat->xkb_state.leds = 0;
2645
2646         wl_keyboard_init(&seat->keyboard.keyboard);
2647         wl_seat_set_keyboard(&seat->seat, &seat->keyboard.keyboard);
2648
2649         seat->has_keyboard = 1;
2650
2651         return 0;
2652 }
2653
2654 WL_EXPORT void
2655 weston_seat_init_pointer(struct weston_seat *seat)
2656 {
2657         if (seat->has_pointer)
2658                 return;
2659
2660         wl_pointer_init(&seat->pointer);
2661         wl_seat_set_pointer(&seat->seat, &seat->pointer);
2662
2663         seat->has_pointer = 1;
2664 }
2665
2666 WL_EXPORT void
2667 weston_seat_init_touch(struct weston_seat *seat)
2668 {
2669         if (seat->has_touch)
2670                 return;
2671
2672         wl_touch_init(&seat->touch);
2673         wl_seat_set_touch(&seat->seat, &seat->touch);
2674
2675         seat->has_touch = 1;
2676 }
2677
2678 WL_EXPORT void
2679 weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec)
2680 {
2681         wl_seat_init(&seat->seat);
2682         seat->has_pointer = 0;
2683         seat->has_keyboard = 0;
2684         seat->has_touch = 0;
2685
2686         wl_display_add_global(ec->wl_display, &wl_seat_interface, seat,
2687                               bind_seat);
2688
2689         seat->sprite = NULL;
2690         seat->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
2691
2692         seat->compositor = ec;
2693         seat->hotspot_x = 16;
2694         seat->hotspot_y = 16;
2695         seat->modifier_state = 0;
2696         seat->num_tp = 0;
2697
2698         seat->drag_surface_destroy_listener.notify =
2699                 handle_drag_surface_destroy;
2700
2701         wl_list_insert(ec->seat_list.prev, &seat->link);
2702
2703         seat->new_drag_icon_listener.notify = device_handle_new_drag_icon;
2704         wl_signal_add(&seat->seat.drag_icon_signal,
2705                       &seat->new_drag_icon_listener);
2706
2707         clipboard_create(seat);
2708         wl_signal_emit(&ec->seat_created_signal, seat);
2709 }
2710
2711 WL_EXPORT void
2712 weston_seat_release(struct weston_seat *seat)
2713 {
2714         wl_list_remove(&seat->link);
2715         /* The global object is destroyed at wl_display_destroy() time. */
2716
2717         if (seat->sprite)
2718                 pointer_unmap_sprite(seat);
2719
2720         if (seat->xkb_state.state != NULL)
2721                 xkb_state_unref(seat->xkb_state.state);
2722         xkb_info_destroy(&seat->xkb_info);
2723
2724         wl_seat_release(&seat->seat);
2725 }
2726
2727 static void
2728 drag_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
2729 {
2730         empty_region(&es->pending.input);
2731
2732         weston_surface_configure(es,
2733                                  es->geometry.x + sx, es->geometry.y + sy,
2734                                  width, height);
2735 }
2736
2737 static int
2738 device_setup_new_drag_surface(struct weston_seat *ws,
2739                               struct weston_surface *surface)
2740 {
2741         struct wl_seat *seat = &ws->seat;
2742
2743         if (surface->configure) {
2744                 wl_resource_post_error(&surface->surface.resource,
2745                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
2746                                        "surface->configure already set");
2747                 return 0;
2748         }
2749
2750         ws->drag_surface = surface;
2751
2752         weston_surface_set_position(ws->drag_surface,
2753                                     wl_fixed_to_double(seat->pointer->x),
2754                                     wl_fixed_to_double(seat->pointer->y));
2755
2756         surface->configure = drag_surface_configure;
2757
2758         wl_signal_add(&surface->surface.resource.destroy_signal,
2759                        &ws->drag_surface_destroy_listener);
2760
2761         return 1;
2762 }
2763
2764 static void
2765 device_release_drag_surface(struct weston_seat *seat)
2766 {
2767         if (weston_surface_is_mapped(seat->drag_surface))
2768                 weston_surface_unmap(seat->drag_surface);
2769
2770         seat->drag_surface->configure = NULL;
2771         empty_region(&seat->drag_surface->pending.input);
2772         wl_list_remove(&seat->drag_surface_destroy_listener.link);
2773         seat->drag_surface = NULL;
2774 }
2775
2776 static void
2777 device_map_drag_surface(struct weston_seat *seat)
2778 {
2779         struct wl_list *list;
2780
2781         if (weston_surface_is_mapped(seat->drag_surface) ||
2782             !seat->drag_surface->buffer_ref.buffer)
2783                 return;
2784
2785         if (seat->sprite && weston_surface_is_mapped(seat->sprite))
2786                 list = &seat->sprite->layer_link;
2787         else
2788                 list = &seat->compositor->cursor_layer.surface_list;
2789
2790         wl_list_insert(list, &seat->drag_surface->layer_link);
2791         weston_surface_update_transform(seat->drag_surface);
2792         empty_region(&seat->drag_surface->input);
2793 }
2794
2795 static  void
2796 weston_seat_update_drag_surface(struct weston_seat *seat,
2797                                 int dx, int dy)
2798 {
2799         int surface_changed = 0;
2800
2801         if (!seat->drag_surface && !seat->seat.drag_surface)
2802                 return;
2803
2804         if (seat->drag_surface && seat->seat.drag_surface &&
2805             (&seat->drag_surface->surface.resource !=
2806              &seat->seat.drag_surface->resource))
2807                 /* between calls to this funcion we got a new drag_surface */
2808                 surface_changed = 1;
2809
2810         if (!seat->seat.drag_surface || surface_changed) {
2811                 device_release_drag_surface(seat);
2812                 if (!surface_changed)
2813                         return;
2814         }
2815
2816         if (!seat->drag_surface || surface_changed) {
2817                 struct weston_surface *surface = (struct weston_surface *)
2818                         seat->seat.drag_surface;
2819                 if (!device_setup_new_drag_surface(seat, surface))
2820                         return;
2821         }
2822
2823         /* the client may not have attached a buffer to the drag surface
2824          * when we setup it up, so check if map is needed on every update */
2825         device_map_drag_surface(seat);
2826
2827         if (!dx && !dy)
2828                 return;
2829
2830         weston_surface_set_position(seat->drag_surface,
2831                                     seat->drag_surface->geometry.x + wl_fixed_to_double(dx),
2832                                     seat->drag_surface->geometry.y + wl_fixed_to_double(dy));
2833 }
2834
2835 WL_EXPORT void
2836 weston_compositor_update_drag_surfaces(struct weston_compositor *compositor)
2837 {
2838         struct weston_seat *seat;
2839
2840         wl_list_for_each(seat, &compositor->seat_list, link)
2841                 weston_seat_update_drag_surface(seat, 0, 0);
2842 }
2843
2844 static void
2845 bind_output(struct wl_client *client,
2846             void *data, uint32_t version, uint32_t id)
2847 {
2848         struct weston_output *output = data;
2849         struct weston_mode *mode;
2850         struct wl_resource *resource;
2851
2852         resource = wl_client_add_object(client,
2853                                         &wl_output_interface, NULL, id, data);
2854
2855         wl_list_insert(&output->resource_list, &resource->link);
2856         resource->destroy = unbind_resource;
2857
2858         wl_output_send_geometry(resource,
2859                                 output->x,
2860                                 output->y,
2861                                 output->mm_width,
2862                                 output->mm_height,
2863                                 output->subpixel,
2864                                 output->make, output->model,
2865                                 output->transform);
2866
2867         wl_list_for_each (mode, &output->mode_list, link) {
2868                 wl_output_send_mode(resource,
2869                                     mode->flags,
2870                                     mode->width,
2871                                     mode->height,
2872                                     mode->refresh);
2873         }
2874 }
2875
2876 WL_EXPORT void
2877 weston_output_destroy(struct weston_output *output)
2878 {
2879         struct weston_compositor *c = output->compositor;
2880
2881         pixman_region32_fini(&output->region);
2882         pixman_region32_fini(&output->previous_damage);
2883         output->compositor->output_id_pool &= ~(1 << output->id);
2884
2885         wl_display_remove_global(c->wl_display, output->global);
2886 }
2887
2888 static void
2889 weston_output_compute_transform(struct weston_output *output)
2890 {
2891         struct weston_matrix transform;
2892         int flip;
2893
2894         weston_matrix_init(&transform);
2895         transform.type = WESTON_MATRIX_TRANSFORM_ROTATE;
2896
2897         switch(output->transform) {
2898         case WL_OUTPUT_TRANSFORM_FLIPPED:
2899         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2900         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
2901         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2902                 transform.type |= WESTON_MATRIX_TRANSFORM_OTHER;
2903                 flip = -1;
2904                 break;
2905         default:
2906                 flip = 1;
2907                 break;
2908         }
2909
2910         switch(output->transform) {
2911         case WL_OUTPUT_TRANSFORM_NORMAL:
2912         case WL_OUTPUT_TRANSFORM_FLIPPED:
2913                 transform.d[0] = flip;
2914                 transform.d[1] = 0;
2915                 transform.d[4] = 0;
2916                 transform.d[5] = 1;
2917                 break;
2918         case WL_OUTPUT_TRANSFORM_90:
2919         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2920                 transform.d[0] = 0;
2921                 transform.d[1] = -flip;
2922                 transform.d[4] = 1;
2923                 transform.d[5] = 0;
2924                 break;
2925         case WL_OUTPUT_TRANSFORM_180:
2926         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
2927                 transform.d[0] = -flip;
2928                 transform.d[1] = 0;
2929                 transform.d[4] = 0;
2930                 transform.d[5] = -1;
2931                 break;
2932         case WL_OUTPUT_TRANSFORM_270:
2933         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2934                 transform.d[0] = 0;
2935                 transform.d[1] = flip;
2936                 transform.d[4] = -1;
2937                 transform.d[5] = 0;
2938                 break;
2939         default:
2940                 break;
2941         }
2942
2943         weston_matrix_multiply(&output->matrix, &transform);
2944 }
2945
2946 WL_EXPORT void
2947 weston_output_update_matrix(struct weston_output *output)
2948 {
2949         float magnification;
2950         struct weston_matrix camera;
2951         struct weston_matrix modelview;
2952
2953         weston_matrix_init(&output->matrix);
2954         weston_matrix_translate(&output->matrix,
2955                                 -(output->x + (output->border.right + output->width - output->border.left) / 2.0),
2956                                 -(output->y + (output->border.bottom + output->height - output->border.top) / 2.0), 0);
2957
2958         weston_matrix_scale(&output->matrix,
2959                             2.0 / (output->width + output->border.left + output->border.right),
2960                             -2.0 / (output->height + output->border.top + output->border.bottom), 1);
2961
2962         weston_output_compute_transform(output);
2963
2964         if (output->zoom.active) {
2965                 magnification = 1 / (1 - output->zoom.spring_z.current);
2966                 weston_matrix_init(&camera);
2967                 weston_matrix_init(&modelview);
2968                 weston_output_update_zoom(output, output->zoom.type);
2969                 weston_matrix_translate(&camera, output->zoom.trans_x,
2970                                         -output->zoom.trans_y, 0);
2971                 weston_matrix_invert(&modelview, &camera);
2972                 weston_matrix_scale(&modelview, magnification, magnification, 1.0);
2973                 weston_matrix_multiply(&output->matrix, &modelview);
2974         }
2975
2976         output->dirty = 0;
2977 }
2978
2979 static void
2980 weston_output_transform_init(struct weston_output *output, uint32_t transform)
2981 {
2982         output->transform = transform;
2983
2984         switch (transform) {
2985         case WL_OUTPUT_TRANSFORM_90:
2986         case WL_OUTPUT_TRANSFORM_270:
2987         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2988         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2989                 /* Swap width and height */
2990                 output->width = output->current->height;
2991                 output->height = output->current->width;
2992                 break;
2993         case WL_OUTPUT_TRANSFORM_NORMAL:
2994         case WL_OUTPUT_TRANSFORM_180:
2995         case WL_OUTPUT_TRANSFORM_FLIPPED:
2996         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
2997                 output->width = output->current->width;
2998                 output->height = output->current->height;
2999                 break;
3000         default:
3001                 break;
3002         }
3003 }
3004
3005 WL_EXPORT void
3006 weston_output_move(struct weston_output *output, int x, int y)
3007 {
3008         output->x = x;
3009         output->y = y;
3010
3011         pixman_region32_init(&output->previous_damage);
3012         pixman_region32_init_rect(&output->region, x, y,
3013                                   output->width,
3014                                   output->height);
3015 }
3016
3017 WL_EXPORT void
3018 weston_output_init(struct weston_output *output, struct weston_compositor *c,
3019                    int x, int y, int width, int height, uint32_t transform)
3020 {
3021         output->compositor = c;
3022         output->x = x;
3023         output->y = y;
3024         output->border.top = 0;
3025         output->border.bottom = 0;
3026         output->border.left = 0;
3027         output->border.right = 0;
3028         output->mm_width = width;
3029         output->mm_height = height;
3030         output->dirty = 1;
3031
3032         weston_output_transform_init(output, transform);
3033         weston_output_init_zoom(output);
3034
3035         weston_output_move(output, x, y);
3036         weston_output_damage(output);
3037
3038         wl_signal_init(&output->frame_signal);
3039         wl_list_init(&output->animation_list);
3040         wl_list_init(&output->resource_list);
3041
3042         output->id = ffs(~output->compositor->output_id_pool) - 1;
3043         output->compositor->output_id_pool |= 1 << output->id;
3044
3045         output->global =
3046                 wl_display_add_global(c->wl_display, &wl_output_interface,
3047                                       output, bind_output);
3048 }
3049
3050 static void
3051 compositor_bind(struct wl_client *client,
3052                 void *data, uint32_t version, uint32_t id)
3053 {
3054         struct weston_compositor *compositor = data;
3055
3056         wl_client_add_object(client, &wl_compositor_interface,
3057                              &compositor_interface, id, compositor);
3058 }
3059
3060 static void
3061 log_uname(void)
3062 {
3063         struct utsname usys;
3064
3065         uname(&usys);
3066
3067         weston_log("OS: %s, %s, %s, %s\n", usys.sysname, usys.release,
3068                                                 usys.version, usys.machine);
3069 }
3070
3071 WL_EXPORT int
3072 weston_environment_get_fd(const char *env)
3073 {
3074         char *e, *end;
3075         int fd, flags;
3076
3077         e = getenv(env);
3078         if (!e)
3079                 return -1;
3080         fd = strtol(e, &end, 0);
3081         if (*end != '\0')
3082                 return -1;
3083
3084         flags = fcntl(fd, F_GETFD);
3085         if (flags == -1)
3086                 return -1;
3087
3088         fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
3089         unsetenv(env);
3090
3091         return fd;
3092 }
3093
3094 WL_EXPORT int
3095 weston_compositor_init(struct weston_compositor *ec,
3096                        struct wl_display *display,
3097                        int *argc, char *argv[],
3098                        const char *config_file)
3099 {
3100         struct wl_event_loop *loop;
3101         struct xkb_rule_names xkb_names;
3102         const struct config_key keyboard_config_keys[] = {
3103                 { "keymap_rules", CONFIG_KEY_STRING, &xkb_names.rules },
3104                 { "keymap_model", CONFIG_KEY_STRING, &xkb_names.model },
3105                 { "keymap_layout", CONFIG_KEY_STRING, &xkb_names.layout },
3106                 { "keymap_variant", CONFIG_KEY_STRING, &xkb_names.variant },
3107                 { "keymap_options", CONFIG_KEY_STRING, &xkb_names.options },
3108         };
3109         const struct config_section cs[] = {
3110                 { "keyboard",
3111                   keyboard_config_keys, ARRAY_LENGTH(keyboard_config_keys) },
3112         };
3113
3114         memset(&xkb_names, 0, sizeof(xkb_names));
3115         parse_config_file(config_file, cs, ARRAY_LENGTH(cs), ec);
3116
3117         ec->wl_display = display;
3118         wl_signal_init(&ec->destroy_signal);
3119         wl_signal_init(&ec->activate_signal);
3120         wl_signal_init(&ec->kill_signal);
3121         wl_signal_init(&ec->idle_signal);
3122         wl_signal_init(&ec->wake_signal);
3123         wl_signal_init(&ec->show_input_panel_signal);
3124         wl_signal_init(&ec->hide_input_panel_signal);
3125         wl_signal_init(&ec->seat_created_signal);
3126         ec->launcher_sock = weston_environment_get_fd("WESTON_LAUNCHER_SOCK");
3127
3128         ec->output_id_pool = 0;
3129
3130         if (!wl_display_add_global(display, &wl_compositor_interface,
3131                                    ec, compositor_bind))
3132                 return -1;
3133
3134         wl_list_init(&ec->surface_list);
3135         wl_list_init(&ec->plane_list);
3136         wl_list_init(&ec->layer_list);
3137         wl_list_init(&ec->seat_list);
3138         wl_list_init(&ec->output_list);
3139         wl_list_init(&ec->key_binding_list);
3140         wl_list_init(&ec->button_binding_list);
3141         wl_list_init(&ec->axis_binding_list);
3142         wl_list_init(&ec->debug_binding_list);
3143
3144         weston_plane_init(&ec->primary_plane, 0, 0);
3145         weston_compositor_stack_plane(ec, &ec->primary_plane, NULL);
3146
3147         if (weston_compositor_xkb_init(ec, &xkb_names) < 0)
3148                 return -1;
3149
3150         ec->ping_handler = NULL;
3151
3152         screenshooter_create(ec);
3153         text_cursor_position_notifier_create(ec);
3154         text_backend_init(ec);
3155
3156         wl_data_device_manager_init(ec->wl_display);
3157
3158         wl_display_init_shm(display);
3159
3160         loop = wl_display_get_event_loop(ec->wl_display);
3161         ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
3162         wl_event_source_timer_update(ec->idle_source, ec->idle_time * 1000);
3163
3164         ec->input_loop = wl_event_loop_create();
3165
3166         weston_layer_init(&ec->fade_layer, &ec->layer_list);
3167         weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
3168
3169         weston_compositor_schedule_repaint(ec);
3170
3171         return 0;
3172 }
3173
3174 WL_EXPORT void
3175 weston_compositor_shutdown(struct weston_compositor *ec)
3176 {
3177         struct weston_output *output, *next;
3178
3179         wl_event_source_remove(ec->idle_source);
3180         if (ec->input_loop_source)
3181                 wl_event_source_remove(ec->input_loop_source);
3182
3183         /* Destroy all outputs associated with this compositor */
3184         wl_list_for_each_safe(output, next, &ec->output_list, link)
3185                 output->destroy(output);
3186
3187         weston_binding_list_destroy_all(&ec->key_binding_list);
3188         weston_binding_list_destroy_all(&ec->button_binding_list);
3189         weston_binding_list_destroy_all(&ec->axis_binding_list);
3190         weston_binding_list_destroy_all(&ec->debug_binding_list);
3191
3192         weston_plane_release(&ec->primary_plane);
3193
3194         wl_array_release(&ec->vertices);
3195         wl_array_release(&ec->indices);
3196         wl_array_release(&ec->vtxcnt);
3197
3198         wl_event_loop_destroy(ec->input_loop);
3199 }
3200
3201 WL_EXPORT void
3202 weston_version(int *major, int *minor, int *micro)
3203 {
3204         *major = WESTON_VERSION_MAJOR;
3205         *minor = WESTON_VERSION_MINOR;
3206         *micro = WESTON_VERSION_MICRO;
3207 }
3208
3209 static int on_term_signal(int signal_number, void *data)
3210 {
3211         struct wl_display *display = data;
3212
3213         weston_log("caught signal %d\n", signal_number);
3214         wl_display_terminate(display);
3215
3216         return 1;
3217 }
3218
3219 #ifdef HAVE_LIBUNWIND
3220
3221 static void
3222 print_backtrace(void)
3223 {
3224         unw_cursor_t cursor;
3225         unw_context_t context;
3226         unw_word_t off;
3227         unw_proc_info_t pip;
3228         int ret, i = 0;
3229         char procname[256];
3230         const char *filename;
3231         Dl_info dlinfo;
3232
3233         pip.unwind_info = NULL;
3234         ret = unw_getcontext(&context);
3235         if (ret) {
3236                 weston_log("unw_getcontext: %d\n", ret);
3237                 return;
3238         }
3239
3240         ret = unw_init_local(&cursor, &context);
3241         if (ret) {
3242                 weston_log("unw_init_local: %d\n", ret);
3243                 return;
3244         }
3245
3246         ret = unw_step(&cursor);
3247         while (ret > 0) {
3248                 ret = unw_get_proc_info(&cursor, &pip);
3249                 if (ret) {
3250                         weston_log("unw_get_proc_info: %d\n", ret);
3251                         break;
3252                 }
3253
3254                 ret = unw_get_proc_name(&cursor, procname, 256, &off);
3255                 if (ret && ret != -UNW_ENOMEM) {
3256                         if (ret != -UNW_EUNSPEC)
3257                                 weston_log("unw_get_proc_name: %d\n", ret);
3258                         procname[0] = '?';
3259                         procname[1] = 0;
3260                 }
3261
3262                 if (dladdr((void *)(pip.start_ip + off), &dlinfo) && dlinfo.dli_fname &&
3263                     *dlinfo.dli_fname)
3264                         filename = dlinfo.dli_fname;
3265                 else
3266                         filename = "?";
3267                 
3268                 weston_log("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,
3269                            ret == -UNW_ENOMEM ? "..." : "", (int)off, (void *)(pip.start_ip + off));
3270
3271                 ret = unw_step(&cursor);
3272                 if (ret < 0)
3273                         weston_log("unw_step: %d\n", ret);
3274         }
3275 }
3276
3277 #else
3278
3279 static void
3280 print_backtrace(void)
3281 {
3282         void *buffer[32];
3283         int i, count;
3284         Dl_info info;
3285
3286         count = backtrace(buffer, ARRAY_LENGTH(buffer));
3287         for (i = 0; i < count; i++) {
3288                 dladdr(buffer[i], &info);
3289                 weston_log("  [%016lx]  %s  (%s)\n",
3290                         (long) buffer[i],
3291                         info.dli_sname ? info.dli_sname : "--",
3292                         info.dli_fname);
3293         }
3294 }
3295
3296 #endif
3297
3298 static void
3299 on_segv_signal(int s, siginfo_t *siginfo, void *context)
3300 {
3301         /* This SIGSEGV handler will do a best-effort backtrace, and
3302          * then call the backend restore function, which will switch
3303          * back to the vt we launched from or ungrab X etc and then
3304          * raise SIGTRAP.  If we run weston under gdb from X or a
3305          * different vt, and tell gdb "handle SIGSEGV nostop", this
3306          * will allow weston to switch back to gdb on crash and then
3307          * gdb will catch the crash with SIGTRAP. */
3308
3309         weston_log("caught segv\n");
3310
3311         print_backtrace();
3312
3313         segv_compositor->restore(segv_compositor);
3314
3315         raise(SIGTRAP);
3316 }
3317
3318
3319 static void *
3320 load_module(const char *name, const char *entrypoint)
3321 {
3322         char path[PATH_MAX];
3323         void *module, *init;
3324
3325         if (name[0] != '/')
3326                 snprintf(path, sizeof path, "%s/%s", MODULEDIR, name);
3327         else
3328                 snprintf(path, sizeof path, "%s", name);
3329
3330         module = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
3331         if (module) {
3332                 weston_log("Module '%s' already loaded\n", path);
3333                 dlclose(module);
3334                 return NULL;
3335         }
3336
3337         weston_log("Loading module '%s'\n", path);
3338         module = dlopen(path, RTLD_NOW);
3339         if (!module) {
3340                 weston_log("Failed to load module: %s\n", dlerror());
3341                 return NULL;
3342         }
3343
3344         init = dlsym(module, entrypoint);
3345         if (!init) {
3346                 weston_log("Failed to lookup init function: %s\n", dlerror());
3347                 dlclose(module);
3348                 return NULL;
3349         }
3350
3351         return init;
3352 }
3353
3354 static int
3355 load_modules(struct weston_compositor *ec, const char *modules,
3356              int *argc, char *argv[], const char *config_file)
3357 {
3358         const char *p, *end;
3359         char buffer[256];
3360         int (*module_init)(struct weston_compositor *ec,
3361                            int *argc, char *argv[], const char *config_file);
3362
3363         if (modules == NULL)
3364                 return 0;
3365
3366         p = modules;
3367         while (*p) {
3368                 end = strchrnul(p, ',');
3369                 snprintf(buffer, sizeof buffer, "%.*s", (int) (end - p), p);
3370                 module_init = load_module(buffer, "module_init");
3371                 if (module_init)
3372                         module_init(ec, argc, argv, config_file);
3373                 p = end;
3374                 while (*p == ',')
3375                         p++;
3376
3377         }
3378
3379         return 0;
3380 }
3381
3382 static const char xdg_error_message[] =
3383         "fatal: environment variable XDG_RUNTIME_DIR is not set.\n";
3384
3385 static const char xdg_wrong_message[] =
3386         "fatal: environment variable XDG_RUNTIME_DIR\n"
3387         "is set to \"%s\", which is not a directory.\n";
3388
3389 static const char xdg_wrong_mode_message[] =
3390         "warning: XDG_RUNTIME_DIR \"%s\" is not configured\n"
3391         "correctly.  Unix access mode must be 0700 but is %o,\n"
3392         "and XDG_RUNTIME_DIR must be owned by the user, but is\n"
3393         "owned by UID %d.\n";
3394
3395 static const char xdg_detail_message[] =
3396         "Refer to your distribution on how to get it, or\n"
3397         "http://www.freedesktop.org/wiki/Specifications/basedir-spec\n"
3398         "on how to implement it.\n";
3399
3400 static void
3401 verify_xdg_runtime_dir(void)
3402 {
3403         char *dir = getenv("XDG_RUNTIME_DIR");
3404         struct stat s;
3405
3406         if (!dir) {
3407                 weston_log(xdg_error_message);
3408                 weston_log_continue(xdg_detail_message);
3409                 exit(EXIT_FAILURE);
3410         }
3411
3412         if (stat(dir, &s) || !S_ISDIR(s.st_mode)) {
3413                 weston_log(xdg_wrong_message, dir);
3414                 weston_log_continue(xdg_detail_message);
3415                 exit(EXIT_FAILURE);
3416         }
3417
3418         if ((s.st_mode & 0777) != 0700 || s.st_uid != getuid()) {
3419                 weston_log(xdg_wrong_mode_message,
3420                            dir, s.st_mode & 0777, s.st_uid);
3421                 weston_log_continue(xdg_detail_message);
3422         }
3423 }
3424
3425 static int
3426 usage(int error_code)
3427 {
3428         fprintf(stderr,
3429                 "Usage: weston [OPTIONS]\n\n"
3430                 "This is weston version " VERSION ", the Wayland reference compositor.\n"
3431                 "Weston supports multiple backends, and depending on which backend is in use\n"
3432                 "different options will be accepted.\n\n"
3433
3434
3435                 "Core options:\n\n"
3436                 "  --version\t\tPrint weston version\n"
3437                 "  -B, --backend=MODULE\tBackend module, one of drm-backend.so,\n"
3438                 "\t\t\t\tx11-backend.so or wayland-backend.so\n"
3439                 "  -S, --socket=NAME\tName of socket to listen on\n"
3440                 "  -i, --idle-time=SECS\tIdle time in seconds\n"
3441                 "  --modules\t\tLoad the comma-separated list of modules\n"
3442                 "  --log==FILE\t\tLog to the given file\n"
3443                 "  -h, --help\t\tThis help message\n\n");
3444
3445         fprintf(stderr,
3446                 "Options for drm-backend.so:\n\n"
3447                 "  --connector=ID\tBring up only this connector\n"
3448                 "  --seat=SEAT\t\tThe seat that weston should run on\n"
3449                 "  --tty=TTY\t\tThe tty to use\n"
3450                 "  --use-pixman\t\tUse the pixman (CPU) renderer\n"
3451                 "  --current-mode\tPrefer current KMS mode over EDID preferred mode\n\n");
3452
3453         fprintf(stderr,
3454                 "Options for x11-backend.so:\n\n"
3455                 "  --width=WIDTH\t\tWidth of X window\n"
3456                 "  --height=HEIGHT\tHeight of X window\n"
3457                 "  --fullscreen\t\tRun in fullscreen mode\n"
3458                 "  --use-pixman\t\tUse the pixman (CPU) renderer\n"
3459                 "  --output-count=COUNT\tCreate multiple outputs\n"
3460                 "  --no-input\t\tDont create input devices\n\n");
3461
3462         fprintf(stderr,
3463                 "Options for wayland-backend.so:\n\n"
3464                 "  --width=WIDTH\t\tWidth of Wayland surface\n"
3465                 "  --height=HEIGHT\tHeight of Wayland surface\n"
3466                 "  --display=DISPLAY\tWayland display to connect to\n\n");
3467
3468         exit(error_code);
3469 }
3470
3471 int main(int argc, char *argv[])
3472 {
3473         int ret = EXIT_SUCCESS;
3474         struct wl_display *display;
3475         struct weston_compositor *ec;
3476         struct wl_event_source *signals[4];
3477         struct wl_event_loop *loop;
3478         struct sigaction segv_action;
3479         struct weston_compositor
3480                 *(*backend_init)(struct wl_display *display,
3481                                  int *argc, char *argv[], const char *config_file);
3482         int i;
3483         char *backend = NULL;
3484         const char *modules = "desktop-shell.so", *option_modules = NULL;
3485         char *log = NULL;
3486         int32_t idle_time = 300;
3487         int32_t help = 0;
3488         char *socket_name = "wayland-0";
3489         int32_t version = 0;
3490         char *config_file;
3491
3492         const struct config_key core_config_keys[] = {
3493                 { "modules", CONFIG_KEY_STRING, &modules },
3494         };
3495
3496         const struct config_section cs[] = {
3497                 { "core",
3498                   core_config_keys, ARRAY_LENGTH(core_config_keys) },
3499         };
3500
3501         const struct weston_option core_options[] = {
3502                 { WESTON_OPTION_STRING, "backend", 'B', &backend },
3503                 { WESTON_OPTION_STRING, "socket", 'S', &socket_name },
3504                 { WESTON_OPTION_INTEGER, "idle-time", 'i', &idle_time },
3505                 { WESTON_OPTION_STRING, "modules", 0, &option_modules },
3506                 { WESTON_OPTION_STRING, "log", 0, &log },
3507                 { WESTON_OPTION_BOOLEAN, "help", 'h', &help },
3508                 { WESTON_OPTION_BOOLEAN, "version", 0, &version },
3509         };
3510
3511         parse_options(core_options, ARRAY_LENGTH(core_options), &argc, argv);
3512
3513         if (help)
3514                 usage(EXIT_SUCCESS);
3515
3516         if (version) {
3517                 printf(PACKAGE_STRING "\n");
3518                 return EXIT_SUCCESS;
3519         }
3520
3521         weston_log_file_open(log);
3522         
3523         weston_log("%s\n"
3524                    STAMP_SPACE "%s\n"
3525                    STAMP_SPACE "Bug reports to: %s\n"
3526                    STAMP_SPACE "Build: %s\n",
3527                    PACKAGE_STRING, PACKAGE_URL, PACKAGE_BUGREPORT,
3528                    BUILD_ID);
3529         log_uname();
3530
3531         verify_xdg_runtime_dir();
3532
3533         display = wl_display_create();
3534
3535         loop = wl_display_get_event_loop(display);
3536         signals[0] = wl_event_loop_add_signal(loop, SIGTERM, on_term_signal,
3537                                               display);
3538         signals[1] = wl_event_loop_add_signal(loop, SIGINT, on_term_signal,
3539                                               display);
3540         signals[2] = wl_event_loop_add_signal(loop, SIGQUIT, on_term_signal,
3541                                               display);
3542
3543         wl_list_init(&child_process_list);
3544         signals[3] = wl_event_loop_add_signal(loop, SIGCHLD, sigchld_handler,
3545                                               NULL);
3546
3547         if (!backend) {
3548                 if (getenv("WAYLAND_DISPLAY"))
3549                         backend = "wayland-backend.so";
3550                 else if (getenv("DISPLAY"))
3551                         backend = "x11-backend.so";
3552                 else
3553                         backend = WESTON_NATIVE_BACKEND;
3554         }
3555
3556         config_file = config_file_path("weston.ini");
3557         parse_config_file(config_file, cs, ARRAY_LENGTH(cs), NULL);
3558
3559         backend_init = load_module(backend, "backend_init");
3560         if (!backend_init)
3561                 exit(EXIT_FAILURE);
3562
3563         ec = backend_init(display, &argc, argv, config_file);
3564         if (ec == NULL) {
3565                 weston_log("fatal: failed to create compositor\n");
3566                 exit(EXIT_FAILURE);
3567         }
3568
3569         segv_action.sa_flags = SA_SIGINFO | SA_RESETHAND;
3570         segv_action.sa_sigaction = on_segv_signal;
3571         sigemptyset(&segv_action.sa_mask);
3572         sigaction(SIGSEGV, &segv_action, NULL);
3573         segv_compositor = ec;
3574
3575         ec->option_idle_time = idle_time;
3576         ec->idle_time = idle_time;
3577
3578         setenv("WAYLAND_DISPLAY", socket_name, 1);
3579
3580         if (load_modules(ec, modules, &argc, argv, config_file) < 0)
3581                 goto out;
3582         if (load_modules(ec, option_modules, &argc, argv, config_file) < 0)
3583                 goto out;
3584
3585         free(config_file);
3586
3587         for (i = 1; i < argc; i++)
3588                 weston_log("fatal: unhandled option: %s\n", argv[i]);
3589         if (argc > 1) {
3590                 ret = EXIT_FAILURE;
3591                 goto out;
3592         }
3593
3594         if (wl_display_add_socket(display, socket_name)) {
3595                 weston_log("fatal: failed to add socket: %m\n");
3596                 ret = EXIT_FAILURE;
3597                 goto out;
3598         }
3599
3600         weston_compositor_wake(ec);
3601
3602         wl_display_run(display);
3603
3604  out:
3605         /* prevent further rendering while shutting down */
3606         ec->state = WESTON_COMPOSITOR_SLEEPING;
3607
3608         wl_signal_emit(&ec->destroy_signal, ec);
3609
3610         for (i = ARRAY_LENGTH(signals); i;)
3611                 wl_event_source_remove(signals[--i]);
3612
3613         weston_compositor_xkb_destroy(ec);
3614
3615         ec->destroy(ec);
3616         wl_display_destroy(display);
3617
3618         weston_log_file_close();
3619
3620         return ret;
3621 }