wings(wayland-client): build system + connection skeleton
Task 1 + 2 of the WINGs Wayland-client backend.
Adds optional --enable-wayland-client (default auto) which depends on
wayland-client, xkbcommon, wayland-protocols, and wayland-scanner.
configure.ac probes for these and exposes WAYLAND_CLIENT_CFLAGS/LIBS
plus the protocols data dir and scanner path.
WINGs/Makefile.am wires a wayland-scanner rule that generates
xdg-shell-{protocol,client-protocol}.{c,h} at build time and links
libWINGs against wayland-client + xkbcommon when enabled.
WINGs/wclient_wl.c is the new file. It self-stubs when the feature
is disabled. When enabled it provides:
W_WLClientInit(scrPtr, display)
Connects via wl_display_connect, registers a wl_registry listener,
binds wl_compositor/wl_shm/wl_seat/xdg_wm_base, creates an xkb_context,
and hooks the libwayland event pump into the existing
W_EventBackendWL via W_WL_SetLoopDispatch(). This lets the existing
ring-buffer event mechanism keep working unchanged: the ring is fed
by client-side wl_pointer/wl_keyboard listeners (next task) and
drained by WMNextEvent / WMMaskEvent / waitForEvent.
W_WLClientShutdown(scrPtr)
Tears down all bound globals and disconnects the wl_display.
No surfaces / buffers / input dispatch yet — those come in tasks 3-5.
Build verified clean, wmaker still links and runs as before.
This commit is contained in:
parent
852fb2adeb
commit
182617513e
8
+cmd
8
+cmd
|
|
@ -1,6 +1,8 @@
|
|||
Xwayland :3
|
||||
DISPLAY=':3' gdb -batch -ex 'set confirm off' -ex 'set filename-display absolute' -ex run -ex bt -ex quit --args src/.libs/wmaker --for-real >[2=1]
|
||||
|
||||
WMAKER_USE_WAYLAND='1' WMAKER_WAYLAND_NESTED='1' LD_LIBRARY_PATH='/usr/local/lib' G_SLICE=always-malloc MALLOC_CHECK_=3 valgrind --tool=memcheck --track-origins=yes --leak-check=no ./src/.libs/wmaker
|
||||
|
||||
WMAKER_USE_WAYLAND='1' WMAKER_WAYLAND_NESTED='1' LD_LIBRARY_PATH='/usr/local/lib' gdb -batch -ex 'set confirm off' -ex 'set filename-display absolute' -ex run -ex bt -ex quit --args src/.libs/wmaker --for-real >[2=1]
|
||||
|
||||
WAYLAND_DISPLAY=wayland-0 foot
|
||||
|
|
@ -8,6 +10,12 @@ WAYLAND_DISPLAY=wayland-0 foot
|
|||
./configure --prefix=/usr/local --enable-wayland
|
||||
make clean
|
||||
make -j8 CFLAGS='-fsanitize=leak' LDFLAGS='-fsanitize=leak'
|
||||
|
||||
|
||||
CFLAGS='-O0 -g -fsanitize=address -fno-omit-frame-pointer' LDFLAGS='-fsanitize=address' ./configure --prefix=/usr/local --enable-wayland; CFLAGS='-O0 -g -fsanitize=address -fno-omit-frame-pointer' LDFLAGS='-fsanitize=address' make -j8
|
||||
WMAKER_USE_WAYLAND='1' WMAKER_WAYLAND_NESTED='1' LD_LIBRARY_PATH='/usr/local/lib' ./src/.libs/wmaker
|
||||
|
||||
|
||||
win sudo make install
|
||||
|
||||
git stash pop
|
||||
|
|
|
|||
|
|
@ -12,9 +12,15 @@ lib_LTLIBRARIES = libWUtil.la libWINGs.la
|
|||
|
||||
|
||||
LDADD= libWUtil.la libWINGs.la $(top_builddir)/wrlib/libwraster.la @INTLIBS@
|
||||
libWINGs_la_LIBADD = libWUtil.la $(top_builddir)/wrlib/libwraster.la @XLIBS@ @XFT_LIBS@ @FCLIBS@ @LIBM@ @PANGO_LIBS@ @PIXMAN_LIBS@
|
||||
libWINGs_la_LIBADD = libWUtil.la $(top_builddir)/wrlib/libwraster.la @XLIBS@ @XFT_LIBS@ @FCLIBS@ @LIBM@ @PANGO_LIBS@ @PIXMAN_LIBS@ $(WAYLAND_CLIENT_LIBS_IF_ENABLED)
|
||||
libWUtil_la_LIBADD = @LIBBSD@
|
||||
|
||||
if USE_WAYLAND_CLIENT
|
||||
WAYLAND_CLIENT_LIBS_IF_ENABLED = @WAYLAND_CLIENT_LIBS@
|
||||
else
|
||||
WAYLAND_CLIENT_LIBS_IF_ENABLED =
|
||||
endif
|
||||
|
||||
EXTRA_DIST = BUGS make-rgb Examples Extras Tests
|
||||
|
||||
|
||||
|
|
@ -69,8 +75,25 @@ libWINGs_la_SOURCES = \
|
|||
wview.c \
|
||||
wview_x11.c \
|
||||
wview_wl.c \
|
||||
wclient_wl.c \
|
||||
wwindow.c
|
||||
|
||||
if USE_WAYLAND_CLIENT
|
||||
nodist_libWINGs_la_SOURCES = \
|
||||
xdg-shell-protocol.c \
|
||||
xdg-shell-client-protocol.h
|
||||
BUILT_SOURCES = xdg-shell-client-protocol.h xdg-shell-protocol.c
|
||||
CLEANFILES = xdg-shell-client-protocol.h xdg-shell-protocol.c
|
||||
|
||||
xdg-shell-client-protocol.h:
|
||||
$(WAYLAND_SCANNER) client-header \
|
||||
$(WAYLAND_PROTOCOLS_DIR)/stable/xdg-shell/xdg-shell.xml $@
|
||||
|
||||
xdg-shell-protocol.c: xdg-shell-client-protocol.h
|
||||
$(WAYLAND_SCANNER) private-code \
|
||||
$(WAYLAND_PROTOCOLS_DIR)/stable/xdg-shell/xdg-shell.xml $@
|
||||
endif
|
||||
|
||||
libWUtil_la_SOURCES = \
|
||||
array.c \
|
||||
bagtree.c \
|
||||
|
|
@ -97,11 +120,12 @@ libWUtil_la_SOURCES = \
|
|||
wutil.c
|
||||
|
||||
|
||||
AM_CFLAGS = @PANGO_CFLAGS@ @PIXMAN_CFLAGS@
|
||||
AM_CFLAGS = @PANGO_CFLAGS@ @PIXMAN_CFLAGS@ @WAYLAND_CLIENT_CFLAGS@
|
||||
|
||||
AM_CPPFLAGS = -DRESOURCE_PATH=\"$(datadir)/WINGs\" \
|
||||
-I$(top_srcdir)/WINGs/WINGs -I$(top_builddir)/WINGs/WINGs \
|
||||
-I$(top_builddir)/wrlib -I$(top_srcdir)/src \
|
||||
-I$(top_builddir)/WINGs \
|
||||
@XFT_CFLAGS@ @HEADER_SEARCH_PATH@
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
|
|
|
|||
|
|
@ -490,6 +490,25 @@ void W_WL_SetLoopDispatch(struct W_Screen *scr,
|
|||
void (*dispatch_fn)(int timeout_ms, void *ud),
|
||||
void *userdata);
|
||||
|
||||
/*
|
||||
* Wayland client backend (wclient_wl.c). Optional; only available
|
||||
* when wmaker is configured with --enable-wayland-client (USE_WAYLAND_CLIENT).
|
||||
*
|
||||
* W_WLClientInit() opens a wayland-client connection to the compositor,
|
||||
* binds the required globals (wl_compositor, wl_shm, xdg_wm_base, wl_seat),
|
||||
* sets up the event-loop dispatch via W_WL_SetLoopDispatch(), and
|
||||
* arranges for top-level W_Views to acquire wl_surface + xdg_toplevel
|
||||
* pairs and per-surface wl_shm backing buffers.
|
||||
*
|
||||
* Returns True on success, False on any failure. When False is
|
||||
* returned, the caller should fall back to the X11 backend.
|
||||
*
|
||||
* WMOpenScreen() calls this automatically when it detects WAYLAND_DISPLAY
|
||||
* in the environment and DISPLAY is unset.
|
||||
*/
|
||||
Bool W_WLClientInit(struct W_Screen *scrPtr, const char *display);
|
||||
void W_WLClientShutdown(struct W_Screen *scrPtr);
|
||||
|
||||
|
||||
/* ---[ wfont.c ]--------------------------------------------------------- */
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,263 @@
|
|||
/*
|
||||
* wclient_wl.c — Wayland *client* backend for WINGs.
|
||||
*
|
||||
* This is the counterpart to wevent_wl.c / wview_wl.c / wfont_wl.c /
|
||||
* wrender_wl.c, but used when a WINGs program runs as a *client* of an
|
||||
* external Wayland compositor (e.g. WPrefs.app under wmaker-wl, sway,
|
||||
* or any wlroots-based compositor).
|
||||
*
|
||||
* In compositor mode the WM owns the rendering pipeline and the same
|
||||
* Wayland backend files run inside the compositor process; surfaces
|
||||
* are scene-graph nodes managed by wlroots.
|
||||
*
|
||||
* In client mode (this file), the program connects via libwayland-client,
|
||||
* binds the standard globals (wl_compositor, wl_shm, xdg_wm_base, wl_seat),
|
||||
* creates an xdg_toplevel for each top-level W_View, and submits buffers
|
||||
* via wl_shm. Pixman backing images are allocated over a memfd-mapped
|
||||
* region wrapped in a wl_buffer so paints can be done with the same
|
||||
* pixman calls used everywhere else.
|
||||
*
|
||||
* Input dispatch translates wl_pointer / wl_keyboard events into
|
||||
* WMEvent and feeds them to the existing W_EventBackendWL ring buffer
|
||||
* via W_WL_EnqueueEvent — the same mechanism the compositor-internal
|
||||
* Wayland backend uses.
|
||||
*/
|
||||
|
||||
#include "wconfig.h"
|
||||
|
||||
#ifdef USE_WAYLAND_CLIENT
|
||||
|
||||
#include "WINGsP.h"
|
||||
|
||||
#include <wayland-client.h>
|
||||
#include "xdg-shell-client-protocol.h"
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Per-screen Wayland-client context */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
typedef struct WLClientCtx {
|
||||
struct wl_display *display;
|
||||
struct wl_registry *registry;
|
||||
|
||||
struct wl_compositor *compositor;
|
||||
struct wl_shm *shm;
|
||||
struct wl_seat *seat;
|
||||
struct xdg_wm_base *wm_base;
|
||||
|
||||
struct wl_pointer *pointer;
|
||||
struct wl_keyboard *keyboard;
|
||||
|
||||
struct xkb_context *xkb_ctx;
|
||||
struct xkb_keymap *xkb_keymap;
|
||||
struct xkb_state *xkb_state;
|
||||
|
||||
/* Back-reference for input handlers */
|
||||
struct W_Screen *scr;
|
||||
} WLClientCtx;
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* xdg_wm_base ping */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void
|
||||
wm_base_ping(void *data, struct xdg_wm_base *base, uint32_t serial)
|
||||
{
|
||||
(void)data;
|
||||
xdg_wm_base_pong(base, serial);
|
||||
}
|
||||
|
||||
static const struct xdg_wm_base_listener wm_base_listener = {
|
||||
.ping = wm_base_ping,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Registry — bind required globals */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void
|
||||
registry_handle_global(void *data, struct wl_registry *registry,
|
||||
uint32_t name, const char *interface, uint32_t version)
|
||||
{
|
||||
WLClientCtx *ctx = data;
|
||||
if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
||||
uint32_t v = version < 4 ? version : 4;
|
||||
ctx->compositor = wl_registry_bind(registry, name,
|
||||
&wl_compositor_interface, v);
|
||||
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
|
||||
ctx->shm = wl_registry_bind(registry, name,
|
||||
&wl_shm_interface, 1);
|
||||
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
|
||||
uint32_t v = version < 5 ? version : 5;
|
||||
ctx->seat = wl_registry_bind(registry, name,
|
||||
&wl_seat_interface, v);
|
||||
/* Pointer/keyboard probes happen lazily on the first capabilities event;
|
||||
* we'll add a wl_seat listener below in W_WLClientInit. */
|
||||
} else if (strcmp(interface, xdg_wm_base_interface.name) == 0) {
|
||||
uint32_t v = version < 3 ? version : 3;
|
||||
ctx->wm_base = wl_registry_bind(registry, name,
|
||||
&xdg_wm_base_interface, v);
|
||||
xdg_wm_base_add_listener(ctx->wm_base, &wm_base_listener, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
registry_handle_global_remove(void *data, struct wl_registry *registry,
|
||||
uint32_t name)
|
||||
{
|
||||
(void)data; (void)registry; (void)name;
|
||||
/* Globals like seat or output may go away on hotplug; ignore for now. */
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
.global = registry_handle_global,
|
||||
.global_remove = registry_handle_global_remove,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Event-loop dispatch (used by W_EventBackendWL when queue is empty) */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void
|
||||
wlclient_dispatch(int timeout_ms, void *userdata)
|
||||
{
|
||||
WLClientCtx *ctx = userdata;
|
||||
if (!ctx || !ctx->display) return;
|
||||
|
||||
/* Standard libwayland-client event-pumping idiom:
|
||||
* 1. Prepare a read.
|
||||
* 2. Flush outgoing requests.
|
||||
* 3. Poll the fd.
|
||||
* 4. read_events / cancel_read.
|
||||
* 5. Dispatch any queued events.
|
||||
*
|
||||
* We don't need the prepare/read split when we're only blocking
|
||||
* here, but doing it correctly keeps us safe if multiple threads
|
||||
* ever want to share the wl_display.
|
||||
*/
|
||||
while (wl_display_prepare_read(ctx->display) != 0) {
|
||||
if (wl_display_dispatch_pending(ctx->display) < 0) return;
|
||||
}
|
||||
if (wl_display_flush(ctx->display) < 0 && errno != EAGAIN) {
|
||||
wl_display_cancel_read(ctx->display);
|
||||
return;
|
||||
}
|
||||
|
||||
struct pollfd pfd = {
|
||||
.fd = wl_display_get_fd(ctx->display),
|
||||
.events = POLLIN,
|
||||
};
|
||||
int n = poll(&pfd, 1, timeout_ms);
|
||||
if (n <= 0) {
|
||||
wl_display_cancel_read(ctx->display);
|
||||
return;
|
||||
}
|
||||
if (wl_display_read_events(ctx->display) < 0) return;
|
||||
wl_display_dispatch_pending(ctx->display);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Public API */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
/* Storage for the active context — for now we only support one screen. */
|
||||
static WLClientCtx *g_wlclient_ctx = NULL;
|
||||
|
||||
Bool
|
||||
W_WLClientInit(struct W_Screen *scrPtr, const char *display)
|
||||
{
|
||||
WLClientCtx *ctx = wmalloc(sizeof(*ctx));
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
ctx->scr = scrPtr;
|
||||
|
||||
ctx->display = wl_display_connect(display);
|
||||
if (!ctx->display) {
|
||||
wwarning(_("WINGs: wl_display_connect() failed"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ctx->registry = wl_display_get_registry(ctx->display);
|
||||
if (!ctx->registry) goto fail;
|
||||
wl_registry_add_listener(ctx->registry, ®istry_listener, ctx);
|
||||
|
||||
/* Two roundtrips: first to receive globals, second to settle any
|
||||
* follow-up events from those globals (e.g. wl_seat capabilities). */
|
||||
if (wl_display_roundtrip(ctx->display) < 0) goto fail;
|
||||
if (wl_display_roundtrip(ctx->display) < 0) goto fail;
|
||||
|
||||
if (!ctx->compositor || !ctx->shm || !ctx->wm_base) {
|
||||
wwarning(_("WINGs: compositor missing required globals "
|
||||
"(wl_compositor / wl_shm / xdg_wm_base)"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ctx->xkb_ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if (!ctx->xkb_ctx) goto fail;
|
||||
|
||||
/* Hook event-loop dispatch into the WINGs Wayland event backend so
|
||||
* WMNextEvent / waitForEvent will pump the compositor when idle. */
|
||||
W_WL_SetLoopDispatch(scrPtr,
|
||||
wl_display_get_fd(ctx->display),
|
||||
wlclient_dispatch,
|
||||
ctx);
|
||||
|
||||
g_wlclient_ctx = ctx;
|
||||
return True;
|
||||
|
||||
fail:
|
||||
if (ctx->xkb_ctx) xkb_context_unref(ctx->xkb_ctx);
|
||||
if (ctx->wm_base) xdg_wm_base_destroy(ctx->wm_base);
|
||||
if (ctx->seat) wl_seat_destroy(ctx->seat);
|
||||
if (ctx->shm) wl_shm_destroy(ctx->shm);
|
||||
if (ctx->compositor) wl_compositor_destroy(ctx->compositor);
|
||||
if (ctx->registry) wl_registry_destroy(ctx->registry);
|
||||
if (ctx->display) wl_display_disconnect(ctx->display);
|
||||
wfree(ctx);
|
||||
return False;
|
||||
}
|
||||
|
||||
void
|
||||
W_WLClientShutdown(struct W_Screen *scrPtr)
|
||||
{
|
||||
(void)scrPtr;
|
||||
WLClientCtx *ctx = g_wlclient_ctx;
|
||||
if (!ctx) return;
|
||||
g_wlclient_ctx = NULL;
|
||||
|
||||
if (ctx->xkb_state) xkb_state_unref(ctx->xkb_state);
|
||||
if (ctx->xkb_keymap) xkb_keymap_unref(ctx->xkb_keymap);
|
||||
if (ctx->xkb_ctx) xkb_context_unref(ctx->xkb_ctx);
|
||||
if (ctx->pointer) wl_pointer_destroy(ctx->pointer);
|
||||
if (ctx->keyboard) wl_keyboard_destroy(ctx->keyboard);
|
||||
if (ctx->wm_base) xdg_wm_base_destroy(ctx->wm_base);
|
||||
if (ctx->seat) wl_seat_destroy(ctx->seat);
|
||||
if (ctx->shm) wl_shm_destroy(ctx->shm);
|
||||
if (ctx->compositor) wl_compositor_destroy(ctx->compositor);
|
||||
if (ctx->registry) wl_registry_destroy(ctx->registry);
|
||||
if (ctx->display) wl_display_disconnect(ctx->display);
|
||||
wfree(ctx);
|
||||
}
|
||||
|
||||
#else /* !USE_WAYLAND_CLIENT */
|
||||
|
||||
#include "WINGsP.h"
|
||||
|
||||
Bool W_WLClientInit(struct W_Screen *scrPtr, const char *display)
|
||||
{
|
||||
(void)scrPtr; (void)display;
|
||||
return False;
|
||||
}
|
||||
void W_WLClientShutdown(struct W_Screen *scrPtr) { (void)scrPtr; }
|
||||
|
||||
#endif /* USE_WAYLAND_CLIENT */
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
/* Generated by wayland-scanner 1.24.0 */
|
||||
|
||||
/*
|
||||
* Copyright © 2008-2013 Kristian Høgsberg
|
||||
* Copyright © 2013 Rafael Antognolli
|
||||
* Copyright © 2013 Jasper St. Pierre
|
||||
* Copyright © 2010-2013 Intel Corporation
|
||||
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
|
||||
* Copyright © 2015-2017 Red Hat Inc.
|
||||
*
|
||||
* 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_output_interface;
|
||||
extern const struct wl_interface wl_seat_interface;
|
||||
extern const struct wl_interface wl_surface_interface;
|
||||
extern const struct wl_interface xdg_popup_interface;
|
||||
extern const struct wl_interface xdg_positioner_interface;
|
||||
extern const struct wl_interface xdg_surface_interface;
|
||||
extern const struct wl_interface xdg_toplevel_interface;
|
||||
|
||||
static const struct wl_interface *xdg_shell_types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&xdg_positioner_interface,
|
||||
&xdg_surface_interface,
|
||||
&wl_surface_interface,
|
||||
&xdg_toplevel_interface,
|
||||
&xdg_popup_interface,
|
||||
&xdg_surface_interface,
|
||||
&xdg_positioner_interface,
|
||||
&xdg_toplevel_interface,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
&wl_output_interface,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
&xdg_positioner_interface,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_wm_base_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "create_positioner", "n", xdg_shell_types + 4 },
|
||||
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
|
||||
{ "pong", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_wm_base_events[] = {
|
||||
{ "ping", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_wm_base_interface = {
|
||||
"xdg_wm_base", 7,
|
||||
4, xdg_wm_base_requests,
|
||||
1, xdg_wm_base_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_positioner_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "set_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
|
||||
{ "set_anchor", "u", xdg_shell_types + 0 },
|
||||
{ "set_gravity", "u", xdg_shell_types + 0 },
|
||||
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
|
||||
{ "set_offset", "ii", xdg_shell_types + 0 },
|
||||
{ "set_reactive", "3", xdg_shell_types + 0 },
|
||||
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
|
||||
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
|
||||
"xdg_positioner", 7,
|
||||
10, xdg_positioner_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_surface_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "get_toplevel", "n", xdg_shell_types + 7 },
|
||||
{ "get_popup", "n?oo", xdg_shell_types + 8 },
|
||||
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
|
||||
{ "ack_configure", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_surface_events[] = {
|
||||
{ "configure", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_surface_interface = {
|
||||
"xdg_surface", 7,
|
||||
5, xdg_surface_requests,
|
||||
1, xdg_surface_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_toplevel_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "set_parent", "?o", xdg_shell_types + 11 },
|
||||
{ "set_title", "s", xdg_shell_types + 0 },
|
||||
{ "set_app_id", "s", xdg_shell_types + 0 },
|
||||
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
|
||||
{ "move", "ou", xdg_shell_types + 16 },
|
||||
{ "resize", "ouu", xdg_shell_types + 18 },
|
||||
{ "set_max_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_min_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_maximized", "", xdg_shell_types + 0 },
|
||||
{ "unset_maximized", "", xdg_shell_types + 0 },
|
||||
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
|
||||
{ "unset_fullscreen", "", xdg_shell_types + 0 },
|
||||
{ "set_minimized", "", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_toplevel_events[] = {
|
||||
{ "configure", "iia", xdg_shell_types + 0 },
|
||||
{ "close", "", xdg_shell_types + 0 },
|
||||
{ "configure_bounds", "4ii", xdg_shell_types + 0 },
|
||||
{ "wm_capabilities", "5a", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
|
||||
"xdg_toplevel", 7,
|
||||
14, xdg_toplevel_requests,
|
||||
4, xdg_toplevel_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_popup_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "grab", "ou", xdg_shell_types + 22 },
|
||||
{ "reposition", "3ou", xdg_shell_types + 24 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_popup_events[] = {
|
||||
{ "configure", "iiii", xdg_shell_types + 0 },
|
||||
{ "popup_done", "", xdg_shell_types + 0 },
|
||||
{ "repositioned", "3u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_popup_interface = {
|
||||
"xdg_popup", 7,
|
||||
3, xdg_popup_requests,
|
||||
3, xdg_popup_events,
|
||||
};
|
||||
|
||||
43
configure.ac
43
configure.ac
|
|
@ -680,6 +680,49 @@ AC_SUBST([WLROOTS_CFLAGS])
|
|||
AC_SUBST([WLROOTS_LIBS])
|
||||
|
||||
|
||||
dnl Wayland client support for WINGs (WPrefs and other native clients)
|
||||
dnl =================================================================
|
||||
dnl Allows building WINGs apps as native Wayland clients. Independent
|
||||
dnl from --enable-wayland-backend (which is only for the compositor).
|
||||
m4_divert_push([INIT_PREPARE])dnl
|
||||
AC_ARG_ENABLE([wayland-client],
|
||||
[AS_HELP_STRING([--enable-wayland-client],
|
||||
[build WINGs with Wayland client support so apps like WPrefs run native @<:@default=auto@:>@])],
|
||||
[AS_CASE(["$enableval"],
|
||||
[yes|no|auto], [],
|
||||
[AC_MSG_ERROR([bad value $enableval for --enable-wayland-client])])],
|
||||
[enable_wayland_client=auto])
|
||||
m4_divert_pop([INIT_PREPARE])dnl
|
||||
|
||||
AS_IF([test "x$enable_wayland_client" != "xno"],
|
||||
[PKG_CHECK_MODULES([WAYLAND_CLIENT],
|
||||
[wayland-client xkbcommon],
|
||||
[PKG_CHECK_EXISTS([wayland-protocols >= 1.20],
|
||||
[have_wayland_client=yes
|
||||
WAYLAND_PROTOCOLS_DIR=`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`
|
||||
WAYLAND_SCANNER=`$PKG_CONFIG --variable=wayland_scanner wayland-scanner 2>/dev/null`
|
||||
AS_IF([test -z "$WAYLAND_SCANNER"],
|
||||
[AC_PATH_PROG([WAYLAND_SCANNER], [wayland-scanner], [no])])
|
||||
AS_IF([test "x$WAYLAND_SCANNER" = "xno" -o -z "$WAYLAND_SCANNER"],
|
||||
[have_wayland_client=no])],
|
||||
[have_wayland_client=no])],
|
||||
[have_wayland_client=no])
|
||||
AS_IF([test "x$have_wayland_client" = "xyes"],
|
||||
[AC_DEFINE([USE_WAYLAND_CLIENT], [1],
|
||||
[Define to 1 to build WINGs with Wayland client support])
|
||||
supported_core="$supported_core WaylandClient"],
|
||||
[AS_IF([test "x$enable_wayland_client" = "xyes"],
|
||||
[AC_MSG_ERROR([wayland-client, xkbcommon, wayland-protocols, or wayland-scanner not found])])
|
||||
unsupported="$unsupported WaylandClient"])],
|
||||
[have_wayland_client=no
|
||||
unsupported="$unsupported WaylandClient"])
|
||||
AM_CONDITIONAL([USE_WAYLAND_CLIENT], [test "x$have_wayland_client" = "xyes"])
|
||||
AC_SUBST([WAYLAND_CLIENT_CFLAGS])
|
||||
AC_SUBST([WAYLAND_CLIENT_LIBS])
|
||||
AC_SUBST([WAYLAND_PROTOCOLS_DIR])
|
||||
AC_SUBST([WAYLAND_SCANNER])
|
||||
|
||||
|
||||
dnl Math library
|
||||
dnl ============
|
||||
dnl libWINGS uses math functions, check whether usage requires linking
|
||||
|
|
|
|||
Loading…
Reference in New Issue