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