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