2 * Copyright (c) 2014-2015 Andy Spencer <andy753421@gmail.com>
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.
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
24 #include <libevdev/libevdev.h>
25 #include <xkbcommon/xkbcommon.h>
26 #include <wayland-server.h>
27 #include <wayland-client.h>
36 #include "xdg-shell-client-protocol.h"
37 #include "xdg-shell-server-protocol.h"
38 #include "gtk-shell-client-protocol.h"
39 #include "gtk-shell-server-protocol.h"
41 /* Window Managers calls */
44 /* Wayland user data */
53 cairo_surface_t *surface;
57 struct wl_client *cli;
58 list_t *ptrs; // of struct wl_resource
59 list_t *kbds; // of struct wl_resource
60 list_t *tchs; // of struct wl_resource
63 /* Internal structures */
65 struct wl_resource *sfc;
66 struct wl_resource *ssfc;
67 struct wl_resource *xsfc;
68 struct wl_resource *buf;
70 int x,y; // surface x,y
71 int wx,wy; // window x,y inside sfc
72 int ww,wh; // window w,h inside sfc
78 static list_t *clients; // of sys_cdata_t
79 static list_t *windows; // of win_t
82 static double cursor_x;
83 static double cursor_y;
84 static double cursor_dx;
85 static double cursor_dy;
87 static GtkWidget *screen;
89 static struct wl_resource *output;
90 static struct wl_display *display;
91 static struct wl_event_loop *events;
97 static int get_serial(void)
99 static int serial = 0;
103 static int get_time(void)
105 static uint64_t epoch;
108 clock_gettime(CLOCK_REALTIME, &ts);
110 uint64_t now = (((uint64_t)ts.tv_sec ) * 1000)
111 + (((uint64_t)ts.tv_nsec) / 1000000);
116 return (int)(now - epoch);
119 static win_t *find_win(int x, int y)
121 for (list_t *cur = windows; cur; cur = cur->prev) {
122 win_t *win = cur->data;
127 if (l <= x && x <= r && t <= y && y <= b)
133 static sys_cdata_t *find_cdata(struct wl_client *cli)
135 // Search for existing client
136 for (list_t *cur = clients; cur; cur = cur->next) {
137 sys_cdata_t *cdata = cur->data;
138 if (cdata->cli == cli)
142 // Not found, create new one
143 sys_cdata_t *cdata = new0(sys_cdata_t);
144 clients = list_insert(clients, cdata);
149 /****************************
150 * Wayland Buffer Interface *
151 ****************************/
152 static void buffer_destroy(struct wl_client *cli, struct wl_resource *reso)
154 printf("buffer_destroy\n");
157 static struct wl_buffer_interface buffer_iface = {
158 .destroy = buffer_destroy,
161 /***********************************
162 * Wayland Shared Memory Interface *
163 ***********************************/
166 static void pool_create_buffer(struct wl_client *cli, struct wl_resource *pool,
167 uint32_t id, int32_t offset, int32_t width, int32_t height,
168 int32_t stride, uint32_t format)
170 sys_bdata_t *bdata = new0(sys_bdata_t);
171 bdata->pool = wl_resource_get_user_data(pool);
172 bdata->mem = bdata->pool->mem + offset;
174 printf("pool_create_buffer - %dx%d %p+%d : %d,%d,%d\n",
175 width, height, bdata->pool->mem, offset, id, stride, format);
177 if (offset > bdata->pool->size || offset < 0)
179 printf("\n\nerror\n\n");
180 wl_resource_post_error(pool, WL_SHM_ERROR_INVALID_STRIDE,
181 "offset is too big or negative");
186 format == WL_SHM_FORMAT_ARGB8888 ? CAIRO_FORMAT_ARGB32 :
187 format == WL_SHM_FORMAT_XRGB8888 ? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_INVALID;
189 bdata->surface = cairo_image_surface_create_for_data(bdata->mem, cf, width, height, stride);
191 struct wl_resource *res = wl_resource_create(cli, &wl_buffer_interface,
192 wl_resource_get_version(pool), id);
193 wl_resource_set_implementation(res, &buffer_iface, bdata, NULL);
196 static void pool_destroy(struct wl_client *cli, struct wl_resource *pool)
198 printf("pool_destroy\n");
201 static void pool_resize(struct wl_client *cli, struct wl_resource *pool,
204 printf("[ WMPUS ] pool_resize - %d\n", size);
205 sys_pool_t *data = wl_resource_get_user_data(pool);
206 void *ptr = mremap(data->mem, data->size, size, MREMAP_MAYMOVE);
207 if (ptr == MAP_FAILED)
209 printf("\n\nerror\n\n");
210 wl_resource_post_error(pool, WL_SHM_ERROR_INVALID_FD,
211 "mremap failed: %s", strerror(errno));
218 static struct wl_shm_pool_interface pool_iface = {
219 .create_buffer = &pool_create_buffer,
220 .destroy = &pool_destroy,
221 .resize = &pool_resize,
225 static void shm_create_pool(struct wl_client *cli, struct wl_resource *shm,
226 uint32_t id, int32_t fd, int32_t size)
228 printf("shm_create_pool - #%d %d %d\n", id, fd, size);
230 sys_pool_t *data = new0(sys_pool_t);
232 struct wl_resource *res = wl_resource_create(cli, &wl_shm_pool_interface,
233 wl_resource_get_version(shm), id);
234 wl_resource_set_implementation(res, &pool_iface, data, NULL);
236 data->mem = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
240 static struct wl_shm_interface shm_iface = {
241 .create_pool = shm_create_pool,
244 /**************************
245 * Wayland Seat Interface *
246 **************************/
249 static void pointer_kill(struct wl_resource *ptr)
251 sys_cdata_t *cdata = wl_resource_get_user_data(ptr);
252 list_t *link = list_find(cdata->ptrs, ptr);
253 cdata->ptrs = list_remove(cdata->ptrs, link, 0);
254 if (!cdata->ptrs && !cdata->kbds && !cdata->tchs) {
255 list_t *clink = list_find(clients, cdata);
256 clients = list_remove(clients, clink, 1);
260 static void pointer_set_cursor(struct wl_client *cli, struct wl_resource *ptr,
261 uint32_t serial, struct wl_resource *sfc,
262 int32_t hotspot_x, int32_t hotspot_y)
264 printf("pointer_set_cursor %d,%d\n", hotspot_x, hotspot_y);
265 win_t *win = wl_resource_get_user_data(sfc);
266 win->type = TYPE_CURSOR;
267 cursor_dx = hotspot_x;
268 cursor_dy = hotspot_y;
272 static void pointer_release(struct wl_client *cli, struct wl_resource *ptr)
274 printf("pointer_release\n");
277 static struct wl_pointer_interface pointer_iface = {
278 .set_cursor = pointer_set_cursor,
279 .release = pointer_release,
283 static void keyboard_kill(struct wl_resource *kbd)
285 sys_cdata_t *cdata = wl_resource_get_user_data(kbd);
286 list_t *link = list_find(cdata->kbds, kbd);
287 cdata->kbds = list_remove(cdata->kbds, link, 0);
288 if (!cdata->ptrs && !cdata->kbds && !cdata->tchs) {
289 list_t *clink = list_find(clients, cdata);
290 clients = list_remove(clients, clink, 1);
294 static void keyboard_release(struct wl_client *cli, struct wl_resource *kbd)
296 printf("keyboard_release\n");
299 static struct wl_keyboard_interface keyboard_iface = {
300 .release = keyboard_release,
304 static void touch_kill(struct wl_resource *tch)
306 sys_cdata_t *cdata = wl_resource_get_user_data(tch);
307 list_t *link = list_find(cdata->tchs, tch);
308 cdata->tchs = list_remove(cdata->tchs, link, 0);
309 if (!cdata->ptrs && !cdata->kbds && !cdata->tchs) {
310 list_t *clink = list_find(clients, cdata);
311 clients = list_remove(clients, clink, 1);
315 static void touch_release(struct wl_client *cli, struct wl_resource *tch)
317 printf("touch_release\n");
320 static struct wl_touch_interface touch_iface = {
321 .release = touch_release,
325 static void seat_get_pointer(struct wl_client *cli, struct wl_resource *seat,
327 sys_cdata_t *cdata = find_cdata(cli);
328 struct wl_resource *res = wl_resource_create(cli, &wl_pointer_interface, 3, id);
329 wl_resource_set_implementation(res, &pointer_iface, cdata, pointer_kill);
330 cdata->ptrs = list_insert(cdata->ptrs, res);
331 printf("seat_get_pointer - cli=%p cdata=%p ptr=%p\n", cli, cdata, res);
334 static void seat_get_keyboard(struct wl_client *cli, struct wl_resource *seat,
336 sys_cdata_t *cdata = find_cdata(cli);
337 struct wl_resource *res = wl_resource_create(cli, &wl_keyboard_interface, 4, id);
338 wl_resource_set_implementation(res, &keyboard_iface, cdata, keyboard_kill);
340 //map = xkb_keymap_new_from_names(xkb->context, NULL, 0);
341 //xkb->context = xkb_context_new(0);
342 //xkb->keymap.map = xkb_keymap_new_from_names(xkb->context, NULL, 0);
343 //wl_keyboard_send_keymap(cli, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
344 // keyboard->xkb.keymap.fd,
345 // keyboard->xkb.keymap.size - 1);
347 cdata->kbds = list_insert(cdata->kbds, res);
348 printf("seat_get_keyboard - cli=%p cdata=%p kbd=%p\n", cli, cdata, res);
351 static void seat_get_touch(struct wl_client *cli, struct wl_resource *seat,
353 sys_cdata_t *cdata = find_cdata(cli);
354 struct wl_resource *res = wl_resource_create(cli, &wl_touch_interface, 3, id);
355 wl_resource_set_implementation(res, &touch_iface, cdata, touch_kill);
356 cdata->tchs = list_insert(cdata->tchs, res);
357 printf("seat_get_touch - cli=%p cdata=%p tch=%p\n", cli, cdata, res);
360 static struct wl_seat_interface seat_iface = {
361 .get_pointer = &seat_get_pointer,
362 .get_keyboard = &seat_get_keyboard,
363 .get_touch = &seat_get_touch,
366 /*****************************************
367 * Wayland Data Device Manager Interface *
368 *****************************************/
371 static void doff_accept(struct wl_client *cli, struct wl_resource *doff,
372 uint32_t serial, const char *mime_type)
374 printf("doff_accept\n");
377 static void doff_receive(struct wl_client *cli, struct wl_resource *doff,
378 const char *mime_type, int32_t fd)
380 printf("doff_receive\n");
383 static void doff_destroy(struct wl_client *cli, struct wl_resource *doff)
385 printf("doff_destroy\n");
388 static struct wl_data_offer_interface doff_iface = {
389 .accept = doff_accept,
390 .receive = doff_receive,
391 .destroy = doff_destroy,
395 static void dsrc_offer(struct wl_client *cli, struct wl_resource *dsrc,
396 const char *mime_type)
399 printf("dsrc_offer\n");
402 static void dsrc_destroy(struct wl_client *cli, struct wl_resource *dsrc)
404 printf("dsrc_destroy\n");
407 static struct wl_data_source_interface dsrc_iface = {
409 .destroy = dsrc_destroy,
413 static void ddev_start_drag(struct wl_client *cli, struct wl_resource *dsrc,
414 struct wl_resource *source, struct wl_resource *origin,
415 struct wl_resource *icon, uint32_t serial)
417 printf("start_drag\n");
420 static void ddev_set_selection(struct wl_client *cli, struct wl_resource *dsrc,
421 struct wl_resource *source, uint32_t serial)
423 printf("set_selection\n");
426 static struct wl_data_device_interface ddev_iface = {
427 .start_drag = ddev_start_drag,
428 .set_selection = ddev_set_selection,
431 /* Data Device Manager */
432 static void ddm_create_data_source(struct wl_client *cli, struct wl_resource *ddm,
435 printf("ddm_create_data_source\n");
436 struct wl_resource *res = wl_resource_create(cli, &wl_data_device_interface, 1, id);
437 wl_resource_set_implementation(res, &dsrc_iface, NULL, NULL);
440 static void ddm_get_data_device(struct wl_client *cli, struct wl_resource *ddm,
441 uint32_t id, struct wl_resource *seat)
443 printf("ddm_get_data_device\n");
444 struct wl_resource *res = wl_resource_create(cli, &wl_data_device_interface, 1, id);
445 wl_resource_set_implementation(res, &ddev_iface, NULL, NULL);
448 static struct wl_data_device_manager_interface ddm_iface = {
449 .create_data_source = &ddm_create_data_source,
450 .get_data_device = &ddm_get_data_device,
453 /**************************************
454 * Wayland Shell/Compositor Interface *
455 **************************************/
458 static void surface_kill(struct wl_resource *sfc)
460 printf("surface_kill\n");
461 win_t *win = wl_resource_get_user_data(sfc);
462 list_t *link = list_find(windows, win);
465 windows = list_remove(windows, link, 0);
466 gtk_widget_queue_draw(screen);
469 static void surface_destroy(struct wl_client *cli, struct wl_resource *sfc)
471 printf("surface_destroy\n");
475 static void surface_attach(struct wl_client *cli, struct wl_resource *sfc,
476 struct wl_resource *buf, int32_t x, int32_t y)
478 win_t *win = wl_resource_get_user_data(sfc);
479 sys_bdata_t *bdata = wl_resource_get_user_data(buf);
480 printf("surface_attach - %p - %d,%d\n", bdata->pool->mem, x, y);
486 static void surface_damage(struct wl_client *cli, struct wl_resource *sfc,
487 int32_t x, int32_t y, int32_t width, int32_t height)
489 printf("surface_damage\n");
492 static void surface_frame(struct wl_client *cli, struct wl_resource *sfc,
495 printf("surface_frame\n");
496 struct wl_resource *cb = wl_resource_create(cli, &wl_callback_interface, 1, id);
497 wl_resource_set_implementation(cb, NULL, NULL, NULL);
498 wl_callback_send_done(cb, get_time());
501 static void surface_set_opaque_region(struct wl_client *cli, struct wl_resource *sfc,
502 struct wl_resource *reg)
504 printf("surface_set_opaque_region\n");
507 static void surface_set_input_region(struct wl_client *cli, struct wl_resource *sfc,
508 struct wl_resource *reg)
510 printf("surface_set_input_region\n");
513 static void surface_commit(struct wl_client *cli, struct wl_resource *sfc)
515 printf("surface_commit\n");
516 gtk_widget_queue_draw(screen);
519 static void surface_set_buffer_transform(struct wl_client *cli, struct wl_resource *sfc,
522 printf("surface_set_buffer_transform\n");
525 static void surface_set_buffer_scale(struct wl_client *cli, struct wl_resource *sfc,
528 printf("surface_set_buffer_scale\n");
531 static struct wl_surface_interface surface_iface = {
532 .destroy = surface_destroy,
533 .attach = surface_attach,
534 .damage = surface_damage,
535 .frame = surface_frame,
536 .set_opaque_region = surface_set_opaque_region,
537 .set_input_region = surface_set_input_region,
538 .commit = surface_commit,
539 .set_buffer_transform = surface_set_buffer_transform,
540 .set_buffer_scale = surface_set_buffer_scale,
544 static void region_destroy(struct wl_client *cli, struct wl_resource *reg)
546 printf("region_destroy\n");
549 static void region_add(struct wl_client *cli, struct wl_resource *reg,
550 int32_t x, int32_t y, int32_t width, int32_t height)
552 printf("region_add\n");
555 static void region_subtract(struct wl_client *cli, struct wl_resource *reg,
556 int32_t x, int32_t y, int32_t width, int32_t height)
558 printf("region_subtract\n");
561 static struct wl_region_interface region_iface = {
562 .destroy = region_destroy,
564 .subtract = region_subtract,
568 static void comp_create_surface(struct wl_client *cli, struct wl_resource *comp,
571 win_t *win = new0(win_t);
572 win->sys = new0(win_sys_t);
574 struct wl_resource *res = wl_resource_create(cli, &wl_surface_interface, 3, id);
575 wl_resource_set_implementation(res, &surface_iface, win, surface_kill);
576 wl_surface_send_enter(res, output);
579 win->sys->cdata = find_cdata(cli);
581 windows = list_insert(windows, win);
583 printf("comp_create_surface - cli=%p win=%p cdata=%p\n",
584 cli, win, win->sys->cdata);
587 static void comp_create_region(struct wl_client *cli, struct wl_resource *comp,
590 printf("comp_create_region\n");
591 struct wl_resource *res = wl_resource_create(cli, &wl_region_interface, 1, id);
592 wl_resource_set_implementation(res, ®ion_iface, NULL, NULL);
595 static struct wl_compositor_interface comp_iface = {
596 .create_surface = comp_create_surface,
597 .create_region = comp_create_region,
601 static void ssurface_kill(struct wl_resource *ssfc)
603 win_t *win = wl_resource_get_user_data(ssfc);
604 printf("ssurface_kill - %p\n", win);
605 win->sys->ssfc = NULL;
610 static void ssurface_pong(struct wl_client *cli, struct wl_resource *ssfc,
613 printf("ssurface_pong\n");
616 static void ssurface_move(struct wl_client *cli, struct wl_resource *ssfc,
617 struct wl_resource *seat, uint32_t serial)
619 printf("ssurface_move\n");
622 static void ssurface_resize(struct wl_client *cli, struct wl_resource *ssfc,
623 struct wl_resource *seat, uint32_t serial, uint32_t edges)
625 printf("ssurface_resize\n");
628 static void ssurface_set_toplevel(struct wl_client *cli, struct wl_resource *ssfc)
630 printf("ssurface_set_toplevel\n");
633 static void ssurface_set_transient(struct wl_client *cli, struct wl_resource *ssfc,
634 struct wl_resource *parent, int32_t x, int32_t y, uint32_t flags)
636 printf("ssurface_set_transient\n");
639 static void ssurface_set_fullscreen(struct wl_client *cli, struct wl_resource *ssfc,
640 uint32_t method, uint32_t framerate, struct wl_resource *out)
642 printf("ssurface_set_fullscreen\n");
645 static void ssurface_set_popup(struct wl_client *cli, struct wl_resource *ssfc,
646 struct wl_resource *seat, uint32_t serial, struct wl_resource *parent,
647 int32_t x, int32_t y, uint32_t flags)
649 printf("ssurface_set_popup\n");
652 static void ssurface_set_maximized(struct wl_client *cli, struct wl_resource *ssfc,
653 struct wl_resource *out)
655 printf("ssurface_set_maximized\n");
658 static void ssurface_set_title(struct wl_client *cli, struct wl_resource *ssfc,
661 printf("ssurface_set_title\n");
664 static void ssurface_set_class(struct wl_client *cli, struct wl_resource *ssfc,
667 printf("ssurface_set_class\n");
670 static struct wl_shell_surface_interface ssurface_iface = {
671 .pong = ssurface_pong,
672 .move = ssurface_move,
673 .resize = ssurface_resize,
674 .set_toplevel = ssurface_set_toplevel,
675 .set_transient = ssurface_set_transient,
676 .set_fullscreen = ssurface_set_fullscreen,
677 .set_popup = ssurface_set_popup,
678 .set_maximized = ssurface_set_maximized,
679 .set_title = ssurface_set_title,
680 .set_class = ssurface_set_class,
684 static void shell_get_shell_surface(struct wl_client *cli, struct wl_resource *shell, uint32_t id,
685 struct wl_resource *sfc) {
686 win_t *win = wl_resource_get_user_data(sfc);
687 printf("shell_get_shell_surface - %p\n", win);
689 struct wl_resource *res = wl_resource_create(cli, &wl_shell_surface_interface, 1, id);
690 wl_resource_set_implementation(res, &ssurface_iface, win, ssurface_kill);
692 win->type = TYPE_NORMAL;
693 win->sys->ssfc = res;
697 static struct wl_shell_interface shell_iface = {
698 .get_shell_surface = shell_get_shell_surface,
702 static void xpopup_destroy(struct wl_client *cli, struct wl_resource *xpopup)
704 printf("xpopup_destroy\n");
707 static struct xdg_popup_interface xpopup_iface = {
708 .destroy = xpopup_destroy,
712 static void xsurface_kill(struct wl_resource *xsfc)
714 win_t *win = wl_resource_get_user_data(xsfc);
715 printf("xsurface_kill - %p\n", win);
716 win->sys->xsfc = NULL;
721 static void xsurface_destroy(struct wl_client *cli, struct wl_resource *xsfc)
723 printf("xsurface_destroy\n");
726 static void xsurface_set_parent(struct wl_client *cli, struct wl_resource *xsfc,
727 struct wl_resource *parent)
729 win_t *win = wl_resource_get_user_data(xsfc);
730 printf("xsurface_set_parent - %p\n", win);
731 //win->type = TYPE_DIALOG;
734 static void xsurface_set_title(struct wl_client *cli, struct wl_resource *xsfc,
737 printf("xsurface_set_title\n");
740 static void xsurface_set_app_id(struct wl_client *cli, struct wl_resource *xsfc,
743 printf("xsurface_set_app_id\n");
746 static void xsurface_show_window_menu(struct wl_client *cli, struct wl_resource *xsfc,
747 struct wl_resource *seat, uint32_t serial, int32_t x, int32_t y)
749 printf("xsurface_show_window_menu\n");
752 static void xsurface_move(struct wl_client *cli, struct wl_resource *xsfc,
753 struct wl_resource *seat, uint32_t serial)
755 printf("xsurface_move\n");
758 static void xsurface_resize(struct wl_client *cli, struct wl_resource *xsfc,
759 struct wl_resource *seat, uint32_t serial, uint32_t edges)
761 printf("xsurface_resize\n");
764 static void xsurface_ack_configure(struct wl_client *cli, struct wl_resource *xsfc,
767 printf("xsurface_ack_configure\n");
770 static void xsurface_set_window_geometry(struct wl_client *cli, struct wl_resource *xsfc,
771 int32_t x, int32_t y, int32_t width, int32_t height)
773 win_t *win = wl_resource_get_user_data(xsfc);
774 printf("xsurface_set_window_geometry - %p\n", win);
777 win->sys->ww = width;
778 win->sys->wh = height;
781 static void xsurface_set_maximized(struct wl_client *cli, struct wl_resource *xsfc)
783 printf("xsurface_set_maximized\n");
786 static void xsurface_unset_maximized(struct wl_client *cli, struct wl_resource *xsfc)
788 printf("xsurface_unset_maximized\n");
791 static void xsurface_set_fullscreen(struct wl_client *cli, struct wl_resource *xsfc,
792 struct wl_resource *output)
794 printf("xsurface_set_fullscreen\n");
797 static void xsurface_unset_fullscreen(struct wl_client *cli, struct wl_resource *xsfc)
799 printf("xsurface_unset_fullscreen\n");
802 static void xsurface_set_minimized(struct wl_client *cli, struct wl_resource *xsfc)
804 printf("xsurface_set_minimized\n");
807 static struct xdg_surface_interface xsurface_iface = {
808 .destroy = xsurface_destroy,
809 .set_parent = xsurface_set_parent,
810 .set_title = xsurface_set_title,
811 .set_app_id = xsurface_set_app_id,
812 .show_window_menu = xsurface_show_window_menu,
813 .move = xsurface_move,
814 .resize = xsurface_resize,
815 .ack_configure = xsurface_ack_configure,
816 .set_window_geometry = xsurface_set_window_geometry,
817 .set_maximized = xsurface_set_maximized,
818 .unset_maximized = xsurface_unset_maximized,
819 .set_fullscreen = xsurface_set_fullscreen,
820 .unset_fullscreen = xsurface_unset_fullscreen,
821 .set_minimized = xsurface_set_minimized,
825 static void xshell_use_unstable_version(struct wl_client *cli, struct wl_resource *xshell,
828 printf("xshell_use_unstable_version\n");
831 static void xshell_get_xdg_surface(struct wl_client *cli, struct wl_resource *xshell,
832 uint32_t id, struct wl_resource *sfc)
834 win_t *win = wl_resource_get_user_data(sfc);
835 printf("xshell_get_xdg_surface - %p\n", win);
837 struct wl_resource *res = wl_resource_create(cli, &xdg_surface_interface, 1, id);
838 wl_resource_set_implementation(res, &xsurface_iface, win, xsurface_kill);
840 win->type = TYPE_NORMAL;
841 win->sys->xsfc = res;
845 static void xshell_get_xdg_popup(struct wl_client *cli, struct wl_resource *xshell,
846 uint32_t id, struct wl_resource *sfc, struct wl_resource *parent,
847 struct wl_resource *seat, uint32_t serial, int32_t x, int32_t y, uint32_t flags)
849 win_t *win = wl_resource_get_user_data(sfc);
850 printf("xshell_get_xdg_popup - %p @ %d,%d\n", win, x, y);
852 struct wl_resource *res = wl_resource_create(cli, &xdg_popup_interface, 1, id);
853 wl_resource_set_implementation(res, &xpopup_iface, win, NULL);
855 win_t *par = wl_resource_get_user_data(parent);
856 win->type = TYPE_POPUP;
862 static void xshell_pong(struct wl_client *cli, struct wl_resource *xshell,
865 printf("xshell_pong\n");
868 static struct xdg_shell_interface xshell_iface = {
869 .use_unstable_version = xshell_use_unstable_version,
870 .get_xdg_surface = xshell_get_xdg_surface,
871 .get_xdg_popup = xshell_get_xdg_popup,
876 static void gsurface_set_dbus_properties(struct wl_client *cli, struct wl_resource *gsfc,
877 const char *application_id, const char *app_menu_path,
878 const char *menubar_path, const char *window_object_path,
879 const char *application_object_path, const char *unique_bus_name)
881 printf("gsurface_set_dbus_properties\n");
884 static struct gtk_surface_interface gsurface_iface = {
885 .set_dbus_properties = gsurface_set_dbus_properties,
889 static void gshell_get_gtk_surface(struct wl_client *cli, struct wl_resource *gshell,
890 uint32_t id, struct wl_resource *sfc)
892 printf("gshell_get_gtk_surface\n");
893 struct wl_resource *res = wl_resource_create(cli, >k_surface_interface, 1, id);
894 wl_resource_set_implementation(res, &gsurface_iface, NULL, NULL);
897 static struct gtk_shell_interface gshell_iface = {
898 .get_gtk_surface = gshell_get_gtk_surface,
906 static struct wl_global *ref_shm;
907 static struct wl_global *ref_output;
908 static struct wl_global *ref_seat;
909 static struct wl_global *ref_ddm;
910 static struct wl_global *ref_comp;
911 static struct wl_global *ref_shell;
912 static struct wl_global *ref_xshell;
913 static struct wl_global *ref_gshell;
916 static void bind_shm(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
918 printf("bind_shm\n");
923 struct wl_resource *res = wl_resource_create(cli, &wl_shm_interface, version, id);
924 wl_resource_set_implementation(res, &shm_iface, NULL, NULL);
926 wl_shm_send_format(res, WL_SHM_FORMAT_XRGB8888);
927 wl_shm_send_format(res, WL_SHM_FORMAT_ARGB8888);
930 static void bind_output(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
932 printf("bind_output\n");
934 struct wl_resource *res = wl_resource_create(cli, &wl_output_interface, version, id);
937 wl_output_send_geometry(res,
938 0, 0, 330, 210, // x/y (px), w/h (mm)
939 WL_OUTPUT_SUBPIXEL_UNKNOWN, // subpixel format
940 "unknown", "unknown", // make, model
941 WL_OUTPUT_TRANSFORM_NORMAL); // rotatoin
942 wl_output_send_mode(res, WL_OUTPUT_MODE_CURRENT, 800, 600, 60);
943 wl_output_send_mode(res, WL_OUTPUT_MODE_CURRENT, 1024, 768, 60);
944 wl_output_send_mode(res, WL_OUTPUT_MODE_CURRENT, 1280, 1024, 60);
945 wl_output_send_done(res);
948 static void bind_seat(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
950 printf("bind_seat\n");
952 struct wl_resource *res = wl_resource_create(cli, &wl_seat_interface, version, id);
953 wl_resource_set_implementation(res, &seat_iface, NULL, NULL);
955 wl_seat_send_capabilities(res,
956 WL_SEAT_CAPABILITY_KEYBOARD |
957 WL_SEAT_CAPABILITY_POINTER);
960 static void bind_ddm(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
962 printf("bind_ddm\n");
964 struct wl_resource *res = wl_resource_create(cli, &wl_data_device_manager_interface, version, id);
965 wl_resource_set_implementation(res, &ddm_iface, NULL, NULL);
968 static void bind_comp(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
970 printf("bind_comp\n");
971 struct wl_resource *res = wl_resource_create(cli, &wl_compositor_interface, version, id);
972 wl_resource_set_implementation(res, &comp_iface, NULL, NULL);
975 static void bind_shell(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
977 printf("bind_shell\n");
978 struct wl_resource *res = wl_resource_create(cli, &wl_shell_interface, version, id);
979 wl_resource_set_implementation(res, &shell_iface, NULL, NULL);
982 static void bind_xshell(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
984 printf("bind_xshell\n");
985 struct wl_resource *res = wl_resource_create(cli, &xdg_shell_interface, version, id);
986 wl_resource_set_implementation(res, &xshell_iface, NULL, NULL);
989 static void bind_gshell(struct wl_client *cli, void *data, uint32_t version, uint32_t id)
991 printf("bind_gshell\n");
992 struct wl_resource *res = wl_resource_create(cli, >k_shell_interface, version, id);
993 wl_resource_set_implementation(res, &gshell_iface, NULL, NULL);
1000 static void on_destroy(GtkWidget *widget, GdkEvent *event, gpointer user_data)
1002 printf("on_destroy\n");
1006 static gboolean on_key(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
1008 /* Handle special keys */
1009 if (event->keyval == GDK_KEY_q)
1011 if (event->keyval == GDK_KEY_t)
1012 g_spawn_command_line_async("st-wl", NULL);
1014 /* Send key to wayland */
1015 printf(g_ascii_isprint(event->keyval)
1016 ? "on_key - win=%p cdata=%p '%c'\n"
1017 : "on_key - win=%p cdata=%p 0x%X\n",
1018 focus, focus?focus->sys->cdata:0, event->keyval);
1019 if (!focus || !focus->sys->cdata)
1021 for (list_t *cur = focus->sys->cdata->kbds; cur; cur = cur->next) {
1022 uint32_t serial = get_serial();
1023 uint32_t stamp = get_time();
1024 uint32_t key = event->hardware_keycode-8;
1025 uint32_t state = event->type == GDK_KEY_PRESS
1026 ? WL_KEYBOARD_KEY_STATE_PRESSED
1027 : WL_KEYBOARD_KEY_STATE_RELEASED;
1028 wl_keyboard_send_key(cur->data, serial, stamp, key, state);
1029 printf(" send -> %p tm=%d key=%d state=%d\n",
1030 cur->data, stamp, key, state);
1035 static gboolean on_button(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
1037 win_t *win = find_win(event->x, event->y);
1038 printf("on_button - win=%p cdata=%p\n",
1039 win, win?win->sys->cdata:0);
1040 if (!win || !win->sys->cdata)
1042 for (list_t *cur = win->sys->cdata->ptrs; cur; cur = cur->next) {
1043 uint32_t serial = get_serial();
1044 uint32_t stamp = get_time();
1045 uint32_t button = BTN_MOUSE+(event->button-1);
1046 uint32_t state = event->type == GDK_BUTTON_PRESS
1047 ? WL_POINTER_BUTTON_STATE_PRESSED
1048 : WL_POINTER_BUTTON_STATE_RELEASED;
1049 wl_pointer_send_button(cur->data, serial, stamp, button, state);
1050 printf(" send -> %p tm=%d btn=%d state=%d\n",
1051 cur->data, stamp, button, state);
1056 static gboolean on_move(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
1058 win_t *win = find_win(event->x, event->y);
1063 static struct wl_array keys;
1065 /* Queue draw event for cursor */
1066 gtk_widget_queue_draw(screen);
1068 /* Save cursor position */
1069 cursor_x = event->x;
1070 cursor_y = event->y;
1073 wl_fixed_t x = wl_fixed_from_double(event->x - win->x);
1074 wl_fixed_t y = wl_fixed_from_double(event->y - win->y);
1076 /* No focus change */
1077 if (win == focus && win->sys->cdata) {
1078 uint32_t t = get_time();
1079 for (list_t *cur = win->sys->cdata->ptrs; cur; cur = cur->next)
1080 wl_pointer_send_motion(cur->data, t, x, y);
1084 /* Send leave event */
1085 uint32_t s = get_serial();
1086 if (focus && focus->sys->sfc && focus->sys->cdata) {
1087 printf("on_move - leave win=%p\n", focus);
1088 for (list_t *cur = focus->sys->cdata->ptrs; cur; cur = cur->next)
1089 wl_pointer_send_leave(cur->data, s, focus->sys->sfc);
1090 for (list_t *cur = focus->sys->cdata->kbds; cur; cur = cur->next)
1091 wl_keyboard_send_leave(cur->data, s, focus->sys->sfc);
1093 if (win && win->sys->sfc && win->sys->cdata) {
1094 for (list_t *cur = win->sys->cdata->ptrs; cur; cur = cur->next) {
1095 printf("on_move - enter win=%p ptr=%p\n", win, cur->data);
1096 wl_pointer_send_enter(cur->data, s, win->sys->sfc, x, y);
1098 for (list_t *cur = win->sys->cdata->kbds; cur; cur = cur->next) {
1099 printf("on_move - enter win=%p kbd=%p\n", win, cur->data);
1100 wl_keyboard_send_enter(cur->data, s, win->sys->sfc, &keys);
1107 static void on_size(GtkWidget *widget, GtkAllocation *alloc, gpointer user_data)
1109 printf("on_size - %dx%d\n", alloc->width, alloc->height);
1110 root->w = alloc->width;
1111 root->h = alloc->height;
1114 static gboolean on_draw(GtkWidget *widget, cairo_t *cairo, gpointer user_data)
1116 printf("on_draw\n");
1118 wm_update(); // Hacks for now
1120 /* Draw windows bottom up */
1121 list_t *bottom = list_last(windows);
1122 for (list_t *cur = bottom; cur; cur = cur->prev) {
1123 win_t *win = cur->data;
1124 if (win->sys->buf == NULL)
1126 if (win->type == TYPE_CURSOR)
1128 sys_bdata_t *bdata = wl_resource_get_user_data(win->sys->buf);
1131 if (win->type == TYPE_POPUP && win->parent) {
1132 x += win->parent->x;
1133 y += win->parent->y;
1135 //if (win->sys->wx) x -= win->sys->wx;
1136 //if (win->sys->wy) y -= win->sys->wy;
1137 printf(" win = %p %dx%d @ %d,%d\n",
1138 win, win->w, win->h, x, y);
1139 cairo_surface_mark_dirty(bdata->surface);
1140 cairo_set_source_surface(cairo, bdata->surface, x, y);
1142 //wl_buffer_send_release(win->sys->buf);
1143 //win->sys->buf = 0;
1147 if (cursor && cursor->sys->buf) {
1148 int x = cursor_x, y = cursor_y;
1149 sys_bdata_t *bdata = wl_resource_get_user_data(cursor->sys->buf);
1150 cairo_surface_mark_dirty(bdata->surface);
1151 cairo_set_source_surface(cairo, bdata->surface, x, y);
1158 static gboolean on_wayland(gpointer user_data)
1160 // TODO - convert to polled execution
1161 wl_display_flush_clients(display);
1162 wl_event_loop_dispatch(events, 0);
1166 /********************
1167 * System functions *
1168 ********************/
1169 void sys_move(win_t *win, int x, int y, int w, int h)
1171 static uint32_t active;
1172 static struct wl_array states;
1174 active = XDG_SURFACE_STATE_ACTIVATED;
1175 wl_array_init(&states);
1176 uint32_t *ptr = wl_array_add(&states, sizeof(active));
1181 printf("sys_move: %p - %d,%d %dx%d\n",
1184 if (win->x == x && win->y == y &&
1185 win->w == w && win->h == h)
1194 wl_shell_surface_send_configure(win->sys->ssfc,
1195 WL_SHELL_SURFACE_RESIZE_NONE, w, h);
1198 xdg_surface_send_configure(win->sys->xsfc,
1199 w, h, &states, get_serial());
1202 void sys_raise(win_t *win)
1204 printf("sys_raise: %p\n", win);
1207 void sys_focus(win_t *win)
1209 printf("sys_focus: %p\n", win);
1212 void sys_show(win_t *win, state_t state)
1214 printf("sys_show: %p: %d\n", win, state);
1217 void sys_watch(win_t *win, event_t ev, mod_t mod)
1219 printf("sys_watch: %p - %x %hhx\n",
1220 win, ev, mod2int(mod));
1223 void sys_unwatch(win_t *win, event_t ev, mod_t mod)
1225 printf("sys_unwatch: %p - %x %hhx\n",
1226 win, ev, mod2int(mod));
1229 list_t *sys_info(win_t *win)
1231 printf("sys_info: %p\n", win);
1232 return list_insert(NULL, win);
1235 win_t *sys_init(void)
1237 printf("sys_init\n");
1239 /* Create root window */
1246 /* Register log handler */
1247 wl_log_set_handler_server((wl_log_func_t)vprintf);
1249 /* Open the display */
1250 if (!(display = wl_display_create()))
1251 error("Unable to create display");
1252 if (wl_display_add_socket(display, NULL) != 0)
1253 error("Unable to add socket");
1254 if (!(events = wl_display_get_event_loop(display)))
1255 error("Unable to get event loop");
1257 /* Register interfaces */
1258 ref_shm = wl_global_create(display, &wl_shm_interface, 1, NULL, &bind_shm);
1259 ref_output = wl_global_create(display, &wl_output_interface, 2, NULL, &bind_output);
1260 ref_ddm = wl_global_create(display, &wl_data_device_manager_interface, 1, NULL, &bind_ddm);
1261 ref_shell = wl_global_create(display, &wl_shell_interface, 1, NULL, &bind_shell);
1262 ref_comp = wl_global_create(display, &wl_compositor_interface, 3, NULL, &bind_comp);
1263 ref_seat = wl_global_create(display, &wl_seat_interface, 4, NULL, &bind_seat);
1264 ref_xshell = wl_global_create(display, &xdg_shell_interface, 1, NULL, &bind_xshell);
1265 ref_gshell = wl_global_create(display, >k_shell_interface, 1, NULL, &bind_gshell);
1267 /* Setup GTK display */
1268 gtk_init(&conf_argc, &conf_argv);
1269 screen = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1270 gtk_widget_add_events(screen,
1271 GDK_KEY_PRESS_MASK |
1272 GDK_BUTTON_PRESS_MASK |
1273 GDK_BUTTON_RELEASE_MASK |
1274 GDK_POINTER_MOTION_MASK);
1275 g_signal_connect(screen, "destroy", G_CALLBACK(on_destroy), NULL);
1276 g_signal_connect(screen, "key-press-event", G_CALLBACK(on_key), NULL);
1277 g_signal_connect(screen, "key-release-event", G_CALLBACK(on_key), NULL);
1278 g_signal_connect(screen, "button-press-event", G_CALLBACK(on_button), NULL);
1279 g_signal_connect(screen, "button-release-event", G_CALLBACK(on_button), NULL);
1280 g_signal_connect(screen, "motion-notify-event", G_CALLBACK(on_move), NULL);
1281 g_signal_connect(screen, "size-allocate", G_CALLBACK(on_size), NULL);
1282 g_signal_connect(screen, "draw", G_CALLBACK(on_draw), NULL);
1283 g_timeout_add(1000/60, on_wayland, NULL);
1284 gtk_widget_show(screen);
1289 void sys_run(win_t *root)
1291 printf("sys_run: %p\n", root);
1297 printf("sys_exit\n");
1301 void sys_free(win_t *root)
1303 printf("sys_free: %p\n", root);