esc

Externally Scriptable Editor

git clone git://mccd.space/esc

commit d0fcbcda3d81161dc288ca099fdaeca8b88f686b
parent 2e672b43b33d8158e7c6876b887480cefd2bff12
Author: Marc Coquand <marc@coquand.email>
Date:   Wed, 25 Feb 2026 16:22:15 +0100

Revert "Test wayland primary selection"

This reverts commit 2e672b43b33d8158e7c6876b887480cefd2bff12.

Diffstat:
MMakefile | 21++++-----------------
Mmain.c | 5+----
Dprimary-selection-unstable-v1-client-protocol.h | 582------------------------------------------------------------------------------
Dprimary-selection-unstable-v1-protocol.c | 116-------------------------------------------------------------------------------
Munix_utils.h | 5-----
Dwayland_primary.c | 260-------------------------------------------------------------------------------
Dwayland_primary.h | 17-----------------
7 files changed, 5 insertions(+), 1001 deletions(-)
diff --git a/Makefile b/Makefile
@@ -5,28 +5,15 @@ SANITIZE = -fsanitize=address,undefined
 SDL3_CFLAGS = $(shell pkg-config --cflags sdl3)
 SDL3_LIBS   = $(shell pkg-config --libs sdl3)
 
-WAYLAND_SCANNER ?= wayland-scanner
-PS_XML = /usr/share/wayland-protocols/unstable/primary-selection/primary-selection-unstable-v1.xml
-PS_HDR = primary-selection-unstable-v1-client-protocol.h
-PS_SRC = primary-selection-unstable-v1-protocol.c
-
 .PHONY: all test clean
 
 all: esc
 
-$(PS_HDR): $(PS_XML)
-	$(WAYLAND_SCANNER) client-header $< $@
-
-$(PS_SRC): $(PS_XML)
-	$(WAYLAND_SCANNER) private-code $< $@
-
 esc: main.c unix_utils.c unix_utils.h editor.c editor.h \
-     strbuf.c strbuf.h fuse_ipc.c fuse_ipc.h renderer.c renderer.h \
-     wayland_primary.c wayland_primary.h $(PS_HDR) $(PS_SRC)
+     strbuf.c strbuf.h fuse_ipc.c fuse_ipc.h renderer.c renderer.h
 	$(CC) $(CFLAGS) $(CFLAGS_OPT) main.c unix_utils.c editor.c strbuf.c \
-	      fuse_ipc.c renderer.c wayland_primary.c $(PS_SRC) -o esc \
-	      $(shell pkg-config --cflags --libs sdl3 sdl3-ttf fuse) \
-	      $(shell pkg-config --libs wayland-client)
+	      fuse_ipc.c renderer.c -o esc \
+	      $(shell pkg-config --cflags --libs sdl3 sdl3-ttf fuse)
 
 test: tests/test_strbuf tests/test_editor
 	@echo "--- running test_strbuf ---"
@@ -45,4 +32,4 @@ tests/test_editor: tests/test_editor.c tests/test_harness.h \
 	      $(SDL3_LIBS) -o tests/test_editor
 
 clean:
-	rm -f esc tests/test_strbuf tests/test_editor $(PS_HDR) $(PS_SRC)
+	rm -f esc tests/test_strbuf tests/test_editor
diff --git a/main.c b/main.c
@@ -2,7 +2,6 @@
 #include "fuse_ipc.h"
 #include "renderer.h"
 #include "unix_utils.h"
-#include "wayland_primary.h"
 #include <SDL3/SDL.h>
 #include <SDL3/SDL_clipboard.h>
 #include <SDL3/SDL_events.h>
@@ -278,7 +277,7 @@ void handle_events(Editor *ed, SDL_Renderer *renderer, float *scroll_x,
 		if (editor_has_selection(ed)) {
 			char *sel = editor_get_selection(ed);
 			if (sel) {
-				wayland_primary_set(sel);
+				SDL_SetPrimarySelectionText(sel);
 				free(sel);
 			}
 		}
@@ -319,7 +318,6 @@ int main(int argc, char *argv[]) {
 	float line_height = (float)TTF_GetFontHeight(font) * 1.5;
 	float cursor_height = (float)TTF_GetFontHeight(font);
 	Editor *ed = editor_create(char_width, line_height);
-	wayland_primary_init(window);
 	if (argc > 1) {
 		editor_load_file(ed, argv[1]);
 		editor_parse_ansi_codes(ed);
@@ -340,7 +338,6 @@ int main(int argc, char *argv[]) {
 	while (running) {
 		handle_events(ed, renderer, &scroll_x, &scroll_y, line_height,
 			      &running, &is_dragging);
-		wayland_primary_dispatch();
 
 		ctx.scroll_x = scroll_x;
 		ctx.scroll_y = scroll_y;
diff --git a/primary-selection-unstable-v1-client-protocol.h b/primary-selection-unstable-v1-client-protocol.h
@@ -1,582 +0,0 @@
-/* Generated by wayland-scanner 1.23.1 */
-
-#ifndef WP_PRIMARY_SELECTION_UNSTABLE_V1_CLIENT_PROTOCOL_H
-#define WP_PRIMARY_SELECTION_UNSTABLE_V1_CLIENT_PROTOCOL_H
-
-#include <stdint.h>
-#include <stddef.h>
-#include "wayland-client.h"
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-/**
- * @page page_wp_primary_selection_unstable_v1 The wp_primary_selection_unstable_v1 protocol
- * Primary selection protocol
- *
- * @section page_desc_wp_primary_selection_unstable_v1 Description
- *
- * This protocol provides the ability to have a primary selection device to
- * match that of the X server. This primary selection is a shortcut to the
- * common clipboard selection, where text just needs to be selected in order
- * to allow copying it elsewhere. The de facto way to perform this action
- * is the middle mouse button, although it is not limited to this one.
- *
- * Clients wishing to honor primary selection should create a primary
- * selection source and set it as the selection through
- * wp_primary_selection_device.set_selection whenever the text selection
- * changes. In order to minimize calls in pointer-driven text selection,
- * it should happen only once after the operation finished. Similarly,
- * a NULL source should be set when text is unselected.
- *
- * wp_primary_selection_offer objects are first announced through the
- * wp_primary_selection_device.data_offer event. Immediately after this event,
- * the primary data offer will emit wp_primary_selection_offer.offer events
- * to let know of the mime types being offered.
- *
- * When the primary selection changes, the client with the keyboard focus
- * will receive wp_primary_selection_device.selection events. Only the client
- * with the keyboard focus will receive such events with a non-NULL
- * wp_primary_selection_offer. Across keyboard focus changes, previously
- * focused clients will receive wp_primary_selection_device.events with a
- * NULL wp_primary_selection_offer.
- *
- * In order to request the primary selection data, the client must pass
- * a recent serial pertaining to the press event that is triggering the
- * operation, if the compositor deems the serial valid and recent, the
- * wp_primary_selection_source.send event will happen in the other end
- * to let the transfer begin. The client owning the primary selection
- * should write the requested data, and close the file descriptor
- * immediately.
- *
- * If the primary selection owner client disappeared during the transfer,
- * the client reading the data will receive a
- * wp_primary_selection_device.selection event with a NULL
- * wp_primary_selection_offer, the client should take this as a hint
- * to finish the reads related to the no longer existing offer.
- *
- * The primary selection owner should be checking for errors during
- * writes, merely cancelling the ongoing transfer if any happened.
- *
- * @section page_ifaces_wp_primary_selection_unstable_v1 Interfaces
- * - @subpage page_iface_zwp_primary_selection_device_manager_v1 - X primary selection emulation
- * - @subpage page_iface_zwp_primary_selection_device_v1 - 
- * - @subpage page_iface_zwp_primary_selection_offer_v1 - offer to transfer primary selection contents
- * - @subpage page_iface_zwp_primary_selection_source_v1 - offer to replace the contents of the primary selection
- * @section page_copyright_wp_primary_selection_unstable_v1 Copyright
- * <pre>
- *
- * Copyright © 2015, 2016 Red Hat
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * </pre>
- */
-struct wl_seat;
-struct zwp_primary_selection_device_manager_v1;
-struct zwp_primary_selection_device_v1;
-struct zwp_primary_selection_offer_v1;
-struct zwp_primary_selection_source_v1;
-
-#ifndef ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_INTERFACE
-#define ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_INTERFACE
-/**
- * @page page_iface_zwp_primary_selection_device_manager_v1 zwp_primary_selection_device_manager_v1
- * @section page_iface_zwp_primary_selection_device_manager_v1_desc Description
- *
- * The primary selection device manager is a singleton global object that
- * provides access to the primary selection. It allows to create
- * wp_primary_selection_source objects, as well as retrieving the per-seat
- * wp_primary_selection_device objects.
- * @section page_iface_zwp_primary_selection_device_manager_v1_api API
- * See @ref iface_zwp_primary_selection_device_manager_v1.
- */
-/**
- * @defgroup iface_zwp_primary_selection_device_manager_v1 The zwp_primary_selection_device_manager_v1 interface
- *
- * The primary selection device manager is a singleton global object that
- * provides access to the primary selection. It allows to create
- * wp_primary_selection_source objects, as well as retrieving the per-seat
- * wp_primary_selection_device objects.
- */
-extern const struct wl_interface zwp_primary_selection_device_manager_v1_interface;
-#endif
-#ifndef ZWP_PRIMARY_SELECTION_DEVICE_V1_INTERFACE
-#define ZWP_PRIMARY_SELECTION_DEVICE_V1_INTERFACE
-/**
- * @page page_iface_zwp_primary_selection_device_v1 zwp_primary_selection_device_v1
- * @section page_iface_zwp_primary_selection_device_v1_api API
- * See @ref iface_zwp_primary_selection_device_v1.
- */
-/**
- * @defgroup iface_zwp_primary_selection_device_v1 The zwp_primary_selection_device_v1 interface
- */
-extern const struct wl_interface zwp_primary_selection_device_v1_interface;
-#endif
-#ifndef ZWP_PRIMARY_SELECTION_OFFER_V1_INTERFACE
-#define ZWP_PRIMARY_SELECTION_OFFER_V1_INTERFACE
-/**
- * @page page_iface_zwp_primary_selection_offer_v1 zwp_primary_selection_offer_v1
- * @section page_iface_zwp_primary_selection_offer_v1_desc Description
- *
- * A wp_primary_selection_offer represents an offer to transfer the contents
- * of the primary selection clipboard to the client. Similar to
- * wl_data_offer, the offer also describes the mime types that the data can
- * be converted to and provides the mechanisms for transferring the data
- * directly to the client.
- * @section page_iface_zwp_primary_selection_offer_v1_api API
- * See @ref iface_zwp_primary_selection_offer_v1.
- */
-/**
- * @defgroup iface_zwp_primary_selection_offer_v1 The zwp_primary_selection_offer_v1 interface
- *
- * A wp_primary_selection_offer represents an offer to transfer the contents
- * of the primary selection clipboard to the client. Similar to
- * wl_data_offer, the offer also describes the mime types that the data can
- * be converted to and provides the mechanisms for transferring the data
- * directly to the client.
- */
-extern const struct wl_interface zwp_primary_selection_offer_v1_interface;
-#endif
-#ifndef ZWP_PRIMARY_SELECTION_SOURCE_V1_INTERFACE
-#define ZWP_PRIMARY_SELECTION_SOURCE_V1_INTERFACE
-/**
- * @page page_iface_zwp_primary_selection_source_v1 zwp_primary_selection_source_v1
- * @section page_iface_zwp_primary_selection_source_v1_desc Description
- *
- * The source side of a wp_primary_selection_offer, it provides a way to
- * describe the offered data and respond to requests to transfer the
- * requested contents of the primary selection clipboard.
- * @section page_iface_zwp_primary_selection_source_v1_api API
- * See @ref iface_zwp_primary_selection_source_v1.
- */
-/**
- * @defgroup iface_zwp_primary_selection_source_v1 The zwp_primary_selection_source_v1 interface
- *
- * The source side of a wp_primary_selection_offer, it provides a way to
- * describe the offered data and respond to requests to transfer the
- * requested contents of the primary selection clipboard.
- */
-extern const struct wl_interface zwp_primary_selection_source_v1_interface;
-#endif
-
-#define ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_CREATE_SOURCE 0
-#define ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_GET_DEVICE 1
-#define ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_DESTROY 2
-
-
-/**
- * @ingroup iface_zwp_primary_selection_device_manager_v1
- */
-#define ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_CREATE_SOURCE_SINCE_VERSION 1
-/**
- * @ingroup iface_zwp_primary_selection_device_manager_v1
- */
-#define ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_GET_DEVICE_SINCE_VERSION 1
-/**
- * @ingroup iface_zwp_primary_selection_device_manager_v1
- */
-#define ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_DESTROY_SINCE_VERSION 1
-
-/** @ingroup iface_zwp_primary_selection_device_manager_v1 */
-static inline void
-zwp_primary_selection_device_manager_v1_set_user_data(struct zwp_primary_selection_device_manager_v1 *zwp_primary_selection_device_manager_v1, void *user_data)
-{
-	wl_proxy_set_user_data((struct wl_proxy *) zwp_primary_selection_device_manager_v1, user_data);
-}
-
-/** @ingroup iface_zwp_primary_selection_device_manager_v1 */
-static inline void *
-zwp_primary_selection_device_manager_v1_get_user_data(struct zwp_primary_selection_device_manager_v1 *zwp_primary_selection_device_manager_v1)
-{
-	return wl_proxy_get_user_data((struct wl_proxy *) zwp_primary_selection_device_manager_v1);
-}
-
-static inline uint32_t
-zwp_primary_selection_device_manager_v1_get_version(struct zwp_primary_selection_device_manager_v1 *zwp_primary_selection_device_manager_v1)
-{
-	return wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_device_manager_v1);
-}
-
-/**
- * @ingroup iface_zwp_primary_selection_device_manager_v1
- *
- * Create a new primary selection source.
- */
-static inline struct zwp_primary_selection_source_v1 *
-zwp_primary_selection_device_manager_v1_create_source(struct zwp_primary_selection_device_manager_v1 *zwp_primary_selection_device_manager_v1)
-{
-	struct wl_proxy *id;
-
-	id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_primary_selection_device_manager_v1,
-			 ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_CREATE_SOURCE, &zwp_primary_selection_source_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_device_manager_v1), 0, NULL);
-
-	return (struct zwp_primary_selection_source_v1 *) id;
-}
-
-/**
- * @ingroup iface_zwp_primary_selection_device_manager_v1
- *
- * Create a new data device for a given seat.
- */
-static inline struct zwp_primary_selection_device_v1 *
-zwp_primary_selection_device_manager_v1_get_device(struct zwp_primary_selection_device_manager_v1 *zwp_primary_selection_device_manager_v1, struct wl_seat *seat)
-{
-	struct wl_proxy *id;
-
-	id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_primary_selection_device_manager_v1,
-			 ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_GET_DEVICE, &zwp_primary_selection_device_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_device_manager_v1), 0, NULL, seat);
-
-	return (struct zwp_primary_selection_device_v1 *) id;
-}
-
-/**
- * @ingroup iface_zwp_primary_selection_device_manager_v1
- *
- * Destroy the primary selection device manager.
- */
-static inline void
-zwp_primary_selection_device_manager_v1_destroy(struct zwp_primary_selection_device_manager_v1 *zwp_primary_selection_device_manager_v1)
-{
-	wl_proxy_marshal_flags((struct wl_proxy *) zwp_primary_selection_device_manager_v1,
-			 ZWP_PRIMARY_SELECTION_DEVICE_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_device_manager_v1), WL_MARSHAL_FLAG_DESTROY);
-}
-
-/**
- * @ingroup iface_zwp_primary_selection_device_v1
- * @struct zwp_primary_selection_device_v1_listener
- */
-struct zwp_primary_selection_device_v1_listener {
-	/**
-	 * introduce a new wp_primary_selection_offer
-	 *
-	 * Introduces a new wp_primary_selection_offer object that may be
-	 * used to receive the current primary selection. Immediately
-	 * following this event, the new wp_primary_selection_offer object
-	 * will send wp_primary_selection_offer.offer events to describe
-	 * the offered mime types.
-	 */
-	void (*data_offer)(void *data,
-			   struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1,
-			   struct zwp_primary_selection_offer_v1 *offer);
-	/**
-	 * advertise a new primary selection
-	 *
-	 * The wp_primary_selection_device.selection event is sent to
-	 * notify the client of a new primary selection. This event is sent
-	 * after the wp_primary_selection.data_offer event introducing this
-	 * object, and after the offer has announced its mimetypes through
-	 * wp_primary_selection_offer.offer.
-	 *
-	 * The data_offer is valid until a new offer or NULL is received or
-	 * until the client loses keyboard focus. The client must destroy
-	 * the previous selection data_offer, if any, upon receiving this
-	 * event.
-	 */
-	void (*selection)(void *data,
-			  struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1,
-			  struct zwp_primary_selection_offer_v1 *id);
-};
-
-/**
- * @ingroup iface_zwp_primary_selection_device_v1
- */
-static inline int
-zwp_primary_selection_device_v1_add_listener(struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1,
-					     const struct zwp_primary_selection_device_v1_listener *listener, void *data)
-{
-	return wl_proxy_add_listener((struct wl_proxy *) zwp_primary_selection_device_v1,
-				     (void (**)(void)) listener, data);
-}
-
-#define ZWP_PRIMARY_SELECTION_DEVICE_V1_SET_SELECTION 0
-#define ZWP_PRIMARY_SELECTION_DEVICE_V1_DESTROY 1
-
-/**
- * @ingroup iface_zwp_primary_selection_device_v1
- */
-#define ZWP_PRIMARY_SELECTION_DEVICE_V1_DATA_OFFER_SINCE_VERSION 1
-/**
- * @ingroup iface_zwp_primary_selection_device_v1
- */
-#define ZWP_PRIMARY_SELECTION_DEVICE_V1_SELECTION_SINCE_VERSION 1
-
-/**
- * @ingroup iface_zwp_primary_selection_device_v1
- */
-#define ZWP_PRIMARY_SELECTION_DEVICE_V1_SET_SELECTION_SINCE_VERSION 1
-/**
- * @ingroup iface_zwp_primary_selection_device_v1
- */
-#define ZWP_PRIMARY_SELECTION_DEVICE_V1_DESTROY_SINCE_VERSION 1
-
-/** @ingroup iface_zwp_primary_selection_device_v1 */
-static inline void
-zwp_primary_selection_device_v1_set_user_data(struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1, void *user_data)
-{
-	wl_proxy_set_user_data((struct wl_proxy *) zwp_primary_selection_device_v1, user_data);
-}
-
-/** @ingroup iface_zwp_primary_selection_device_v1 */
-static inline void *
-zwp_primary_selection_device_v1_get_user_data(struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1)
-{
-	return wl_proxy_get_user_data((struct wl_proxy *) zwp_primary_selection_device_v1);
-}
-
-static inline uint32_t
-zwp_primary_selection_device_v1_get_version(struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1)
-{
-	return wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_device_v1);
-}
-
-/**
- * @ingroup iface_zwp_primary_selection_device_v1
- *
- * Replaces the current selection. The previous owner of the primary
- * selection will receive a wp_primary_selection_source.cancelled event.
- *
- * To unset the selection, set the source to NULL.
- */
-static inline void
-zwp_primary_selection_device_v1_set_selection(struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1, struct zwp_primary_selection_source_v1 *source, uint32_t serial)
-{
-	wl_proxy_marshal_flags((struct wl_proxy *) zwp_primary_selection_device_v1,
-			 ZWP_PRIMARY_SELECTION_DEVICE_V1_SET_SELECTION, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_device_v1), 0, source, serial);
-}
-
-/**
- * @ingroup iface_zwp_primary_selection_device_v1
- *
- * Destroy the primary selection device.
- */
-static inline void
-zwp_primary_selection_device_v1_destroy(struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1)
-{
-	wl_proxy_marshal_flags((struct wl_proxy *) zwp_primary_selection_device_v1,
-			 ZWP_PRIMARY_SELECTION_DEVICE_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_device_v1), WL_MARSHAL_FLAG_DESTROY);
-}
-
-/**
- * @ingroup iface_zwp_primary_selection_offer_v1
- * @struct zwp_primary_selection_offer_v1_listener
- */
-struct zwp_primary_selection_offer_v1_listener {
-	/**
-	 * advertise offered mime type
-	 *
-	 * Sent immediately after creating announcing the
-	 * wp_primary_selection_offer through
-	 * wp_primary_selection_device.data_offer. One event is sent per
-	 * offered mime type.
-	 */
-	void (*offer)(void *data,
-		      struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1,
-		      const char *mime_type);
-};
-
-/**
- * @ingroup iface_zwp_primary_selection_offer_v1
- */
-static inline int
-zwp_primary_selection_offer_v1_add_listener(struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1,
-					    const struct zwp_primary_selection_offer_v1_listener *listener, void *data)
-{
-	return wl_proxy_add_listener((struct wl_proxy *) zwp_primary_selection_offer_v1,
-				     (void (**)(void)) listener, data);
-}
-
-#define ZWP_PRIMARY_SELECTION_OFFER_V1_RECEIVE 0
-#define ZWP_PRIMARY_SELECTION_OFFER_V1_DESTROY 1
-
-/**
- * @ingroup iface_zwp_primary_selection_offer_v1
- */
-#define ZWP_PRIMARY_SELECTION_OFFER_V1_OFFER_SINCE_VERSION 1
-
-/**
- * @ingroup iface_zwp_primary_selection_offer_v1
- */
-#define ZWP_PRIMARY_SELECTION_OFFER_V1_RECEIVE_SINCE_VERSION 1
-/**
- * @ingroup iface_zwp_primary_selection_offer_v1
- */
-#define ZWP_PRIMARY_SELECTION_OFFER_V1_DESTROY_SINCE_VERSION 1
-
-/** @ingroup iface_zwp_primary_selection_offer_v1 */
-static inline void
-zwp_primary_selection_offer_v1_set_user_data(struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1, void *user_data)
-{
-	wl_proxy_set_user_data((struct wl_proxy *) zwp_primary_selection_offer_v1, user_data);
-}
-
-/** @ingroup iface_zwp_primary_selection_offer_v1 */
-static inline void *
-zwp_primary_selection_offer_v1_get_user_data(struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1)
-{
-	return wl_proxy_get_user_data((struct wl_proxy *) zwp_primary_selection_offer_v1);
-}
-
-static inline uint32_t
-zwp_primary_selection_offer_v1_get_version(struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1)
-{
-	return wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_offer_v1);
-}
-
-/**
- * @ingroup iface_zwp_primary_selection_offer_v1
- *
- * To transfer the contents of the primary selection clipboard, the client
- * issues this request and indicates the mime type that it wants to
- * receive. The transfer happens through the passed file descriptor
- * (typically created with the pipe system call). The source client writes
- * the data in the mime type representation requested and then closes the
- * file descriptor.
- *
- * The receiving client reads from the read end of the pipe until EOF and
- * closes its end, at which point the transfer is complete.
- */
-static inline void
-zwp_primary_selection_offer_v1_receive(struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1, const char *mime_type, int32_t fd)
-{
-	wl_proxy_marshal_flags((struct wl_proxy *) zwp_primary_selection_offer_v1,
-			 ZWP_PRIMARY_SELECTION_OFFER_V1_RECEIVE, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_offer_v1), 0, mime_type, fd);
-}
-
-/**
- * @ingroup iface_zwp_primary_selection_offer_v1
- *
- * Destroy the primary selection offer.
- */
-static inline void
-zwp_primary_selection_offer_v1_destroy(struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1)
-{
-	wl_proxy_marshal_flags((struct wl_proxy *) zwp_primary_selection_offer_v1,
-			 ZWP_PRIMARY_SELECTION_OFFER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_offer_v1), WL_MARSHAL_FLAG_DESTROY);
-}
-
-/**
- * @ingroup iface_zwp_primary_selection_source_v1
- * @struct zwp_primary_selection_source_v1_listener
- */
-struct zwp_primary_selection_source_v1_listener {
-	/**
-	 * send the primary selection contents
-	 *
-	 * Request for the current primary selection contents from the
-	 * client. Send the specified mime type over the passed file
-	 * descriptor, then close it.
-	 */
-	void (*send)(void *data,
-		     struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1,
-		     const char *mime_type,
-		     int32_t fd);
-	/**
-	 * request for primary selection contents was canceled
-	 *
-	 * This primary selection source is no longer valid. The client
-	 * should clean up and destroy this primary selection source.
-	 */
-	void (*cancelled)(void *data,
-			  struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1);
-};
-
-/**
- * @ingroup iface_zwp_primary_selection_source_v1
- */
-static inline int
-zwp_primary_selection_source_v1_add_listener(struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1,
-					     const struct zwp_primary_selection_source_v1_listener *listener, void *data)
-{
-	return wl_proxy_add_listener((struct wl_proxy *) zwp_primary_selection_source_v1,
-				     (void (**)(void)) listener, data);
-}
-
-#define ZWP_PRIMARY_SELECTION_SOURCE_V1_OFFER 0
-#define ZWP_PRIMARY_SELECTION_SOURCE_V1_DESTROY 1
-
-/**
- * @ingroup iface_zwp_primary_selection_source_v1
- */
-#define ZWP_PRIMARY_SELECTION_SOURCE_V1_SEND_SINCE_VERSION 1
-/**
- * @ingroup iface_zwp_primary_selection_source_v1
- */
-#define ZWP_PRIMARY_SELECTION_SOURCE_V1_CANCELLED_SINCE_VERSION 1
-
-/**
- * @ingroup iface_zwp_primary_selection_source_v1
- */
-#define ZWP_PRIMARY_SELECTION_SOURCE_V1_OFFER_SINCE_VERSION 1
-/**
- * @ingroup iface_zwp_primary_selection_source_v1
- */
-#define ZWP_PRIMARY_SELECTION_SOURCE_V1_DESTROY_SINCE_VERSION 1
-
-/** @ingroup iface_zwp_primary_selection_source_v1 */
-static inline void
-zwp_primary_selection_source_v1_set_user_data(struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1, void *user_data)
-{
-	wl_proxy_set_user_data((struct wl_proxy *) zwp_primary_selection_source_v1, user_data);
-}
-
-/** @ingroup iface_zwp_primary_selection_source_v1 */
-static inline void *
-zwp_primary_selection_source_v1_get_user_data(struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1)
-{
-	return wl_proxy_get_user_data((struct wl_proxy *) zwp_primary_selection_source_v1);
-}
-
-static inline uint32_t
-zwp_primary_selection_source_v1_get_version(struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1)
-{
-	return wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_source_v1);
-}
-
-/**
- * @ingroup iface_zwp_primary_selection_source_v1
- *
- * This request adds a mime type to the set of mime types advertised to
- * targets. Can be called several times to offer multiple types.
- */
-static inline void
-zwp_primary_selection_source_v1_offer(struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1, const char *mime_type)
-{
-	wl_proxy_marshal_flags((struct wl_proxy *) zwp_primary_selection_source_v1,
-			 ZWP_PRIMARY_SELECTION_SOURCE_V1_OFFER, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_source_v1), 0, mime_type);
-}
-
-/**
- * @ingroup iface_zwp_primary_selection_source_v1
- *
- * Destroy the primary selection source.
- */
-static inline void
-zwp_primary_selection_source_v1_destroy(struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1)
-{
-	wl_proxy_marshal_flags((struct wl_proxy *) zwp_primary_selection_source_v1,
-			 ZWP_PRIMARY_SELECTION_SOURCE_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_primary_selection_source_v1), WL_MARSHAL_FLAG_DESTROY);
-}
-
-#ifdef  __cplusplus
-}
-#endif
-
-#endif
diff --git a/primary-selection-unstable-v1-protocol.c b/primary-selection-unstable-v1-protocol.c
@@ -1,116 +0,0 @@
-/* Generated by wayland-scanner 1.23.1 */
-
-/*
- * Copyright © 2015, 2016 Red Hat
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include "wayland-util.h"
-
-#ifndef __has_attribute
-# define __has_attribute(x) 0  /* Compatibility with non-clang compilers. */
-#endif
-
-#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
-#define WL_PRIVATE __attribute__ ((visibility("hidden")))
-#else
-#define WL_PRIVATE
-#endif
-
-extern const struct wl_interface wl_seat_interface;
-extern const struct wl_interface zwp_primary_selection_device_v1_interface;
-extern const struct wl_interface zwp_primary_selection_offer_v1_interface;
-extern const struct wl_interface zwp_primary_selection_source_v1_interface;
-
-static const struct wl_interface *wp_primary_selection_unstable_v1_types[] = {
-	NULL,
-	NULL,
-	&zwp_primary_selection_source_v1_interface,
-	&zwp_primary_selection_device_v1_interface,
-	&wl_seat_interface,
-	&zwp_primary_selection_source_v1_interface,
-	NULL,
-	&zwp_primary_selection_offer_v1_interface,
-	&zwp_primary_selection_offer_v1_interface,
-};
-
-static const struct wl_message zwp_primary_selection_device_manager_v1_requests[] = {
-	{ "create_source", "n", wp_primary_selection_unstable_v1_types + 2 },
-	{ "get_device", "no", wp_primary_selection_unstable_v1_types + 3 },
-	{ "destroy", "", wp_primary_selection_unstable_v1_types + 0 },
-};
-
-WL_PRIVATE const struct wl_interface zwp_primary_selection_device_manager_v1_interface = {
-	"zwp_primary_selection_device_manager_v1", 1,
-	3, zwp_primary_selection_device_manager_v1_requests,
-	0, NULL,
-};
-
-static const struct wl_message zwp_primary_selection_device_v1_requests[] = {
-	{ "set_selection", "?ou", wp_primary_selection_unstable_v1_types + 5 },
-	{ "destroy", "", wp_primary_selection_unstable_v1_types + 0 },
-};
-
-static const struct wl_message zwp_primary_selection_device_v1_events[] = {
-	{ "data_offer", "n", wp_primary_selection_unstable_v1_types + 7 },
-	{ "selection", "?o", wp_primary_selection_unstable_v1_types + 8 },
-};
-
-WL_PRIVATE const struct wl_interface zwp_primary_selection_device_v1_interface = {
-	"zwp_primary_selection_device_v1", 1,
-	2, zwp_primary_selection_device_v1_requests,
-	2, zwp_primary_selection_device_v1_events,
-};
-
-static const struct wl_message zwp_primary_selection_offer_v1_requests[] = {
-	{ "receive", "sh", wp_primary_selection_unstable_v1_types + 0 },
-	{ "destroy", "", wp_primary_selection_unstable_v1_types + 0 },
-};
-
-static const struct wl_message zwp_primary_selection_offer_v1_events[] = {
-	{ "offer", "s", wp_primary_selection_unstable_v1_types + 0 },
-};
-
-WL_PRIVATE const struct wl_interface zwp_primary_selection_offer_v1_interface = {
-	"zwp_primary_selection_offer_v1", 1,
-	2, zwp_primary_selection_offer_v1_requests,
-	1, zwp_primary_selection_offer_v1_events,
-};
-
-static const struct wl_message zwp_primary_selection_source_v1_requests[] = {
-	{ "offer", "s", wp_primary_selection_unstable_v1_types + 0 },
-	{ "destroy", "", wp_primary_selection_unstable_v1_types + 0 },
-};
-
-static const struct wl_message zwp_primary_selection_source_v1_events[] = {
-	{ "send", "sh", wp_primary_selection_unstable_v1_types + 0 },
-	{ "cancelled", "", wp_primary_selection_unstable_v1_types + 0 },
-};
-
-WL_PRIVATE const struct wl_interface zwp_primary_selection_source_v1_interface = {
-	"zwp_primary_selection_source_v1", 1,
-	2, zwp_primary_selection_source_v1_requests,
-	2, zwp_primary_selection_source_v1_events,
-};
-
diff --git a/unix_utils.h b/unix_utils.h
@@ -11,9 +11,4 @@ char *unix_run_command(const char *command, const char *input);
 
 // Ignores output
 void unix_exec_command(const char *command, const char *input);
-
-// Sets the Wayland primary selection via wl-copy --primary.
-// Text is piped exactly (no trailing newline added).
-// Skips re-spawning if the text hasn't changed.
-void unix_set_primary_selection(const char *text);
 #endif
diff --git a/wayland_primary.c b/wayland_primary.c
@@ -1,260 +0,0 @@
-#include "wayland_primary.h"
-#include "primary-selection-unstable-v1-client-protocol.h"
-#include <SDL3/SDL.h>
-#include <wayland-client.h>
-#include <poll.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-static struct wl_display   *s_display;
-static struct wl_registry  *s_registry;
-static struct wl_seat      *s_seat;
-static struct wl_pointer   *s_pointer;
-static struct wl_keyboard  *s_keyboard;
-static struct zwp_primary_selection_device_manager_v1 *s_manager;
-static struct zwp_primary_selection_device_v1         *s_device;
-static struct zwp_primary_selection_source_v1         *s_source;
-static struct zwp_primary_selection_offer_v1          *s_pending_offer;
-
-static uint32_t  s_last_serial;
-static char     *s_current_text;
-
-/* ── source events ─────────────────────────────────────────────────────── */
-
-static void source_send(void *data,
-	struct zwp_primary_selection_source_v1 *source,
-	const char *mime_type, int32_t fd)
-{
-	(void)data; (void)source; (void)mime_type;
-	if (s_current_text)
-		write(fd, s_current_text, strlen(s_current_text));
-	close(fd);
-}
-
-static void source_cancelled(void *data,
-	struct zwp_primary_selection_source_v1 *source)
-{
-	(void)data;
-	zwp_primary_selection_source_v1_destroy(source);
-	if (s_source == source)
-		s_source = NULL;
-	free(s_current_text);
-	s_current_text = NULL;
-}
-
-static const struct zwp_primary_selection_source_v1_listener s_source_listener = {
-	.send      = source_send,
-	.cancelled = source_cancelled,
-};
-
-/* ── device events ──────────────────────────────────────────────────────── */
-
-static void device_data_offer(void *data,
-	struct zwp_primary_selection_device_v1 *device,
-	struct zwp_primary_selection_offer_v1 *offer)
-{
-	(void)data; (void)device;
-	if (s_pending_offer)
-		zwp_primary_selection_offer_v1_destroy(s_pending_offer);
-	s_pending_offer = offer;
-}
-
-static void device_selection(void *data,
-	struct zwp_primary_selection_device_v1 *device,
-	struct zwp_primary_selection_offer_v1 *id)
-{
-	(void)data; (void)device; (void)id;
-	if (s_pending_offer) {
-		zwp_primary_selection_offer_v1_destroy(s_pending_offer);
-		s_pending_offer = NULL;
-	}
-}
-
-static const struct zwp_primary_selection_device_v1_listener s_device_listener = {
-	.data_offer = device_data_offer,
-	.selection  = device_selection,
-};
-
-/* ── pointer listener (serial capture) ─────────────────────────────────── */
-
-static void ptr_enter(void *d, struct wl_pointer *p, uint32_t serial,
-	struct wl_surface *surf, wl_fixed_t x, wl_fixed_t y)
-{ (void)d; (void)p; (void)serial; (void)surf; (void)x; (void)y; }
-
-static void ptr_leave(void *d, struct wl_pointer *p, uint32_t serial,
-	struct wl_surface *surf)
-{ (void)d; (void)p; (void)serial; (void)surf; }
-
-static void ptr_motion(void *d, struct wl_pointer *p, uint32_t t,
-	wl_fixed_t x, wl_fixed_t y)
-{ (void)d; (void)p; (void)t; (void)x; (void)y; }
-
-static void ptr_button(void *d, struct wl_pointer *p, uint32_t serial,
-	uint32_t t, uint32_t btn, uint32_t state)
-{ (void)d; (void)p; (void)t; (void)btn; (void)state; s_last_serial = serial; }
-
-static void ptr_axis(void *d, struct wl_pointer *p, uint32_t t,
-	uint32_t axis, wl_fixed_t val)
-{ (void)d; (void)p; (void)t; (void)axis; (void)val; }
-
-/* v5+ events — never sent to a version-1 proxy, but slots must be non-NULL
- * only for the version we bind at.  We bind at v1, so these are safe NULL. */
-static const struct wl_pointer_listener s_pointer_listener = {
-	.enter                   = ptr_enter,
-	.leave                   = ptr_leave,
-	.motion                  = ptr_motion,
-	.button                  = ptr_button,
-	.axis                    = ptr_axis,
-	.frame                   = NULL,
-	.axis_source             = NULL,
-	.axis_stop               = NULL,
-	.axis_discrete           = NULL,
-	.axis_value120           = NULL,
-	.axis_relative_direction = NULL,
-};
-
-/* ── keyboard listener (serial capture) ────────────────────────────────── */
-
-static void kbd_keymap(void *d, struct wl_keyboard *kb, uint32_t fmt,
-	int32_t fd, uint32_t size)
-{ (void)d; (void)kb; (void)fmt; (void)size; close(fd); }
-
-static void kbd_enter(void *d, struct wl_keyboard *kb, uint32_t serial,
-	struct wl_surface *surf, struct wl_array *keys)
-{ (void)d; (void)kb; (void)serial; (void)surf; (void)keys; }
-
-static void kbd_leave(void *d, struct wl_keyboard *kb, uint32_t serial,
-	struct wl_surface *surf)
-{ (void)d; (void)kb; (void)serial; (void)surf; }
-
-static void kbd_key(void *d, struct wl_keyboard *kb, uint32_t serial,
-	uint32_t t, uint32_t key, uint32_t state)
-{ (void)d; (void)kb; (void)t; (void)key; (void)state; s_last_serial = serial; }
-
-static void kbd_modifiers(void *d, struct wl_keyboard *kb, uint32_t serial,
-	uint32_t dep, uint32_t lat, uint32_t lock, uint32_t grp)
-{ (void)d; (void)kb; (void)serial; (void)dep; (void)lat; (void)lock; (void)grp; }
-
-/* .repeat_info is v4 — never sent to a v1 proxy */
-static const struct wl_keyboard_listener s_keyboard_listener = {
-	.keymap      = kbd_keymap,
-	.enter       = kbd_enter,
-	.leave       = kbd_leave,
-	.key         = kbd_key,
-	.modifiers   = kbd_modifiers,
-	.repeat_info = NULL,
-};
-
-/* ── seat listener ──────────────────────────────────────────────────────── */
-
-static void seat_capabilities(void *data, struct wl_seat *seat, uint32_t caps)
-{
-	(void)data;
-	if ((caps & WL_SEAT_CAPABILITY_POINTER) && !s_pointer) {
-		s_pointer = wl_seat_get_pointer(seat);
-		wl_pointer_add_listener(s_pointer, &s_pointer_listener, NULL);
-	}
-	if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !s_keyboard) {
-		s_keyboard = wl_seat_get_keyboard(seat);
-		wl_keyboard_add_listener(s_keyboard, &s_keyboard_listener, NULL);
-	}
-}
-
-/* .name is v2 — never sent to a v1 seat proxy */
-static const struct wl_seat_listener s_seat_listener = {
-	.capabilities = seat_capabilities,
-	.name         = NULL,
-};
-
-/* ── registry listener ──────────────────────────────────────────────────── */
-
-static void registry_global(void *data, struct wl_registry *registry,
-	uint32_t name, const char *interface, uint32_t version)
-{
-	(void)data;
-	if (strcmp(interface, wl_seat_interface.name) == 0 && !s_seat) {
-		s_seat = wl_registry_bind(registry, name, &wl_seat_interface,
-				version < 1 ? version : 1);
-		wl_seat_add_listener(s_seat, &s_seat_listener, NULL);
-	} else if (strcmp(interface,
-			zwp_primary_selection_device_manager_v1_interface.name) == 0) {
-		s_manager = wl_registry_bind(registry, name,
-				&zwp_primary_selection_device_manager_v1_interface, 1);
-	}
-}
-
-static void registry_global_remove(void *data, struct wl_registry *registry,
-	uint32_t name)
-{ (void)data; (void)registry; (void)name; }
-
-static const struct wl_registry_listener s_registry_listener = {
-	.global        = registry_global,
-	.global_remove = registry_global_remove,
-};
-
-/* ── public API ─────────────────────────────────────────────────────────── */
-
-void wayland_primary_init(SDL_Window *window)
-{
-	SDL_PropertiesID props = SDL_GetWindowProperties(window);
-	s_display = SDL_GetPointerProperty(props,
-			SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, NULL);
-	if (!s_display)
-		return;
-
-	s_registry = wl_display_get_registry(s_display);
-	wl_registry_add_listener(s_registry, &s_registry_listener, NULL);
-	/* Roundtrip: triggers registry_global and seat_capabilities callbacks. */
-	wl_display_roundtrip(s_display);
-
-	if (!s_manager || !s_seat)
-		return;
-
-	s_device = zwp_primary_selection_device_manager_v1_get_device(
-			s_manager, s_seat);
-	zwp_primary_selection_device_v1_add_listener(s_device,
-			&s_device_listener, NULL);
-	wl_display_flush(s_display);
-}
-
-void wayland_primary_set(const char *text)
-{
-	if (!s_device || !s_manager || !text || !*text)
-		return;
-	if (s_current_text && strcmp(s_current_text, text) == 0)
-		return;
-
-	if (s_source) {
-		zwp_primary_selection_source_v1_destroy(s_source);
-		s_source = NULL;
-	}
-	free(s_current_text);
-	s_current_text = strdup(text);
-
-	s_source = zwp_primary_selection_device_manager_v1_create_source(s_manager);
-	zwp_primary_selection_source_v1_add_listener(s_source,
-			&s_source_listener, NULL);
-	zwp_primary_selection_source_v1_offer(s_source, "text/plain;charset=utf-8");
-	zwp_primary_selection_source_v1_offer(s_source, "text/plain");
-	zwp_primary_selection_source_v1_offer(s_source, "UTF8_STRING");
-	zwp_primary_selection_source_v1_offer(s_source, "STRING");
-	zwp_primary_selection_source_v1_offer(s_source, "TEXT");
-
-	zwp_primary_selection_device_v1_set_selection(s_device, s_source,
-			s_last_serial);
-	wl_display_flush(s_display);
-}
-
-void wayland_primary_dispatch(void)
-{
-	if (!s_display)
-		return;
-	/*
-	 * SDL's Wayland read thread reads events from the socket and places
-	 * them in their respective queues.  Our proxies use the default queue,
-	 * so dispatch_pending processes whatever SDL's thread has already read.
-	 * No socket read is needed here.
-	 */
-	wl_display_dispatch_pending(s_display);
-}
diff --git a/wayland_primary.h b/wayland_primary.h
@@ -1,17 +0,0 @@
-#ifndef WAYLAND_PRIMARY_H
-#define WAYLAND_PRIMARY_H
-
-#include <SDL3/SDL_video.h>
-
-/* Initialize Wayland primary selection using SDL3's wl_display.
- * Call once after the SDL window is created, before the event loop. */
-void wayland_primary_init(SDL_Window *window);
-
-/* Set the primary selection text.  Skips if text is unchanged. */
-void wayland_primary_set(const char *text);
-
-/* Dispatch pending events on our Wayland proxies (default queue).
- * Call once per main-loop iteration, after handle_events(). */
-void wayland_primary_dispatch(void);
-
-#endif