Use the global handler in dnd instead of custom drag_offer hook
[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 #include "../config.h"
24
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #include <math.h>
32 #include <time.h>
33 #include <cairo.h>
34 #include <glib.h>
35 #include <glib-object.h>
36 #include <gdk-pixbuf/gdk-pixbuf.h>
37 #include <xf86drm.h>
38 #include <sys/mman.h>
39
40 #define EGL_EGLEXT_PROTOTYPES 1
41 #define GL_GLEXT_PROTOTYPES 1
42 #include <GL/gl.h>
43 #include <EGL/egl.h>
44 #include <EGL/eglext.h>
45
46 #ifdef HAVE_CAIRO_EGL
47 #include <cairo-gl.h>
48 #endif
49
50 #include <X11/extensions/XKBcommon.h>
51
52 #include <linux/input.h>
53 #include "wayland-util.h"
54 #include "wayland-client.h"
55 #include "wayland-glib.h"
56 #include "cairo-util.h"
57
58 #include "window.h"
59
60 struct display {
61         struct wl_display *display;
62         struct wl_compositor *compositor;
63         struct wl_shell *shell;
64         struct wl_drm *drm;
65         struct wl_shm *shm;
66         struct wl_output *output;
67         struct rectangle screen_allocation;
68         int authenticated;
69         EGLDisplay dpy;
70         EGLContext ctx;
71         cairo_device_t *device;
72         int fd;
73         GMainLoop *loop;
74         GSource *source;
75         struct wl_list window_list;
76         struct wl_list input_list;
77         char *device_name;
78         cairo_surface_t *active_frame, *inactive_frame, *shadow;
79         struct xkb_desc *xkb;
80         cairo_surface_t **pointer_surfaces;
81
82         display_global_handler_t global_handler;
83 };
84
85 struct window {
86         struct display *display;
87         struct wl_surface *surface;
88         const char *title;
89         struct rectangle allocation, saved_allocation, server_allocation;
90         int resize_edges;
91         int redraw_scheduled;
92         int minimum_width, minimum_height;
93         int margin;
94         int fullscreen;
95         int decoration;
96         struct input *grab_device;
97         struct input *keyboard_device;
98         uint32_t name;
99         enum window_buffer_type buffer_type;
100         int mapped;
101
102         EGLImageKHR *image;
103         cairo_surface_t *cairo_surface, *pending_surface;
104
105         window_resize_handler_t resize_handler;
106         window_redraw_handler_t redraw_handler;
107         window_key_handler_t key_handler;
108         window_button_handler_t button_handler;
109         window_keyboard_focus_handler_t keyboard_focus_handler;
110         window_motion_handler_t motion_handler;
111
112         void *user_data;
113         struct wl_list link;
114 };
115
116 struct input {
117         struct display *display;
118         struct wl_input_device *input_device;
119         struct window *pointer_focus;
120         struct window *keyboard_focus;
121         uint32_t current_pointer_image;
122         uint32_t modifiers;
123         int32_t x, y, sx, sy;
124         struct wl_list link;
125 };
126
127 enum {
128         POINTER_DEFAULT = 100,
129         POINTER_UNSET
130 };
131
132 enum window_location {
133         WINDOW_INTERIOR = 0,
134         WINDOW_RESIZING_TOP = 1,
135         WINDOW_RESIZING_BOTTOM = 2,
136         WINDOW_RESIZING_LEFT = 4,
137         WINDOW_RESIZING_TOP_LEFT = 5,
138         WINDOW_RESIZING_BOTTOM_LEFT = 6,
139         WINDOW_RESIZING_RIGHT = 8,
140         WINDOW_RESIZING_TOP_RIGHT = 9,
141         WINDOW_RESIZING_BOTTOM_RIGHT = 10,
142         WINDOW_RESIZING_MASK = 15,
143         WINDOW_EXTERIOR = 16,
144         WINDOW_TITLEBAR = 17,
145         WINDOW_CLIENT_AREA = 18,
146 };
147
148 const char *option_xkb_layout = "us";
149 const char *option_xkb_variant = "";
150 const char *option_xkb_options = "";
151
152 static const GOptionEntry xkb_option_entries[] = {
153         { "xkb-layout", 0, 0, G_OPTION_ARG_STRING,
154           &option_xkb_layout, "XKB Layout" },
155         { "xkb-variant", 0, 0, G_OPTION_ARG_STRING,
156           &option_xkb_variant, "XKB Variant" },
157         { "xkb-options", 0, 0, G_OPTION_ARG_STRING,
158           &option_xkb_options, "XKB Options" },
159         { NULL }
160 };
161
162 static void
163 rounded_rect(cairo_t *cr, int x0, int y0, int x1, int y1, int radius)
164 {
165         cairo_move_to(cr, x0, y0 + radius);
166         cairo_arc(cr, x0 + radius, y0 + radius, radius, M_PI, 3 * M_PI / 2);
167         cairo_line_to(cr, x1 - radius, y0);
168         cairo_arc(cr, x1 - radius, y0 + radius, radius, 3 * M_PI / 2, 2 * M_PI);
169         cairo_line_to(cr, x1, y1 - radius);
170         cairo_arc(cr, x1 - radius, y1 - radius, radius, 0, M_PI / 2);
171         cairo_line_to(cr, x0 + radius, y1);
172         cairo_arc(cr, x0 + radius, y1 - radius, radius, M_PI / 2, M_PI);
173         cairo_close_path(cr);
174 }
175
176 static const cairo_user_data_key_t surface_data_key;
177 struct surface_data {
178         struct wl_buffer *buffer;
179 };
180
181 #define MULT(_d,c,a,t) \
182         do { t = c * a + 0x7f; _d = ((t >> 8) + t) >> 8; } while (0)
183
184 #ifdef HAVE_CAIRO_EGL
185
186 struct drm_surface_data {
187         struct surface_data data;
188         EGLImageKHR image;
189         GLuint texture;
190         struct display *display;
191 };
192
193 static void
194 drm_surface_data_destroy(void *p)
195 {
196         struct drm_surface_data *data = p;
197         struct display *d = data->display;
198
199         cairo_device_acquire(d->device);
200         glDeleteTextures(1, &data->texture);
201         cairo_device_release(d->device);
202
203         eglDestroyImageKHR(d->dpy, data->image);
204         wl_buffer_destroy(data->data.buffer);
205 }
206
207 EGLImageKHR
208 display_get_image_for_drm_surface(struct display *display,
209                                   cairo_surface_t *surface)
210 {
211         struct drm_surface_data *data;
212
213         data = cairo_surface_get_user_data (surface, &surface_data_key);
214
215         return data->image;
216 }
217
218 static cairo_surface_t *
219 display_create_drm_surface(struct display *display,
220                            struct rectangle *rectangle)
221 {
222         struct drm_surface_data *data;
223         EGLDisplay dpy = display->dpy;
224         cairo_surface_t *surface;
225         struct wl_visual *visual;
226         EGLint name, stride;
227
228         EGLint image_attribs[] = {
229                 EGL_WIDTH,              0,
230                 EGL_HEIGHT,             0,
231                 EGL_DRM_BUFFER_FORMAT_MESA,     EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
232                 EGL_DRM_BUFFER_USE_MESA,        EGL_DRM_BUFFER_USE_SCANOUT_MESA,
233                 EGL_NONE
234         };
235
236         data = malloc(sizeof *data);
237         if (data == NULL)
238                 return NULL;
239
240         data->display = display;
241
242         image_attribs[1] = rectangle->width;
243         image_attribs[3] = rectangle->height;
244         data->image = eglCreateDRMImageMESA(dpy, image_attribs);
245
246         cairo_device_acquire(display->device);
247         glGenTextures(1, &data->texture);
248         glBindTexture(GL_TEXTURE_2D, data->texture);
249         glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, data->image);
250         cairo_device_release(display->device);
251
252         eglExportDRMImageMESA(display->dpy, data->image, &name, NULL, &stride);
253
254         visual = wl_display_get_premultiplied_argb_visual(display->display);
255         data->data.buffer =
256                 wl_drm_create_buffer(display->drm, name, rectangle->width,
257                                      rectangle->height, stride, visual);
258
259         surface = cairo_gl_surface_create_for_texture(display->device,
260                                                       CAIRO_CONTENT_COLOR_ALPHA,
261                                                       data->texture,
262                                                       rectangle->width,
263                                                       rectangle->height);
264
265         cairo_surface_set_user_data (surface, &surface_data_key,
266                                      data, drm_surface_data_destroy);
267
268         return surface;
269 }
270
271 static cairo_surface_t *
272 display_create_drm_surface_from_file(struct display *display,
273                                      const char *filename,
274                                      struct rectangle *rect)
275 {
276         cairo_surface_t *surface;
277         GdkPixbuf *pixbuf;
278         GError *error = NULL;
279         int stride, i;
280         unsigned char *pixels, *p, *end;
281         struct drm_surface_data *data;
282
283         pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
284                                                    rect->width, rect->height,
285                                                    FALSE, &error);
286         if (error != NULL)
287                 return NULL;
288
289         if (!gdk_pixbuf_get_has_alpha(pixbuf) ||
290             gdk_pixbuf_get_n_channels(pixbuf) != 4) {
291                 gdk_pixbuf_unref(pixbuf);
292                 return NULL;
293         }
294
295
296         stride = gdk_pixbuf_get_rowstride(pixbuf);
297         pixels = gdk_pixbuf_get_pixels(pixbuf);
298
299         for (i = 0; i < rect->height; i++) {
300                 p = pixels + i * stride;
301                 end = p + rect->width * 4;
302                 while (p < end) {
303                         unsigned int t;
304
305                         MULT(p[0], p[0], p[3], t);
306                         MULT(p[1], p[1], p[3], t);
307                         MULT(p[2], p[2], p[3], t);
308                         p += 4;
309
310                 }
311         }
312
313         surface = display_create_drm_surface(display, rect);
314         data = cairo_surface_get_user_data(surface, &surface_data_key);
315
316         cairo_device_acquire(display->device);
317         glBindTexture(GL_TEXTURE_2D, data->texture);
318         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rect->width, rect->height,
319                         GL_RGBA, GL_UNSIGNED_BYTE, pixels);
320         cairo_device_release(display->device);
321
322         gdk_pixbuf_unref(pixbuf);
323
324         return surface;
325 }
326
327 #endif
328
329 struct wl_buffer *
330 display_get_buffer_for_surface(struct display *display,
331                                cairo_surface_t *surface)
332 {
333         struct surface_data *data;
334
335         data = cairo_surface_get_user_data (surface, &surface_data_key);
336
337         return data->buffer;
338 }
339
340 struct shm_surface_data {
341         struct surface_data data;
342         void *map;
343         size_t length;
344 };
345
346 static void
347 shm_surface_data_destroy(void *p)
348 {
349         struct shm_surface_data *data = p;
350
351         wl_buffer_destroy(data->data.buffer);
352         munmap(data->map, data->length);
353 }
354
355 static cairo_surface_t *
356 display_create_shm_surface(struct display *display,
357                            struct rectangle *rectangle)
358 {
359         struct shm_surface_data *data;
360         cairo_surface_t *surface;
361         struct wl_visual *visual;
362         int stride, fd;
363         char filename[] = "/tmp/wayland-shm-XXXXXX";
364
365         data = malloc(sizeof *data);
366         if (data == NULL)
367                 return NULL;
368
369         stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,
370                                                 rectangle->width);
371         data->length = stride * rectangle->height;
372         fd = mkstemp(filename);
373         if (fd < 0) {
374                 fprintf(stderr, "open %s failed: %m", filename);
375                 return NULL;
376         }
377         if (ftruncate(fd, data->length) < 0) {
378                 fprintf(stderr, "ftruncate failed: %m");
379                 close(fd);
380                 return NULL;
381         }
382
383         data->map = mmap(NULL, data->length,
384                          PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
385         unlink(filename);
386
387         if (data->map == MAP_FAILED) {
388                 fprintf(stderr, "mmap failed: %m");
389                 close(fd);
390                 return NULL;
391         }
392
393         surface = cairo_image_surface_create_for_data (data->map,
394                                                        CAIRO_FORMAT_ARGB32,
395                                                        rectangle->width,
396                                                        rectangle->height,
397                                                        stride);
398
399         cairo_surface_set_user_data (surface, &surface_data_key,
400                                      data, shm_surface_data_destroy);
401
402         visual = wl_display_get_premultiplied_argb_visual(display->display);
403         data->data.buffer = wl_shm_create_buffer(display->shm,
404                                                  fd,
405                                                  rectangle->width,
406                                                  rectangle->height,
407                                                  stride, visual);
408
409         close(fd);
410
411         return surface;
412 }
413
414 static cairo_surface_t *
415 display_create_shm_surface_from_file(struct display *display,
416                                      const char *filename,
417                                      struct rectangle *rect)
418 {
419         cairo_surface_t *surface;
420         GdkPixbuf *pixbuf;
421         GError *error = NULL;
422         int stride, i;
423         unsigned char *pixels, *p, *end, *dest_data;
424         int dest_stride;
425         uint32_t *d;
426
427         pixbuf = gdk_pixbuf_new_from_file_at_scale(filename,
428                                                    rect->width, rect->height,
429                                                    FALSE, &error);
430         if (error != NULL)
431                 return NULL;
432
433         if (!gdk_pixbuf_get_has_alpha(pixbuf) ||
434             gdk_pixbuf_get_n_channels(pixbuf) != 4) {
435                 gdk_pixbuf_unref(pixbuf);
436                 return NULL;
437         }
438
439         stride = gdk_pixbuf_get_rowstride(pixbuf);
440         pixels = gdk_pixbuf_get_pixels(pixbuf);
441
442         surface = display_create_shm_surface(display, rect);
443         dest_data = cairo_image_surface_get_data (surface);
444         dest_stride = cairo_image_surface_get_stride (surface);
445
446         for (i = 0; i < rect->height; i++) {
447                 d = (uint32_t *) (dest_data + i * dest_stride);
448                 p = pixels + i * stride;
449                 end = p + rect->width * 4;
450                 while (p < end) {
451                         unsigned int t;
452                         unsigned char a, r, g, b;
453
454                         a = p[3];
455                         MULT(r, p[0], a, t);
456                         MULT(g, p[1], a, t);
457                         MULT(b, p[2], a, t);
458                         p += 4;
459                         *d++ = (a << 24) | (r << 16) | (g << 8) | b;
460                 }
461         }
462
463         gdk_pixbuf_unref(pixbuf);
464
465         return surface;
466 }
467
468 cairo_surface_t *
469 display_create_surface(struct display *display,
470                        struct rectangle *rectangle)
471 {
472 #ifdef HAVE_CAIRO_EGL
473         if (display->drm) {
474                 return display_create_drm_surface(display, rectangle);
475         }
476 #endif
477         return display_create_shm_surface(display, rectangle);
478 }
479
480 static cairo_surface_t *
481 display_create_surface_from_file(struct display *display,
482                                  const char *filename,
483                                  struct rectangle *rectangle)
484 {
485 #ifdef HAVE_CAIRO_EGL
486         if (display->drm) {
487                 return display_create_drm_surface_from_file(display, filename, rectangle);
488         }
489 #endif
490         return display_create_shm_surface_from_file(display, filename, rectangle);
491 }
492  static const struct {
493         const char *filename;
494         int hotspot_x, hotspot_y;
495 } pointer_images[] = {
496         { DATADIR "/wayland/bottom_left_corner.png",     6, 30 },
497         { DATADIR "/wayland/bottom_right_corner.png",   28, 28 },
498         { DATADIR "/wayland/bottom_side.png",           16, 20 },
499         { DATADIR "/wayland/grabbing.png",              20, 17 },
500         { DATADIR "/wayland/left_ptr.png",              10,  5 },
501         { DATADIR "/wayland/left_side.png",             10, 20 },
502         { DATADIR "/wayland/right_side.png",            30, 19 },
503         { DATADIR "/wayland/top_left_corner.png",        8,  8 },
504         { DATADIR "/wayland/top_right_corner.png",      26,  8 },
505         { DATADIR "/wayland/top_side.png",              18,  8 },
506         { DATADIR "/wayland/xterm.png",                 15, 15 },
507         { DATADIR "/wayland/hand1.png",                 18, 11 }
508 };
509
510 static void
511 create_pointer_surfaces(struct display *display)
512 {
513         int i, count;
514         const int width = 32, height = 32;
515         struct rectangle rect;
516
517         count = ARRAY_LENGTH(pointer_images);
518         display->pointer_surfaces =
519                 malloc(count * sizeof *display->pointer_surfaces);
520         rect.width = width;
521         rect.height = height;
522         for (i = 0; i < count; i++) {
523                 display->pointer_surfaces[i] =
524                         display_create_surface_from_file(display,
525                                                          pointer_images[i].filename,
526                                                          &rect);
527         }
528
529 }
530
531 cairo_surface_t *
532 display_get_pointer_surface(struct display *display, int pointer,
533                             int *width, int *height,
534                             int *hotspot_x, int *hotspot_y)
535 {
536         cairo_surface_t *surface;
537
538         surface = display->pointer_surfaces[pointer];
539 #if HAVE_CAIRO_EGL
540         *width = cairo_gl_surface_get_width(surface);
541         *height = cairo_gl_surface_get_height(surface);
542 #else
543         *width = cairo_image_surface_get_width(surface);
544         *height = cairo_image_surface_get_height(surface);
545 #endif
546         *hotspot_x = pointer_images[pointer].hotspot_x;
547         *hotspot_y = pointer_images[pointer].hotspot_y;
548
549         return cairo_surface_reference(surface);
550 }
551
552
553 static void
554 window_attach_surface(struct window *window);
555
556 static void
557 free_surface(void *data)
558 {
559         struct window *window = data;
560
561         cairo_surface_destroy(window->pending_surface);
562         window->pending_surface = NULL;
563         if (window->cairo_surface)
564                 window_attach_surface(window);
565 }
566
567 static void
568 window_attach_surface(struct window *window)
569 {
570         struct display *display = window->display;
571         struct wl_buffer *buffer;
572         int32_t x, y;
573
574         if (window->pending_surface != NULL)
575                 return;
576
577         window->pending_surface = window->cairo_surface;
578         window->cairo_surface = NULL;
579
580         buffer = display_get_buffer_for_surface(display,
581                                                 window->pending_surface);
582         if (window->resize_edges & WINDOW_RESIZING_LEFT)
583                 x = window->server_allocation.width -
584                         window->allocation.width;
585         else
586                 x = 0;
587
588         if (window->resize_edges & WINDOW_RESIZING_TOP)
589                 y = window->server_allocation.height -
590                         window->allocation.height;
591         else
592                 y = 0;
593
594         window->server_allocation = window->allocation;
595         window->resize_edges = 0;
596         wl_surface_attach(window->surface, buffer, x, y);
597         wl_display_sync_callback(display->display, free_surface, window);
598
599         if (!window->mapped) {
600                 wl_surface_map_toplevel(window->surface);
601                 window->mapped = 1;
602         }
603
604         wl_surface_damage(window->surface, 0, 0,
605                           window->allocation.width,
606                           window->allocation.height);
607 }
608
609 void
610 window_flush(struct window *window)
611 {
612        if (window->cairo_surface)
613                window_attach_surface(window);
614 }
615
616 void
617 window_set_surface(struct window *window, cairo_surface_t *surface)
618 {
619         cairo_surface_reference(surface);
620
621         if (window->cairo_surface != NULL)
622                 cairo_surface_destroy(window->cairo_surface);
623
624         window->cairo_surface = surface;
625 }
626
627 void
628 window_create_surface(struct window *window)
629 {
630         cairo_surface_t *surface;
631
632         switch (window->buffer_type) {
633 #ifdef HAVE_CAIRO_EGL
634         case WINDOW_BUFFER_TYPE_DRM:
635                 surface = display_create_surface(window->display,
636                                                  &window->allocation);
637                 break;
638 #endif
639         case WINDOW_BUFFER_TYPE_SHM:
640                 surface = display_create_shm_surface(window->display,
641                                                      &window->allocation);
642                 break;
643         default:
644                 surface = NULL;
645                 break;
646         }
647
648         window_set_surface(window, surface);
649         cairo_surface_destroy(surface);
650 }
651
652 static void
653 window_draw_decorations(struct window *window)
654 {
655         cairo_t *cr;
656         cairo_text_extents_t extents;
657         cairo_pattern_t *outline, *bright, *dim;
658         cairo_surface_t *frame;
659         int width, height, shadow_dx = 3, shadow_dy = 3;
660
661         window_create_surface(window);
662
663         width = window->allocation.width;
664         height = window->allocation.height;
665
666         outline = cairo_pattern_create_rgb(0.1, 0.1, 0.1);
667         bright = cairo_pattern_create_rgb(0.8, 0.8, 0.8);
668         dim = cairo_pattern_create_rgb(0.4, 0.4, 0.4);
669
670         cr = cairo_create(window->cairo_surface);
671
672         cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
673         cairo_set_source_rgba(cr, 0, 0, 0, 0);
674         cairo_paint(cr);
675
676         cairo_set_source_rgba(cr, 0, 0, 0, 0.6);
677         tile_mask(cr, window->display->shadow,
678                   shadow_dx, shadow_dy, width, height,
679                   window->margin + 10 - shadow_dx,
680                   window->margin + 10 - shadow_dy);
681
682         if (window->keyboard_device)
683                 frame = window->display->active_frame;
684         else
685                 frame = window->display->inactive_frame;
686
687         tile_source(cr, frame, 0, 0, width, height,
688                     window->margin + 10, window->margin + 50);
689
690         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
691         cairo_set_font_size(cr, 14);
692         cairo_text_extents(cr, window->title, &extents);
693         cairo_move_to(cr, (width - extents.width) / 2, 32 - extents.y_bearing);
694         cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
695         cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
696         cairo_set_line_width (cr, 4);
697         if (window->keyboard_device)
698                 cairo_set_source_rgb(cr, 0, 0, 0);
699         else
700                 cairo_set_source_rgb(cr, 0.8, 0.8, 0.8);
701         cairo_show_text(cr, window->title);
702
703         cairo_destroy(cr);
704
705         cairo_device_flush (window->display->device);
706 }
707
708 void
709 display_flush_cairo_device(struct display *display)
710 {
711         cairo_device_flush (display->device);
712 }
713
714 void
715 window_draw(struct window *window)
716 {
717         if (window->fullscreen || !window->decoration)
718                 window_create_surface(window);
719         else
720                 window_draw_decorations(window);
721 }
722
723 cairo_surface_t *
724 window_get_surface(struct window *window)
725 {
726         return cairo_surface_reference(window->cairo_surface);
727 }
728
729 static int
730 get_pointer_location(struct window *window, int32_t x, int32_t y)
731 {
732         int vlocation, hlocation, location;
733         const int grip_size = 8;
734
735         if (!window->decoration)
736                 return WINDOW_CLIENT_AREA;
737
738         if (x < window->margin)
739                 hlocation = WINDOW_EXTERIOR;
740         else if (window->margin <= x && x < window->margin + grip_size)
741                 hlocation = WINDOW_RESIZING_LEFT;
742         else if (x < window->allocation.width - window->margin - grip_size)
743                 hlocation = WINDOW_INTERIOR;
744         else if (x < window->allocation.width - window->margin)
745                 hlocation = WINDOW_RESIZING_RIGHT;
746         else
747                 hlocation = WINDOW_EXTERIOR;
748
749         if (y < window->margin)
750                 vlocation = WINDOW_EXTERIOR;
751         else if (window->margin <= y && y < window->margin + grip_size)
752                 vlocation = WINDOW_RESIZING_TOP;
753         else if (y < window->allocation.height - window->margin - grip_size)
754                 vlocation = WINDOW_INTERIOR;
755         else if (y < window->allocation.height - window->margin)
756                 vlocation = WINDOW_RESIZING_BOTTOM;
757         else
758                 vlocation = WINDOW_EXTERIOR;
759
760         location = vlocation | hlocation;
761         if (location & WINDOW_EXTERIOR)
762                 location = WINDOW_EXTERIOR;
763         if (location == WINDOW_INTERIOR && y < window->margin + 50)
764                 location = WINDOW_TITLEBAR;
765         else if (location == WINDOW_INTERIOR)
766                 location = WINDOW_CLIENT_AREA;
767
768         return location;
769 }
770
771 static void
772 set_pointer_image(struct input *input, uint32_t time, int pointer)
773 {
774         struct display *display = input->display;
775         struct wl_buffer *buffer;
776         cairo_surface_t *surface;
777         int location;
778
779         location = get_pointer_location(input->pointer_focus,
780                                         input->sx, input->sy);
781         switch (location) {
782         case WINDOW_RESIZING_TOP:
783                 pointer = POINTER_TOP;
784                 break;
785         case WINDOW_RESIZING_BOTTOM:
786                 pointer = POINTER_BOTTOM;
787                 break;
788         case WINDOW_RESIZING_LEFT:
789                 pointer = POINTER_LEFT;
790                 break;
791         case WINDOW_RESIZING_RIGHT:
792                 pointer = POINTER_RIGHT;
793                 break;
794         case WINDOW_RESIZING_TOP_LEFT:
795                 pointer = POINTER_TOP_LEFT;
796                 break;
797         case WINDOW_RESIZING_TOP_RIGHT:
798                 pointer = POINTER_TOP_RIGHT;
799                 break;
800         case WINDOW_RESIZING_BOTTOM_LEFT:
801                 pointer = POINTER_BOTTOM_LEFT;
802                 break;
803         case WINDOW_RESIZING_BOTTOM_RIGHT:
804                 pointer = POINTER_BOTTOM_RIGHT;
805                 break;
806         case WINDOW_EXTERIOR:
807         case WINDOW_TITLEBAR:
808                 if (input->current_pointer_image == POINTER_DEFAULT)
809                         return;
810
811                 wl_input_device_attach(input->input_device, time, NULL, 0, 0);
812                 input->current_pointer_image = POINTER_DEFAULT;
813                 return;
814         default:
815                 break;
816         }
817
818         if (pointer == input->current_pointer_image)
819                 return;
820
821         input->current_pointer_image = pointer;
822         surface = display->pointer_surfaces[pointer];
823         buffer = display_get_buffer_for_surface(display, surface);
824         wl_input_device_attach(input->input_device, time, buffer,
825                                pointer_images[pointer].hotspot_x,
826                                pointer_images[pointer].hotspot_y);
827 }
828
829 static void
830 window_handle_motion(void *data, struct wl_input_device *input_device,
831                      uint32_t time,
832                      int32_t x, int32_t y, int32_t sx, int32_t sy)
833 {
834         struct input *input = data;
835         struct window *window = input->pointer_focus;
836         int location, pointer = POINTER_LEFT_PTR;
837
838         input->x = x;
839         input->y = y;
840         input->sx = sx;
841         input->sy = sy;
842
843         location = get_pointer_location(window, input->sx, input->sy);
844
845         if (window->motion_handler)
846                 pointer = (*window->motion_handler)(window, input, time,
847                                                     x, y, sx, sy,
848                                                     window->user_data);
849
850         set_pointer_image(input, time, pointer);
851 }
852
853 static void
854 window_handle_button(void *data,
855                      struct wl_input_device *input_device,
856                      uint32_t time, uint32_t button, uint32_t state)
857 {
858         struct input *input = data;
859         struct window *window = input->pointer_focus;
860         int location;
861
862         location = get_pointer_location(window, input->sx, input->sy);
863
864         if (button == BTN_LEFT && state == 1) {
865                 switch (location) {
866                 case WINDOW_TITLEBAR:
867                         wl_shell_move(window->display->shell,
868                                       window->surface, input_device, time);
869                         break;
870                 case WINDOW_RESIZING_TOP:
871                 case WINDOW_RESIZING_BOTTOM:
872                 case WINDOW_RESIZING_LEFT:
873                 case WINDOW_RESIZING_RIGHT:
874                 case WINDOW_RESIZING_TOP_LEFT:
875                 case WINDOW_RESIZING_TOP_RIGHT:
876                 case WINDOW_RESIZING_BOTTOM_LEFT:
877                 case WINDOW_RESIZING_BOTTOM_RIGHT:
878                         wl_shell_resize(window->display->shell,
879                                         window->surface, input_device, time,
880                                         location);
881                         break;
882                 case WINDOW_CLIENT_AREA:
883                         if (window->button_handler)
884                                 (*window->button_handler)(window,
885                                                           input, time,
886                                                           button, state,
887                                                           window->user_data);
888                         break;
889                 }
890         } else {
891                 if (window->button_handler)
892                         (*window->button_handler)(window,
893                                                   input, time,
894                                                   button, state,
895                                                   window->user_data);
896         }
897 }
898
899 static void
900 window_handle_key(void *data, struct wl_input_device *input_device,
901                   uint32_t time, uint32_t key, uint32_t state)
902 {
903         struct input *input = data;
904         struct window *window = input->keyboard_focus;
905         struct display *d = window->display;
906         uint32_t code, sym, level;
907
908         code = key + d->xkb->min_key_code;
909         if (window->keyboard_device != input)
910                 return;
911
912         level = 0;
913         if (input->modifiers & WINDOW_MODIFIER_SHIFT &&
914             XkbKeyGroupWidth(d->xkb, code, 0) > 1)
915                 level = 1;
916
917         sym = XkbKeySymEntry(d->xkb, code, level, 0);
918
919         if (state)
920                 input->modifiers |= d->xkb->map->modmap[code];
921         else
922                 input->modifiers &= ~d->xkb->map->modmap[code];
923
924         if (window->key_handler)
925                 (*window->key_handler)(window, key, sym, state,
926                                        input->modifiers, window->user_data);
927 }
928
929 static void
930 window_handle_pointer_focus(void *data,
931                             struct wl_input_device *input_device,
932                             uint32_t time, struct wl_surface *surface,
933                             int32_t x, int32_t y, int32_t sx, int32_t sy)
934 {
935         struct input *input = data;
936         struct window *window;
937         int pointer;
938
939         if (surface) {
940                 input->pointer_focus = wl_surface_get_user_data(surface);
941                 window = input->pointer_focus;
942
943                 pointer = POINTER_LEFT_PTR;
944                 if (window->motion_handler)
945                         pointer = (*window->motion_handler)(window,
946                                                             input, time,
947                                                             x, y, sx, sy,
948                                                             window->user_data);
949
950                 set_pointer_image(input, time, pointer);
951         } else {
952                 input->pointer_focus = NULL;
953                 input->current_pointer_image = POINTER_UNSET;
954         }
955 }
956
957 static void
958 window_handle_keyboard_focus(void *data,
959                              struct wl_input_device *input_device,
960                              uint32_t time,
961                              struct wl_surface *surface,
962                              struct wl_array *keys)
963 {
964         struct input *input = data;
965         struct window *window = input->keyboard_focus;
966         struct display *d = input->display;
967         uint32_t *k, *end;
968
969         window = input->keyboard_focus;
970         if (window) {
971                 window->keyboard_device = NULL;
972                 if (window->keyboard_focus_handler)
973                         (*window->keyboard_focus_handler)(window, NULL,
974                                                           window->user_data);
975         }
976
977         if (surface)
978                 input->keyboard_focus = wl_surface_get_user_data(surface);
979         else
980                 input->keyboard_focus = NULL;
981
982         end = keys->data + keys->size;
983         for (k = keys->data; k < end; k++)
984                 input->modifiers |= d->xkb->map->modmap[*k];
985
986         window = input->keyboard_focus;
987         if (window) {
988                 window->keyboard_device = input;
989                 if (window->keyboard_focus_handler)
990                         (*window->keyboard_focus_handler)(window,
991                                                           window->keyboard_device,
992                                                           window->user_data);
993         }
994 }
995
996 static const struct wl_input_device_listener input_device_listener = {
997         window_handle_motion,
998         window_handle_button,
999         window_handle_key,
1000         window_handle_pointer_focus,
1001         window_handle_keyboard_focus,
1002 };
1003
1004 void
1005 input_get_position(struct input *input, int32_t *x, int32_t *y)
1006 {
1007         *x = input->sx;
1008         *y = input->sy;
1009 }
1010
1011 struct wl_input_device *
1012 input_get_input_device(struct input *input)
1013 {
1014         return input->input_device;
1015 }
1016
1017 struct wl_drag *
1018 window_create_drag(struct window *window)
1019 {
1020         cairo_device_flush (window->display->device);
1021
1022         return wl_shell_create_drag(window->display->shell);
1023 }
1024
1025 void
1026 window_move(struct window *window, struct input *input, uint32_t time)
1027 {
1028         wl_shell_move(window->display->shell,
1029                       window->surface, input->input_device, time);
1030 }
1031
1032 void
1033 window_activate_drag(struct wl_drag *drag, struct window *window,
1034                      struct input *input, uint32_t time)
1035 {
1036         wl_drag_activate(drag, window->surface, input->input_device, time);
1037 }
1038
1039 static void
1040 handle_configure(void *data, struct wl_shell *shell,
1041                  uint32_t time, uint32_t edges,
1042                  struct wl_surface *surface, int32_t width, int32_t height)
1043 {
1044         struct window *window = wl_surface_get_user_data(surface);
1045         int32_t child_width, child_height;
1046
1047         if (window->resize_handler) {
1048                 child_width = width - 20 - window->margin * 2;
1049                 child_height = height - 60 - window->margin * 2;
1050
1051                 (*window->resize_handler)(window,
1052                                           child_width, child_height,
1053                                           window->user_data);
1054         } else {
1055                 window->resize_edges = edges;
1056                 window->allocation.width = width;
1057                 window->allocation.height = height;
1058
1059                 if (window->redraw_handler)
1060                         window_schedule_redraw(window);
1061         }
1062 }
1063
1064 static const struct wl_shell_listener shell_listener = {
1065         handle_configure,
1066 };
1067
1068 void
1069 window_get_child_allocation(struct window *window,
1070                             struct rectangle *allocation)
1071 {
1072         if (window->fullscreen && !window->decoration) {
1073                 *allocation = window->allocation;
1074         } else {
1075                 allocation->x = window->margin + 10;
1076                 allocation->y = window->margin + 50;
1077                 allocation->width =
1078                         window->allocation.width - 20 - window->margin * 2;
1079                 allocation->height =
1080                         window->allocation.height - 60 - window->margin * 2;
1081         }
1082 }
1083
1084 void
1085 window_set_child_size(struct window *window, int32_t width, int32_t height)
1086 {
1087         if (!window->fullscreen) {
1088                 window->allocation.width = width + 20 + window->margin * 2;
1089                 window->allocation.height = height + 60 + window->margin * 2;
1090         }
1091 }
1092
1093 void
1094 window_copy_image(struct window *window,
1095                   struct rectangle *rectangle, EGLImageKHR image)
1096 {
1097         /* set image as read buffer, copy pixels or something... */
1098 }
1099
1100 void
1101 window_copy_surface(struct window *window,
1102                     struct rectangle *rectangle,
1103                     cairo_surface_t *surface)
1104 {
1105         cairo_t *cr;
1106
1107         cr = cairo_create (window->cairo_surface);
1108
1109         cairo_set_source_surface (cr,
1110                                   surface,
1111                                   rectangle->x, rectangle->y);
1112
1113         cairo_paint (cr);
1114         cairo_destroy (cr);
1115 }
1116
1117 static gboolean
1118 idle_redraw(void *data)
1119 {
1120         struct window *window = data;
1121
1122         window->redraw_handler(window, window->user_data);
1123
1124         window->redraw_scheduled = 0;
1125
1126         return FALSE;
1127 }
1128
1129 void
1130 window_schedule_redraw(struct window *window)
1131 {
1132         if (!window->redraw_scheduled) {
1133                 g_idle_add(idle_redraw, window);
1134                 window->redraw_scheduled = 1;
1135         }
1136 }
1137
1138 void
1139 window_set_fullscreen(struct window *window, int fullscreen)
1140 {
1141         window->fullscreen = fullscreen;
1142         if (window->fullscreen) {
1143                 window->saved_allocation = window->allocation;
1144                 window->allocation = window->display->screen_allocation;
1145         } else {
1146                 window->allocation = window->saved_allocation;
1147         }
1148 }
1149
1150 void
1151 window_set_decoration(struct window *window, int decoration)
1152 {
1153         window->decoration = decoration;
1154 }
1155
1156 void
1157 window_set_user_data(struct window *window, void *data)
1158 {
1159         window->user_data = data;
1160 }
1161
1162 void *
1163 window_get_user_data(struct window *window)
1164 {
1165         return window->user_data;
1166 }
1167
1168 void
1169 window_set_resize_handler(struct window *window,
1170                           window_resize_handler_t handler)
1171 {
1172         window->resize_handler = handler;
1173 }
1174
1175 void
1176 window_set_redraw_handler(struct window *window,
1177                           window_redraw_handler_t handler)
1178 {
1179         window->redraw_handler = handler;
1180 }
1181
1182 void
1183 window_set_key_handler(struct window *window,
1184                        window_key_handler_t handler)
1185 {
1186         window->key_handler = handler;
1187 }
1188
1189 void
1190 window_set_button_handler(struct window *window,
1191                           window_button_handler_t handler)
1192 {
1193         window->button_handler = handler;
1194 }
1195
1196 void
1197 window_set_motion_handler(struct window *window,
1198                           window_motion_handler_t handler)
1199 {
1200         window->motion_handler = handler;
1201 }
1202
1203 void
1204 window_set_keyboard_focus_handler(struct window *window,
1205                                   window_keyboard_focus_handler_t handler)
1206 {
1207         window->keyboard_focus_handler = handler;
1208 }
1209
1210 void
1211 window_damage(struct window *window, int32_t x, int32_t y,
1212               int32_t width, int32_t height)
1213 {
1214         wl_surface_damage(window->surface, x, y, width, height);
1215 }
1216
1217 struct window *
1218 window_create(struct display *display, const char *title,
1219               int32_t width, int32_t height)
1220 {
1221         struct window *window;
1222
1223         window = malloc(sizeof *window);
1224         if (window == NULL)
1225                 return NULL;
1226
1227         memset(window, 0, sizeof *window);
1228         window->display = display;
1229         window->title = strdup(title);
1230         window->surface = wl_compositor_create_surface(display->compositor);
1231         window->allocation.x = 0;
1232         window->allocation.y = 0;
1233         window->allocation.width = width;
1234         window->allocation.height = height;
1235         window->saved_allocation = window->allocation;
1236         window->margin = 16;
1237         window->decoration = 1;
1238
1239         if (display->drm)
1240                 window->buffer_type = WINDOW_BUFFER_TYPE_DRM;
1241         else
1242                 window->buffer_type = WINDOW_BUFFER_TYPE_SHM;
1243
1244         wl_surface_set_user_data(window->surface, window);
1245         wl_list_insert(display->window_list.prev, &window->link);
1246
1247         return window;
1248 }
1249
1250 void
1251 window_set_buffer_type(struct window *window, enum window_buffer_type type)
1252 {
1253         window->buffer_type = type;
1254 }
1255
1256 static void
1257 drm_handle_device(void *data, struct wl_drm *drm, const char *device)
1258 {
1259         struct display *d = data;
1260
1261         d->device_name = strdup(device);
1262 }
1263
1264 static void drm_handle_authenticated(void *data, struct wl_drm *drm)
1265 {
1266         struct display *d = data;
1267
1268         d->authenticated = 1;
1269 }
1270
1271 static const struct wl_drm_listener drm_listener = {
1272         drm_handle_device,
1273         drm_handle_authenticated
1274 };
1275
1276 static void
1277 display_handle_geometry(void *data,
1278                         struct wl_output *output,
1279                         int32_t x, int32_t y, int32_t width, int32_t height)
1280 {
1281         struct display *display = data;
1282
1283         display->screen_allocation.x = x;
1284         display->screen_allocation.y = y;
1285         display->screen_allocation.width = width;
1286         display->screen_allocation.height = height;
1287 }
1288
1289 static const struct wl_output_listener output_listener = {
1290         display_handle_geometry,
1291 };
1292
1293 static void
1294 display_add_input(struct display *d, uint32_t id)
1295 {
1296         struct input *input;
1297
1298         input = malloc(sizeof *input);
1299         if (input == NULL)
1300                 return;
1301
1302         memset(input, 0, sizeof *input);
1303         input->display = d;
1304         input->input_device = wl_input_device_create(d->display, id);
1305         input->pointer_focus = NULL;
1306         input->keyboard_focus = NULL;
1307         wl_list_insert(d->input_list.prev, &input->link);
1308
1309         wl_input_device_add_listener(input->input_device,
1310                                      &input_device_listener, input);
1311         wl_input_device_set_user_data(input->input_device, input);
1312 }
1313
1314 static void
1315 display_handle_global(struct wl_display *display, uint32_t id,
1316                       const char *interface, uint32_t version, void *data)
1317 {
1318         struct display *d = data;
1319
1320         if (strcmp(interface, "compositor") == 0) {
1321                 d->compositor = wl_compositor_create(display, id);
1322         } else if (strcmp(interface, "output") == 0) {
1323                 d->output = wl_output_create(display, id);
1324                 wl_output_add_listener(d->output, &output_listener, d);
1325         } else if (strcmp(interface, "input_device") == 0) {
1326                 display_add_input(d, id);
1327         } else if (strcmp(interface, "shell") == 0) {
1328                 d->shell = wl_shell_create(display, id);
1329                 wl_shell_add_listener(d->shell, &shell_listener, d);
1330         } else if (strcmp(interface, "drm") == 0) {
1331                 d->drm = wl_drm_create(display, id);
1332                 wl_drm_add_listener(d->drm, &drm_listener, d);
1333         } else if (strcmp(interface, "shm") == 0) {
1334                 d->shm = wl_shm_create(display, id);
1335         } else if (d->global_handler) {
1336                 d->global_handler(d, interface, id, version);
1337         }
1338 }
1339
1340 static void
1341 display_render_frame(struct display *d)
1342 {
1343         int radius = 8;
1344         cairo_t *cr;
1345
1346         d->shadow = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
1347         cr = cairo_create(d->shadow);
1348         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
1349         cairo_set_source_rgba(cr, 0, 0, 0, 1);
1350         rounded_rect(cr, 16, 16, 112, 112, radius);
1351         cairo_fill(cr);
1352         cairo_destroy(cr);
1353         blur_surface(d->shadow, 64);
1354
1355         d->active_frame =
1356                 cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
1357         cr = cairo_create(d->active_frame);
1358         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
1359         cairo_set_source_rgba(cr, 0.8, 0.8, 0.4, 1);
1360         rounded_rect(cr, 16, 16, 112, 112, radius);
1361         cairo_fill(cr);
1362         cairo_destroy(cr);
1363
1364         d->inactive_frame =
1365                 cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 128, 128);
1366         cr = cairo_create(d->inactive_frame);
1367         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
1368         cairo_set_source_rgba(cr, 0.6, 0.6, 0.6, 1);
1369         rounded_rect(cr, 16, 16, 112, 112, radius);
1370         cairo_fill(cr);
1371         cairo_destroy(cr);
1372 }
1373
1374 static void
1375 init_xkb(struct display *d)
1376 {
1377         struct xkb_rule_names names;
1378
1379         names.rules = "evdev";
1380         names.model = "pc105";
1381         names.layout = option_xkb_layout;
1382         names.variant = option_xkb_variant;
1383         names.options = option_xkb_options;
1384
1385         d->xkb = xkb_compile_keymap_from_rules(&names);
1386         if (!d->xkb) {
1387                 fprintf(stderr, "Failed to compile keymap\n");
1388                 exit(1);
1389         }
1390 }
1391
1392 static int
1393 init_drm(struct display *d)
1394 {
1395         EGLint major, minor;
1396         int fd;
1397         drm_magic_t magic;
1398
1399         fd = open(d->device_name, O_RDWR);
1400         if (fd < 0) {
1401                 fprintf(stderr, "drm open failed: %m\n");
1402                 return -1;
1403         }
1404
1405         if (drmGetMagic(fd, &magic)) {
1406                 fprintf(stderr, "DRI2: failed to get drm magic");
1407                 return -1;
1408         }
1409
1410         /* Wait for authenticated event */
1411         wl_drm_authenticate(d->drm, magic);
1412         wl_display_iterate(d->display, WL_DISPLAY_WRITABLE);
1413         while (!d->authenticated)
1414                 wl_display_iterate(d->display, WL_DISPLAY_READABLE);
1415
1416         d->dpy = eglGetDRMDisplayMESA(fd);
1417         if (!eglInitialize(d->dpy, &major, &minor)) {
1418                 fprintf(stderr, "failed to initialize display\n");
1419                 return -1;
1420         }
1421
1422         if (!eglBindAPI(EGL_OPENGL_API)) {
1423                 fprintf(stderr, "failed to bind api EGL_OPENGL_API\n");
1424                 return -1;
1425         }
1426
1427         d->ctx = eglCreateContext(d->dpy, NULL, EGL_NO_CONTEXT, NULL);
1428         if (d->ctx == NULL) {
1429                 fprintf(stderr, "failed to create context\n");
1430                 return -1;
1431         }
1432
1433         if (!eglMakeCurrent(d->dpy, NULL, NULL, d->ctx)) {
1434                 fprintf(stderr, "faile to make context current\n");
1435                 return -1;
1436         }
1437
1438 #ifdef HAVE_CAIRO_EGL
1439         d->device = cairo_egl_device_create(d->dpy, d->ctx);
1440         if (d->device == NULL) {
1441                 fprintf(stderr, "failed to get cairo drm device\n");
1442                 return -1;
1443         }
1444 #endif
1445
1446         return 0;
1447 }
1448
1449 struct display *
1450 display_create(int *argc, char **argv[], const GOptionEntry *option_entries)
1451 {
1452         struct display *d;
1453         GOptionContext *context;
1454         GOptionGroup *xkb_option_group;
1455         GError *error;
1456
1457         g_type_init();
1458
1459         context = g_option_context_new(NULL);
1460         if (option_entries)
1461                 g_option_context_add_main_entries(context, option_entries, "Wayland View");
1462
1463         xkb_option_group = g_option_group_new("xkb",
1464                                               "Keyboard options",
1465                                               "Show all XKB options",
1466                                               NULL, NULL);
1467         g_option_group_add_entries(xkb_option_group, xkb_option_entries);
1468         g_option_context_add_group (context, xkb_option_group);
1469
1470         if (!g_option_context_parse(context, argc, argv, &error)) {
1471                 fprintf(stderr, "option parsing failed: %s\n", error->message);
1472                 exit(EXIT_FAILURE);
1473         }
1474
1475
1476         d = malloc(sizeof *d);
1477         if (d == NULL)
1478                 return NULL;
1479
1480         d->display = wl_display_connect(NULL);
1481         if (d->display == NULL) {
1482                 fprintf(stderr, "failed to create display: %m\n");
1483                 return NULL;
1484         }
1485
1486         wl_list_init(&d->input_list);
1487
1488         /* Set up listener so we'll catch all events. */
1489         wl_display_add_global_listener(d->display,
1490                                        display_handle_global, d);
1491
1492         /* Process connection events. */
1493         wl_display_iterate(d->display, WL_DISPLAY_READABLE);
1494
1495         if (d->device_name && init_drm(d) < 0)
1496                 return NULL;
1497
1498         create_pointer_surfaces(d);
1499
1500         display_render_frame(d);
1501
1502         d->loop = g_main_loop_new(NULL, FALSE);
1503         d->source = wl_glib_source_new(d->display);
1504         g_source_attach(d->source, NULL);
1505
1506         wl_list_init(&d->window_list);
1507
1508         init_xkb(d);
1509
1510         return d;
1511 }
1512
1513 struct wl_display *
1514 display_get_display(struct display *display)
1515 {
1516         return display->display;
1517 }
1518
1519 struct wl_compositor *
1520 display_get_compositor(struct display *display)
1521 {
1522         return display->compositor;
1523 }
1524
1525 EGLDisplay
1526 display_get_egl_display(struct display *d)
1527 {
1528         return d->dpy;
1529 }
1530
1531 void
1532 display_run(struct display *d)
1533 {
1534         g_main_loop_run(d->loop);
1535 }
1536
1537 void
1538 display_set_global_handler(struct display *display,
1539                            display_global_handler_t handler)
1540 {
1541         display->global_handler = handler;
1542 }