5d33a3c20eb675b8118d65303358ebaee008b5e8
[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_key(void *data, struct wl_input_device *input_device,
1525                  uint32_t time, uint32_t key, uint32_t state)
1526 {
1527         struct input *input = data;
1528         struct window *window = input->keyboard_focus;
1529         struct display *d = input->display;
1530         uint32_t code, sym, level;
1531
1532         code = key + 8;
1533         if (!window || window->keyboard_device != input)
1534                 return;
1535
1536         level = 0;
1537         if (input->modifiers & XKB_COMMON_SHIFT_MASK &&
1538             XkbKeyGroupWidth(d->xkb, code, 0) > 1)
1539                 level = 1;
1540
1541         sym = XkbKeySymEntry(d->xkb, code, level, 0);
1542
1543         if (state)
1544                 input->modifiers |= d->xkb->map->modmap[code];
1545         else
1546                 input->modifiers &= ~d->xkb->map->modmap[code];
1547
1548         if (key == KEY_F5 && input->modifiers == Mod4Mask) {
1549                 if (state)
1550                         window_set_maximized(window,
1551                                              window->type != TYPE_MAXIMIZED);
1552         } else if (window->key_handler) {
1553                 (*window->key_handler)(window, input, time, key,
1554                                        sym, state, window->user_data);
1555         }
1556 }
1557
1558 static void
1559 input_remove_pointer_focus(struct input *input, uint32_t time)
1560 {
1561         struct window *window = input->pointer_focus;
1562
1563         if (!window)
1564                 return;
1565
1566         input_set_focus_widget(input, NULL, 0, 0, 0);
1567
1568         input->pointer_focus = NULL;
1569         input->current_pointer_image = POINTER_UNSET;
1570 }
1571
1572 static void
1573 input_handle_pointer_enter(void *data,
1574                            struct wl_input_device *input_device,
1575                            uint32_t time, struct wl_surface *surface,
1576                            int32_t sx, int32_t sy)
1577 {
1578         struct input *input = data;
1579         struct window *window;
1580         struct widget *widget;
1581
1582         input->pointer_focus = wl_surface_get_user_data(surface);
1583         window = input->pointer_focus;
1584
1585         input->sx = sx;
1586         input->sy = sy;
1587
1588         widget = widget_find_widget(window->widget, sx, sy);
1589         input_set_focus_widget(input, widget, time, sx, sy);
1590 }
1591
1592 static void
1593 input_handle_pointer_leave(void *data,
1594                            struct wl_input_device *input_device,
1595                            uint32_t time, struct wl_surface *surface)
1596 {
1597         struct input *input = data;
1598
1599         input_remove_pointer_focus(input, time);
1600 }
1601
1602 static void
1603 input_remove_keyboard_focus(struct input *input)
1604 {
1605         struct window *window = input->keyboard_focus;
1606
1607         if (!window)
1608                 return;
1609
1610         window->keyboard_device = NULL;
1611         if (window->keyboard_focus_handler)
1612                 (*window->keyboard_focus_handler)(window, NULL,
1613                                                   window->user_data);
1614
1615         input->keyboard_focus = NULL;
1616 }
1617
1618 static void
1619 input_handle_keyboard_enter(void *data,
1620                             struct wl_input_device *input_device,
1621                             uint32_t time,
1622                             struct wl_surface *surface,
1623                             struct wl_array *keys)
1624 {
1625         struct input *input = data;
1626         struct window *window;
1627         struct display *d = input->display;
1628         uint32_t *k, *end;
1629
1630         input->keyboard_focus = wl_surface_get_user_data(surface);
1631
1632         end = keys->data + keys->size;
1633         input->modifiers = 0;
1634         for (k = keys->data; k < end; k++)
1635                 input->modifiers |= d->xkb->map->modmap[*k];
1636
1637         window = input->keyboard_focus;
1638         window->keyboard_device = input;
1639         if (window->keyboard_focus_handler)
1640                 (*window->keyboard_focus_handler)(window,
1641                                                   window->keyboard_device,
1642                                                   window->user_data);
1643 }
1644
1645 static void
1646 input_handle_keyboard_leave(void *data,
1647                             struct wl_input_device *input_device,
1648                             uint32_t time,
1649                             struct wl_surface *surface)
1650 {
1651         struct input *input = data;
1652
1653         input_remove_keyboard_focus(input);
1654 }
1655
1656 static void
1657 input_handle_touch_down(void *data,
1658                         struct wl_input_device *wl_input_device,
1659                         uint32_t time, struct wl_surface *surface,
1660                         int32_t id, int32_t x, int32_t y)
1661 {
1662 }
1663
1664 static void
1665 input_handle_touch_up(void *data,
1666                       struct wl_input_device *wl_input_device,
1667                       uint32_t time, int32_t id)
1668 {
1669 }
1670
1671 static void
1672 input_handle_touch_motion(void *data,
1673                           struct wl_input_device *wl_input_device,
1674                           uint32_t time, int32_t id, int32_t x, int32_t y)
1675 {
1676 }
1677
1678 static void
1679 input_handle_touch_frame(void *data,
1680                          struct wl_input_device *wl_input_device)
1681 {
1682 }
1683
1684 static void
1685 input_handle_touch_cancel(void *data,
1686                           struct wl_input_device *wl_input_device)
1687 {
1688 }
1689
1690 static const struct wl_input_device_listener input_device_listener = {
1691         input_handle_motion,
1692         input_handle_button,
1693         input_handle_key,
1694         input_handle_pointer_enter,
1695         input_handle_pointer_leave,
1696         input_handle_keyboard_enter,
1697         input_handle_keyboard_leave,
1698         input_handle_touch_down,
1699         input_handle_touch_up,
1700         input_handle_touch_motion,
1701         input_handle_touch_frame,
1702         input_handle_touch_cancel,
1703 };
1704
1705 void
1706 input_get_position(struct input *input, int32_t *x, int32_t *y)
1707 {
1708         *x = input->sx;
1709         *y = input->sy;
1710 }
1711
1712 struct wl_input_device *
1713 input_get_input_device(struct input *input)
1714 {
1715         return input->input_device;
1716 }
1717
1718 uint32_t
1719 input_get_modifiers(struct input *input)
1720 {
1721         return input->modifiers;
1722 }
1723
1724 struct widget *
1725 input_get_focus_widget(struct input *input)
1726 {
1727         return input->focus_widget;
1728 }
1729
1730 struct data_offer {
1731         struct wl_data_offer *offer;
1732         struct input *input;
1733         struct wl_array types;
1734         int refcount;
1735
1736         struct task io_task;
1737         int fd;
1738         data_func_t func;
1739         int32_t x, y;
1740         void *user_data;
1741 };
1742
1743 static void
1744 data_offer_offer(void *data, struct wl_data_offer *wl_data_offer, const char *type)
1745 {
1746         struct data_offer *offer = data;
1747         char **p;
1748
1749         p = wl_array_add(&offer->types, sizeof *p);
1750         *p = strdup(type);
1751 }
1752
1753 static const struct wl_data_offer_listener data_offer_listener = {
1754         data_offer_offer,
1755 };
1756
1757 static void
1758 data_offer_destroy(struct data_offer *offer)
1759 {
1760         char **p;
1761
1762         offer->refcount--;
1763         if (offer->refcount == 0) {
1764                 wl_data_offer_destroy(offer->offer);
1765                 for (p = offer->types.data; *p; p++)
1766                         free(*p);
1767                 wl_array_release(&offer->types);
1768                 free(offer);
1769         }
1770 }
1771
1772 static void
1773 data_device_data_offer(void *data,
1774                        struct wl_data_device *data_device, uint32_t id)
1775 {
1776         struct data_offer *offer;
1777
1778         offer = malloc(sizeof *offer);
1779
1780         wl_array_init(&offer->types);
1781         offer->refcount = 1;
1782         offer->input = data;
1783
1784         /* FIXME: Generate typesafe wrappers for this */
1785         offer->offer = (struct wl_data_offer *)
1786                 wl_proxy_create_for_id((struct wl_proxy *) data_device,
1787                                        id, &wl_data_offer_interface);
1788
1789         wl_data_offer_add_listener(offer->offer,
1790                                    &data_offer_listener, offer);
1791 }
1792
1793 static void
1794 data_device_enter(void *data, struct wl_data_device *data_device,
1795                   uint32_t time, struct wl_surface *surface,
1796                   int32_t x, int32_t y, struct wl_data_offer *offer)
1797 {
1798         struct input *input = data;
1799         struct window *window;
1800         char **p;
1801
1802         input->drag_offer = wl_data_offer_get_user_data(offer);
1803         window = wl_surface_get_user_data(surface);
1804         input->pointer_focus = window;
1805
1806         p = wl_array_add(&input->drag_offer->types, sizeof *p);
1807         *p = NULL;
1808
1809         window = input->pointer_focus;
1810         if (window->data_handler)
1811                 window->data_handler(window, input, time, x, y,
1812                                      input->drag_offer->types.data,
1813                                      window->user_data);
1814 }
1815
1816 static void
1817 data_device_leave(void *data, struct wl_data_device *data_device)
1818 {
1819         struct input *input = data;
1820
1821         data_offer_destroy(input->drag_offer);
1822         input->drag_offer = NULL;
1823 }
1824
1825 static void
1826 data_device_motion(void *data, struct wl_data_device *data_device,
1827                    uint32_t time, int32_t x, int32_t y)
1828 {
1829         struct input *input = data;
1830         struct window *window = input->pointer_focus;
1831
1832         input->sx = x;
1833         input->sy = y;
1834
1835         if (window->data_handler)
1836                 window->data_handler(window, input, time, x, y,
1837                                      input->drag_offer->types.data,
1838                                      window->user_data);
1839 }
1840
1841 static void
1842 data_device_drop(void *data, struct wl_data_device *data_device)
1843 {
1844         struct input *input = data;
1845         struct window *window = input->pointer_focus;
1846
1847         if (window->drop_handler)
1848                 window->drop_handler(window, input,
1849                                      input->sx, input->sy, window->user_data);
1850 }
1851
1852 static void
1853 data_device_selection(void *data,
1854                       struct wl_data_device *wl_data_device,
1855                       struct wl_data_offer *offer)
1856 {
1857         struct input *input = data;
1858         char **p;
1859
1860         if (input->selection_offer)
1861                 data_offer_destroy(input->selection_offer);
1862
1863         if (offer) {
1864                 input->selection_offer = wl_data_offer_get_user_data(offer);
1865                 p = wl_array_add(&input->selection_offer->types, sizeof *p);
1866                 *p = NULL;
1867         }
1868 }
1869
1870 static const struct wl_data_device_listener data_device_listener = {
1871         data_device_data_offer,
1872         data_device_enter,
1873         data_device_leave,
1874         data_device_motion,
1875         data_device_drop,
1876         data_device_selection
1877 };
1878
1879 void
1880 input_set_pointer_image(struct input *input, uint32_t time, int pointer)
1881 {
1882         struct display *display = input->display;
1883         struct wl_buffer *buffer;
1884         cairo_surface_t *surface;
1885
1886         if (pointer == input->current_pointer_image)
1887                 return;
1888
1889         input->current_pointer_image = pointer;
1890         surface = display->pointer_surfaces[pointer];
1891
1892         if (!surface)
1893                 return;
1894
1895         buffer = display_get_buffer_for_surface(display, surface);
1896         wl_input_device_attach(input->input_device, time, buffer,
1897                                pointer_images[pointer].hotspot_x,
1898                                pointer_images[pointer].hotspot_y);
1899 }
1900
1901 struct wl_data_device *
1902 input_get_data_device(struct input *input)
1903 {
1904         return input->data_device;
1905 }
1906
1907 void
1908 input_set_selection(struct input *input,
1909                     struct wl_data_source *source, uint32_t time)
1910 {
1911         wl_data_device_set_selection(input->data_device, source, time);
1912 }
1913
1914 void
1915 input_accept(struct input *input, uint32_t time, const char *type)
1916 {
1917         wl_data_offer_accept(input->drag_offer->offer, time, type);
1918 }
1919
1920 static void
1921 offer_io_func(struct task *task, uint32_t events)
1922 {
1923         struct data_offer *offer =
1924                 container_of(task, struct data_offer, io_task);
1925         unsigned int len;
1926         char buffer[4096];
1927
1928         len = read(offer->fd, buffer, sizeof buffer);
1929         offer->func(buffer, len,
1930                     offer->x, offer->y, offer->user_data);
1931
1932         if (len == 0) {
1933                 close(offer->fd);
1934                 data_offer_destroy(offer);
1935         }
1936 }
1937
1938 static void
1939 data_offer_receive_data(struct data_offer *offer, const char *mime_type,
1940                         data_func_t func, void *user_data)
1941 {
1942         int p[2];
1943
1944         pipe2(p, O_CLOEXEC);
1945         wl_data_offer_receive(offer->offer, mime_type, p[1]);
1946         close(p[1]);
1947
1948         offer->io_task.run = offer_io_func;
1949         offer->fd = p[0];
1950         offer->func = func;
1951         offer->refcount++;
1952         offer->user_data = user_data;
1953
1954         display_watch_fd(offer->input->display,
1955                          offer->fd, EPOLLIN, &offer->io_task);
1956 }
1957
1958 void
1959 input_receive_drag_data(struct input *input, const char *mime_type,
1960                         data_func_t func, void *data)
1961 {
1962         data_offer_receive_data(input->drag_offer, mime_type, func, data);
1963         input->drag_offer->x = input->sx;
1964         input->drag_offer->y = input->sy;
1965 }
1966
1967 int
1968 input_receive_selection_data(struct input *input, const char *mime_type,
1969                              data_func_t func, void *data)
1970 {
1971         char **p;
1972
1973         if (input->selection_offer == NULL)
1974                 return -1;
1975
1976         for (p = input->selection_offer->types.data; *p; p++)
1977                 if (strcmp(mime_type, *p) == 0)
1978                         break;
1979
1980         if (*p == NULL)
1981                 return -1;
1982
1983         data_offer_receive_data(input->selection_offer,
1984                                 mime_type, func, data);
1985         return 0;
1986 }
1987
1988 int
1989 input_receive_selection_data_to_fd(struct input *input,
1990                                    const char *mime_type, int fd)
1991 {
1992         wl_data_offer_receive(input->selection_offer->offer, mime_type, fd);
1993
1994         return 0;
1995 }
1996
1997 void
1998 window_move(struct window *window, struct input *input, uint32_t time)
1999 {
2000         if (!window->shell_surface)
2001                 return;
2002
2003         wl_shell_surface_move(window->shell_surface,
2004                               input->input_device, time);
2005 }
2006
2007 static void
2008 idle_resize(struct task *task, uint32_t events)
2009 {
2010         struct window *window =
2011                 container_of(task, struct window, resize_task);
2012         struct widget *widget;
2013
2014         window->resize_scheduled = 0;
2015         widget = window->widget;
2016         widget_set_allocation(widget,
2017                               window->pending_allocation.x,
2018                               window->pending_allocation.y,
2019                               window->pending_allocation.width,
2020                               window->pending_allocation.height);
2021
2022         if (window->input_region) {
2023                 wl_region_destroy(window->input_region);
2024                 window->input_region = NULL;
2025         }
2026
2027         if (window->opaque_region) {
2028                 wl_region_destroy(window->opaque_region);
2029                 window->opaque_region = NULL;
2030         }
2031
2032         if (widget->resize_handler)
2033                 widget->resize_handler(widget,
2034                                        widget->allocation.width,
2035                                        widget->allocation.height,
2036                                        widget->user_data);
2037
2038         if (window->allocation.width != widget->allocation.width ||
2039             window->allocation.height != widget->allocation.height) {
2040                 window->allocation = widget->allocation;
2041                 window_schedule_redraw(window);
2042         }
2043 }
2044
2045 void
2046 window_schedule_resize(struct window *window, int width, int height)
2047 {
2048         window->pending_allocation.x = 0;
2049         window->pending_allocation.y = 0;
2050         window->pending_allocation.width = width;
2051         window->pending_allocation.height = height;
2052
2053         if (!window->resize_scheduled) {
2054                 window->resize_task.run = idle_resize;
2055                 display_defer(window->display, &window->resize_task);
2056                 window->resize_scheduled = 1;
2057         }
2058 }
2059
2060 void
2061 widget_schedule_resize(struct widget *widget, int32_t width, int32_t height)
2062 {
2063         window_schedule_resize(widget->window, width, height);
2064 }
2065
2066 static void
2067 handle_configure(void *data, struct wl_shell_surface *shell_surface,
2068                  uint32_t time, uint32_t edges,
2069                  int32_t width, int32_t height)
2070 {
2071         struct window *window = data;
2072
2073         if (width <= 0 || height <= 0)
2074                 return;
2075
2076         window->resize_edges = edges;
2077         window_schedule_resize(window, width, height);
2078 }
2079
2080 static void
2081 menu_destroy(struct menu *menu)
2082 {
2083         widget_destroy(menu->widget);
2084         window_destroy(menu->window);
2085         free(menu);
2086 }
2087
2088 static void
2089 handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
2090 {
2091         struct window *window = data;
2092         struct menu *menu = window->widget->user_data;
2093
2094         /* FIXME: Need more context in this event, at least the input
2095          * device.  Or just use wl_callback.  And this really needs to
2096          * be a window vfunc that the menu can set.  And we need the
2097          * time. */
2098
2099         menu->func(window->parent, menu->current, window->parent->user_data);
2100         input_ungrab(menu->input, 0);
2101         menu_destroy(menu);
2102 }
2103
2104 static const struct wl_shell_surface_listener shell_surface_listener = {
2105         handle_configure,
2106         handle_popup_done
2107 };
2108
2109 void
2110 window_get_allocation(struct window *window,
2111                       struct rectangle *allocation)
2112 {
2113         *allocation = window->allocation;
2114 }
2115
2116 static void
2117 widget_redraw(struct widget *widget)
2118 {
2119         struct widget *child;
2120
2121         if (widget->redraw_handler)
2122                 widget->redraw_handler(widget, widget->user_data);
2123         wl_list_for_each(child, &widget->child_list, link)
2124                 widget_redraw(child);
2125 }
2126
2127 static void
2128 idle_redraw(struct task *task, uint32_t events)
2129 {
2130         struct window *window =
2131                 container_of(task, struct window, redraw_task);
2132
2133         window_create_surface(window);
2134         widget_redraw(window->widget);
2135         window_flush(window);
2136         window->redraw_scheduled = 0;
2137 }
2138
2139 void
2140 window_schedule_redraw(struct window *window)
2141 {
2142         if (!window->redraw_scheduled) {
2143                 window->redraw_task.run = idle_redraw;
2144                 display_defer(window->display, &window->redraw_task);
2145                 window->redraw_scheduled = 1;
2146         }
2147 }
2148
2149 void
2150 window_set_custom(struct window *window)
2151 {
2152         window->type = TYPE_CUSTOM;
2153 }
2154
2155 void
2156 window_set_fullscreen(struct window *window, int fullscreen)
2157 {
2158         if (!window->display->shell)
2159                 return;
2160
2161         if ((window->type == TYPE_FULLSCREEN) == fullscreen)
2162                 return;
2163
2164         if (fullscreen) {
2165                 window->type = TYPE_FULLSCREEN;
2166                 window->saved_allocation = window->allocation;
2167                 wl_shell_surface_set_fullscreen(window->shell_surface,
2168                                                 WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
2169                                                 0, NULL);
2170         } else {
2171                 window->type = TYPE_TOPLEVEL;
2172                 wl_shell_surface_set_toplevel(window->shell_surface);
2173                 window_schedule_resize(window,
2174                                        window->saved_allocation.width,
2175                                        window->saved_allocation.height);
2176         }
2177 }
2178
2179 void
2180 window_set_maximized(struct window *window, int maximized)
2181 {
2182         if (!window->display->shell)
2183                 return;
2184
2185         if ((window->type == TYPE_MAXIMIZED) == maximized)
2186                 return;
2187
2188         if (window->type == TYPE_TOPLEVEL) {
2189                 window->saved_allocation = window->allocation;
2190                 wl_shell_surface_set_maximized(window->shell_surface, NULL);
2191                 window->type = TYPE_MAXIMIZED;
2192         } else {
2193                 wl_shell_surface_set_toplevel(window->shell_surface);
2194                 window->type = TYPE_TOPLEVEL;
2195                 window_schedule_resize(window,
2196                                        window->saved_allocation.width,
2197                                        window->saved_allocation.height);
2198         }
2199 }
2200
2201 void
2202 window_set_user_data(struct window *window, void *data)
2203 {
2204         window->user_data = data;
2205 }
2206
2207 void *
2208 window_get_user_data(struct window *window)
2209 {
2210         return window->user_data;
2211 }
2212
2213 void
2214 window_set_key_handler(struct window *window,
2215                        window_key_handler_t handler)
2216 {
2217         window->key_handler = handler;
2218 }
2219
2220 void
2221 window_set_keyboard_focus_handler(struct window *window,
2222                                   window_keyboard_focus_handler_t handler)
2223 {
2224         window->keyboard_focus_handler = handler;
2225 }
2226
2227 void
2228 window_set_data_handler(struct window *window, window_data_handler_t handler)
2229 {
2230         window->data_handler = handler;
2231 }
2232
2233 void
2234 window_set_drop_handler(struct window *window, window_drop_handler_t handler)
2235 {
2236         window->drop_handler = handler;
2237 }
2238
2239 void
2240 window_set_close_handler(struct window *window,
2241                          window_close_handler_t handler)
2242 {
2243         window->close_handler = handler;
2244 }
2245
2246 void
2247 window_set_title(struct window *window, const char *title)
2248 {
2249         free(window->title);
2250         window->title = strdup(title);
2251 }
2252
2253 const char *
2254 window_get_title(struct window *window)
2255 {
2256         return window->title;
2257 }
2258
2259 void
2260 display_surface_damage(struct display *display, cairo_surface_t *cairo_surface,
2261                        int32_t x, int32_t y, int32_t width, int32_t height)
2262 {
2263         struct wl_buffer *buffer;
2264
2265         buffer = display_get_buffer_for_surface(display, cairo_surface);
2266
2267         wl_buffer_damage(buffer, x, y, width, height);
2268 }
2269
2270 void
2271 window_damage(struct window *window, int32_t x, int32_t y,
2272               int32_t width, int32_t height)
2273 {
2274         wl_surface_damage(window->surface, x, y, width, height);
2275 }
2276
2277 static struct window *
2278 window_create_internal(struct display *display, struct window *parent)
2279 {
2280         struct window *window;
2281
2282         window = malloc(sizeof *window);
2283         if (window == NULL)
2284                 return NULL;
2285
2286         memset(window, 0, sizeof *window);
2287         window->display = display;
2288         window->parent = parent;
2289         window->surface = wl_compositor_create_surface(display->compositor);
2290         if (display->shell) {
2291                 window->shell_surface =
2292                         wl_shell_get_shell_surface(display->shell,
2293                                                    window->surface);
2294         }
2295         window->allocation.x = 0;
2296         window->allocation.y = 0;
2297         window->allocation.width = 0;
2298         window->allocation.height = 0;
2299         window->saved_allocation = window->allocation;
2300         window->transparent = 1;
2301         window->type = TYPE_TOPLEVEL;
2302         window->input_region = NULL;
2303         window->opaque_region = NULL;
2304
2305         if (display->dpy)
2306 #ifdef HAVE_CAIRO_EGL
2307                 /* FIXME: make TYPE_EGL_IMAGE choosable for testing */
2308                 window->buffer_type = WINDOW_BUFFER_TYPE_EGL_WINDOW;
2309 #else
2310                 window->buffer_type = WINDOW_BUFFER_TYPE_SHM;
2311 #endif
2312         else
2313                 window->buffer_type = WINDOW_BUFFER_TYPE_SHM;
2314
2315         wl_surface_set_user_data(window->surface, window);
2316         wl_list_insert(display->window_list.prev, &window->link);
2317
2318         if (window->shell_surface) {
2319                 wl_shell_surface_set_user_data(window->shell_surface, window);
2320                 wl_shell_surface_add_listener(window->shell_surface,
2321                                               &shell_surface_listener, window);
2322         }
2323
2324         return window;
2325 }
2326
2327 struct window *
2328 window_create(struct display *display)
2329 {
2330         struct window *window;
2331
2332         window = window_create_internal(display, NULL);
2333         if (!window)
2334                 return NULL;
2335
2336         window->type = TYPE_TOPLEVEL;
2337         if (display->shell)
2338                 wl_shell_surface_set_toplevel(window->shell_surface);
2339
2340         return window;
2341 }
2342
2343 struct window *
2344 window_create_transient(struct display *display, struct window *parent,
2345                         int32_t x, int32_t y)
2346 {
2347         struct window *window;
2348
2349         window = window_create_internal(parent->display, parent);
2350         if (!window)
2351                 return NULL;
2352
2353         window->type = TYPE_TRANSIENT;
2354         window->x = x;
2355         window->y = y;
2356
2357         if (display->shell)
2358                 wl_shell_surface_set_transient(window->shell_surface,
2359                                                window->parent->shell_surface,
2360                                                window->x, window->y, 0);
2361
2362         return window;
2363 }
2364
2365 static void
2366 menu_set_item(struct menu *menu, int sy)
2367 {
2368         int next;
2369
2370         next = (sy - 8) / 20;
2371         if (menu->current != next) {
2372                 menu->current = next;
2373                 widget_schedule_redraw(menu->widget);
2374         }
2375 }
2376
2377 static int
2378 menu_motion_handler(struct widget *widget,
2379                     struct input *input, uint32_t time,
2380                     int32_t x, int32_t y, void *data)
2381 {
2382         struct menu *menu = data;
2383
2384         if (widget == menu->widget)
2385                 menu_set_item(data, y);
2386
2387         return POINTER_LEFT_PTR;
2388 }
2389
2390 static int
2391 menu_enter_handler(struct widget *widget,
2392                    struct input *input, uint32_t time,
2393                    int32_t x, int32_t y, void *data)
2394 {
2395         struct menu *menu = data;
2396
2397         if (widget == menu->widget)
2398                 menu_set_item(data, y);
2399
2400         return POINTER_LEFT_PTR;
2401 }
2402
2403 static void
2404 menu_leave_handler(struct widget *widget, struct input *input, void *data)
2405 {
2406         struct menu *menu = data;
2407
2408         if (widget == menu->widget)
2409                 menu_set_item(data, -200);
2410 }
2411
2412 static void
2413 menu_button_handler(struct widget *widget,
2414                     struct input *input, uint32_t time,
2415                     int button, int state, void *data)
2416
2417 {
2418         struct menu *menu = data;
2419
2420         if (state == 0 && time - menu->time > 500) {
2421                 /* Either relase after press-drag-release or
2422                  * click-motion-click. */
2423                 menu->func(menu->window->parent, 
2424                            menu->current, menu->window->parent->user_data);
2425                 input_ungrab(input, time);
2426                 menu_destroy(menu);
2427         }
2428 }
2429
2430 static void
2431 menu_redraw_handler(struct widget *widget, void *data)
2432 {
2433         cairo_t *cr;
2434         const int32_t r = 3, margin = 3;
2435         struct menu *menu = data;
2436         int32_t width, height, i;
2437         struct window *window = widget->window;
2438
2439         cr = cairo_create(window->cairo_surface);
2440         cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
2441         cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
2442         cairo_paint(cr);
2443
2444         width = window->allocation.width;
2445         height = window->allocation.height;
2446         rounded_rect(cr, 0, 0, width, height, r);
2447
2448         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
2449         cairo_set_source_rgba(cr, 0.0, 0.0, 0.4, 0.8);
2450         cairo_fill(cr);
2451
2452         for (i = 0; i < menu->count; i++) {
2453                 if (i == menu->current) {
2454                         cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
2455                         cairo_rectangle(cr, margin, i * 20 + margin,
2456                                         width - 2 * margin, 20);
2457                         cairo_fill(cr);
2458                         cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
2459                         cairo_move_to(cr, 10, i * 20 + 16);
2460                         cairo_show_text(cr, menu->entries[i]);
2461                 } else {
2462                         cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
2463                         cairo_move_to(cr, 10, i * 20 + 16);
2464                         cairo_show_text(cr, menu->entries[i]);
2465                 }
2466         }
2467
2468         cairo_destroy(cr);
2469 }
2470
2471 void
2472 window_show_menu(struct display *display,
2473                  struct input *input, uint32_t time, struct window *parent,
2474                  int32_t x, int32_t y,
2475                  menu_func_t func, const char **entries, int count)
2476 {
2477         struct window *window;
2478         struct menu *menu;
2479         const int32_t margin = 3;
2480
2481         menu = malloc(sizeof *menu);
2482         if (!menu)
2483                 return;
2484
2485         window = window_create_internal(parent->display, parent);
2486         if (!window)
2487                 return;
2488
2489         menu->window = window;
2490         menu->widget = window_add_widget(menu->window, menu);
2491         menu->entries = entries;
2492         menu->count = count;
2493         menu->current = -1;
2494         menu->time = time;
2495         menu->func = func;
2496         menu->input = input;
2497         window->type = TYPE_MENU;
2498         window->x = x;
2499         window->y = y;
2500
2501         wl_shell_surface_set_popup(window->shell_surface,
2502                                    input->input_device, time,
2503                                    window->parent->shell_surface,
2504                                    window->x, window->y, 0);
2505
2506         widget_set_redraw_handler(menu->widget, menu_redraw_handler);
2507         widget_set_enter_handler(menu->widget, menu_enter_handler);
2508         widget_set_leave_handler(menu->widget, menu_leave_handler);
2509         widget_set_motion_handler(menu->widget, menu_motion_handler);
2510         widget_set_button_handler(menu->widget, menu_button_handler);
2511
2512         input_grab(input, menu->widget, 0);
2513         window_schedule_resize(window, 200, count * 20 + margin * 2);
2514 }
2515
2516 void
2517 window_set_buffer_type(struct window *window, enum window_buffer_type type)
2518 {
2519         window->buffer_type = type;
2520 }
2521
2522
2523 static void
2524 display_handle_geometry(void *data,
2525                         struct wl_output *wl_output,
2526                         int x, int y,
2527                         int physical_width,
2528                         int physical_height,
2529                         int subpixel,
2530                         const char *make,
2531                         const char *model)
2532 {
2533         struct output *output = data;
2534
2535         output->allocation.x = x;
2536         output->allocation.y = y;
2537 }
2538
2539 static void
2540 display_handle_mode(void *data,
2541                     struct wl_output *wl_output,
2542                     uint32_t flags,
2543                     int width,
2544                     int height,
2545                     int refresh)
2546 {
2547         struct output *output = data;
2548         struct display *display = output->display;
2549
2550         if (flags & WL_OUTPUT_MODE_CURRENT) {
2551                 output->allocation.width = width;
2552                 output->allocation.height = height;
2553                 if (display->output_configure_handler)
2554                         (*display->output_configure_handler)(
2555                                                 output, display->user_data);
2556         }
2557 }
2558
2559 static const struct wl_output_listener output_listener = {
2560         display_handle_geometry,
2561         display_handle_mode
2562 };
2563
2564 static void
2565 display_add_output(struct display *d, uint32_t id)
2566 {
2567         struct output *output;
2568
2569         output = malloc(sizeof *output);
2570         if (output == NULL)
2571                 return;
2572
2573         memset(output, 0, sizeof *output);
2574         output->display = d;
2575         output->output =
2576                 wl_display_bind(d->display, id, &wl_output_interface);
2577         wl_list_insert(d->output_list.prev, &output->link);
2578
2579         wl_output_add_listener(output->output, &output_listener, output);
2580 }
2581
2582 static void
2583 output_destroy(struct output *output)
2584 {
2585         if (output->destroy_handler)
2586                 (*output->destroy_handler)(output, output->user_data);
2587
2588         wl_output_destroy(output->output);
2589         wl_list_remove(&output->link);
2590         free(output);
2591 }
2592
2593 void
2594 display_set_output_configure_handler(struct display *display,
2595                                      display_output_handler_t handler)
2596 {
2597         struct output *output;
2598
2599         display->output_configure_handler = handler;
2600         if (!handler)
2601                 return;
2602
2603         wl_list_for_each(output, &display->output_list, link)
2604                 (*display->output_configure_handler)(output,
2605                                                      display->user_data);
2606 }
2607
2608 void
2609 output_set_user_data(struct output *output, void *data)
2610 {
2611         output->user_data = data;
2612 }
2613
2614 void *
2615 output_get_user_data(struct output *output)
2616 {
2617         return output->user_data;
2618 }
2619
2620 void
2621 output_set_destroy_handler(struct output *output,
2622                            display_output_handler_t handler)
2623 {
2624         output->destroy_handler = handler;
2625         /* FIXME: implement this, once we have way to remove outputs */
2626 }
2627
2628 void
2629 output_get_allocation(struct output *output, struct rectangle *allocation)
2630 {
2631         *allocation = output->allocation;
2632 }
2633
2634 struct wl_output *
2635 output_get_wl_output(struct output *output)
2636 {
2637         return output->output;
2638 }
2639
2640 static void
2641 display_add_input(struct display *d, uint32_t id)
2642 {
2643         struct input *input;
2644
2645         input = malloc(sizeof *input);
2646         if (input == NULL)
2647                 return;
2648
2649         memset(input, 0, sizeof *input);
2650         input->display = d;
2651         input->input_device =
2652                 wl_display_bind(d->display, id, &wl_input_device_interface);
2653         input->pointer_focus = NULL;
2654         input->keyboard_focus = NULL;
2655         wl_list_insert(d->input_list.prev, &input->link);
2656
2657         wl_input_device_add_listener(input->input_device,
2658                                      &input_device_listener, input);
2659         wl_input_device_set_user_data(input->input_device, input);
2660
2661         input->data_device =
2662                 wl_data_device_manager_get_data_device(d->data_device_manager,
2663                                                        input->input_device);
2664         wl_data_device_add_listener(input->data_device,
2665                                     &data_device_listener, input);
2666 }
2667
2668 static void
2669 input_destroy(struct input *input)
2670 {
2671         input_remove_keyboard_focus(input);
2672         input_remove_pointer_focus(input, 0);
2673
2674         if (input->drag_offer)
2675                 data_offer_destroy(input->drag_offer);
2676
2677         if (input->selection_offer)
2678                 data_offer_destroy(input->selection_offer);
2679
2680         wl_data_device_destroy(input->data_device);
2681         wl_list_remove(&input->link);
2682         wl_input_device_destroy(input->input_device);
2683         free(input);
2684 }
2685
2686 static void
2687 display_handle_global(struct wl_display *display, uint32_t id,
2688                       const char *interface, uint32_t version, void *data)
2689 {
2690         struct display *d = data;
2691
2692         if (strcmp(interface, "wl_compositor") == 0) {
2693                 d->compositor =
2694                         wl_display_bind(display, id, &wl_compositor_interface);
2695         } else if (strcmp(interface, "wl_output") == 0) {
2696                 display_add_output(d, id);
2697         } else if (strcmp(interface, "wl_input_device") == 0) {
2698                 display_add_input(d, id);
2699         } else if (strcmp(interface, "wl_shell") == 0) {
2700                 d->shell = wl_display_bind(display, id, &wl_shell_interface);
2701         } else if (strcmp(interface, "wl_shm") == 0) {
2702                 d->shm = wl_display_bind(display, id, &wl_shm_interface);
2703         } else if (strcmp(interface, "wl_data_device_manager") == 0) {
2704                 d->data_device_manager =
2705                         wl_display_bind(display, id,
2706                                         &wl_data_device_manager_interface);
2707         }
2708 }
2709
2710 static void
2711 display_render_frame(struct display *d)
2712 {
2713         cairo_t *cr;
2714         cairo_pattern_t *pattern;
2715
2716         d->frame_radius = 3;
2717         d->shadow = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
2718         cr = cairo_create(d->shadow);
2719         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
2720         cairo_set_source_rgba(cr, 0, 0, 0, 1);
2721         rounded_rect(cr, 32, 32, 96, 96, d->frame_radius);
2722         cairo_fill(cr);
2723         cairo_destroy(cr);
2724         blur_surface(d->shadow, 64);
2725
2726         d->active_frame =
2727                 cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
2728         cr = cairo_create(d->active_frame);
2729         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
2730
2731         pattern = cairo_pattern_create_linear(16, 16, 16, 112);
2732         cairo_pattern_add_color_stop_rgb(pattern, 0.0, 1.0, 1.0, 1.0);
2733         cairo_pattern_add_color_stop_rgb(pattern, 0.2, 0.8, 0.8, 0.8);
2734         cairo_set_source(cr, pattern);
2735         cairo_pattern_destroy(pattern);
2736
2737         rounded_rect(cr, 0, 0, 128, 128, d->frame_radius);
2738         cairo_fill(cr);
2739         cairo_destroy(cr);
2740
2741         d->inactive_frame =
2742                 cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
2743         cr = cairo_create(d->inactive_frame);
2744         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
2745         cairo_set_source_rgba(cr, 0.75, 0.75, 0.75, 1);
2746         rounded_rect(cr, 0, 0, 128, 128, d->frame_radius);
2747         cairo_fill(cr);
2748         cairo_destroy(cr);
2749 }
2750
2751 static void
2752 init_xkb(struct display *d)
2753 {
2754         struct xkb_rule_names names;
2755
2756         names.rules = "evdev";
2757         names.model = "pc105";
2758         names.layout = option_xkb_layout;
2759         names.variant = option_xkb_variant;
2760         names.options = option_xkb_options;
2761
2762         d->xkb = xkb_compile_keymap_from_rules(&names);
2763         if (!d->xkb) {
2764                 fprintf(stderr, "Failed to compile keymap\n");
2765                 exit(1);
2766         }
2767 }
2768
2769 static void
2770 fini_xkb(struct display *display)
2771 {
2772         xkb_free_keymap(display->xkb);
2773 }
2774
2775 static int
2776 init_egl(struct display *d)
2777 {
2778         EGLint major, minor;
2779         EGLint n;
2780
2781 #ifdef USE_CAIRO_GLESV2
2782 #  define GL_BIT EGL_OPENGL_ES2_BIT
2783 #else
2784 #  define GL_BIT EGL_OPENGL_BIT
2785 #endif
2786
2787         static const EGLint argb_cfg_attribs[] = {
2788                 EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PIXMAP_BIT,
2789                 EGL_RED_SIZE, 1,
2790                 EGL_GREEN_SIZE, 1,
2791                 EGL_BLUE_SIZE, 1,
2792                 EGL_ALPHA_SIZE, 1,
2793                 EGL_DEPTH_SIZE, 1,
2794                 EGL_RENDERABLE_TYPE, GL_BIT,
2795                 EGL_NONE
2796         };
2797
2798 #ifdef USE_CAIRO_GLESV2
2799         static const EGLint context_attribs[] = {
2800                 EGL_CONTEXT_CLIENT_VERSION, 2,
2801                 EGL_NONE
2802         };
2803         EGLint api = EGL_OPENGL_ES_API;
2804 #else
2805         EGLint *context_attribs = NULL;
2806         EGLint api = EGL_OPENGL_API;
2807 #endif
2808
2809         d->dpy = eglGetDisplay(d->display);
2810         if (!eglInitialize(d->dpy, &major, &minor)) {
2811                 fprintf(stderr, "failed to initialize display\n");
2812                 return -1;
2813         }
2814
2815         if (!eglBindAPI(api)) {
2816                 fprintf(stderr, "failed to bind api EGL_OPENGL_API\n");
2817                 return -1;
2818         }
2819
2820         if (!eglChooseConfig(d->dpy, argb_cfg_attribs,
2821                              &d->argb_config, 1, &n) || n != 1) {
2822                 fprintf(stderr, "failed to choose argb config\n");
2823                 return -1;
2824         }
2825
2826         d->argb_ctx = eglCreateContext(d->dpy, d->argb_config,
2827                                        EGL_NO_CONTEXT, context_attribs);
2828         if (d->argb_ctx == NULL) {
2829                 fprintf(stderr, "failed to create context\n");
2830                 return -1;
2831         }
2832
2833         if (!eglMakeCurrent(d->dpy, NULL, NULL, d->argb_ctx)) {
2834                 fprintf(stderr, "failed to make context current\n");
2835                 return -1;
2836         }
2837
2838 #ifdef HAVE_CAIRO_EGL
2839         d->argb_device = cairo_egl_device_create(d->dpy, d->argb_ctx);
2840         if (cairo_device_status(d->argb_device) != CAIRO_STATUS_SUCCESS) {
2841                 fprintf(stderr, "failed to get cairo egl argb device\n");
2842                 return -1;
2843         }
2844 #endif
2845
2846         return 0;
2847 }
2848
2849 static void
2850 fini_egl(struct display *display)
2851 {
2852 #ifdef HAVE_CAIRO_EGL
2853         cairo_device_destroy(display->argb_device);
2854 #endif
2855
2856         eglMakeCurrent(display->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE,
2857                        EGL_NO_CONTEXT);
2858
2859         eglTerminate(display->dpy);
2860         eglReleaseThread();
2861 }
2862
2863 static int
2864 event_mask_update(uint32_t mask, void *data)
2865 {
2866         struct display *d = data;
2867
2868         d->mask = mask;
2869
2870         return 0;
2871 }
2872
2873 static void
2874 handle_display_data(struct task *task, uint32_t events)
2875 {
2876         struct display *display =
2877                 container_of(task, struct display, display_task);
2878         
2879         wl_display_iterate(display->display, display->mask);
2880 }
2881
2882 struct display *
2883 display_create(int argc, char *argv[])
2884 {
2885         struct display *d;
2886
2887         argc = parse_options(xkb_options,
2888                              ARRAY_LENGTH(xkb_options), argc, argv);
2889
2890         d = malloc(sizeof *d);
2891         if (d == NULL)
2892                 return NULL;
2893
2894         memset(d, 0, sizeof *d);
2895
2896         d->display = wl_display_connect(NULL);
2897         if (d->display == NULL) {
2898                 fprintf(stderr, "failed to create display: %m\n");
2899                 return NULL;
2900         }
2901
2902         d->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
2903         d->display_fd = wl_display_get_fd(d->display, event_mask_update, d);
2904         d->display_task.run = handle_display_data;
2905         display_watch_fd(d, d->display_fd, EPOLLIN, &d->display_task);
2906
2907         wl_list_init(&d->deferred_list);
2908         wl_list_init(&d->input_list);
2909         wl_list_init(&d->output_list);
2910
2911         /* Set up listener so we'll catch all events. */
2912         wl_display_add_global_listener(d->display,
2913                                        display_handle_global, d);
2914
2915         /* Process connection events. */
2916         wl_display_iterate(d->display, WL_DISPLAY_READABLE);
2917         if (init_egl(d) < 0)
2918                 return NULL;
2919
2920         d->image_target_texture_2d =
2921                 (void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
2922         d->create_image = (void *) eglGetProcAddress("eglCreateImageKHR");
2923         d->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR");
2924
2925         create_pointer_surfaces(d);
2926
2927         display_render_frame(d);
2928
2929         wl_list_init(&d->window_list);
2930
2931         init_xkb(d);
2932
2933         return d;
2934 }
2935
2936 static void
2937 display_destroy_outputs(struct display *display)
2938 {
2939         struct output *tmp;
2940         struct output *output;
2941
2942         wl_list_for_each_safe(output, tmp, &display->output_list, link)
2943                 output_destroy(output);
2944 }
2945
2946 static void
2947 display_destroy_inputs(struct display *display)
2948 {
2949         struct input *tmp;
2950         struct input *input;
2951
2952         wl_list_for_each_safe(input, tmp, &display->input_list, link)
2953                 input_destroy(input);
2954 }
2955
2956 void
2957 display_destroy(struct display *display)
2958 {
2959         if (!wl_list_empty(&display->window_list))
2960                 fprintf(stderr, "toytoolkit warning: windows exist.\n");
2961
2962         if (!wl_list_empty(&display->deferred_list))
2963                 fprintf(stderr, "toytoolkit warning: deferred tasks exist.\n");
2964
2965         display_destroy_outputs(display);
2966         display_destroy_inputs(display);
2967
2968         fini_xkb(display);
2969
2970         cairo_surface_destroy(display->active_frame);
2971         cairo_surface_destroy(display->inactive_frame);
2972         cairo_surface_destroy(display->shadow);
2973         destroy_pointer_surfaces(display);
2974
2975         fini_egl(display);
2976
2977         if (display->shell)
2978                 wl_shell_destroy(display->shell);
2979
2980         if (display->shm)
2981                 wl_shm_destroy(display->shm);
2982
2983         if (display->data_device_manager)
2984                 wl_data_device_manager_destroy(display->data_device_manager);
2985
2986         wl_compositor_destroy(display->compositor);
2987
2988         close(display->epoll_fd);
2989
2990         wl_display_flush(display->display);
2991         wl_display_disconnect(display->display);
2992         free(display);
2993 }
2994
2995 void
2996 display_set_user_data(struct display *display, void *data)
2997 {
2998         display->user_data = data;
2999 }
3000
3001 void *
3002 display_get_user_data(struct display *display)
3003 {
3004         return display->user_data;
3005 }
3006
3007 struct wl_display *
3008 display_get_display(struct display *display)
3009 {
3010         return display->display;
3011 }
3012
3013 struct output *
3014 display_get_output(struct display *display)
3015 {
3016         return container_of(display->output_list.next, struct output, link);
3017 }
3018
3019 struct wl_compositor *
3020 display_get_compositor(struct display *display)
3021 {
3022         return display->compositor;
3023 }
3024
3025 EGLDisplay
3026 display_get_egl_display(struct display *d)
3027 {
3028         return d->dpy;
3029 }
3030
3031 struct wl_data_source *
3032 display_create_data_source(struct display *display)
3033 {
3034         return wl_data_device_manager_create_data_source(display->data_device_manager);
3035 }
3036
3037 EGLConfig
3038 display_get_argb_egl_config(struct display *d)
3039 {
3040         return d->argb_config;
3041 }
3042
3043 struct wl_shell *
3044 display_get_shell(struct display *display)
3045 {
3046         return display->shell;
3047 }
3048
3049 int
3050 display_acquire_window_surface(struct display *display,
3051                                struct window *window,
3052                                EGLContext ctx)
3053 {
3054 #ifdef HAVE_CAIRO_EGL
3055         struct egl_window_surface_data *data;
3056         cairo_device_t *device;
3057
3058         if (!window->cairo_surface)
3059                 return -1;
3060         device = cairo_surface_get_device(window->cairo_surface);
3061         if (!device)
3062                 return -1;
3063
3064         if (!ctx) {
3065                 if (device == display->argb_device)
3066                         ctx = display->argb_ctx;
3067                 else
3068                         assert(0);
3069         }
3070
3071         data = cairo_surface_get_user_data(window->cairo_surface,
3072                                            &surface_data_key);
3073
3074         cairo_device_flush(device);
3075         cairo_device_acquire(device);
3076         if (!eglMakeCurrent(display->dpy, data->surf, data->surf, ctx))
3077                 fprintf(stderr, "failed to make surface current\n");
3078
3079         return 0;
3080 #else
3081         return -1;
3082 #endif
3083 }
3084
3085 void
3086 display_release_window_surface(struct display *display,
3087                                struct window *window)
3088 {
3089 #ifdef HAVE_CAIRO_EGL
3090         cairo_device_t *device;
3091         
3092         device = cairo_surface_get_device(window->cairo_surface);
3093         if (!device)
3094                 return;
3095
3096         if (!eglMakeCurrent(display->dpy, NULL, NULL, display->argb_ctx))
3097                 fprintf(stderr, "failed to make context current\n");
3098         cairo_device_release(device);
3099 #endif
3100 }
3101
3102 void
3103 display_defer(struct display *display, struct task *task)
3104 {
3105         wl_list_insert(&display->deferred_list, &task->link);
3106 }
3107
3108 void
3109 display_watch_fd(struct display *display,
3110                  int fd, uint32_t events, struct task *task)
3111 {
3112         struct epoll_event ep;
3113
3114         ep.events = events;
3115         ep.data.ptr = task;
3116         epoll_ctl(display->epoll_fd, EPOLL_CTL_ADD, fd, &ep);
3117 }
3118
3119 void
3120 display_run(struct display *display)
3121 {
3122         struct task *task;
3123         struct epoll_event ep[16];
3124         int i, count;
3125
3126         display->running = 1;
3127         while (1) {
3128                 wl_display_flush(display->display);
3129
3130                 while (!wl_list_empty(&display->deferred_list)) {
3131                         task = container_of(display->deferred_list.next,
3132                                             struct task, link);
3133                         wl_list_remove(&task->link);
3134                         task->run(task, 0);
3135                 }
3136
3137                 if (!display->running)
3138                         break;
3139
3140                 wl_display_flush(display->display);
3141
3142                 count = epoll_wait(display->epoll_fd,
3143                                    ep, ARRAY_LENGTH(ep), -1);
3144                 for (i = 0; i < count; i++) {
3145                         task = ep[i].data.ptr;
3146                         task->run(task, ep[i].events);
3147                 }
3148         }
3149 }
3150
3151 void
3152 display_exit(struct display *display)
3153 {
3154         display->running = 0;
3155 }