compositor: Generalize module loading
[profile/ivi/weston.git] / src / compositor.c
1 /*
2  * Copyright © 2010-2011 Intel Corporation
3  * Copyright © 2008-2011 Kristian Høgsberg
4  * Copyright © 2012 Collabora, Ltd.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and
7  * its documentation for any purpose is hereby granted without fee, provided
8  * that the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of the copyright holders not be used in
11  * advertising or publicity pertaining to distribution of the software
12  * without specific, written prior permission.  The copyright holders make
13  * no representations about the suitability of this software for any
14  * purpose.  It is provided "as is" without express or implied warranty.
15  *
16  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
17  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
20  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
21  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23  */
24
25 #define _GNU_SOURCE
26
27 #include "config.h"
28
29 #include <fcntl.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <stdint.h>
34 #include <limits.h>
35 #include <stdarg.h>
36 #include <assert.h>
37 #include <sys/ioctl.h>
38 #include <sys/mman.h>
39 #include <sys/wait.h>
40 #include <sys/socket.h>
41 #include <sys/utsname.h>
42 #include <sys/stat.h>
43 #include <unistd.h>
44 #include <math.h>
45 #include <linux/input.h>
46 #include <dlfcn.h>
47 #include <signal.h>
48 #include <setjmp.h>
49 #include <sys/time.h>
50 #include <time.h>
51
52 #include <wayland-server.h>
53 #include "compositor.h"
54 #include "../shared/os-compatibility.h"
55 #include "git-version.h"
56
57 static struct wl_list child_process_list;
58 static struct weston_compositor *segv_compositor;
59
60 static int
61 sigchld_handler(int signal_number, void *data)
62 {
63         struct weston_process *p;
64         int status;
65         pid_t pid;
66
67         pid = waitpid(-1, &status, WNOHANG);
68         if (!pid)
69                 return 1;
70
71         wl_list_for_each(p, &child_process_list, link) {
72                 if (p->pid == pid)
73                         break;
74         }
75
76         if (&p->link == &child_process_list) {
77                 weston_log("unknown child process exited\n");
78                 return 1;
79         }
80
81         wl_list_remove(&p->link);
82         p->cleanup(p, status);
83
84         return 1;
85 }
86
87 WL_EXPORT int
88 weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode)
89 {
90         if (!output->switch_mode)
91                 return -1;
92
93         return output->switch_mode(output, mode);
94 }
95
96 WL_EXPORT void
97 weston_watch_process(struct weston_process *process)
98 {
99         wl_list_insert(&child_process_list, &process->link);
100 }
101
102 static void
103 child_client_exec(int sockfd, const char *path)
104 {
105         int clientfd;
106         char s[32];
107         sigset_t allsigs;
108
109         /* do not give our signal mask to the new process */
110         sigfillset(&allsigs);
111         sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
112
113         /* Launch clients as the user. */
114         seteuid(getuid());
115
116         /* SOCK_CLOEXEC closes both ends, so we dup the fd to get a
117          * non-CLOEXEC fd to pass through exec. */
118         clientfd = dup(sockfd);
119         if (clientfd == -1) {
120                 weston_log("compositor: dup failed: %m\n");
121                 return;
122         }
123
124         snprintf(s, sizeof s, "%d", clientfd);
125         setenv("WAYLAND_SOCKET", s, 1);
126
127         if (execl(path, path, NULL) < 0)
128                 weston_log("compositor: executing '%s' failed: %m\n",
129                         path);
130 }
131
132 WL_EXPORT struct wl_client *
133 weston_client_launch(struct weston_compositor *compositor,
134                      struct weston_process *proc,
135                      const char *path,
136                      weston_process_cleanup_func_t cleanup)
137 {
138         int sv[2];
139         pid_t pid;
140         struct wl_client *client;
141
142         weston_log("launching '%s'\n", path);
143
144         if (os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, sv) < 0) {
145                 weston_log("weston_client_launch: "
146                         "socketpair failed while launching '%s': %m\n",
147                         path);
148                 return NULL;
149         }
150
151         pid = fork();
152         if (pid == -1) {
153                 close(sv[0]);
154                 close(sv[1]);
155                 weston_log("weston_client_launch: "
156                         "fork failed while launching '%s': %m\n", path);
157                 return NULL;
158         }
159
160         if (pid == 0) {
161                 child_client_exec(sv[1], path);
162                 exit(-1);
163         }
164
165         close(sv[1]);
166
167         client = wl_client_create(compositor->wl_display, sv[0]);
168         if (!client) {
169                 close(sv[0]);
170                 weston_log("weston_client_launch: "
171                         "wl_client_create failed while launching '%s'.\n",
172                         path);
173                 return NULL;
174         }
175
176         proc->pid = pid;
177         proc->cleanup = cleanup;
178         weston_watch_process(proc);
179
180         return client;
181 }
182
183 static void
184 surface_handle_buffer_destroy(struct wl_listener *listener, void *data)
185 {
186         struct weston_surface *es =
187                 container_of(listener, struct weston_surface, 
188                              buffer_destroy_listener);
189
190         if (es->buffer && wl_buffer_is_shm(es->buffer))
191                 es->compositor->renderer->flush_damage(es);
192
193         es->buffer = NULL;
194 }
195
196 static const pixman_region32_data_t undef_region_data;
197
198 static void
199 undef_region(pixman_region32_t *region)
200 {
201         if (region->data != &undef_region_data)
202                 pixman_region32_fini(region);
203         region->data = (pixman_region32_data_t *) &undef_region_data;
204 }
205
206 static int
207 region_is_undefined(pixman_region32_t *region)
208 {
209         return region->data == &undef_region_data;
210 }
211
212 static void
213 empty_region(pixman_region32_t *region)
214 {
215         if (!region_is_undefined(region))
216                 pixman_region32_fini(region);
217
218         pixman_region32_init(region);
219 }
220
221 WL_EXPORT struct weston_surface *
222 weston_surface_create(struct weston_compositor *compositor)
223 {
224         struct weston_surface *surface;
225
226         surface = calloc(1, sizeof *surface);
227         if (surface == NULL)
228                 return NULL;
229
230         wl_signal_init(&surface->surface.resource.destroy_signal);
231
232         wl_list_init(&surface->link);
233         wl_list_init(&surface->layer_link);
234
235         surface->surface.resource.client = NULL;
236
237         surface->compositor = compositor;
238         surface->alpha = 1.0;
239         surface->pitch = 1;
240
241         surface->num_textures = 0;
242         surface->num_images = 0;
243
244         surface->buffer = NULL;
245         surface->output = NULL;
246         surface->plane = &compositor->primary_plane;
247
248         pixman_region32_init(&surface->damage);
249         pixman_region32_init(&surface->opaque);
250         pixman_region32_init(&surface->clip);
251         undef_region(&surface->input);
252         pixman_region32_init(&surface->transform.opaque);
253         wl_list_init(&surface->frame_callback_list);
254
255         surface->buffer_destroy_listener.notify =
256                 surface_handle_buffer_destroy;
257
258         wl_list_init(&surface->geometry.transformation_list);
259         wl_list_insert(&surface->geometry.transformation_list,
260                        &surface->transform.position.link);
261         weston_matrix_init(&surface->transform.position.matrix);
262         pixman_region32_init(&surface->transform.boundingbox);
263         surface->geometry.dirty = 1;
264
265         return surface;
266 }
267
268 WL_EXPORT void
269 weston_surface_set_color(struct weston_surface *surface,
270                  GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
271 {
272         surface->color[0] = red;
273         surface->color[1] = green;
274         surface->color[2] = blue;
275         surface->color[3] = alpha;
276         surface->shader = &surface->compositor->solid_shader;
277 }
278
279 WL_EXPORT void
280 weston_surface_to_global_float(struct weston_surface *surface,
281                                GLfloat sx, GLfloat sy, GLfloat *x, GLfloat *y)
282 {
283         if (surface->transform.enabled) {
284                 struct weston_vector v = { { sx, sy, 0.0f, 1.0f } };
285
286                 weston_matrix_transform(&surface->transform.matrix, &v);
287
288                 if (fabsf(v.f[3]) < 1e-6) {
289                         weston_log("warning: numerical instability in "
290                                 "weston_surface_to_global(), divisor = %g\n",
291                                 v.f[3]);
292                         *x = 0;
293                         *y = 0;
294                         return;
295                 }
296
297                 *x = v.f[0] / v.f[3];
298                 *y = v.f[1] / v.f[3];
299         } else {
300                 *x = sx + surface->geometry.x;
301                 *y = sy + surface->geometry.y;
302         }
303 }
304
305 WL_EXPORT void
306 weston_surface_move_to_plane(struct weston_surface *surface,
307                              struct weston_plane *plane)
308 {
309         if (surface->plane == plane)
310                 return;
311
312         weston_surface_damage_below(surface);
313         surface->plane = plane;
314         weston_surface_damage(surface);
315 }
316
317 WL_EXPORT void
318 weston_surface_damage_below(struct weston_surface *surface)
319 {
320         pixman_region32_t damage;
321
322         pixman_region32_init(&damage);
323         pixman_region32_subtract(&damage, &surface->transform.boundingbox,
324                                  &surface->clip);
325         pixman_region32_union(&surface->plane->damage,
326                               &surface->plane->damage, &damage);
327         pixman_region32_fini(&damage);
328 }
329
330 static void
331 surface_compute_bbox(struct weston_surface *surface, int32_t sx, int32_t sy,
332                      int32_t width, int32_t height,
333                      pixman_region32_t *bbox)
334 {
335         GLfloat min_x = HUGE_VALF,  min_y = HUGE_VALF;
336         GLfloat max_x = -HUGE_VALF, max_y = -HUGE_VALF;
337         int32_t s[4][2] = {
338                 { sx,         sy },
339                 { sx,         sy + height },
340                 { sx + width, sy },
341                 { sx + width, sy + height }
342         };
343         GLfloat int_x, int_y;
344         int i;
345
346         if (width == 0 || height == 0) {
347                 /* avoid rounding empty bbox to 1x1 */
348                 pixman_region32_init(bbox);
349                 return;
350         }
351
352         for (i = 0; i < 4; ++i) {
353                 GLfloat x, y;
354                 weston_surface_to_global_float(surface,
355                                                s[i][0], s[i][1], &x, &y);
356                 if (x < min_x)
357                         min_x = x;
358                 if (x > max_x)
359                         max_x = x;
360                 if (y < min_y)
361                         min_y = y;
362                 if (y > max_y)
363                         max_y = y;
364         }
365
366         int_x = floorf(min_x);
367         int_y = floorf(min_y);
368         pixman_region32_init_rect(bbox, int_x, int_y,
369                                   ceilf(max_x) - int_x, ceilf(max_y) - int_y);
370 }
371
372 static void
373 weston_surface_update_transform_disable(struct weston_surface *surface)
374 {
375         surface->transform.enabled = 0;
376
377         /* round off fractions when not transformed */
378         surface->geometry.x = roundf(surface->geometry.x);
379         surface->geometry.y = roundf(surface->geometry.y);
380
381         pixman_region32_init_rect(&surface->transform.boundingbox,
382                                   surface->geometry.x,
383                                   surface->geometry.y,
384                                   surface->geometry.width,
385                                   surface->geometry.height);
386
387         if (surface->alpha == 1.0) {
388                 pixman_region32_copy(&surface->transform.opaque,
389                                      &surface->opaque);
390                 pixman_region32_translate(&surface->transform.opaque,
391                                           surface->geometry.x,
392                                           surface->geometry.y);
393         }
394 }
395
396 static int
397 weston_surface_update_transform_enable(struct weston_surface *surface)
398 {
399         struct weston_matrix *matrix = &surface->transform.matrix;
400         struct weston_matrix *inverse = &surface->transform.inverse;
401         struct weston_transform *tform;
402
403         surface->transform.enabled = 1;
404
405         /* Otherwise identity matrix, but with x and y translation. */
406         surface->transform.position.matrix.d[12] = surface->geometry.x;
407         surface->transform.position.matrix.d[13] = surface->geometry.y;
408
409         weston_matrix_init(matrix);
410         wl_list_for_each(tform, &surface->geometry.transformation_list, link)
411                 weston_matrix_multiply(matrix, &tform->matrix);
412
413         if (weston_matrix_invert(inverse, matrix) < 0) {
414                 /* Oops, bad total transformation, not invertible */
415                 weston_log("error: weston_surface %p"
416                         " transformation not invertible.\n", surface);
417                 return -1;
418         }
419
420         surface_compute_bbox(surface, 0, 0, surface->geometry.width,
421                              surface->geometry.height,
422                              &surface->transform.boundingbox);
423
424         return 0;
425 }
426
427 WL_EXPORT void
428 weston_surface_update_transform(struct weston_surface *surface)
429 {
430         if (!surface->geometry.dirty)
431                 return;
432
433         surface->geometry.dirty = 0;
434
435         weston_surface_damage_below(surface);
436
437         pixman_region32_fini(&surface->transform.boundingbox);
438         pixman_region32_fini(&surface->transform.opaque);
439         pixman_region32_init(&surface->transform.opaque);
440
441         if (region_is_undefined(&surface->input))
442                 pixman_region32_init_rect(&surface->input, 0, 0, 
443                                           surface->geometry.width,
444                                           surface->geometry.height);
445
446         /* transform.position is always in transformation_list */
447         if (surface->geometry.transformation_list.next ==
448             &surface->transform.position.link &&
449             surface->geometry.transformation_list.prev ==
450             &surface->transform.position.link) {
451                 weston_surface_update_transform_disable(surface);
452         } else {
453                 if (weston_surface_update_transform_enable(surface) < 0)
454                         weston_surface_update_transform_disable(surface);
455         }
456
457         weston_surface_damage_below(surface);
458
459         if (weston_surface_is_mapped(surface))
460                 weston_surface_assign_output(surface);
461 }
462
463 WL_EXPORT void
464 weston_surface_to_global_fixed(struct weston_surface *surface,
465                                wl_fixed_t sx, wl_fixed_t sy,
466                                wl_fixed_t *x, wl_fixed_t *y)
467 {
468         GLfloat xf, yf;
469
470         weston_surface_to_global_float(surface,
471                                        wl_fixed_to_double(sx),
472                                        wl_fixed_to_double(sy),
473                                        &xf, &yf);
474         *x = wl_fixed_from_double(xf);
475         *y = wl_fixed_from_double(yf);
476 }
477
478 WL_EXPORT void
479 weston_surface_from_global_float(struct weston_surface *surface,
480                                  GLfloat x, GLfloat y, GLfloat *sx, GLfloat *sy)
481 {
482         if (surface->transform.enabled) {
483                 struct weston_vector v = { { x, y, 0.0f, 1.0f } };
484
485                 weston_matrix_transform(&surface->transform.inverse, &v);
486
487                 if (fabsf(v.f[3]) < 1e-6) {
488                         weston_log("warning: numerical instability in "
489                                 "weston_surface_from_global(), divisor = %g\n",
490                                 v.f[3]);
491                         *sx = 0;
492                         *sy = 0;
493                         return;
494                 }
495
496                 *sx = v.f[0] / v.f[3];
497                 *sy = v.f[1] / v.f[3];
498         } else {
499                 *sx = x - surface->geometry.x;
500                 *sy = y - surface->geometry.y;
501         }
502 }
503
504 WL_EXPORT void
505 weston_surface_from_global_fixed(struct weston_surface *surface,
506                                  wl_fixed_t x, wl_fixed_t y,
507                                  wl_fixed_t *sx, wl_fixed_t *sy)
508 {
509         GLfloat sxf, syf;
510
511         weston_surface_from_global_float(surface,
512                                          wl_fixed_to_double(x),
513                                          wl_fixed_to_double(y),
514                                          &sxf, &syf);
515         *sx = wl_fixed_from_double(sxf);
516         *sy = wl_fixed_from_double(syf);
517 }
518
519 WL_EXPORT void
520 weston_surface_from_global(struct weston_surface *surface,
521                            int32_t x, int32_t y, int32_t *sx, int32_t *sy)
522 {
523         GLfloat sxf, syf;
524
525         weston_surface_from_global_float(surface, x, y, &sxf, &syf);
526         *sx = floorf(sxf);
527         *sy = floorf(syf);
528 }
529
530 WL_EXPORT void
531 weston_surface_schedule_repaint(struct weston_surface *surface)
532 {
533         struct weston_output *output;
534
535         wl_list_for_each(output, &surface->compositor->output_list, link)
536                 if (surface->output_mask & (1 << output->id))
537                         weston_output_schedule_repaint(output);
538 }
539
540 WL_EXPORT void
541 weston_surface_damage(struct weston_surface *surface)
542 {
543         pixman_region32_union_rect(&surface->damage, &surface->damage,
544                                    0, 0, surface->geometry.width,
545                                    surface->geometry.height);
546
547         weston_surface_schedule_repaint(surface);
548 }
549
550 WL_EXPORT void
551 weston_surface_configure(struct weston_surface *surface,
552                          GLfloat x, GLfloat y, int width, int height)
553 {
554         surface->geometry.x = x;
555         surface->geometry.y = y;
556         surface->geometry.width = width;
557         surface->geometry.height = height;
558         surface->geometry.dirty = 1;
559 }
560
561 WL_EXPORT void
562 weston_surface_set_position(struct weston_surface *surface,
563                             GLfloat x, GLfloat y)
564 {
565         surface->geometry.x = x;
566         surface->geometry.y = y;
567         surface->geometry.dirty = 1;
568 }
569
570 WL_EXPORT int
571 weston_surface_is_mapped(struct weston_surface *surface)
572 {
573         if (surface->output)
574                 return 1;
575         else
576                 return 0;
577 }
578
579 WL_EXPORT uint32_t
580 weston_compositor_get_time(void)
581 {
582        struct timeval tv;
583
584        gettimeofday(&tv, NULL);
585
586        return tv.tv_sec * 1000 + tv.tv_usec / 1000;
587 }
588
589 static struct weston_surface *
590 weston_compositor_pick_surface(struct weston_compositor *compositor,
591                                wl_fixed_t x, wl_fixed_t y,
592                                wl_fixed_t *sx, wl_fixed_t *sy)
593 {
594         struct weston_surface *surface;
595
596         wl_list_for_each(surface, &compositor->surface_list, link) {
597                 weston_surface_from_global_fixed(surface, x, y, sx, sy);
598                 if (pixman_region32_contains_point(&surface->input,
599                                                    wl_fixed_to_int(*sx),
600                                                    wl_fixed_to_int(*sy),
601                                                    NULL))
602                         return surface;
603         }
604
605         return NULL;
606 }
607
608 static void
609 weston_device_repick(struct weston_seat *seat)
610 {
611         const struct wl_pointer_grab_interface *interface;
612         struct weston_surface *surface, *focus;
613         struct wl_pointer *pointer = seat->seat.pointer;
614
615         if (!pointer)
616                 return;
617
618         surface = weston_compositor_pick_surface(seat->compositor,
619                                                  pointer->x,
620                                                  pointer->y,
621                                                  &pointer->current_x,
622                                                  &pointer->current_y);
623
624         if (&surface->surface != pointer->current) {
625                 interface = pointer->grab->interface;
626                 pointer->current = &surface->surface;
627                 interface->focus(pointer->grab, &surface->surface,
628                                  pointer->current_x,
629                                  pointer->current_y);
630         }
631
632         focus = (struct weston_surface *) pointer->grab->focus;
633         if (focus)
634                 weston_surface_from_global_fixed(focus,
635                                                  pointer->x,
636                                                  pointer->y,
637                                                  &pointer->grab->x,
638                                                  &pointer->grab->y);
639 }
640
641 static void
642 weston_compositor_repick(struct weston_compositor *compositor)
643 {
644         struct weston_seat *seat;
645
646         if (!compositor->focus)
647                 return;
648
649         wl_list_for_each(seat, &compositor->seat_list, link)
650                 weston_device_repick(seat);
651 }
652
653 WL_EXPORT void
654 weston_surface_unmap(struct weston_surface *surface)
655 {
656         struct weston_seat *seat;
657
658         weston_surface_damage_below(surface);
659         surface->output = NULL;
660         wl_list_remove(&surface->layer_link);
661
662         wl_list_for_each(seat, &surface->compositor->seat_list, link) {
663                 if (seat->seat.keyboard &&
664                     seat->seat.keyboard->focus == &surface->surface)
665                         wl_keyboard_set_focus(seat->seat.keyboard, NULL);
666                 if (seat->seat.pointer &&
667                     seat->seat.pointer->focus == &surface->surface)
668                         wl_pointer_set_focus(seat->seat.pointer,
669                                              NULL,
670                                              wl_fixed_from_int(0),
671                                              wl_fixed_from_int(0));
672         }
673
674         weston_surface_schedule_repaint(surface);
675 }
676
677 struct weston_frame_callback {
678         struct wl_resource resource;
679         struct wl_list link;
680 };
681
682 static void
683 destroy_surface(struct wl_resource *resource)
684 {
685         struct weston_surface *surface =
686                 container_of(resource,
687                              struct weston_surface, surface.resource);
688         struct weston_compositor *compositor = surface->compositor;
689         struct weston_frame_callback *cb, *next;
690
691         if (weston_surface_is_mapped(surface))
692                 weston_surface_unmap(surface);
693
694         if (surface->buffer)
695                 wl_list_remove(&surface->buffer_destroy_listener.link);
696
697         compositor->renderer->destroy_surface(surface);
698
699         pixman_region32_fini(&surface->transform.boundingbox);
700         pixman_region32_fini(&surface->damage);
701         pixman_region32_fini(&surface->opaque);
702         pixman_region32_fini(&surface->clip);
703         if (!region_is_undefined(&surface->input))
704                 pixman_region32_fini(&surface->input);
705
706         wl_list_for_each_safe(cb, next, &surface->frame_callback_list, link)
707                 wl_resource_destroy(&cb->resource);
708
709         free(surface);
710 }
711
712 WL_EXPORT void
713 weston_surface_destroy(struct weston_surface *surface)
714 {
715         /* Not a valid way to destroy a client surface */
716         assert(surface->surface.resource.client == NULL);
717
718         wl_signal_emit(&surface->surface.resource.destroy_signal,
719                        &surface->surface.resource);
720         destroy_surface(&surface->surface.resource);
721 }
722
723 static void
724 weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
725 {
726         struct weston_surface *es = (struct weston_surface *) surface;
727
728         if (es->buffer) {
729                 weston_buffer_post_release(es->buffer);
730                 wl_list_remove(&es->buffer_destroy_listener.link);
731         }
732
733         if (buffer) {
734                 buffer->busy_count++;
735                 wl_signal_add(&buffer->resource.destroy_signal, 
736                               &es->buffer_destroy_listener);
737
738                 if (es->geometry.width != buffer->width ||
739                     es->geometry.height != buffer->height) {
740                         undef_region(&es->input);
741                         pixman_region32_fini(&es->opaque);
742                         pixman_region32_init(&es->opaque);
743                 }
744         } else {
745                 if (weston_surface_is_mapped(es))
746                         weston_surface_unmap(es);
747         }
748
749         es->compositor->renderer->attach(es, buffer);
750         es->buffer = buffer;
751 }
752
753 WL_EXPORT void
754 weston_surface_restack(struct weston_surface *surface, struct wl_list *below)
755 {
756         wl_list_remove(&surface->layer_link);
757         wl_list_insert(below, &surface->layer_link);
758         weston_surface_damage_below(surface);
759         weston_surface_damage(surface);
760 }
761
762 WL_EXPORT void
763 weston_compositor_damage_all(struct weston_compositor *compositor)
764 {
765         struct weston_output *output;
766
767         wl_list_for_each(output, &compositor->output_list, link)
768                 weston_output_damage(output);
769 }
770
771 WL_EXPORT void
772 weston_buffer_post_release(struct wl_buffer *buffer)
773 {
774         if (--buffer->busy_count > 0)
775                 return;
776
777         assert(buffer->resource.client != NULL);
778         wl_resource_queue_event(&buffer->resource, WL_BUFFER_RELEASE);
779 }
780
781 WL_EXPORT void
782 weston_output_damage(struct weston_output *output)
783 {
784         struct weston_compositor *compositor = output->compositor;
785
786         pixman_region32_union(&compositor->primary_plane.damage,
787                               &compositor->primary_plane.damage,
788                               &output->region);
789         weston_output_schedule_repaint(output);
790 }
791
792 static void
793 fade_frame(struct weston_animation *animation,
794            struct weston_output *output, uint32_t msecs)
795 {
796         struct weston_compositor *compositor =
797                 container_of(animation,
798                              struct weston_compositor, fade.animation);
799         struct weston_surface *surface;
800
801         if (animation->frame_counter <= 1)
802                 compositor->fade.spring.timestamp = msecs;
803
804         surface = compositor->fade.surface;
805         weston_spring_update(&compositor->fade.spring, msecs);
806         weston_surface_set_color(surface, 0.0, 0.0, 0.0,
807                                  compositor->fade.spring.current);
808         weston_surface_damage(surface);
809
810         if (weston_spring_done(&compositor->fade.spring)) {
811                 compositor->fade.spring.current =
812                         compositor->fade.spring.target;
813                 wl_list_remove(&animation->link);
814                 wl_list_init(&animation->link);
815
816                 if (compositor->fade.spring.current < 0.001) {
817                         destroy_surface(&surface->surface.resource);
818                         compositor->fade.surface = NULL;
819                 } else if (compositor->fade.spring.current > 0.999) {
820                         compositor->state = WESTON_COMPOSITOR_SLEEPING;
821                         wl_signal_emit(&compositor->lock_signal, compositor);
822                 }
823         }
824 }
825
826 static void
827 surface_accumulate_damage(struct weston_surface *surface,
828                           pixman_region32_t *opaque)
829 {
830         if (surface->buffer && wl_buffer_is_shm(surface->buffer))
831                 surface->compositor->renderer->flush_damage(surface);
832
833         if (surface->transform.enabled) {
834                 pixman_box32_t *extents;
835
836                 extents = pixman_region32_extents(&surface->damage);
837                 surface_compute_bbox(surface, extents->x1, extents->y1,
838                                      extents->x2 - extents->x1,
839                                      extents->y2 - extents->y1,
840                                      &surface->damage);
841                 pixman_region32_translate(&surface->damage,
842                                           -surface->plane->x,
843                                           -surface->plane->y);
844         } else {
845                 pixman_region32_translate(&surface->damage,
846                                           surface->geometry.x - surface->plane->x,
847                                           surface->geometry.y - surface->plane->y);
848         }
849
850         pixman_region32_subtract(&surface->damage, &surface->damage, opaque);
851         pixman_region32_union(&surface->plane->damage,
852                               &surface->plane->damage, &surface->damage);
853         empty_region(&surface->damage);
854         pixman_region32_copy(&surface->clip, opaque);
855         pixman_region32_union(opaque, opaque, &surface->transform.opaque);
856 }
857
858 static void
859 weston_output_repaint(struct weston_output *output, uint32_t msecs)
860 {
861         struct weston_compositor *ec = output->compositor;
862         struct weston_surface *es;
863         struct weston_layer *layer;
864         struct weston_animation *animation, *next;
865         struct weston_frame_callback *cb, *cnext;
866         struct wl_list frame_callback_list;
867         pixman_region32_t opaque, output_damage, new_damage;
868
869         weston_compositor_update_drag_surfaces(ec);
870
871         /* Rebuild the surface list and update surface transforms up front. */
872         wl_list_init(&ec->surface_list);
873         wl_list_init(&frame_callback_list);
874         wl_list_for_each(layer, &ec->layer_list, link) {
875                 wl_list_for_each(es, &layer->surface_list, layer_link) {
876                         weston_surface_update_transform(es);
877                         wl_list_insert(ec->surface_list.prev, &es->link);
878                         if (es->output == output) {
879                                 wl_list_insert_list(&frame_callback_list,
880                                                     &es->frame_callback_list);
881                                 wl_list_init(&es->frame_callback_list);
882                         }
883                 }
884         }
885
886         if (output->assign_planes && !output->disable_planes)
887                 output->assign_planes(output);
888         else
889                 wl_list_for_each(es, &ec->surface_list, link)
890                         weston_surface_move_to_plane(es, &ec->primary_plane);
891
892         pixman_region32_init(&opaque);
893
894         wl_list_for_each(es, &ec->surface_list, link)
895                 surface_accumulate_damage(es, &opaque);
896
897         pixman_region32_fini(&opaque);
898
899         pixman_region32_init(&output_damage);
900
901         pixman_region32_init(&new_damage);
902         pixman_region32_copy(&new_damage, &ec->primary_plane.damage);
903
904         pixman_region32_union(&ec->primary_plane.damage,
905                               &ec->primary_plane.damage,
906                               &output->previous_damage);
907
908         pixman_region32_intersect(&output->previous_damage,
909                                   &new_damage, &output->region);
910
911         pixman_region32_intersect(&output_damage,
912                                   &ec->primary_plane.damage, &output->region);
913
914         pixman_region32_fini(&new_damage);
915
916         if (output->dirty)
917                 weston_output_update_matrix(output);
918
919         output->repaint(output, &output_damage);
920
921         pixman_region32_fini(&output_damage);
922
923         output->repaint_needed = 0;
924
925         weston_compositor_repick(ec);
926         wl_event_loop_dispatch(ec->input_loop, 0);
927
928         wl_list_for_each_safe(cb, cnext, &frame_callback_list, link) {
929                 wl_callback_send_done(&cb->resource, msecs);
930                 wl_resource_destroy(&cb->resource);
931         }
932         wl_list_init(&frame_callback_list);
933
934         wl_list_for_each_safe(animation, next, &output->animation_list, link) {
935                 animation->frame_counter++;
936                 animation->frame(animation, output, msecs);
937         }
938 }
939
940 static int
941 weston_compositor_read_input(int fd, uint32_t mask, void *data)
942 {
943         struct weston_compositor *compositor = data;
944
945         wl_event_loop_dispatch(compositor->input_loop, 0);
946
947         return 1;
948 }
949
950 WL_EXPORT void
951 weston_output_finish_frame(struct weston_output *output, uint32_t msecs)
952 {
953         struct weston_compositor *compositor = output->compositor;
954         struct wl_event_loop *loop =
955                 wl_display_get_event_loop(compositor->wl_display);
956         int fd;
957
958         output->frame_time = msecs;
959         if (output->repaint_needed) {
960                 weston_output_repaint(output, msecs);
961                 return;
962         }
963
964         output->repaint_scheduled = 0;
965         if (compositor->input_loop_source)
966                 return;
967
968         fd = wl_event_loop_get_fd(compositor->input_loop);
969         compositor->input_loop_source =
970                 wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
971                                      weston_compositor_read_input, compositor);
972 }
973
974 static void
975 idle_repaint(void *data)
976 {
977         struct weston_output *output = data;
978
979         weston_output_finish_frame(output, weston_compositor_get_time());
980 }
981
982 WL_EXPORT void
983 weston_layer_init(struct weston_layer *layer, struct wl_list *below)
984 {
985         wl_list_init(&layer->surface_list);
986         if (below != NULL)
987                 wl_list_insert(below, &layer->link);
988 }
989
990 WL_EXPORT void
991 weston_output_schedule_repaint(struct weston_output *output)
992 {
993         struct weston_compositor *compositor = output->compositor;
994         struct wl_event_loop *loop;
995
996         if (compositor->state == WESTON_COMPOSITOR_SLEEPING)
997                 return;
998
999         loop = wl_display_get_event_loop(compositor->wl_display);
1000         output->repaint_needed = 1;
1001         if (output->repaint_scheduled)
1002                 return;
1003
1004         wl_event_loop_add_idle(loop, idle_repaint, output);
1005         output->repaint_scheduled = 1;
1006
1007         if (compositor->input_loop_source) {
1008                 wl_event_source_remove(compositor->input_loop_source);
1009                 compositor->input_loop_source = NULL;
1010         }
1011 }
1012
1013 WL_EXPORT void
1014 weston_compositor_schedule_repaint(struct weston_compositor *compositor)
1015 {
1016         struct weston_output *output;
1017
1018         wl_list_for_each(output, &compositor->output_list, link)
1019                 weston_output_schedule_repaint(output);
1020 }
1021
1022 WL_EXPORT void
1023 weston_compositor_fade(struct weston_compositor *compositor, float tint)
1024 {
1025         struct weston_output *output;
1026         struct weston_surface *surface;
1027
1028         output = container_of(compositor->output_list.next,
1029                              struct weston_output, link);
1030
1031         compositor->fade.spring.target = tint;
1032         if (weston_spring_done(&compositor->fade.spring))
1033                 return;
1034
1035         if (compositor->fade.surface == NULL) {
1036                 surface = weston_surface_create(compositor);
1037                 weston_surface_configure(surface, 0, 0, 8192, 8192);
1038                 weston_surface_set_color(surface, 0.0, 0.0, 0.0, 0.0);
1039                 wl_list_insert(&compositor->fade_layer.surface_list,
1040                                &surface->layer_link);
1041                 weston_surface_assign_output(surface);
1042                 compositor->fade.surface = surface;
1043                 pixman_region32_init(&surface->input);
1044         }
1045
1046         weston_surface_damage(compositor->fade.surface);
1047         if (wl_list_empty(&compositor->fade.animation.link)) {
1048                 compositor->fade.animation.frame_counter = 0;
1049                 wl_list_insert(output->animation_list.prev,
1050                                &compositor->fade.animation.link);
1051         }
1052 }
1053
1054 static void
1055 surface_destroy(struct wl_client *client, struct wl_resource *resource)
1056 {
1057         wl_resource_destroy(resource);
1058 }
1059
1060 static struct wl_resource *
1061 find_resource_for_client(struct wl_list *list, struct wl_client *client)
1062 {
1063         struct wl_resource *r;
1064
1065         wl_list_for_each(r, list, link) {
1066                 if (r->client == client)
1067                         return r;
1068         }
1069
1070         return NULL;
1071 }
1072
1073 static void
1074 weston_surface_update_output_mask(struct weston_surface *es, uint32_t mask)
1075 {
1076         uint32_t different = es->output_mask ^ mask;
1077         uint32_t entered = mask & different;
1078         uint32_t left = es->output_mask & different;
1079         struct weston_output *output;
1080         struct wl_resource *resource = NULL;
1081         struct wl_client *client = es->surface.resource.client;
1082
1083         es->output_mask = mask;
1084         if (es->surface.resource.client == NULL)
1085                 return;
1086         if (different == 0)
1087                 return;
1088
1089         wl_list_for_each(output, &es->compositor->output_list, link) {
1090                 if (1 << output->id & different)
1091                         resource =
1092                                 find_resource_for_client(&output->resource_list,
1093                                                          client);
1094                 if (resource == NULL)
1095                         continue;
1096                 if (1 << output->id & entered)
1097                         wl_surface_send_enter(&es->surface.resource, resource);
1098                 if (1 << output->id & left)
1099                         wl_surface_send_leave(&es->surface.resource, resource);
1100         }
1101 }
1102
1103 WL_EXPORT void
1104 weston_surface_assign_output(struct weston_surface *es)
1105 {
1106         struct weston_compositor *ec = es->compositor;
1107         struct weston_output *output, *new_output;
1108         pixman_region32_t region;
1109         uint32_t max, area, mask;
1110         pixman_box32_t *e;
1111
1112         new_output = NULL;
1113         max = 0;
1114         mask = 0;
1115         pixman_region32_init(&region);
1116         wl_list_for_each(output, &ec->output_list, link) {
1117                 pixman_region32_intersect(&region, &es->transform.boundingbox,
1118                                           &output->region);
1119
1120                 e = pixman_region32_extents(&region);
1121                 area = (e->x2 - e->x1) * (e->y2 - e->y1);
1122
1123                 if (area > 0)
1124                         mask |= 1 << output->id;
1125
1126                 if (area >= max) {
1127                         new_output = output;
1128                         max = area;
1129                 }
1130         }
1131         pixman_region32_fini(&region);
1132
1133         es->output = new_output;
1134         weston_surface_update_output_mask(es, mask);
1135 }
1136
1137 static void
1138 surface_attach(struct wl_client *client,
1139                struct wl_resource *resource,
1140                struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
1141 {
1142         struct weston_surface *es = resource->data;
1143         struct wl_buffer *buffer = NULL;
1144
1145         if (buffer_resource)
1146                 buffer = buffer_resource->data;
1147
1148         weston_surface_attach(&es->surface, buffer);
1149
1150         if (buffer && es->configure)
1151                 es->configure(es, sx, sy);
1152 }
1153
1154 static void
1155 surface_damage(struct wl_client *client,
1156                struct wl_resource *resource,
1157                int32_t x, int32_t y, int32_t width, int32_t height)
1158 {
1159         struct weston_surface *es = resource->data;
1160
1161         pixman_region32_union_rect(&es->damage, &es->damage,
1162                                    x, y, width, height);
1163         weston_surface_schedule_repaint(es);
1164 }
1165
1166 static void
1167 destroy_frame_callback(struct wl_resource *resource)
1168 {
1169         struct weston_frame_callback *cb = resource->data;
1170
1171         wl_list_remove(&cb->link);
1172         free(cb);
1173 }
1174
1175 static void
1176 surface_frame(struct wl_client *client,
1177               struct wl_resource *resource, uint32_t callback)
1178 {
1179         struct weston_frame_callback *cb;
1180         struct weston_surface *es = resource->data;
1181
1182         cb = malloc(sizeof *cb);
1183         if (cb == NULL) {
1184                 wl_resource_post_no_memory(resource);
1185                 return;
1186         }
1187                 
1188         cb->resource.object.interface = &wl_callback_interface;
1189         cb->resource.object.id = callback;
1190         cb->resource.destroy = destroy_frame_callback;
1191         cb->resource.client = client;
1192         cb->resource.data = cb;
1193
1194         wl_client_add_resource(client, &cb->resource);
1195         wl_list_insert(es->frame_callback_list.prev, &cb->link);
1196 }
1197
1198 static void
1199 surface_set_opaque_region(struct wl_client *client,
1200                           struct wl_resource *resource,
1201                           struct wl_resource *region_resource)
1202 {
1203         struct weston_surface *surface = resource->data;
1204         struct weston_region *region;
1205
1206         pixman_region32_fini(&surface->opaque);
1207
1208         if (region_resource) {
1209                 region = region_resource->data;
1210                 pixman_region32_init_rect(&surface->opaque, 0, 0,
1211                                           surface->geometry.width,
1212                                           surface->geometry.height);
1213                 pixman_region32_intersect(&surface->opaque,
1214                                           &surface->opaque, &region->region);
1215         } else {
1216                 pixman_region32_init(&surface->opaque);
1217         }
1218
1219         surface->geometry.dirty = 1;
1220 }
1221
1222 static void
1223 surface_set_input_region(struct wl_client *client,
1224                          struct wl_resource *resource,
1225                          struct wl_resource *region_resource)
1226 {
1227         struct weston_surface *surface = resource->data;
1228         struct weston_region *region;
1229
1230         if (region_resource) {
1231                 region = region_resource->data;
1232                 pixman_region32_init_rect(&surface->input, 0, 0,
1233                                           surface->geometry.width,
1234                                           surface->geometry.height);
1235                 pixman_region32_intersect(&surface->input,
1236                                           &surface->input, &region->region);
1237         } else {
1238                 pixman_region32_init_rect(&surface->input, 0, 0,
1239                                           surface->geometry.width,
1240                                           surface->geometry.height);
1241         }
1242
1243         weston_surface_schedule_repaint(surface);
1244 }
1245
1246 static const struct wl_surface_interface surface_interface = {
1247         surface_destroy,
1248         surface_attach,
1249         surface_damage,
1250         surface_frame,
1251         surface_set_opaque_region,
1252         surface_set_input_region
1253 };
1254
1255 static void
1256 compositor_create_surface(struct wl_client *client,
1257                           struct wl_resource *resource, uint32_t id)
1258 {
1259         struct weston_compositor *ec = resource->data;
1260         struct weston_surface *surface;
1261
1262         surface = weston_surface_create(ec);
1263         if (surface == NULL) {
1264                 wl_resource_post_no_memory(resource);
1265                 return;
1266         }
1267
1268         surface->surface.resource.destroy = destroy_surface;
1269
1270         surface->surface.resource.object.id = id;
1271         surface->surface.resource.object.interface = &wl_surface_interface;
1272         surface->surface.resource.object.implementation =
1273                 (void (**)(void)) &surface_interface;
1274         surface->surface.resource.data = surface;
1275
1276         wl_client_add_resource(client, &surface->surface.resource);
1277 }
1278
1279 static void
1280 destroy_region(struct wl_resource *resource)
1281 {
1282         struct weston_region *region =
1283                 container_of(resource, struct weston_region, resource);
1284
1285         pixman_region32_fini(&region->region);
1286         free(region);
1287 }
1288
1289 static void
1290 region_destroy(struct wl_client *client, struct wl_resource *resource)
1291 {
1292         wl_resource_destroy(resource);
1293 }
1294
1295 static void
1296 region_add(struct wl_client *client, struct wl_resource *resource,
1297            int32_t x, int32_t y, int32_t width, int32_t height)
1298 {
1299         struct weston_region *region = resource->data;
1300
1301         pixman_region32_union_rect(&region->region, &region->region,
1302                                    x, y, width, height);
1303 }
1304
1305 static void
1306 region_subtract(struct wl_client *client, struct wl_resource *resource,
1307                 int32_t x, int32_t y, int32_t width, int32_t height)
1308 {
1309         struct weston_region *region = resource->data;
1310         pixman_region32_t rect;
1311
1312         pixman_region32_init_rect(&rect, x, y, width, height);
1313         pixman_region32_subtract(&region->region, &region->region, &rect);
1314         pixman_region32_fini(&rect);
1315 }
1316
1317 static const struct wl_region_interface region_interface = {
1318         region_destroy,
1319         region_add,
1320         region_subtract
1321 };
1322
1323 static void
1324 compositor_create_region(struct wl_client *client,
1325                          struct wl_resource *resource, uint32_t id)
1326 {
1327         struct weston_region *region;
1328
1329         region = malloc(sizeof *region);
1330         if (region == NULL) {
1331                 wl_resource_post_no_memory(resource);
1332                 return;
1333         }
1334
1335         region->resource.destroy = destroy_region;
1336
1337         region->resource.object.id = id;
1338         region->resource.object.interface = &wl_region_interface;
1339         region->resource.object.implementation =
1340                 (void (**)(void)) &region_interface;
1341         region->resource.data = region;
1342
1343         pixman_region32_init(&region->region);
1344
1345         wl_client_add_resource(client, &region->resource);
1346 }
1347
1348 static const struct wl_compositor_interface compositor_interface = {
1349         compositor_create_surface,
1350         compositor_create_region
1351 };
1352
1353 WL_EXPORT void
1354 weston_compositor_wake(struct weston_compositor *compositor)
1355 {
1356         compositor->state = WESTON_COMPOSITOR_ACTIVE;
1357         weston_compositor_fade(compositor, 0.0);
1358
1359         wl_event_source_timer_update(compositor->idle_source,
1360                                      compositor->idle_time * 1000);
1361 }
1362
1363 static void
1364 weston_compositor_dpms_on(struct weston_compositor *compositor)
1365 {
1366         struct weston_output *output;
1367
1368         wl_list_for_each(output, &compositor->output_list, link)
1369                 if (output->set_dpms)
1370                         output->set_dpms(output, WESTON_DPMS_ON);
1371 }
1372
1373 WL_EXPORT void
1374 weston_compositor_activity(struct weston_compositor *compositor)
1375 {
1376         if (compositor->state == WESTON_COMPOSITOR_ACTIVE) {
1377                 weston_compositor_wake(compositor);
1378         } else {
1379                 weston_compositor_dpms_on(compositor);
1380                 wl_signal_emit(&compositor->unlock_signal, compositor);
1381         }
1382 }
1383
1384 static void
1385 weston_compositor_idle_inhibit(struct weston_compositor *compositor)
1386 {
1387         weston_compositor_activity(compositor);
1388         compositor->idle_inhibit++;
1389 }
1390
1391 static void
1392 weston_compositor_idle_release(struct weston_compositor *compositor)
1393 {
1394         compositor->idle_inhibit--;
1395         weston_compositor_activity(compositor);
1396 }
1397
1398 static int
1399 idle_handler(void *data)
1400 {
1401         struct weston_compositor *compositor = data;
1402
1403         if (compositor->idle_inhibit)
1404                 return 1;
1405
1406         weston_compositor_fade(compositor, 1.0);
1407
1408         return 1;
1409 }
1410
1411 WL_EXPORT void
1412 weston_plane_init(struct weston_plane *plane, int32_t x, int32_t y)
1413 {
1414         pixman_region32_init(&plane->damage);
1415         plane->x = x;
1416         plane->y = y;
1417 }
1418
1419 WL_EXPORT void
1420 weston_plane_release(struct weston_plane *plane)
1421 {
1422         pixman_region32_fini(&plane->damage);
1423 }
1424
1425 static  void
1426 weston_seat_update_drag_surface(struct weston_seat *seat, int dx, int dy);
1427
1428 static void
1429 clip_pointer_motion(struct weston_seat *seat, wl_fixed_t *fx, wl_fixed_t *fy)
1430 {
1431         struct weston_compositor *ec = seat->compositor;
1432         struct weston_output *output, *prev = NULL;
1433         int x, y, old_x, old_y, valid = 0;
1434
1435         x = wl_fixed_to_int(*fx);
1436         y = wl_fixed_to_int(*fy);
1437         old_x = wl_fixed_to_int(seat->seat.pointer->x);
1438         old_y = wl_fixed_to_int(seat->seat.pointer->y);
1439
1440         wl_list_for_each(output, &ec->output_list, link) {
1441                 if (pixman_region32_contains_point(&output->region,
1442                                                    x, y, NULL))
1443                         valid = 1;
1444                 if (pixman_region32_contains_point(&output->region,
1445                                                    old_x, old_y, NULL))
1446                         prev = output;
1447         }
1448
1449         if (!valid) {
1450                 if (x < prev->x)
1451                         *fx = wl_fixed_from_int(prev->x);
1452                 else if (x >= prev->x + prev->width)
1453                         *fx = wl_fixed_from_int(prev->x +
1454                                                 prev->width - 1);
1455                 if (y < prev->y)
1456                         *fy = wl_fixed_from_int(prev->y);
1457                 else if (y >= prev->y + prev->current->height)
1458                         *fy = wl_fixed_from_int(prev->y +
1459                                                 prev->height - 1);
1460         }
1461 }
1462
1463 WL_EXPORT void
1464 notify_motion(struct weston_seat *seat, uint32_t time, wl_fixed_t x, wl_fixed_t y)
1465 {
1466         const struct wl_pointer_grab_interface *interface;
1467         struct weston_compositor *ec = seat->compositor;
1468         struct weston_output *output;
1469         struct wl_pointer *pointer = seat->seat.pointer;
1470         int32_t ix, iy;
1471
1472         weston_compositor_activity(ec);
1473
1474         clip_pointer_motion(seat, &x, &y);
1475
1476         weston_seat_update_drag_surface(seat, x - pointer->x, y - pointer->y);
1477
1478         pointer->x = x;
1479         pointer->y = y;
1480
1481         ix = wl_fixed_to_int(x);
1482         iy = wl_fixed_to_int(y);
1483
1484         wl_list_for_each(output, &ec->output_list, link)
1485                 if (output->zoom.active &&
1486                     pixman_region32_contains_point(&output->region,
1487                                                    ix, iy, NULL))
1488                         weston_output_update_zoom(output, ZOOM_FOCUS_POINTER);
1489
1490         weston_device_repick(seat);
1491         interface = pointer->grab->interface;
1492         interface->motion(pointer->grab, time,
1493                           pointer->grab->x, pointer->grab->y);
1494
1495         if (seat->sprite) {
1496                 weston_surface_set_position(seat->sprite,
1497                                             ix - seat->hotspot_x,
1498                                             iy - seat->hotspot_y);
1499                 weston_surface_schedule_repaint(seat->sprite);
1500         }
1501 }
1502
1503 WL_EXPORT void
1504 weston_surface_activate(struct weston_surface *surface,
1505                         struct weston_seat *seat)
1506 {
1507         struct weston_compositor *compositor = seat->compositor;
1508
1509         if (seat->seat.keyboard) {
1510                 wl_keyboard_set_focus(seat->seat.keyboard, &surface->surface);
1511                 wl_data_device_set_keyboard_focus(&seat->seat);
1512         }
1513
1514         wl_signal_emit(&compositor->activate_signal, surface);
1515 }
1516
1517 WL_EXPORT void
1518 notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
1519               enum wl_pointer_button_state state)
1520 {
1521         struct weston_compositor *compositor = seat->compositor;
1522         struct wl_pointer *pointer = seat->seat.pointer;
1523         struct weston_surface *focus =
1524                 (struct weston_surface *) pointer->focus;
1525         uint32_t serial = wl_display_next_serial(compositor->wl_display);
1526
1527         if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
1528                 if (compositor->ping_handler && focus)
1529                         compositor->ping_handler(focus, serial);
1530                 weston_compositor_idle_inhibit(compositor);
1531                 if (pointer->button_count == 0) {
1532                         pointer->grab_button = button;
1533                         pointer->grab_time = time;
1534                         pointer->grab_x = pointer->x;
1535                         pointer->grab_y = pointer->y;
1536                 }
1537                 pointer->button_count++;
1538         } else {
1539                 weston_compositor_idle_release(compositor);
1540                 pointer->button_count--;
1541         }
1542
1543         weston_compositor_run_button_binding(compositor, seat, time, button,
1544                                              state);
1545
1546         pointer->grab->interface->button(pointer->grab, time, button, state);
1547
1548         if (pointer->button_count == 1)
1549                 pointer->grab_serial =
1550                         wl_display_get_serial(compositor->wl_display);
1551 }
1552
1553 WL_EXPORT void
1554 notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
1555             wl_fixed_t value)
1556 {
1557         struct weston_compositor *compositor = seat->compositor;
1558         struct wl_pointer *pointer = seat->seat.pointer;
1559         struct weston_surface *focus =
1560                 (struct weston_surface *) pointer->focus;
1561         uint32_t serial = wl_display_next_serial(compositor->wl_display);
1562
1563         if (compositor->ping_handler && focus)
1564                 compositor->ping_handler(focus, serial);
1565
1566         weston_compositor_activity(compositor);
1567
1568         if (value)
1569                 weston_compositor_run_axis_binding(compositor, seat,
1570                                                    time, axis, value);
1571         else
1572                 return;
1573
1574         if (pointer->focus_resource)
1575                 wl_pointer_send_axis(pointer->focus_resource, time, axis,
1576                                      value);
1577 }
1578
1579 WL_EXPORT void
1580 notify_modifiers(struct weston_seat *seat, uint32_t serial)
1581 {
1582         struct wl_keyboard *keyboard = &seat->keyboard;
1583         struct wl_keyboard_grab *grab = keyboard->grab;
1584         uint32_t mods_depressed, mods_latched, mods_locked, group;
1585         uint32_t mods_lookup;
1586         enum weston_led leds = 0;
1587         int changed = 0;
1588
1589         /* Serialize and update our internal state, checking to see if it's
1590          * different to the previous state. */
1591         mods_depressed = xkb_state_serialize_mods(seat->xkb_state.state,
1592                                                   XKB_STATE_DEPRESSED);
1593         mods_latched = xkb_state_serialize_mods(seat->xkb_state.state,
1594                                                 XKB_STATE_LATCHED);
1595         mods_locked = xkb_state_serialize_mods(seat->xkb_state.state,
1596                                                XKB_STATE_LOCKED);
1597         group = xkb_state_serialize_group(seat->xkb_state.state,
1598                                           XKB_STATE_EFFECTIVE);
1599
1600         if (mods_depressed != seat->seat.keyboard->modifiers.mods_depressed ||
1601             mods_latched != seat->seat.keyboard->modifiers.mods_latched ||
1602             mods_locked != seat->seat.keyboard->modifiers.mods_locked ||
1603             group != seat->seat.keyboard->modifiers.group)
1604                 changed = 1;
1605
1606         seat->seat.keyboard->modifiers.mods_depressed = mods_depressed;
1607         seat->seat.keyboard->modifiers.mods_latched = mods_latched;
1608         seat->seat.keyboard->modifiers.mods_locked = mods_locked;
1609         seat->seat.keyboard->modifiers.group = group;
1610
1611         /* And update the modifier_state for bindings. */
1612         mods_lookup = mods_depressed | mods_latched;
1613         seat->modifier_state = 0;
1614         if (mods_lookup & (1 << seat->xkb_info.ctrl_mod))
1615                 seat->modifier_state |= MODIFIER_CTRL;
1616         if (mods_lookup & (1 << seat->xkb_info.alt_mod))
1617                 seat->modifier_state |= MODIFIER_ALT;
1618         if (mods_lookup & (1 << seat->xkb_info.super_mod))
1619                 seat->modifier_state |= MODIFIER_SUPER;
1620         if (mods_lookup & (1 << seat->xkb_info.shift_mod))
1621                 seat->modifier_state |= MODIFIER_SHIFT;
1622
1623         /* Finally, notify the compositor that LEDs have changed. */
1624         if (xkb_state_led_index_is_active(seat->xkb_state.state,
1625                                           seat->xkb_info.num_led))
1626                 leds |= LED_NUM_LOCK;
1627         if (xkb_state_led_index_is_active(seat->xkb_state.state,
1628                                           seat->xkb_info.caps_led))
1629                 leds |= LED_CAPS_LOCK;
1630         if (xkb_state_led_index_is_active(seat->xkb_state.state,
1631                                           seat->xkb_info.scroll_led))
1632                 leds |= LED_SCROLL_LOCK;
1633         if (leds != seat->xkb_state.leds && seat->led_update)
1634                 seat->led_update(seat, leds);
1635         seat->xkb_state.leds = leds;
1636
1637         if (changed) {
1638                 grab->interface->modifiers(grab,
1639                                            serial,
1640                                            keyboard->modifiers.mods_depressed,
1641                                            keyboard->modifiers.mods_latched,
1642                                            keyboard->modifiers.mods_locked,
1643                                            keyboard->modifiers.group);
1644         }
1645 }
1646
1647 static void
1648 update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1649                       enum wl_keyboard_key_state state)
1650 {
1651         enum xkb_key_direction direction;
1652
1653         if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1654                 direction = XKB_KEY_DOWN;
1655         else
1656                 direction = XKB_KEY_UP;
1657
1658         /* Offset the keycode by 8, as the evdev XKB rules reflect X's
1659          * broken keycode system, which starts at 8. */
1660         xkb_state_update_key(seat->xkb_state.state, key + 8, direction);
1661
1662         notify_modifiers(seat, serial);
1663 }
1664
1665 WL_EXPORT void
1666 notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
1667            enum wl_keyboard_key_state state,
1668            enum weston_key_state_update update_state)
1669 {
1670         struct weston_compositor *compositor = seat->compositor;
1671         struct wl_keyboard *keyboard = seat->seat.keyboard;
1672         struct weston_surface *focus =
1673                 (struct weston_surface *) keyboard->focus;
1674         struct wl_keyboard_grab *grab = keyboard->grab;
1675         uint32_t serial = wl_display_next_serial(compositor->wl_display);
1676         uint32_t *k, *end;
1677
1678         if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1679                 if (compositor->ping_handler && focus)
1680                         compositor->ping_handler(focus, serial);
1681
1682                 weston_compositor_idle_inhibit(compositor);
1683                 keyboard->grab_key = key;
1684                 keyboard->grab_time = time;
1685         } else {
1686                 weston_compositor_idle_release(compositor);
1687         }
1688
1689         end = keyboard->keys.data + keyboard->keys.size;
1690         for (k = keyboard->keys.data; k < end; k++) {
1691                 if (*k == key) {
1692                         /* Ignore server-generated repeats. */
1693                         if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1694                                 return;
1695                         *k = *--end;
1696                 }
1697         }
1698         keyboard->keys.size = (void *) end - keyboard->keys.data;
1699         if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1700                 k = wl_array_add(&keyboard->keys, sizeof *k);
1701                 *k = key;
1702         }
1703
1704         if (grab == &keyboard->default_grab) {
1705                 weston_compositor_run_key_binding(compositor, seat, time, key,
1706                                                   state);
1707                 grab = keyboard->grab;
1708         }
1709
1710         grab->interface->key(grab, time, key, state);
1711
1712         if (update_state == STATE_UPDATE_AUTOMATIC) {
1713                 update_modifier_state(seat,
1714                                       wl_display_get_serial(compositor->wl_display),
1715                                       key,
1716                                       state);
1717         }
1718 }
1719
1720 WL_EXPORT void
1721 notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
1722                      wl_fixed_t x, wl_fixed_t y)
1723 {
1724         struct weston_compositor *compositor = seat->compositor;
1725         struct wl_pointer *pointer = seat->seat.pointer;
1726
1727         if (output) {
1728                 weston_seat_update_drag_surface(seat,
1729                                                 x - pointer->x,
1730                                                 y - pointer->y);
1731
1732                 pointer->x = x;
1733                 pointer->y = y;
1734                 compositor->focus = 1;
1735                 weston_compositor_repick(compositor);
1736         } else {
1737                 compositor->focus = 0;
1738                 /* FIXME: We should call wl_pointer_set_focus(seat,
1739                  * NULL) here, but somehow that breaks re-entry... */
1740         }
1741 }
1742
1743 static void
1744 destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
1745 {
1746         struct weston_seat *ws;
1747
1748         ws = container_of(listener, struct weston_seat,
1749                           saved_kbd_focus_listener);
1750
1751         ws->saved_kbd_focus = NULL;
1752 }
1753
1754 WL_EXPORT void
1755 notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
1756                          enum weston_key_state_update update_state)
1757 {
1758         struct weston_compositor *compositor = seat->compositor;
1759         struct wl_keyboard *keyboard = seat->seat.keyboard;
1760         struct wl_surface *surface;
1761         uint32_t *k, serial;
1762
1763         serial = wl_display_next_serial(compositor->wl_display);
1764         wl_array_copy(&keyboard->keys, keys);
1765         wl_array_for_each(k, &keyboard->keys) {
1766                 weston_compositor_idle_inhibit(compositor);
1767                 if (update_state == STATE_UPDATE_AUTOMATIC)
1768                         update_modifier_state(seat, serial, *k,
1769                                               WL_KEYBOARD_KEY_STATE_PRESSED);
1770         }
1771
1772         /* Run key bindings after we've updated the state. */
1773         wl_array_for_each(k, &keyboard->keys) {
1774                 weston_compositor_run_key_binding(compositor, seat, 0, *k,
1775                                                   WL_KEYBOARD_KEY_STATE_PRESSED);
1776         }
1777
1778         surface = seat->saved_kbd_focus;
1779
1780         if (surface) {
1781                 wl_list_remove(&seat->saved_kbd_focus_listener.link);
1782                 wl_keyboard_set_focus(keyboard, surface);
1783                 seat->saved_kbd_focus = NULL;
1784         }
1785 }
1786
1787 WL_EXPORT void
1788 notify_keyboard_focus_out(struct weston_seat *seat)
1789 {
1790         struct weston_compositor *compositor = seat->compositor;
1791         struct wl_keyboard *keyboard = seat->seat.keyboard;
1792         uint32_t *k, serial;
1793
1794         serial = wl_display_next_serial(compositor->wl_display);
1795         wl_array_for_each(k, &keyboard->keys) {
1796                 weston_compositor_idle_release(compositor);
1797                 update_modifier_state(seat, serial, *k,
1798                                       WL_KEYBOARD_KEY_STATE_RELEASED);
1799         }
1800
1801         seat->modifier_state = 0;
1802
1803         if (keyboard->focus) {
1804                 seat->saved_kbd_focus = keyboard->focus;
1805                 seat->saved_kbd_focus_listener.notify =
1806                         destroy_device_saved_kbd_focus;
1807                 wl_signal_add(&keyboard->focus->resource.destroy_signal,
1808                               &seat->saved_kbd_focus_listener);
1809         }
1810
1811         wl_keyboard_set_focus(keyboard, NULL);
1812         /* FIXME: We really need keyboard grab cancel here to
1813          * let the grab shut down properly.  As it is we leak
1814          * the grab data. */
1815         wl_keyboard_end_grab(keyboard);
1816 }
1817
1818 static void
1819 touch_set_focus(struct weston_seat *ws, struct wl_surface *surface)
1820 {
1821         struct wl_seat *seat = &ws->seat;
1822         struct wl_resource *resource;
1823
1824         if (seat->touch->focus == surface)
1825                 return;
1826
1827         if (seat->touch->focus_resource)
1828                 wl_list_remove(&seat->touch->focus_listener.link);
1829         seat->touch->focus = NULL;
1830         seat->touch->focus_resource = NULL;
1831
1832         if (surface) {
1833                 resource =
1834                         find_resource_for_client(&seat->touch->resource_list,
1835                                                  surface->resource.client);
1836                 if (!resource) {
1837                         weston_log("couldn't find resource\n");
1838                         return;
1839                 }
1840
1841                 seat->touch->focus = surface;
1842                 seat->touch->focus_resource = resource;
1843                 wl_signal_add(&resource->destroy_signal,
1844                               &seat->touch->focus_listener);
1845         }
1846 }
1847
1848 /**
1849  * notify_touch - emulates button touches and notifies surfaces accordingly.
1850  *
1851  * It assumes always the correct cycle sequence until it gets here: touch_down
1852  * → touch_update → ... → touch_update → touch_end. The driver is responsible
1853  * for sending along such order.
1854  *
1855  */
1856 WL_EXPORT void
1857 notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
1858              wl_fixed_t x, wl_fixed_t y, int touch_type)
1859 {
1860         struct weston_compositor *ec = seat->compositor;
1861         struct wl_touch *touch = seat->seat.touch;
1862         struct weston_surface *es;
1863         wl_fixed_t sx, sy;
1864         uint32_t serial = 0;
1865
1866         switch (touch_type) {
1867         case WL_TOUCH_DOWN:
1868                 weston_compositor_idle_inhibit(ec);
1869
1870                 seat->num_tp++;
1871
1872                 /* the first finger down picks the surface, and all further go
1873                  * to that surface for the remainder of the touch session i.e.
1874                  * until all touch points are up again. */
1875                 if (seat->num_tp == 1) {
1876                         es = weston_compositor_pick_surface(ec, x, y, &sx, &sy);
1877                         touch_set_focus(seat, &es->surface);
1878                 } else if (touch->focus) {
1879                         es = (struct weston_surface *) touch->focus;
1880                         weston_surface_from_global_fixed(es, x, y, &sx, &sy);
1881                 }
1882
1883                 if (touch->focus_resource && touch->focus)
1884                         wl_touch_send_down(touch->focus_resource,
1885                                            serial, time,
1886                                            &touch->focus->resource,
1887                                            touch_id, sx, sy);
1888                 break;
1889         case WL_TOUCH_MOTION:
1890                 es = (struct weston_surface *) touch->focus;
1891                 if (!es)
1892                         break;
1893
1894                 weston_surface_from_global_fixed(es, x, y, &sx, &sy);
1895                 if (touch->focus_resource)
1896                         wl_touch_send_motion(touch->focus_resource,
1897                                              time, touch_id, sx, sy);
1898                 break;
1899         case WL_TOUCH_UP:
1900                 weston_compositor_idle_release(ec);
1901                 seat->num_tp--;
1902
1903                 if (touch->focus_resource)
1904                         wl_touch_send_up(touch->focus_resource,
1905                                          serial, time, touch_id);
1906                 if (seat->num_tp == 0)
1907                         touch_set_focus(seat, NULL);
1908                 break;
1909         }
1910 }
1911
1912 static void
1913 pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
1914 {
1915         struct weston_seat *seat = container_of(listener, struct weston_seat,
1916                                                 sprite_destroy_listener);
1917
1918         seat->sprite = NULL;
1919 }
1920
1921 static void
1922 pointer_cursor_surface_configure(struct weston_surface *es,
1923                                  int32_t dx, int32_t dy)
1924 {
1925         struct weston_seat *seat = es->private;
1926         int x, y;
1927
1928         assert(es == seat->sprite);
1929
1930         seat->hotspot_x -= dx;
1931         seat->hotspot_y -= dy;
1932
1933         x = wl_fixed_to_int(seat->seat.pointer->x) - seat->hotspot_x;
1934         y = wl_fixed_to_int(seat->seat.pointer->y) - seat->hotspot_y;
1935
1936         weston_surface_configure(seat->sprite, x, y,
1937                                  es->buffer->width, es->buffer->height);
1938
1939         empty_region(&es->input);
1940
1941         if (!weston_surface_is_mapped(es)) {
1942                 wl_list_insert(&es->compositor->cursor_layer.surface_list,
1943                                &es->layer_link);
1944                 weston_surface_assign_output(es);
1945         }
1946 }
1947
1948 static void
1949 pointer_unmap_sprite(struct weston_seat *seat)
1950 {
1951         if (weston_surface_is_mapped(seat->sprite))
1952                 weston_surface_unmap(seat->sprite);
1953
1954         wl_list_remove(&seat->sprite_destroy_listener.link);
1955         seat->sprite->configure = NULL;
1956         seat->sprite->private = NULL;
1957         seat->sprite = NULL;
1958 }
1959
1960 static void
1961 pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
1962                    uint32_t serial, struct wl_resource *surface_resource,
1963                    int32_t x, int32_t y)
1964 {
1965         struct weston_seat *seat = resource->data;
1966         struct weston_surface *surface = NULL;
1967
1968         if (surface_resource)
1969                 surface = container_of(surface_resource->data,
1970                                        struct weston_surface, surface);
1971
1972         if (seat->seat.pointer->focus == NULL)
1973                 return;
1974         if (seat->seat.pointer->focus->resource.client != client)
1975                 return;
1976         if (seat->seat.pointer->focus_serial - serial > UINT32_MAX / 2)
1977                 return;
1978
1979         if (surface && surface != seat->sprite) {
1980                 if (surface->configure) {
1981                         wl_resource_post_error(&surface->surface.resource,
1982                                                WL_DISPLAY_ERROR_INVALID_OBJECT,
1983                                                "surface->configure already "
1984                                                "set");
1985                         return;
1986                 }
1987         }
1988
1989         if (seat->sprite)
1990                 pointer_unmap_sprite(seat);
1991
1992         if (!surface)
1993                 return;
1994
1995         wl_signal_add(&surface->surface.resource.destroy_signal,
1996                       &seat->sprite_destroy_listener);
1997
1998         surface->configure = pointer_cursor_surface_configure;
1999         surface->private = seat;
2000         seat->sprite = surface;
2001         seat->hotspot_x = x;
2002         seat->hotspot_y = y;
2003
2004         if (surface->buffer)
2005                 pointer_cursor_surface_configure(surface, 0, 0);
2006 }
2007
2008 static const struct wl_pointer_interface pointer_interface = {
2009         pointer_set_cursor
2010 };
2011
2012 static void
2013 handle_drag_surface_destroy(struct wl_listener *listener, void *data)
2014 {
2015         struct weston_seat *seat;
2016
2017         seat = container_of(listener, struct weston_seat,
2018                             drag_surface_destroy_listener);
2019
2020         seat->drag_surface = NULL;
2021 }
2022
2023 static void unbind_resource(struct wl_resource *resource)
2024 {
2025         wl_list_remove(&resource->link);
2026         free(resource);
2027 }
2028
2029 static void
2030 seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
2031                  uint32_t id)
2032 {
2033         struct weston_seat *seat = resource->data;
2034         struct wl_resource *cr;
2035
2036         if (!seat->seat.pointer)
2037                 return;
2038
2039         cr = wl_client_add_object(client, &wl_pointer_interface,
2040                                   &pointer_interface, id, seat);
2041         wl_list_insert(&seat->seat.pointer->resource_list, &cr->link);
2042         cr->destroy = unbind_resource;
2043
2044         if (seat->seat.pointer->focus &&
2045             seat->seat.pointer->focus->resource.client == client) {
2046                 struct weston_surface *surface;
2047                 wl_fixed_t sx, sy;
2048
2049                 surface = (struct weston_surface *) seat->seat.pointer->focus;
2050                 weston_surface_from_global_fixed(surface,
2051                                                  seat->seat.pointer->x,
2052                                                  seat->seat.pointer->y,
2053                                                  &sx,
2054                                                  &sy);
2055                 wl_pointer_set_focus(seat->seat.pointer,
2056                                      seat->seat.pointer->focus,
2057                                      sx,
2058                                      sy);
2059         }
2060 }
2061
2062 static void
2063 seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
2064                   uint32_t id)
2065 {
2066         struct weston_seat *seat = resource->data;
2067         struct wl_resource *cr;
2068
2069         if (!seat->seat.keyboard)
2070                 return;
2071
2072         cr = wl_client_add_object(client, &wl_keyboard_interface, NULL, id,
2073                                   seat);
2074         wl_list_insert(&seat->seat.keyboard->resource_list, &cr->link);
2075         cr->destroy = unbind_resource;
2076
2077         wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
2078                                 seat->xkb_info.keymap_fd,
2079                                 seat->xkb_info.keymap_size);
2080
2081         if (seat->seat.keyboard->focus &&
2082             seat->seat.keyboard->focus->resource.client == client) {
2083                 wl_keyboard_set_focus(seat->seat.keyboard,
2084                                       seat->seat.keyboard->focus);
2085         }
2086 }
2087
2088 static void
2089 seat_get_touch(struct wl_client *client, struct wl_resource *resource,
2090                uint32_t id)
2091 {
2092         struct weston_seat *seat = resource->data;
2093         struct wl_resource *cr;
2094
2095         if (!seat->seat.touch)
2096                 return;
2097
2098         cr = wl_client_add_object(client, &wl_touch_interface, NULL, id, seat);
2099         wl_list_insert(&seat->seat.touch->resource_list, &cr->link);
2100         cr->destroy = unbind_resource;
2101 }
2102
2103 static const struct wl_seat_interface seat_interface = {
2104         seat_get_pointer,
2105         seat_get_keyboard,
2106         seat_get_touch,
2107 };
2108
2109 static void
2110 bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
2111 {
2112         struct wl_seat *seat = data;
2113         struct wl_resource *resource;
2114         enum wl_seat_capability caps = 0;
2115
2116         resource = wl_client_add_object(client, &wl_seat_interface,
2117                                         &seat_interface, id, data);
2118         wl_list_insert(&seat->base_resource_list, &resource->link);
2119         resource->destroy = unbind_resource;
2120
2121         if (seat->pointer)
2122                 caps |= WL_SEAT_CAPABILITY_POINTER;
2123         if (seat->keyboard)
2124                 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
2125         if (seat->touch)
2126                 caps |= WL_SEAT_CAPABILITY_TOUCH;
2127
2128         wl_seat_send_capabilities(resource, caps);
2129 }
2130
2131 static void
2132 device_handle_new_drag_icon(struct wl_listener *listener, void *data)
2133 {
2134         struct weston_seat *seat;
2135
2136         seat = container_of(listener, struct weston_seat,
2137                             new_drag_icon_listener);
2138
2139         weston_seat_update_drag_surface(seat, 0, 0);
2140 }
2141
2142 static void weston_compositor_xkb_init(struct weston_compositor *ec,
2143                                        struct xkb_rule_names *names)
2144 {
2145         if (ec->xkb_context == NULL) {
2146                 ec->xkb_context = xkb_context_new(0);
2147                 if (ec->xkb_context == NULL) {
2148                         weston_log("failed to create XKB context\n");
2149                         exit(1);
2150                 }
2151         }
2152
2153         if (names)
2154                 ec->xkb_names = *names;
2155         if (!ec->xkb_names.rules)
2156                 ec->xkb_names.rules = strdup("evdev");
2157         if (!ec->xkb_names.model)
2158                 ec->xkb_names.model = strdup("pc105");
2159         if (!ec->xkb_names.layout)
2160                 ec->xkb_names.layout = strdup("us");
2161 }
2162
2163 static void xkb_info_destroy(struct weston_xkb_info *xkb_info)
2164 {
2165         if (xkb_info->keymap)
2166                 xkb_map_unref(xkb_info->keymap);
2167
2168         if (xkb_info->keymap_area)
2169                 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
2170         if (xkb_info->keymap_fd >= 0)
2171                 close(xkb_info->keymap_fd);
2172 }
2173
2174 static void weston_compositor_xkb_destroy(struct weston_compositor *ec)
2175 {
2176         free((char *) ec->xkb_names.rules);
2177         free((char *) ec->xkb_names.model);
2178         free((char *) ec->xkb_names.layout);
2179         free((char *) ec->xkb_names.variant);
2180         free((char *) ec->xkb_names.options);
2181
2182         xkb_info_destroy(&ec->xkb_info);
2183         xkb_context_unref(ec->xkb_context);
2184 }
2185
2186 static void
2187 weston_xkb_info_new_keymap(struct weston_xkb_info *xkb_info)
2188 {
2189         char *keymap_str;
2190
2191         xkb_info->shift_mod = xkb_map_mod_get_index(xkb_info->keymap,
2192                                                     XKB_MOD_NAME_SHIFT);
2193         xkb_info->caps_mod = xkb_map_mod_get_index(xkb_info->keymap,
2194                                                    XKB_MOD_NAME_CAPS);
2195         xkb_info->ctrl_mod = xkb_map_mod_get_index(xkb_info->keymap,
2196                                                    XKB_MOD_NAME_CTRL);
2197         xkb_info->alt_mod = xkb_map_mod_get_index(xkb_info->keymap,
2198                                                   XKB_MOD_NAME_ALT);
2199         xkb_info->mod2_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod2");
2200         xkb_info->mod3_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod3");
2201         xkb_info->super_mod = xkb_map_mod_get_index(xkb_info->keymap,
2202                                                     XKB_MOD_NAME_LOGO);
2203         xkb_info->mod5_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod5");
2204
2205         xkb_info->num_led = xkb_map_led_get_index(xkb_info->keymap,
2206                                                   XKB_LED_NAME_NUM);
2207         xkb_info->caps_led = xkb_map_led_get_index(xkb_info->keymap,
2208                                                    XKB_LED_NAME_CAPS);
2209         xkb_info->scroll_led = xkb_map_led_get_index(xkb_info->keymap,
2210                                                      XKB_LED_NAME_SCROLL);
2211
2212         keymap_str = xkb_map_get_as_string(xkb_info->keymap);
2213         if (keymap_str == NULL) {
2214                 weston_log("failed to get string version of keymap\n");
2215                 exit(EXIT_FAILURE);
2216         }
2217         xkb_info->keymap_size = strlen(keymap_str) + 1;
2218
2219         xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
2220         if (xkb_info->keymap_fd < 0) {
2221                 weston_log("creating a keymap file for %lu bytes failed: %m\n",
2222                         (unsigned long) xkb_info->keymap_size);
2223                 goto err_keymap_str;
2224         }
2225
2226         xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
2227                                      PROT_READ | PROT_WRITE,
2228                                      MAP_SHARED, xkb_info->keymap_fd, 0);
2229         if (xkb_info->keymap_area == MAP_FAILED) {
2230                 weston_log("failed to mmap() %lu bytes\n",
2231                         (unsigned long) xkb_info->keymap_size);
2232                 goto err_dev_zero;
2233         }
2234         strcpy(xkb_info->keymap_area, keymap_str);
2235         free(keymap_str);
2236
2237         return;
2238
2239 err_dev_zero:
2240         close(xkb_info->keymap_fd);
2241         xkb_info->keymap_fd = -1;
2242 err_keymap_str:
2243         free(keymap_str);
2244         exit(EXIT_FAILURE);
2245 }
2246
2247 static void
2248 weston_compositor_build_global_keymap(struct weston_compositor *ec)
2249 {
2250         if (ec->xkb_info.keymap != NULL)
2251                 return;
2252
2253         ec->xkb_info.keymap = xkb_map_new_from_names(ec->xkb_context,
2254                                                      &ec->xkb_names,
2255                                                      0);
2256         if (ec->xkb_info.keymap == NULL) {
2257                 weston_log("failed to compile global XKB keymap\n");
2258                 weston_log("  tried rules %s, model %s, layout %s, variant %s, "
2259                         "options %s",
2260                         ec->xkb_names.rules, ec->xkb_names.model,
2261                         ec->xkb_names.layout, ec->xkb_names.variant,
2262                         ec->xkb_names.options);
2263                 exit(1);
2264         }
2265
2266         weston_xkb_info_new_keymap(&ec->xkb_info);
2267 }
2268
2269 WL_EXPORT void
2270 weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
2271 {
2272         if (seat->has_keyboard)
2273                 return;
2274
2275         if (keymap != NULL) {
2276                 seat->xkb_info.keymap = xkb_map_ref(keymap);
2277                 weston_xkb_info_new_keymap(&seat->xkb_info);
2278         }
2279         else {
2280                 weston_compositor_build_global_keymap(seat->compositor);
2281                 seat->xkb_info = seat->compositor->xkb_info;
2282                 seat->xkb_info.keymap = xkb_map_ref(seat->xkb_info.keymap);
2283         }
2284
2285         seat->xkb_state.state = xkb_state_new(seat->xkb_info.keymap);
2286         if (seat->xkb_state.state == NULL) {
2287                 weston_log("failed to initialise XKB state\n");
2288                 exit(1);
2289         }
2290
2291         seat->xkb_state.leds = 0;
2292
2293         wl_keyboard_init(&seat->keyboard);
2294         wl_seat_set_keyboard(&seat->seat, &seat->keyboard);
2295
2296         seat->has_keyboard = 1;
2297 }
2298
2299 WL_EXPORT void
2300 weston_seat_init_pointer(struct weston_seat *seat)
2301 {
2302         if (seat->has_pointer)
2303                 return;
2304
2305         wl_pointer_init(&seat->pointer);
2306         wl_seat_set_pointer(&seat->seat, &seat->pointer);
2307
2308         seat->has_pointer = 1;
2309 }
2310
2311 WL_EXPORT void
2312 weston_seat_init_touch(struct weston_seat *seat)
2313 {
2314         if (seat->has_touch)
2315                 return;
2316
2317         wl_touch_init(&seat->touch);
2318         wl_seat_set_touch(&seat->seat, &seat->touch);
2319
2320         seat->has_touch = 1;
2321 }
2322
2323 WL_EXPORT void
2324 weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec)
2325 {
2326         wl_seat_init(&seat->seat);
2327         seat->has_pointer = 0;
2328         seat->has_keyboard = 0;
2329         seat->has_touch = 0;
2330
2331         wl_display_add_global(ec->wl_display, &wl_seat_interface, seat,
2332                               bind_seat);
2333
2334         seat->sprite = NULL;
2335         seat->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
2336
2337         seat->compositor = ec;
2338         seat->hotspot_x = 16;
2339         seat->hotspot_y = 16;
2340         seat->modifier_state = 0;
2341         seat->num_tp = 0;
2342
2343         seat->drag_surface_destroy_listener.notify =
2344                 handle_drag_surface_destroy;
2345
2346         wl_list_insert(ec->seat_list.prev, &seat->link);
2347
2348         seat->new_drag_icon_listener.notify = device_handle_new_drag_icon;
2349         wl_signal_add(&seat->seat.drag_icon_signal,
2350                       &seat->new_drag_icon_listener);
2351
2352         clipboard_create(seat);
2353         input_method_create(ec, seat);
2354 }
2355
2356 WL_EXPORT void
2357 weston_seat_release(struct weston_seat *seat)
2358 {
2359         wl_list_remove(&seat->link);
2360         /* The global object is destroyed at wl_display_destroy() time. */
2361
2362         if (seat->sprite)
2363                 pointer_unmap_sprite(seat);
2364
2365         if (seat->xkb_state.state != NULL)
2366                 xkb_state_unref(seat->xkb_state.state);
2367         xkb_info_destroy(&seat->xkb_info);
2368
2369         wl_seat_release(&seat->seat);
2370 }
2371
2372 static void
2373 drag_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
2374 {
2375         weston_surface_configure(es,
2376                                  es->geometry.x + sx, es->geometry.y + sy,
2377                                  es->buffer->width, es->buffer->height);
2378 }
2379
2380 static int
2381 device_setup_new_drag_surface(struct weston_seat *ws,
2382                               struct weston_surface *surface)
2383 {
2384         struct wl_seat *seat = &ws->seat;
2385
2386         if (surface->configure) {
2387                 wl_resource_post_error(&surface->surface.resource,
2388                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
2389                                        "surface->configure already set");
2390                 return 0;
2391         }
2392
2393         ws->drag_surface = surface;
2394
2395         weston_surface_set_position(ws->drag_surface,
2396                                     wl_fixed_to_double(seat->pointer->x),
2397                                     wl_fixed_to_double(seat->pointer->y));
2398
2399         surface->configure = drag_surface_configure;
2400
2401         wl_signal_add(&surface->surface.resource.destroy_signal,
2402                        &ws->drag_surface_destroy_listener);
2403
2404         return 1;
2405 }
2406
2407 static void
2408 device_release_drag_surface(struct weston_seat *seat)
2409 {
2410         seat->drag_surface->configure = NULL;
2411         undef_region(&seat->drag_surface->input);
2412         wl_list_remove(&seat->drag_surface_destroy_listener.link);
2413         seat->drag_surface = NULL;
2414 }
2415
2416 static void
2417 device_map_drag_surface(struct weston_seat *seat)
2418 {
2419         struct wl_list *list;
2420
2421         if (weston_surface_is_mapped(seat->drag_surface) ||
2422             !seat->drag_surface->buffer)
2423                 return;
2424
2425         if (seat->sprite && weston_surface_is_mapped(seat->sprite))
2426                 list = &seat->sprite->layer_link;
2427         else
2428                 list = &seat->compositor->cursor_layer.surface_list;
2429
2430         wl_list_insert(list, &seat->drag_surface->layer_link);
2431         weston_surface_assign_output(seat->drag_surface);
2432         empty_region(&seat->drag_surface->input);
2433 }
2434
2435 static  void
2436 weston_seat_update_drag_surface(struct weston_seat *seat,
2437                                 int dx, int dy)
2438 {
2439         int surface_changed = 0;
2440
2441         if (!seat->drag_surface && !seat->seat.drag_surface)
2442                 return;
2443
2444         if (seat->drag_surface && seat->seat.drag_surface &&
2445             (&seat->drag_surface->surface.resource !=
2446              &seat->seat.drag_surface->resource))
2447                 /* between calls to this funcion we got a new drag_surface */
2448                 surface_changed = 1;
2449
2450         if (!seat->seat.drag_surface || surface_changed) {
2451                 device_release_drag_surface(seat);
2452                 if (!surface_changed)
2453                         return;
2454         }
2455
2456         if (!seat->drag_surface || surface_changed) {
2457                 struct weston_surface *surface = (struct weston_surface *)
2458                         seat->seat.drag_surface;
2459                 if (!device_setup_new_drag_surface(seat, surface))
2460                         return;
2461         }
2462
2463         /* the client may not have attached a buffer to the drag surface
2464          * when we setup it up, so check if map is needed on every update */
2465         device_map_drag_surface(seat);
2466
2467         /* the client may have attached a buffer with a different size to
2468          * the drag surface, causing the input region to be reset */
2469         if (region_is_undefined(&seat->drag_surface->input))
2470                 empty_region(&seat->drag_surface->input);
2471
2472         if (!dx && !dy)
2473                 return;
2474
2475         weston_surface_set_position(seat->drag_surface,
2476                                     seat->drag_surface->geometry.x + wl_fixed_to_double(dx),
2477                                     seat->drag_surface->geometry.y + wl_fixed_to_double(dy));
2478 }
2479
2480 WL_EXPORT void
2481 weston_compositor_update_drag_surfaces(struct weston_compositor *compositor)
2482 {
2483         struct weston_seat *seat;
2484
2485         wl_list_for_each(seat, &compositor->seat_list, link)
2486                 weston_seat_update_drag_surface(seat, 0, 0);
2487 }
2488
2489 static void
2490 bind_output(struct wl_client *client,
2491             void *data, uint32_t version, uint32_t id)
2492 {
2493         struct weston_output *output = data;
2494         struct weston_mode *mode;
2495         struct wl_resource *resource;
2496
2497         resource = wl_client_add_object(client,
2498                                         &wl_output_interface, NULL, id, data);
2499
2500         wl_list_insert(&output->resource_list, &resource->link);
2501         resource->destroy = unbind_resource;
2502
2503         wl_output_send_geometry(resource,
2504                                 output->x,
2505                                 output->y,
2506                                 output->mm_width,
2507                                 output->mm_height,
2508                                 output->subpixel,
2509                                 output->make, output->model,
2510                                 output->transform);
2511
2512         wl_list_for_each (mode, &output->mode_list, link) {
2513                 wl_output_send_mode(resource,
2514                                     mode->flags,
2515                                     mode->width,
2516                                     mode->height,
2517                                     mode->refresh);
2518         }
2519 }
2520
2521 WL_EXPORT void
2522 weston_output_destroy(struct weston_output *output)
2523 {
2524         struct weston_compositor *c = output->compositor;
2525
2526         pixman_region32_fini(&output->region);
2527         pixman_region32_fini(&output->previous_damage);
2528         output->compositor->output_id_pool &= ~(1 << output->id);
2529
2530         wl_display_remove_global(c->wl_display, output->global);
2531 }
2532
2533 static void
2534 weston_output_compute_transform(struct weston_output *output)
2535 {
2536         struct weston_matrix transform;
2537         int flip;
2538
2539         weston_matrix_init(&transform);
2540
2541         switch(output->transform) {
2542         case WL_OUTPUT_TRANSFORM_FLIPPED:
2543         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2544         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
2545         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2546                 flip = -1;
2547                 break;
2548         default:
2549                 flip = 1;
2550                 break;
2551         }
2552
2553         switch(output->transform) {
2554         case WL_OUTPUT_TRANSFORM_NORMAL:
2555         case WL_OUTPUT_TRANSFORM_FLIPPED:
2556                 transform.d[0] = flip;
2557                 transform.d[1] = 0;
2558                 transform.d[4] = 0;
2559                 transform.d[5] = 1;
2560                 break;
2561         case WL_OUTPUT_TRANSFORM_90:
2562         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2563                 transform.d[0] = 0;
2564                 transform.d[1] = -flip;
2565                 transform.d[4] = 1;
2566                 transform.d[5] = 0;
2567                 break;
2568         case WL_OUTPUT_TRANSFORM_180:
2569         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
2570                 transform.d[0] = -flip;
2571                 transform.d[1] = 0;
2572                 transform.d[4] = 0;
2573                 transform.d[5] = -1;
2574                 break;
2575         case WL_OUTPUT_TRANSFORM_270:
2576         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2577                 transform.d[0] = 0;
2578                 transform.d[1] = flip;
2579                 transform.d[4] = -1;
2580                 transform.d[5] = 0;
2581                 break;
2582         default:
2583                 break;
2584         }
2585
2586         weston_matrix_multiply(&output->matrix, &transform);
2587 }
2588
2589 WL_EXPORT void
2590 weston_output_update_matrix(struct weston_output *output)
2591 {
2592         float magnification;
2593         struct weston_matrix camera;
2594         struct weston_matrix modelview;
2595
2596         weston_matrix_init(&output->matrix);
2597         weston_matrix_translate(&output->matrix,
2598                                 -(output->x + (output->border.right + output->width - output->border.left) / 2.0),
2599                                 -(output->y + (output->border.bottom + output->height - output->border.top) / 2.0), 0);
2600
2601         weston_matrix_scale(&output->matrix,
2602                             2.0 / (output->width + output->border.left + output->border.right),
2603                             -2.0 / (output->height + output->border.top + output->border.bottom), 1);
2604
2605         weston_output_compute_transform(output);
2606
2607         if (output->zoom.active) {
2608                 magnification = 1 / (1 - output->zoom.spring_z.current);
2609                 weston_matrix_init(&camera);
2610                 weston_matrix_init(&modelview);
2611                 weston_output_update_zoom(output, output->zoom.type);
2612                 weston_matrix_translate(&camera, output->zoom.trans_x,
2613                                         -output->zoom.trans_y, 0);
2614                 weston_matrix_invert(&modelview, &camera);
2615                 weston_matrix_scale(&modelview, magnification, magnification, 1.0);
2616                 weston_matrix_multiply(&output->matrix, &modelview);
2617         }
2618
2619         output->dirty = 0;
2620 }
2621
2622 static void
2623 weston_output_transform_init(struct weston_output *output, uint32_t transform)
2624 {
2625         output->transform = transform;
2626
2627         switch (transform) {
2628         case WL_OUTPUT_TRANSFORM_90:
2629         case WL_OUTPUT_TRANSFORM_270:
2630         case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2631         case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2632                 /* Swap width and height */
2633                 output->width = output->current->height;
2634                 output->height = output->current->width;
2635                 break;
2636         case WL_OUTPUT_TRANSFORM_NORMAL:
2637         case WL_OUTPUT_TRANSFORM_180:
2638         case WL_OUTPUT_TRANSFORM_FLIPPED:
2639         case WL_OUTPUT_TRANSFORM_FLIPPED_180:
2640                 output->width = output->current->width;
2641                 output->height = output->current->height;
2642                 break;
2643         default:
2644                 break;
2645         }
2646 }
2647
2648 WL_EXPORT void
2649 weston_output_move(struct weston_output *output, int x, int y)
2650 {
2651         output->x = x;
2652         output->y = y;
2653
2654         pixman_region32_init(&output->previous_damage);
2655         pixman_region32_init_rect(&output->region, x, y,
2656                                   output->width,
2657                                   output->height);
2658 }
2659
2660 WL_EXPORT void
2661 weston_output_init(struct weston_output *output, struct weston_compositor *c,
2662                    int x, int y, int width, int height, uint32_t transform)
2663 {
2664         output->compositor = c;
2665         output->x = x;
2666         output->y = y;
2667         output->border.top = 0;
2668         output->border.bottom = 0;
2669         output->border.left = 0;
2670         output->border.right = 0;
2671         output->mm_width = width;
2672         output->mm_height = height;
2673         output->dirty = 1;
2674
2675         if (transform != WL_OUTPUT_TRANSFORM_NORMAL)
2676                 output->disable_planes++;
2677
2678         weston_output_transform_init(output, transform);
2679         weston_output_init_zoom(output);
2680
2681         weston_output_move(output, x, y);
2682         weston_output_damage(output);
2683
2684         wl_signal_init(&output->frame_signal);
2685         wl_list_init(&output->animation_list);
2686         wl_list_init(&output->resource_list);
2687
2688         output->id = ffs(~output->compositor->output_id_pool) - 1;
2689         output->compositor->output_id_pool |= 1 << output->id;
2690
2691         output->global =
2692                 wl_display_add_global(c->wl_display, &wl_output_interface,
2693                                       output, bind_output);
2694 }
2695
2696 static void
2697 compositor_bind(struct wl_client *client,
2698                 void *data, uint32_t version, uint32_t id)
2699 {
2700         struct weston_compositor *compositor = data;
2701
2702         wl_client_add_object(client, &wl_compositor_interface,
2703                              &compositor_interface, id, compositor);
2704 }
2705
2706 static void
2707 log_uname(void)
2708 {
2709         struct utsname usys;
2710
2711         uname(&usys);
2712
2713         weston_log("OS: %s, %s, %s, %s\n", usys.sysname, usys.release,
2714                                                 usys.version, usys.machine);
2715 }
2716
2717 WL_EXPORT int
2718 weston_compositor_init(struct weston_compositor *ec,
2719                        struct wl_display *display,
2720                        int argc,
2721                        char *argv[],
2722                        const char *config_file)
2723 {
2724         struct wl_event_loop *loop;
2725         struct xkb_rule_names xkb_names;
2726         const struct config_key keyboard_config_keys[] = {
2727                 { "keymap_rules", CONFIG_KEY_STRING, &xkb_names.rules },
2728                 { "keymap_model", CONFIG_KEY_STRING, &xkb_names.model },
2729                 { "keymap_layout", CONFIG_KEY_STRING, &xkb_names.layout },
2730                 { "keymap_variant", CONFIG_KEY_STRING, &xkb_names.variant },
2731                 { "keymap_options", CONFIG_KEY_STRING, &xkb_names.options },
2732         };
2733         const struct config_section cs[] = {
2734                 { "keyboard",
2735                   keyboard_config_keys, ARRAY_LENGTH(keyboard_config_keys) },
2736         };
2737
2738         memset(&xkb_names, 0, sizeof(xkb_names));
2739         parse_config_file(config_file, cs, ARRAY_LENGTH(cs), ec);
2740
2741         ec->wl_display = display;
2742         wl_signal_init(&ec->destroy_signal);
2743         wl_signal_init(&ec->activate_signal);
2744         wl_signal_init(&ec->lock_signal);
2745         wl_signal_init(&ec->unlock_signal);
2746         wl_signal_init(&ec->show_input_panel_signal);
2747         wl_signal_init(&ec->hide_input_panel_signal);
2748         ec->launcher_sock = weston_environment_get_fd("WESTON_LAUNCHER_SOCK");
2749
2750         ec->output_id_pool = 0;
2751
2752         if (!wl_display_add_global(display, &wl_compositor_interface,
2753                                    ec, compositor_bind))
2754                 return -1;
2755
2756         wl_list_init(&ec->surface_list);
2757         wl_list_init(&ec->layer_list);
2758         wl_list_init(&ec->seat_list);
2759         wl_list_init(&ec->output_list);
2760         wl_list_init(&ec->key_binding_list);
2761         wl_list_init(&ec->button_binding_list);
2762         wl_list_init(&ec->axis_binding_list);
2763         wl_list_init(&ec->fade.animation.link);
2764
2765         weston_plane_init(&ec->primary_plane, 0, 0);
2766
2767         weston_compositor_xkb_init(ec, &xkb_names);
2768
2769         ec->ping_handler = NULL;
2770
2771         screenshooter_create(ec);
2772         text_cursor_position_notifier_create(ec);
2773
2774         wl_data_device_manager_init(ec->wl_display);
2775
2776         wl_display_init_shm(display);
2777
2778         loop = wl_display_get_event_loop(ec->wl_display);
2779         ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
2780         wl_event_source_timer_update(ec->idle_source, ec->idle_time * 1000);
2781
2782         ec->input_loop = wl_event_loop_create();
2783
2784         weston_spring_init(&ec->fade.spring, 30.0, 1.0, 1.0);
2785         ec->fade.animation.frame = fade_frame;
2786
2787         weston_layer_init(&ec->fade_layer, &ec->layer_list);
2788         weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
2789
2790         weston_compositor_schedule_repaint(ec);
2791
2792         return 0;
2793 }
2794
2795 WL_EXPORT void
2796 weston_compositor_shutdown(struct weston_compositor *ec)
2797 {
2798         struct weston_output *output, *next;
2799
2800         wl_event_source_remove(ec->idle_source);
2801         if (ec->input_loop_source)
2802                 wl_event_source_remove(ec->input_loop_source);
2803
2804         /* Destroy all outputs associated with this compositor */
2805         wl_list_for_each_safe(output, next, &ec->output_list, link)
2806                 output->destroy(output);
2807
2808         weston_binding_list_destroy_all(&ec->key_binding_list);
2809         weston_binding_list_destroy_all(&ec->button_binding_list);
2810         weston_binding_list_destroy_all(&ec->axis_binding_list);
2811
2812         weston_plane_release(&ec->primary_plane);
2813
2814         wl_array_release(&ec->vertices);
2815         wl_array_release(&ec->indices);
2816         wl_array_release(&ec->vtxcnt);
2817
2818         wl_event_loop_destroy(ec->input_loop);
2819 }
2820
2821 static int on_term_signal(int signal_number, void *data)
2822 {
2823         struct wl_display *display = data;
2824
2825         weston_log("caught signal %d\n", signal_number);
2826         wl_display_terminate(display);
2827
2828         return 1;
2829 }
2830
2831 static void
2832 on_segv_signal(int s, siginfo_t *siginfo, void *context)
2833 {
2834         void *buffer[32];
2835         int i, count;
2836         Dl_info info;
2837
2838         /* This SIGSEGV handler will do a best-effort backtrace, and
2839          * then call the backend restore function, which will switch
2840          * back to the vt we launched from or ungrab X etc and then
2841          * raise SIGTRAP.  If we run weston under gdb from X or a
2842          * different vt, and tell gdb "handle SIGSEGV nostop", this
2843          * will allow weston to switch back to gdb on crash and then
2844          * gdb will catch the crash with SIGTRAP. */
2845
2846         weston_log("caught segv\n");
2847
2848         count = backtrace(buffer, ARRAY_LENGTH(buffer));
2849         for (i = 0; i < count; i++) {
2850                 dladdr(buffer[i], &info);
2851                 weston_log("  [%016lx]  %s  (%s)\n",
2852                         (long) buffer[i],
2853                         info.dli_sname ? info.dli_sname : "--",
2854                         info.dli_fname);
2855         }
2856
2857         segv_compositor->restore(segv_compositor);
2858
2859         raise(SIGTRAP);
2860 }
2861
2862
2863 static void *
2864 load_module(const char *name, const char *entrypoint)
2865 {
2866         char path[PATH_MAX];
2867         void *module, *init;
2868
2869         if (name[0] != '/')
2870                 snprintf(path, sizeof path, "%s/%s", MODULEDIR, name);
2871         else
2872                 snprintf(path, sizeof path, "%s", name);
2873
2874         module = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
2875         if (module) {
2876                 weston_log("Module '%s' already loaded\n", path);
2877                 dlclose(module);
2878                 return NULL;
2879         }
2880
2881         weston_log("Loading module '%s'\n", path);
2882         module = dlopen(path, RTLD_NOW);
2883         if (!module) {
2884                 weston_log("Failed to load module: %s\n", dlerror());
2885                 return NULL;
2886         }
2887
2888         init = dlsym(module, entrypoint);
2889         if (!init) {
2890                 weston_log("Failed to lookup init function: %s\n", dlerror());
2891                 return NULL;
2892         }
2893
2894         return init;
2895 }
2896
2897 static int
2898 load_modules(struct weston_compositor *ec, const char *modules)
2899 {
2900         const char *p, *end;
2901         char buffer[256];
2902         int (*module_init)(struct weston_compositor *ec);
2903
2904         if (modules == NULL)
2905                 return 0;
2906
2907         p = modules;
2908         while (*p) {
2909                 end = strchrnul(p, ',');
2910                 snprintf(buffer, sizeof buffer, "%.*s", (int) (end - p), p);
2911                 module_init = load_module(buffer, "module_init");
2912                 if (module_init)
2913                         module_init(ec);
2914                 p = end;
2915                 while (*p == ',')
2916                         p++;
2917
2918         }
2919
2920         return 0;
2921 }
2922
2923 static const char xdg_error_message[] =
2924         "fatal: environment variable XDG_RUNTIME_DIR is not set.\n";
2925
2926 static const char xdg_wrong_message[] =
2927         "fatal: environment variable XDG_RUNTIME_DIR\n"
2928         "is set to \"%s\", which is not a directory.\n";
2929
2930 static const char xdg_wrong_mode_message[] =
2931         "warning: XDG_RUNTIME_DIR \"%s\" is not configured\n"
2932         "correctly.  Unix access mode must be 0700 but is %o,\n"
2933         "and XDG_RUNTIME_DIR must be owned by the user, but is\n"
2934         "owned by UID %d.\n";
2935
2936 static const char xdg_detail_message[] =
2937         "Refer to your distribution on how to get it, or\n"
2938         "http://www.freedesktop.org/wiki/Specifications/basedir-spec\n"
2939         "on how to implement it.\n";
2940
2941 static void
2942 verify_xdg_runtime_dir(void)
2943 {
2944         char *dir = getenv("XDG_RUNTIME_DIR");
2945         struct stat s;
2946
2947         if (!dir) {
2948                 weston_log(xdg_error_message);
2949                 weston_log_continue(xdg_detail_message);
2950                 exit(EXIT_FAILURE);
2951         }
2952
2953         if (stat(dir, &s) || !S_ISDIR(s.st_mode)) {
2954                 weston_log(xdg_wrong_message, dir);
2955                 weston_log_continue(xdg_detail_message);
2956                 exit(EXIT_FAILURE);
2957         }
2958
2959         if ((s.st_mode & 0777) != 0700 || s.st_uid != getuid()) {
2960                 weston_log(xdg_wrong_mode_message,
2961                            dir, s.st_mode & 0777, s.st_uid);
2962                 weston_log_continue(xdg_detail_message);
2963         }
2964 }
2965
2966 static int
2967 usage(int error_code)
2968 {
2969         fprintf(stderr,
2970                 "Usage: weston [OPTIONS]\n\n"
2971                 "This is weston version " VERSION ", the Wayland reference compositor.\n"
2972                 "Weston supports multiple backends, and depending on which backend is in use\n"
2973                 "different options will be accepted.\n\n"
2974
2975
2976                 "Core options:\n\n"
2977                 "  -B, --backend=MODULE\tBackend module, one of drm-backend.so,\n"
2978                 "\t\t\t\tx11-backend.so or wayland-backend.so\n"
2979                 "  -S, --socket=NAME\tName of socket to listen on\n"
2980                 "  -i, --idle-time=SECS\tIdle time in seconds\n"
2981                 "  --modules\t\tLoad the comma-separated list of modules\n"
2982                 "  --log==FILE\t\tLog to the given file\n"
2983                 "  -h, --help\t\tThis help message\n\n");
2984
2985         fprintf(stderr,
2986                 "Options for drm-backend.so:\n\n"
2987                 "  --connector=ID\tBring up only this connector\n"
2988                 "  --seat=SEAT\t\tThe seat that weston should run on\n"
2989                 "  --tty=TTY\t\tThe tty to use\n"
2990                 "  --current-mode\tPrefer current KMS mode over EDID preferred mode\n\n");
2991
2992         fprintf(stderr,
2993                 "Options for x11-backend.so:\n\n"
2994                 "  --width=WIDTH\t\tWidth of X window\n"
2995                 "  --height=HEIGHT\tHeight of X window\n"
2996                 "  --fullscreen\t\tRun in fullscreen mode\n"
2997                 "  --output-count=COUNT\tCreate multiple outputs\n"
2998                 "  --no-input\t\tDont create input devices\n\n");
2999
3000         fprintf(stderr,
3001                 "Options for wayland-backend.so:\n\n"
3002                 "  --width=WIDTH\t\tWidth of Wayland surface\n"
3003                 "  --height=HEIGHT\tHeight of Wayland surface\n"
3004                 "  --display=DISPLAY\tWayland display to connect to\n\n");
3005
3006         exit(error_code);
3007 }
3008
3009 int main(int argc, char *argv[])
3010 {
3011         int ret = EXIT_SUCCESS;
3012         struct wl_display *display;
3013         struct weston_compositor *ec;
3014         struct wl_event_source *signals[4];
3015         struct wl_event_loop *loop;
3016         struct sigaction segv_action;
3017         struct weston_compositor
3018                 *(*backend_init)(struct wl_display *display,
3019                                  int argc, char *argv[], const char *config_file);
3020         int i;
3021         char *backend = NULL;
3022         const char *modules = "desktop-shell.so", *option_modules = NULL;
3023         char *log = NULL;
3024         int32_t idle_time = 300;
3025         int32_t help = 0;
3026         char *socket_name = "wayland-0";
3027         char *config_file;
3028
3029         const struct config_key core_config_keys[] = {
3030                 { "modules", CONFIG_KEY_STRING, &modules },
3031         };
3032
3033         const struct config_section cs[] = {
3034                 { "core",
3035                   core_config_keys, ARRAY_LENGTH(core_config_keys) },
3036         };
3037
3038         const struct weston_option core_options[] = {
3039                 { WESTON_OPTION_STRING, "backend", 'B', &backend },
3040                 { WESTON_OPTION_STRING, "socket", 'S', &socket_name },
3041                 { WESTON_OPTION_INTEGER, "idle-time", 'i', &idle_time },
3042                 { WESTON_OPTION_STRING, "modules", 0, &option_modules },
3043                 { WESTON_OPTION_STRING, "log", 0, &log },
3044                 { WESTON_OPTION_BOOLEAN, "help", 'h', &help },
3045         };
3046
3047         argc = parse_options(core_options,
3048                              ARRAY_LENGTH(core_options), argc, argv);
3049
3050         if (help)
3051                 usage(EXIT_SUCCESS);
3052
3053         weston_log_file_open(log);
3054         
3055         weston_log("%s\n"
3056                    STAMP_SPACE "%s\n"
3057                    STAMP_SPACE "Bug reports to: %s\n"
3058                    STAMP_SPACE "Build: %s\n",
3059                    PACKAGE_STRING, PACKAGE_URL, PACKAGE_BUGREPORT,
3060                    BUILD_ID);
3061         log_uname();
3062
3063         verify_xdg_runtime_dir();
3064
3065         display = wl_display_create();
3066
3067         loop = wl_display_get_event_loop(display);
3068         signals[0] = wl_event_loop_add_signal(loop, SIGTERM, on_term_signal,
3069                                               display);
3070         signals[1] = wl_event_loop_add_signal(loop, SIGINT, on_term_signal,
3071                                               display);
3072         signals[2] = wl_event_loop_add_signal(loop, SIGQUIT, on_term_signal,
3073                                               display);
3074
3075         wl_list_init(&child_process_list);
3076         signals[3] = wl_event_loop_add_signal(loop, SIGCHLD, sigchld_handler,
3077                                               NULL);
3078
3079         if (!backend) {
3080                 if (getenv("WAYLAND_DISPLAY"))
3081                         backend = "wayland-backend.so";
3082                 else if (getenv("DISPLAY"))
3083                         backend = "x11-backend.so";
3084                 else
3085                         backend = "drm-backend.so";
3086         }
3087
3088         config_file = config_file_path("weston.ini");
3089         parse_config_file(config_file, cs, ARRAY_LENGTH(cs), NULL);
3090
3091         backend_init = load_module(backend, "backend_init");
3092         if (!backend_init)
3093                 exit(EXIT_FAILURE);
3094
3095         ec = backend_init(display, argc, argv, config_file);
3096         if (ec == NULL) {
3097                 weston_log("fatal: failed to create compositor\n");
3098                 exit(EXIT_FAILURE);
3099         }
3100
3101         segv_action.sa_flags = SA_SIGINFO | SA_RESETHAND;
3102         segv_action.sa_sigaction = on_segv_signal;
3103         sigemptyset(&segv_action.sa_mask);
3104         sigaction(SIGSEGV, &segv_action, NULL);
3105         segv_compositor = ec;
3106
3107         for (i = 1; argv[i]; i++)
3108                 weston_log("fatal: unhandled option: %s\n", argv[i]);
3109         if (argv[1]) {
3110                 ret = EXIT_FAILURE;
3111                 goto out;
3112         }
3113
3114         free(config_file);
3115
3116         ec->option_idle_time = idle_time;
3117         ec->idle_time = idle_time;
3118
3119         setenv("WAYLAND_DISPLAY", socket_name, 1);
3120
3121         if (load_modules(ec, modules) < 0)
3122                 goto out;
3123         if (load_modules(ec, option_modules) < 0)
3124                 goto out;
3125
3126         if (wl_display_add_socket(display, socket_name)) {
3127                 weston_log("fatal: failed to add socket: %m\n");
3128                 ret = EXIT_FAILURE;
3129                 goto out;
3130         }
3131
3132         weston_compositor_dpms_on(ec);
3133         weston_compositor_wake(ec);
3134
3135         wl_display_run(display);
3136
3137  out:
3138         /* prevent further rendering while shutting down */
3139         ec->state = WESTON_COMPOSITOR_SLEEPING;
3140
3141         wl_signal_emit(&ec->destroy_signal, ec);
3142
3143         for (i = ARRAY_LENGTH(signals); i;)
3144                 wl_event_source_remove(signals[--i]);
3145
3146         weston_compositor_xkb_destroy(ec);
3147
3148         ec->destroy(ec);
3149         wl_display_destroy(display);
3150
3151         weston_log_file_close();
3152
3153         return ret;
3154 }