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