window: use libwayland-cursor instead of libXcursor
[platform/upstream/weston.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
40 #include <pixman.h>
41
42 #include <wayland-egl.h>
43
44 #ifdef USE_CAIRO_GLESV2
45 #include <GLES2/gl2.h>
46 #include <GLES2/gl2ext.h>
47 #else
48 #include <GL/gl.h>
49 #endif
50 #include <EGL/egl.h>
51 #include <EGL/eglext.h>
52
53 #ifdef HAVE_CAIRO_EGL
54 #include <cairo-gl.h>
55 #endif
56
57 #include <xkbcommon/xkbcommon.h>
58 #include <wayland-cursor.h>
59
60 #include <linux/input.h>
61 #include <wayland-client.h>
62 #include "../shared/cairo-util.h"
63
64 #include "window.h"
65
66 struct shm_pool;
67
68 struct display {
69         struct wl_display *display;
70         struct wl_compositor *compositor;
71         struct wl_shell *shell;
72         struct wl_shm *shm;
73         struct wl_data_device_manager *data_device_manager;
74         EGLDisplay dpy;
75         EGLConfig argb_config;
76         EGLContext argb_ctx;
77         cairo_device_t *argb_device;
78         uint32_t serial;
79
80         int display_fd;
81         uint32_t mask;
82         struct task display_task;
83
84         int epoll_fd;
85         struct wl_list deferred_list;
86
87         int running;
88
89         struct wl_list window_list;
90         struct wl_list input_list;
91         struct wl_list output_list;
92
93         struct theme *theme;
94
95         struct {
96                 struct xkb_rule_names names;
97                 struct xkb_keymap *keymap;
98                 struct xkb_state *state;
99                 struct xkb_context *context;
100                 xkb_mod_mask_t control_mask;
101                 xkb_mod_mask_t alt_mask;
102                 xkb_mod_mask_t shift_mask;
103         } xkb;
104
105         struct wl_cursor_theme *cursor_theme;
106
107         PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d;
108         PFNEGLCREATEIMAGEKHRPROC create_image;
109         PFNEGLDESTROYIMAGEKHRPROC destroy_image;
110
111         display_output_handler_t output_configure_handler;
112
113         void *user_data;
114 };
115
116 enum {
117         TYPE_NONE,
118         TYPE_TOPLEVEL,
119         TYPE_FULLSCREEN,
120         TYPE_MAXIMIZED,
121         TYPE_TRANSIENT,
122         TYPE_MENU,
123         TYPE_CUSTOM
124 };
125
126 struct window_output {
127         struct output *output;
128         struct wl_list link;
129 };
130
131 struct window {
132         struct display *display;
133         struct window *parent;
134         struct wl_list window_output_list;
135         struct wl_surface *surface;
136         struct wl_shell_surface *shell_surface;
137         struct wl_region *input_region;
138         struct wl_region *opaque_region;
139         char *title;
140         struct rectangle allocation, saved_allocation, server_allocation;
141         struct rectangle pending_allocation;
142         int x, y;
143         int resize_edges;
144         int redraw_scheduled;
145         int redraw_needed;
146         struct task redraw_task;
147         int resize_needed;
148         int type;
149         int transparent;
150         struct input *keyboard_device;
151         enum window_buffer_type buffer_type;
152
153         cairo_surface_t *cairo_surface;
154
155         struct shm_pool *pool;
156
157         window_key_handler_t key_handler;
158         window_keyboard_focus_handler_t keyboard_focus_handler;
159         window_data_handler_t data_handler;
160         window_drop_handler_t drop_handler;
161         window_close_handler_t close_handler;
162
163         struct frame *frame;
164         struct widget *widget;
165
166         void *user_data;
167         struct wl_list link;
168 };
169
170 struct widget {
171         struct window *window;
172         struct wl_list child_list;
173         struct wl_list link;
174         struct rectangle allocation;
175         widget_resize_handler_t resize_handler;
176         widget_redraw_handler_t redraw_handler;
177         widget_enter_handler_t enter_handler;
178         widget_leave_handler_t leave_handler;
179         widget_motion_handler_t motion_handler;
180         widget_button_handler_t button_handler;
181         void *user_data;
182         int opaque;
183 };
184
185 struct input {
186         struct display *display;
187         struct wl_seat *seat;
188         struct wl_pointer *pointer;
189         struct wl_keyboard *keyboard;
190         struct window *pointer_focus;
191         struct window *keyboard_focus;
192         int current_cursor;
193         uint32_t modifiers;
194         uint32_t pointer_enter_serial;
195         float sx, sy;
196         struct wl_list link;
197
198         struct widget *focus_widget;
199         struct widget *grab;
200         uint32_t grab_button;
201
202         struct wl_data_device *data_device;
203         struct data_offer *drag_offer;
204         struct data_offer *selection_offer;
205 };
206
207 struct output {
208         struct display *display;
209         struct wl_output *output;
210         struct rectangle allocation;
211         struct wl_list link;
212
213         display_output_handler_t destroy_handler;
214         void *user_data;
215 };
216
217 enum frame_button_action {
218         FRAME_BUTTON_NULL = 0,
219         FRAME_BUTTON_ICON = 1,
220         FRAME_BUTTON_CLOSE = 2,
221         FRAME_BUTTON_MINIMIZE = 3,
222         FRAME_BUTTON_MAXIMIZE = 4,
223 };
224
225 enum frame_button_pointer {
226         FRAME_BUTTON_DEFAULT = 0,
227         FRAME_BUTTON_OVER = 1,
228         FRAME_BUTTON_ACTIVE = 2,
229 };
230
231 enum frame_button_align {
232         FRAME_BUTTON_RIGHT = 0,
233         FRAME_BUTTON_LEFT = 1,
234 };
235
236 enum frame_button_decoration {
237         FRAME_BUTTON_NONE = 0,
238         FRAME_BUTTON_FANCY = 1,
239 };
240
241 struct frame_button {
242         struct widget *widget;
243         struct frame *frame;
244         cairo_surface_t *icon;
245         enum frame_button_action type;
246         enum frame_button_pointer state;
247         struct wl_list link;    /* buttons_list */
248         enum frame_button_align align;
249         enum frame_button_decoration decoration;
250 };
251
252 struct frame {
253         struct widget *widget;
254         struct widget *child;
255         struct wl_list buttons_list;
256 };
257
258 struct menu {
259         struct window *window;
260         struct widget *widget;
261         struct input *input;
262         const char **entries;
263         uint32_t time;
264         int current;
265         int count;
266         menu_func_t func;
267 };
268
269 struct shm_pool {
270         struct wl_shm_pool *pool;
271         size_t size;
272         size_t used;
273         void *data;
274 };
275
276 enum {
277         WL_CURSOR_DEFAULT = 100,
278         WL_CURSOR_UNSET
279 };
280
281 enum window_location {
282         WINDOW_INTERIOR = 0,
283         WINDOW_RESIZING_TOP = 1,
284         WINDOW_RESIZING_BOTTOM = 2,
285         WINDOW_RESIZING_LEFT = 4,
286         WINDOW_RESIZING_TOP_LEFT = 5,
287         WINDOW_RESIZING_BOTTOM_LEFT = 6,
288         WINDOW_RESIZING_RIGHT = 8,
289         WINDOW_RESIZING_TOP_RIGHT = 9,
290         WINDOW_RESIZING_BOTTOM_RIGHT = 10,
291         WINDOW_RESIZING_MASK = 15,
292         WINDOW_EXTERIOR = 16,
293         WINDOW_TITLEBAR = 17,
294         WINDOW_CLIENT_AREA = 18,
295 };
296
297 const char *option_xkb_layout = "us";
298 const char *option_xkb_variant = "";
299 const char *option_xkb_options = "";
300
301 static const struct weston_option xkb_options[] = {
302         { WESTON_OPTION_STRING, "xkb-layout", 0, &option_xkb_layout },
303         { WESTON_OPTION_STRING, "xkb-variant", 0, &option_xkb_variant },
304         { WESTON_OPTION_STRING, "xkb-options", 0, &option_xkb_options },
305 };
306
307 static const cairo_user_data_key_t surface_data_key;
308 struct surface_data {
309         struct wl_buffer *buffer;
310 };
311
312 #define MULT(_d,c,a,t) \
313         do { t = c * a + 0x7f; _d = ((t >> 8) + t) >> 8; } while (0)
314
315 #ifdef HAVE_CAIRO_EGL
316
317 struct egl_window_surface_data {
318         struct display *display;
319         struct wl_surface *surface;
320         struct wl_egl_window *window;
321         EGLSurface surf;
322 };
323
324 static void
325 egl_window_surface_data_destroy(void *p)
326 {
327         struct egl_window_surface_data *data = p;
328         struct display *d = data->display;
329
330         eglDestroySurface(d->dpy, data->surf);
331         wl_egl_window_destroy(data->window);
332         data->surface = NULL;
333
334         free(p);
335 }
336
337 static cairo_surface_t *
338 display_create_egl_window_surface(struct display *display,
339                                   struct wl_surface *surface,
340                                   uint32_t flags,
341                                   struct rectangle *rectangle)
342 {
343         cairo_surface_t *cairo_surface;
344         struct egl_window_surface_data *data;
345         EGLConfig config;
346         cairo_device_t *device;
347
348         data = malloc(sizeof *data);
349         if (data == NULL)
350                 return NULL;
351
352         data->display = display;
353         data->surface = surface;
354
355         config = display->argb_config;
356         device = display->argb_device;
357
358         data->window = wl_egl_window_create(surface,
359                                             rectangle->width,
360                                             rectangle->height);
361
362         data->surf = eglCreateWindowSurface(display->dpy, config,
363                                             data->window, NULL);
364
365         cairo_surface = cairo_gl_surface_create_for_egl(device,
366                                                         data->surf,
367                                                         rectangle->width,
368                                                         rectangle->height);
369
370         cairo_surface_set_user_data(cairo_surface, &surface_data_key,
371                                     data, egl_window_surface_data_destroy);
372
373         return cairo_surface;
374 }
375
376 #endif
377
378 struct wl_buffer *
379 display_get_buffer_for_surface(struct display *display,
380                                cairo_surface_t *surface)
381 {
382         struct surface_data *data;
383
384         data = cairo_surface_get_user_data (surface, &surface_data_key);
385
386         return data->buffer;
387 }
388
389 struct shm_surface_data {
390         struct surface_data data;
391         struct shm_pool *pool;
392 };
393
394 static void
395 shm_pool_destroy(struct shm_pool *pool);
396
397 static void
398 shm_surface_data_destroy(void *p)
399 {
400         struct shm_surface_data *data = p;
401
402         wl_buffer_destroy(data->data.buffer);
403         if (data->pool)
404                 shm_pool_destroy(data->pool);
405 }
406
407 static struct wl_shm_pool *
408 make_shm_pool(struct display *display, int size, void **data)
409 {
410         char filename[] = "/tmp/wayland-shm-XXXXXX";
411         struct wl_shm_pool *pool;
412         int fd;
413
414         fd = mkstemp(filename);
415         if (fd < 0) {
416                 fprintf(stderr, "open %s failed: %m\n", filename);
417                 return NULL;
418         }
419         if (ftruncate(fd, size) < 0) {
420                 fprintf(stderr, "ftruncate failed: %m\n");
421                 close(fd);
422                 return NULL;
423         }
424
425         *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
426         unlink(filename);
427
428         if (*data == MAP_FAILED) {
429                 fprintf(stderr, "mmap failed: %m\n");
430                 close(fd);
431                 return NULL;
432         }
433
434         pool = wl_shm_create_pool(display->shm, fd, size);
435
436         close(fd);
437
438         return pool;
439 }
440
441 static struct shm_pool *
442 shm_pool_create(struct display *display, size_t size)
443 {
444         struct shm_pool *pool = malloc(sizeof *pool);
445
446         if (!pool)
447                 return NULL;
448
449         pool->pool = make_shm_pool(display, size, &pool->data);
450         if (!pool->pool) {
451                 free(pool);
452                 return NULL;
453         }
454
455         pool->size = size;
456         pool->used = 0;
457
458         return pool;
459 }
460
461 static void *
462 shm_pool_allocate(struct shm_pool *pool, size_t size, int *offset)
463 {
464         if (pool->used + size > pool->size)
465                 return NULL;
466
467         *offset = pool->used;
468         pool->used += size;
469
470         return (char *) pool->data + *offset;
471 }
472
473 /* destroy the pool. this does not unmap the memory though */
474 static void
475 shm_pool_destroy(struct shm_pool *pool)
476 {
477         munmap(pool->data, pool->size);
478         wl_shm_pool_destroy(pool->pool);
479         free(pool);
480 }
481
482 /* Start allocating from the beginning of the pool again */
483 static void
484 shm_pool_reset(struct shm_pool *pool)
485 {
486         pool->used = 0;
487 }
488
489 static int
490 data_length_for_shm_surface(struct rectangle *rect)
491 {
492         int stride;
493
494         stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,
495                                                 rect->width);
496         return stride * rect->height;
497 }
498
499 static cairo_surface_t *
500 display_create_shm_surface_from_pool(struct display *display,
501                                      struct rectangle *rectangle,
502                                      uint32_t flags, struct shm_pool *pool)
503 {
504         struct shm_surface_data *data;
505         uint32_t format;
506         cairo_surface_t *surface;
507         int stride, length, offset;
508         void *map;
509
510         data = malloc(sizeof *data);
511         if (data == NULL)
512                 return NULL;
513
514         stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,
515                                                 rectangle->width);
516         length = stride * rectangle->height;
517         data->pool = NULL;
518         map = shm_pool_allocate(pool, length, &offset);
519
520         if (!map) {
521                 free(data);
522                 return NULL;
523         }
524
525         surface = cairo_image_surface_create_for_data (map,
526                                                        CAIRO_FORMAT_ARGB32,
527                                                        rectangle->width,
528                                                        rectangle->height,
529                                                        stride);
530
531         cairo_surface_set_user_data (surface, &surface_data_key,
532                                      data, shm_surface_data_destroy);
533
534         if (flags & SURFACE_OPAQUE)
535                 format = WL_SHM_FORMAT_XRGB8888;
536         else
537                 format = WL_SHM_FORMAT_ARGB8888;
538
539         data->data.buffer = wl_shm_pool_create_buffer(pool->pool, offset,
540                                                       rectangle->width,
541                                                       rectangle->height,
542                                                       stride, format);
543
544         return surface;
545 }
546
547 static cairo_surface_t *
548 display_create_shm_surface(struct display *display,
549                            struct rectangle *rectangle, uint32_t flags,
550                            struct window *window)
551 {
552         struct shm_surface_data *data;
553         struct shm_pool *pool;
554         cairo_surface_t *surface;
555
556         if (window && window->pool) {
557                 shm_pool_reset(window->pool);
558                 surface = display_create_shm_surface_from_pool(display,
559                                                                rectangle,
560                                                                flags,
561                                                                window->pool);
562                 if (surface)
563                         return surface;
564         }
565
566         pool = shm_pool_create(display,
567                                data_length_for_shm_surface(rectangle));
568         if (!pool)
569                 return NULL;
570
571         surface =
572                 display_create_shm_surface_from_pool(display, rectangle,
573                                                      flags, pool);
574
575         if (!surface) {
576                 shm_pool_destroy(pool);
577                 return NULL;
578         }
579
580         /* make sure we destroy the pool when the surface is destroyed */
581         data = cairo_surface_get_user_data(surface, &surface_data_key);
582         data->pool = pool;
583
584         return surface;
585 }
586
587 static int
588 check_size(struct rectangle *rect)
589 {
590         if (rect->width && rect->height)
591                 return 0;
592
593         fprintf(stderr, "tried to create surface of "
594                 "width: %d, height: %d\n", rect->width, rect->height);
595         return -1;
596 }
597
598 cairo_surface_t *
599 display_create_surface(struct display *display,
600                        struct wl_surface *surface,
601                        struct rectangle *rectangle,
602                        uint32_t flags)
603 {
604         if (check_size(rectangle) < 0)
605                 return NULL;
606 #ifdef HAVE_CAIRO_EGL
607         if (display->dpy)
608                 return display_create_egl_window_surface(display,
609                                                          surface,
610                                                          flags,
611                                                          rectangle);
612 #endif
613         return display_create_shm_surface(display, rectangle, flags, NULL);
614 }
615
616 struct wl_cursor_image *
617 display_get_pointer_image(struct display *display, int pointer)
618 {
619         struct wl_cursor *cursor =
620                 wl_cursor_theme_get_cursor(display->cursor_theme, pointer);
621
622         return cursor ? cursor->images[0] : NULL;
623 }
624
625 static void
626 window_get_resize_dx_dy(struct window *window, int *x, int *y)
627 {
628         if (window->resize_edges & WINDOW_RESIZING_LEFT)
629                 *x = window->server_allocation.width - window->allocation.width;
630         else
631                 *x = 0;
632
633         if (window->resize_edges & WINDOW_RESIZING_TOP)
634                 *y = window->server_allocation.height -
635                         window->allocation.height;
636         else
637                 *y = 0;
638
639         window->resize_edges = 0;
640 }
641
642 static void
643 window_attach_surface(struct window *window)
644 {
645         struct display *display = window->display;
646         struct wl_buffer *buffer;
647 #ifdef HAVE_CAIRO_EGL
648         struct egl_window_surface_data *data;
649 #endif
650         int32_t x, y;
651
652         if (window->type == TYPE_NONE) {
653                 window->type = TYPE_TOPLEVEL;
654                 if (display->shell)
655                         wl_shell_surface_set_toplevel(window->shell_surface);
656         }
657
658         switch (window->buffer_type) {
659 #ifdef HAVE_CAIRO_EGL
660         case WINDOW_BUFFER_TYPE_EGL_WINDOW:
661                 data = cairo_surface_get_user_data(window->cairo_surface,
662                                                    &surface_data_key);
663
664                 cairo_gl_surface_swapbuffers(window->cairo_surface);
665                 wl_egl_window_get_attached_size(data->window,
666                                 &window->server_allocation.width,
667                                 &window->server_allocation.height);
668                 break;
669 #endif
670         case WINDOW_BUFFER_TYPE_SHM:
671                 buffer =
672                         display_get_buffer_for_surface(display,
673                                                        window->cairo_surface);
674
675                 window_get_resize_dx_dy(window, &x, &y);
676                 wl_surface_attach(window->surface, buffer, x, y);
677                 wl_surface_damage(window->surface, 0, 0,
678                                   window->allocation.width,
679                                   window->allocation.height);
680                 window->server_allocation = window->allocation;
681                 cairo_surface_destroy(window->cairo_surface);
682                 window->cairo_surface = NULL;
683                 break;
684         default:
685                 return;
686         }
687
688         if (window->input_region) {
689                 wl_surface_set_input_region(window->surface,
690                                             window->input_region);
691                 wl_region_destroy(window->input_region);
692                 window->input_region = NULL;
693         }
694
695         if (window->opaque_region) {
696                 wl_surface_set_opaque_region(window->surface,
697                                              window->opaque_region);
698                 wl_region_destroy(window->opaque_region);
699                 window->opaque_region = NULL;
700         }
701 }
702
703 void
704 window_flush(struct window *window)
705 {
706         if (window->cairo_surface)
707                 window_attach_surface(window);
708 }
709
710 void
711 window_set_surface(struct window *window, cairo_surface_t *surface)
712 {
713         cairo_surface_reference(surface);
714
715         if (window->cairo_surface != NULL)
716                 cairo_surface_destroy(window->cairo_surface);
717
718         window->cairo_surface = surface;
719 }
720
721 #ifdef HAVE_CAIRO_EGL
722 static void
723 window_resize_cairo_window_surface(struct window *window)
724 {
725         struct egl_window_surface_data *data;
726         int x, y;
727
728         data = cairo_surface_get_user_data(window->cairo_surface,
729                                            &surface_data_key);
730
731         window_get_resize_dx_dy(window, &x, &y),
732         wl_egl_window_resize(data->window,
733                              window->allocation.width,
734                              window->allocation.height,
735                              x,y);
736
737         cairo_gl_surface_set_size(window->cairo_surface,
738                                   window->allocation.width,
739                                   window->allocation.height);
740 }
741 #endif
742
743 struct display *
744 window_get_display(struct window *window)
745 {
746         return window->display;
747 }
748
749 void
750 window_create_surface(struct window *window)
751 {
752         cairo_surface_t *surface;
753         uint32_t flags = 0;
754         
755         if (!window->transparent)
756                 flags = SURFACE_OPAQUE;
757         
758         switch (window->buffer_type) {
759 #ifdef HAVE_CAIRO_EGL
760         case WINDOW_BUFFER_TYPE_EGL_WINDOW:
761                 if (window->cairo_surface) {
762                         window_resize_cairo_window_surface(window);
763                         return;
764                 }
765                 surface = display_create_surface(window->display,
766                                                  window->surface,
767                                                  &window->allocation, flags);
768                 break;
769 #endif
770         case WINDOW_BUFFER_TYPE_SHM:
771                 surface = display_create_shm_surface(window->display,
772                                                      &window->allocation,
773                                                      flags, window);
774                 break;
775         default:
776                 surface = NULL;
777                 break;
778         }
779
780         window_set_surface(window, surface);
781         cairo_surface_destroy(surface);
782 }
783
784 static void frame_destroy(struct frame *frame);
785
786 void
787 window_destroy(struct window *window)
788 {
789         struct display *display = window->display;
790         struct input *input;
791         struct window_output *window_output;
792         struct window_output *window_output_tmp;
793
794         if (window->redraw_scheduled)
795                 wl_list_remove(&window->redraw_task.link);
796
797         wl_list_for_each(input, &display->input_list, link) {
798                 if (input->pointer_focus == window)
799                         input->pointer_focus = NULL;
800                 if (input->keyboard_focus == window)
801                         input->keyboard_focus = NULL;
802                 if (input->focus_widget &&
803                     input->focus_widget->window == window)
804                         input->focus_widget = NULL;
805         }
806
807         wl_list_for_each_safe(window_output, window_output_tmp,
808                               &window->window_output_list, link) {
809                 free (window_output);
810         }
811
812         if (window->input_region)
813                 wl_region_destroy(window->input_region);
814         if (window->opaque_region)
815                 wl_region_destroy(window->opaque_region);
816
817         if (window->frame)
818                 frame_destroy(window->frame);
819
820         if (window->shell_surface)
821                 wl_shell_surface_destroy(window->shell_surface);
822         wl_surface_destroy(window->surface);
823         wl_list_remove(&window->link);
824
825         if (window->cairo_surface != NULL)
826                 cairo_surface_destroy(window->cairo_surface);
827
828         free(window->title);
829         free(window);
830 }
831
832 static struct widget *
833 widget_find_widget(struct widget *widget, int32_t x, int32_t y)
834 {
835         struct widget *child, *target;
836
837         wl_list_for_each(child, &widget->child_list, link) {
838                 target = widget_find_widget(child, x, y);
839                 if (target)
840                         return target;
841         }
842
843         if (widget->allocation.x <= x &&
844             x < widget->allocation.x + widget->allocation.width &&
845             widget->allocation.y <= y &&
846             y < widget->allocation.y + widget->allocation.height) {
847                 return widget;
848         }
849
850         return NULL;
851 }
852
853 static struct widget *
854 widget_create(struct window *window, void *data)
855 {
856         struct widget *widget;
857
858         widget = malloc(sizeof *widget);
859         memset(widget, 0, sizeof *widget);
860         widget->window = window;
861         widget->user_data = data;
862         widget->allocation = window->allocation;
863         wl_list_init(&widget->child_list);
864         widget->opaque = 0;
865
866         return widget;
867 }
868
869 struct widget *
870 window_add_widget(struct window *window, void *data)
871 {
872         window->widget = widget_create(window, data);
873         wl_list_init(&window->widget->link);
874
875         return window->widget;
876 }
877
878 struct widget *
879 widget_add_widget(struct widget *parent, void *data)
880 {
881         struct widget *widget;
882
883         widget = widget_create(parent->window, data);
884         wl_list_insert(parent->child_list.prev, &widget->link);
885
886         return widget;
887 }
888
889 void
890 widget_destroy(struct widget *widget)
891 {
892         struct display *display = widget->window->display;
893         struct input *input;
894
895         wl_list_for_each(input, &display->input_list, link) {
896                 if (input->focus_widget == widget)
897                         input->focus_widget = NULL;
898         }
899
900         wl_list_remove(&widget->link);
901         free(widget);
902 }
903
904 void
905 widget_get_allocation(struct widget *widget, struct rectangle *allocation)
906 {
907         *allocation = widget->allocation;
908 }
909
910 void
911 widget_set_size(struct widget *widget, int32_t width, int32_t height)
912 {
913         widget->allocation.width = width;
914         widget->allocation.height = height;
915 }
916
917 void
918 widget_set_allocation(struct widget *widget,
919                       int32_t x, int32_t y, int32_t width, int32_t height)
920 {
921         widget->allocation.x = x;
922         widget->allocation.y = y;
923         widget_set_size(widget, width, height);
924 }
925
926 void
927 widget_set_transparent(struct widget *widget, int transparent)
928 {
929         widget->opaque = !transparent;
930 }
931
932 void *
933 widget_get_user_data(struct widget *widget)
934 {
935         return widget->user_data;
936 }
937
938 void
939 widget_set_resize_handler(struct widget *widget,
940                           widget_resize_handler_t handler)
941 {
942         widget->resize_handler = handler;
943 }
944
945 void
946 widget_set_redraw_handler(struct widget *widget,
947                           widget_redraw_handler_t handler)
948 {
949         widget->redraw_handler = handler;
950 }
951
952 void
953 widget_set_enter_handler(struct widget *widget, widget_enter_handler_t handler)
954 {
955         widget->enter_handler = handler;
956 }
957
958 void
959 widget_set_leave_handler(struct widget *widget, widget_leave_handler_t handler)
960 {
961         widget->leave_handler = handler;
962 }
963
964 void
965 widget_set_motion_handler(struct widget *widget,
966                           widget_motion_handler_t handler)
967 {
968         widget->motion_handler = handler;
969 }
970
971 void
972 widget_set_button_handler(struct widget *widget,
973                           widget_button_handler_t handler)
974 {
975         widget->button_handler = handler;
976 }
977
978 void
979 widget_schedule_redraw(struct widget *widget)
980 {
981         window_schedule_redraw(widget->window);
982 }
983
984 cairo_surface_t *
985 window_get_surface(struct window *window)
986 {
987         return cairo_surface_reference(window->cairo_surface);
988 }
989
990 struct wl_surface *
991 window_get_wl_surface(struct window *window)
992 {
993         return window->surface;
994 }
995
996 struct wl_shell_surface *
997 window_get_wl_shell_surface(struct window *window)
998 {
999         return window->shell_surface;
1000 }
1001
1002 static void
1003 frame_resize_handler(struct widget *widget,
1004                      int32_t width, int32_t height, void *data)
1005 {
1006         struct frame *frame = data;
1007         struct widget *child = frame->child;
1008         struct rectangle allocation;
1009         struct display *display = widget->window->display;
1010         struct frame_button * button;
1011         struct theme *t = display->theme;
1012         int x_l, x_r, y, w, h;
1013         int decoration_width, decoration_height;
1014         int opaque_margin;
1015
1016         if (widget->window->type != TYPE_FULLSCREEN) {
1017                 decoration_width = (t->width + t->margin) * 2;
1018                 decoration_height = t->width +
1019                         t->titlebar_height + t->margin * 2;
1020
1021                 allocation.x = t->width + t->margin;
1022                 allocation.y = t->titlebar_height + t->margin;
1023                 allocation.width = width - decoration_width;
1024                 allocation.height = height - decoration_height;
1025
1026                 opaque_margin = t->margin + t->frame_radius;
1027
1028                 wl_list_for_each(button, &frame->buttons_list, link)
1029                         button->widget->opaque = 0;
1030         } else {
1031                 decoration_width = 0;
1032                 decoration_height = 0;
1033
1034                 allocation.x = 0;
1035                 allocation.y = 0;
1036                 allocation.width = width;
1037                 allocation.height = height;
1038                 opaque_margin = 0;
1039
1040                 wl_list_for_each(button, &frame->buttons_list, link)
1041                         button->widget->opaque = 1;
1042         }
1043
1044         widget_set_allocation(child, allocation.x, allocation.y,
1045                               allocation.width, allocation.height);
1046
1047         if (child->resize_handler)
1048                 child->resize_handler(child,
1049                                       allocation.width,
1050                                       allocation.height,
1051                                       child->user_data);
1052
1053         width = child->allocation.width + decoration_width;
1054         height = child->allocation.height + decoration_height;
1055
1056         widget->window->input_region =
1057                       wl_compositor_create_region(display->compositor);
1058         wl_region_add(widget->window->input_region,
1059                       t->margin, t->margin,
1060                       width - 2 * t->margin,
1061                       height - 2 * t->margin);
1062
1063         widget_set_allocation(widget, 0, 0, width, height);
1064
1065         if (child->opaque) {
1066                 widget->window->opaque_region =
1067                         wl_compositor_create_region(display->compositor);
1068                 wl_region_add(widget->window->opaque_region,
1069                               opaque_margin, opaque_margin,
1070                               widget->allocation.width - 2 * opaque_margin,
1071                               widget->allocation.height - 2 * opaque_margin);
1072         }
1073
1074         /* frame internal buttons */
1075         x_r = frame->widget->allocation.width - t->width - t->margin;
1076         x_l = t->width + t->margin;
1077         y = t->width + t->margin;
1078         wl_list_for_each(button, &frame->buttons_list, link) {
1079                 const int button_padding = 4;
1080                 w = cairo_image_surface_get_width(button->icon);
1081                 h = cairo_image_surface_get_height(button->icon);
1082
1083                 if (button->decoration == FRAME_BUTTON_FANCY)
1084                         w += 10;
1085
1086                 if (button->align == FRAME_BUTTON_LEFT) {
1087                         widget_set_allocation(button->widget,
1088                                               x_l, y , w + 1, h + 1);
1089                         x_l += w;
1090                         x_l += button_padding;
1091                 } else {
1092                         x_r -= w;
1093                         widget_set_allocation(button->widget,
1094                                               x_r, y , w + 1, h + 1);
1095                         x_r -= button_padding;
1096                 }
1097         }
1098 }
1099
1100 static int
1101 frame_button_enter_handler(struct widget *widget,
1102                            struct input *input, float x, float y, void *data)
1103 {
1104         struct frame_button *frame_button = data;
1105
1106         widget_schedule_redraw(frame_button->widget);
1107         frame_button->state = FRAME_BUTTON_OVER;
1108
1109         return WL_CURSOR_LEFT_PTR;
1110 }
1111
1112 static void
1113 frame_button_leave_handler(struct widget *widget, struct input *input, void *data)
1114 {
1115         struct frame_button *frame_button = data;
1116
1117         widget_schedule_redraw(frame_button->widget);
1118         frame_button->state = FRAME_BUTTON_DEFAULT;
1119 }
1120
1121 static void
1122 frame_button_button_handler(struct widget *widget,
1123                             struct input *input, uint32_t time,
1124                             uint32_t button, uint32_t state, void *data)
1125 {
1126         struct frame_button *frame_button = data;
1127         struct window *window = widget->window;
1128
1129         if (button != BTN_LEFT)
1130                 return;
1131
1132         switch (state) {
1133         case 1:
1134                 frame_button->state = FRAME_BUTTON_ACTIVE;
1135                 widget_schedule_redraw(frame_button->widget);
1136
1137                 if (frame_button->type == FRAME_BUTTON_ICON)
1138                         window_show_frame_menu(window, input, time);
1139                 return;
1140         case 0:
1141                 frame_button->state = FRAME_BUTTON_DEFAULT;
1142                 widget_schedule_redraw(frame_button->widget);
1143                 break;
1144         }
1145
1146         switch (frame_button->type) {
1147         case FRAME_BUTTON_CLOSE:
1148                 if (window->close_handler)
1149                         window->close_handler(window->parent,
1150                                               window->user_data);
1151                 else
1152                         display_exit(window->display);
1153                 break;
1154         case FRAME_BUTTON_MINIMIZE:
1155                 fprintf(stderr,"Minimize stub\n");
1156                 break;
1157         case FRAME_BUTTON_MAXIMIZE:
1158                 window_set_maximized(window, window->type != TYPE_MAXIMIZED);
1159                 break;
1160         default:
1161                 /* Unknown operation */
1162                 break;
1163         }
1164 }
1165
1166 static void
1167 frame_button_redraw_handler(struct widget *widget, void *data)
1168 {
1169         struct frame_button *frame_button = data;
1170         cairo_t *cr;
1171         int width, height, x, y;
1172         struct window *window = widget->window;
1173
1174         x = widget->allocation.x;
1175         y = widget->allocation.y;
1176         width = widget->allocation.width;
1177         height = widget->allocation.height;
1178
1179         if (!width)
1180                 return;
1181         if (!height)
1182                 return;
1183         if (widget->opaque)
1184                 return;
1185
1186         cr = cairo_create(window->cairo_surface);
1187
1188         if (frame_button->decoration == FRAME_BUTTON_FANCY) {
1189                 cairo_set_line_width(cr, 1);
1190
1191                 cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
1192                 cairo_rectangle (cr, x, y, 25, 16);
1193
1194                 cairo_stroke_preserve(cr);
1195
1196                 switch (frame_button->state) {
1197                 case FRAME_BUTTON_DEFAULT:
1198                         cairo_set_source_rgb(cr, 0.88, 0.88, 0.88);
1199                         break;
1200                 case FRAME_BUTTON_OVER:
1201                         cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
1202                         break;
1203                 case FRAME_BUTTON_ACTIVE:
1204                         cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
1205                         break;
1206                 }
1207
1208                 cairo_fill (cr);
1209
1210                 x += 4;
1211         }
1212
1213         cairo_set_source_surface(cr, frame_button->icon, x, y);
1214         cairo_paint(cr);
1215
1216         cairo_destroy(cr);
1217 }
1218
1219 static struct widget *
1220 frame_button_create(struct frame *frame, void *data, enum frame_button_action type,
1221         enum frame_button_align align, enum frame_button_decoration style)
1222 {
1223         struct frame_button *frame_button;
1224         const char *icon = data;
1225
1226         frame_button = malloc (sizeof *frame_button);
1227         memset(frame_button, 0, sizeof *frame_button);
1228
1229         frame_button->icon = cairo_image_surface_create_from_png(icon);
1230         frame_button->widget = widget_add_widget(frame->widget, frame_button);
1231         frame_button->frame = frame;
1232         frame_button->type = type;
1233         frame_button->align = align;
1234         frame_button->decoration = style;
1235
1236         wl_list_insert(frame->buttons_list.prev, &frame_button->link);
1237
1238         widget_set_redraw_handler(frame_button->widget, frame_button_redraw_handler);
1239         widget_set_enter_handler(frame_button->widget, frame_button_enter_handler);
1240         widget_set_leave_handler(frame_button->widget, frame_button_leave_handler);
1241         widget_set_button_handler(frame_button->widget, frame_button_button_handler);
1242         return frame_button->widget;
1243 }
1244
1245 static void
1246 frame_button_destroy(struct frame_button *frame_button)
1247 {
1248         widget_destroy(frame_button->widget);
1249         wl_list_remove(&frame_button->link);
1250         cairo_surface_destroy(frame_button->icon);
1251         free(frame_button);
1252
1253         return;
1254 }
1255
1256 static void
1257 frame_redraw_handler(struct widget *widget, void *data)
1258 {
1259         cairo_t *cr;
1260         struct window *window = widget->window;
1261         struct theme *t = window->display->theme;
1262         uint32_t flags = 0;
1263
1264         if (window->type == TYPE_FULLSCREEN)
1265                 return;
1266
1267         cr = cairo_create(window->cairo_surface);
1268
1269         if (window->keyboard_device)
1270                 flags |= THEME_FRAME_ACTIVE;
1271         theme_render_frame(t, cr, widget->allocation.width,
1272                            widget->allocation.height, window->title, flags);
1273
1274         cairo_destroy(cr);
1275 }
1276
1277 static int
1278 frame_get_pointer_location(struct frame *frame, int32_t x, int32_t y)
1279 {
1280         struct widget *widget = frame->widget;
1281         int vlocation, hlocation, location;
1282         const int grip_size = 8;
1283         struct theme *t = widget->window->display->theme;
1284
1285         if (x < t->margin)
1286                 hlocation = WINDOW_EXTERIOR;
1287         else if (t->margin <= x && x < t->margin + grip_size)
1288                 hlocation = WINDOW_RESIZING_LEFT;
1289         else if (x < widget->allocation.width - t->margin - grip_size)
1290                 hlocation = WINDOW_INTERIOR;
1291         else if (x < widget->allocation.width - t->margin)
1292                 hlocation = WINDOW_RESIZING_RIGHT;
1293         else
1294                 hlocation = WINDOW_EXTERIOR;
1295
1296         if (y < t->margin)
1297                 vlocation = WINDOW_EXTERIOR;
1298         else if (t->margin <= y && y < t->margin + grip_size)
1299                 vlocation = WINDOW_RESIZING_TOP;
1300         else if (y < widget->allocation.height - t->margin - grip_size)
1301                 vlocation = WINDOW_INTERIOR;
1302         else if (y < widget->allocation.height - t->margin)
1303                 vlocation = WINDOW_RESIZING_BOTTOM;
1304         else
1305                 vlocation = WINDOW_EXTERIOR;
1306
1307         location = vlocation | hlocation;
1308         if (location & WINDOW_EXTERIOR)
1309                 location = WINDOW_EXTERIOR;
1310         if (location == WINDOW_INTERIOR && y < t->margin + 50)
1311                 location = WINDOW_TITLEBAR;
1312         else if (location == WINDOW_INTERIOR)
1313                 location = WINDOW_CLIENT_AREA;
1314
1315         return location;
1316 }
1317
1318 static int
1319 frame_get_pointer_image_for_location(struct frame *frame, struct input *input)
1320 {
1321         int location;
1322
1323         location = frame_get_pointer_location(frame, input->sx, input->sy);
1324         switch (location) {
1325         case WINDOW_RESIZING_TOP:
1326                 return WL_CURSOR_TOP;
1327         case WINDOW_RESIZING_BOTTOM:
1328                 return WL_CURSOR_BOTTOM;
1329         case WINDOW_RESIZING_LEFT:
1330                 return WL_CURSOR_LEFT;
1331         case WINDOW_RESIZING_RIGHT:
1332                 return WL_CURSOR_RIGHT;
1333         case WINDOW_RESIZING_TOP_LEFT:
1334                 return WL_CURSOR_TOP_LEFT;
1335         case WINDOW_RESIZING_TOP_RIGHT:
1336                 return WL_CURSOR_TOP_RIGHT;
1337         case WINDOW_RESIZING_BOTTOM_LEFT:
1338                 return WL_CURSOR_BOTTOM_LEFT;
1339         case WINDOW_RESIZING_BOTTOM_RIGHT:
1340                 return WL_CURSOR_BOTTOM_RIGHT;
1341         case WINDOW_EXTERIOR:
1342         case WINDOW_TITLEBAR:
1343         default:
1344                 return WL_CURSOR_LEFT_PTR;
1345         }
1346 }
1347
1348 static void
1349 frame_menu_func(struct window *window, int index, void *data)
1350 {
1351         switch (index) {
1352         case 0: /* close */
1353                 if (window->close_handler)
1354                         window->close_handler(window->parent,
1355                                               window->user_data);
1356                 else
1357                         display_exit(window->display);
1358                 break;
1359         case 1: /* fullscreen */
1360                 /* we don't have a way to get out of fullscreen for now */
1361                 window_set_fullscreen(window, 1);
1362                 break;
1363         case 2: /* rotate */
1364         case 3: /* scale */
1365                 break;
1366         }
1367 }
1368
1369 void
1370 window_show_frame_menu(struct window *window,
1371                        struct input *input, uint32_t time)
1372 {
1373         int32_t x, y;
1374
1375         static const char *entries[] = {
1376                 "Close", "Fullscreen", "Rotate", "Scale"
1377         };
1378
1379         input_get_position(input, &x, &y);
1380         window_show_menu(window->display, input, time, window,
1381                          x - 10, y - 10, frame_menu_func, entries, 4);
1382 }
1383
1384 static int
1385 frame_enter_handler(struct widget *widget,
1386                     struct input *input, float x, float y, void *data)
1387 {
1388         return frame_get_pointer_image_for_location(data, input);
1389 }
1390
1391 static int
1392 frame_motion_handler(struct widget *widget,
1393                      struct input *input, uint32_t time,
1394                      float x, float y, void *data)
1395 {
1396         return frame_get_pointer_image_for_location(data, input);
1397 }
1398
1399 static void
1400 frame_button_handler(struct widget *widget,
1401                      struct input *input, uint32_t time,
1402                      uint32_t button, uint32_t state, void *data)
1403
1404 {
1405         struct frame *frame = data;
1406         struct window *window = widget->window;
1407         struct display *display = window->display;
1408         int location;
1409
1410         location = frame_get_pointer_location(frame, input->sx, input->sy);
1411
1412         if (window->display->shell && button == BTN_LEFT && state == 1) {
1413                 switch (location) {
1414                 case WINDOW_TITLEBAR:
1415                         if (!window->shell_surface)
1416                                 break;
1417                         input_set_pointer_image(input, time, WL_CURSOR_DRAGGING);
1418                         input_ungrab(input);
1419                         wl_shell_surface_move(window->shell_surface,
1420                                               input_get_seat(input),
1421                                               display->serial);
1422                         break;
1423                 case WINDOW_RESIZING_TOP:
1424                 case WINDOW_RESIZING_BOTTOM:
1425                 case WINDOW_RESIZING_LEFT:
1426                 case WINDOW_RESIZING_RIGHT:
1427                 case WINDOW_RESIZING_TOP_LEFT:
1428                 case WINDOW_RESIZING_TOP_RIGHT:
1429                 case WINDOW_RESIZING_BOTTOM_LEFT:
1430                 case WINDOW_RESIZING_BOTTOM_RIGHT:
1431                         if (!window->shell_surface)
1432                                 break;
1433                         input_ungrab(input);
1434
1435                         if (!display->dpy) {
1436                                 /* If we're using shm, allocate a big
1437                                    pool to create buffers out of while
1438                                    we resize.  We should probably base
1439                                    this number on the size of the output. */
1440                                 window->pool =
1441                                         shm_pool_create(display, 6 * 1024 * 1024);
1442                         }
1443
1444                         wl_shell_surface_resize(window->shell_surface,
1445                                                 input_get_seat(input),
1446                                                 display->serial, location);
1447                         break;
1448                 }
1449         } else if (button == BTN_RIGHT && state == 1) {
1450                 window_show_frame_menu(window, input, time);
1451         }
1452 }
1453
1454 struct widget *
1455 frame_create(struct window *window, void *data)
1456 {
1457         struct frame *frame;
1458
1459         frame = malloc(sizeof *frame);
1460         memset(frame, 0, sizeof *frame);
1461
1462         frame->widget = window_add_widget(window, frame);
1463         frame->child = widget_add_widget(frame->widget, data);
1464
1465         widget_set_redraw_handler(frame->widget, frame_redraw_handler);
1466         widget_set_resize_handler(frame->widget, frame_resize_handler);
1467         widget_set_enter_handler(frame->widget, frame_enter_handler);
1468         widget_set_motion_handler(frame->widget, frame_motion_handler);
1469         widget_set_button_handler(frame->widget, frame_button_handler);
1470
1471         /* Create empty list for frame buttons */
1472         wl_list_init(&frame->buttons_list);
1473
1474         frame_button_create(frame, DATADIR "/weston/icon_window.png",
1475                 FRAME_BUTTON_ICON, FRAME_BUTTON_LEFT, FRAME_BUTTON_NONE);
1476
1477         frame_button_create(frame, DATADIR "/weston/sign_close.png",
1478                 FRAME_BUTTON_CLOSE, FRAME_BUTTON_RIGHT, FRAME_BUTTON_FANCY);
1479
1480         frame_button_create(frame, DATADIR "/weston/sign_maximize.png",
1481                 FRAME_BUTTON_MAXIMIZE, FRAME_BUTTON_RIGHT, FRAME_BUTTON_FANCY);
1482
1483         frame_button_create(frame, DATADIR "/weston/sign_minimize.png",
1484                 FRAME_BUTTON_MINIMIZE, FRAME_BUTTON_RIGHT, FRAME_BUTTON_FANCY);
1485
1486         window->frame = frame;
1487
1488         return frame->child;
1489 }
1490
1491 static void
1492 frame_destroy(struct frame *frame)
1493 {
1494         struct frame_button *button, *tmp;
1495
1496         wl_list_for_each_safe(button, tmp, &frame->buttons_list, link)
1497                 frame_button_destroy(button);
1498
1499         /* frame->child must be destroyed by the application */
1500         widget_destroy(frame->widget);
1501         free(frame);
1502 }
1503
1504 static void
1505 input_set_focus_widget(struct input *input, struct widget *focus,
1506                        float x, float y)
1507 {
1508         struct widget *old, *widget;
1509         int pointer = WL_CURSOR_LEFT_PTR;
1510
1511         if (focus == input->focus_widget)
1512                 return;
1513
1514         old = input->focus_widget;
1515         if (old) {
1516                 widget = old;
1517                 if (input->grab)
1518                         widget = input->grab;
1519                 if (widget->leave_handler)
1520                         widget->leave_handler(old, input, widget->user_data);
1521                 input->focus_widget = NULL;
1522         }
1523
1524         if (focus) {
1525                 widget = focus;
1526                 if (input->grab)
1527                         widget = input->grab;
1528                 if (widget->enter_handler)
1529                         pointer = widget->enter_handler(focus, input, x, y,
1530                                                         widget->user_data);
1531                 input->focus_widget = focus;
1532
1533                 input_set_pointer_image(input, input->pointer_enter_serial,
1534                                         pointer);
1535         }
1536 }
1537
1538 static void
1539 pointer_handle_motion(void *data, struct wl_pointer *pointer,
1540                       uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
1541 {
1542         struct input *input = data;
1543         struct window *window = input->pointer_focus;
1544         struct widget *widget;
1545         int cursor = WL_CURSOR_LEFT_PTR;
1546         float sx = wl_fixed_to_double(sx_w);
1547         float sy = wl_fixed_to_double(sy_w);
1548
1549         input->sx = sx;
1550         input->sy = sy;
1551
1552         if (!(input->grab && input->grab_button)) {
1553                 widget = widget_find_widget(window->widget, sx, sy);
1554                 input_set_focus_widget(input, widget, sx, sy);
1555         }
1556
1557         if (input->grab)
1558                 widget = input->grab;
1559         else
1560                 widget = input->focus_widget;
1561         if (widget && widget->motion_handler)
1562                 cursor = widget->motion_handler(input->focus_widget,
1563                                                 input, time, sx, sy,
1564                                                 widget->user_data);
1565
1566         input_set_pointer_image(input, time, cursor);
1567 }
1568
1569 void
1570 input_grab(struct input *input, struct widget *widget, uint32_t button)
1571 {
1572         input->grab = widget;
1573         input->grab_button = button;
1574 }
1575
1576 void
1577 input_ungrab(struct input *input)
1578 {
1579         struct widget *widget;
1580
1581         input->grab = NULL;
1582         if (input->pointer_focus) {
1583                 widget = widget_find_widget(input->pointer_focus->widget,
1584                                             input->sx, input->sy);
1585                 input_set_focus_widget(input, widget, input->sx, input->sy);
1586         }
1587 }
1588
1589 static void
1590 pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
1591                       uint32_t time, uint32_t button, uint32_t state)
1592 {
1593         struct input *input = data;
1594         struct widget *widget;
1595
1596         input->display->serial = serial;
1597         if (input->focus_widget && input->grab == NULL && state)
1598                 input_grab(input, input->focus_widget, button);
1599
1600         widget = input->grab;
1601         if (widget && widget->button_handler)
1602                 (*widget->button_handler)(widget,
1603                                           input, time,
1604                                           button, state,
1605                                           input->grab->user_data);
1606
1607         if (input->grab && input->grab_button == button && !state)
1608                 input_ungrab(input);
1609 }
1610
1611 static void
1612 pointer_handle_axis(void *data, struct wl_pointer *pointer,
1613                     uint32_t time, uint32_t axis, int32_t value)
1614 {
1615 }
1616
1617 static void
1618 keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
1619                     uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
1620 {
1621         struct input *input = data;
1622         struct window *window = input->keyboard_focus;
1623         struct display *d = input->display;
1624         uint32_t code, num_syms;
1625         const xkb_keysym_t *syms;
1626         xkb_keysym_t sym;
1627         xkb_mod_mask_t mask;
1628
1629         input->display->serial = serial;
1630         code = key + 8;
1631         if (!window || window->keyboard_device != input)
1632                 return;
1633
1634         num_syms = xkb_key_get_syms(d->xkb.state, code, &syms);
1635         xkb_state_update_key(d->xkb.state, code,
1636                              state ? XKB_KEY_DOWN : XKB_KEY_UP);
1637
1638         mask = xkb_state_serialize_mods(d->xkb.state, 
1639                                         XKB_STATE_DEPRESSED | 
1640                                         XKB_STATE_LATCHED);
1641         input->modifiers = 0;
1642         if (mask & input->display->xkb.control_mask)
1643                 input->modifiers |= MOD_CONTROL_MASK;
1644         if (mask & input->display->xkb.alt_mask)
1645                 input->modifiers |= MOD_ALT_MASK;
1646         if (mask & input->display->xkb.shift_mask)
1647                 input->modifiers |= MOD_SHIFT_MASK;
1648
1649         if (num_syms == 1 && syms[0] == XKB_KEY_F5 &&
1650             input->modifiers == MOD_ALT_MASK) {
1651                 if (state)
1652                         window_set_maximized(window,
1653                                              window->type != TYPE_MAXIMIZED);
1654         } else if (window->key_handler) {
1655                 if (num_syms == 1)
1656                         sym = syms[0];
1657                 else
1658                         sym = XKB_KEY_NoSymbol;
1659
1660                 (*window->key_handler)(window, input, time, key,
1661                                        sym, state, window->user_data);
1662         }
1663 }
1664
1665 static void
1666 input_remove_pointer_focus(struct input *input)
1667 {
1668         struct window *window = input->pointer_focus;
1669
1670         if (!window)
1671                 return;
1672
1673         input_set_focus_widget(input, NULL, 0, 0);
1674
1675         input->pointer_focus = NULL;
1676         input->current_cursor = WL_CURSOR_UNSET;
1677 }
1678
1679 static void
1680 pointer_handle_enter(void *data, struct wl_pointer *pointer,
1681                      uint32_t serial, struct wl_surface *surface,
1682                      wl_fixed_t sx_w, wl_fixed_t sy_w)
1683 {
1684         struct input *input = data;
1685         struct window *window;
1686         struct widget *widget;
1687         float sx = wl_fixed_to_double(sx_w);
1688         float sy = wl_fixed_to_double(sy_w);
1689
1690         if (!surface) {
1691                 /* enter event for a window we've just destroyed */
1692                 return;
1693         }
1694
1695         input->display->serial = serial;
1696         input->pointer_enter_serial = serial;
1697         input->pointer_focus = wl_surface_get_user_data(surface);
1698         window = input->pointer_focus;
1699
1700         if (window->pool) {
1701                 shm_pool_destroy(window->pool);
1702                 window->pool = NULL;
1703                 /* Schedule a redraw to free the pool */
1704                 window_schedule_redraw(window);
1705         }
1706
1707         input->sx = sx;
1708         input->sy = sy;
1709
1710         widget = widget_find_widget(window->widget, sx, sy);
1711         input_set_focus_widget(input, widget, sx, sy);
1712 }
1713
1714 static void
1715 pointer_handle_leave(void *data, struct wl_pointer *pointer,
1716                      uint32_t serial, struct wl_surface *surface)
1717 {
1718         struct input *input = data;
1719
1720         input->display->serial = serial;
1721         input_remove_pointer_focus(input);
1722 }
1723
1724 static void
1725 input_remove_keyboard_focus(struct input *input)
1726 {
1727         struct window *window = input->keyboard_focus;
1728
1729         if (!window)
1730                 return;
1731
1732         window->keyboard_device = NULL;
1733         if (window->keyboard_focus_handler)
1734                 (*window->keyboard_focus_handler)(window, NULL,
1735                                                   window->user_data);
1736
1737         input->keyboard_focus = NULL;
1738 }
1739
1740 static void
1741 keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
1742                       uint32_t serial, struct wl_surface *surface,
1743                       struct wl_array *keys)
1744 {
1745         struct input *input = data;
1746         struct window *window;
1747
1748         input->display->serial = serial;
1749         input->keyboard_focus = wl_surface_get_user_data(surface);
1750
1751         window = input->keyboard_focus;
1752         window->keyboard_device = input;
1753         if (window->keyboard_focus_handler)
1754                 (*window->keyboard_focus_handler)(window,
1755                                                   window->keyboard_device,
1756                                                   window->user_data);
1757 }
1758
1759 static void
1760 keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
1761                       uint32_t serial, struct wl_surface *surface)
1762 {
1763         struct input *input = data;
1764
1765         input->display->serial = serial;
1766         input_remove_keyboard_focus(input);
1767 }
1768
1769 static const struct wl_pointer_listener pointer_listener = {
1770         pointer_handle_enter,
1771         pointer_handle_leave,
1772         pointer_handle_motion,
1773         pointer_handle_button,
1774         pointer_handle_axis,
1775 };
1776
1777 static const struct wl_keyboard_listener keyboard_listener = {
1778         keyboard_handle_enter,
1779         keyboard_handle_leave,
1780         keyboard_handle_key,
1781 };
1782
1783 static void
1784 seat_handle_capabilities(void *data, struct wl_seat *seat,
1785                          enum wl_seat_capability caps)
1786 {
1787         struct input *input = data;
1788
1789         if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
1790                 input->pointer = wl_seat_get_pointer(seat);
1791                 wl_pointer_set_user_data(input->pointer, input);
1792                 wl_pointer_add_listener(input->pointer, &pointer_listener,
1793                                         input);
1794         } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
1795                 wl_pointer_destroy(input->pointer);
1796                 input->pointer = NULL;
1797         }
1798
1799         if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) {
1800                 input->keyboard = wl_seat_get_keyboard(seat);
1801                 wl_keyboard_set_user_data(input->keyboard, input);
1802                 wl_keyboard_add_listener(input->keyboard, &keyboard_listener,
1803                                          input);
1804         } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) {
1805                 wl_keyboard_destroy(input->keyboard);
1806                 input->keyboard = NULL;
1807         }
1808 }
1809
1810 static const struct wl_seat_listener seat_listener = {
1811         seat_handle_capabilities,
1812 };
1813
1814 void
1815 input_get_position(struct input *input, int32_t *x, int32_t *y)
1816 {
1817         *x = input->sx;
1818         *y = input->sy;
1819 }
1820
1821 struct wl_seat *
1822 input_get_seat(struct input *input)
1823 {
1824         return input->seat;
1825 }
1826
1827 uint32_t
1828 input_get_modifiers(struct input *input)
1829 {
1830         return input->modifiers;
1831 }
1832
1833 struct widget *
1834 input_get_focus_widget(struct input *input)
1835 {
1836         return input->focus_widget;
1837 }
1838
1839 struct data_offer {
1840         struct wl_data_offer *offer;
1841         struct input *input;
1842         struct wl_array types;
1843         int refcount;
1844
1845         struct task io_task;
1846         int fd;
1847         data_func_t func;
1848         int32_t x, y;
1849         void *user_data;
1850 };
1851
1852 static void
1853 data_offer_offer(void *data, struct wl_data_offer *wl_data_offer, const char *type)
1854 {
1855         struct data_offer *offer = data;
1856         char **p;
1857
1858         p = wl_array_add(&offer->types, sizeof *p);
1859         *p = strdup(type);
1860 }
1861
1862 static const struct wl_data_offer_listener data_offer_listener = {
1863         data_offer_offer,
1864 };
1865
1866 static void
1867 data_offer_destroy(struct data_offer *offer)
1868 {
1869         char **p;
1870
1871         offer->refcount--;
1872         if (offer->refcount == 0) {
1873                 wl_data_offer_destroy(offer->offer);
1874                 for (p = offer->types.data; *p; p++)
1875                         free(*p);
1876                 wl_array_release(&offer->types);
1877                 free(offer);
1878         }
1879 }
1880
1881 static void
1882 data_device_data_offer(void *data,
1883                        struct wl_data_device *data_device, uint32_t id)
1884 {
1885         struct data_offer *offer;
1886
1887         offer = malloc(sizeof *offer);
1888
1889         wl_array_init(&offer->types);
1890         offer->refcount = 1;
1891         offer->input = data;
1892
1893         /* FIXME: Generate typesafe wrappers for this */
1894         offer->offer = (struct wl_data_offer *)
1895                 wl_proxy_create_for_id((struct wl_proxy *) data_device,
1896                                        id, &wl_data_offer_interface);
1897
1898         wl_data_offer_add_listener(offer->offer,
1899                                    &data_offer_listener, offer);
1900 }
1901
1902 static void
1903 data_device_enter(void *data, struct wl_data_device *data_device,
1904                   uint32_t serial, struct wl_surface *surface,
1905                   wl_fixed_t x_w, wl_fixed_t y_w,
1906                   struct wl_data_offer *offer)
1907 {
1908         struct input *input = data;
1909         struct window *window;
1910         float x = wl_fixed_to_double(x_w);
1911         float y = wl_fixed_to_double(y_w);
1912         char **p;
1913
1914         input->pointer_enter_serial = serial;
1915         input->drag_offer = wl_data_offer_get_user_data(offer);
1916         window = wl_surface_get_user_data(surface);
1917         input->pointer_focus = window;
1918
1919         p = wl_array_add(&input->drag_offer->types, sizeof *p);
1920         *p = NULL;
1921
1922         window = input->pointer_focus;
1923         if (window->data_handler)
1924                 window->data_handler(window, input, x, y,
1925                                      input->drag_offer->types.data,
1926                                      window->user_data);
1927 }
1928
1929 static void
1930 data_device_leave(void *data, struct wl_data_device *data_device)
1931 {
1932         struct input *input = data;
1933
1934         data_offer_destroy(input->drag_offer);
1935         input->drag_offer = NULL;
1936 }
1937
1938 static void
1939 data_device_motion(void *data, struct wl_data_device *data_device,
1940                    uint32_t time, wl_fixed_t x_w, wl_fixed_t y_w)
1941 {
1942         struct input *input = data;
1943         struct window *window = input->pointer_focus;
1944         float x = wl_fixed_to_double(x_w);
1945         float y = wl_fixed_to_double(y_w);
1946
1947         input->sx = x;
1948         input->sy = y;
1949
1950         if (window->data_handler)
1951                 window->data_handler(window, input, x, y,
1952                                      input->drag_offer->types.data,
1953                                      window->user_data);
1954 }
1955
1956 static void
1957 data_device_drop(void *data, struct wl_data_device *data_device)
1958 {
1959         struct input *input = data;
1960         struct window *window = input->pointer_focus;
1961
1962         if (window->drop_handler)
1963                 window->drop_handler(window, input,
1964                                      input->sx, input->sy, window->user_data);
1965 }
1966
1967 static void
1968 data_device_selection(void *data,
1969                       struct wl_data_device *wl_data_device,
1970                       struct wl_data_offer *offer)
1971 {
1972         struct input *input = data;
1973         char **p;
1974
1975         if (input->selection_offer)
1976                 data_offer_destroy(input->selection_offer);
1977
1978         if (offer) {
1979                 input->selection_offer = wl_data_offer_get_user_data(offer);
1980                 p = wl_array_add(&input->selection_offer->types, sizeof *p);
1981                 *p = NULL;
1982         }
1983 }
1984
1985 static const struct wl_data_device_listener data_device_listener = {
1986         data_device_data_offer,
1987         data_device_enter,
1988         data_device_leave,
1989         data_device_motion,
1990         data_device_drop,
1991         data_device_selection
1992 };
1993
1994 void
1995 input_set_pointer_image(struct input *input, uint32_t time, int pointer)
1996 {
1997         struct display *display = input->display;
1998         struct wl_buffer *buffer;
1999         struct wl_cursor *cursor;
2000         struct wl_cursor_image *image;
2001
2002         if (pointer == input->current_cursor)
2003                 return;
2004
2005         cursor = wl_cursor_theme_get_cursor(display->cursor_theme, pointer);
2006         if (!cursor)
2007                 return;
2008
2009         image = cursor->images[0];
2010         buffer = wl_cursor_image_get_buffer(image);
2011         if (!buffer)
2012                 return;
2013
2014         input->current_cursor = pointer;
2015         wl_pointer_attach(input->pointer, time, buffer,
2016                           image->hotspot_x, image->hotspot_y);
2017 }
2018
2019 struct wl_data_device *
2020 input_get_data_device(struct input *input)
2021 {
2022         return input->data_device;
2023 }
2024
2025 void
2026 input_set_selection(struct input *input,
2027                     struct wl_data_source *source, uint32_t time)
2028 {
2029         wl_data_device_set_selection(input->data_device, source, time);
2030 }
2031
2032 void
2033 input_accept(struct input *input, const char *type)
2034 {
2035         wl_data_offer_accept(input->drag_offer->offer,
2036                              input->pointer_enter_serial, type);
2037 }
2038
2039 static void
2040 offer_io_func(struct task *task, uint32_t events)
2041 {
2042         struct data_offer *offer =
2043                 container_of(task, struct data_offer, io_task);
2044         unsigned int len;
2045         char buffer[4096];
2046
2047         len = read(offer->fd, buffer, sizeof buffer);
2048         offer->func(buffer, len,
2049                     offer->x, offer->y, offer->user_data);
2050
2051         if (len == 0) {
2052                 close(offer->fd);
2053                 data_offer_destroy(offer);
2054         }
2055 }
2056
2057 static void
2058 data_offer_receive_data(struct data_offer *offer, const char *mime_type,
2059                         data_func_t func, void *user_data)
2060 {
2061         int p[2];
2062
2063         if (pipe2(p, O_CLOEXEC) == -1)
2064                 return;
2065
2066         wl_data_offer_receive(offer->offer, mime_type, p[1]);
2067         close(p[1]);
2068
2069         offer->io_task.run = offer_io_func;
2070         offer->fd = p[0];
2071         offer->func = func;
2072         offer->refcount++;
2073         offer->user_data = user_data;
2074
2075         display_watch_fd(offer->input->display,
2076                          offer->fd, EPOLLIN, &offer->io_task);
2077 }
2078
2079 void
2080 input_receive_drag_data(struct input *input, const char *mime_type,
2081                         data_func_t func, void *data)
2082 {
2083         data_offer_receive_data(input->drag_offer, mime_type, func, data);
2084         input->drag_offer->x = input->sx;
2085         input->drag_offer->y = input->sy;
2086 }
2087
2088 int
2089 input_receive_selection_data(struct input *input, const char *mime_type,
2090                              data_func_t func, void *data)
2091 {
2092         char **p;
2093
2094         if (input->selection_offer == NULL)
2095                 return -1;
2096
2097         for (p = input->selection_offer->types.data; *p; p++)
2098                 if (strcmp(mime_type, *p) == 0)
2099                         break;
2100
2101         if (*p == NULL)
2102                 return -1;
2103
2104         data_offer_receive_data(input->selection_offer,
2105                                 mime_type, func, data);
2106         return 0;
2107 }
2108
2109 int
2110 input_receive_selection_data_to_fd(struct input *input,
2111                                    const char *mime_type, int fd)
2112 {
2113         wl_data_offer_receive(input->selection_offer->offer, mime_type, fd);
2114
2115         return 0;
2116 }
2117
2118 void
2119 window_move(struct window *window, struct input *input, uint32_t serial)
2120 {
2121         if (!window->shell_surface)
2122                 return;
2123
2124         wl_shell_surface_move(window->shell_surface, input->seat, serial);
2125 }
2126
2127 static void
2128 idle_resize(struct window *window)
2129 {
2130         struct widget *widget;
2131
2132         window->resize_needed = 0;
2133         widget = window->widget;
2134         widget_set_allocation(widget,
2135                               window->pending_allocation.x,
2136                               window->pending_allocation.y,
2137                               window->pending_allocation.width,
2138                               window->pending_allocation.height);
2139
2140         if (window->input_region) {
2141                 wl_region_destroy(window->input_region);
2142                 window->input_region = NULL;
2143         }
2144
2145         if (window->opaque_region) {
2146                 wl_region_destroy(window->opaque_region);
2147                 window->opaque_region = NULL;
2148         }
2149
2150         if (widget->resize_handler)
2151                 widget->resize_handler(widget,
2152                                        widget->allocation.width,
2153                                        widget->allocation.height,
2154                                        widget->user_data);
2155
2156         if (window->allocation.width != widget->allocation.width ||
2157             window->allocation.height != widget->allocation.height) {
2158                 window->allocation = widget->allocation;
2159                 window_schedule_redraw(window);
2160         }
2161 }
2162
2163 void
2164 window_schedule_resize(struct window *window, int width, int height)
2165 {
2166         window->pending_allocation.x = 0;
2167         window->pending_allocation.y = 0;
2168         window->pending_allocation.width = width;
2169         window->pending_allocation.height = height;
2170
2171         window->resize_needed = 1;
2172         window_schedule_redraw(window);
2173 }
2174
2175 void
2176 widget_schedule_resize(struct widget *widget, int32_t width, int32_t height)
2177 {
2178         window_schedule_resize(widget->window, width, height);
2179 }
2180
2181 static void
2182 handle_ping(void *data, struct wl_shell_surface *shell_surface,
2183                                                         uint32_t serial)
2184 {
2185         wl_shell_surface_pong(shell_surface, serial);
2186 }
2187
2188 static void
2189 handle_configure(void *data, struct wl_shell_surface *shell_surface,
2190                  uint32_t edges, int32_t width, int32_t height)
2191 {
2192         struct window *window = data;
2193
2194         if (width <= 0 || height <= 0)
2195                 return;
2196
2197         window->resize_edges = edges;
2198         window_schedule_resize(window, width, height);
2199 }
2200
2201 static void
2202 menu_destroy(struct menu *menu)
2203 {
2204         widget_destroy(menu->widget);
2205         window_destroy(menu->window);
2206         free(menu);
2207 }
2208
2209 static void
2210 handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
2211 {
2212         struct window *window = data;
2213         struct menu *menu = window->widget->user_data;
2214
2215         /* FIXME: Need more context in this event, at least the input
2216          * device.  Or just use wl_callback.  And this really needs to
2217          * be a window vfunc that the menu can set.  And we need the
2218          * time. */
2219
2220         menu->func(window->parent, menu->current, window->parent->user_data);
2221         input_ungrab(menu->input);
2222         menu_destroy(menu);
2223 }
2224
2225 static const struct wl_shell_surface_listener shell_surface_listener = {
2226         handle_ping,
2227         handle_configure,
2228         handle_popup_done
2229 };
2230
2231 void
2232 window_get_allocation(struct window *window,
2233                       struct rectangle *allocation)
2234 {
2235         *allocation = window->allocation;
2236 }
2237
2238 static void
2239 widget_redraw(struct widget *widget)
2240 {
2241         struct widget *child;
2242
2243         if (widget->redraw_handler)
2244                 widget->redraw_handler(widget, widget->user_data);
2245         wl_list_for_each(child, &widget->child_list, link)
2246                 widget_redraw(child);
2247 }
2248
2249 static void
2250 frame_callback(void *data, struct wl_callback *callback, uint32_t time)
2251 {
2252         struct window *window = data;
2253
2254         wl_callback_destroy(callback);
2255         window->redraw_scheduled = 0;
2256         if (window->redraw_needed)
2257                 window_schedule_redraw(window);
2258 }
2259
2260 static const struct wl_callback_listener listener = {
2261         frame_callback
2262 };
2263
2264 static void
2265 idle_redraw(struct task *task, uint32_t events)
2266 {
2267         struct window *window = container_of(task, struct window, redraw_task);
2268         struct wl_callback *callback;
2269
2270         if (window->resize_needed)
2271                 idle_resize(window);
2272
2273         window_create_surface(window);
2274         widget_redraw(window->widget);
2275         window_flush(window);
2276         window->redraw_needed = 0;
2277         wl_list_init(&window->redraw_task.link);
2278
2279         callback = wl_surface_frame(window->surface);
2280         wl_callback_add_listener(callback, &listener, window);
2281 }
2282
2283 void
2284 window_schedule_redraw(struct window *window)
2285 {
2286         window->redraw_needed = 1;
2287         if (!window->redraw_scheduled) {
2288                 window->redraw_task.run = idle_redraw;
2289                 display_defer(window->display, &window->redraw_task);
2290                 window->redraw_scheduled = 1;
2291         }
2292 }
2293
2294 void
2295 window_set_custom(struct window *window)
2296 {
2297         window->type = TYPE_CUSTOM;
2298 }
2299
2300 void
2301 window_set_fullscreen(struct window *window, int fullscreen)
2302 {
2303         if (!window->display->shell)
2304                 return;
2305
2306         if ((window->type == TYPE_FULLSCREEN) == fullscreen)
2307                 return;
2308
2309         if (fullscreen) {
2310                 window->type = TYPE_FULLSCREEN;
2311                 window->saved_allocation = window->allocation;
2312                 wl_shell_surface_set_fullscreen(window->shell_surface,
2313                                                 WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
2314                                                 0, NULL);
2315         } else {
2316                 window->type = TYPE_TOPLEVEL;
2317                 wl_shell_surface_set_toplevel(window->shell_surface);
2318                 window_schedule_resize(window,
2319                                        window->saved_allocation.width,
2320                                        window->saved_allocation.height);
2321         }
2322 }
2323
2324 void
2325 window_set_maximized(struct window *window, int maximized)
2326 {
2327         if (!window->display->shell)
2328                 return;
2329
2330         if ((window->type == TYPE_MAXIMIZED) == maximized)
2331                 return;
2332
2333         if (window->type == TYPE_TOPLEVEL) {
2334                 window->saved_allocation = window->allocation;
2335                 wl_shell_surface_set_maximized(window->shell_surface, NULL);
2336                 window->type = TYPE_MAXIMIZED;
2337         } else {
2338                 wl_shell_surface_set_toplevel(window->shell_surface);
2339                 window->type = TYPE_TOPLEVEL;
2340                 window_schedule_resize(window,
2341                                        window->saved_allocation.width,
2342                                        window->saved_allocation.height);
2343         }
2344 }
2345
2346 void
2347 window_set_user_data(struct window *window, void *data)
2348 {
2349         window->user_data = data;
2350 }
2351
2352 void *
2353 window_get_user_data(struct window *window)
2354 {
2355         return window->user_data;
2356 }
2357
2358 void
2359 window_set_key_handler(struct window *window,
2360                        window_key_handler_t handler)
2361 {
2362         window->key_handler = handler;
2363 }
2364
2365 void
2366 window_set_keyboard_focus_handler(struct window *window,
2367                                   window_keyboard_focus_handler_t handler)
2368 {
2369         window->keyboard_focus_handler = handler;
2370 }
2371
2372 void
2373 window_set_data_handler(struct window *window, window_data_handler_t handler)
2374 {
2375         window->data_handler = handler;
2376 }
2377
2378 void
2379 window_set_drop_handler(struct window *window, window_drop_handler_t handler)
2380 {
2381         window->drop_handler = handler;
2382 }
2383
2384 void
2385 window_set_close_handler(struct window *window,
2386                          window_close_handler_t handler)
2387 {
2388         window->close_handler = handler;
2389 }
2390
2391 void
2392 window_set_title(struct window *window, const char *title)
2393 {
2394         free(window->title);
2395         window->title = strdup(title);
2396         if (window->shell_surface)
2397                 wl_shell_surface_set_title(window->shell_surface, title);
2398 }
2399
2400 const char *
2401 window_get_title(struct window *window)
2402 {
2403         return window->title;
2404 }
2405
2406 void
2407 window_damage(struct window *window, int32_t x, int32_t y,
2408               int32_t width, int32_t height)
2409 {
2410         wl_surface_damage(window->surface, x, y, width, height);
2411 }
2412
2413 static void
2414 surface_enter(void *data,
2415               struct wl_surface *wl_surface, struct wl_output *wl_output)
2416 {
2417         struct window *window = data;
2418         struct output *output;
2419         struct output *output_found = NULL;
2420         struct window_output *window_output;
2421
2422         wl_list_for_each(output, &window->display->output_list, link) {
2423                 if (output->output == wl_output) {
2424                         output_found = output;
2425                         break;
2426                 }
2427         }
2428
2429         if (!output_found)
2430                 return;
2431
2432         window_output = malloc (sizeof *window_output);
2433         window_output->output = output_found;
2434
2435         wl_list_insert (&window->window_output_list, &window_output->link);
2436 }
2437
2438 static void
2439 surface_leave(void *data,
2440               struct wl_surface *wl_surface, struct wl_output *output)
2441 {
2442         struct window *window = data;
2443         struct window_output *window_output;
2444         struct window_output *window_output_found = NULL;
2445
2446         wl_list_for_each(window_output, &window->window_output_list, link) {
2447                 if (window_output->output->output == output) {
2448                         window_output_found = window_output;
2449                         break;
2450                 }
2451         }
2452
2453         if (window_output_found) {
2454                 wl_list_remove(&window_output_found->link);
2455                 free(window_output_found);
2456         }
2457 }
2458
2459 static const struct wl_surface_listener surface_listener = {
2460         surface_enter,
2461         surface_leave
2462 };
2463
2464 static struct window *
2465 window_create_internal(struct display *display, struct window *parent)
2466 {
2467         struct window *window;
2468
2469         window = malloc(sizeof *window);
2470         if (window == NULL)
2471                 return NULL;
2472
2473         memset(window, 0, sizeof *window);
2474         window->display = display;
2475         window->parent = parent;
2476         window->surface = wl_compositor_create_surface(display->compositor);
2477         wl_surface_add_listener(window->surface, &surface_listener, window);
2478         if (display->shell) {
2479                 window->shell_surface =
2480                         wl_shell_get_shell_surface(display->shell,
2481                                                    window->surface);
2482                 if (window->title)
2483                         wl_shell_surface_set_title(window->shell_surface,
2484                                                    window->title);
2485         }
2486         window->allocation.x = 0;
2487         window->allocation.y = 0;
2488         window->allocation.width = 0;
2489         window->allocation.height = 0;
2490         window->saved_allocation = window->allocation;
2491         window->transparent = 1;
2492         window->type = TYPE_NONE;
2493         window->input_region = NULL;
2494         window->opaque_region = NULL;
2495
2496         if (display->dpy)
2497 #ifdef HAVE_CAIRO_EGL
2498                 window->buffer_type = WINDOW_BUFFER_TYPE_EGL_WINDOW;
2499 #else
2500                 window->buffer_type = WINDOW_BUFFER_TYPE_SHM;
2501 #endif
2502         else
2503                 window->buffer_type = WINDOW_BUFFER_TYPE_SHM;
2504
2505         wl_surface_set_user_data(window->surface, window);
2506         wl_list_insert(display->window_list.prev, &window->link);
2507         wl_list_init(&window->redraw_task.link);
2508
2509         if (window->shell_surface) {
2510                 wl_shell_surface_set_user_data(window->shell_surface, window);
2511                 wl_shell_surface_add_listener(window->shell_surface,
2512                                               &shell_surface_listener, window);
2513         }
2514
2515         wl_list_init (&window->window_output_list);
2516
2517         return window;
2518 }
2519
2520 struct window *
2521 window_create(struct display *display)
2522 {
2523         struct window *window;
2524
2525         window = window_create_internal(display, NULL);
2526         if (!window)
2527                 return NULL;
2528
2529         return window;
2530 }
2531
2532 struct window *
2533 window_create_transient(struct display *display, struct window *parent,
2534                         int32_t x, int32_t y, uint32_t flags)
2535 {
2536         struct window *window;
2537
2538         window = window_create_internal(parent->display, parent);
2539         if (!window)
2540                 return NULL;
2541
2542         window->type = TYPE_TRANSIENT;
2543         window->x = x;
2544         window->y = y;
2545
2546         if (display->shell)
2547                 wl_shell_surface_set_transient(window->shell_surface,
2548                                                window->parent->shell_surface,
2549                                                window->x, window->y, flags);
2550
2551         return window;
2552 }
2553
2554 static void
2555 menu_set_item(struct menu *menu, int sy)
2556 {
2557         int next;
2558
2559         next = (sy - 8) / 20;
2560         if (menu->current != next) {
2561                 menu->current = next;
2562                 widget_schedule_redraw(menu->widget);
2563         }
2564 }
2565
2566 static int
2567 menu_motion_handler(struct widget *widget,
2568                     struct input *input, uint32_t time,
2569                     float x, float y, void *data)
2570 {
2571         struct menu *menu = data;
2572
2573         if (widget == menu->widget)
2574                 menu_set_item(data, y);
2575
2576         return WL_CURSOR_LEFT_PTR;
2577 }
2578
2579 static int
2580 menu_enter_handler(struct widget *widget,
2581                    struct input *input, float x, float y, void *data)
2582 {
2583         struct menu *menu = data;
2584
2585         if (widget == menu->widget)
2586                 menu_set_item(data, y);
2587
2588         return WL_CURSOR_LEFT_PTR;
2589 }
2590
2591 static void
2592 menu_leave_handler(struct widget *widget, struct input *input, void *data)
2593 {
2594         struct menu *menu = data;
2595
2596         if (widget == menu->widget)
2597                 menu_set_item(data, -200);
2598 }
2599
2600 static void
2601 menu_button_handler(struct widget *widget,
2602                     struct input *input, uint32_t time,
2603                     uint32_t button, uint32_t state, void *data)
2604
2605 {
2606         struct menu *menu = data;
2607
2608         if (state == 0 && time - menu->time > 500) {
2609                 /* Either relase after press-drag-release or
2610                  * click-motion-click. */
2611                 menu->func(menu->window->parent, 
2612                            menu->current, menu->window->parent->user_data);
2613                 input_ungrab(input);
2614                 menu_destroy(menu);
2615         }
2616 }
2617
2618 static void
2619 menu_redraw_handler(struct widget *widget, void *data)
2620 {
2621         cairo_t *cr;
2622         const int32_t r = 3, margin = 3;
2623         struct menu *menu = data;
2624         int32_t width, height, i;
2625         struct window *window = widget->window;
2626
2627         cr = cairo_create(window->cairo_surface);
2628         cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
2629         cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
2630         cairo_paint(cr);
2631
2632         width = window->allocation.width;
2633         height = window->allocation.height;
2634         rounded_rect(cr, 0, 0, width, height, r);
2635
2636         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
2637         cairo_set_source_rgba(cr, 0.0, 0.0, 0.4, 0.8);
2638         cairo_fill(cr);
2639
2640         for (i = 0; i < menu->count; i++) {
2641                 if (i == menu->current) {
2642                         cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
2643                         cairo_rectangle(cr, margin, i * 20 + margin,
2644                                         width - 2 * margin, 20);
2645                         cairo_fill(cr);
2646                         cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
2647                         cairo_move_to(cr, 10, i * 20 + 16);
2648                         cairo_show_text(cr, menu->entries[i]);
2649                 } else {
2650                         cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
2651                         cairo_move_to(cr, 10, i * 20 + 16);
2652                         cairo_show_text(cr, menu->entries[i]);
2653                 }
2654         }
2655
2656         cairo_destroy(cr);
2657 }
2658
2659 void
2660 window_show_menu(struct display *display,
2661                  struct input *input, uint32_t time, struct window *parent,
2662                  int32_t x, int32_t y,
2663                  menu_func_t func, const char **entries, int count)
2664 {
2665         struct window *window;
2666         struct menu *menu;
2667         const int32_t margin = 3;
2668
2669         menu = malloc(sizeof *menu);
2670         if (!menu)
2671                 return;
2672
2673         window = window_create_internal(parent->display, parent);
2674         if (!window)
2675                 return;
2676
2677         menu->window = window;
2678         menu->widget = window_add_widget(menu->window, menu);
2679         menu->entries = entries;
2680         menu->count = count;
2681         menu->current = -1;
2682         menu->time = time;
2683         menu->func = func;
2684         menu->input = input;
2685         window->type = TYPE_MENU;
2686         window->x = x;
2687         window->y = y;
2688
2689         input_ungrab(input);
2690         wl_shell_surface_set_popup(window->shell_surface, input->seat,
2691                                    display_get_serial(window->display),
2692                                    window->parent->shell_surface,
2693                                    window->x, window->y, 0);
2694
2695         widget_set_redraw_handler(menu->widget, menu_redraw_handler);
2696         widget_set_enter_handler(menu->widget, menu_enter_handler);
2697         widget_set_leave_handler(menu->widget, menu_leave_handler);
2698         widget_set_motion_handler(menu->widget, menu_motion_handler);
2699         widget_set_button_handler(menu->widget, menu_button_handler);
2700
2701         input_grab(input, menu->widget, 0);
2702         window_schedule_resize(window, 200, count * 20 + margin * 2);
2703 }
2704
2705 void
2706 window_set_buffer_type(struct window *window, enum window_buffer_type type)
2707 {
2708         window->buffer_type = type;
2709 }
2710
2711
2712 static void
2713 display_handle_geometry(void *data,
2714                         struct wl_output *wl_output,
2715                         int x, int y,
2716                         int physical_width,
2717                         int physical_height,
2718                         int subpixel,
2719                         const char *make,
2720                         const char *model)
2721 {
2722         struct output *output = data;
2723
2724         output->allocation.x = x;
2725         output->allocation.y = y;
2726 }
2727
2728 static void
2729 display_handle_mode(void *data,
2730                     struct wl_output *wl_output,
2731                     uint32_t flags,
2732                     int width,
2733                     int height,
2734                     int refresh)
2735 {
2736         struct output *output = data;
2737         struct display *display = output->display;
2738
2739         if (flags & WL_OUTPUT_MODE_CURRENT) {
2740                 output->allocation.width = width;
2741                 output->allocation.height = height;
2742                 if (display->output_configure_handler)
2743                         (*display->output_configure_handler)(
2744                                                 output, display->user_data);
2745         }
2746 }
2747
2748 static const struct wl_output_listener output_listener = {
2749         display_handle_geometry,
2750         display_handle_mode
2751 };
2752
2753 static void
2754 display_add_output(struct display *d, uint32_t id)
2755 {
2756         struct output *output;
2757
2758         output = malloc(sizeof *output);
2759         if (output == NULL)
2760                 return;
2761
2762         memset(output, 0, sizeof *output);
2763         output->display = d;
2764         output->output =
2765                 wl_display_bind(d->display, id, &wl_output_interface);
2766         wl_list_insert(d->output_list.prev, &output->link);
2767
2768         wl_output_add_listener(output->output, &output_listener, output);
2769 }
2770
2771 static void
2772 output_destroy(struct output *output)
2773 {
2774         if (output->destroy_handler)
2775                 (*output->destroy_handler)(output, output->user_data);
2776
2777         wl_output_destroy(output->output);
2778         wl_list_remove(&output->link);
2779         free(output);
2780 }
2781
2782 void
2783 display_set_output_configure_handler(struct display *display,
2784                                      display_output_handler_t handler)
2785 {
2786         struct output *output;
2787
2788         display->output_configure_handler = handler;
2789         if (!handler)
2790                 return;
2791
2792         wl_list_for_each(output, &display->output_list, link)
2793                 (*display->output_configure_handler)(output,
2794                                                      display->user_data);
2795 }
2796
2797 void
2798 output_set_user_data(struct output *output, void *data)
2799 {
2800         output->user_data = data;
2801 }
2802
2803 void *
2804 output_get_user_data(struct output *output)
2805 {
2806         return output->user_data;
2807 }
2808
2809 void
2810 output_set_destroy_handler(struct output *output,
2811                            display_output_handler_t handler)
2812 {
2813         output->destroy_handler = handler;
2814         /* FIXME: implement this, once we have way to remove outputs */
2815 }
2816
2817 void
2818 output_get_allocation(struct output *output, struct rectangle *allocation)
2819 {
2820         *allocation = output->allocation;
2821 }
2822
2823 struct wl_output *
2824 output_get_wl_output(struct output *output)
2825 {
2826         return output->output;
2827 }
2828
2829 static void
2830 display_add_input(struct display *d, uint32_t id)
2831 {
2832         struct input *input;
2833
2834         input = malloc(sizeof *input);
2835         if (input == NULL)
2836                 return;
2837
2838         memset(input, 0, sizeof *input);
2839         input->display = d;
2840         input->seat = wl_display_bind(d->display, id, &wl_seat_interface);
2841         input->pointer_focus = NULL;
2842         input->keyboard_focus = NULL;
2843         wl_list_insert(d->input_list.prev, &input->link);
2844
2845         wl_seat_add_listener(input->seat, &seat_listener, input);
2846         wl_seat_set_user_data(input->seat, input);
2847
2848         input->data_device =
2849                 wl_data_device_manager_get_data_device(d->data_device_manager,
2850                                                        input->seat);
2851         wl_data_device_add_listener(input->data_device, &data_device_listener,
2852                                     input);
2853 }
2854
2855 static void
2856 input_destroy(struct input *input)
2857 {
2858         input_remove_keyboard_focus(input);
2859         input_remove_pointer_focus(input);
2860
2861         if (input->drag_offer)
2862                 data_offer_destroy(input->drag_offer);
2863
2864         if (input->selection_offer)
2865                 data_offer_destroy(input->selection_offer);
2866
2867         wl_data_device_destroy(input->data_device);
2868         wl_list_remove(&input->link);
2869         wl_seat_destroy(input->seat);
2870         free(input);
2871 }
2872
2873 static void
2874 display_handle_global(struct wl_display *display, uint32_t id,
2875                       const char *interface, uint32_t version, void *data)
2876 {
2877         struct display *d = data;
2878
2879         if (strcmp(interface, "wl_compositor") == 0) {
2880                 d->compositor =
2881                         wl_display_bind(display, id, &wl_compositor_interface);
2882         } else if (strcmp(interface, "wl_output") == 0) {
2883                 display_add_output(d, id);
2884         } else if (strcmp(interface, "wl_seat") == 0) {
2885                 display_add_input(d, id);
2886         } else if (strcmp(interface, "wl_shell") == 0) {
2887                 d->shell = wl_display_bind(display, id, &wl_shell_interface);
2888         } else if (strcmp(interface, "wl_shm") == 0) {
2889                 d->shm = wl_display_bind(display, id, &wl_shm_interface);
2890         } else if (strcmp(interface, "wl_data_device_manager") == 0) {
2891                 d->data_device_manager =
2892                         wl_display_bind(display, id,
2893                                         &wl_data_device_manager_interface);
2894         }
2895 }
2896
2897 static void
2898 init_xkb(struct display *d)
2899 {
2900         d->xkb.names.rules = "evdev";
2901         d->xkb.names.model = "pc105";
2902         d->xkb.names.layout = (char *) option_xkb_layout;
2903         d->xkb.names.variant = (char *) option_xkb_variant;
2904         d->xkb.names.options = (char *) option_xkb_options;
2905
2906         d->xkb.context = xkb_context_new(0);
2907         if (!d->xkb.context) {
2908                 fprintf(stderr, "Failed to create XKB context\n");
2909                 exit(1);
2910         }
2911
2912         d->xkb.keymap = xkb_map_new_from_names(d->xkb.context, &d->xkb.names, 0);
2913         if (!d->xkb.keymap) {
2914                 fprintf(stderr, "Failed to compile keymap\n");
2915                 exit(1);
2916         }
2917
2918         d->xkb.state = xkb_state_new(d->xkb.keymap);
2919         if (!d->xkb.state) {
2920                 fprintf(stderr, "Failed to create XKB state\n");
2921                 exit(1);
2922         }
2923
2924         d->xkb.control_mask =
2925                 1 << xkb_map_mod_get_index(d->xkb.keymap, "Control");
2926         d->xkb.alt_mask =
2927                 1 << xkb_map_mod_get_index(d->xkb.keymap, "Mod1");
2928         d->xkb.shift_mask =
2929                 1 << xkb_map_mod_get_index(d->xkb.keymap, "Shift");
2930
2931 }
2932
2933 static void
2934 fini_xkb(struct display *display)
2935 {
2936         xkb_state_unref(display->xkb.state);
2937         xkb_map_unref(display->xkb.keymap);
2938         xkb_context_unref(display->xkb.context);
2939 }
2940
2941 #ifdef HAVE_CAIRO_EGL
2942 static int
2943 init_egl(struct display *d)
2944 {
2945         EGLint major, minor;
2946         EGLint n;
2947
2948 #ifdef USE_CAIRO_GLESV2
2949 #  define GL_BIT EGL_OPENGL_ES2_BIT
2950 #else
2951 #  define GL_BIT EGL_OPENGL_BIT
2952 #endif
2953
2954         static const EGLint argb_cfg_attribs[] = {
2955                 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PIXMAP_BIT,
2956                 EGL_RED_SIZE, 1,
2957                 EGL_GREEN_SIZE, 1,
2958                 EGL_BLUE_SIZE, 1,
2959                 EGL_ALPHA_SIZE, 1,
2960                 EGL_DEPTH_SIZE, 1,
2961                 EGL_RENDERABLE_TYPE, GL_BIT,
2962                 EGL_NONE
2963         };
2964
2965 #ifdef USE_CAIRO_GLESV2
2966         static const EGLint context_attribs[] = {
2967                 EGL_CONTEXT_CLIENT_VERSION, 2,
2968                 EGL_NONE
2969         };
2970         EGLint api = EGL_OPENGL_ES_API;
2971 #else
2972         EGLint *context_attribs = NULL;
2973         EGLint api = EGL_OPENGL_API;
2974 #endif
2975
2976         d->dpy = eglGetDisplay(d->display);
2977         if (!eglInitialize(d->dpy, &major, &minor)) {
2978                 fprintf(stderr, "failed to initialize display\n");
2979                 return -1;
2980         }
2981
2982         if (!eglBindAPI(api)) {
2983                 fprintf(stderr, "failed to bind api EGL_OPENGL_API\n");
2984                 return -1;
2985         }
2986
2987         if (!eglChooseConfig(d->dpy, argb_cfg_attribs,
2988                              &d->argb_config, 1, &n) || n != 1) {
2989                 fprintf(stderr, "failed to choose argb config\n");
2990                 return -1;
2991         }
2992
2993         d->argb_ctx = eglCreateContext(d->dpy, d->argb_config,
2994                                        EGL_NO_CONTEXT, context_attribs);
2995         if (d->argb_ctx == NULL) {
2996                 fprintf(stderr, "failed to create context\n");
2997                 return -1;
2998         }
2999
3000         if (!eglMakeCurrent(d->dpy, NULL, NULL, d->argb_ctx)) {
3001                 fprintf(stderr, "failed to make context current\n");
3002                 return -1;
3003         }
3004
3005 #ifdef HAVE_CAIRO_EGL
3006         d->argb_device = cairo_egl_device_create(d->dpy, d->argb_ctx);
3007         if (cairo_device_status(d->argb_device) != CAIRO_STATUS_SUCCESS) {
3008                 fprintf(stderr, "failed to get cairo egl argb device\n");
3009                 return -1;
3010         }
3011 #endif
3012
3013         return 0;
3014 }
3015
3016 static void
3017 fini_egl(struct display *display)
3018 {
3019 #ifdef HAVE_CAIRO_EGL
3020         cairo_device_destroy(display->argb_device);
3021 #endif
3022
3023         eglMakeCurrent(display->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE,
3024                        EGL_NO_CONTEXT);
3025
3026         eglTerminate(display->dpy);
3027         eglReleaseThread();
3028 }
3029 #endif
3030
3031 static int
3032 event_mask_update(uint32_t mask, void *data)
3033 {
3034         struct display *d = data;
3035
3036         d->mask = mask;
3037
3038         return 0;
3039 }
3040
3041 static void
3042 handle_display_data(struct task *task, uint32_t events)
3043 {
3044         struct display *display =
3045                 container_of(task, struct display, display_task);
3046         
3047         wl_display_iterate(display->display, display->mask);
3048 }
3049
3050 struct display *
3051 display_create(int argc, char *argv[])
3052 {
3053         struct display *d;
3054
3055         argc = parse_options(xkb_options,
3056                              ARRAY_LENGTH(xkb_options), argc, argv);
3057
3058         d = malloc(sizeof *d);
3059         if (d == NULL)
3060                 return NULL;
3061
3062         memset(d, 0, sizeof *d);
3063
3064         d->display = wl_display_connect(NULL);
3065         if (d->display == NULL) {
3066                 fprintf(stderr, "failed to create display: %m\n");
3067                 return NULL;
3068         }
3069
3070         d->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
3071         d->display_fd = wl_display_get_fd(d->display, event_mask_update, d);
3072         d->display_task.run = handle_display_data;
3073         display_watch_fd(d, d->display_fd, EPOLLIN, &d->display_task);
3074
3075         wl_list_init(&d->deferred_list);
3076         wl_list_init(&d->input_list);
3077         wl_list_init(&d->output_list);
3078
3079         /* Set up listener so we'll catch all events. */
3080         wl_display_add_global_listener(d->display,
3081                                        display_handle_global, d);
3082
3083         /* Process connection events. */
3084         wl_display_iterate(d->display, WL_DISPLAY_READABLE);
3085 #ifdef HAVE_CAIRO_EGL
3086         if (init_egl(d) < 0)
3087                 return NULL;
3088 #endif
3089
3090         d->image_target_texture_2d =
3091                 (void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
3092         d->create_image = (void *) eglGetProcAddress("eglCreateImageKHR");
3093         d->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR");
3094
3095         d->cursor_theme = wl_cursor_theme_load(NULL, 32, d->shm);
3096
3097         d->theme = theme_create();
3098
3099         wl_list_init(&d->window_list);
3100
3101         init_xkb(d);
3102
3103         return d;
3104 }
3105
3106 static void
3107 display_destroy_outputs(struct display *display)
3108 {
3109         struct output *tmp;
3110         struct output *output;
3111
3112         wl_list_for_each_safe(output, tmp, &display->output_list, link)
3113                 output_destroy(output);
3114 }
3115
3116 static void
3117 display_destroy_inputs(struct display *display)
3118 {
3119         struct input *tmp;
3120         struct input *input;
3121
3122         wl_list_for_each_safe(input, tmp, &display->input_list, link)
3123                 input_destroy(input);
3124 }
3125
3126 void
3127 display_destroy(struct display *display)
3128 {
3129         if (!wl_list_empty(&display->window_list))
3130                 fprintf(stderr, "toytoolkit warning: windows exist.\n");
3131
3132         if (!wl_list_empty(&display->deferred_list))
3133                 fprintf(stderr, "toytoolkit warning: deferred tasks exist.\n");
3134
3135         display_destroy_outputs(display);
3136         display_destroy_inputs(display);
3137
3138         fini_xkb(display);
3139
3140         theme_destroy(display->theme);
3141         wl_cursor_theme_destroy(display->cursor_theme);
3142
3143 #ifdef HAVE_CAIRO_EGL
3144         fini_egl(display);
3145 #endif
3146
3147         if (display->shell)
3148                 wl_shell_destroy(display->shell);
3149
3150         if (display->shm)
3151                 wl_shm_destroy(display->shm);
3152
3153         if (display->data_device_manager)
3154                 wl_data_device_manager_destroy(display->data_device_manager);
3155
3156         wl_compositor_destroy(display->compositor);
3157
3158         close(display->epoll_fd);
3159
3160         wl_display_flush(display->display);
3161         wl_display_disconnect(display->display);
3162         free(display);
3163 }
3164
3165 void
3166 display_set_user_data(struct display *display, void *data)
3167 {
3168         display->user_data = data;
3169 }
3170
3171 void *
3172 display_get_user_data(struct display *display)
3173 {
3174         return display->user_data;
3175 }
3176
3177 struct wl_display *
3178 display_get_display(struct display *display)
3179 {
3180         return display->display;
3181 }
3182
3183 struct output *
3184 display_get_output(struct display *display)
3185 {
3186         return container_of(display->output_list.next, struct output, link);
3187 }
3188
3189 struct wl_compositor *
3190 display_get_compositor(struct display *display)
3191 {
3192         return display->compositor;
3193 }
3194
3195 uint32_t
3196 display_get_serial(struct display *display)
3197 {
3198         return display->serial;
3199 }
3200
3201 EGLDisplay
3202 display_get_egl_display(struct display *d)
3203 {
3204         return d->dpy;
3205 }
3206
3207 struct wl_data_source *
3208 display_create_data_source(struct display *display)
3209 {
3210         return wl_data_device_manager_create_data_source(display->data_device_manager);
3211 }
3212
3213 EGLConfig
3214 display_get_argb_egl_config(struct display *d)
3215 {
3216         return d->argb_config;
3217 }
3218
3219 struct wl_shell *
3220 display_get_shell(struct display *display)
3221 {
3222         return display->shell;
3223 }
3224
3225 int
3226 display_acquire_window_surface(struct display *display,
3227                                struct window *window,
3228                                EGLContext ctx)
3229 {
3230 #ifdef HAVE_CAIRO_EGL
3231         struct egl_window_surface_data *data;
3232         cairo_device_t *device;
3233
3234         if (!window->cairo_surface)
3235                 return -1;
3236         device = cairo_surface_get_device(window->cairo_surface);
3237         if (!device)
3238                 return -1;
3239
3240         if (!ctx) {
3241                 if (device == display->argb_device)
3242                         ctx = display->argb_ctx;
3243                 else
3244                         assert(0);
3245         }
3246
3247         data = cairo_surface_get_user_data(window->cairo_surface,
3248                                            &surface_data_key);
3249
3250         cairo_device_flush(device);
3251         cairo_device_acquire(device);
3252         if (!eglMakeCurrent(display->dpy, data->surf, data->surf, ctx))
3253                 fprintf(stderr, "failed to make surface current\n");
3254
3255         return 0;
3256 #else
3257         return -1;
3258 #endif
3259 }
3260
3261 void
3262 display_release_window_surface(struct display *display,
3263                                struct window *window)
3264 {
3265 #ifdef HAVE_CAIRO_EGL
3266         cairo_device_t *device;
3267         
3268         device = cairo_surface_get_device(window->cairo_surface);
3269         if (!device)
3270                 return;
3271
3272         if (!eglMakeCurrent(display->dpy, NULL, NULL, display->argb_ctx))
3273                 fprintf(stderr, "failed to make context current\n");
3274         cairo_device_release(device);
3275 #endif
3276 }
3277
3278 void
3279 display_defer(struct display *display, struct task *task)
3280 {
3281         wl_list_insert(&display->deferred_list, &task->link);
3282 }
3283
3284 void
3285 display_watch_fd(struct display *display,
3286                  int fd, uint32_t events, struct task *task)
3287 {
3288         struct epoll_event ep;
3289
3290         ep.events = events;
3291         ep.data.ptr = task;
3292         epoll_ctl(display->epoll_fd, EPOLL_CTL_ADD, fd, &ep);
3293 }
3294
3295 void
3296 display_run(struct display *display)
3297 {
3298         struct task *task;
3299         struct epoll_event ep[16];
3300         int i, count;
3301
3302         display->running = 1;
3303         while (1) {
3304                 wl_display_flush(display->display);
3305
3306                 while (!wl_list_empty(&display->deferred_list)) {
3307                         task = container_of(display->deferred_list.next,
3308                                             struct task, link);
3309                         wl_list_remove(&task->link);
3310                         task->run(task, 0);
3311                 }
3312
3313                 if (!display->running)
3314                         break;
3315
3316                 wl_display_flush(display->display);
3317
3318                 count = epoll_wait(display->epoll_fd,
3319                                    ep, ARRAY_LENGTH(ep), -1);
3320                 for (i = 0; i < count; i++) {
3321                         task = ep[i].data.ptr;
3322                         task->run(task, ep[i].events);
3323                 }
3324         }
3325 }
3326
3327 void
3328 display_exit(struct display *display)
3329 {
3330         display->running = 0;
3331 }