#include #include #include "wayland.h" #include "drw.h" #include "xdg-shell-client-protocol.h" /* macro definitions */ #define match_then_bind(obj, inter, ver) \ if (strcmp(interface, inter.name) == 0) { \ obj = wl_registry_bind(registry, name, &inter, ver); #define end_match } #define or_match } else /* struct definitions */ typedef struct { unsigned width; unsigned height; struct { struct wl_surface *wl; struct xdg_surface *xdg; struct xdg_toplevel *toplevel; } surface; Canvas *canvas; Font *font; } Window; static void buffer_release(void *data, struct wl_buffer *buffer); static void draw_frame(); static void surface_configure(void *data, struct xdg_surface *surface, uint32_t serial); static void toplevel_configure(void *data, struct xdg_toplevel *toplevel, int32_t width, int32_t height, struct wl_array *states); static void toplevel_close(void *data, struct xdg_toplevel *toplevel); static void wm_base_ping(void *data, struct xdg_wm_base *wm_base, uint32_t serial); static void registry_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version); static void registry_global_remove(void *data, struct wl_registry *registry, uint32_t name); /* global variables */ static const struct wl_registry_listener registry_listener = { .global = registry_global, .global_remove = registry_global_remove }; static const struct wl_buffer_listener buffer_listener = { .release = buffer_release }; static const struct xdg_surface_listener surface_listener = { .configure = surface_configure, }; static const struct xdg_toplevel_listener toplevel_listener = { .configure = toplevel_configure, .close = toplevel_close }; static const struct xdg_wm_base_listener wm_base_listener = { .ping = wm_base_ping }; struct client_state state = { 0 }; Window win = { 0 }; int running = 1; #include "config.h" /* function implementation */ void buffer_release(void *data, struct wl_buffer *buffer) { wl_buffer_destroy(buffer); } void draw_frame() { draw_rect(win.canvas, 0, 0, win.width, win.height, 0xff00ff00); } void surface_configure(void *data, struct xdg_surface *surface, uint32_t serial) { xdg_surface_ack_configure(surface, serial); fprintf(stderr, "configure\n"); if (win.canvas != 0) { free_drw(win.canvas); } win.canvas = create_drw(state.shm, win.width, win.height); draw_frame(); wl_surface_attach(win.surface.wl, win.canvas->buffer, 0, 0); wl_surface_damage_buffer(win.surface.wl, 0, 0, win.width, win.height); wl_surface_commit(win.surface.wl); } void toplevel_configure(void *data, struct xdg_toplevel *toplevel, int32_t width, int32_t height, struct wl_array *states) { if (width == 0 || height == 0) { win.width = 800; win.height = 600; } else { win.width = width; win.height = height; } } void toplevel_close(void *data, struct xdg_toplevel *toplevel) { running = 0; } void wm_base_ping(void *data, struct xdg_wm_base *wm_base, uint32_t serial) { xdg_wm_base_pong(wm_base, serial); } void registry_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { match_then_bind(state.shm, wl_shm_interface, 1) or_match match_then_bind(state.compositor, wl_compositor_interface, 4) or_match match_then_bind(state.wm_base, xdg_wm_base_interface, 1) /* TODO: or_match match_then_bind(state.seat, wl_seat_interface, 7) wl_seat_add_listener(state.seat, &seat_listener, &state);*/ end_match } void registry_global_remove(void *data, struct wl_registry *registry, uint32_t name) { /* TODO */ } int main() { state.display = wl_display_connect(0); state.registry = wl_display_get_registry(state.display); wl_registry_add_listener(state.registry, ®istry_listener, &state); wl_display_roundtrip(state.display); xdg_wm_base_add_listener(state.wm_base, &wm_base_listener, &state); wl_display_roundtrip(state.display); win.surface.wl = wl_compositor_create_surface(state.compositor); win.surface.xdg = xdg_wm_base_get_xdg_surface(state.wm_base, win.surface.wl); xdg_surface_add_listener(win.surface.xdg, &surface_listener, &win); win.surface.toplevel = xdg_surface_get_toplevel(win.surface.xdg); xdg_toplevel_add_listener(win.surface.toplevel, &toplevel_listener, &win); xdg_toplevel_set_title(win.surface.toplevel, "swt"); wl_surface_commit(win.surface.wl); while (wl_display_dispatch(state.display) && running) { } wl_display_disconnect(state.display); return 0; }