]> Pileus Git - wmpus/blob - sys-xwl.c
76ffd8cabad6b08f27e9eadac604590fd38c718d
[wmpus] / sys-xwl.c
1 /*
2  * Copyright (c) 2014-2015 Andy Spencer <andy753421@gmail.com>
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  */
15
16 #define _GNU_SOURCE
17 #include <string.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <errno.h>
21 #include <unistd.h>
22 #include <sys/mman.h>
23
24 #include <xkbcommon/xkbcommon.h>
25 #include <wayland-server.h>
26 #include <wayland-client.h>
27
28 #include <gtk/gtk.h>
29
30 #include "util.h"
31 #include "conf.h"
32 #include "sys.h"
33 #include "wm.h"
34
35 #include "xdg-shell-client-protocol.h"
36 #include "xdg-shell-server-protocol.h"
37 #include "gtk-shell-client-protocol.h"
38 #include "gtk-shell-server-protocol.h"
39
40 /* Wayland user data */
41 typedef struct {
42         uint8_t *mem;
43         size_t   size;
44 } sys_pool_t;
45
46 typedef struct {
47         sys_pool_t      *pool;
48         uint8_t         *mem;
49         cairo_surface_t *surface;
50 } sys_buf_t;
51
52 /* Internal structures */
53 struct win_sys {
54         struct wl_client   *cli;
55         struct wl_resource *sfc;
56         sys_buf_t          *buf;
57 };
58
59 /* Global data */
60 static GtkWidget            *screen;
61 static list_t               *windows;
62
63 static struct wl_resource   *output;
64 static struct wl_display    *display;
65 static struct wl_event_loop *events;
66
67 /*****************
68  * Gtk Callbacks *
69  *****************/
70
71 static void on_destroy(GtkWidget *widget, GdkEvent *event, gpointer user_data)
72 {
73         printf("on_destroy\n");
74         sys_exit();
75 }
76
77 static gboolean on_key(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
78 {
79         printf(g_ascii_isprint(event->keyval)
80                 ? "on_key: '%c'\n"
81                 : "on_key: 0x%X\n",
82                 event->keyval);
83         if (event->keyval == GDK_KEY_q)
84                 sys_exit();
85         if (event->keyval == GDK_KEY_t)
86                 g_spawn_command_line_async("st-wl", NULL);
87         return TRUE;
88 }
89
90 static gboolean on_button(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
91 {
92         printf("on_button\n");
93         return TRUE;
94 }
95
96 static gboolean on_move(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
97 {
98         return TRUE;
99 }
100
101 static gboolean on_draw(GtkWidget *widget, cairo_t *cairo, gpointer user_data)
102 {
103         printf("on_draw\n");
104
105         list_t *bottom = list_last(windows);
106         for (list_t *cur = bottom; cur; cur = cur->prev) {
107                 win_t     *win = cur->data;
108                 sys_buf_t *buf = win->sys->buf;
109                 if (buf == NULL)
110                         continue;
111                 printf("    win = %p", win);
112                 cairo_surface_mark_dirty(buf->surface);
113                 cairo_set_source_surface(cairo, buf->surface, 10, 10);
114                 cairo_paint(cairo);
115         }
116
117         return TRUE;
118 }
119
120 static gboolean on_wayland(gpointer user_data)
121 {
122         // TODO - convert to polled execution
123         wl_display_flush_clients(display);
124         wl_event_loop_dispatch(events, 0);
125         return TRUE;
126 }
127
128 /****************************
129  * Wayland Buffer Interface *
130  ****************************/
131 static void buffer_destroy(struct wl_client *cli, struct wl_resource *reso)
132 {
133         printf("buffer_destroy\n");
134 }
135
136 static struct wl_buffer_interface buffer_iface = {
137         .destroy  = buffer_destroy,
138 };
139
140 /***********************************
141  * Wayland Shared Memory Interface *
142  ***********************************/
143
144 /* Shm Pool */
145 static void pool_create_buffer(struct wl_client *cli, struct wl_resource *pool,
146                 uint32_t id, int32_t offset, int32_t width, int32_t height,
147                 int32_t stride, uint32_t format)
148 {
149         sys_buf_t  *buf  = new0(sys_buf_t);
150         buf->pool = wl_resource_get_user_data(pool);
151         buf->mem  = buf->pool->mem + offset;
152
153         printf("pool_create_buffer - %dx%d %p+%d : %d,%d,%d\n",
154                         width, height, buf->pool->mem, offset, id, stride, format);
155
156         if (offset > buf->pool->size || offset < 0)
157         {
158                 printf("\n\nerror\n\n");
159                 wl_resource_post_error(pool, WL_SHM_ERROR_INVALID_STRIDE,
160                                 "offset is too big or negative");
161                 return;
162         }
163
164         cairo_format_t cf =
165                 format == WL_SHM_FORMAT_ARGB8888 ? CAIRO_FORMAT_ARGB32 :
166                 format == WL_SHM_FORMAT_XRGB8888 ? CAIRO_FORMAT_RGB24  : CAIRO_FORMAT_INVALID;
167
168         buf->surface = cairo_image_surface_create_for_data(buf->mem, cf, width, height, stride);
169
170         struct wl_resource *res = wl_resource_create(cli, &wl_buffer_interface,
171                                         wl_resource_get_version(pool), id);
172         wl_resource_set_implementation(res, &buffer_iface, buf, NULL);
173 }
174
175 static void pool_destroy(struct wl_client *cli, struct wl_resource *pool)
176 {
177         printf("pool_destroy\n");
178 }
179
180 static void pool_resize(struct wl_client *cli, struct wl_resource *pool,
181                 int32_t size)
182 {
183         printf("[   WMPUS   ] pool_resize - %d\n", size);
184         sys_pool_t *data = wl_resource_get_user_data(pool);
185         void *ptr = mremap(data->mem, data->size, size, MREMAP_MAYMOVE);
186         if (ptr == MAP_FAILED)
187         {
188                 printf("\n\nerror\n\n");
189                 wl_resource_post_error(pool, WL_SHM_ERROR_INVALID_FD,
190                                 "mremap failed: %s", strerror(errno));
191                 return;
192         }
193         data->mem  = ptr;
194         data->size = size;
195 }
196
197 static struct wl_shm_pool_interface pool_iface = {
198         .create_buffer = &pool_create_buffer,
199         .destroy       = &pool_destroy,
200         .resize        = &pool_resize,
201 };
202
203 /* Shm */
204 static void shm_create_pool(struct wl_client *cli, struct wl_resource *shm,
205                 uint32_t id, int32_t fd, int32_t size)
206 {
207         printf("shm_create_pool - #%d %d %d\n", id, fd, size);
208
209         sys_pool_t *data = new0(sys_pool_t);
210
211         struct wl_resource *res = wl_resource_create(cli, &wl_shm_pool_interface,
212                                         wl_resource_get_version(shm), id);
213         wl_resource_set_implementation(res, &pool_iface, data, NULL);
214
215         data->mem  = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
216         data->size = size;
217 }
218
219 static struct wl_shm_interface shm_iface = {
220         .create_pool = shm_create_pool,
221 };
222
223 /**************************
224  * Wayland Seat Interface *
225  **************************/
226
227 /* Pointer */
228 static void pointer_set_cursor(struct wl_client *cli, struct wl_resource *ptr,
229                            uint32_t serial,
230                            struct wl_resource *surface,
231                            int32_t hotspot_x,
232                            int32_t hotspot_y)
233 {
234         printf("pointer_set_cursor\n");
235 }
236
237 static void pointer_release(struct wl_client *cli, struct wl_resource *ptr)
238 {
239         printf("pointer_release\n");
240 }
241
242 static struct wl_pointer_interface pointer_iface = {
243         .set_cursor = pointer_set_cursor,
244         .release    = pointer_release,
245 };
246
247 /* Keyboard */
248 static void keyboard_release(struct wl_client *cli, struct wl_resource *kbd)
249 {
250         printf("keyboard_release\n");
251 }
252
253 static struct wl_keyboard_interface keyboard_iface = {
254         .release = keyboard_release,
255 };
256
257 /* Touch */
258 static void touch_release(struct wl_client *cli, struct wl_resource *tch)
259 {
260         printf("touch_release\n");
261 }
262
263 static struct wl_touch_interface touch_iface = {
264         .release = touch_release,
265 };
266
267 /* Seat */
268 static void seat_get_pointer(struct wl_client *cli, struct wl_resource *seat,
269                 uint32_t id) {
270         printf("seat_get_pointer\n");
271         struct wl_resource *res = wl_resource_create(cli, &wl_pointer_interface, 3, id);
272         wl_resource_set_implementation(res, &pointer_iface, NULL, NULL);
273 }
274
275 static void seat_get_keyboard(struct wl_client *cli, struct wl_resource *seat,
276                 uint32_t id) {
277         printf("seat_get_keyboard\n");
278         struct wl_resource *res = wl_resource_create(cli, &wl_keyboard_interface, 4, id);
279         wl_resource_set_implementation(res, &keyboard_iface, NULL, NULL);
280 }
281
282 static void seat_get_touch(struct wl_client *cli, struct wl_resource *seat,
283                 uint32_t id) {
284         printf("seat_get_touch\n");
285         struct wl_resource *res = wl_resource_create(cli, &wl_touch_interface, 3, id);
286         wl_resource_set_implementation(res, &touch_iface, NULL, NULL);
287 }
288
289 static struct wl_seat_interface seat_iface = {
290         .get_pointer  = &seat_get_pointer,
291         .get_keyboard = &seat_get_keyboard,
292         .get_touch    = &seat_get_touch,
293 };
294
295 /*****************************************
296  * Wayland Data Device Manager Interface *
297  *****************************************/
298
299 /* Data Offer */
300 static void doff_accept(struct wl_client *cli, struct wl_resource *doff,
301                uint32_t serial, const char *mime_type)
302 {
303         printf("doff_accept\n");
304 }
305
306 static void doff_receive(struct wl_client *cli, struct wl_resource *doff,
307                 const char *mime_type, int32_t fd)
308 {
309         printf("doff_receive\n");
310 }
311
312 static void doff_destroy(struct wl_client *cli, struct wl_resource *doff)
313 {
314         printf("doff_destroy\n");
315 }
316
317 static struct wl_data_offer_interface doff_iface = {
318         .accept  = doff_accept,
319         .receive = doff_receive,
320         .destroy = doff_destroy,
321 };
322
323 /* Data Source */
324 static void dsrc_offer(struct wl_client *cli, struct wl_resource *dsrc,
325               const char *mime_type)
326 {
327         (void)doff_iface;
328         printf("dsrc_offer\n");
329 }
330
331 static void dsrc_destroy(struct wl_client *cli, struct wl_resource *dsrc)
332 {
333         printf("dsrc_destroy\n");
334 }
335
336 static struct wl_data_source_interface dsrc_iface = {
337         .offer   = dsrc_offer,
338         .destroy = dsrc_destroy,
339 };
340
341 /* Data Device */
342 static void ddev_start_drag(struct wl_client *cli, struct wl_resource *dsrc,
343                    struct wl_resource *source, struct wl_resource *origin,
344                    struct wl_resource *icon, uint32_t serial)
345 {
346         printf("start_drag\n");
347 }
348
349 static void ddev_set_selection(struct wl_client *cli, struct wl_resource *dsrc,
350                       struct wl_resource *source, uint32_t serial)
351 {
352         printf("set_selection\n");
353 }
354
355 static struct wl_data_device_interface ddev_iface = {
356         .start_drag    = ddev_start_drag,
357         .set_selection = ddev_set_selection,
358 };
359
360 /* Data Device Manager */
361 static void ddm_create_data_source(struct wl_client *cli, struct wl_resource *ddm,
362                 uint32_t id)
363 {
364         printf("ddm_create_data_source\n");
365         struct wl_resource *res = wl_resource_create(cli, &wl_data_device_interface, 1, id);
366         wl_resource_set_implementation(res, &dsrc_iface, NULL, NULL);
367 }
368
369 static void ddm_get_data_device(struct wl_client *cli, struct wl_resource *ddm,
370                 uint32_t id, struct wl_resource *seat)
371 {
372         printf("ddm_get_data_device\n");
373         struct wl_resource *res = wl_resource_create(cli, &wl_data_device_interface, 1, id);
374         wl_resource_set_implementation(res, &ddev_iface, NULL, NULL);
375 }
376
377 static struct wl_data_device_manager_interface ddm_iface = {
378         .create_data_source = &ddm_create_data_source,
379         .get_data_device    = &ddm_get_data_device,
380 };
381
382 /**************************************
383  * Wayland Shell/Compositor Interface *
384  **************************************/
385
386 /* Surface */
387 static void surface_kill(struct wl_resource *sfc)
388 {
389         printf("surface_kill\n");
390         list_t *link = wl_resource_get_user_data(sfc);
391         win_t  *win  = link->data;
392         free(win->sys);
393         free(win);
394         windows = list_remove(windows, link, 0);
395         gtk_widget_queue_draw(screen);
396 }
397
398 static void surface_destroy(struct wl_client *cli, struct wl_resource *sfc)
399 {
400         printf("surface_destroy\n");
401         surface_kill(sfc);
402 }
403
404 static void surface_attach(struct wl_client *cli, struct wl_resource *sfc,
405                 struct wl_resource *buf, int32_t x, int32_t y)
406 {
407         list_t    *link = wl_resource_get_user_data(sfc);
408         sys_buf_t *data = wl_resource_get_user_data(buf);
409         win_t     *win  = link->data;
410         printf("surface_attach - %p\n", data->pool->mem);
411         win->sys->buf = data;
412 }
413
414 static void surface_damage(struct wl_client *cli, struct wl_resource *sfc,
415                    int32_t x, int32_t y, int32_t width, int32_t height)
416 {
417         printf("surface_damage\n");
418 }
419
420 static void surface_frame(struct wl_client *cli, struct wl_resource *sfc,
421                 uint32_t id)
422 {
423         printf("surface_frame\n");
424         struct wl_resource *cb = wl_resource_create(cli, &wl_callback_interface, 1, id);
425         wl_resource_set_implementation(cb, NULL, NULL, NULL);
426         wl_callback_send_done(cb, time(NULL));
427 }
428
429 static void surface_set_opaque_region(struct wl_client *cli, struct wl_resource *sfc,
430                 struct wl_resource *reg)
431 {
432         printf("surface_set_opaque_region\n");
433 }
434
435 static void surface_set_input_region(struct wl_client *cli, struct wl_resource *sfc,
436                 struct wl_resource *reg)
437 {
438         printf("surface_set_input_region\n");
439 }
440
441 static void surface_commit(struct wl_client *cli, struct wl_resource *sfc)
442 {
443         printf("surface_commit\n");
444         gtk_widget_queue_draw(screen);
445 }
446
447 static void surface_set_buffer_transform(struct wl_client *cli, struct wl_resource *sfc,
448                 int32_t transform)
449 {
450         printf("surface_set_buffer_transform\n");
451 }
452
453 static void surface_set_buffer_scale(struct wl_client *cli, struct wl_resource *sfc,
454                 int32_t scale)
455 {
456         printf("surface_set_buffer_scale\n");
457 }
458
459 static struct wl_surface_interface surface_iface = {
460         .destroy              = surface_destroy,
461         .attach               = surface_attach,
462         .damage               = surface_damage,
463         .frame                = surface_frame,
464         .set_opaque_region    = surface_set_opaque_region,
465         .set_input_region     = surface_set_input_region,
466         .commit               = surface_commit,
467         .set_buffer_transform = surface_set_buffer_transform,
468         .set_buffer_scale     = surface_set_buffer_scale,
469 };
470
471 /* Region */
472 static void region_destroy(struct wl_client *cli, struct wl_resource *reg)
473 {
474         printf("region_destroy\n");
475 }
476
477 static void region_add(struct wl_client *cli, struct wl_resource *reg,
478                 int32_t x, int32_t y, int32_t width, int32_t height)
479 {
480         printf("region_add\n");
481 }
482
483 static void region_subtract(struct wl_client *cli, struct wl_resource *reg,
484                      int32_t x, int32_t y, int32_t width, int32_t height)
485 {
486         printf("region_subtract\n");
487 }
488
489 static struct wl_region_interface region_iface = {
490         .destroy  = region_destroy,
491         .add      = region_add,
492         .subtract = region_subtract,
493 };
494
495 /* Compositor */
496 static void comp_create_surface(struct wl_client *cli, struct wl_resource *comp,
497                 uint32_t id)
498 {
499         win_t *win = new0(win_t);
500         printf("comp_create_surface - win=%p\n", win);
501
502         windows = list_insert(windows, win);
503
504         struct wl_resource *res = wl_resource_create(cli, &wl_surface_interface, 3, id);
505         wl_resource_set_implementation(res, &surface_iface, windows, surface_kill);
506         wl_surface_send_enter(res, output);
507
508         win->sys = new0(win_sys_t);
509         win->sys->cli = cli;
510         win->sys->sfc = res;
511 }
512
513 static void comp_create_region(struct wl_client *cli, struct wl_resource *comp,
514                 uint32_t id)
515 {
516         printf("comp_create_region\n");
517         struct wl_resource *res = wl_resource_create(cli, &wl_region_interface, 1, id);
518         wl_resource_set_implementation(res, &region_iface, NULL, NULL);
519 }
520
521 static struct wl_compositor_interface comp_iface = {
522         .create_surface = comp_create_surface,
523         .create_region  = comp_create_region,
524 };
525
526 /* Shell Surface */
527 static void ssurface_pong(struct wl_client *cli, struct wl_resource *ssfc,
528                 uint32_t serial)
529 {
530         printf("ssurface_pong\n");
531 }
532
533 static void ssurface_move(struct wl_client *cli, struct wl_resource *ssfc,
534                 struct wl_resource *seat, uint32_t serial)
535 {
536         printf("ssurface_move\n");
537 }
538
539 static void ssurface_resize(struct wl_client *cli, struct wl_resource *ssfc,
540                 struct wl_resource *seat, uint32_t serial, uint32_t edges)
541 {
542         printf("ssurface_resize\n");
543 }
544
545 static void ssurface_set_toplevel(struct wl_client *cli, struct wl_resource *ssfc)
546 {
547         printf("ssurface_set_toplevel\n");
548 }
549
550 static void ssurface_set_transient(struct wl_client *cli, struct wl_resource *ssfc,
551                 struct wl_resource *parent, int32_t x, int32_t y, uint32_t flags)
552 {
553         printf("ssurface_set_transient\n");
554 }
555
556 static void ssurface_set_fullscreen(struct wl_client *cli, struct wl_resource *ssfc,
557                 uint32_t method, uint32_t framerate, struct wl_resource *out)
558 {
559         printf("ssurface_set_fullscreen\n");
560 }
561
562 static void ssurface_set_popup(struct wl_client *cli, struct wl_resource *ssfc,
563                 struct wl_resource *seat, uint32_t serial, struct wl_resource *parent,
564                 int32_t x, int32_t y, uint32_t flags)
565 {
566         printf("ssurface_set_popup\n");
567 }
568
569 static void ssurface_set_maximized(struct wl_client *cli, struct wl_resource *ssfc,
570                 struct wl_resource *out)
571 {
572         printf("ssurface_set_maximized\n");
573 }
574
575 static void ssurface_set_title(struct wl_client *cli, struct wl_resource *ssfc,
576                 const char *title)
577 {
578         printf("ssurface_set_title\n");
579 }
580
581 static void ssurface_set_class(struct wl_client *cli, struct wl_resource *ssfc,
582                 const char *class)
583 {
584         printf("ssurface_set_class\n");
585 }
586
587 static struct wl_shell_surface_interface ssurface_iface = {
588         .pong           = ssurface_pong,
589         .move           = ssurface_move,
590         .resize         = ssurface_resize,
591         .set_toplevel   = ssurface_set_toplevel,
592         .set_transient  = ssurface_set_transient,
593         .set_fullscreen = ssurface_set_fullscreen,
594         .set_popup      = ssurface_set_popup,
595         .set_maximized  = ssurface_set_maximized,
596         .set_title      = ssurface_set_title,
597         .set_class      = ssurface_set_class,
598 };
599
600 /* Shell */
601 static void shell_get_shell_surface(struct wl_client *cli, struct wl_resource *shell, uint32_t id,
602                               struct wl_resource *sfc) {
603         printf("shell_get_shell_surface\n");
604         struct wl_resource *res = wl_resource_create(cli, &wl_shell_surface_interface, 1, id);
605         wl_resource_set_implementation(res, &ssurface_iface, NULL, NULL);
606 }
607
608 static struct wl_shell_interface shell_iface = {
609         .get_shell_surface = shell_get_shell_surface,
610 };
611
612 /* XDG Popup */
613 static void xpopup_destroy(struct wl_client *cli, struct wl_resource *xpopup)
614 {
615         printf("xpopup_destroy\n");
616 }
617
618 static struct xdg_popup_interface xpopup_iface = {
619         .destroy = xpopup_destroy,
620 };
621
622 /* XDG Surface */
623 static void xsurface_destroy(struct wl_client *cli, struct wl_resource *xsfc)
624 {
625         printf("xsurface_destroy\n");
626 }
627
628 static void xsurface_set_parent(struct wl_client *cli, struct wl_resource *xsfc,
629                 struct wl_resource *parent)
630 {
631         printf("xsurface_set_parent\n");
632 }
633
634 static void xsurface_set_title(struct wl_client *cli, struct wl_resource *xsfc,
635                 const char *title)
636 {
637         printf("xsurface_set_title\n");
638 }
639
640 static void xsurface_set_app_id(struct wl_client *cli, struct wl_resource *xsfc,
641                 const char *app_id)
642 {
643         printf("xsurface_set_app_id\n");
644 }
645
646 static void xsurface_show_window_menu(struct wl_client *cli, struct wl_resource *xsfc,
647                 struct wl_resource *seat, uint32_t serial, int32_t x, int32_t y)
648 {
649         printf("xsurface_show_window_menu\n");
650 }
651
652 static void xsurface_move(struct wl_client *cli, struct wl_resource *xsfc,
653                 struct wl_resource *seat, uint32_t serial)
654 {
655         printf("xsurface_move\n");
656 }
657
658 static void xsurface_resize(struct wl_client *cli, struct wl_resource *xsfc,
659                 struct wl_resource *seat, uint32_t serial, uint32_t edges)
660 {
661         printf("xsurface_resize\n");
662 }
663
664 static void xsurface_ack_configure(struct wl_client *cli, struct wl_resource *xsfc,
665                 uint32_t serial)
666 {
667         printf("xsurface_ack_configure\n");
668 }
669
670 static void xsurface_set_window_geometry(struct wl_client *cli, struct wl_resource *xsfc,
671                 int32_t x, int32_t y, int32_t width, int32_t height)
672 {
673         printf("xsurface_set_window_geometry\n");
674 }
675
676 static void xsurface_set_maximized(struct wl_client *cli, struct wl_resource *xsfc)
677 {
678         printf("xsurface_set_maximized\n");
679 }
680
681 static void xsurface_unset_maximized(struct wl_client *cli, struct wl_resource *xsfc)
682 {
683         printf("xsurface_unset_maximized\n");
684 }
685
686 static void xsurface_set_fullscreen(struct wl_client *cli, struct wl_resource *xsfc,
687                 struct wl_resource *output)
688 {
689         printf("xsurface_set_fullscreen\n");
690 }
691
692 static void xsurface_unset_fullscreen(struct wl_client *cli, struct wl_resource *xsfc)
693 {
694         printf("xsurface_unset_fullscreen\n");
695 }
696
697 static void xsurface_set_minimized(struct wl_client *cli, struct wl_resource *xsfc)
698 {
699         printf("xsurface_set_minimized\n");
700 }
701
702 static struct xdg_surface_interface xsurface_iface = {
703         .destroy             = xsurface_destroy,
704         .set_parent          = xsurface_set_parent,
705         .set_title           = xsurface_set_title,
706         .set_app_id          = xsurface_set_app_id,
707         .show_window_menu    = xsurface_show_window_menu,
708         .move                = xsurface_move,
709         .resize              = xsurface_resize,
710         .ack_configure       = xsurface_ack_configure,
711         .set_window_geometry = xsurface_set_window_geometry,
712         .set_maximized       = xsurface_set_maximized,
713         .unset_maximized     = xsurface_unset_maximized,
714         .set_fullscreen      = xsurface_set_fullscreen,
715         .unset_fullscreen    = xsurface_unset_fullscreen,
716         .set_minimized       = xsurface_set_minimized,
717 };
718
719 /* XDG Shell */
720 static void xshell_use_unstable_version(struct wl_client *cli, struct wl_resource *gshell,
721                 int32_t version)
722 {
723         printf("xshell_use_unstable_version\n");
724 }
725
726 static void xshell_get_xdg_surface(struct wl_client *cli, struct wl_resource *gshell,
727                 uint32_t id, struct wl_resource *surface)
728 {
729         printf("xshell_get_xdg_surface\n");
730         struct wl_resource *res = wl_resource_create(cli, &xdg_surface_interface, 1, id);
731         wl_resource_set_implementation(res, &xsurface_iface, NULL, NULL);
732 }
733
734 static void xshell_get_xdg_popup(struct wl_client *cli, struct wl_resource *gshell,
735                 uint32_t id, struct wl_resource *surface, struct wl_resource *parent,
736                 struct wl_resource *seat, uint32_t serial, int32_t x, int32_t y, uint32_t flags)
737 {
738         printf("xshell_get_xdg_popup\n");
739         struct wl_resource *res = wl_resource_create(cli, &xdg_popup_interface, 1, id);
740         wl_resource_set_implementation(res, &xpopup_iface, NULL, NULL);
741 }
742
743 static void xshell_pong(struct wl_client *cli, struct wl_resource *gshell,
744                 uint32_t serial)
745 {
746         printf("xshell_pong\n");
747 }
748
749 static struct xdg_shell_interface xshell_iface = {
750         .use_unstable_version = xshell_use_unstable_version,
751         .get_xdg_surface      = xshell_get_xdg_surface,
752         .get_xdg_popup        = xshell_get_xdg_popup,
753         .pong                 = xshell_pong,
754 };
755
756 /* GTK Surface */
757 static void gsurface_set_dbus_properties(struct wl_client *cli, struct wl_resource *gsfc,
758                             const char *application_id, const char *app_menu_path,
759                             const char *menubar_path, const char *window_object_path,
760                             const char *application_object_path, const char *unique_bus_name)
761 {
762         printf("gsurface_set_dbus_properties\n");
763 }
764
765 static struct gtk_surface_interface gsurface_iface = {
766         .set_dbus_properties = gsurface_set_dbus_properties,
767 };
768
769 /* GTK Shell */
770 static void gshell_get_gtk_surface(struct wl_client *cli, struct wl_resource *gshell,
771                 uint32_t id, struct wl_resource *sfc)
772 {
773         printf("gshell_get_gtk_surface\n");
774         struct wl_resource *res = wl_resource_create(cli, &gtk_surface_interface, 1, id);
775         wl_resource_set_implementation(res, &gsurface_iface, NULL, NULL);
776 }
777
778 static struct gtk_shell_interface gshell_iface = {
779         .get_gtk_surface = gshell_get_gtk_surface,
780 };
781
782 /*******************
783  * Wayland Globals *
784  *******************/
785
786 /* References */
787 static struct wl_global *ref_shm;
788 static struct wl_global *ref_output;
789 static struct wl_global *ref_seat;
790 static struct wl_global *ref_ddm;
791 static struct wl_global *ref_comp;
792 static struct wl_global *ref_shell;
793 static struct wl_global *ref_xshell;
794 static struct wl_global *ref_gshell;
795
796 /* Bind functions */
797 static void bind_shm(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
798 {
799         printf("bind_shm\n");
800
801         if (version > 1)
802                 version = 1;
803
804         struct wl_resource *res = wl_resource_create(cli, &wl_shm_interface, version, id);
805         wl_resource_set_implementation(res, &shm_iface, NULL, NULL);
806
807         wl_shm_send_format(res, WL_SHM_FORMAT_XRGB8888);
808         wl_shm_send_format(res, WL_SHM_FORMAT_ARGB8888);
809 }
810
811 static void bind_output(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
812 {
813         printf("bind_output\n");
814
815         struct wl_resource *res = wl_resource_create(cli, &wl_output_interface, version, id);
816         output = res;
817
818         wl_output_send_geometry(res,
819                         0, 0, 330, 210,              // x/y (px), w/h (mm)
820                         WL_OUTPUT_SUBPIXEL_UNKNOWN,  // subpixel format
821                         "unknown", "unknown",        // make, model
822                         WL_OUTPUT_TRANSFORM_NORMAL); // rotatoin
823         wl_output_send_mode(res, WL_OUTPUT_MODE_CURRENT, 800,  600,  60);
824         wl_output_send_mode(res, WL_OUTPUT_MODE_CURRENT, 1024, 768,  60);
825         wl_output_send_mode(res, WL_OUTPUT_MODE_CURRENT, 1280, 1024, 60);
826         wl_output_send_done(res);
827 }
828
829 static void bind_seat(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
830 {
831         printf("bind_seat\n");
832
833         struct wl_resource *res = wl_resource_create(cli, &wl_seat_interface, version, id);
834         wl_resource_set_implementation(res, &seat_iface, NULL, NULL);
835
836         wl_seat_send_capabilities(res,
837                         WL_SEAT_CAPABILITY_KEYBOARD |
838                         WL_SEAT_CAPABILITY_POINTER);
839 }
840
841 static void bind_ddm(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
842 {
843         printf("bind_ddm\n");
844
845         struct wl_resource *res = wl_resource_create(cli, &wl_data_device_manager_interface, version, id);
846         wl_resource_set_implementation(res, &ddm_iface, NULL, NULL);
847 }
848
849 static void bind_comp(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
850 {
851         printf("bind_comp\n");
852         struct wl_resource *res = wl_resource_create(cli, &wl_compositor_interface, version, id);
853         wl_resource_set_implementation(res, &comp_iface, NULL, NULL);
854 }
855
856 static void bind_shell(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
857 {
858         printf("bind_shell\n");
859         struct wl_resource *res = wl_resource_create(cli, &wl_shell_interface, version, id);
860         wl_resource_set_implementation(res, &shell_iface, NULL, NULL);
861 }
862
863 static void bind_xshell(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
864 {
865         printf("bind_xshell\n");
866         struct wl_resource *res = wl_resource_create(cli, &xdg_shell_interface, version, id);
867         wl_resource_set_implementation(res, &xshell_iface, NULL, NULL);
868 }
869
870 static void bind_gshell(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
871 {
872         printf("bind_gshell\n");
873         struct wl_resource *res = wl_resource_create(cli, &gtk_shell_interface, version, id);
874         wl_resource_set_implementation(res, &gshell_iface, NULL, NULL);
875 }
876
877 /********************
878  * System functions *
879  ********************/
880 void sys_move(win_t *win, int x, int y, int w, int h)
881 {
882         printf("sys_move: %p - %d,%d  %dx%d\n",
883                         win, x, y, w, h);
884 }
885
886 void sys_raise(win_t *win)
887 {
888         printf("sys_raise: %p\n", win);
889 }
890
891 void sys_focus(win_t *win)
892 {
893         printf("sys_focus: %p\n", win);
894 }
895
896 void sys_show(win_t *win, state_t state)
897 {
898         printf("sys_show: %p: %d\n", win, state);
899 }
900
901 void sys_watch(win_t *win, event_t ev, mod_t mod)
902 {
903         printf("sys_watch: %p - %x %hhx\n",
904                         win, ev, mod2int(mod));
905 }
906
907 void sys_unwatch(win_t *win, event_t ev, mod_t mod)
908 {
909         printf("sys_unwatch: %p - %x %hhx\n",
910                         win, ev, mod2int(mod));
911 }
912
913 list_t *sys_info(win_t *win)
914 {
915         printf("sys_info: %p\n", win);
916         return list_insert(NULL, win);
917 }
918
919 win_t *sys_init(void)
920 {
921         printf("sys_init\n");
922
923         /* Register log handler */
924         wl_log_set_handler_server((wl_log_func_t)vprintf);
925
926         /* Open the display */
927         if (!(display = wl_display_create()))
928                 error("Unable to  create display");
929         if (wl_display_add_socket(display, NULL) != 0)
930                 error("Unable to add socket");
931         if (!(events = wl_display_get_event_loop(display)))
932                 error("Unable to get event loop");
933
934         /* Register interfaces */
935         ref_shm    = wl_global_create(display, &wl_shm_interface,                 1, NULL, &bind_shm);
936         ref_output = wl_global_create(display, &wl_output_interface,              2, NULL, &bind_output);
937         ref_ddm    = wl_global_create(display, &wl_data_device_manager_interface, 1, NULL, &bind_ddm);
938         ref_shell  = wl_global_create(display, &wl_shell_interface,               1, NULL, &bind_shell);
939         ref_comp   = wl_global_create(display, &wl_compositor_interface,          3, NULL, &bind_comp);
940         ref_seat   = wl_global_create(display, &wl_seat_interface,                4, NULL, &bind_seat);
941         ref_xshell = wl_global_create(display, &xdg_shell_interface,              1, NULL, &bind_xshell);
942         ref_gshell = wl_global_create(display, &gtk_shell_interface,              1, NULL, &bind_gshell);
943
944         /* Setup GTK display */
945         gtk_init(&conf_argc, &conf_argv);
946         screen = gtk_window_new(GTK_WINDOW_TOPLEVEL);
947         gtk_widget_add_events(screen,
948                         GDK_KEY_PRESS_MASK |
949                         GDK_BUTTON_PRESS_MASK |
950                         GDK_BUTTON_RELEASE_MASK |
951                         GDK_POINTER_MOTION_MASK);
952         g_signal_connect(screen, "destroy",             G_CALLBACK(on_destroy), NULL);
953         g_signal_connect(screen, "key-press-event",     G_CALLBACK(on_key),     NULL);
954         g_signal_connect(screen, "button-press-event",  G_CALLBACK(on_button),  NULL);
955         g_signal_connect(screen, "motion-notify-event", G_CALLBACK(on_move),    NULL);
956         g_signal_connect(screen, "draw",                G_CALLBACK(on_draw),    NULL);
957         g_timeout_add(1000/60, on_wayland, NULL);
958         gtk_widget_show(screen);
959
960         return new0(win_t);
961 }
962
963 void sys_run(win_t *root)
964 {
965         printf("sys_run: %p\n", root);
966         gtk_main();
967 }
968
969 void sys_exit(void)
970 {
971         printf("sys_exit\n");
972         gtk_main_quit();
973 }
974
975 void sys_free(win_t *root)
976 {
977         printf("sys_free: %p\n", root);
978 }
979