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