d06d4aa535ec17e08265cf5e1a75c5dd03c7ac68
[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 <gdk-pixbuf/gdk-pixbuf.h>
39 #include <sys/mman.h>
40 #include <sys/epoll.h>
41
42 #include <wayland-egl.h>
43
44 #include <GL/gl.h>
45 #include <EGL/egl.h>
46 #include <EGL/eglext.h>
47
48 #ifdef HAVE_CAIRO_EGL
49 #include <cairo-gl.h>
50 #endif
51
52 #include <X11/extensions/XKBcommon.h>
53
54 #include <linux/input.h>
55 #include <wayland-client.h>
56 #include "cairo-util.h"
57
58 #include "window.h"
59
60 struct display {
61         struct wl_display *display;
62         struct wl_compositor *compositor;
63         struct wl_shell *shell;
64         struct wl_shm *shm;
65         struct wl_output *output;
66         struct wl_data_device_manager *data_device_manager;
67         EGLDisplay dpy;
68         EGLConfig rgb_config;
69         EGLConfig premultiplied_argb_config;
70         EGLContext rgb_ctx;
71         EGLContext argb_ctx;
72         cairo_device_t *rgb_device;
73         cairo_device_t *argb_device;
74
75         int display_fd;
76         uint32_t mask;
77         struct task display_task;
78
79         int epoll_fd;
80         struct wl_list deferred_list;
81
82         struct wl_list window_list;
83         struct wl_list input_list;
84         struct wl_list output_list;
85         char *device_name;
86         cairo_surface_t *active_frame, *inactive_frame, *shadow;
87         struct xkb_desc *xkb;
88         cairo_surface_t **pointer_surfaces;
89
90         PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d;
91         PFNEGLCREATEIMAGEKHRPROC create_image;
92         PFNEGLDESTROYIMAGEKHRPROC destroy_image;
93
94         display_output_handler_t output_configure_handler;
95
96         void *user_data;
97 };
98
99 enum {
100         TYPE_TOPLEVEL,
101         TYPE_FULLSCREEN,
102         TYPE_TRANSIENT,
103         TYPE_CUSTOM
104 };
105        
106 struct window {
107         struct display *display;
108         struct window *parent;
109         struct wl_surface *surface;
110         struct wl_shell_surface *shell_surface;
111         char *title;
112         struct rectangle allocation, saved_allocation, server_allocation;
113         int x, y;
114         int resize_edges;
115         int redraw_scheduled;
116         struct task redraw_task;
117         int minimum_width, minimum_height;
118         int margin;
119         int type;
120         int decoration;
121         int transparent;
122         struct input *keyboard_device;
123         uint32_t name;
124         enum window_buffer_type buffer_type;
125
126         EGLImageKHR *image;
127         cairo_surface_t *cairo_surface, *pending_surface;
128
129         window_resize_handler_t resize_handler;
130         window_redraw_handler_t redraw_handler;
131         window_key_handler_t key_handler;
132         window_button_handler_t button_handler;
133         window_keyboard_focus_handler_t keyboard_focus_handler;
134         window_motion_handler_t motion_handler;
135         window_enter_handler_t enter_handler;
136         window_leave_handler_t leave_handler;
137         window_item_focus_handler_t item_focus_handler;
138         window_data_handler_t data_handler;
139         window_drop_handler_t drop_handler;
140
141         struct wl_list item_list;
142         struct item *focus_item;
143         uint32_t item_grab_button;
144
145         void *user_data;
146         struct wl_list link;
147 };
148
149 struct item {
150         struct wl_list link;
151         struct rectangle allocation;
152         void *user_data;
153 };
154
155 struct input {
156         struct display *display;
157         struct wl_input_device *input_device;
158         struct window *pointer_focus;
159         struct window *keyboard_focus;
160         uint32_t current_pointer_image;
161         uint32_t modifiers;
162         int32_t x, y, sx, sy;
163         struct wl_list link;
164
165         struct wl_data_device *data_device;
166         struct data_offer *drag_offer;
167         struct data_offer *selection_offer;
168 };
169
170 struct output {
171         struct display *display;
172         struct wl_output *output;
173         struct rectangle allocation;
174         struct wl_list link;
175
176         display_output_handler_t destroy_handler;
177         void *user_data;
178 };
179
180 enum {
181         POINTER_DEFAULT = 100,
182         POINTER_UNSET
183 };
184
185 enum window_location {
186         WINDOW_INTERIOR = 0,
187         WINDOW_RESIZING_TOP = 1,
188         WINDOW_RESIZING_BOTTOM = 2,
189         WINDOW_RESIZING_LEFT = 4,
190         WINDOW_RESIZING_TOP_LEFT = 5,
191         WINDOW_RESIZING_BOTTOM_LEFT = 6,
192         WINDOW_RESIZING_RIGHT = 8,
193         WINDOW_RESIZING_TOP_RIGHT = 9,
194         WINDOW_RESIZING_BOTTOM_RIGHT = 10,
195         WINDOW_RESIZING_MASK = 15,
196         WINDOW_EXTERIOR = 16,
197         WINDOW_TITLEBAR = 17,
198         WINDOW_CLIENT_AREA = 18,
199 };
200
201 const char *option_xkb_layout = "us";
202 const char *option_xkb_variant = "";
203 const char *option_xkb_options = "";
204
205 static const GOptionEntry xkb_option_entries[] = {
206         { "xkb-layout", 0, 0, G_OPTION_ARG_STRING,
207           &option_xkb_layout, "XKB Layout" },
208         { "xkb-variant", 0, 0, G_OPTION_ARG_STRING,
209           &option_xkb_variant, "XKB Variant" },
210         { "xkb-options", 0, 0, G_OPTION_ARG_STRING,
211           &option_xkb_options, "XKB Options" },
212         { NULL }
213 };
214
215 static const cairo_user_data_key_t surface_data_key;
216 struct surface_data {
217         struct wl_buffer *buffer;
218 };
219
220 #define MULT(_d,c,a,t) \
221         do { t = c * a + 0x7f; _d = ((t >> 8) + t) >> 8; } while (0)
222
223 #ifdef HAVE_CAIRO_EGL
224
225 struct egl_window_surface_data {
226         struct display *display;
227         struct wl_surface *surface;
228         struct wl_egl_window *window;
229         EGLSurface surf;
230 };
231
232 static void
233 egl_window_surface_data_destroy(void *p)
234 {
235         struct egl_window_surface_data *data = p;
236         struct display *d = data->display;
237
238         eglDestroySurface(d->dpy, data->surf);
239         wl_egl_window_destroy(data->window);
240         data->surface = NULL;
241
242         free(p);
243 }
244
245 static cairo_surface_t *
246 display_create_egl_window_surface(struct display *display,
247                                   struct wl_surface *surface,
248                                   uint32_t flags,
249                                   struct rectangle *rectangle)
250 {
251         cairo_surface_t *cairo_surface;
252         struct egl_window_surface_data *data;
253         EGLConfig config;
254         const EGLint *attribs;
255         cairo_device_t *device;
256
257         static const EGLint premul_attribs[] = {
258                 EGL_ALPHA_FORMAT, EGL_ALPHA_FORMAT_PRE,
259                 EGL_NONE
260         };
261         
262         data = malloc(sizeof *data);
263         if (data == NULL)
264                 return NULL;
265
266         data->display = display;
267         data->surface = surface;
268
269         if (flags & SURFACE_OPAQUE) {
270                 config = display->rgb_config;
271                 device = display->rgb_device;
272                 attribs = NULL;
273         } else {
274                 config = display->premultiplied_argb_config;
275                 device = display->argb_device;
276                 attribs = premul_attribs;
277         }
278
279         data->window = wl_egl_window_create(surface,
280                                             rectangle->width,
281                                             rectangle->height);
282
283         data->surf = eglCreateWindowSurface(display->dpy, config,
284                                             data->window, attribs);
285
286         cairo_surface = cairo_gl_surface_create_for_egl(device,
287                                                         data->surf,
288                                                         rectangle->width,
289                                                         rectangle->height);
290
291         cairo_surface_set_user_data(cairo_surface, &surface_data_key,
292                                     data, egl_window_surface_data_destroy);
293
294         return cairo_surface;
295 }
296
297 struct egl_image_surface_data {
298         struct surface_data data;
299         cairo_device_t *device;
300         EGLImageKHR image;
301         GLuint texture;
302         struct display *display;
303         struct wl_egl_pixmap *pixmap;
304 };
305
306 static void
307 egl_image_surface_data_destroy(void *p)
308 {
309         struct egl_image_surface_data *data = p;
310         struct display *d = data->display;
311
312         cairo_device_acquire(data->device);
313         glDeleteTextures(1, &data->texture);
314         cairo_device_release(data->device);
315
316         d->destroy_image(d->dpy, data->image);
317         wl_buffer_destroy(data->data.buffer);
318         wl_egl_pixmap_destroy(data->pixmap);
319         free(p);
320 }
321
322 EGLImageKHR
323 display_get_image_for_egl_image_surface(struct display *display,
324                                         cairo_surface_t *surface)
325 {
326         struct egl_image_surface_data *data;
327
328         data = cairo_surface_get_user_data (surface, &surface_data_key);
329
330         return data->image;
331 }
332
333 static cairo_surface_t *
334 display_create_egl_image_surface(struct display *display,
335                                  uint32_t flags,
336                                  struct rectangle *rectangle)
337 {
338         struct egl_image_surface_data *data;
339         EGLDisplay dpy = display->dpy;
340         cairo_surface_t *surface;
341         cairo_content_t content;
342
343         data = malloc(sizeof *data);
344         if (data == NULL)
345                 return NULL;
346
347         data->display = display;
348
349         data->pixmap = wl_egl_pixmap_create(rectangle->width,
350                                             rectangle->height, 0);
351         if (data->pixmap == NULL) {
352                 free(data);
353                 return NULL;
354         }
355
356         if (flags & SURFACE_OPAQUE) {
357                 data->device = display->rgb_device;
358                 content = CAIRO_CONTENT_COLOR;
359         } else {
360                 data->device = display->argb_device;
361                 content = CAIRO_CONTENT_COLOR_ALPHA;
362         }
363
364         data->image = display->create_image(dpy, NULL,
365                                             EGL_NATIVE_PIXMAP_KHR,
366                                             (EGLClientBuffer) data->pixmap,
367                                             NULL);
368         if (data->image == EGL_NO_IMAGE_KHR) {
369                 wl_egl_pixmap_destroy(data->pixmap);
370                 free(data);
371                 return NULL;
372         }
373
374         data->data.buffer =
375                 wl_egl_pixmap_create_buffer(data->pixmap);
376
377         cairo_device_acquire(data->device);
378         glGenTextures(1, &data->texture);
379         glBindTexture(GL_TEXTURE_2D, data->texture);
380         display->image_target_texture_2d(GL_TEXTURE_2D, data->image);
381         cairo_device_release(data->device);
382
383         surface = cairo_gl_surface_create_for_texture(data->device,
384                                                       content,
385                                                       data->texture,
386                                                       rectangle->width,
387                                                       rectangle->height);
388
389         cairo_surface_set_user_data (surface, &surface_data_key,
390                                      data, egl_image_surface_data_destroy);
391
392         return surface;
393 }
394
395 static cairo_surface_t *
396 display_create_egl_image_surface_from_file(struct display *display,
397                                            const char *filename,
398                                            struct rectangle *rect)
399 {
400         cairo_surface_t *surface;
401         GdkPixbuf *pixbuf;
402         GError *error = NULL;
403         int stride, i;
404         unsigned char *pixels, *p, *end;
405         struct egl_image_surface_data *data;
406
407         pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
408                                                    rect->width, rect->height,
409                                                    FALSE, &error);
410         if (error != NULL)
411                 return NULL;
412
413         if (!gdk_pixbuf_get_has_alpha(pixbuf) ||
414             gdk_pixbuf_get_n_channels(pixbuf) != 4) {
415                 g_object_unref(pixbuf);
416                 return NULL;
417         }
418
419
420         stride = gdk_pixbuf_get_rowstride(pixbuf);
421         pixels = gdk_pixbuf_get_pixels(pixbuf);
422
423         for (i = 0; i < rect->height; i++) {
424                 p = pixels + i * stride;
425                 end = p + rect->width * 4;
426                 while (p < end) {
427                         unsigned int t;
428
429                         MULT(p[0], p[0], p[3], t);
430                         MULT(p[1], p[1], p[3], t);
431                         MULT(p[2], p[2], p[3], t);
432                         p += 4;
433
434                 }
435         }
436
437         surface = display_create_egl_image_surface(display, 0, rect);
438         if (surface == NULL) {
439                 g_object_unref(pixbuf);
440                 return NULL;
441         }
442
443         data = cairo_surface_get_user_data(surface, &surface_data_key);
444
445         cairo_device_acquire(display->argb_device);
446         glBindTexture(GL_TEXTURE_2D, data->texture);
447         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rect->width, rect->height,
448                         GL_RGBA, GL_UNSIGNED_BYTE, pixels);
449         cairo_device_release(display->argb_device);
450
451         g_object_unref(pixbuf);
452
453         return surface;
454 }
455
456 #endif
457
458 struct wl_buffer *
459 display_get_buffer_for_surface(struct display *display,
460                                cairo_surface_t *surface)
461 {
462         struct surface_data *data;
463
464         data = cairo_surface_get_user_data (surface, &surface_data_key);
465
466         return data->buffer;
467 }
468
469 struct shm_surface_data {
470         struct surface_data data;
471         void *map;
472         size_t length;
473 };
474
475 static void
476 shm_surface_data_destroy(void *p)
477 {
478         struct shm_surface_data *data = p;
479
480         wl_buffer_destroy(data->data.buffer);
481         munmap(data->map, data->length);
482 }
483
484 static cairo_surface_t *
485 display_create_shm_surface(struct display *display,
486                            struct rectangle *rectangle, uint32_t flags)
487 {
488         struct shm_surface_data *data;
489         uint32_t format;
490         cairo_surface_t *surface;
491         int stride, fd;
492         char filename[] = "/tmp/wayland-shm-XXXXXX";
493
494         data = malloc(sizeof *data);
495         if (data == NULL)
496                 return NULL;
497
498         stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,
499                                                 rectangle->width);
500         data->length = stride * rectangle->height;
501         fd = mkstemp(filename);
502         if (fd < 0) {
503                 fprintf(stderr, "open %s failed: %m\n", filename);
504                 return NULL;
505         }
506         if (ftruncate(fd, data->length) < 0) {
507                 fprintf(stderr, "ftruncate failed: %m\n");
508                 close(fd);
509                 return NULL;
510         }
511
512         data->map = mmap(NULL, data->length,
513                          PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
514         unlink(filename);
515
516         if (data->map == MAP_FAILED) {
517                 fprintf(stderr, "mmap failed: %m\n");
518                 close(fd);
519                 return NULL;
520         }
521
522         surface = cairo_image_surface_create_for_data (data->map,
523                                                        CAIRO_FORMAT_ARGB32,
524                                                        rectangle->width,
525                                                        rectangle->height,
526                                                        stride);
527
528         cairo_surface_set_user_data (surface, &surface_data_key,
529                                      data, shm_surface_data_destroy);
530
531         if (flags & SURFACE_OPAQUE)
532                 format = WL_SHM_FORMAT_XRGB32;
533         else
534                 format = WL_SHM_FORMAT_PREMULTIPLIED_ARGB32;
535
536         data->data.buffer = wl_shm_create_buffer(display->shm,
537                                                  fd,
538                                                  rectangle->width,
539                                                  rectangle->height,
540                                                  stride, format);
541
542         close(fd);
543
544         return surface;
545 }
546
547 static cairo_surface_t *
548 display_create_shm_surface_from_file(struct display *display,
549                                      const char *filename,
550                                      struct rectangle *rect)
551 {
552         cairo_surface_t *surface;
553         GdkPixbuf *pixbuf;
554         GError *error = NULL;
555         int stride, i;
556         unsigned char *pixels, *p, *end, *dest_data;
557         int dest_stride;
558         uint32_t *d;
559
560         pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
561                                                    rect->width, rect->height,
562                                                    FALSE, &error);
563         if (error != NULL)
564                 return NULL;
565
566         if (!gdk_pixbuf_get_has_alpha(pixbuf) ||
567             gdk_pixbuf_get_n_channels(pixbuf) != 4) {
568                 g_object_unref(pixbuf);
569                 return NULL;
570         }
571
572         stride = gdk_pixbuf_get_rowstride(pixbuf);
573         pixels = gdk_pixbuf_get_pixels(pixbuf);
574
575         surface = display_create_shm_surface(display, rect, 0);
576         if (surface == NULL) {
577                 g_object_unref(pixbuf);
578                 return NULL;
579         }
580
581         dest_data = cairo_image_surface_get_data (surface);
582         dest_stride = cairo_image_surface_get_stride (surface);
583
584         for (i = 0; i < rect->height; i++) {
585                 d = (uint32_t *) (dest_data + i * dest_stride);
586                 p = pixels + i * stride;
587                 end = p + rect->width * 4;
588                 while (p < end) {
589                         unsigned int t;
590                         unsigned char a, r, g, b;
591
592                         a = p[3];
593                         MULT(r, p[0], a, t);
594                         MULT(g, p[1], a, t);
595                         MULT(b, p[2], a, t);
596                         p += 4;
597                         *d++ = (a << 24) | (r << 16) | (g << 8) | b;
598                 }
599         }
600
601         g_object_unref(pixbuf);
602
603         return surface;
604 }
605
606 static int
607 check_size(struct rectangle *rect)
608 {
609         if (rect->width && rect->height)
610                 return 0;
611
612         fprintf(stderr, "tried to create surface of "
613                 "width: %d, height: %d\n", rect->width, rect->height);
614         return -1;
615 }
616
617 cairo_surface_t *
618 display_create_surface(struct display *display,
619                        struct wl_surface *surface,
620                        struct rectangle *rectangle,
621                        uint32_t flags)
622 {
623         if (check_size(rectangle) < 0)
624                 return NULL;
625 #ifdef HAVE_CAIRO_EGL
626         if (display->dpy) {
627                 if (surface)
628                         return display_create_egl_window_surface(display,
629                                                                  surface,
630                                                                  flags,
631                                                                  rectangle);
632                 else
633                         return display_create_egl_image_surface(display,
634                                                                 flags,
635                                                                 rectangle);
636         }
637 #endif
638         return display_create_shm_surface(display, rectangle, flags);
639 }
640
641 static cairo_surface_t *
642 display_create_surface_from_file(struct display *display,
643                                  const char *filename,
644                                  struct rectangle *rectangle)
645 {
646         if (check_size(rectangle) < 0)
647                 return NULL;
648 #ifdef HAVE_CAIRO_EGL
649         if (display->dpy) {
650                 return display_create_egl_image_surface_from_file(display,
651                                                                   filename,
652                                                                   rectangle);
653         }
654 #endif
655         return display_create_shm_surface_from_file(display, filename, rectangle);
656 }
657  static const struct {
658         const char *filename;
659         int hotspot_x, hotspot_y;
660 } pointer_images[] = {
661         { DATADIR "/wayland/bottom_left_corner.png",     6, 30 },
662         { DATADIR "/wayland/bottom_right_corner.png",   28, 28 },
663         { DATADIR "/wayland/bottom_side.png",           16, 20 },
664         { DATADIR "/wayland/grabbing.png",              20, 17 },
665         { DATADIR "/wayland/left_ptr.png",              10,  5 },
666         { DATADIR "/wayland/left_side.png",             10, 20 },
667         { DATADIR "/wayland/right_side.png",            30, 19 },
668         { DATADIR "/wayland/top_left_corner.png",        8,  8 },
669         { DATADIR "/wayland/top_right_corner.png",      26,  8 },
670         { DATADIR "/wayland/top_side.png",              18,  8 },
671         { DATADIR "/wayland/xterm.png",                 15, 15 },
672         { DATADIR "/wayland/hand1.png",                 18, 11 }
673 };
674
675 static void
676 create_pointer_surfaces(struct display *display)
677 {
678         int i, count;
679         const int width = 32, height = 32;
680         struct rectangle rect;
681
682         count = ARRAY_LENGTH(pointer_images);
683         display->pointer_surfaces =
684                 malloc(count * sizeof *display->pointer_surfaces);
685         rect.width = width;
686         rect.height = height;
687         for (i = 0; i < count; i++) {
688                 display->pointer_surfaces[i] =
689                         display_create_surface_from_file(display,
690                                                          pointer_images[i].filename,
691                                                          &rect);
692                 if (!display->pointer_surfaces[i]) {
693                         fprintf(stderr, "Error loading pointer image: %s\n",
694                                 pointer_images[i].filename);
695                 }
696         }
697
698 }
699
700 cairo_surface_t *
701 display_get_pointer_surface(struct display *display, int pointer,
702                             int *width, int *height,
703                             int *hotspot_x, int *hotspot_y)
704 {
705         cairo_surface_t *surface;
706
707         surface = display->pointer_surfaces[pointer];
708 #if HAVE_CAIRO_EGL
709         *width = cairo_gl_surface_get_width(surface);
710         *height = cairo_gl_surface_get_height(surface);
711 #else
712         *width = cairo_image_surface_get_width(surface);
713         *height = cairo_image_surface_get_height(surface);
714 #endif
715         *hotspot_x = pointer_images[pointer].hotspot_x;
716         *hotspot_y = pointer_images[pointer].hotspot_y;
717
718         return cairo_surface_reference(surface);
719 }
720
721 static void
722 window_attach_surface(struct window *window);
723
724 static void
725 free_surface(void *data, struct wl_callback *callback, uint32_t time)
726 {
727         struct window *window = data;
728
729         wl_callback_destroy(callback);
730         cairo_surface_destroy(window->pending_surface);
731         window->pending_surface = NULL;
732         if (window->cairo_surface)
733                 window_attach_surface(window);
734 }
735
736 static const struct wl_callback_listener free_surface_listener = {
737         free_surface
738 };
739
740 static void
741 window_get_resize_dx_dy(struct window *window, int *x, int *y)
742 {
743         if (window->resize_edges & WINDOW_RESIZING_LEFT)
744                 *x = window->server_allocation.width - window->allocation.width;
745         else
746                 *x = 0;
747
748         if (window->resize_edges & WINDOW_RESIZING_TOP)
749                 *y = window->server_allocation.height -
750                         window->allocation.height;
751         else
752                 *y = 0;
753
754         window->resize_edges = 0;
755 }
756
757 static void
758 window_set_type(struct window *window)
759 {
760         if (!window->shell_surface)
761                 return;
762
763         switch (window->type) {
764         case TYPE_FULLSCREEN:
765                 wl_shell_surface_set_fullscreen(window->shell_surface);
766                 break;
767         case TYPE_TOPLEVEL:
768                 wl_shell_surface_set_toplevel(window->shell_surface);
769                 break;
770         case TYPE_TRANSIENT:
771                 wl_shell_surface_set_transient(window->shell_surface,
772                                                window->parent->shell_surface,
773                                                window->x, window->y, 0);
774                 break;
775         case TYPE_CUSTOM:
776                 break;
777         }
778 }
779
780 static void
781 window_attach_surface(struct window *window)
782 {
783         struct display *display = window->display;
784         struct wl_buffer *buffer;
785         struct wl_callback *cb;
786 #ifdef HAVE_CAIRO_EGL
787         struct egl_window_surface_data *data;
788 #endif
789         int32_t x, y;
790
791         if (display->shell)
792                 window_set_type(window);
793
794         switch (window->buffer_type) {
795 #ifdef HAVE_CAIRO_EGL
796         case WINDOW_BUFFER_TYPE_EGL_WINDOW:
797                 data = cairo_surface_get_user_data(window->cairo_surface,
798                                                    &surface_data_key);
799
800                 cairo_gl_surface_swapbuffers(window->cairo_surface);
801                 wl_egl_window_get_attached_size(data->window,
802                                 &window->server_allocation.width,
803                                 &window->server_allocation.height);
804                 break;
805         case WINDOW_BUFFER_TYPE_EGL_IMAGE:
806 #endif
807         case WINDOW_BUFFER_TYPE_SHM:
808                 window_get_resize_dx_dy(window, &x, &y);
809
810                 if (window->pending_surface != NULL)
811                         return;
812
813                 window->pending_surface = window->cairo_surface;
814                 window->cairo_surface = NULL;
815
816                 buffer =
817                         display_get_buffer_for_surface(display,
818                                                        window->pending_surface);
819
820                 wl_surface_attach(window->surface, buffer, x, y);
821                 window->server_allocation = window->allocation;
822                 cb = wl_display_sync(display->display);
823                 wl_callback_add_listener(cb, &free_surface_listener, window);
824                 break;
825         default:
826                 return;
827         }
828
829         wl_surface_damage(window->surface, 0, 0,
830                           window->allocation.width,
831                           window->allocation.height);
832 }
833
834 void
835 window_flush(struct window *window)
836 {
837         if (window->cairo_surface) {
838                 switch (window->buffer_type) {
839                 case WINDOW_BUFFER_TYPE_EGL_IMAGE:
840                 case WINDOW_BUFFER_TYPE_SHM:
841                         display_surface_damage(window->display,
842                                                window->cairo_surface,
843                                                0, 0,
844                                                window->allocation.width,
845                                                window->allocation.height);
846                         break;
847                 default:
848                         break;
849                 }
850                 window_attach_surface(window);
851         }
852 }
853
854 void
855 window_set_surface(struct window *window, cairo_surface_t *surface)
856 {
857         cairo_surface_reference(surface);
858
859         if (window->cairo_surface != NULL)
860                 cairo_surface_destroy(window->cairo_surface);
861
862         window->cairo_surface = surface;
863 }
864
865 #ifdef HAVE_CAIRO_EGL
866 static void
867 window_resize_cairo_window_surface(struct window *window)
868 {
869         struct egl_window_surface_data *data;
870         int x, y;
871
872         data = cairo_surface_get_user_data(window->cairo_surface,
873                                            &surface_data_key);
874
875         window_get_resize_dx_dy(window, &x, &y),
876         wl_egl_window_resize(data->window,
877                              window->allocation.width,
878                              window->allocation.height,
879                              x,y);
880
881         cairo_gl_surface_set_size(window->cairo_surface,
882                                   window->allocation.width,
883                                   window->allocation.height);
884 }
885 #endif
886
887 struct display *
888 window_get_display(struct window *window)
889 {
890         return window->display;
891 }
892
893 void
894 window_create_surface(struct window *window)
895 {
896         cairo_surface_t *surface;
897         uint32_t flags = 0;
898         
899         if (!window->transparent)
900                 flags = SURFACE_OPAQUE;
901         
902         switch (window->buffer_type) {
903 #ifdef HAVE_CAIRO_EGL
904         case WINDOW_BUFFER_TYPE_EGL_WINDOW:
905                 if (window->cairo_surface) {
906                         window_resize_cairo_window_surface(window);
907                         return;
908                 }
909                 surface = display_create_surface(window->display,
910                                                  window->surface,
911                                                  &window->allocation, flags);
912                 break;
913         case WINDOW_BUFFER_TYPE_EGL_IMAGE:
914                 surface = display_create_surface(window->display,
915                                                  NULL,
916                                                  &window->allocation, flags);
917                 break;
918 #endif
919         case WINDOW_BUFFER_TYPE_SHM:
920                 surface = display_create_shm_surface(window->display,
921                                                      &window->allocation, flags);
922                 break;
923         default:
924                 surface = NULL;
925                 break;
926         }
927
928         window_set_surface(window, surface);
929         cairo_surface_destroy(surface);
930 }
931
932 static void
933 window_draw_menu(struct window *window)
934 {
935         cairo_t *cr;
936         int width, height, r = 5;
937
938         window_create_surface(window);
939
940         cr = cairo_create(window->cairo_surface);
941         cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
942         cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
943         cairo_paint(cr);
944
945         width = window->allocation.width;
946         height = window->allocation.height;
947         rounded_rect(cr, r, r, width - r, height - r, r);
948         cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
949         cairo_set_source_rgba(cr, 1.0, 1.0, 0.0, 0.5);
950         cairo_fill(cr);
951         cairo_destroy(cr);
952 }
953
954 static void
955 window_draw_decorations(struct window *window)
956 {
957         cairo_t *cr;
958         cairo_text_extents_t extents;
959         cairo_surface_t *frame;
960         int width, height, shadow_dx = 3, shadow_dy = 3;
961
962         window_create_surface(window);
963
964         width = window->allocation.width;
965         height = window->allocation.height;
966
967         cr = cairo_create(window->cairo_surface);
968
969         cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
970         cairo_set_source_rgba(cr, 0, 0, 0, 0);
971         cairo_paint(cr);
972
973         cairo_set_source_rgba(cr, 0, 0, 0, 0.6);
974         tile_mask(cr, window->display->shadow,
975                   shadow_dx, shadow_dy, width, height,
976                   window->margin + 10 - shadow_dx,
977                   window->margin + 10 - shadow_dy);
978
979         if (window->keyboard_device)
980                 frame = window->display->active_frame;
981         else
982                 frame = window->display->inactive_frame;
983
984         tile_source(cr, frame, 0, 0, width, height,
985                     window->margin + 10, window->margin + 50);
986
987         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
988         cairo_set_font_size(cr, 14);
989         cairo_text_extents(cr, window->title, &extents);
990         cairo_move_to(cr, (width - extents.width) / 2, 32 - extents.y_bearing);
991         if (window->keyboard_device)
992                 cairo_set_source_rgb(cr, 0, 0, 0);
993         else
994                 cairo_set_source_rgb(cr, 0.8, 0.8, 0.8);
995         cairo_show_text(cr, window->title);
996
997         cairo_destroy(cr);
998 }
999
1000 void
1001 window_destroy(struct window *window)
1002 {
1003         struct display *display = window->display;
1004         struct input *input;
1005
1006         if (window->redraw_scheduled)
1007                 wl_list_remove(&window->redraw_task.link);
1008
1009         wl_list_for_each(input, &display->input_list, link) {
1010                 if (input->pointer_focus == window)
1011                         input->pointer_focus = NULL;
1012                 if (input->keyboard_focus == window)
1013                         input->keyboard_focus = NULL;
1014         }
1015
1016         if (window->shell_surface)
1017                 wl_shell_surface_destroy(window->shell_surface);
1018         wl_surface_destroy(window->surface);
1019         wl_list_remove(&window->link);
1020         free(window);
1021 }
1022
1023 static struct item *
1024 window_find_item(struct window *window, int32_t x, int32_t y)
1025 {
1026         struct item *item;
1027
1028         wl_list_for_each(item, &window->item_list, link) {
1029                 if (item->allocation.x <= x &&
1030                     x < item->allocation.x + item->allocation.width &&
1031                     item->allocation.y <= y &&
1032                     y < item->allocation.y + item->allocation.height) {
1033                         return item;
1034                 }
1035         }
1036
1037         return NULL;
1038 }
1039
1040 struct item *
1041 window_add_item(struct window *window, void *data)
1042 {
1043         struct item *item;
1044
1045         item = malloc(sizeof *item);
1046         memset(item, 0, sizeof *item);
1047         item->user_data = data;
1048         wl_list_insert(window->item_list.prev, &item->link);
1049
1050         return item;
1051 }
1052
1053 void
1054 window_for_each_item(struct window *window, item_func_t func, void *data)
1055 {
1056         struct item *item;
1057
1058         wl_list_for_each(item, &window->item_list, link)
1059                 func(item, data);
1060 }
1061
1062 struct item *
1063 window_get_focus_item(struct window *window)
1064 {
1065         return window->focus_item;
1066 }
1067
1068 void
1069 item_get_allocation(struct item *item, struct rectangle *allocation)
1070 {
1071         *allocation = item->allocation;
1072 }
1073
1074 void
1075 item_set_allocation(struct item *item,
1076                     int32_t x, int32_t y, int32_t width, int32_t height)
1077 {
1078         item->allocation.x = x;
1079         item->allocation.y = y;
1080         item->allocation.width = width;
1081         item->allocation.height = height;
1082 }
1083
1084 void *
1085 item_get_user_data(struct item *item)
1086 {
1087         return item->user_data;
1088 }
1089
1090 void
1091 window_draw(struct window *window)
1092 {
1093         if (window->parent)
1094                 window_draw_menu(window);
1095         else if (!window->decoration)
1096                 window_create_surface(window);
1097         else
1098                 window_draw_decorations(window);
1099 }
1100
1101 cairo_surface_t *
1102 window_get_surface(struct window *window)
1103 {
1104         return cairo_surface_reference(window->cairo_surface);
1105 }
1106
1107 struct wl_surface *
1108 window_get_wl_surface(struct window *window)
1109 {
1110         return window->surface;
1111 }
1112
1113 struct wl_shell_surface *
1114 window_get_wl_shell_surface(struct window *window)
1115 {
1116         return window->shell_surface;
1117 }
1118
1119 static int
1120 get_pointer_location(struct window *window, int32_t x, int32_t y)
1121 {
1122         int vlocation, hlocation, location;
1123         const int grip_size = 8;
1124
1125         if (!window->decoration)
1126                 return WINDOW_CLIENT_AREA;
1127
1128         if (x < window->margin)
1129                 hlocation = WINDOW_EXTERIOR;
1130         else if (window->margin <= x && x < window->margin + grip_size)
1131                 hlocation = WINDOW_RESIZING_LEFT;
1132         else if (x < window->allocation.width - window->margin - grip_size)
1133                 hlocation = WINDOW_INTERIOR;
1134         else if (x < window->allocation.width - window->margin)
1135                 hlocation = WINDOW_RESIZING_RIGHT;
1136         else
1137                 hlocation = WINDOW_EXTERIOR;
1138
1139         if (y < window->margin)
1140                 vlocation = WINDOW_EXTERIOR;
1141         else if (window->margin <= y && y < window->margin + grip_size)
1142                 vlocation = WINDOW_RESIZING_TOP;
1143         else if (y < window->allocation.height - window->margin - grip_size)
1144                 vlocation = WINDOW_INTERIOR;
1145         else if (y < window->allocation.height - window->margin)
1146                 vlocation = WINDOW_RESIZING_BOTTOM;
1147         else
1148                 vlocation = WINDOW_EXTERIOR;
1149
1150         location = vlocation | hlocation;
1151         if (location & WINDOW_EXTERIOR)
1152                 location = WINDOW_EXTERIOR;
1153         if (location == WINDOW_INTERIOR && y < window->margin + 50)
1154                 location = WINDOW_TITLEBAR;
1155         else if (location == WINDOW_INTERIOR)
1156                 location = WINDOW_CLIENT_AREA;
1157
1158         return location;
1159 }
1160
1161 static int
1162 input_get_pointer_image_for_location(struct input *input, int pointer)
1163 {
1164         int location;
1165
1166         location = get_pointer_location(input->pointer_focus,
1167                                         input->sx, input->sy);
1168         switch (location) {
1169         case WINDOW_RESIZING_TOP:
1170                 return POINTER_TOP;
1171         case WINDOW_RESIZING_BOTTOM:
1172                 return POINTER_BOTTOM;
1173         case WINDOW_RESIZING_LEFT:
1174                 return POINTER_LEFT;
1175         case WINDOW_RESIZING_RIGHT:
1176                 return POINTER_RIGHT;
1177         case WINDOW_RESIZING_TOP_LEFT:
1178                 return POINTER_TOP_LEFT;
1179         case WINDOW_RESIZING_TOP_RIGHT:
1180                 return POINTER_TOP_RIGHT;
1181         case WINDOW_RESIZING_BOTTOM_LEFT:
1182                 return POINTER_BOTTOM_LEFT;
1183         case WINDOW_RESIZING_BOTTOM_RIGHT:
1184                 return POINTER_BOTTOM_RIGHT;
1185         case WINDOW_EXTERIOR:
1186         case WINDOW_TITLEBAR:
1187                 return POINTER_LEFT_PTR;
1188         default:
1189                 return pointer;
1190         }
1191 }
1192
1193 void
1194 input_set_pointer_image(struct input *input, uint32_t time, int pointer)
1195 {
1196         struct display *display = input->display;
1197         struct wl_buffer *buffer;
1198         cairo_surface_t *surface;
1199
1200         if (pointer == input->current_pointer_image)
1201                 return;
1202
1203         input->current_pointer_image = pointer;
1204         surface = display->pointer_surfaces[pointer];
1205
1206         if (!surface)
1207                 return;
1208
1209         buffer = display_get_buffer_for_surface(display, surface);
1210         wl_input_device_attach(input->input_device, time, buffer,
1211                                pointer_images[pointer].hotspot_x,
1212                                pointer_images[pointer].hotspot_y);
1213 }
1214
1215 static void
1216 window_set_focus_item(struct window *window, struct item *focus)
1217 {
1218         void *data;
1219
1220         if (focus == window->focus_item)
1221                 return;
1222
1223         window->focus_item = focus;
1224         data = focus ? focus->user_data : NULL;
1225         if (window->item_focus_handler)
1226                 window->item_focus_handler(window, focus, data);
1227 }
1228
1229 static void
1230 window_handle_motion(void *data, struct wl_input_device *input_device,
1231                      uint32_t time,
1232                      int32_t x, int32_t y, int32_t sx, int32_t sy)
1233 {
1234         struct input *input = data;
1235         struct window *window = input->pointer_focus;
1236         struct item *item;
1237         int pointer = POINTER_LEFT_PTR;
1238
1239         input->x = x;
1240         input->y = y;
1241         input->sx = sx;
1242         input->sy = sy;
1243
1244         if (!window->focus_item || !window->item_grab_button) {
1245                 item = window_find_item(window, sx, sy);
1246                 window_set_focus_item(window, item);
1247         }
1248
1249         if (window->motion_handler)
1250                 pointer = (*window->motion_handler)(window, input, time,
1251                                                     x, y, sx, sy,
1252                                                     window->user_data);
1253
1254         pointer = input_get_pointer_image_for_location(input, pointer);
1255         input_set_pointer_image(input, time, pointer);
1256 }
1257
1258 static void
1259 window_handle_button(void *data,
1260                      struct wl_input_device *input_device,
1261                      uint32_t time, uint32_t button, uint32_t state)
1262 {
1263         struct input *input = data;
1264         struct window *window = input->pointer_focus;
1265         struct item *item;
1266         int location;
1267
1268         if (window->focus_item && window->item_grab_button == 0 && state)
1269                 window->item_grab_button = button;
1270
1271         location = get_pointer_location(window, input->sx, input->sy);
1272
1273         if (window->display->shell &&
1274             button == BTN_LEFT && state == 1) {
1275                 switch (location) {
1276                 case WINDOW_TITLEBAR:
1277                         if (!window->shell_surface)
1278                                 break;
1279                         input_set_pointer_image(input, time, POINTER_DRAGGING);
1280                         wl_shell_surface_move(window->shell_surface,
1281                                               input_device, time);
1282                         break;
1283                 case WINDOW_RESIZING_TOP:
1284                 case WINDOW_RESIZING_BOTTOM:
1285                 case WINDOW_RESIZING_LEFT:
1286                 case WINDOW_RESIZING_RIGHT:
1287                 case WINDOW_RESIZING_TOP_LEFT:
1288                 case WINDOW_RESIZING_TOP_RIGHT:
1289                 case WINDOW_RESIZING_BOTTOM_LEFT:
1290                 case WINDOW_RESIZING_BOTTOM_RIGHT:
1291                         if (!window->shell_surface)
1292                                 break;
1293                         wl_shell_surface_resize(window->shell_surface,
1294                                                 input_device, time,
1295                                                 location);
1296                         break;
1297                 case WINDOW_CLIENT_AREA:
1298                         if (window->button_handler)
1299                                 (*window->button_handler)(window,
1300                                                           input, time,
1301                                                           button, state,
1302                                                           window->user_data);
1303                         break;
1304                 }
1305         } else {
1306                 if (window->button_handler)
1307                         (*window->button_handler)(window,
1308                                                   input, time,
1309                                                   button, state,
1310                                                   window->user_data);
1311         }
1312
1313         if (window->focus_item &&
1314             window->item_grab_button == button && !state) {
1315                 window->item_grab_button = 0;
1316                 item = window_find_item(window, input->sx, input->sy);
1317                 window_set_focus_item(window, item);
1318         }
1319 }
1320
1321 static void
1322 window_handle_key(void *data, struct wl_input_device *input_device,
1323                   uint32_t time, uint32_t key, uint32_t state)
1324 {
1325         struct input *input = data;
1326         struct window *window = input->keyboard_focus;
1327         struct display *d = input->display;
1328         uint32_t code, sym, level;
1329
1330         code = key + d->xkb->min_key_code;
1331         if (!window || window->keyboard_device != input)
1332                 return;
1333
1334         level = 0;
1335         if (input->modifiers & XKB_COMMON_SHIFT_MASK &&
1336             XkbKeyGroupWidth(d->xkb, code, 0) > 1)
1337                 level = 1;
1338
1339         sym = XkbKeySymEntry(d->xkb, code, level, 0);
1340
1341         if (state)
1342                 input->modifiers |= d->xkb->map->modmap[code];
1343         else
1344                 input->modifiers &= ~d->xkb->map->modmap[code];
1345
1346         if (window->key_handler)
1347                 (*window->key_handler)(window, input, time, key, sym, state,
1348                                        window->user_data);
1349 }
1350
1351 static void
1352 window_handle_pointer_focus(void *data,
1353                             struct wl_input_device *input_device,
1354                             uint32_t time, struct wl_surface *surface,
1355                             int32_t x, int32_t y, int32_t sx, int32_t sy)
1356 {
1357         struct input *input = data;
1358         struct window *window;
1359         struct item *item;
1360         int pointer;
1361
1362         window = input->pointer_focus;
1363         if (window && window->surface != surface) {
1364                 window_set_focus_item(window, NULL);
1365
1366                 if (window->leave_handler)
1367                         window->leave_handler(window, input,
1368                                               time, window->user_data);
1369                 input->pointer_focus = NULL;
1370                 input->current_pointer_image = POINTER_UNSET;
1371         }
1372
1373         if (surface) {
1374                 input->pointer_focus = wl_surface_get_user_data(surface);
1375                 window = input->pointer_focus;
1376
1377                 input->x = x;
1378                 input->y = y;
1379                 input->sx = sx;
1380                 input->sy = sy;
1381
1382                 pointer = POINTER_LEFT_PTR;
1383                 if (window->enter_handler)
1384                         pointer = window->enter_handler(window, input,
1385                                                         time, sx, sy,
1386                                                         window->user_data);
1387
1388                 item = window_find_item(window, x, y);
1389                 window_set_focus_item(window, item);
1390
1391                 pointer = input_get_pointer_image_for_location(input, pointer);
1392                 input_set_pointer_image(input, time, pointer);
1393         }
1394 }
1395
1396 static void
1397 window_handle_keyboard_focus(void *data,
1398                              struct wl_input_device *input_device,
1399                              uint32_t time,
1400                              struct wl_surface *surface,
1401                              struct wl_array *keys)
1402 {
1403         struct input *input = data;
1404         struct window *window = input->keyboard_focus;
1405         struct display *d = input->display;
1406         uint32_t *k, *end;
1407
1408         if (window) {
1409                 window->keyboard_device = NULL;
1410                 if (window->keyboard_focus_handler)
1411                         (*window->keyboard_focus_handler)(window, NULL,
1412                                                           window->user_data);
1413         }
1414
1415         if (surface)
1416                 input->keyboard_focus = wl_surface_get_user_data(surface);
1417         else
1418                 input->keyboard_focus = NULL;
1419
1420         end = keys->data + keys->size;
1421         input->modifiers = 0;
1422         for (k = keys->data; k < end; k++)
1423                 input->modifiers |= d->xkb->map->modmap[*k];
1424
1425         window = input->keyboard_focus;
1426         if (window) {
1427                 window->keyboard_device = input;
1428                 if (window->keyboard_focus_handler)
1429                         (*window->keyboard_focus_handler)(window,
1430                                                           window->keyboard_device,
1431                                                           window->user_data);
1432         }
1433 }
1434
1435 static const struct wl_input_device_listener input_device_listener = {
1436         window_handle_motion,
1437         window_handle_button,
1438         window_handle_key,
1439         window_handle_pointer_focus,
1440         window_handle_keyboard_focus,
1441 };
1442
1443 void
1444 input_get_position(struct input *input, int32_t *x, int32_t *y)
1445 {
1446         *x = input->sx;
1447         *y = input->sy;
1448 }
1449
1450 struct wl_input_device *
1451 input_get_input_device(struct input *input)
1452 {
1453         return input->input_device;
1454 }
1455
1456 uint32_t
1457 input_get_modifiers(struct input *input)
1458 {
1459         return input->modifiers;
1460 }
1461
1462 struct data_offer {
1463         struct wl_data_offer *offer;
1464         struct input *input;
1465         struct wl_array types;
1466         int refcount;
1467
1468         struct task io_task;
1469         int fd;
1470         data_func_t func;
1471         int32_t x, y;
1472         void *user_data;
1473 };
1474
1475 static void
1476 data_offer_offer(void *data, struct wl_data_offer *wl_data_offer, const char *type)
1477 {
1478         struct data_offer *offer = data;
1479         char **p;
1480
1481         p = wl_array_add(&offer->types, sizeof *p);
1482         *p = strdup(type);
1483 }
1484
1485 static const struct wl_data_offer_listener data_offer_listener = {
1486         data_offer_offer,
1487 };
1488
1489 static void
1490 data_offer_destroy(struct data_offer *offer)
1491 {
1492         char **p;
1493
1494         offer->refcount--;
1495         if (offer->refcount == 0) {
1496                 wl_data_offer_destroy(offer->offer);
1497                 for (p = offer->types.data; *p; p++)
1498                         free(*p);
1499                 wl_array_release(&offer->types);
1500                 free(offer);
1501         }
1502 }
1503
1504 static void
1505 data_device_data_offer(void *data,
1506                        struct wl_data_device *data_device, uint32_t id)
1507 {
1508         struct data_offer *offer;
1509
1510         offer = malloc(sizeof *offer);
1511
1512         wl_array_init(&offer->types);
1513         offer->refcount = 1;
1514         offer->input = data;
1515
1516         /* FIXME: Generate typesafe wrappers for this */
1517         offer->offer = (struct wl_data_offer *)
1518                 wl_proxy_create_for_id((struct wl_proxy *) data_device,
1519                                        id, &wl_data_offer_interface);
1520
1521         wl_data_offer_add_listener(offer->offer,
1522                                    &data_offer_listener, offer);
1523 }
1524
1525 static void
1526 data_device_enter(void *data, struct wl_data_device *data_device,
1527                   uint32_t time, struct wl_surface *surface,
1528                   int32_t x, int32_t y, struct wl_data_offer *offer)
1529 {
1530         struct input *input = data;
1531         struct window *window;
1532         char **p;
1533
1534         input->drag_offer = wl_data_offer_get_user_data(offer);
1535         window = wl_surface_get_user_data(surface);
1536         input->pointer_focus = window;
1537
1538         p = wl_array_add(&input->drag_offer->types, sizeof *p);
1539         *p = NULL;
1540
1541         window = input->pointer_focus;
1542         if (window->data_handler)
1543                 window->data_handler(window, input, time, x, y,
1544                                      input->drag_offer->types.data,
1545                                      window->user_data);
1546 }
1547
1548 static void
1549 data_device_leave(void *data, struct wl_data_device *data_device)
1550 {
1551         struct input *input = data;
1552
1553         data_offer_destroy(input->drag_offer);
1554         input->drag_offer = NULL;
1555 }
1556
1557 static void
1558 data_device_motion(void *data, struct wl_data_device *data_device,
1559                    uint32_t time, int32_t x, int32_t y)
1560 {
1561         struct input *input = data;
1562         struct window *window = input->pointer_focus;
1563
1564         input->sx = x;
1565         input->sy = y;
1566
1567         if (window->data_handler)
1568                 window->data_handler(window, input, time, x, y,
1569                                      input->drag_offer->types.data,
1570                                      window->user_data);
1571 }
1572
1573 static void
1574 data_device_drop(void *data, struct wl_data_device *data_device)
1575 {
1576         struct input *input = data;
1577         struct window *window = input->pointer_focus;
1578
1579         if (window->drop_handler)
1580                 window->drop_handler(window, input,
1581                                      input->sx, input->sy, window->user_data);
1582 }
1583
1584 static void
1585 data_device_selection(void *data,
1586                       struct wl_data_device *wl_data_device,
1587                       struct wl_data_offer *offer)
1588 {
1589         struct input *input = data;
1590         char **p;
1591
1592         if (input->selection_offer)
1593                 data_offer_destroy(input->selection_offer);
1594
1595         input->selection_offer = wl_data_offer_get_user_data(offer);
1596         p = wl_array_add(&input->selection_offer->types, sizeof *p);
1597         *p = NULL;
1598 }
1599
1600 static const struct wl_data_device_listener data_device_listener = {
1601         data_device_data_offer,
1602         data_device_enter,
1603         data_device_leave,
1604         data_device_motion,
1605         data_device_drop,
1606         data_device_selection
1607 };
1608
1609 struct wl_data_device *
1610 input_get_data_device(struct input *input)
1611 {
1612         return input->data_device;
1613 }
1614
1615 void
1616 input_set_selection(struct input *input,
1617                     struct wl_data_source *source, uint32_t time)
1618 {
1619         wl_data_device_set_selection(input->data_device, source, time);
1620 }
1621
1622 void
1623 input_accept(struct input *input, uint32_t time, const char *type)
1624 {
1625         wl_data_offer_accept(input->drag_offer->offer, time, type);
1626 }
1627
1628 static void
1629 offer_io_func(struct task *task, uint32_t events)
1630 {
1631         struct data_offer *offer =
1632                 container_of(task, struct data_offer, io_task);
1633         unsigned int len;
1634         char buffer[4096];
1635
1636         len = read(offer->fd, buffer, sizeof buffer);
1637         offer->func(buffer, len,
1638                     offer->x, offer->y, offer->user_data);
1639
1640         if (len == 0) {
1641                 close(offer->fd);
1642                 data_offer_destroy(offer);
1643         }
1644 }
1645
1646 static void
1647 data_offer_receive_data(struct data_offer *offer, const char *mime_type,
1648                         data_func_t func, void *user_data)
1649 {
1650         int p[2];
1651
1652         pipe2(p, O_CLOEXEC);
1653         wl_data_offer_receive(offer->offer, mime_type, p[1]);
1654         close(p[1]);
1655
1656         offer->io_task.run = offer_io_func;
1657         offer->fd = p[0];
1658         offer->func = func;
1659         offer->refcount++;
1660         offer->user_data = user_data;
1661
1662         display_watch_fd(offer->input->display,
1663                          offer->fd, EPOLLIN, &offer->io_task);
1664 }
1665
1666 void
1667 input_receive_drag_data(struct input *input, const char *mime_type,
1668                         data_func_t func, void *data)
1669 {
1670         data_offer_receive_data(input->drag_offer, mime_type, func, data);
1671         input->drag_offer->x = input->sx;
1672         input->drag_offer->y = input->sy;
1673 }
1674
1675 int
1676 input_receive_selection_data(struct input *input, const char *mime_type,
1677                              data_func_t func, void *data)
1678 {
1679         char **p;
1680
1681         if (input->selection_offer == NULL)
1682                 return -1;
1683
1684         for (p = input->selection_offer->types.data; *p; p++)
1685                 if (strcmp(mime_type, *p) == 0)
1686                         break;
1687
1688         if (*p == NULL)
1689                 return -1;
1690
1691         data_offer_receive_data(input->selection_offer,
1692                                 mime_type, func, data);
1693         return 0;
1694 }
1695
1696 void
1697 window_move(struct window *window, struct input *input, uint32_t time)
1698 {
1699         if (!window->shell_surface)
1700                 return;
1701
1702         wl_shell_surface_move(window->shell_surface,
1703                               input->input_device, time);
1704 }
1705
1706 static void
1707 handle_configure(void *data, struct wl_shell_surface *shell_surface,
1708                  uint32_t time, uint32_t edges,
1709                  int32_t width, int32_t height)
1710 {
1711         struct window *window = data;
1712         int32_t child_width, child_height;
1713
1714         /* FIXME: this is probably the wrong place to check for width
1715          * or height <= 0, but it prevents the compositor from crashing
1716          */
1717         if (width <= 0 || height <= 0)
1718                 return;
1719
1720         window->resize_edges = edges;
1721
1722         if (window->resize_handler) {
1723                 child_width = width - 20 - window->margin * 2;
1724                 child_height = height - 60 - window->margin * 2;
1725
1726                 (*window->resize_handler)(window,
1727                                           child_width, child_height,
1728                                           window->user_data);
1729         } else {
1730                 window->allocation.width = width;
1731                 window->allocation.height = height;
1732
1733                 if (window->redraw_handler)
1734                         window_schedule_redraw(window);
1735         }
1736 }
1737
1738 static const struct wl_shell_surface_listener shell_surface_listener = {
1739         handle_configure,
1740 };
1741
1742 void
1743 window_get_allocation(struct window *window,
1744                       struct rectangle *allocation)
1745 {
1746         *allocation = window->allocation;
1747 }
1748
1749 void
1750 window_get_child_allocation(struct window *window,
1751                             struct rectangle *allocation)
1752 {
1753         if (!window->decoration) {
1754                 *allocation = window->allocation;
1755         } else {
1756                 allocation->x = window->margin + 10;
1757                 allocation->y = window->margin + 50;
1758                 allocation->width =
1759                         window->allocation.width - 20 - window->margin * 2;
1760                 allocation->height =
1761                         window->allocation.height - 60 - window->margin * 2;
1762         }
1763 }
1764
1765 void
1766 window_set_child_size(struct window *window, int32_t width, int32_t height)
1767 {
1768         if (window->decoration) {
1769                 window->allocation.x = 20 + window->margin;
1770                 window->allocation.y = 60 + window->margin;
1771                 window->allocation.width = width + 20 + window->margin * 2;
1772                 window->allocation.height = height + 60 + window->margin * 2;
1773         } else {
1774                 window->allocation.x = 0;
1775                 window->allocation.y = 0;
1776                 window->allocation.width = width;
1777                 window->allocation.height = height;
1778         }
1779 }
1780
1781 static void
1782 idle_redraw(struct task *task, uint32_t events)
1783 {
1784         struct window *window =
1785                 container_of(task, struct window, redraw_task);
1786
1787         window->redraw_handler(window, window->user_data);
1788         window->redraw_scheduled = 0;
1789 }
1790
1791 void
1792 window_schedule_redraw(struct window *window)
1793 {
1794         if (!window->redraw_scheduled) {
1795                 window->redraw_task.run = idle_redraw;
1796                 display_defer(window->display, &window->redraw_task);
1797                 window->redraw_scheduled = 1;
1798         }
1799 }
1800
1801 void
1802 window_set_custom(struct window *window)
1803 {
1804         window->type = TYPE_CUSTOM;
1805 }
1806
1807 void
1808 window_set_fullscreen(struct window *window, int fullscreen)
1809 {
1810         int32_t width, height;
1811         struct output *output;
1812
1813         if ((window->type == TYPE_FULLSCREEN) == fullscreen)
1814                 return;
1815
1816         if (fullscreen) {
1817                 output = display_get_output(window->display);
1818                 window->type = TYPE_FULLSCREEN;
1819                 window->saved_allocation = window->allocation;
1820                 width = output->allocation.width;
1821                 height = output->allocation.height;
1822                 window->decoration = 0;
1823         } else {
1824                 window->type = TYPE_TOPLEVEL;
1825                 width = window->saved_allocation.width - 20 - window->margin * 2;
1826                 height = window->saved_allocation.height - 60 - window->margin * 2;
1827                 window->decoration = 1;
1828         }
1829
1830         (*window->resize_handler)(window, width, height, window->user_data);
1831 }
1832
1833 void
1834 window_set_decoration(struct window *window, int decoration)
1835 {
1836         window->decoration = decoration;
1837 }
1838
1839 void
1840 window_set_user_data(struct window *window, void *data)
1841 {
1842         window->user_data = data;
1843 }
1844
1845 void *
1846 window_get_user_data(struct window *window)
1847 {
1848         return window->user_data;
1849 }
1850
1851 void
1852 window_set_resize_handler(struct window *window,
1853                           window_resize_handler_t handler)
1854 {
1855         window->resize_handler = handler;
1856 }
1857
1858 void
1859 window_set_redraw_handler(struct window *window,
1860                           window_redraw_handler_t handler)
1861 {
1862         window->redraw_handler = handler;
1863 }
1864
1865 void
1866 window_set_key_handler(struct window *window,
1867                        window_key_handler_t handler)
1868 {
1869         window->key_handler = handler;
1870 }
1871
1872 void
1873 window_set_button_handler(struct window *window,
1874                           window_button_handler_t handler)
1875 {
1876         window->button_handler = handler;
1877 }
1878
1879 void
1880 window_set_motion_handler(struct window *window,
1881                           window_motion_handler_t handler)
1882 {
1883         window->motion_handler = handler;
1884 }
1885
1886 void
1887 window_set_enter_handler(struct window *window,
1888                           window_enter_handler_t handler)
1889 {
1890         window->enter_handler = handler;
1891 }
1892
1893 void
1894 window_set_leave_handler(struct window *window,
1895                           window_leave_handler_t handler)
1896 {
1897         window->leave_handler = handler;
1898 }
1899
1900 void
1901 window_set_keyboard_focus_handler(struct window *window,
1902                                   window_keyboard_focus_handler_t handler)
1903 {
1904         window->keyboard_focus_handler = handler;
1905 }
1906
1907 void
1908 window_set_item_focus_handler(struct window *window,
1909                               window_item_focus_handler_t handler)
1910 {
1911         window->item_focus_handler = handler;
1912 }
1913
1914 void
1915 window_set_data_handler(struct window *window, window_data_handler_t handler)
1916 {
1917         window->data_handler = handler;
1918 }
1919
1920 void
1921 window_set_drop_handler(struct window *window, window_drop_handler_t handler)
1922 {
1923         window->drop_handler = handler;
1924 }
1925
1926 void
1927 window_set_transparent(struct window *window, int transparent)
1928 {
1929         window->transparent = transparent;
1930 }
1931
1932 void
1933 window_set_title(struct window *window, const char *title)
1934 {
1935         free(window->title);
1936         window->title = strdup(title);
1937 }
1938
1939 const char *
1940 window_get_title(struct window *window)
1941 {
1942         return window->title;
1943 }
1944
1945 void
1946 display_surface_damage(struct display *display, cairo_surface_t *cairo_surface,
1947                        int32_t x, int32_t y, int32_t width, int32_t height)
1948 {
1949         struct wl_buffer *buffer;
1950
1951         buffer = display_get_buffer_for_surface(display, cairo_surface);
1952
1953         wl_buffer_damage(buffer, x, y, width, height);
1954 }
1955
1956 void
1957 window_damage(struct window *window, int32_t x, int32_t y,
1958               int32_t width, int32_t height)
1959 {
1960         wl_surface_damage(window->surface, x, y, width, height);
1961 }
1962
1963 static struct window *
1964 window_create_internal(struct display *display, struct window *parent,
1965                         int32_t width, int32_t height)
1966 {
1967         struct window *window;
1968
1969         window = malloc(sizeof *window);
1970         if (window == NULL)
1971                 return NULL;
1972
1973         memset(window, 0, sizeof *window);
1974         window->display = display;
1975         window->parent = parent;
1976         window->surface = wl_compositor_create_surface(display->compositor);
1977         if (display->shell) {
1978                 window->shell_surface =
1979                         wl_shell_get_shell_surface(display->shell,
1980                                                    window->surface);
1981         }
1982         window->allocation.x = 0;
1983         window->allocation.y = 0;
1984         window->allocation.width = width;
1985         window->allocation.height = height;
1986         window->saved_allocation = window->allocation;
1987         window->margin = 16;
1988         window->decoration = 1;
1989         window->transparent = 1;
1990         wl_list_init(&window->item_list);
1991
1992         if (display->dpy)
1993 #ifdef HAVE_CAIRO_EGL
1994                 /* FIXME: make TYPE_EGL_IMAGE choosable for testing */
1995                 window->buffer_type = WINDOW_BUFFER_TYPE_EGL_WINDOW;
1996 #else
1997                 window->buffer_type = WINDOW_BUFFER_TYPE_SHM;
1998 #endif
1999         else
2000                 window->buffer_type = WINDOW_BUFFER_TYPE_SHM;
2001
2002         wl_surface_set_user_data(window->surface, window);
2003         wl_list_insert(display->window_list.prev, &window->link);
2004
2005         if (window->shell_surface) {
2006                 wl_shell_surface_set_user_data(window->shell_surface, window);
2007                 wl_shell_surface_add_listener(window->shell_surface,
2008                                               &shell_surface_listener, window);
2009         }
2010
2011         return window;
2012 }
2013
2014 struct window *
2015 window_create(struct display *display, int32_t width, int32_t height)
2016 {
2017         struct window *window;
2018
2019         window = window_create_internal(display, NULL, width, height);
2020         if (!window)
2021                 return NULL;
2022
2023         return window;
2024 }
2025
2026 struct window *
2027 window_create_transient(struct display *display, struct window *parent,
2028                         int32_t x, int32_t y, int32_t width, int32_t height)
2029 {
2030         struct window *window;
2031
2032         window = window_create_internal(parent->display,
2033                                         parent, width, height);
2034         if (!window)
2035                 return NULL;
2036
2037         window->type = TYPE_TRANSIENT;
2038         window->x = x;
2039         window->y = y;
2040
2041         return window;
2042 }
2043
2044 void
2045 window_set_buffer_type(struct window *window, enum window_buffer_type type)
2046 {
2047         window->buffer_type = type;
2048 }
2049
2050
2051 static void
2052 display_handle_geometry(void *data,
2053                         struct wl_output *wl_output,
2054                         int x, int y,
2055                         int physical_width,
2056                         int physical_height,
2057                         int subpixel,
2058                         const char *make,
2059                         const char *model)
2060 {
2061         struct output *output = data;
2062
2063         output->allocation.x = x;
2064         output->allocation.y = y;
2065 }
2066
2067 static void
2068 display_handle_mode(void *data,
2069                     struct wl_output *wl_output,
2070                     uint32_t flags,
2071                     int width,
2072                     int height,
2073                     int refresh)
2074 {
2075         struct output *output = data;
2076         struct display *display = output->display;
2077
2078         if (flags & WL_OUTPUT_MODE_CURRENT) {
2079                 output->allocation.width = width;
2080                 output->allocation.height = height;
2081                 if (display->output_configure_handler)
2082                         (*display->output_configure_handler)(
2083                                                 output, display->user_data);
2084         }
2085 }
2086
2087 static const struct wl_output_listener output_listener = {
2088         display_handle_geometry,
2089         display_handle_mode
2090 };
2091
2092 static void
2093 display_add_output(struct display *d, uint32_t id)
2094 {
2095         struct output *output;
2096
2097         output = malloc(sizeof *output);
2098         if (output == NULL)
2099                 return;
2100
2101         memset(output, 0, sizeof *output);
2102         output->display = d;
2103         output->output =
2104                 wl_display_bind(d->display, id, &wl_output_interface);
2105         wl_list_insert(d->output_list.prev, &output->link);
2106
2107         wl_output_add_listener(output->output, &output_listener, output);
2108 }
2109
2110 void
2111 display_set_output_configure_handler(struct display *display,
2112                                      display_output_handler_t handler)
2113 {
2114         struct output *output;
2115
2116         display->output_configure_handler = handler;
2117         if (!handler)
2118                 return;
2119
2120         wl_list_for_each(output, &display->output_list, link)
2121                 (*display->output_configure_handler)(output,
2122                                                      display->user_data);
2123 }
2124
2125 void
2126 output_set_user_data(struct output *output, void *data)
2127 {
2128         output->user_data = data;
2129 }
2130
2131 void *
2132 output_get_user_data(struct output *output)
2133 {
2134         return output->user_data;
2135 }
2136
2137 void
2138 output_set_destroy_handler(struct output *output,
2139                            display_output_handler_t handler)
2140 {
2141         output->destroy_handler = handler;
2142         /* FIXME: implement this, once we have way to remove outputs */
2143 }
2144
2145 void
2146 output_get_allocation(struct output *output, struct rectangle *allocation)
2147 {
2148         *allocation = output->allocation;
2149 }
2150
2151 struct wl_output *
2152 output_get_wl_output(struct output *output)
2153 {
2154         return output->output;
2155 }
2156
2157 static void
2158 display_add_input(struct display *d, uint32_t id)
2159 {
2160         struct input *input;
2161
2162         input = malloc(sizeof *input);
2163         if (input == NULL)
2164                 return;
2165
2166         memset(input, 0, sizeof *input);
2167         input->display = d;
2168         input->input_device =
2169                 wl_display_bind(d->display, id, &wl_input_device_interface);
2170         input->pointer_focus = NULL;
2171         input->keyboard_focus = NULL;
2172         wl_list_insert(d->input_list.prev, &input->link);
2173
2174         wl_input_device_add_listener(input->input_device,
2175                                      &input_device_listener, input);
2176         wl_input_device_set_user_data(input->input_device, input);
2177
2178         input->data_device =
2179                 wl_data_device_manager_get_data_device(d->data_device_manager,
2180                                                        input->input_device);
2181         wl_data_device_add_listener(input->data_device,
2182                                     &data_device_listener, input);
2183 }
2184
2185 static void
2186 display_handle_global(struct wl_display *display, uint32_t id,
2187                       const char *interface, uint32_t version, void *data)
2188 {
2189         struct display *d = data;
2190
2191         if (strcmp(interface, "wl_compositor") == 0) {
2192                 d->compositor =
2193                         wl_display_bind(display, id, &wl_compositor_interface);
2194         } else if (strcmp(interface, "wl_output") == 0) {
2195                 display_add_output(d, id);
2196         } else if (strcmp(interface, "wl_input_device") == 0) {
2197                 display_add_input(d, id);
2198         } else if (strcmp(interface, "wl_shell") == 0) {
2199                 d->shell = wl_display_bind(display, id, &wl_shell_interface);
2200         } else if (strcmp(interface, "wl_shm") == 0) {
2201                 d->shm = wl_display_bind(display, id, &wl_shm_interface);
2202         } else if (strcmp(interface, "wl_data_device_manager") == 0) {
2203                 d->data_device_manager =
2204                         wl_display_bind(display, id,
2205                                         &wl_data_device_manager_interface);
2206         }
2207 }
2208
2209 static void
2210 display_render_frame(struct display *d)
2211 {
2212         int radius = 8;
2213         cairo_t *cr;
2214
2215         d->shadow = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
2216         cr = cairo_create(d->shadow);
2217         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
2218         cairo_set_source_rgba(cr, 0, 0, 0, 1);
2219         rounded_rect(cr, 16, 16, 112, 112, radius);
2220         cairo_fill(cr);
2221         cairo_destroy(cr);
2222         blur_surface(d->shadow, 64);
2223
2224         d->active_frame =
2225                 cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
2226         cr = cairo_create(d->active_frame);
2227         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
2228         cairo_set_source_rgba(cr, 0.8, 0.8, 0.4, 1);
2229         rounded_rect(cr, 16, 16, 112, 112, radius);
2230         cairo_fill(cr);
2231         cairo_destroy(cr);
2232
2233         d->inactive_frame =
2234                 cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
2235         cr = cairo_create(d->inactive_frame);
2236         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
2237         cairo_set_source_rgba(cr, 0.6, 0.6, 0.6, 1);
2238         rounded_rect(cr, 16, 16, 112, 112, radius);
2239         cairo_fill(cr);
2240         cairo_destroy(cr);
2241 }
2242
2243 static void
2244 init_xkb(struct display *d)
2245 {
2246         struct xkb_rule_names names;
2247
2248         names.rules = "evdev";
2249         names.model = "pc105";
2250         names.layout = option_xkb_layout;
2251         names.variant = option_xkb_variant;
2252         names.options = option_xkb_options;
2253
2254         d->xkb = xkb_compile_keymap_from_rules(&names);
2255         if (!d->xkb) {
2256                 fprintf(stderr, "Failed to compile keymap\n");
2257                 exit(1);
2258         }
2259 }
2260
2261 static int
2262 init_egl(struct display *d)
2263 {
2264         EGLint major, minor;
2265         EGLint n;
2266
2267         static const EGLint premul_argb_cfg_attribs[] = {
2268                 EGL_SURFACE_TYPE,
2269                         EGL_WINDOW_BIT | EGL_PIXMAP_BIT |
2270                         EGL_VG_ALPHA_FORMAT_PRE_BIT,
2271                 EGL_RED_SIZE, 1,
2272                 EGL_GREEN_SIZE, 1,
2273                 EGL_BLUE_SIZE, 1,
2274                 EGL_ALPHA_SIZE, 1,
2275                 EGL_DEPTH_SIZE, 1,
2276                 EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
2277                 EGL_NONE
2278         };
2279
2280         static const EGLint rgb_cfg_attribs[] = {
2281                 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PIXMAP_BIT,
2282                 EGL_RED_SIZE, 1,
2283                 EGL_GREEN_SIZE, 1,
2284                 EGL_BLUE_SIZE, 1,
2285                 EGL_ALPHA_SIZE, 0,
2286                 EGL_DEPTH_SIZE, 1,
2287                 EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
2288                 EGL_NONE
2289         };
2290
2291         d->dpy = eglGetDisplay(d->display);
2292         if (!eglInitialize(d->dpy, &major, &minor)) {
2293                 fprintf(stderr, "failed to initialize display\n");
2294                 return -1;
2295         }
2296
2297         if (!eglBindAPI(EGL_OPENGL_API)) {
2298                 fprintf(stderr, "failed to bind api EGL_OPENGL_API\n");
2299                 return -1;
2300         }
2301
2302         if (!eglChooseConfig(d->dpy, premul_argb_cfg_attribs,
2303                              &d->premultiplied_argb_config, 1, &n) || n != 1) {
2304                 fprintf(stderr, "failed to choose premul argb config\n");
2305                 return -1;
2306         }
2307
2308         if (!eglChooseConfig(d->dpy, rgb_cfg_attribs,
2309                              &d->rgb_config, 1, &n) || n != 1) {
2310                 fprintf(stderr, "failed to choose rgb config\n");
2311                 return -1;
2312         }
2313
2314         d->rgb_ctx = eglCreateContext(d->dpy, d->rgb_config, EGL_NO_CONTEXT, NULL);
2315         if (d->rgb_ctx == NULL) {
2316                 fprintf(stderr, "failed to create context\n");
2317                 return -1;
2318         }
2319         d->argb_ctx = eglCreateContext(d->dpy, d->premultiplied_argb_config,
2320                                        EGL_NO_CONTEXT, NULL);
2321         if (d->argb_ctx == NULL) {
2322                 fprintf(stderr, "failed to create context\n");
2323                 return -1;
2324         }
2325
2326         if (!eglMakeCurrent(d->dpy, NULL, NULL, d->rgb_ctx)) {
2327                 fprintf(stderr, "failed to make context current\n");
2328                 return -1;
2329         }
2330
2331 #ifdef HAVE_CAIRO_EGL
2332         d->rgb_device = cairo_egl_device_create(d->dpy, d->rgb_ctx);
2333         if (cairo_device_status(d->rgb_device) != CAIRO_STATUS_SUCCESS) {
2334                 fprintf(stderr, "failed to get cairo egl device\n");
2335                 return -1;
2336         }
2337         d->argb_device = cairo_egl_device_create(d->dpy, d->argb_ctx);
2338         if (cairo_device_status(d->argb_device) != CAIRO_STATUS_SUCCESS) {
2339                 fprintf(stderr, "failed to get cairo egl argb device\n");
2340                 return -1;
2341         }
2342 #endif
2343
2344         return 0;
2345 }
2346
2347 static int
2348 event_mask_update(uint32_t mask, void *data)
2349 {
2350         struct display *d = data;
2351
2352         d->mask = mask;
2353
2354         return 0;
2355 }
2356
2357 static void
2358 handle_display_data(struct task *task, uint32_t events)
2359 {
2360         struct display *display =
2361                 container_of(task, struct display, display_task);
2362         
2363         wl_display_iterate(display->display, display->mask);
2364 }
2365
2366 struct display *
2367 display_create(int *argc, char **argv[], const GOptionEntry *option_entries)
2368 {
2369         struct display *d;
2370         GOptionContext *context;
2371         GOptionGroup *xkb_option_group;
2372         GError *error;
2373
2374         g_type_init();
2375
2376         context = g_option_context_new(NULL);
2377         if (option_entries)
2378                 g_option_context_add_main_entries(context, option_entries, "Wayland View");
2379
2380         xkb_option_group = g_option_group_new("xkb",
2381                                               "Keyboard options",
2382                                               "Show all XKB options",
2383                                               NULL, NULL);
2384         g_option_group_add_entries(xkb_option_group, xkb_option_entries);
2385         g_option_context_add_group (context, xkb_option_group);
2386
2387         if (!g_option_context_parse(context, argc, argv, &error)) {
2388                 fprintf(stderr, "option parsing failed: %s\n", error->message);
2389                 exit(EXIT_FAILURE);
2390         }
2391
2392         g_option_context_free(context);
2393
2394         d = malloc(sizeof *d);
2395         if (d == NULL)
2396                 return NULL;
2397
2398         memset(d, 0, sizeof *d);
2399
2400         d->display = wl_display_connect(NULL);
2401         if (d->display == NULL) {
2402                 fprintf(stderr, "failed to create display: %m\n");
2403                 return NULL;
2404         }
2405
2406         d->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
2407         d->display_fd = wl_display_get_fd(d->display, event_mask_update, d);
2408         d->display_task.run = handle_display_data;
2409         display_watch_fd(d, d->display_fd, EPOLLIN, &d->display_task);
2410
2411         wl_list_init(&d->deferred_list);
2412         wl_list_init(&d->input_list);
2413         wl_list_init(&d->output_list);
2414
2415         /* Set up listener so we'll catch all events. */
2416         wl_display_add_global_listener(d->display,
2417                                        display_handle_global, d);
2418
2419         /* Process connection events. */
2420         wl_display_iterate(d->display, WL_DISPLAY_READABLE);
2421         if (init_egl(d) < 0)
2422                 return NULL;
2423
2424         d->image_target_texture_2d =
2425                 (void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
2426         d->create_image = (void *) eglGetProcAddress("eglCreateImageKHR");
2427         d->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR");
2428
2429         create_pointer_surfaces(d);
2430
2431         display_render_frame(d);
2432
2433         wl_list_init(&d->window_list);
2434
2435         init_xkb(d);
2436
2437         return d;
2438 }
2439
2440 void
2441 display_set_user_data(struct display *display, void *data)
2442 {
2443         display->user_data = data;
2444 }
2445
2446 void *
2447 display_get_user_data(struct display *display)
2448 {
2449         return display->user_data;
2450 }
2451
2452 struct wl_display *
2453 display_get_display(struct display *display)
2454 {
2455         return display->display;
2456 }
2457
2458 struct output *
2459 display_get_output(struct display *display)
2460 {
2461         return container_of(display->output_list.next, struct output, link);
2462 }
2463
2464 struct wl_compositor *
2465 display_get_compositor(struct display *display)
2466 {
2467         return display->compositor;
2468 }
2469
2470 EGLDisplay
2471 display_get_egl_display(struct display *d)
2472 {
2473         return d->dpy;
2474 }
2475
2476 struct wl_data_source *
2477 display_create_data_source(struct display *display)
2478 {
2479         return wl_data_device_manager_create_data_source(display->data_device_manager);
2480 }
2481
2482 EGLConfig
2483 display_get_rgb_egl_config(struct display *d)
2484 {
2485         return d->rgb_config;
2486 }
2487
2488 EGLConfig
2489 display_get_argb_egl_config(struct display *d)
2490 {
2491         return d->premultiplied_argb_config;
2492 }
2493
2494 struct wl_shell *
2495 display_get_shell(struct display *display)
2496 {
2497         return display->shell;
2498 }
2499
2500 int
2501 display_acquire_window_surface(struct display *display,
2502                                struct window *window,
2503                                EGLContext ctx)
2504 {
2505 #ifdef HAVE_CAIRO_EGL
2506         struct egl_window_surface_data *data;
2507         cairo_device_t *device;
2508
2509         if (!window->cairo_surface)
2510                 return -1;
2511         device = cairo_surface_get_device(window->cairo_surface);
2512         if (!device)
2513                 return -1;
2514
2515         if (!ctx) {
2516                 if (device == display->rgb_device)
2517                         ctx = display->rgb_ctx;
2518                 else if (device == display->argb_device)
2519                         ctx = display->argb_ctx;
2520                 else
2521                         assert(0);
2522         }
2523
2524         data = cairo_surface_get_user_data(window->cairo_surface,
2525                                            &surface_data_key);
2526
2527         cairo_device_flush(device);
2528         cairo_device_acquire(device);
2529         if (!eglMakeCurrent(display->dpy, data->surf, data->surf, ctx))
2530                 fprintf(stderr, "failed to make surface current\n");
2531
2532         return 0;
2533 #else
2534         return -1;
2535 #endif
2536 }
2537
2538 void
2539 display_release_window_surface(struct display *display,
2540                                struct window *window)
2541 {
2542 #ifdef HAVE_CAIRO_EGL
2543         cairo_device_t *device;
2544         
2545         device = cairo_surface_get_device(window->cairo_surface);
2546         if (!device)
2547                 return;
2548
2549         if (!eglMakeCurrent(display->dpy, NULL, NULL, display->rgb_ctx))
2550                 fprintf(stderr, "failed to make context current\n");
2551         cairo_device_release(device);
2552 #endif
2553 }
2554
2555 void
2556 display_defer(struct display *display, struct task *task)
2557 {
2558         wl_list_insert(&display->deferred_list, &task->link);
2559 }
2560
2561 void
2562 display_watch_fd(struct display *display,
2563                  int fd, uint32_t events, struct task *task)
2564 {
2565         struct epoll_event ep;
2566
2567         ep.events = events;
2568         ep.data.ptr = task;
2569         epoll_ctl(display->epoll_fd, EPOLL_CTL_ADD, fd, &ep);
2570 }
2571
2572 void
2573 display_run(struct display *display)
2574 {
2575         struct task *task;
2576         struct epoll_event ep[16];
2577         int i, count;
2578
2579         while (1) {
2580                 while (display->mask & WL_DISPLAY_WRITABLE)
2581                         wl_display_iterate(display->display,
2582                                            WL_DISPLAY_WRITABLE);
2583
2584                 count = epoll_wait(display->epoll_fd,
2585                                    ep, ARRAY_LENGTH(ep), -1);
2586                 for (i = 0; i < count; i++) {
2587                         task = ep[i].data.ptr;
2588                         task->run(task, ep[i].events);
2589                 }
2590
2591                 while (!wl_list_empty(&display->deferred_list)) {
2592                         task = container_of(display->deferred_list.next,
2593                                             struct task, link);
2594                         wl_list_remove(&task->link);
2595                         task->run(task, 0);
2596                 }
2597         }
2598 }