diff options
Diffstat (limited to 'swt.c')
| -rw-r--r-- | swt.c | 173 |
1 files changed, 173 insertions, 0 deletions
@@ -0,0 +1,173 @@ +#include <string.h> +#include <stdio.h> + +#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; +} |