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