toytoolkit: Process deferred tasks on fifo order instead
[profile/ivi/weston-ivi-shell.git] / clients / window.c
1 /*
2  * Copyright © 2008 Kristian Høgsberg
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  The copyright holders make no representations
11  * about the suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22
23 #define _GNU_SOURCE
24
25 #include "../config.h"
26
27 #include <stdint.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <fcntl.h>
32 #include <unistd.h>
33 #include <math.h>
34 #include <assert.h>
35 #include <time.h>
36 #include <cairo.h>
37 #include <sys/mman.h>
38 #include <sys/epoll.h>
39 #include <sys/timerfd.h>
40
41 #include <pixman.h>
42
43 #include <wayland-egl.h>
44
45 #ifdef USE_CAIRO_GLESV2
46 #include <GLES2/gl2.h>
47 #include <GLES2/gl2ext.h>
48 #else
49 #include <GL/gl.h>
50 #endif
51 #include <EGL/egl.h>
52 #include <EGL/eglext.h>
53
54 #ifdef HAVE_CAIRO_EGL
55 #include <cairo-gl.h>
56 #endif
57
58 #include <xkbcommon/xkbcommon.h>
59 #include <wayland-cursor.h>
60
61 #include <linux/input.h>
62 #include <wayland-client.h>
63 #include "../shared/cairo-util.h"
64 #include "text-cursor-position-client-protocol.h"
65 #include "workspaces-client-protocol.h"
66 #include "../shared/os-compatibility.h"
67
68 #include "window.h"
69
70 struct shm_pool;
71
72 struct display {
73         struct wl_display *display;
74         struct wl_compositor *compositor;
75         struct wl_shell *shell;
76         struct wl_shm *shm;
77         struct wl_data_device_manager *data_device_manager;
78         struct text_cursor_position *text_cursor_position;
79         struct workspace_manager *workspace_manager;
80         EGLDisplay dpy;
81         EGLConfig argb_config;
82         EGLContext argb_ctx;
83         cairo_device_t *argb_device;
84         uint32_t serial;
85
86         int display_fd;
87         uint32_t mask;
88         struct task display_task;
89
90         int epoll_fd;
91         struct wl_list deferred_list;
92
93         int running;
94
95         struct wl_list window_list;
96         struct wl_list input_list;
97         struct wl_list output_list;
98
99         struct theme *theme;
100
101         struct wl_cursor_theme *cursor_theme;
102         struct wl_cursor **cursors;
103
104         PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d;
105         PFNEGLCREATEIMAGEKHRPROC create_image;
106         PFNEGLDESTROYIMAGEKHRPROC destroy_image;
107
108         display_output_handler_t output_configure_handler;
109
110         void *user_data;
111
112         struct xkb_context *xkb_context;
113
114         uint32_t workspace;
115         uint32_t workspace_count;
116 };
117
118 enum {
119         TYPE_NONE,
120         TYPE_TOPLEVEL,
121         TYPE_FULLSCREEN,
122         TYPE_MAXIMIZED,
123         TYPE_TRANSIENT,
124         TYPE_MENU,
125         TYPE_CUSTOM
126 };
127
128 struct window_output {
129         struct output *output;
130         struct wl_list link;
131 };
132
133 struct window {
134         struct display *display;
135         struct window *parent;
136         struct wl_list window_output_list;
137         struct wl_surface *surface;
138         struct wl_shell_surface *shell_surface;
139         struct wl_region *input_region;
140         struct wl_region *opaque_region;
141         char *title;
142         struct rectangle allocation, saved_allocation, server_allocation;
143         struct rectangle min_allocation;
144         struct rectangle pending_allocation;
145         int x, y;
146         int resize_edges;
147         int redraw_scheduled;
148         int redraw_needed;
149         struct task redraw_task;
150         int resize_needed;
151         int type;
152         int transparent;
153         int focus_count;
154
155         enum window_buffer_type buffer_type;
156
157         cairo_surface_t *cairo_surface;
158
159         struct shm_pool *pool;
160
161         window_key_handler_t key_handler;
162         window_keyboard_focus_handler_t keyboard_focus_handler;
163         window_data_handler_t data_handler;
164         window_drop_handler_t drop_handler;
165         window_close_handler_t close_handler;
166         window_fullscreen_handler_t fullscreen_handler;
167
168         struct wl_callback *frame_cb;
169
170         struct frame *frame;
171         struct widget *widget;
172
173         void *user_data;
174         struct wl_list link;
175 };
176
177 struct widget {
178         struct window *window;
179         struct tooltip *tooltip;
180         struct wl_list child_list;
181         struct wl_list link;
182         struct rectangle allocation;
183         widget_resize_handler_t resize_handler;
184         widget_redraw_handler_t redraw_handler;
185         widget_enter_handler_t enter_handler;
186         widget_leave_handler_t leave_handler;
187         widget_motion_handler_t motion_handler;
188         widget_button_handler_t button_handler;
189         widget_axis_handler_t axis_handler;
190         void *user_data;
191         int opaque;
192         int tooltip_count;
193 };
194
195 struct input {
196         struct display *display;
197         struct wl_seat *seat;
198         struct wl_pointer *pointer;
199         struct wl_keyboard *keyboard;
200         struct window *pointer_focus;
201         struct window *keyboard_focus;
202         int current_cursor;
203         uint32_t cursor_anim_start;
204         struct wl_callback *cursor_frame_cb;
205         struct wl_surface *pointer_surface;
206         uint32_t modifiers;
207         uint32_t pointer_enter_serial;
208         uint32_t cursor_serial;
209         float sx, sy;
210         struct wl_list link;
211
212         struct widget *focus_widget;
213         struct widget *grab;
214         uint32_t grab_button;
215
216         struct wl_data_device *data_device;
217         struct data_offer *drag_offer;
218         struct data_offer *selection_offer;
219
220         struct {
221                 struct xkb_keymap *keymap;
222                 struct xkb_state *state;
223                 xkb_mod_mask_t control_mask;
224                 xkb_mod_mask_t alt_mask;
225                 xkb_mod_mask_t shift_mask;
226         } xkb;
227
228         struct task repeat_task;
229         int repeat_timer_fd;
230         uint32_t repeat_sym;
231         uint32_t repeat_key;
232         uint32_t repeat_time;
233 };
234
235 struct output {
236         struct display *display;
237         struct wl_output *output;
238         struct rectangle allocation;
239         struct wl_list link;
240
241         display_output_handler_t destroy_handler;
242         void *user_data;
243 };
244
245 enum frame_button_action {
246         FRAME_BUTTON_NULL = 0,
247         FRAME_BUTTON_ICON = 1,
248         FRAME_BUTTON_CLOSE = 2,
249         FRAME_BUTTON_MINIMIZE = 3,
250         FRAME_BUTTON_MAXIMIZE = 4,
251 };
252
253 enum frame_button_pointer {
254         FRAME_BUTTON_DEFAULT = 0,
255         FRAME_BUTTON_OVER = 1,
256         FRAME_BUTTON_ACTIVE = 2,
257 };
258
259 enum frame_button_align {
260         FRAME_BUTTON_RIGHT = 0,
261         FRAME_BUTTON_LEFT = 1,
262 };
263
264 enum frame_button_decoration {
265         FRAME_BUTTON_NONE = 0,
266         FRAME_BUTTON_FANCY = 1,
267 };
268
269 struct frame_button {
270         struct widget *widget;
271         struct frame *frame;
272         cairo_surface_t *icon;
273         enum frame_button_action type;
274         enum frame_button_pointer state;
275         struct wl_list link;    /* buttons_list */
276         enum frame_button_align align;
277         enum frame_button_decoration decoration;
278 };
279
280 struct frame {
281         struct widget *widget;
282         struct widget *child;
283         struct wl_list buttons_list;
284 };
285
286 struct menu {
287         struct window *window;
288         struct widget *widget;
289         struct input *input;
290         const char **entries;
291         uint32_t time;
292         int current;
293         int count;
294         menu_func_t func;
295 };
296
297 struct tooltip {
298         struct widget *parent;
299         struct window *window;
300         struct widget *widget;
301         char *entry;
302         struct task tooltip_task;
303         int tooltip_fd;
304         float x, y;
305 };
306
307 struct shm_pool {
308         struct wl_shm_pool *pool;
309         size_t size;
310         size_t used;
311         void *data;
312 };
313
314 enum {
315         CURSOR_DEFAULT = 100,
316         CURSOR_UNSET
317 };
318
319 enum window_location {
320         WINDOW_INTERIOR = 0,
321         WINDOW_RESIZING_TOP = 1,
322         WINDOW_RESIZING_BOTTOM = 2,
323         WINDOW_RESIZING_LEFT = 4,
324         WINDOW_RESIZING_TOP_LEFT = 5,
325         WINDOW_RESIZING_BOTTOM_LEFT = 6,
326         WINDOW_RESIZING_RIGHT = 8,
327         WINDOW_RESIZING_TOP_RIGHT = 9,
328         WINDOW_RESIZING_BOTTOM_RIGHT = 10,
329         WINDOW_RESIZING_MASK = 15,
330         WINDOW_EXTERIOR = 16,
331         WINDOW_TITLEBAR = 17,
332         WINDOW_CLIENT_AREA = 18,
333 };
334
335 static const cairo_user_data_key_t surface_data_key;
336 struct surface_data {
337         struct wl_buffer *buffer;
338 };
339
340 #define MULT(_d,c,a,t) \
341         do { t = c * a + 0x7f; _d = ((t >> 8) + t) >> 8; } while (0)
342
343 #ifdef HAVE_CAIRO_EGL
344
345 struct egl_window_surface_data {
346         struct display *display;
347         struct wl_surface *surface;
348         struct wl_egl_window *window;
349         EGLSurface surf;
350 };
351
352 static void
353 egl_window_surface_data_destroy(void *p)
354 {
355         struct egl_window_surface_data *data = p;
356         struct display *d = data->display;
357
358         eglDestroySurface(d->dpy, data->surf);
359         wl_egl_window_destroy(data->window);
360         data->surface = NULL;
361
362         free(p);
363 }
364
365 static cairo_surface_t *
366 display_create_egl_window_surface(struct display *display,
367                                   struct wl_surface *surface,
368                                   uint32_t flags,
369                                   struct rectangle *rectangle)
370 {
371         cairo_surface_t *cairo_surface;
372         struct egl_window_surface_data *data;
373         EGLConfig config;
374         cairo_device_t *device;
375
376         data = malloc(sizeof *data);
377         if (data == NULL)
378                 return NULL;
379
380         data->display = display;
381         data->surface = surface;
382
383         config = display->argb_config;
384         device = display->argb_device;
385
386         data->window = wl_egl_window_create(surface,
387                                             rectangle->width,
388                                             rectangle->height);
389
390         data->surf = eglCreateWindowSurface(display->dpy, config,
391                                             data->window, NULL);
392
393         cairo_surface = cairo_gl_surface_create_for_egl(device,
394                                                         data->surf,
395                                                         rectangle->width,
396                                                         rectangle->height);
397
398         cairo_surface_set_user_data(cairo_surface, &surface_data_key,
399                                     data, egl_window_surface_data_destroy);
400
401         return cairo_surface;
402 }
403
404 #endif
405
406 struct wl_buffer *
407 display_get_buffer_for_surface(struct display *display,
408                                cairo_surface_t *surface)
409 {
410         struct surface_data *data;
411
412         data = cairo_surface_get_user_data (surface, &surface_data_key);
413
414         return data->buffer;
415 }
416
417 struct shm_surface_data {
418         struct surface_data data;
419         struct shm_pool *pool;
420 };
421
422 static void
423 shm_pool_destroy(struct shm_pool *pool);
424
425 static void
426 shm_surface_data_destroy(void *p)
427 {
428         struct shm_surface_data *data = p;
429
430         wl_buffer_destroy(data->data.buffer);
431         if (data->pool)
432                 shm_pool_destroy(data->pool);
433
434         free(data);
435 }
436
437 static struct wl_shm_pool *
438 make_shm_pool(struct display *display, int size, void **data)
439 {
440         struct wl_shm_pool *pool;
441         int fd;
442
443         fd = os_create_anonymous_file(size);
444         if (fd < 0) {
445                 fprintf(stderr, "creating a buffer file for %d B failed: %m\n",
446                         size);
447                 return NULL;
448         }
449
450         *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
451         if (*data == MAP_FAILED) {
452                 fprintf(stderr, "mmap failed: %m\n");
453                 close(fd);
454                 return NULL;
455         }
456
457         pool = wl_shm_create_pool(display->shm, fd, size);
458
459         close(fd);
460
461         return pool;
462 }
463
464 static struct shm_pool *
465 shm_pool_create(struct display *display, size_t size)
466 {
467         struct shm_pool *pool = malloc(sizeof *pool);
468
469         if (!pool)
470                 return NULL;
471
472         pool->pool = make_shm_pool(display, size, &pool->data);
473         if (!pool->pool) {
474                 free(pool);
475                 return NULL;
476         }
477
478         pool->size = size;
479         pool->used = 0;
480
481         return pool;
482 }
483
484 static void *
485 shm_pool_allocate(struct shm_pool *pool, size_t size, int *offset)
486 {
487         if (pool->used + size > pool->size)
488                 return NULL;
489
490         *offset = pool->used;
491         pool->used += size;
492
493         return (char *) pool->data + *offset;
494 }
495
496 /* destroy the pool. this does not unmap the memory though */
497 static void
498 shm_pool_destroy(struct shm_pool *pool)
499 {
500         munmap(pool->data, pool->size);
501         wl_shm_pool_destroy(pool->pool);
502         free(pool);
503 }
504
505 /* Start allocating from the beginning of the pool again */
506 static void
507 shm_pool_reset(struct shm_pool *pool)
508 {
509         pool->used = 0;
510 }
511
512 static int
513 data_length_for_shm_surface(struct rectangle *rect)
514 {
515         int stride;
516
517         stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,
518                                                 rect->width);
519         return stride * rect->height;
520 }
521
522 static cairo_surface_t *
523 display_create_shm_surface_from_pool(struct display *display,
524                                      struct rectangle *rectangle,
525                                      uint32_t flags, struct shm_pool *pool)
526 {
527         struct shm_surface_data *data;
528         uint32_t format;
529         cairo_surface_t *surface;
530         int stride, length, offset;
531         void *map;
532
533         data = malloc(sizeof *data);
534         if (data == NULL)
535                 return NULL;
536
537         stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,
538                                                 rectangle->width);
539         length = stride * rectangle->height;
540         data->pool = NULL;
541         map = shm_pool_allocate(pool, length, &offset);
542
543         if (!map) {
544                 free(data);
545                 return NULL;
546         }
547
548         surface = cairo_image_surface_create_for_data (map,
549                                                        CAIRO_FORMAT_ARGB32,
550                                                        rectangle->width,
551                                                        rectangle->height,
552                                                        stride);
553
554         cairo_surface_set_user_data (surface, &surface_data_key,
555                                      data, shm_surface_data_destroy);
556
557         if (flags & SURFACE_OPAQUE)
558                 format = WL_SHM_FORMAT_XRGB8888;
559         else
560                 format = WL_SHM_FORMAT_ARGB8888;
561
562         data->data.buffer = wl_shm_pool_create_buffer(pool->pool, offset,
563                                                       rectangle->width,
564                                                       rectangle->height,
565                                                       stride, format);
566
567         return surface;
568 }
569
570 static cairo_surface_t *
571 display_create_shm_surface(struct display *display,
572                            struct rectangle *rectangle, uint32_t flags,
573                            struct window *window)
574 {
575         struct shm_surface_data *data;
576         struct shm_pool *pool;
577         cairo_surface_t *surface;
578
579         if (window && window->pool) {
580                 shm_pool_reset(window->pool);
581                 surface = display_create_shm_surface_from_pool(display,
582                                                                rectangle,
583                                                                flags,
584                                                                window->pool);
585                 if (surface)
586                         return surface;
587         }
588
589         pool = shm_pool_create(display,
590                                data_length_for_shm_surface(rectangle));
591         if (!pool)
592                 return NULL;
593
594         surface =
595                 display_create_shm_surface_from_pool(display, rectangle,
596                                                      flags, pool);
597
598         if (!surface) {
599                 shm_pool_destroy(pool);
600                 return NULL;
601         }
602
603         /* make sure we destroy the pool when the surface is destroyed */
604         data = cairo_surface_get_user_data(surface, &surface_data_key);
605         data->pool = pool;
606
607         return surface;
608 }
609
610 static int
611 check_size(struct rectangle *rect)
612 {
613         if (rect->width && rect->height)
614                 return 0;
615
616         fprintf(stderr, "tried to create surface of "
617                 "width: %d, height: %d\n", rect->width, rect->height);
618         return -1;
619 }
620
621 cairo_surface_t *
622 display_create_surface(struct display *display,
623                        struct wl_surface *surface,
624                        struct rectangle *rectangle,
625                        uint32_t flags)
626 {
627         if (check_size(rectangle) < 0)
628                 return NULL;
629 #ifdef HAVE_CAIRO_EGL
630         if (display->dpy && !(flags & SURFACE_SHM))
631                 return display_create_egl_window_surface(display,
632                                                          surface,
633                                                          flags,
634                                                          rectangle);
635 #endif
636         return display_create_shm_surface(display, rectangle, flags, NULL);
637 }
638
639 /*
640  * The following correspondences between file names and cursors was copied
641  * from: https://bugs.kde.org/attachment.cgi?id=67313
642  */
643
644 static const char *bottom_left_corners[] = {
645         "bottom_left_corner",
646         "sw-resize"
647 };
648
649 static const char *bottom_right_corners[] = {
650         "bottom_right_corner",
651         "se-resize"
652 };
653
654 static const char *bottom_sides[] = {
655         "bottom_side",
656         "s-resize"
657 };
658
659 static const char *grabbings[] = {
660         "grabbing",
661         "closedhand",
662         "208530c400c041818281048008011002"
663 };
664
665 static const char *left_ptrs[] = {
666         "left_ptr",
667         "default",
668         "top_left_arrow",
669         "left-arrow"
670 };
671
672 static const char *left_sides[] = {
673         "left_side",
674         "w-resize"
675 };
676
677 static const char *right_sides[] = {
678         "right_side",
679         "e-resize"
680 };
681
682 static const char *top_left_corners[] = {
683         "top_left_corner",
684         "nw-resize"
685 };
686
687 static const char *top_right_corners[] = {
688         "top_right_corner",
689         "ne-resize"
690 };
691
692 static const char *top_sides[] = {
693         "top_side",
694         "n-resize"
695 };
696
697 static const char *xterms[] = {
698         "xterm",
699         "ibeam",
700         "text"
701 };
702
703 static const char *hand1s[] = {
704         "hand1",
705         "pointer",
706         "pointing_hand",
707         "e29285e634086352946a0e7090d73106"
708 };
709
710 static const char *watches[] = {
711         "watch",
712         "wait",
713         "0426c94ea35c87780ff01dc239897213"
714 };
715
716 struct cursor_alternatives {
717         const char **names;
718         size_t count;
719 };
720
721 static const struct cursor_alternatives cursors[] = {
722         {bottom_left_corners, ARRAY_LENGTH(bottom_left_corners)},
723         {bottom_right_corners, ARRAY_LENGTH(bottom_right_corners)},
724         {bottom_sides, ARRAY_LENGTH(bottom_sides)},
725         {grabbings, ARRAY_LENGTH(grabbings)},
726         {left_ptrs, ARRAY_LENGTH(left_ptrs)},
727         {left_sides, ARRAY_LENGTH(left_sides)},
728         {right_sides, ARRAY_LENGTH(right_sides)},
729         {top_left_corners, ARRAY_LENGTH(top_left_corners)},
730         {top_right_corners, ARRAY_LENGTH(top_right_corners)},
731         {top_sides, ARRAY_LENGTH(top_sides)},
732         {xterms, ARRAY_LENGTH(xterms)},
733         {hand1s, ARRAY_LENGTH(hand1s)},
734         {watches, ARRAY_LENGTH(watches)},
735 };
736
737 static void
738 create_cursors(struct display *display)
739 {
740         char *config_file;
741         char *theme = NULL;
742         unsigned int i, j;
743         struct wl_cursor *cursor;
744         struct config_key shell_keys[] = {
745                 { "cursor-theme", CONFIG_KEY_STRING, &theme },
746         };
747         struct config_section cs[] = {
748                 { "shell", shell_keys, ARRAY_LENGTH(shell_keys), NULL },
749         };
750
751         config_file = config_file_path("weston.ini");
752         parse_config_file(config_file, cs, ARRAY_LENGTH(cs), NULL);
753         free(config_file);
754
755         display->cursor_theme = wl_cursor_theme_load(theme, 32, display->shm);
756         display->cursors =
757                 malloc(ARRAY_LENGTH(cursors) * sizeof display->cursors[0]);
758
759         for (i = 0; i < ARRAY_LENGTH(cursors); i++) {
760                 cursor = NULL;
761                 for (j = 0; !cursor && j < cursors[i].count; ++j)
762                         cursor = wl_cursor_theme_get_cursor(
763                             display->cursor_theme, cursors[i].names[j]);
764
765                 if (!cursor)
766                         fprintf(stderr, "could not load cursor '%s'\n",
767                                 cursors[i].names[0]);
768
769                 display->cursors[i] = cursor;
770         }
771 }
772
773 static void
774 destroy_cursors(struct display *display)
775 {
776         wl_cursor_theme_destroy(display->cursor_theme);
777         free(display->cursors);
778 }
779
780 struct wl_cursor_image *
781 display_get_pointer_image(struct display *display, int pointer)
782 {
783         struct wl_cursor *cursor = display->cursors[pointer];
784
785         return cursor ? cursor->images[0] : NULL;
786 }
787
788 static void
789 window_get_resize_dx_dy(struct window *window, int *x, int *y)
790 {
791         if (window->resize_edges & WINDOW_RESIZING_LEFT)
792                 *x = window->server_allocation.width - window->allocation.width;
793         else
794                 *x = 0;
795
796         if (window->resize_edges & WINDOW_RESIZING_TOP)
797                 *y = window->server_allocation.height -
798                         window->allocation.height;
799         else
800                 *y = 0;
801
802         window->resize_edges = 0;
803 }
804
805 static void
806 window_attach_surface(struct window *window)
807 {
808         struct display *display = window->display;
809         struct wl_buffer *buffer;
810 #ifdef HAVE_CAIRO_EGL
811         struct egl_window_surface_data *data;
812 #endif
813         int32_t x, y;
814
815         if (window->type == TYPE_NONE) {
816                 window->type = TYPE_TOPLEVEL;
817                 if (display->shell)
818                         wl_shell_surface_set_toplevel(window->shell_surface);
819         }
820
821         switch (window->buffer_type) {
822 #ifdef HAVE_CAIRO_EGL
823         case WINDOW_BUFFER_TYPE_EGL_WINDOW:
824                 data = cairo_surface_get_user_data(window->cairo_surface,
825                                                    &surface_data_key);
826
827                 cairo_gl_surface_swapbuffers(window->cairo_surface);
828                 wl_egl_window_get_attached_size(data->window,
829                                 &window->server_allocation.width,
830                                 &window->server_allocation.height);
831                 break;
832 #endif
833         case WINDOW_BUFFER_TYPE_SHM:
834                 buffer =
835                         display_get_buffer_for_surface(display,
836                                                        window->cairo_surface);
837
838                 window_get_resize_dx_dy(window, &x, &y);
839                 wl_surface_attach(window->surface, buffer, x, y);
840                 wl_surface_damage(window->surface, 0, 0,
841                                   window->allocation.width,
842                                   window->allocation.height);
843                 window->server_allocation = window->allocation;
844                 cairo_surface_destroy(window->cairo_surface);
845                 window->cairo_surface = NULL;
846                 break;
847         default:
848                 return;
849         }
850
851         if (window->input_region) {
852                 wl_surface_set_input_region(window->surface,
853                                             window->input_region);
854                 wl_region_destroy(window->input_region);
855                 window->input_region = NULL;
856         }
857
858         if (window->opaque_region) {
859                 wl_surface_set_opaque_region(window->surface,
860                                              window->opaque_region);
861                 wl_region_destroy(window->opaque_region);
862                 window->opaque_region = NULL;
863         }
864 }
865
866 int
867 window_has_focus(struct window *window)
868 {
869         return window->focus_count > 0;
870 }
871
872 void
873 window_flush(struct window *window)
874 {
875         if (window->cairo_surface)
876                 window_attach_surface(window);
877 }
878
879 void
880 window_set_surface(struct window *window, cairo_surface_t *surface)
881 {
882         cairo_surface_reference(surface);
883
884         if (window->cairo_surface != NULL)
885                 cairo_surface_destroy(window->cairo_surface);
886
887         window->cairo_surface = surface;
888 }
889
890 #ifdef HAVE_CAIRO_EGL
891 static void
892 window_resize_cairo_window_surface(struct window *window)
893 {
894         struct egl_window_surface_data *data;
895         int x, y;
896
897         data = cairo_surface_get_user_data(window->cairo_surface,
898                                            &surface_data_key);
899
900         window_get_resize_dx_dy(window, &x, &y),
901         wl_egl_window_resize(data->window,
902                              window->allocation.width,
903                              window->allocation.height,
904                              x,y);
905
906         cairo_gl_surface_set_size(window->cairo_surface,
907                                   window->allocation.width,
908                                   window->allocation.height);
909 }
910 #endif
911
912 struct display *
913 window_get_display(struct window *window)
914 {
915         return window->display;
916 }
917
918 void
919 window_create_surface(struct window *window)
920 {
921         cairo_surface_t *surface;
922         uint32_t flags = 0;
923         
924         if (!window->transparent)
925                 flags = SURFACE_OPAQUE;
926         
927         switch (window->buffer_type) {
928 #ifdef HAVE_CAIRO_EGL
929         case WINDOW_BUFFER_TYPE_EGL_WINDOW:
930                 if (window->cairo_surface) {
931                         window_resize_cairo_window_surface(window);
932                         return;
933                 }
934                 surface = display_create_surface(window->display,
935                                                  window->surface,
936                                                  &window->allocation, flags);
937                 break;
938 #endif
939         case WINDOW_BUFFER_TYPE_SHM:
940                 surface = display_create_shm_surface(window->display,
941                                                      &window->allocation,
942                                                      flags, window);
943                 break;
944         default:
945                 surface = NULL;
946                 break;
947         }
948
949         window_set_surface(window, surface);
950         cairo_surface_destroy(surface);
951 }
952
953 static void frame_destroy(struct frame *frame);
954
955 void
956 window_destroy(struct window *window)
957 {
958         struct display *display = window->display;
959         struct input *input;
960         struct window_output *window_output;
961         struct window_output *window_output_tmp;
962
963         if (window->redraw_scheduled)
964                 wl_list_remove(&window->redraw_task.link);
965
966         wl_list_for_each(input, &display->input_list, link) {
967                 if (input->pointer_focus == window)
968                         input->pointer_focus = NULL;
969                 if (input->keyboard_focus == window)
970                         input->keyboard_focus = NULL;
971                 if (input->focus_widget &&
972                     input->focus_widget->window == window)
973                         input->focus_widget = NULL;
974         }
975
976         wl_list_for_each_safe(window_output, window_output_tmp,
977                               &window->window_output_list, link) {
978                 free (window_output);
979         }
980
981         if (window->input_region)
982                 wl_region_destroy(window->input_region);
983         if (window->opaque_region)
984                 wl_region_destroy(window->opaque_region);
985
986         if (window->frame)
987                 frame_destroy(window->frame);
988
989         if (window->shell_surface)
990                 wl_shell_surface_destroy(window->shell_surface);
991         wl_surface_destroy(window->surface);
992         wl_list_remove(&window->link);
993
994         if (window->cairo_surface != NULL)
995                 cairo_surface_destroy(window->cairo_surface);
996
997         if (window->frame_cb)
998                 wl_callback_destroy(window->frame_cb);
999         free(window->title);
1000         free(window);
1001 }
1002
1003 static struct widget *
1004 widget_find_widget(struct widget *widget, int32_t x, int32_t y)
1005 {
1006         struct widget *child, *target;
1007
1008         wl_list_for_each(child, &widget->child_list, link) {
1009                 target = widget_find_widget(child, x, y);
1010                 if (target)
1011                         return target;
1012         }
1013
1014         if (widget->allocation.x <= x &&
1015             x < widget->allocation.x + widget->allocation.width &&
1016             widget->allocation.y <= y &&
1017             y < widget->allocation.y + widget->allocation.height) {
1018                 return widget;
1019         }
1020
1021         return NULL;
1022 }
1023
1024 static struct widget *
1025 widget_create(struct window *window, void *data)
1026 {
1027         struct widget *widget;
1028
1029         widget = malloc(sizeof *widget);
1030         memset(widget, 0, sizeof *widget);
1031         widget->window = window;
1032         widget->user_data = data;
1033         widget->allocation = window->allocation;
1034         wl_list_init(&widget->child_list);
1035         widget->opaque = 0;
1036         widget->tooltip = NULL;
1037         widget->tooltip_count = 0;
1038
1039         return widget;
1040 }
1041
1042 struct widget *
1043 window_add_widget(struct window *window, void *data)
1044 {
1045         window->widget = widget_create(window, data);
1046         wl_list_init(&window->widget->link);
1047
1048         return window->widget;
1049 }
1050
1051 struct widget *
1052 widget_add_widget(struct widget *parent, void *data)
1053 {
1054         struct widget *widget;
1055
1056         widget = widget_create(parent->window, data);
1057         wl_list_insert(parent->child_list.prev, &widget->link);
1058
1059         return widget;
1060 }
1061
1062 void
1063 widget_destroy(struct widget *widget)
1064 {
1065         struct display *display = widget->window->display;
1066         struct input *input;
1067
1068         if (widget->tooltip) {
1069                 free(widget->tooltip);
1070                 widget->tooltip = NULL;
1071         }
1072
1073         wl_list_for_each(input, &display->input_list, link) {
1074                 if (input->focus_widget == widget)
1075                         input->focus_widget = NULL;
1076         }
1077
1078         wl_list_remove(&widget->link);
1079         free(widget);
1080 }
1081
1082 void
1083 widget_get_allocation(struct widget *widget, struct rectangle *allocation)
1084 {
1085         *allocation = widget->allocation;
1086 }
1087
1088 void
1089 widget_set_size(struct widget *widget, int32_t width, int32_t height)
1090 {
1091         widget->allocation.width = width;
1092         widget->allocation.height = height;
1093 }
1094
1095 void
1096 widget_set_allocation(struct widget *widget,
1097                       int32_t x, int32_t y, int32_t width, int32_t height)
1098 {
1099         widget->allocation.x = x;
1100         widget->allocation.y = y;
1101         widget_set_size(widget, width, height);
1102 }
1103
1104 void
1105 widget_set_transparent(struct widget *widget, int transparent)
1106 {
1107         widget->opaque = !transparent;
1108 }
1109
1110 void *
1111 widget_get_user_data(struct widget *widget)
1112 {
1113         return widget->user_data;
1114 }
1115
1116 void
1117 widget_set_resize_handler(struct widget *widget,
1118                           widget_resize_handler_t handler)
1119 {
1120         widget->resize_handler = handler;
1121 }
1122
1123 void
1124 widget_set_redraw_handler(struct widget *widget,
1125                           widget_redraw_handler_t handler)
1126 {
1127         widget->redraw_handler = handler;
1128 }
1129
1130 void
1131 widget_set_enter_handler(struct widget *widget, widget_enter_handler_t handler)
1132 {
1133         widget->enter_handler = handler;
1134 }
1135
1136 void
1137 widget_set_leave_handler(struct widget *widget, widget_leave_handler_t handler)
1138 {
1139         widget->leave_handler = handler;
1140 }
1141
1142 void
1143 widget_set_motion_handler(struct widget *widget,
1144                           widget_motion_handler_t handler)
1145 {
1146         widget->motion_handler = handler;
1147 }
1148
1149 void
1150 widget_set_button_handler(struct widget *widget,
1151                           widget_button_handler_t handler)
1152 {
1153         widget->button_handler = handler;
1154 }
1155
1156 void
1157 widget_set_axis_handler(struct widget *widget,
1158                         widget_axis_handler_t handler)
1159 {
1160         widget->axis_handler = handler;
1161 }
1162
1163 void
1164 widget_schedule_redraw(struct widget *widget)
1165 {
1166         window_schedule_redraw(widget->window);
1167 }
1168
1169 cairo_surface_t *
1170 window_get_surface(struct window *window)
1171 {
1172         return cairo_surface_reference(window->cairo_surface);
1173 }
1174
1175 struct wl_surface *
1176 window_get_wl_surface(struct window *window)
1177 {
1178         return window->surface;
1179 }
1180
1181 struct wl_shell_surface *
1182 window_get_wl_shell_surface(struct window *window)
1183 {
1184         return window->shell_surface;
1185 }
1186
1187 static void
1188 tooltip_redraw_handler(struct widget *widget, void *data)
1189 {
1190         cairo_t *cr;
1191         const int32_t r = 3;
1192         struct tooltip *tooltip = data;
1193         int32_t width, height;
1194         struct window *window = widget->window;
1195
1196         cr = cairo_create(window->cairo_surface);
1197         cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
1198         cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
1199         cairo_paint(cr);
1200
1201         width = window->allocation.width;
1202         height = window->allocation.height;
1203         rounded_rect(cr, 0, 0, width, height, r);
1204
1205         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
1206         cairo_set_source_rgba(cr, 0.0, 0.0, 0.4, 0.8);
1207         cairo_fill(cr);
1208
1209         cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
1210         cairo_move_to(cr, 10, 16);
1211         cairo_show_text(cr, tooltip->entry);
1212         cairo_destroy(cr);
1213 }
1214
1215 static cairo_text_extents_t
1216 get_text_extents(struct tooltip *tooltip)
1217 {
1218         struct window *window;
1219         cairo_t *cr;
1220         cairo_text_extents_t extents;
1221
1222         /* we borrow cairo_surface from the parent cause tooltip's wasn't
1223          * created yet */
1224         window = tooltip->widget->window->parent;
1225         cr = cairo_create(window->cairo_surface);
1226         cairo_text_extents(cr, tooltip->entry, &extents);
1227         cairo_destroy(cr);
1228
1229         return extents;
1230 }
1231
1232 static int
1233 window_create_tooltip(struct tooltip *tooltip)
1234 {
1235         struct widget *parent = tooltip->parent;
1236         struct display *display = parent->window->display;
1237         struct window *window;
1238         const int offset_y = 27;
1239         const int margin = 3;
1240         cairo_text_extents_t extents;
1241
1242         if (tooltip->widget)
1243                 return 0;
1244
1245         window = window_create_transient(display, parent->window, tooltip->x,
1246                                          tooltip->y + offset_y,
1247                                          WL_SHELL_SURFACE_TRANSIENT_INACTIVE);
1248         if (!window)
1249                 return -1;
1250
1251         tooltip->window = window;
1252         tooltip->widget = window_add_widget(tooltip->window, tooltip);
1253
1254         extents = get_text_extents(tooltip);
1255         widget_set_redraw_handler(tooltip->widget, tooltip_redraw_handler);
1256         window_schedule_resize(window, extents.width + 20, 20 + margin * 2);
1257
1258         return 0;
1259 }
1260
1261 void
1262 widget_destroy_tooltip(struct widget *parent)
1263 {
1264         struct tooltip *tooltip = parent->tooltip;
1265
1266         parent->tooltip_count = 0;
1267         if (!tooltip)
1268                 return;
1269
1270         if (tooltip->widget) {
1271                 widget_destroy(tooltip->widget);
1272                 window_destroy(tooltip->window);
1273                 tooltip->widget = NULL;
1274                 tooltip->window = NULL;
1275         }
1276
1277         close(tooltip->tooltip_fd);
1278         free(tooltip->entry);
1279         free(tooltip);
1280         parent->tooltip = NULL;
1281 }
1282
1283 static void
1284 tooltip_func(struct task *task, uint32_t events)
1285 {
1286         struct tooltip *tooltip =
1287                 container_of(task, struct tooltip, tooltip_task);
1288         uint64_t exp;
1289
1290         if (read(tooltip->tooltip_fd, &exp, sizeof (uint64_t)) != sizeof (uint64_t))
1291                 abort();
1292         window_create_tooltip(tooltip);
1293 }
1294
1295 #define TOOLTIP_TIMEOUT 500
1296 static int
1297 tooltip_timer_reset(struct tooltip *tooltip)
1298 {
1299         struct itimerspec its;
1300
1301         its.it_interval.tv_sec = 0;
1302         its.it_interval.tv_nsec = 0;
1303         its.it_value.tv_sec = TOOLTIP_TIMEOUT / 1000;
1304         its.it_value.tv_nsec = (TOOLTIP_TIMEOUT % 1000) * 1000 * 1000;
1305         if (timerfd_settime(tooltip->tooltip_fd, 0, &its, NULL) < 0) {
1306                 fprintf(stderr, "could not set timerfd\n: %m");
1307                 return -1;
1308         }
1309
1310         return 0;
1311 }
1312
1313 int
1314 widget_set_tooltip(struct widget *parent, char *entry, float x, float y)
1315 {
1316         struct tooltip *tooltip = parent->tooltip;
1317
1318         parent->tooltip_count++;
1319         if (tooltip) {
1320                 tooltip->x = x;
1321                 tooltip->y = y;
1322                 tooltip_timer_reset(tooltip);
1323                 return 0;
1324         }
1325
1326         /* the handler might be triggered too fast via input device motion, so
1327          * we need this check here to make sure tooltip is fully initialized */
1328         if (parent->tooltip_count > 1)
1329                 return 0;
1330
1331         tooltip = malloc(sizeof *tooltip);
1332         if (!tooltip)
1333                 return -1;
1334
1335         parent->tooltip = tooltip;
1336         tooltip->parent = parent;
1337         tooltip->widget = NULL;
1338         tooltip->window = NULL;
1339         tooltip->x = x;
1340         tooltip->y = y;
1341         tooltip->entry = strdup(entry);
1342         tooltip->tooltip_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
1343         if (tooltip->tooltip_fd < 0) {
1344                 fprintf(stderr, "could not create timerfd\n: %m");
1345                 return -1;
1346         }
1347
1348         tooltip->tooltip_task.run = tooltip_func;
1349         display_watch_fd(parent->window->display, tooltip->tooltip_fd,
1350                          EPOLLIN, &tooltip->tooltip_task);
1351         tooltip_timer_reset(tooltip);
1352
1353         return 0;
1354 }
1355
1356 static void
1357 workspace_manager_state(void *data,
1358                         struct workspace_manager *workspace_manager,
1359                         uint32_t current,
1360                         uint32_t count)
1361 {
1362         struct display *display = data;
1363
1364         display->workspace = current;
1365         display->workspace_count = count;
1366 }
1367
1368 static const struct workspace_manager_listener workspace_manager_listener = {
1369         workspace_manager_state
1370 };
1371
1372 static void
1373 frame_resize_handler(struct widget *widget,
1374                      int32_t width, int32_t height, void *data)
1375 {
1376         struct frame *frame = data;
1377         struct widget *child = frame->child;
1378         struct rectangle allocation;
1379         struct display *display = widget->window->display;
1380         struct frame_button * button;
1381         struct theme *t = display->theme;
1382         int x_l, x_r, y, w, h;
1383         int decoration_width, decoration_height;
1384         int opaque_margin;
1385
1386         if (widget->window->type != TYPE_FULLSCREEN) {
1387                 decoration_width = (t->width + t->margin) * 2;
1388                 decoration_height = t->width +
1389                         t->titlebar_height + t->margin * 2;
1390
1391                 allocation.x = t->width + t->margin;
1392                 allocation.y = t->titlebar_height + t->margin;
1393                 allocation.width = width - decoration_width;
1394                 allocation.height = height - decoration_height;
1395
1396                 opaque_margin = t->margin + t->frame_radius;
1397
1398                 wl_list_for_each(button, &frame->buttons_list, link)
1399                         button->widget->opaque = 0;
1400         } else {
1401                 decoration_width = 0;
1402                 decoration_height = 0;
1403
1404                 allocation.x = 0;
1405                 allocation.y = 0;
1406                 allocation.width = width;
1407                 allocation.height = height;
1408                 opaque_margin = 0;
1409
1410                 wl_list_for_each(button, &frame->buttons_list, link)
1411                         button->widget->opaque = 1;
1412         }
1413
1414         widget_set_allocation(child, allocation.x, allocation.y,
1415                               allocation.width, allocation.height);
1416
1417         if (child->resize_handler)
1418                 child->resize_handler(child,
1419                                       allocation.width,
1420                                       allocation.height,
1421                                       child->user_data);
1422
1423         width = child->allocation.width + decoration_width;
1424         height = child->allocation.height + decoration_height;
1425
1426         if (widget->window->type != TYPE_FULLSCREEN) {
1427                 widget->window->input_region =
1428                         wl_compositor_create_region(display->compositor);
1429                 wl_region_add(widget->window->input_region,
1430                               t->margin, t->margin,
1431                               width - 2 * t->margin,
1432                               height - 2 * t->margin);
1433         }
1434
1435         widget_set_allocation(widget, 0, 0, width, height);
1436
1437         if (child->opaque) {
1438                 widget->window->opaque_region =
1439                         wl_compositor_create_region(display->compositor);
1440                 wl_region_add(widget->window->opaque_region,
1441                               opaque_margin, opaque_margin,
1442                               widget->allocation.width - 2 * opaque_margin,
1443                               widget->allocation.height - 2 * opaque_margin);
1444         }
1445
1446         /* frame internal buttons */
1447         x_r = frame->widget->allocation.width - t->width - t->margin;
1448         x_l = t->width + t->margin;
1449         y = t->width + t->margin;
1450         wl_list_for_each(button, &frame->buttons_list, link) {
1451                 const int button_padding = 4;
1452                 w = cairo_image_surface_get_width(button->icon);
1453                 h = cairo_image_surface_get_height(button->icon);
1454
1455                 if (button->decoration == FRAME_BUTTON_FANCY)
1456                         w += 10;
1457
1458                 if (button->align == FRAME_BUTTON_LEFT) {
1459                         widget_set_allocation(button->widget,
1460                                               x_l, y , w + 1, h + 1);
1461                         x_l += w;
1462                         x_l += button_padding;
1463                 } else {
1464                         x_r -= w;
1465                         widget_set_allocation(button->widget,
1466                                               x_r, y , w + 1, h + 1);
1467                         x_r -= button_padding;
1468                 }
1469         }
1470 }
1471
1472 static int
1473 frame_button_enter_handler(struct widget *widget,
1474                            struct input *input, float x, float y, void *data)
1475 {
1476         struct frame_button *frame_button = data;
1477
1478         widget_schedule_redraw(frame_button->widget);
1479         frame_button->state = FRAME_BUTTON_OVER;
1480
1481         return CURSOR_LEFT_PTR;
1482 }
1483
1484 static void
1485 frame_button_leave_handler(struct widget *widget, struct input *input, void *data)
1486 {
1487         struct frame_button *frame_button = data;
1488
1489         widget_schedule_redraw(frame_button->widget);
1490         frame_button->state = FRAME_BUTTON_DEFAULT;
1491 }
1492
1493 static void
1494 frame_button_button_handler(struct widget *widget,
1495                             struct input *input, uint32_t time,
1496                             uint32_t button,
1497                             enum wl_pointer_button_state state, void *data)
1498 {
1499         struct frame_button *frame_button = data;
1500         struct window *window = widget->window;
1501         int was_pressed = (frame_button->state == FRAME_BUTTON_ACTIVE);
1502
1503         if (button != BTN_LEFT)
1504                 return;
1505
1506         switch (state) {
1507         case WL_POINTER_BUTTON_STATE_PRESSED:
1508                 frame_button->state = FRAME_BUTTON_ACTIVE;
1509                 widget_schedule_redraw(frame_button->widget);
1510
1511                 if (frame_button->type == FRAME_BUTTON_ICON)
1512                         window_show_frame_menu(window, input, time);
1513                 return;
1514         case WL_POINTER_BUTTON_STATE_RELEASED:
1515                 frame_button->state = FRAME_BUTTON_DEFAULT;
1516                 widget_schedule_redraw(frame_button->widget);
1517                 break;
1518         }
1519
1520         if (!was_pressed)
1521                 return;
1522
1523         switch (frame_button->type) {
1524         case FRAME_BUTTON_CLOSE:
1525                 if (window->close_handler)
1526                         window->close_handler(window->parent,
1527                                               window->user_data);
1528                 else
1529                         display_exit(window->display);
1530                 break;
1531         case FRAME_BUTTON_MINIMIZE:
1532                 fprintf(stderr,"Minimize stub\n");
1533                 break;
1534         case FRAME_BUTTON_MAXIMIZE:
1535                 window_set_maximized(window, window->type != TYPE_MAXIMIZED);
1536                 break;
1537         default:
1538                 /* Unknown operation */
1539                 break;
1540         }
1541 }
1542
1543 static int
1544 frame_button_motion_handler(struct widget *widget,
1545                             struct input *input, uint32_t time,
1546                             float x, float y, void *data)
1547 {
1548         struct frame_button *frame_button = data;
1549         enum frame_button_pointer previous_button_state = frame_button->state;
1550
1551         /* only track state for a pressed button */
1552         if (input->grab != widget)
1553                 return CURSOR_LEFT_PTR;
1554
1555         if (x > widget->allocation.x &&
1556             x < (widget->allocation.x + widget->allocation.width) &&
1557             y > widget->allocation.y &&
1558             y < (widget->allocation.y + widget->allocation.height)) {
1559                 frame_button->state = FRAME_BUTTON_ACTIVE;
1560         } else {
1561                 frame_button->state = FRAME_BUTTON_DEFAULT;
1562         }
1563
1564         if (frame_button->state != previous_button_state)
1565                 widget_schedule_redraw(frame_button->widget);
1566
1567         return CURSOR_LEFT_PTR;
1568 }
1569
1570 static void
1571 frame_button_redraw_handler(struct widget *widget, void *data)
1572 {
1573         struct frame_button *frame_button = data;
1574         cairo_t *cr;
1575         int width, height, x, y;
1576         struct window *window = widget->window;
1577
1578         x = widget->allocation.x;
1579         y = widget->allocation.y;
1580         width = widget->allocation.width;
1581         height = widget->allocation.height;
1582
1583         if (!width)
1584                 return;
1585         if (!height)
1586                 return;
1587         if (widget->opaque)
1588                 return;
1589
1590         cr = cairo_create(window->cairo_surface);
1591
1592         if (frame_button->decoration == FRAME_BUTTON_FANCY) {
1593                 cairo_set_line_width(cr, 1);
1594
1595                 cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
1596                 cairo_rectangle (cr, x, y, 25, 16);
1597
1598                 cairo_stroke_preserve(cr);
1599
1600                 switch (frame_button->state) {
1601                 case FRAME_BUTTON_DEFAULT:
1602                         cairo_set_source_rgb(cr, 0.88, 0.88, 0.88);
1603                         break;
1604                 case FRAME_BUTTON_OVER:
1605                         cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
1606                         break;
1607                 case FRAME_BUTTON_ACTIVE:
1608                         cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
1609                         break;
1610                 }
1611
1612                 cairo_fill (cr);
1613
1614                 x += 4;
1615         }
1616
1617         cairo_set_source_surface(cr, frame_button->icon, x, y);
1618         cairo_paint(cr);
1619
1620         cairo_destroy(cr);
1621 }
1622
1623 static struct widget *
1624 frame_button_create(struct frame *frame, void *data, enum frame_button_action type,
1625         enum frame_button_align align, enum frame_button_decoration style)
1626 {
1627         struct frame_button *frame_button;
1628         const char *icon = data;
1629
1630         frame_button = malloc (sizeof *frame_button);
1631         memset(frame_button, 0, sizeof *frame_button);
1632
1633         frame_button->icon = cairo_image_surface_create_from_png(icon);
1634         frame_button->widget = widget_add_widget(frame->widget, frame_button);
1635         frame_button->frame = frame;
1636         frame_button->type = type;
1637         frame_button->align = align;
1638         frame_button->decoration = style;
1639
1640         wl_list_insert(frame->buttons_list.prev, &frame_button->link);
1641
1642         widget_set_redraw_handler(frame_button->widget, frame_button_redraw_handler);
1643         widget_set_enter_handler(frame_button->widget, frame_button_enter_handler);
1644         widget_set_leave_handler(frame_button->widget, frame_button_leave_handler);
1645         widget_set_button_handler(frame_button->widget, frame_button_button_handler);
1646         widget_set_motion_handler(frame_button->widget, frame_button_motion_handler);
1647         return frame_button->widget;
1648 }
1649
1650 static void
1651 frame_button_destroy(struct frame_button *frame_button)
1652 {
1653         widget_destroy(frame_button->widget);
1654         wl_list_remove(&frame_button->link);
1655         cairo_surface_destroy(frame_button->icon);
1656         free(frame_button);
1657
1658         return;
1659 }
1660
1661 static void
1662 frame_redraw_handler(struct widget *widget, void *data)
1663 {
1664         cairo_t *cr;
1665         struct window *window = widget->window;
1666         struct theme *t = window->display->theme;
1667         uint32_t flags = 0;
1668
1669         if (window->type == TYPE_FULLSCREEN)
1670                 return;
1671
1672         cr = cairo_create(window->cairo_surface);
1673
1674         if (window->focus_count)
1675                 flags |= THEME_FRAME_ACTIVE;
1676         theme_render_frame(t, cr, widget->allocation.width,
1677                            widget->allocation.height, window->title, flags);
1678
1679         cairo_destroy(cr);
1680 }
1681
1682 static int
1683 frame_get_pointer_image_for_location(struct frame *frame, struct input *input)
1684 {
1685         struct theme *t = frame->widget->window->display->theme;
1686         int location;
1687
1688         location = theme_get_location(t, input->sx, input->sy,
1689                                       frame->widget->allocation.width,
1690                                       frame->widget->allocation.height);
1691
1692         switch (location) {
1693         case THEME_LOCATION_RESIZING_TOP:
1694                 return CURSOR_TOP;
1695         case THEME_LOCATION_RESIZING_BOTTOM:
1696                 return CURSOR_BOTTOM;
1697         case THEME_LOCATION_RESIZING_LEFT:
1698                 return CURSOR_LEFT;
1699         case THEME_LOCATION_RESIZING_RIGHT:
1700                 return CURSOR_RIGHT;
1701         case THEME_LOCATION_RESIZING_TOP_LEFT:
1702                 return CURSOR_TOP_LEFT;
1703         case THEME_LOCATION_RESIZING_TOP_RIGHT:
1704                 return CURSOR_TOP_RIGHT;
1705         case THEME_LOCATION_RESIZING_BOTTOM_LEFT:
1706                 return CURSOR_BOTTOM_LEFT;
1707         case THEME_LOCATION_RESIZING_BOTTOM_RIGHT:
1708                 return CURSOR_BOTTOM_RIGHT;
1709         case THEME_LOCATION_EXTERIOR:
1710         case THEME_LOCATION_TITLEBAR:
1711         default:
1712                 return CURSOR_LEFT_PTR;
1713         }
1714 }
1715
1716 static void
1717 frame_menu_func(struct window *window, int index, void *data)
1718 {
1719         struct display *display;
1720
1721         switch (index) {
1722         case 0: /* close */
1723                 if (window->close_handler)
1724                         window->close_handler(window->parent,
1725                                               window->user_data);
1726                 else
1727                         display_exit(window->display);
1728                 break;
1729         case 1: /* fullscreen */
1730                 /* we don't have a way to get out of fullscreen for now */
1731                 if (window->fullscreen_handler)
1732                         window->fullscreen_handler(window, window->user_data);
1733                 break;
1734         case 2: /* move to workspace above */
1735                 display = window->display;
1736                 if (display->workspace > 0)
1737                         workspace_manager_move_surface(display->workspace_manager,
1738                                                        window->surface,
1739                                                        display->workspace - 1);
1740                 break;
1741         case 3: /* move to workspace below */
1742                 display = window->display;
1743                 if (display->workspace < display->workspace_count - 1)
1744                         workspace_manager_move_surface(display->workspace_manager,
1745                                                        window->surface,
1746                                                        display->workspace + 1);
1747                 break;
1748         }
1749 }
1750
1751 void
1752 window_show_frame_menu(struct window *window,
1753                        struct input *input, uint32_t time)
1754 {
1755         int32_t x, y;
1756
1757         static const char *entries[] = {
1758                 "Close", "Fullscreen",
1759                 "Move to workspace above", "Move to workspace below"
1760         };
1761
1762         input_get_position(input, &x, &y);
1763         window_show_menu(window->display, input, time, window,
1764                          x - 10, y - 10, frame_menu_func, entries,
1765                          ARRAY_LENGTH(entries));
1766 }
1767
1768 static int
1769 frame_enter_handler(struct widget *widget,
1770                     struct input *input, float x, float y, void *data)
1771 {
1772         return frame_get_pointer_image_for_location(data, input);
1773 }
1774
1775 static int
1776 frame_motion_handler(struct widget *widget,
1777                      struct input *input, uint32_t time,
1778                      float x, float y, void *data)
1779 {
1780         return frame_get_pointer_image_for_location(data, input);
1781 }
1782
1783 static void
1784 frame_button_handler(struct widget *widget,
1785                      struct input *input, uint32_t time,
1786                      uint32_t button, enum wl_pointer_button_state state,
1787                      void *data)
1788
1789 {
1790         struct frame *frame = data;
1791         struct window *window = widget->window;
1792         struct display *display = window->display;
1793         int location;
1794
1795         location = theme_get_location(display->theme, input->sx, input->sy,
1796                                       frame->widget->allocation.width,
1797                                       frame->widget->allocation.height);
1798
1799         if (window->display->shell && button == BTN_LEFT &&
1800             state == WL_POINTER_BUTTON_STATE_PRESSED) {
1801                 switch (location) {
1802                 case THEME_LOCATION_TITLEBAR:
1803                         if (!window->shell_surface)
1804                                 break;
1805                         input_set_pointer_image(input, CURSOR_DRAGGING);
1806                         input_ungrab(input);
1807                         wl_shell_surface_move(window->shell_surface,
1808                                               input_get_seat(input),
1809                                               display->serial);
1810                         break;
1811                 case THEME_LOCATION_RESIZING_TOP:
1812                 case THEME_LOCATION_RESIZING_BOTTOM:
1813                 case THEME_LOCATION_RESIZING_LEFT:
1814                 case THEME_LOCATION_RESIZING_RIGHT:
1815                 case THEME_LOCATION_RESIZING_TOP_LEFT:
1816                 case THEME_LOCATION_RESIZING_TOP_RIGHT:
1817                 case THEME_LOCATION_RESIZING_BOTTOM_LEFT:
1818                 case THEME_LOCATION_RESIZING_BOTTOM_RIGHT:
1819                         if (!window->shell_surface)
1820                                 break;
1821                         input_ungrab(input);
1822
1823                         if (!display->dpy) {
1824                                 /* If we're using shm, allocate a big
1825                                    pool to create buffers out of while
1826                                    we resize.  We should probably base
1827                                    this number on the size of the output. */
1828                                 window->pool =
1829                                         shm_pool_create(display, 6 * 1024 * 1024);
1830                         }
1831
1832                         wl_shell_surface_resize(window->shell_surface,
1833                                                 input_get_seat(input),
1834                                                 display->serial, location);
1835                         break;
1836                 }
1837         } else if (button == BTN_RIGHT &&
1838                    state == WL_POINTER_BUTTON_STATE_PRESSED) {
1839                 window_show_frame_menu(window, input, time);
1840         }
1841 }
1842
1843 struct widget *
1844 frame_create(struct window *window, void *data)
1845 {
1846         struct frame *frame;
1847
1848         frame = malloc(sizeof *frame);
1849         memset(frame, 0, sizeof *frame);
1850
1851         frame->widget = window_add_widget(window, frame);
1852         frame->child = widget_add_widget(frame->widget, data);
1853
1854         widget_set_redraw_handler(frame->widget, frame_redraw_handler);
1855         widget_set_resize_handler(frame->widget, frame_resize_handler);
1856         widget_set_enter_handler(frame->widget, frame_enter_handler);
1857         widget_set_motion_handler(frame->widget, frame_motion_handler);
1858         widget_set_button_handler(frame->widget, frame_button_handler);
1859
1860         /* Create empty list for frame buttons */
1861         wl_list_init(&frame->buttons_list);
1862
1863         frame_button_create(frame, DATADIR "/weston/icon_window.png",
1864                 FRAME_BUTTON_ICON, FRAME_BUTTON_LEFT, FRAME_BUTTON_NONE);
1865
1866         frame_button_create(frame, DATADIR "/weston/sign_close.png",
1867                 FRAME_BUTTON_CLOSE, FRAME_BUTTON_RIGHT, FRAME_BUTTON_FANCY);
1868
1869         frame_button_create(frame, DATADIR "/weston/sign_maximize.png",
1870                 FRAME_BUTTON_MAXIMIZE, FRAME_BUTTON_RIGHT, FRAME_BUTTON_FANCY);
1871
1872         frame_button_create(frame, DATADIR "/weston/sign_minimize.png",
1873                 FRAME_BUTTON_MINIMIZE, FRAME_BUTTON_RIGHT, FRAME_BUTTON_FANCY);
1874
1875         window->frame = frame;
1876
1877         return frame->child;
1878 }
1879
1880 void
1881 frame_set_child_size(struct widget *widget, int child_width, int child_height)
1882 {
1883         struct display *display = widget->window->display;
1884         struct theme *t = display->theme;
1885         int decoration_width, decoration_height;
1886         int width, height;
1887
1888         if (widget->window->type != TYPE_FULLSCREEN) {
1889                 decoration_width = (t->width + t->margin) * 2;
1890                 decoration_height = t->width +
1891                         t->titlebar_height + t->margin * 2;
1892
1893                 width = child_width + decoration_width;
1894                 height = child_height + decoration_height;
1895         } else {
1896                 width = child_width;
1897                 height = child_height;
1898         }
1899
1900         window_schedule_resize(widget->window, width, height);
1901 }
1902
1903 static void
1904 frame_destroy(struct frame *frame)
1905 {
1906         struct frame_button *button, *tmp;
1907
1908         wl_list_for_each_safe(button, tmp, &frame->buttons_list, link)
1909                 frame_button_destroy(button);
1910
1911         /* frame->child must be destroyed by the application */
1912         widget_destroy(frame->widget);
1913         free(frame);
1914 }
1915
1916 static void
1917 input_set_focus_widget(struct input *input, struct widget *focus,
1918                        float x, float y)
1919 {
1920         struct widget *old, *widget;
1921         int pointer = CURSOR_LEFT_PTR;
1922
1923         if (focus == input->focus_widget)
1924                 return;
1925
1926         old = input->focus_widget;
1927         if (old) {
1928                 widget = old;
1929                 if (input->grab)
1930                         widget = input->grab;
1931                 if (widget->leave_handler)
1932                         widget->leave_handler(old, input, widget->user_data);
1933                 input->focus_widget = NULL;
1934         }
1935
1936         if (focus) {
1937                 widget = focus;
1938                 if (input->grab)
1939                         widget = input->grab;
1940                 input->focus_widget = focus;
1941                 if (widget->enter_handler)
1942                         pointer = widget->enter_handler(focus, input, x, y,
1943                                                         widget->user_data);
1944
1945                 input_set_pointer_image(input, pointer);
1946         }
1947 }
1948
1949 void
1950 input_grab(struct input *input, struct widget *widget, uint32_t button)
1951 {
1952         input->grab = widget;
1953         input->grab_button = button;
1954 }
1955
1956 void
1957 input_ungrab(struct input *input)
1958 {
1959         struct widget *widget;
1960
1961         input->grab = NULL;
1962         if (input->pointer_focus) {
1963                 widget = widget_find_widget(input->pointer_focus->widget,
1964                                             input->sx, input->sy);
1965                 input_set_focus_widget(input, widget, input->sx, input->sy);
1966         }
1967 }
1968
1969 static void
1970 input_remove_pointer_focus(struct input *input)
1971 {
1972         struct window *window = input->pointer_focus;
1973
1974         if (!window)
1975                 return;
1976
1977         input_set_focus_widget(input, NULL, 0, 0);
1978
1979         input->pointer_focus = NULL;
1980         input->current_cursor = CURSOR_UNSET;
1981 }
1982
1983 static void
1984 pointer_handle_enter(void *data, struct wl_pointer *pointer,
1985                      uint32_t serial, struct wl_surface *surface,
1986                      wl_fixed_t sx_w, wl_fixed_t sy_w)
1987 {
1988         struct input *input = data;
1989         struct window *window;
1990         struct widget *widget;
1991         float sx = wl_fixed_to_double(sx_w);
1992         float sy = wl_fixed_to_double(sy_w);
1993
1994         if (!surface) {
1995                 /* enter event for a window we've just destroyed */
1996                 return;
1997         }
1998
1999         input->display->serial = serial;
2000         input->pointer_enter_serial = serial;
2001         input->pointer_focus = wl_surface_get_user_data(surface);
2002         window = input->pointer_focus;
2003
2004         if (window->pool) {
2005                 shm_pool_destroy(window->pool);
2006                 window->pool = NULL;
2007                 /* Schedule a redraw to free the pool */
2008                 window_schedule_redraw(window);
2009         }
2010
2011         input->sx = sx;
2012         input->sy = sy;
2013
2014         widget = widget_find_widget(window->widget, sx, sy);
2015         input_set_focus_widget(input, widget, sx, sy);
2016 }
2017
2018 static void
2019 pointer_handle_leave(void *data, struct wl_pointer *pointer,
2020                      uint32_t serial, struct wl_surface *surface)
2021 {
2022         struct input *input = data;
2023
2024         input->display->serial = serial;
2025         input_remove_pointer_focus(input);
2026 }
2027
2028 static void
2029 pointer_handle_motion(void *data, struct wl_pointer *pointer,
2030                       uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
2031 {
2032         struct input *input = data;
2033         struct window *window = input->pointer_focus;
2034         struct widget *widget;
2035         int cursor = CURSOR_LEFT_PTR;
2036         float sx = wl_fixed_to_double(sx_w);
2037         float sy = wl_fixed_to_double(sy_w);
2038
2039         input->sx = sx;
2040         input->sy = sy;
2041
2042         if (!window)
2043                 return;
2044
2045         if (!(input->grab && input->grab_button)) {
2046                 widget = widget_find_widget(window->widget, sx, sy);
2047                 input_set_focus_widget(input, widget, sx, sy);
2048         }
2049
2050         if (input->grab)
2051                 widget = input->grab;
2052         else
2053                 widget = input->focus_widget;
2054         if (widget && widget->motion_handler)
2055                 cursor = widget->motion_handler(widget,
2056                                                 input, time, sx, sy,
2057                                                 widget->user_data);
2058
2059         input_set_pointer_image(input, cursor);
2060 }
2061
2062 static void
2063 pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
2064                       uint32_t time, uint32_t button, uint32_t state_w)
2065 {
2066         struct input *input = data;
2067         struct widget *widget;
2068         enum wl_pointer_button_state state = state_w;
2069
2070         input->display->serial = serial;
2071         if (input->focus_widget && input->grab == NULL &&
2072             state == WL_POINTER_BUTTON_STATE_PRESSED)
2073                 input_grab(input, input->focus_widget, button);
2074
2075         widget = input->grab;
2076         if (widget && widget->button_handler)
2077                 (*widget->button_handler)(widget,
2078                                           input, time,
2079                                           button, state,
2080                                           input->grab->user_data);
2081
2082         if (input->grab && input->grab_button == button &&
2083             state == WL_POINTER_BUTTON_STATE_RELEASED)
2084                 input_ungrab(input);
2085 }
2086
2087 static void
2088 pointer_handle_axis(void *data, struct wl_pointer *pointer,
2089                     uint32_t time, uint32_t axis, wl_fixed_t value)
2090 {
2091         struct input *input = data;
2092         struct widget *widget;
2093
2094         widget = input->focus_widget;
2095         if (input->grab)
2096                 widget = input->grab;
2097         if (widget && widget->axis_handler)
2098                 (*widget->axis_handler)(widget,
2099                                         input, time,
2100                                         axis, value,
2101                                         widget->user_data);
2102 }
2103
2104 static const struct wl_pointer_listener pointer_listener = {
2105         pointer_handle_enter,
2106         pointer_handle_leave,
2107         pointer_handle_motion,
2108         pointer_handle_button,
2109         pointer_handle_axis,
2110 };
2111
2112 static void
2113 input_remove_keyboard_focus(struct input *input)
2114 {
2115         struct window *window = input->keyboard_focus;
2116         struct itimerspec its;
2117
2118         its.it_interval.tv_sec = 0;
2119         its.it_interval.tv_nsec = 0;
2120         its.it_value.tv_sec = 0;
2121         its.it_value.tv_nsec = 0;
2122         timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
2123
2124         if (!window)
2125                 return;
2126
2127         window->focus_count--;
2128         if (window->keyboard_focus_handler)
2129                 (*window->keyboard_focus_handler)(window, NULL,
2130                                                   window->user_data);
2131
2132         input->keyboard_focus = NULL;
2133 }
2134
2135 static void
2136 keyboard_repeat_func(struct task *task, uint32_t events)
2137 {
2138         struct input *input =
2139                 container_of(task, struct input, repeat_task);
2140         struct window *window = input->keyboard_focus;
2141         uint64_t exp;
2142
2143         if (read(input->repeat_timer_fd, &exp, sizeof exp) != sizeof exp)
2144                 /* If we change the timer between the fd becoming
2145                  * readable and getting here, there'll be nothing to
2146                  * read and we get EAGAIN. */
2147                 return;
2148
2149         if (window && window->key_handler) {
2150                 (*window->key_handler)(window, input, input->repeat_time,
2151                                        input->repeat_key, input->repeat_sym,
2152                                        WL_KEYBOARD_KEY_STATE_PRESSED,
2153                                        window->user_data);
2154         }
2155 }
2156
2157 static void
2158 keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
2159                        uint32_t format, int fd, uint32_t size)
2160 {
2161         struct input *input = data;
2162         char *map_str;
2163
2164         if (!data) {
2165                 close(fd);
2166                 return;
2167         }
2168
2169         if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
2170                 close(fd);
2171                 return;
2172         }
2173
2174         map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
2175         if (map_str == MAP_FAILED) {
2176                 close(fd);
2177                 return;
2178         }
2179
2180         input->xkb.keymap = xkb_map_new_from_string(input->display->xkb_context,
2181                                                     map_str,
2182                                                     XKB_KEYMAP_FORMAT_TEXT_V1,
2183                                                     0);
2184         munmap(map_str, size);
2185         close(fd);
2186
2187         if (!input->xkb.keymap) {
2188                 fprintf(stderr, "failed to compile keymap\n");
2189                 return;
2190         }
2191
2192         input->xkb.state = xkb_state_new(input->xkb.keymap);
2193         if (!input->xkb.state) {
2194                 fprintf(stderr, "failed to create XKB state\n");
2195                 xkb_map_unref(input->xkb.keymap);
2196                 input->xkb.keymap = NULL;
2197                 return;
2198         }
2199
2200         input->xkb.control_mask =
2201                 1 << xkb_map_mod_get_index(input->xkb.keymap, "Control");
2202         input->xkb.alt_mask =
2203                 1 << xkb_map_mod_get_index(input->xkb.keymap, "Mod1");
2204         input->xkb.shift_mask =
2205                 1 << xkb_map_mod_get_index(input->xkb.keymap, "Shift");
2206 }
2207
2208 static void
2209 keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
2210                       uint32_t serial, struct wl_surface *surface,
2211                       struct wl_array *keys)
2212 {
2213         struct input *input = data;
2214         struct window *window;
2215
2216         input->display->serial = serial;
2217         input->keyboard_focus = wl_surface_get_user_data(surface);
2218
2219         window = input->keyboard_focus;
2220         window->focus_count++;
2221         if (window->keyboard_focus_handler)
2222                 (*window->keyboard_focus_handler)(window,
2223                                                   input, window->user_data);
2224 }
2225
2226 static void
2227 keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
2228                       uint32_t serial, struct wl_surface *surface)
2229 {
2230         struct input *input = data;
2231
2232         input->display->serial = serial;
2233         input_remove_keyboard_focus(input);
2234 }
2235
2236 static void
2237 keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
2238                     uint32_t serial, uint32_t time, uint32_t key,
2239                     uint32_t state_w)
2240 {
2241         struct input *input = data;
2242         struct window *window = input->keyboard_focus;
2243         uint32_t code, num_syms;
2244         enum wl_keyboard_key_state state = state_w;
2245         const xkb_keysym_t *syms;
2246         xkb_keysym_t sym;
2247         xkb_mod_mask_t mask;
2248         struct itimerspec its;
2249
2250         input->display->serial = serial;
2251         code = key + 8;
2252         if (!window || !input->xkb.state)
2253                 return;
2254
2255         num_syms = xkb_key_get_syms(input->xkb.state, code, &syms);
2256
2257         mask = xkb_state_serialize_mods(input->xkb.state,
2258                                         XKB_STATE_DEPRESSED |
2259                                         XKB_STATE_LATCHED);
2260         input->modifiers = 0;
2261         if (mask & input->xkb.control_mask)
2262                 input->modifiers |= MOD_CONTROL_MASK;
2263         if (mask & input->xkb.alt_mask)
2264                 input->modifiers |= MOD_ALT_MASK;
2265         if (mask & input->xkb.shift_mask)
2266                 input->modifiers |= MOD_SHIFT_MASK;
2267
2268         sym = XKB_KEY_NoSymbol;
2269         if (num_syms == 1)
2270                 sym = syms[0];
2271
2272         if (sym == XKB_KEY_F5 && input->modifiers == MOD_ALT_MASK) {
2273                 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
2274                         window_set_maximized(window,
2275                                              window->type != TYPE_MAXIMIZED);
2276         } else if (sym == XKB_KEY_F11 &&
2277                    window->fullscreen_handler &&
2278                    state == WL_KEYBOARD_KEY_STATE_PRESSED) {
2279                 window->fullscreen_handler(window, window->user_data);
2280         } else if (sym == XKB_KEY_F4 &&
2281                    input->modifiers == MOD_ALT_MASK &&
2282                    state == WL_KEYBOARD_KEY_STATE_PRESSED) {
2283                 if (window->close_handler)
2284                         window->close_handler(window->parent,
2285                                               window->user_data);
2286                 else
2287                         display_exit(window->display);
2288         } else if (window->key_handler) {
2289                 (*window->key_handler)(window, input, time, key,
2290                                        sym, state, window->user_data);
2291         }
2292
2293         if (state == WL_KEYBOARD_KEY_STATE_RELEASED &&
2294             key == input->repeat_key) {
2295                 its.it_interval.tv_sec = 0;
2296                 its.it_interval.tv_nsec = 0;
2297                 its.it_value.tv_sec = 0;
2298                 its.it_value.tv_nsec = 0;
2299                 timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
2300         } else if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
2301                 input->repeat_sym = sym;
2302                 input->repeat_key = key;
2303                 input->repeat_time = time;
2304                 its.it_interval.tv_sec = 0;
2305                 its.it_interval.tv_nsec = 25 * 1000 * 1000;
2306                 its.it_value.tv_sec = 0;
2307                 its.it_value.tv_nsec = 400 * 1000 * 1000;
2308                 timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
2309         }
2310 }
2311
2312 static void
2313 keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
2314                           uint32_t serial, uint32_t mods_depressed,
2315                           uint32_t mods_latched, uint32_t mods_locked,
2316                           uint32_t group)
2317 {
2318         struct input *input = data;
2319
2320         xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched,
2321                               mods_locked, 0, 0, group);
2322 }
2323
2324 static const struct wl_keyboard_listener keyboard_listener = {
2325         keyboard_handle_keymap,
2326         keyboard_handle_enter,
2327         keyboard_handle_leave,
2328         keyboard_handle_key,
2329         keyboard_handle_modifiers,
2330 };
2331
2332 static void
2333 seat_handle_capabilities(void *data, struct wl_seat *seat,
2334                          enum wl_seat_capability caps)
2335 {
2336         struct input *input = data;
2337
2338         if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
2339                 input->pointer = wl_seat_get_pointer(seat);
2340                 wl_pointer_set_user_data(input->pointer, input);
2341                 wl_pointer_add_listener(input->pointer, &pointer_listener,
2342                                         input);
2343         } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
2344                 wl_pointer_destroy(input->pointer);
2345                 input->pointer = NULL;
2346         }
2347
2348         if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) {
2349                 input->keyboard = wl_seat_get_keyboard(seat);
2350                 wl_keyboard_set_user_data(input->keyboard, input);
2351                 wl_keyboard_add_listener(input->keyboard, &keyboard_listener,
2352                                          input);
2353         } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) {
2354                 wl_keyboard_destroy(input->keyboard);
2355                 input->keyboard = NULL;
2356         }
2357 }
2358
2359 static const struct wl_seat_listener seat_listener = {
2360         seat_handle_capabilities,
2361 };
2362
2363 void
2364 input_get_position(struct input *input, int32_t *x, int32_t *y)
2365 {
2366         *x = input->sx;
2367         *y = input->sy;
2368 }
2369
2370 struct display *
2371 input_get_display(struct input *input)
2372 {
2373         return input->display;
2374 }
2375
2376 struct wl_seat *
2377 input_get_seat(struct input *input)
2378 {
2379         return input->seat;
2380 }
2381
2382 uint32_t
2383 input_get_modifiers(struct input *input)
2384 {
2385         return input->modifiers;
2386 }
2387
2388 struct widget *
2389 input_get_focus_widget(struct input *input)
2390 {
2391         return input->focus_widget;
2392 }
2393
2394 struct data_offer {
2395         struct wl_data_offer *offer;
2396         struct input *input;
2397         struct wl_array types;
2398         int refcount;
2399
2400         struct task io_task;
2401         int fd;
2402         data_func_t func;
2403         int32_t x, y;
2404         void *user_data;
2405 };
2406
2407 static void
2408 data_offer_offer(void *data, struct wl_data_offer *wl_data_offer, const char *type)
2409 {
2410         struct data_offer *offer = data;
2411         char **p;
2412
2413         p = wl_array_add(&offer->types, sizeof *p);
2414         *p = strdup(type);
2415 }
2416
2417 static const struct wl_data_offer_listener data_offer_listener = {
2418         data_offer_offer,
2419 };
2420
2421 static void
2422 data_offer_destroy(struct data_offer *offer)
2423 {
2424         char **p;
2425
2426         offer->refcount--;
2427         if (offer->refcount == 0) {
2428                 wl_data_offer_destroy(offer->offer);
2429                 for (p = offer->types.data; *p; p++)
2430                         free(*p);
2431                 wl_array_release(&offer->types);
2432                 free(offer);
2433         }
2434 }
2435
2436 static void
2437 data_device_data_offer(void *data,
2438                        struct wl_data_device *data_device,
2439                        struct wl_data_offer *_offer)
2440 {
2441         struct data_offer *offer;
2442
2443         offer = malloc(sizeof *offer);
2444
2445         wl_array_init(&offer->types);
2446         offer->refcount = 1;
2447         offer->input = data;
2448         offer->offer = _offer;
2449         wl_data_offer_add_listener(offer->offer,
2450                                    &data_offer_listener, offer);
2451 }
2452
2453 static void
2454 data_device_enter(void *data, struct wl_data_device *data_device,
2455                   uint32_t serial, struct wl_surface *surface,
2456                   wl_fixed_t x_w, wl_fixed_t y_w,
2457                   struct wl_data_offer *offer)
2458 {
2459         struct input *input = data;
2460         struct window *window;
2461         void *types_data;
2462         float x = wl_fixed_to_double(x_w);
2463         float y = wl_fixed_to_double(y_w);
2464         char **p;
2465
2466         input->pointer_enter_serial = serial;
2467         window = wl_surface_get_user_data(surface);
2468         input->pointer_focus = window;
2469
2470         if (offer) {
2471                 input->drag_offer = wl_data_offer_get_user_data(offer);
2472
2473                 p = wl_array_add(&input->drag_offer->types, sizeof *p);
2474                 *p = NULL;
2475
2476                 types_data = input->drag_offer->types.data;
2477         } else {
2478                 input->drag_offer = NULL;
2479                 types_data = NULL;
2480         }
2481
2482         window = input->pointer_focus;
2483         if (window->data_handler)
2484                 window->data_handler(window, input, x, y, types_data,
2485                                      window->user_data);
2486 }
2487
2488 static void
2489 data_device_leave(void *data, struct wl_data_device *data_device)
2490 {
2491         struct input *input = data;
2492
2493         if (input->drag_offer) {
2494                 data_offer_destroy(input->drag_offer);
2495                 input->drag_offer = NULL;
2496         }
2497 }
2498
2499 static void
2500 data_device_motion(void *data, struct wl_data_device *data_device,
2501                    uint32_t time, wl_fixed_t x_w, wl_fixed_t y_w)
2502 {
2503         struct input *input = data;
2504         struct window *window = input->pointer_focus;
2505         float x = wl_fixed_to_double(x_w);
2506         float y = wl_fixed_to_double(y_w);
2507         void *types_data;
2508
2509         input->sx = x;
2510         input->sy = y;
2511
2512         if (input->drag_offer)
2513                 types_data = input->drag_offer->types.data;
2514         else
2515                 types_data = NULL;
2516
2517         if (window->data_handler)
2518                 window->data_handler(window, input, x, y, types_data,
2519                                      window->user_data);
2520 }
2521
2522 static void
2523 data_device_drop(void *data, struct wl_data_device *data_device)
2524 {
2525         struct input *input = data;
2526         struct window *window = input->pointer_focus;
2527
2528         if (window->drop_handler)
2529                 window->drop_handler(window, input,
2530                                      input->sx, input->sy, window->user_data);
2531 }
2532
2533 static void
2534 data_device_selection(void *data,
2535                       struct wl_data_device *wl_data_device,
2536                       struct wl_data_offer *offer)
2537 {
2538         struct input *input = data;
2539         char **p;
2540
2541         if (input->selection_offer)
2542                 data_offer_destroy(input->selection_offer);
2543
2544         if (offer) {
2545                 input->selection_offer = wl_data_offer_get_user_data(offer);
2546                 p = wl_array_add(&input->selection_offer->types, sizeof *p);
2547                 *p = NULL;
2548         } else {
2549                 input->selection_offer = NULL;
2550         }
2551 }
2552
2553 static const struct wl_data_device_listener data_device_listener = {
2554         data_device_data_offer,
2555         data_device_enter,
2556         data_device_leave,
2557         data_device_motion,
2558         data_device_drop,
2559         data_device_selection
2560 };
2561
2562 static void
2563 input_set_pointer_image_index(struct input *input, int index)
2564 {
2565         struct wl_buffer *buffer;
2566         struct wl_cursor *cursor;
2567         struct wl_cursor_image *image;
2568
2569         cursor = input->display->cursors[input->current_cursor];
2570         if (!cursor)
2571                 return;
2572
2573         if (index >= (int) cursor->image_count) {
2574                 fprintf(stderr, "cursor index out of range\n");
2575                 return;
2576         }
2577
2578         image = cursor->images[index];
2579         buffer = wl_cursor_image_get_buffer(image);
2580         if (!buffer)
2581                 return;
2582
2583         wl_pointer_set_cursor(input->pointer, input->pointer_enter_serial,
2584                               input->pointer_surface,
2585                               image->hotspot_x, image->hotspot_y);
2586         wl_surface_attach(input->pointer_surface, buffer, 0, 0);
2587         wl_surface_damage(input->pointer_surface, 0, 0,
2588                           image->width, image->height);
2589 }
2590
2591 static const struct wl_callback_listener pointer_surface_listener;
2592
2593 static void
2594 pointer_surface_frame_callback(void *data, struct wl_callback *callback,
2595                                uint32_t time)
2596 {
2597         struct input *input = data;
2598         struct wl_cursor *cursor;
2599         int i;
2600
2601         if (callback) {
2602                 assert(callback == input->cursor_frame_cb);
2603                 wl_callback_destroy(callback);
2604                 input->cursor_frame_cb = NULL;
2605         }
2606
2607         if (input->current_cursor == CURSOR_BLANK) {
2608                 wl_pointer_set_cursor(input->pointer,
2609                                       input->pointer_enter_serial,
2610                                       NULL, 0, 0);
2611                 return;
2612         }
2613
2614         if (input->current_cursor == CURSOR_UNSET)
2615                 return;
2616         cursor = input->display->cursors[input->current_cursor];
2617         if (!cursor)
2618                 return;
2619
2620         /* FIXME We don't have the current time on the first call so we set
2621          * the animation start to the time of the first frame callback. */
2622         if (time == 0)
2623                 input->cursor_anim_start = 0;
2624         else if (input->cursor_anim_start == 0)
2625                 input->cursor_anim_start = time;
2626
2627         if (time == 0 || input->cursor_anim_start == 0)
2628                 i = 0;
2629         else
2630                 i = wl_cursor_frame(cursor, time - input->cursor_anim_start);
2631
2632         input_set_pointer_image_index(input, i);
2633
2634         if (cursor->image_count == 1)
2635                 return;
2636
2637         input->cursor_frame_cb = wl_surface_frame(input->pointer_surface);
2638         wl_callback_add_listener(input->cursor_frame_cb,
2639                                  &pointer_surface_listener, input);
2640 }
2641
2642 static const struct wl_callback_listener pointer_surface_listener = {
2643         pointer_surface_frame_callback
2644 };
2645
2646 void
2647 input_set_pointer_image(struct input *input, int pointer)
2648 {
2649         int force = 0;
2650
2651         if (input->pointer_enter_serial > input->cursor_serial)
2652                 force = 1;
2653
2654         if (!force && pointer == input->current_cursor)
2655                 return;
2656
2657         input->current_cursor = pointer;
2658         input->cursor_serial = input->pointer_enter_serial;
2659         if (!input->cursor_frame_cb)
2660                 pointer_surface_frame_callback(input, NULL, 0);
2661         else if (force) {
2662                 /* The current frame callback may be stuck if, for instance,
2663                  * the set cursor request was processed by the server after
2664                  * this client lost the focus. In this case the cursor surface
2665                  * might not be mapped and the frame callback wouldn't ever
2666                  * complete. Send a set_cursor and attach to try to map the
2667                  * cursor surface again so that the callback will finish */
2668                 input_set_pointer_image_index(input, 0);
2669         }
2670 }
2671
2672 struct wl_data_device *
2673 input_get_data_device(struct input *input)
2674 {
2675         return input->data_device;
2676 }
2677
2678 void
2679 input_set_selection(struct input *input,
2680                     struct wl_data_source *source, uint32_t time)
2681 {
2682         wl_data_device_set_selection(input->data_device, source, time);
2683 }
2684
2685 void
2686 input_accept(struct input *input, const char *type)
2687 {
2688         wl_data_offer_accept(input->drag_offer->offer,
2689                              input->pointer_enter_serial, type);
2690 }
2691
2692 static void
2693 offer_io_func(struct task *task, uint32_t events)
2694 {
2695         struct data_offer *offer =
2696                 container_of(task, struct data_offer, io_task);
2697         unsigned int len;
2698         char buffer[4096];
2699
2700         len = read(offer->fd, buffer, sizeof buffer);
2701         offer->func(buffer, len,
2702                     offer->x, offer->y, offer->user_data);
2703
2704         if (len == 0) {
2705                 close(offer->fd);
2706                 data_offer_destroy(offer);
2707         }
2708 }
2709
2710 static void
2711 data_offer_receive_data(struct data_offer *offer, const char *mime_type,
2712                         data_func_t func, void *user_data)
2713 {
2714         int p[2];
2715
2716         if (pipe2(p, O_CLOEXEC) == -1)
2717                 return;
2718
2719         wl_data_offer_receive(offer->offer, mime_type, p[1]);
2720         close(p[1]);
2721
2722         offer->io_task.run = offer_io_func;
2723         offer->fd = p[0];
2724         offer->func = func;
2725         offer->refcount++;
2726         offer->user_data = user_data;
2727
2728         display_watch_fd(offer->input->display,
2729                          offer->fd, EPOLLIN, &offer->io_task);
2730 }
2731
2732 void
2733 input_receive_drag_data(struct input *input, const char *mime_type,
2734                         data_func_t func, void *data)
2735 {
2736         data_offer_receive_data(input->drag_offer, mime_type, func, data);
2737         input->drag_offer->x = input->sx;
2738         input->drag_offer->y = input->sy;
2739 }
2740
2741 int
2742 input_receive_selection_data(struct input *input, const char *mime_type,
2743                              data_func_t func, void *data)
2744 {
2745         char **p;
2746
2747         if (input->selection_offer == NULL)
2748                 return -1;
2749
2750         for (p = input->selection_offer->types.data; *p; p++)
2751                 if (strcmp(mime_type, *p) == 0)
2752                         break;
2753
2754         if (*p == NULL)
2755                 return -1;
2756
2757         data_offer_receive_data(input->selection_offer,
2758                                 mime_type, func, data);
2759         return 0;
2760 }
2761
2762 int
2763 input_receive_selection_data_to_fd(struct input *input,
2764                                    const char *mime_type, int fd)
2765 {
2766         if (input->selection_offer)
2767                 wl_data_offer_receive(input->selection_offer->offer,
2768                                       mime_type, fd);
2769
2770         return 0;
2771 }
2772
2773 void
2774 window_move(struct window *window, struct input *input, uint32_t serial)
2775 {
2776         if (!window->shell_surface)
2777                 return;
2778
2779         wl_shell_surface_move(window->shell_surface, input->seat, serial);
2780 }
2781
2782 static void
2783 idle_resize(struct window *window)
2784 {
2785         struct widget *widget;
2786
2787         window->resize_needed = 0;
2788         widget = window->widget;
2789         widget_set_allocation(widget,
2790                               window->pending_allocation.x,
2791                               window->pending_allocation.y,
2792                               window->pending_allocation.width,
2793                               window->pending_allocation.height);
2794
2795         if (window->input_region) {
2796                 wl_region_destroy(window->input_region);
2797                 window->input_region = NULL;
2798         }
2799
2800         if (window->opaque_region) {
2801                 wl_region_destroy(window->opaque_region);
2802                 window->opaque_region = NULL;
2803         }
2804
2805         if (widget->resize_handler)
2806                 widget->resize_handler(widget,
2807                                        widget->allocation.width,
2808                                        widget->allocation.height,
2809                                        widget->user_data);
2810
2811         if (window->allocation.width != widget->allocation.width ||
2812             window->allocation.height != widget->allocation.height) {
2813                 window->allocation = widget->allocation;
2814                 window_schedule_redraw(window);
2815         }
2816 }
2817
2818 void
2819 window_schedule_resize(struct window *window, int width, int height)
2820 {
2821         window->pending_allocation.x = 0;
2822         window->pending_allocation.y = 0;
2823         window->pending_allocation.width = width;
2824         window->pending_allocation.height = height;
2825
2826         if (window->min_allocation.width == 0)
2827                 window->min_allocation = window->pending_allocation;
2828         if (window->pending_allocation.width < window->min_allocation.width)
2829                 window->pending_allocation.width = window->min_allocation.width;
2830         if (window->pending_allocation.height < window->min_allocation.height)
2831                 window->pending_allocation.height = window->min_allocation.height;
2832
2833         window->resize_needed = 1;
2834         window_schedule_redraw(window);
2835 }
2836
2837 void
2838 widget_schedule_resize(struct widget *widget, int32_t width, int32_t height)
2839 {
2840         window_schedule_resize(widget->window, width, height);
2841 }
2842
2843 static void
2844 handle_ping(void *data, struct wl_shell_surface *shell_surface,
2845                                                         uint32_t serial)
2846 {
2847         wl_shell_surface_pong(shell_surface, serial);
2848 }
2849
2850 static void
2851 handle_configure(void *data, struct wl_shell_surface *shell_surface,
2852                  uint32_t edges, int32_t width, int32_t height)
2853 {
2854         struct window *window = data;
2855
2856         window->resize_edges = edges;
2857         window_schedule_resize(window, width, height);
2858 }
2859
2860 static void
2861 menu_destroy(struct menu *menu)
2862 {
2863         widget_destroy(menu->widget);
2864         window_destroy(menu->window);
2865         free(menu);
2866 }
2867
2868 static void
2869 handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
2870 {
2871         struct window *window = data;
2872         struct menu *menu = window->widget->user_data;
2873
2874         /* FIXME: Need more context in this event, at least the input
2875          * device.  Or just use wl_callback.  And this really needs to
2876          * be a window vfunc that the menu can set.  And we need the
2877          * time. */
2878
2879         menu->func(window->parent, menu->current, window->parent->user_data);
2880         input_ungrab(menu->input);
2881         menu_destroy(menu);
2882 }
2883
2884 static const struct wl_shell_surface_listener shell_surface_listener = {
2885         handle_ping,
2886         handle_configure,
2887         handle_popup_done
2888 };
2889
2890 void
2891 window_get_allocation(struct window *window,
2892                       struct rectangle *allocation)
2893 {
2894         *allocation = window->allocation;
2895 }
2896
2897 static void
2898 widget_redraw(struct widget *widget)
2899 {
2900         struct widget *child;
2901
2902         if (widget->redraw_handler)
2903                 widget->redraw_handler(widget, widget->user_data);
2904         wl_list_for_each(child, &widget->child_list, link)
2905                 widget_redraw(child);
2906 }
2907
2908 static void
2909 frame_callback(void *data, struct wl_callback *callback, uint32_t time)
2910 {
2911         struct window *window = data;
2912
2913         assert(callback == window->frame_cb);
2914         wl_callback_destroy(callback);
2915         window->frame_cb = 0;
2916         window->redraw_scheduled = 0;
2917         if (window->redraw_needed)
2918                 window_schedule_redraw(window);
2919 }
2920
2921 static const struct wl_callback_listener listener = {
2922         frame_callback
2923 };
2924
2925 static void
2926 idle_redraw(struct task *task, uint32_t events)
2927 {
2928         struct window *window = container_of(task, struct window, redraw_task);
2929
2930         if (window->resize_needed)
2931                 idle_resize(window);
2932
2933         window_create_surface(window);
2934         widget_redraw(window->widget);
2935         window_flush(window);
2936         window->redraw_needed = 0;
2937         wl_list_init(&window->redraw_task.link);
2938
2939         window->frame_cb = wl_surface_frame(window->surface);
2940         wl_callback_add_listener(window->frame_cb, &listener, window);
2941 }
2942
2943 void
2944 window_schedule_redraw(struct window *window)
2945 {
2946         window->redraw_needed = 1;
2947         if (!window->redraw_scheduled) {
2948                 window->redraw_task.run = idle_redraw;
2949                 display_defer(window->display, &window->redraw_task);
2950                 window->redraw_scheduled = 1;
2951         }
2952 }
2953
2954 void
2955 window_set_fullscreen(struct window *window, int fullscreen)
2956 {
2957         if (!window->display->shell)
2958                 return;
2959
2960         if ((window->type == TYPE_FULLSCREEN) == fullscreen)
2961                 return;
2962
2963         if (fullscreen) {
2964                 window->type = TYPE_FULLSCREEN;
2965                 window->saved_allocation = window->allocation;
2966                 wl_shell_surface_set_fullscreen(window->shell_surface,
2967                                                 WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
2968                                                 0, NULL);
2969         } else {
2970                 window->type = TYPE_TOPLEVEL;
2971                 wl_shell_surface_set_toplevel(window->shell_surface);
2972                 window_schedule_resize(window,
2973                                        window->saved_allocation.width,
2974                                        window->saved_allocation.height);
2975         }
2976 }
2977
2978 void
2979 window_set_maximized(struct window *window, int maximized)
2980 {
2981         if (!window->display->shell)
2982                 return;
2983
2984         if ((window->type == TYPE_MAXIMIZED) == maximized)
2985                 return;
2986
2987         if (window->type == TYPE_TOPLEVEL) {
2988                 window->saved_allocation = window->allocation;
2989                 wl_shell_surface_set_maximized(window->shell_surface, NULL);
2990                 window->type = TYPE_MAXIMIZED;
2991         } else {
2992                 wl_shell_surface_set_toplevel(window->shell_surface);
2993                 window->type = TYPE_TOPLEVEL;
2994                 window_schedule_resize(window,
2995                                        window->saved_allocation.width,
2996                                        window->saved_allocation.height);
2997         }
2998 }
2999
3000 void
3001 window_set_user_data(struct window *window, void *data)
3002 {
3003         window->user_data = data;
3004 }
3005
3006 void *
3007 window_get_user_data(struct window *window)
3008 {
3009         return window->user_data;
3010 }
3011
3012 void
3013 window_set_key_handler(struct window *window,
3014                        window_key_handler_t handler)
3015 {
3016         window->key_handler = handler;
3017 }
3018
3019 void
3020 window_set_keyboard_focus_handler(struct window *window,
3021                                   window_keyboard_focus_handler_t handler)
3022 {
3023         window->keyboard_focus_handler = handler;
3024 }
3025
3026 void
3027 window_set_data_handler(struct window *window, window_data_handler_t handler)
3028 {
3029         window->data_handler = handler;
3030 }
3031
3032 void
3033 window_set_drop_handler(struct window *window, window_drop_handler_t handler)
3034 {
3035         window->drop_handler = handler;
3036 }
3037
3038 void
3039 window_set_close_handler(struct window *window,
3040                          window_close_handler_t handler)
3041 {
3042         window->close_handler = handler;
3043 }
3044
3045 void
3046 window_set_fullscreen_handler(struct window *window,
3047                               window_fullscreen_handler_t handler)
3048 {
3049         window->fullscreen_handler = handler;
3050 }
3051
3052 void
3053 window_set_title(struct window *window, const char *title)
3054 {
3055         free(window->title);
3056         window->title = strdup(title);
3057         if (window->shell_surface)
3058                 wl_shell_surface_set_title(window->shell_surface, title);
3059 }
3060
3061 const char *
3062 window_get_title(struct window *window)
3063 {
3064         return window->title;
3065 }
3066
3067 void
3068 window_set_text_cursor_position(struct window *window, int32_t x, int32_t y)
3069 {
3070         struct text_cursor_position *text_cursor_position =
3071                                         window->display->text_cursor_position;
3072
3073         if (!text_cursor_position)
3074                 return;
3075
3076         text_cursor_position_notify(text_cursor_position,
3077                                                 window->surface,
3078                                                 wl_fixed_from_int(x),
3079                                                 wl_fixed_from_int(y));
3080 }
3081
3082 void
3083 window_damage(struct window *window, int32_t x, int32_t y,
3084               int32_t width, int32_t height)
3085 {
3086         wl_surface_damage(window->surface, x, y, width, height);
3087 }
3088
3089 static void
3090 surface_enter(void *data,
3091               struct wl_surface *wl_surface, struct wl_output *wl_output)
3092 {
3093         struct window *window = data;
3094         struct output *output;
3095         struct output *output_found = NULL;
3096         struct window_output *window_output;
3097
3098         wl_list_for_each(output, &window->display->output_list, link) {
3099                 if (output->output == wl_output) {
3100                         output_found = output;
3101                         break;
3102                 }
3103         }
3104
3105         if (!output_found)
3106                 return;
3107
3108         window_output = malloc (sizeof *window_output);
3109         window_output->output = output_found;
3110
3111         wl_list_insert (&window->window_output_list, &window_output->link);
3112 }
3113
3114 static void
3115 surface_leave(void *data,
3116               struct wl_surface *wl_surface, struct wl_output *output)
3117 {
3118         struct window *window = data;
3119         struct window_output *window_output;
3120         struct window_output *window_output_found = NULL;
3121
3122         wl_list_for_each(window_output, &window->window_output_list, link) {
3123                 if (window_output->output->output == output) {
3124                         window_output_found = window_output;
3125                         break;
3126                 }
3127         }
3128
3129         if (window_output_found) {
3130                 wl_list_remove(&window_output_found->link);
3131                 free(window_output_found);
3132         }
3133 }
3134
3135 static const struct wl_surface_listener surface_listener = {
3136         surface_enter,
3137         surface_leave
3138 };
3139
3140 static struct window *
3141 window_create_internal(struct display *display,
3142                        struct window *parent, int type)
3143 {
3144         struct window *window;
3145
3146         window = malloc(sizeof *window);
3147         if (window == NULL)
3148                 return NULL;
3149
3150         memset(window, 0, sizeof *window);
3151         window->display = display;
3152         window->parent = parent;
3153         window->surface = wl_compositor_create_surface(display->compositor);
3154         wl_surface_add_listener(window->surface, &surface_listener, window);
3155         if (type != TYPE_CUSTOM && display->shell) {
3156                 window->shell_surface =
3157                         wl_shell_get_shell_surface(display->shell,
3158                                                    window->surface);
3159         }
3160         window->allocation.x = 0;
3161         window->allocation.y = 0;
3162         window->allocation.width = 0;
3163         window->allocation.height = 0;
3164         window->saved_allocation = window->allocation;
3165         window->transparent = 1;
3166         window->type = type;
3167         window->input_region = NULL;
3168         window->opaque_region = NULL;
3169
3170         if (display->dpy)
3171 #ifdef HAVE_CAIRO_EGL
3172                 window->buffer_type = WINDOW_BUFFER_TYPE_EGL_WINDOW;
3173 #else
3174                 window->buffer_type = WINDOW_BUFFER_TYPE_SHM;
3175 #endif
3176         else
3177                 window->buffer_type = WINDOW_BUFFER_TYPE_SHM;
3178
3179         wl_surface_set_user_data(window->surface, window);
3180         wl_list_insert(display->window_list.prev, &window->link);
3181         wl_list_init(&window->redraw_task.link);
3182
3183         if (window->shell_surface) {
3184                 wl_shell_surface_set_user_data(window->shell_surface, window);
3185                 wl_shell_surface_add_listener(window->shell_surface,
3186                                               &shell_surface_listener, window);
3187         }
3188
3189         wl_list_init (&window->window_output_list);
3190
3191         return window;
3192 }
3193
3194 struct window *
3195 window_create(struct display *display)
3196 {
3197         struct window *window;
3198
3199         window = window_create_internal(display, NULL, TYPE_NONE);
3200         if (!window)
3201                 return NULL;
3202
3203         return window;
3204 }
3205
3206 struct window *
3207 window_create_custom(struct display *display)
3208 {
3209         struct window *window;
3210
3211         window = window_create_internal(display, NULL, TYPE_CUSTOM);
3212         if (!window)
3213                 return NULL;
3214
3215         return window;
3216 }
3217
3218 struct window *
3219 window_create_transient(struct display *display, struct window *parent,
3220                         int32_t x, int32_t y, uint32_t flags)
3221 {
3222         struct window *window;
3223
3224         window = window_create_internal(parent->display,
3225                                         parent, TYPE_TRANSIENT);
3226         if (!window)
3227                 return NULL;
3228
3229         window->x = x;
3230         window->y = y;
3231
3232         if (display->shell)
3233                 wl_shell_surface_set_transient(window->shell_surface,
3234                                                window->parent->surface,
3235                                                window->x, window->y, flags);
3236
3237         return window;
3238 }
3239
3240 static void
3241 menu_set_item(struct menu *menu, int sy)
3242 {
3243         int next;
3244
3245         next = (sy - 8) / 20;
3246         if (menu->current != next) {
3247                 menu->current = next;
3248                 widget_schedule_redraw(menu->widget);
3249         }
3250 }
3251
3252 static int
3253 menu_motion_handler(struct widget *widget,
3254                     struct input *input, uint32_t time,
3255                     float x, float y, void *data)
3256 {
3257         struct menu *menu = data;
3258
3259         if (widget == menu->widget)
3260                 menu_set_item(data, y);
3261
3262         return CURSOR_LEFT_PTR;
3263 }
3264
3265 static int
3266 menu_enter_handler(struct widget *widget,
3267                    struct input *input, float x, float y, void *data)
3268 {
3269         struct menu *menu = data;
3270
3271         if (widget == menu->widget)
3272                 menu_set_item(data, y);
3273
3274         return CURSOR_LEFT_PTR;
3275 }
3276
3277 static void
3278 menu_leave_handler(struct widget *widget, struct input *input, void *data)
3279 {
3280         struct menu *menu = data;
3281
3282         if (widget == menu->widget)
3283                 menu_set_item(data, -200);
3284 }
3285
3286 static void
3287 menu_button_handler(struct widget *widget,
3288                     struct input *input, uint32_t time,
3289                     uint32_t button, enum wl_pointer_button_state state,
3290                     void *data)
3291
3292 {
3293         struct menu *menu = data;
3294
3295         if (state == WL_POINTER_BUTTON_STATE_PRESSED &&
3296             time - menu->time > 500) {
3297                 /* Either relase after press-drag-release or
3298                  * click-motion-click. */
3299                 menu->func(menu->window->parent, 
3300                            menu->current, menu->window->parent->user_data);
3301                 input_ungrab(input);
3302                 menu_destroy(menu);
3303         }
3304 }
3305
3306 static void
3307 menu_redraw_handler(struct widget *widget, void *data)
3308 {
3309         cairo_t *cr;
3310         const int32_t r = 3, margin = 3;
3311         struct menu *menu = data;
3312         int32_t width, height, i;
3313         struct window *window = widget->window;
3314
3315         cr = cairo_create(window->cairo_surface);
3316         cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
3317         cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
3318         cairo_paint(cr);
3319
3320         width = window->allocation.width;
3321         height = window->allocation.height;
3322         rounded_rect(cr, 0, 0, width, height, r);
3323
3324         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
3325         cairo_set_source_rgba(cr, 0.0, 0.0, 0.4, 0.8);
3326         cairo_fill(cr);
3327
3328         for (i = 0; i < menu->count; i++) {
3329                 if (i == menu->current) {
3330                         cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
3331                         cairo_rectangle(cr, margin, i * 20 + margin,
3332                                         width - 2 * margin, 20);
3333                         cairo_fill(cr);
3334                         cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
3335                         cairo_move_to(cr, 10, i * 20 + 16);
3336                         cairo_show_text(cr, menu->entries[i]);
3337                 } else {
3338                         cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
3339                         cairo_move_to(cr, 10, i * 20 + 16);
3340                         cairo_show_text(cr, menu->entries[i]);
3341                 }
3342         }
3343
3344         cairo_destroy(cr);
3345 }
3346
3347 void
3348 window_show_menu(struct display *display,
3349                  struct input *input, uint32_t time, struct window *parent,
3350                  int32_t x, int32_t y,
3351                  menu_func_t func, const char **entries, int count)
3352 {
3353         struct window *window;
3354         struct menu *menu;
3355         const int32_t margin = 3;
3356
3357         menu = malloc(sizeof *menu);
3358         if (!menu)
3359                 return;
3360
3361         window = window_create_internal(parent->display, parent, TYPE_MENU);
3362         if (!window) {
3363                 free(menu);
3364                 return;
3365         }
3366
3367         menu->window = window;
3368         menu->widget = window_add_widget(menu->window, menu);
3369         menu->entries = entries;
3370         menu->count = count;
3371         menu->current = -1;
3372         menu->time = time;
3373         menu->func = func;
3374         menu->input = input;
3375         window->type = TYPE_MENU;
3376         window->x = x;
3377         window->y = y;
3378
3379         input_ungrab(input);
3380         wl_shell_surface_set_popup(window->shell_surface, input->seat,
3381                                    display_get_serial(window->display),
3382                                    window->parent->surface,
3383                                    window->x, window->y, 0);
3384
3385         widget_set_redraw_handler(menu->widget, menu_redraw_handler);
3386         widget_set_enter_handler(menu->widget, menu_enter_handler);
3387         widget_set_leave_handler(menu->widget, menu_leave_handler);
3388         widget_set_motion_handler(menu->widget, menu_motion_handler);
3389         widget_set_button_handler(menu->widget, menu_button_handler);
3390
3391         input_grab(input, menu->widget, 0);
3392         window_schedule_resize(window, 200, count * 20 + margin * 2);
3393 }
3394
3395 void
3396 window_set_buffer_type(struct window *window, enum window_buffer_type type)
3397 {
3398         window->buffer_type = type;
3399 }
3400
3401
3402 static void
3403 display_handle_geometry(void *data,
3404                         struct wl_output *wl_output,
3405                         int x, int y,
3406                         int physical_width,
3407                         int physical_height,
3408                         int subpixel,
3409                         const char *make,
3410                         const char *model,
3411                         int transform)
3412 {
3413         struct output *output = data;
3414
3415         output->allocation.x = x;
3416         output->allocation.y = y;
3417 }
3418
3419 static void
3420 display_handle_mode(void *data,
3421                     struct wl_output *wl_output,
3422                     uint32_t flags,
3423                     int width,
3424                     int height,
3425                     int refresh)
3426 {
3427         struct output *output = data;
3428         struct display *display = output->display;
3429
3430         if (flags & WL_OUTPUT_MODE_CURRENT) {
3431                 output->allocation.width = width;
3432                 output->allocation.height = height;
3433                 if (display->output_configure_handler)
3434                         (*display->output_configure_handler)(
3435                                                 output, display->user_data);
3436         }
3437 }
3438
3439 static const struct wl_output_listener output_listener = {
3440         display_handle_geometry,
3441         display_handle_mode
3442 };
3443
3444 static void
3445 display_add_output(struct display *d, uint32_t id)
3446 {
3447         struct output *output;
3448
3449         output = malloc(sizeof *output);
3450         if (output == NULL)
3451                 return;
3452
3453         memset(output, 0, sizeof *output);
3454         output->display = d;
3455         output->output =
3456                 wl_display_bind(d->display, id, &wl_output_interface);
3457         wl_list_insert(d->output_list.prev, &output->link);
3458
3459         wl_output_add_listener(output->output, &output_listener, output);
3460 }
3461
3462 static void
3463 output_destroy(struct output *output)
3464 {
3465         if (output->destroy_handler)
3466                 (*output->destroy_handler)(output, output->user_data);
3467
3468         wl_output_destroy(output->output);
3469         wl_list_remove(&output->link);
3470         free(output);
3471 }
3472
3473 void
3474 display_set_output_configure_handler(struct display *display,
3475                                      display_output_handler_t handler)
3476 {
3477         struct output *output;
3478
3479         display->output_configure_handler = handler;
3480         if (!handler)
3481                 return;
3482
3483         wl_list_for_each(output, &display->output_list, link)
3484                 (*display->output_configure_handler)(output,
3485                                                      display->user_data);
3486 }
3487
3488 void
3489 output_set_user_data(struct output *output, void *data)
3490 {
3491         output->user_data = data;
3492 }
3493
3494 void *
3495 output_get_user_data(struct output *output)
3496 {
3497         return output->user_data;
3498 }
3499
3500 void
3501 output_set_destroy_handler(struct output *output,
3502                            display_output_handler_t handler)
3503 {
3504         output->destroy_handler = handler;
3505         /* FIXME: implement this, once we have way to remove outputs */
3506 }
3507
3508 void
3509 output_get_allocation(struct output *output, struct rectangle *allocation)
3510 {
3511         *allocation = output->allocation;
3512 }
3513
3514 struct wl_output *
3515 output_get_wl_output(struct output *output)
3516 {
3517         return output->output;
3518 }
3519
3520 static void
3521 fini_xkb(struct input *input)
3522 {
3523         xkb_state_unref(input->xkb.state);
3524         xkb_map_unref(input->xkb.keymap);
3525 }
3526
3527 static void
3528 display_add_input(struct display *d, uint32_t id)
3529 {
3530         struct input *input;
3531
3532         input = malloc(sizeof *input);
3533         if (input == NULL)
3534                 return;
3535
3536         memset(input, 0, sizeof *input);
3537         input->display = d;
3538         input->seat = wl_display_bind(d->display, id, &wl_seat_interface);
3539         input->pointer_focus = NULL;
3540         input->keyboard_focus = NULL;
3541         wl_list_insert(d->input_list.prev, &input->link);
3542
3543         wl_seat_add_listener(input->seat, &seat_listener, input);
3544         wl_seat_set_user_data(input->seat, input);
3545
3546         input->data_device =
3547                 wl_data_device_manager_get_data_device(d->data_device_manager,
3548                                                        input->seat);
3549         wl_data_device_add_listener(input->data_device, &data_device_listener,
3550                                     input);
3551
3552         input->pointer_surface = wl_compositor_create_surface(d->compositor);
3553
3554         input->repeat_timer_fd = timerfd_create(CLOCK_MONOTONIC,
3555                                                 TFD_CLOEXEC | TFD_NONBLOCK);
3556         input->repeat_task.run = keyboard_repeat_func;
3557         display_watch_fd(d, input->repeat_timer_fd,
3558                          EPOLLIN, &input->repeat_task);
3559 }
3560
3561 static void
3562 input_destroy(struct input *input)
3563 {
3564         input_remove_keyboard_focus(input);
3565         input_remove_pointer_focus(input);
3566
3567         if (input->drag_offer)
3568                 data_offer_destroy(input->drag_offer);
3569
3570         if (input->selection_offer)
3571                 data_offer_destroy(input->selection_offer);
3572
3573         wl_data_device_destroy(input->data_device);
3574         fini_xkb(input);
3575
3576         wl_surface_destroy(input->pointer_surface);
3577
3578         wl_list_remove(&input->link);
3579         wl_seat_destroy(input->seat);
3580         close(input->repeat_timer_fd);
3581         free(input);
3582 }
3583
3584 static void
3585 init_workspace_manager(struct display *d, uint32_t id)
3586 {
3587         d->workspace_manager =
3588                 wl_display_bind(d->display, id, &workspace_manager_interface);
3589         if (d->workspace_manager != NULL)
3590                 workspace_manager_add_listener(d->workspace_manager,
3591                                                &workspace_manager_listener,
3592                                                d);
3593 }
3594
3595 static void
3596 display_handle_global(struct wl_display *display, uint32_t id,
3597                       const char *interface, uint32_t version, void *data)
3598 {
3599         struct display *d = data;
3600
3601         if (strcmp(interface, "wl_compositor") == 0) {
3602                 d->compositor =
3603                         wl_display_bind(display, id, &wl_compositor_interface);
3604         } else if (strcmp(interface, "wl_output") == 0) {
3605                 display_add_output(d, id);
3606         } else if (strcmp(interface, "wl_seat") == 0) {
3607                 display_add_input(d, id);
3608         } else if (strcmp(interface, "wl_shell") == 0) {
3609                 d->shell = wl_display_bind(display, id, &wl_shell_interface);
3610         } else if (strcmp(interface, "wl_shm") == 0) {
3611                 d->shm = wl_display_bind(display, id, &wl_shm_interface);
3612         } else if (strcmp(interface, "wl_data_device_manager") == 0) {
3613                 d->data_device_manager =
3614                         wl_display_bind(display, id,
3615                                         &wl_data_device_manager_interface);
3616         } else if (strcmp(interface, "text_cursor_position") == 0) {
3617                 d->text_cursor_position =
3618                         wl_display_bind(display, id,
3619                                         &text_cursor_position_interface);
3620         } else if (strcmp(interface, "workspace_manager") == 0) {
3621                 init_workspace_manager(d, id);
3622         }
3623 }
3624
3625 #ifdef HAVE_CAIRO_EGL
3626 static int
3627 init_egl(struct display *d)
3628 {
3629         EGLint major, minor;
3630         EGLint n;
3631
3632 #ifdef USE_CAIRO_GLESV2
3633 #  define GL_BIT EGL_OPENGL_ES2_BIT
3634 #else
3635 #  define GL_BIT EGL_OPENGL_BIT
3636 #endif
3637
3638         static const EGLint argb_cfg_attribs[] = {
3639                 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PIXMAP_BIT,
3640                 EGL_RED_SIZE, 1,
3641                 EGL_GREEN_SIZE, 1,
3642                 EGL_BLUE_SIZE, 1,
3643                 EGL_ALPHA_SIZE, 1,
3644                 EGL_DEPTH_SIZE, 1,
3645                 EGL_RENDERABLE_TYPE, GL_BIT,
3646                 EGL_NONE
3647         };
3648
3649 #ifdef USE_CAIRO_GLESV2
3650         static const EGLint context_attribs[] = {
3651                 EGL_CONTEXT_CLIENT_VERSION, 2,
3652                 EGL_NONE
3653         };
3654         EGLint api = EGL_OPENGL_ES_API;
3655 #else
3656         EGLint *context_attribs = NULL;
3657         EGLint api = EGL_OPENGL_API;
3658 #endif
3659
3660         d->dpy = eglGetDisplay(d->display);
3661         if (!eglInitialize(d->dpy, &major, &minor)) {
3662                 fprintf(stderr, "failed to initialize display\n");
3663                 return -1;
3664         }
3665
3666         if (!eglBindAPI(api)) {
3667                 fprintf(stderr, "failed to bind api EGL_OPENGL_API\n");
3668                 return -1;
3669         }
3670
3671         if (!eglChooseConfig(d->dpy, argb_cfg_attribs,
3672                              &d->argb_config, 1, &n) || n != 1) {
3673                 fprintf(stderr, "failed to choose argb config\n");
3674                 return -1;
3675         }
3676
3677         d->argb_ctx = eglCreateContext(d->dpy, d->argb_config,
3678                                        EGL_NO_CONTEXT, context_attribs);
3679         if (d->argb_ctx == NULL) {
3680                 fprintf(stderr, "failed to create context\n");
3681                 return -1;
3682         }
3683
3684         if (!eglMakeCurrent(d->dpy, NULL, NULL, d->argb_ctx)) {
3685                 fprintf(stderr, "failed to make context current\n");
3686                 return -1;
3687         }
3688
3689 #ifdef HAVE_CAIRO_EGL
3690         d->argb_device = cairo_egl_device_create(d->dpy, d->argb_ctx);
3691         if (cairo_device_status(d->argb_device) != CAIRO_STATUS_SUCCESS) {
3692                 fprintf(stderr, "failed to get cairo egl argb device\n");
3693                 return -1;
3694         }
3695 #endif
3696
3697         return 0;
3698 }
3699
3700 static void
3701 fini_egl(struct display *display)
3702 {
3703 #ifdef HAVE_CAIRO_EGL
3704         cairo_device_destroy(display->argb_device);
3705 #endif
3706
3707         eglMakeCurrent(display->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE,
3708                        EGL_NO_CONTEXT);
3709
3710         eglTerminate(display->dpy);
3711         eglReleaseThread();
3712 }
3713 #endif
3714
3715 static int
3716 event_mask_update(uint32_t mask, void *data)
3717 {
3718         struct display *d = data;
3719
3720         d->mask = mask;
3721
3722         return 0;
3723 }
3724
3725 static void
3726 handle_display_data(struct task *task, uint32_t events)
3727 {
3728         struct display *display =
3729                 container_of(task, struct display, display_task);
3730         
3731         wl_display_iterate(display->display, display->mask);
3732 }
3733
3734 struct display *
3735 display_create(int argc, char *argv[])
3736 {
3737         struct display *d;
3738
3739         d = malloc(sizeof *d);
3740         if (d == NULL)
3741                 return NULL;
3742
3743         memset(d, 0, sizeof *d);
3744
3745         d->display = wl_display_connect(NULL);
3746         if (d->display == NULL) {
3747                 fprintf(stderr, "failed to create display: %m\n");
3748                 return NULL;
3749         }
3750
3751         d->epoll_fd = os_epoll_create_cloexec();
3752         d->display_fd = wl_display_get_fd(d->display, event_mask_update, d);
3753         d->display_task.run = handle_display_data;
3754         display_watch_fd(d, d->display_fd, EPOLLIN, &d->display_task);
3755
3756         wl_list_init(&d->deferred_list);
3757         wl_list_init(&d->input_list);
3758         wl_list_init(&d->output_list);
3759
3760         d->xkb_context = xkb_context_new(0);
3761         if (d->xkb_context == NULL) {
3762                 fprintf(stderr, "Failed to create XKB context\n");
3763                 return NULL;
3764         }
3765
3766         /* Set up listener so we'll catch all events. */
3767         wl_display_add_global_listener(d->display,
3768                                        display_handle_global, d);
3769
3770         /* Process connection events. */
3771         wl_display_iterate(d->display, WL_DISPLAY_READABLE);
3772 #ifdef HAVE_CAIRO_EGL
3773         if (init_egl(d) < 0)
3774                 return NULL;
3775 #endif
3776
3777         d->image_target_texture_2d =
3778                 (void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
3779         d->create_image = (void *) eglGetProcAddress("eglCreateImageKHR");
3780         d->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR");
3781
3782         create_cursors(d);
3783
3784         d->theme = theme_create();
3785
3786         wl_list_init(&d->window_list);
3787
3788         d->workspace = 0;
3789         d->workspace_count = 1;
3790
3791         return d;
3792 }
3793
3794 static void
3795 display_destroy_outputs(struct display *display)
3796 {
3797         struct output *tmp;
3798         struct output *output;
3799
3800         wl_list_for_each_safe(output, tmp, &display->output_list, link)
3801                 output_destroy(output);
3802 }
3803
3804 static void
3805 display_destroy_inputs(struct display *display)
3806 {
3807         struct input *tmp;
3808         struct input *input;
3809
3810         wl_list_for_each_safe(input, tmp, &display->input_list, link)
3811                 input_destroy(input);
3812 }
3813
3814 void
3815 display_destroy(struct display *display)
3816 {
3817         if (!wl_list_empty(&display->window_list))
3818                 fprintf(stderr, "toytoolkit warning: windows exist.\n");
3819
3820         if (!wl_list_empty(&display->deferred_list))
3821                 fprintf(stderr, "toytoolkit warning: deferred tasks exist.\n");
3822
3823         display_destroy_outputs(display);
3824         display_destroy_inputs(display);
3825
3826         xkb_context_unref(display->xkb_context);
3827
3828         theme_destroy(display->theme);
3829         destroy_cursors(display);
3830
3831 #ifdef HAVE_CAIRO_EGL
3832         fini_egl(display);
3833 #endif
3834
3835         if (display->shell)
3836                 wl_shell_destroy(display->shell);
3837
3838         if (display->shm)
3839                 wl_shm_destroy(display->shm);
3840
3841         if (display->data_device_manager)
3842                 wl_data_device_manager_destroy(display->data_device_manager);
3843
3844         wl_compositor_destroy(display->compositor);
3845
3846         close(display->epoll_fd);
3847
3848         wl_display_flush(display->display);
3849         wl_display_disconnect(display->display);
3850         free(display);
3851 }
3852
3853 void
3854 display_set_user_data(struct display *display, void *data)
3855 {
3856         display->user_data = data;
3857 }
3858
3859 void *
3860 display_get_user_data(struct display *display)
3861 {
3862         return display->user_data;
3863 }
3864
3865 struct wl_display *
3866 display_get_display(struct display *display)
3867 {
3868         return display->display;
3869 }
3870
3871 struct output *
3872 display_get_output(struct display *display)
3873 {
3874         return container_of(display->output_list.next, struct output, link);
3875 }
3876
3877 struct wl_compositor *
3878 display_get_compositor(struct display *display)
3879 {
3880         return display->compositor;
3881 }
3882
3883 uint32_t
3884 display_get_serial(struct display *display)
3885 {
3886         return display->serial;
3887 }
3888
3889 EGLDisplay
3890 display_get_egl_display(struct display *d)
3891 {
3892         return d->dpy;
3893 }
3894
3895 struct wl_data_source *
3896 display_create_data_source(struct display *display)
3897 {
3898         return wl_data_device_manager_create_data_source(display->data_device_manager);
3899 }
3900
3901 EGLConfig
3902 display_get_argb_egl_config(struct display *d)
3903 {
3904         return d->argb_config;
3905 }
3906
3907 struct wl_shell *
3908 display_get_shell(struct display *display)
3909 {
3910         return display->shell;
3911 }
3912
3913 int
3914 display_acquire_window_surface(struct display *display,
3915                                struct window *window,
3916                                EGLContext ctx)
3917 {
3918 #ifdef HAVE_CAIRO_EGL
3919         struct egl_window_surface_data *data;
3920         cairo_device_t *device;
3921
3922         if (!window->cairo_surface)
3923                 return -1;
3924         device = cairo_surface_get_device(window->cairo_surface);
3925         if (!device)
3926                 return -1;
3927
3928         if (!ctx) {
3929                 if (device == display->argb_device)
3930                         ctx = display->argb_ctx;
3931                 else
3932                         assert(0);
3933         }
3934
3935         data = cairo_surface_get_user_data(window->cairo_surface,
3936                                            &surface_data_key);
3937
3938         cairo_device_flush(device);
3939         cairo_device_acquire(device);
3940         if (!eglMakeCurrent(display->dpy, data->surf, data->surf, ctx))
3941                 fprintf(stderr, "failed to make surface current\n");
3942
3943         return 0;
3944 #else
3945         return -1;
3946 #endif
3947 }
3948
3949 void
3950 display_release_window_surface(struct display *display,
3951                                struct window *window)
3952 {
3953 #ifdef HAVE_CAIRO_EGL
3954         cairo_device_t *device;
3955         
3956         device = cairo_surface_get_device(window->cairo_surface);
3957         if (!device)
3958                 return;
3959
3960         if (!eglMakeCurrent(display->dpy, NULL, NULL, display->argb_ctx))
3961                 fprintf(stderr, "failed to make context current\n");
3962         cairo_device_release(device);
3963 #endif
3964 }
3965
3966 void
3967 display_defer(struct display *display, struct task *task)
3968 {
3969         wl_list_insert(&display->deferred_list, &task->link);
3970 }
3971
3972 void
3973 display_watch_fd(struct display *display,
3974                  int fd, uint32_t events, struct task *task)
3975 {
3976         struct epoll_event ep;
3977
3978         ep.events = events;
3979         ep.data.ptr = task;
3980         epoll_ctl(display->epoll_fd, EPOLL_CTL_ADD, fd, &ep);
3981 }
3982
3983 void
3984 display_run(struct display *display)
3985 {
3986         struct task *task;
3987         struct epoll_event ep[16];
3988         int i, count;
3989
3990         display->running = 1;
3991         while (1) {
3992                 wl_display_flush(display->display);
3993
3994                 while (!wl_list_empty(&display->deferred_list)) {
3995                         task = container_of(display->deferred_list.prev,
3996                                             struct task, link);
3997                         wl_list_remove(&task->link);
3998                         task->run(task, 0);
3999                 }
4000
4001                 if (!display->running)
4002                         break;
4003
4004                 wl_display_flush(display->display);
4005
4006                 count = epoll_wait(display->epoll_fd,
4007                                    ep, ARRAY_LENGTH(ep), -1);
4008                 for (i = 0; i < count; i++) {
4009                         task = ep[i].data.ptr;
4010                         task->run(task, ep[i].events);
4011                 }
4012         }
4013 }
4014
4015 void
4016 display_exit(struct display *display)
4017 {
4018         display->running = 0;
4019 }