diff --git a/CMakeLists.txt b/CMakeLists.txt index 52407a14b..34283d122 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -433,6 +433,7 @@ if(LINUX) src/detection/displayserver/linux/wayland/kde-output.c src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c + src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c src/detection/displayserver/linux/wmde.c src/detection/displayserver/linux/xcb.c src/detection/displayserver/linux/xlib.c @@ -568,6 +569,7 @@ elseif(BSD) src/detection/displayserver/linux/wayland/kde-output.c src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c + src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c src/detection/displayserver/linux/wmde.c src/detection/displayserver/linux/xcb.c src/detection/displayserver/linux/xlib.c @@ -771,6 +773,7 @@ elseif(SunOS) src/detection/displayserver/linux/wayland/kde-output.c src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c + src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c src/detection/displayserver/linux/wmde.c src/detection/displayserver/linux/xcb.c src/detection/displayserver/linux/xlib.c diff --git a/src/detection/displayserver/linux/wayland/global-output.c b/src/detection/displayserver/linux/wayland/global-output.c index 050f1b0de..4b17271e0 100644 --- a/src/detection/displayserver/linux/wayland/global-output.c +++ b/src/detection/displayserver/linux/wayland/global-output.c @@ -124,7 +124,7 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist : &display.name, display.type, false, - 0 + display.id ); ffStrbufDestroy(&display.description); diff --git a/src/detection/displayserver/linux/wayland/kde-output-order-v1-client-protocol.h b/src/detection/displayserver/linux/wayland/kde-output-order-v1-client-protocol.h new file mode 100644 index 000000000..776e51de6 --- /dev/null +++ b/src/detection/displayserver/linux/wayland/kde-output-order-v1-client-protocol.h @@ -0,0 +1,133 @@ +/* Generated by wayland-scanner 1.22.0 */ + +#ifndef KDE_OUTPUT_ORDER_V1_CLIENT_PROTOCOL_H +#define KDE_OUTPUT_ORDER_V1_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_kde_output_order_v1 The kde_output_order_v1 protocol + * @section page_ifaces_kde_output_order_v1 Interfaces + * - @subpage page_iface_kde_output_order_v1 - announce order of outputs + * @section page_copyright_kde_output_order_v1 Copyright + *
+ *
+ * SPDX-FileCopyrightText: 2022 Xaver Hugl 
+ *
+ * SPDX-License-Identifier: MIT-CMU
+ * 
+ */ +struct kde_output_order_v1; + +#ifndef KDE_OUTPUT_ORDER_V1_INTERFACE +#define KDE_OUTPUT_ORDER_V1_INTERFACE +/** + * @page page_iface_kde_output_order_v1 kde_output_order_v1 + * @section page_iface_kde_output_order_v1_desc Description + * + * Announce the order in which desktop environment components should be placed on outputs. + * The compositor will send the list of outputs when the global is bound and whenever there is a change. + * @section page_iface_kde_output_order_v1_api API + * See @ref iface_kde_output_order_v1. + */ +/** + * @defgroup iface_kde_output_order_v1 The kde_output_order_v1 interface + * + * Announce the order in which desktop environment components should be placed on outputs. + * The compositor will send the list of outputs when the global is bound and whenever there is a change. + */ +extern const struct wl_interface kde_output_order_v1_interface; +#endif + +/** + * @ingroup iface_kde_output_order_v1 + * @struct kde_output_order_v1_listener + */ +struct kde_output_order_v1_listener { + /** + * output name + * + * Specifies the output identified by their wl_output.name. + * @param output_name the name of the output + */ + void (*output)(void *data, + struct kde_output_order_v1 *kde_output_order_v1, + const char *output_name); + /** + * done + * + * Specifies that the output list is complete. On the next output + * event, a new list begins. + */ + void (*done)(void *data, + struct kde_output_order_v1 *kde_output_order_v1); +}; + +/** + * @ingroup iface_kde_output_order_v1 + */ +static inline int +kde_output_order_v1_add_listener(struct kde_output_order_v1 *kde_output_order_v1, + const struct kde_output_order_v1_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) kde_output_order_v1, + (void (**)(void)) listener, data); +} + +#define KDE_OUTPUT_ORDER_V1_DESTROY 0 + +/** + * @ingroup iface_kde_output_order_v1 + */ +#define KDE_OUTPUT_ORDER_V1_OUTPUT_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_order_v1 + */ +#define KDE_OUTPUT_ORDER_V1_DONE_SINCE_VERSION 1 + +/** + * @ingroup iface_kde_output_order_v1 + */ +#define KDE_OUTPUT_ORDER_V1_DESTROY_SINCE_VERSION 1 + +/** @ingroup iface_kde_output_order_v1 */ +static inline void +kde_output_order_v1_set_user_data(struct kde_output_order_v1 *kde_output_order_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) kde_output_order_v1, user_data); +} + +/** @ingroup iface_kde_output_order_v1 */ +static inline void * +kde_output_order_v1_get_user_data(struct kde_output_order_v1 *kde_output_order_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) kde_output_order_v1); +} + +static inline uint32_t +kde_output_order_v1_get_version(struct kde_output_order_v1 *kde_output_order_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) kde_output_order_v1); +} + +/** + * @ingroup iface_kde_output_order_v1 + */ +static inline void +kde_output_order_v1_destroy(struct kde_output_order_v1 *kde_output_order_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) kde_output_order_v1, + KDE_OUTPUT_ORDER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) kde_output_order_v1), WL_MARSHAL_FLAG_DESTROY); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c b/src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c new file mode 100644 index 000000000..c7cf90f34 --- /dev/null +++ b/src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c @@ -0,0 +1,35 @@ +#ifdef FF_HAVE_WAYLAND + +/* Generated by wayland-scanner 1.22.0 */ + +/* + * SPDX-FileCopyrightText: 2022 Xaver Hugl + * + * SPDX-License-Identifier: MIT-CMU + */ + +#include +#include +#include "wayland-util.h" + + +static const struct wl_interface *kde_output_order_v1_types[] = { + NULL, +}; + +static const struct wl_message kde_output_order_v1_requests[] = { + { "destroy", "", kde_output_order_v1_types + 0 }, +}; + +static const struct wl_message kde_output_order_v1_events[] = { + { "output", "s", kde_output_order_v1_types + 0 }, + { "done", "", kde_output_order_v1_types + 0 }, +}; + +WL_EXPORT const struct wl_interface kde_output_order_v1_interface = { + "kde_output_order_v1", 1, + 1, kde_output_order_v1_requests, + 2, kde_output_order_v1_events, +}; + +#endif diff --git a/src/detection/displayserver/linux/wayland/kde-output.c b/src/detection/displayserver/linux/wayland/kde-output.c index 07ad91a65..d638a3ec3 100644 --- a/src/detection/displayserver/linux/wayland/kde-output.c +++ b/src/detection/displayserver/linux/wayland/kde-output.c @@ -2,6 +2,7 @@ #include "wayland.h" #include "kde-output-device-v2-client-protocol.h" +#include "kde-output-order-v1-client-protocol.h" #include "util/edidHelper.h" #include "util/base64.h" @@ -214,7 +215,7 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, : &display.name, display.type, false, - 0 + display.id ); ffStrbufDestroy(&display.description); @@ -222,4 +223,28 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, ffStrbufDestroy(&display.edidName); } + +static void waylandKdeOutputOrderListener(void *data, FF_MAYBE_UNUSED struct kde_output_order_v1 *_, const char *output_name) +{ + uint64_t* id = (uint64_t*) data; + if (*id == 0) + strncpy((char*) id, output_name, sizeof(*id)); +} + +void ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) +{ + struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &kde_output_order_v1_interface, version, name, kde_output_order_v1_interface.name, version, NULL); + if(output == NULL) + return; + + struct kde_output_order_v1_listener orderListener = { + .output = waylandKdeOutputOrderListener, + .done = (void*) stubListener, + }; + + wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &orderListener, &wldata->primaryDisplayId); + wldata->ffwl_display_roundtrip(wldata->display); + wldata->ffwl_proxy_destroy(output); +} + #endif diff --git a/src/detection/displayserver/linux/wayland/wayland.c b/src/detection/displayserver/linux/wayland/wayland.c index 9479e7ba8..708aaff02 100644 --- a/src/detection/displayserver/linux/wayland/wayland.c +++ b/src/detection/displayserver/linux/wayland/wayland.c @@ -12,6 +12,7 @@ #include "wayland.h" #include "wlr-output-management-unstable-v1-client-protocol.h" #include "kde-output-device-v2-client-protocol.h" +#include "kde-output-order-v1-client-protocol.h" #ifndef __FreeBSD__ static void waylandDetectWM(int fd, FFDisplayServerResult* result) @@ -53,6 +54,10 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_KDE; ffWaylandHandleKdeOutput(wldata, registry, name, version); } + else if(ffStrEquals(interface, kde_output_order_v1_interface.name)) + { + ffWaylandHandleKdeOutputOrder(wldata, registry, name, version); + } } bool detectWayland(FFDisplayServerResult* result) @@ -99,6 +104,18 @@ bool detectWayland(FFDisplayServerResult* result) data.ffwl_proxy_destroy(registry); ffwl_display_disconnect(data.display); + if(data.primaryDisplayId) + { + FF_LIST_FOR_EACH(FFDisplayResult, d, data.result->displays) + { + if(d->id == data.primaryDisplayId) + { + d->primary = true; + break; + } + } + } + //We successfully connected to wayland and detected the display. //So we can set set the session type to wayland. //This is used as an indicator that we are running wayland by the x11 backends. @@ -115,6 +132,7 @@ void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const display->type = FF_DISPLAY_TYPE_EXTERNAL; if (!display->edidName.length) ffdsMatchDrmConnector(name, &display->edidName); + strncpy((char*) &display->id, name, sizeof(display->id)); ffStrbufAppendS(&display->name, name); } diff --git a/src/detection/displayserver/linux/wayland/wayland.h b/src/detection/displayserver/linux/wayland/wayland.h index ada81ab01..f972c0323 100644 --- a/src/detection/displayserver/linux/wayland/wayland.h +++ b/src/detection/displayserver/linux/wayland/wayland.h @@ -27,6 +27,7 @@ typedef struct WaylandData struct wl_display* display; const struct wl_interface* ffwl_output_interface; WaylandProtocolType protocolType; + uint64_t primaryDisplayId; } WaylandData; typedef struct WaylandDisplay @@ -41,6 +42,7 @@ typedef struct WaylandDisplay FFstrbuf name; FFstrbuf description; FFstrbuf edidName; + uint64_t id; void* internal; } WaylandDisplay; @@ -55,5 +57,6 @@ void ffWaylandOutputDescriptionListener(void* data, FF_MAYBE_UNUSED void* output void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); void ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); +void ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); #endif diff --git a/src/detection/displayserver/linux/wayland/zwlr-output.c b/src/detection/displayserver/linux/wayland/zwlr-output.c index 2071bfa52..63ab7146c 100644 --- a/src/detection/displayserver/linux/wayland/zwlr-output.c +++ b/src/detection/displayserver/linux/wayland/zwlr-output.c @@ -160,7 +160,7 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output : &display.name, display.type, false, - 0 + display.id ); ffStrbufDestroy(&display.description);