aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArslaan Pathan <[email protected]>2026-05-15 08:09:14 +1200
committerArslaan Pathan <[email protected]>2026-05-15 08:09:14 +1200
commitbe3da49ea23bbadf04c8a9b9190598a257a33bf2 (patch)
treecd6395ee905a28640f47e066f0ebbd1acb325f2a
downloadsimple-wayland-client-be3da49ea23bbadf04c8a9b9190598a257a33bf2.tar.xz
simple-wayland-client-be3da49ea23bbadf04c8a9b9190598a257a33bf2.zip
Initial commit
-rw-r--r--.gitignore2
-rw-r--r--main.c109
-rw-r--r--meson.build26
3 files changed, 137 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bc95448
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.cache/
+build/
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..154afef
--- /dev/null
+++ b/main.c
@@ -0,0 +1,109 @@
+#define _POSIX_C_SOURCE 200112L
+#include <wayland-client.h>
+#include "xdg-shell-client-protocol.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+struct wl_display *display = NULL;
+struct wl_registry *registry = NULL;
+struct wl_compositor *compositor = NULL;
+struct xdg_wm_base *wm_base = NULL;
+struct wl_surface *surface = NULL;
+struct xdg_surface *xdg_surface = NULL;
+struct xdg_toplevel *xdg_toplevel = NULL;
+
+static void xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial)
+{
+ xdg_wm_base_pong(xdg_wm_base, serial);
+}
+
+static const struct xdg_wm_base_listener wm_base_listener = {
+ .ping = xdg_wm_base_ping,
+};
+
+static void xdg_surface_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial)
+{
+ xdg_surface_ack_configure(xdg_surface, serial);
+}
+
+static const struct xdg_surface_listener xdg_surface_listener = {
+ .configure = xdg_surface_configure,
+};
+
+static void xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
+ int32_t width, int32_t height, struct wl_array *states)
+{
+ /* just exist */
+}
+
+static void xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel)
+{
+ printf("close requested\n");
+ exit(0);
+}
+
+static const struct xdg_toplevel_listener xdg_toplevel_listener = {
+ .configure = xdg_toplevel_configure,
+ .close = xdg_toplevel_close,
+};
+
+static void registry_handle_global(void *data, struct wl_registry *reg, uint32_t id,
+ const char *interface, uint32_t version)
+{
+ if (strcmp(interface, wl_compositor_interface.name) == 0) {
+ compositor = wl_registry_bind(reg, id, &wl_compositor_interface, 4);
+ } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) {
+ wm_base = wl_registry_bind(reg, id, &xdg_wm_base_interface, 1);
+ xdg_wm_base_add_listener(wm_base, &wm_base_listener, NULL);
+ }
+}
+
+static void registry_handle_global_remove(void *data, struct wl_registry *reg, uint32_t id)
+{
+ /* ignore */
+}
+
+static const struct wl_registry_listener registry_listener = {
+ .global = registry_handle_global,
+ .global_remove = registry_handle_global_remove,
+};
+
+int main(void)
+{
+ display = wl_display_connect(NULL);
+ if (!display) {
+ fprintf(stderr, "can't connect\n");
+ return 1;
+ }
+
+ registry = wl_display_get_registry(display);
+ wl_registry_add_listener(registry, &registry_listener, NULL);
+ wl_display_roundtrip(display);
+
+ if (!compositor || !wm_base) {
+ fprintf(stderr, "missing compositor or xdg_wm_base\n");
+ return 1;
+ }
+
+ surface = wl_compositor_create_surface(compositor);
+ xdg_surface = xdg_wm_base_get_xdg_surface(wm_base, surface);
+ xdg_surface_add_listener(xdg_surface, &xdg_surface_listener, NULL);
+
+ xdg_toplevel = xdg_surface_get_toplevel(xdg_surface);
+ xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL);
+ xdg_toplevel_set_title(xdg_toplevel, "wayland window");
+
+ wl_surface_commit(surface);
+ wl_display_roundtrip(display);
+
+ printf("window open, running...\n");
+
+ while (wl_display_dispatch(display) != -1) {
+ /* events handled by callbacks */
+ }
+
+ wl_display_disconnect(display);
+ return 0;
+}
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..b704ec7
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,26 @@
+project('wayland_test', 'c')
+
+wayland_client = dependency('wayland-client')
+wayland_protocols = dependency('wayland-protocols')
+
+xdg_shell_xml = wayland_protocols.get_variable(pkgconfig: 'pkgdatadir') + '/stable/xdg-shell/xdg-shell.xml'
+
+xdg_shell_header = custom_target(
+ 'xdg-shell-client-protocol.h',
+ input: xdg_shell_xml,
+ output: 'xdg-shell-client-protocol.h',
+ command: ['wayland-scanner', 'client-header', '@INPUT@', '@OUTPUT@']
+)
+
+xdg_shell_source = custom_target(
+ 'xdg-shell-protocol.c',
+ input: xdg_shell_xml,
+ output: 'xdg-shell-protocol.c',
+ command: ['wayland-scanner', 'private-code', '@INPUT@', '@OUTPUT@']
+)
+
+executable('simple-wayland-client',
+ ['main.c', xdg_shell_source, xdg_shell_header],
+ dependencies: [wayland_client],
+ include_directories: include_directories('.')
+)