aboutsummaryrefslogtreecommitdiff
path: root/swt.c
diff options
context:
space:
mode:
Diffstat (limited to 'swt.c')
-rw-r--r--swt.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/swt.c b/swt.c
new file mode 100644
index 0000000..d204bb0
--- /dev/null
+++ b/swt.c
@@ -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, &registry_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;
+}