DisplayServer (Linux): binds minimal version to avoid breakage

This commit is contained in:
Carter Li
2026-05-10 15:36:52 +08:00
parent fbc9569e13
commit b37f020270
4 changed files with 30 additions and 25 deletions
@@ -71,7 +71,9 @@ static struct zxdg_output_v1_listener zxdgOutputListener = {
}; };
const char* ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) { const char* ffWaylandHandleGlobalOutput(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, wldata->ffwl_output_interface, version, name, wldata->ffwl_output_interface->name, version, NULL); const char* api = "wayland-global";
uint32_t bindVersion = min(version, WL_OUTPUT_DESCRIPTION_SINCE_VERSION);
struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, wldata->ffwl_output_interface, bindVersion, name, wldata->ffwl_output_interface->name, bindVersion, NULL);
if (output == NULL) { if (output == NULL) {
return "Failed to create wl_output"; return "Failed to create wl_output";
} }
@@ -95,12 +97,14 @@ const char* ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry*
} }
if (wldata->zxdgOutputManager) { if (wldata->zxdgOutputManager) {
struct wl_proxy* zxdgOutput = wldata->ffwl_proxy_marshal_constructor_versioned(wldata->zxdgOutputManager, ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT, &zxdg_output_v1_interface, version, NULL, output); uint32_t bindVersion = min(version, ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION);
struct wl_proxy* zxdgOutput = wldata->ffwl_proxy_marshal_constructor_versioned(wldata->zxdgOutputManager, ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT, &zxdg_output_v1_interface, bindVersion, NULL, output);
if (zxdgOutput) { if (zxdgOutput) {
wldata->ffwl_proxy_add_listener(zxdgOutput, (void (**)(void)) &zxdgOutputListener, &display); wldata->ffwl_proxy_add_listener(zxdgOutput, (void (**)(void)) &zxdgOutputListener, &display);
wldata->ffwl_display_roundtrip(wldata->display); wldata->ffwl_display_roundtrip(wldata->display);
wldata->ffwl_proxy_destroy(zxdgOutput); wldata->ffwl_proxy_destroy(zxdgOutput);
api = "wayland-global-zxdg";
} }
} }
@@ -132,7 +136,7 @@ const char* ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry*
display.id, display.id,
(uint32_t) display.physicalWidth, (uint32_t) display.physicalWidth,
(uint32_t) display.physicalHeight, (uint32_t) display.physicalHeight,
"wayland-global"); api);
if (item) { if (item) {
if (display.hdrSupported) { if (display.hdrSupported) {
item->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED; item->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED;
@@ -155,7 +159,8 @@ const char* ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry*
} }
const char* ffWaylandHandleZxdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) { const char* ffWaylandHandleZxdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) {
struct wl_proxy* manager = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &zxdg_output_manager_v1_interface, version, name, zxdg_output_manager_v1_interface.name, version, NULL); uint32_t bindVersion = min(version, ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT_SINCE_VERSION);
struct wl_proxy* manager = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &zxdg_output_manager_v1_interface, bindVersion, name, zxdg_output_manager_v1_interface.name, bindVersion, NULL);
if (manager == NULL) { if (manager == NULL) {
return "Failed to create zxdg_output_manager_v1"; return "Failed to create zxdg_output_manager_v1";
} }
@@ -176,17 +176,11 @@ static struct kde_output_device_v2_listener outputListener = {
.max_bits_per_color_range = (void*) stubListener, .max_bits_per_color_range = (void*) stubListener,
.automatic_max_bits_per_color_limit = (void*) stubListener, .automatic_max_bits_per_color_limit = (void*) stubListener,
.edr_policy = (void*) stubListener, .edr_policy = (void*) stubListener,
.sharpness = (void*) stubListener,
.priority = (void*) stubListener,
.auto_brightness = (void*) stubListener,
.removed = (void*) stubListener,
.hdr_icc_profile_path = (void*) stubListener,
.hdr_color_profile_source = (void*) stubListener,
.abm_level = (void*) stubListener,
}; };
const char* ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) { const char* ffWaylandHandleKdeOutput(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_device_v2_interface, version, name, kde_output_device_v2_interface.name, version, NULL); uint32_t bindVersion = min(version, KDE_OUTPUT_DEVICE_V2_MAX_BITS_PER_COLOR_SINCE_VERSION);
struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &kde_output_device_v2_interface, bindVersion, name, kde_output_device_v2_interface.name, bindVersion, NULL);
if (output == NULL) { if (output == NULL) {
return "Failed to create kde_output_device_v2"; return "Failed to create kde_output_device_v2";
} }
@@ -268,17 +262,18 @@ static void waylandKdeOutputOrderListener(void* data, FF_A_UNUSED struct kde_out
} }
} }
const char* ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) { static const struct kde_output_order_v1_listener orderListener = {
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 "Failed to create kde_output_order_v1";
}
struct kde_output_order_v1_listener orderListener = {
.output = waylandKdeOutputOrderListener, .output = waylandKdeOutputOrderListener,
.done = (void*) stubListener, .done = (void*) stubListener,
}; };
const char* ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) {
uint32_t bindVersion = min(version, KDE_OUTPUT_ORDER_V1_OUTPUT_SINCE_VERSION);
struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &kde_output_order_v1_interface, bindVersion, name, kde_output_order_v1_interface.name, bindVersion, NULL);
if (output == NULL) {
return "Failed to create kde_output_order_v1";
}
if (wldata->ffwl_proxy_add_listener(output, (void (**)(void)) &orderListener, &wldata->primaryDisplayId) < 0) { if (wldata->ffwl_proxy_add_listener(output, (void (**)(void)) &orderListener, &wldata->primaryDisplayId) < 0) {
wldata->ffwl_proxy_destroy(output); wldata->ffwl_proxy_destroy(output);
return "Failed to add listener to kde_output_order_v1"; return "Failed to add listener to kde_output_order_v1";
@@ -9,6 +9,10 @@
#include "../displayserver_linux.h" #include "../displayserver_linux.h"
static inline uint32_t min(uint32_t a, uint32_t b) {
return a < b ? a : b;
}
typedef enum FF_A_PACKED WaylandProtocolType { typedef enum FF_A_PACKED WaylandProtocolType {
FF_WAYLAND_PROTOCOL_TYPE_NONE, FF_WAYLAND_PROTOCOL_TYPE_NONE,
FF_WAYLAND_PROTOCOL_TYPE_GLOBAL, FF_WAYLAND_PROTOCOL_TYPE_GLOBAL,
@@ -183,18 +183,19 @@ static void waylandHandleZwlrHead(void* data, FF_A_UNUSED struct zwlr_output_man
wldata->ffwl_proxy_destroy((void*) head); wldata->ffwl_proxy_destroy((void*) head);
} }
const char* ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) { static const struct zwlr_output_manager_v1_listener outputListener = {
struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &zwlr_output_manager_v1_interface, version, name, zwlr_output_manager_v1_interface.name, version, NULL);
if (output == NULL) {
return "Failed to bind zwlr_output_manager_v1";
}
const struct zwlr_output_manager_v1_listener outputListener = {
.head = waylandHandleZwlrHead, .head = waylandHandleZwlrHead,
.done = (void*) stubListener, .done = (void*) stubListener,
.finished = (void*) stubListener, .finished = (void*) stubListener,
}; };
const char* ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) {
uint32_t bindVersion = min(version, ZWLR_OUTPUT_MANAGER_V1_HEAD_SINCE_VERSION);
struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &zwlr_output_manager_v1_interface, bindVersion, name, zwlr_output_manager_v1_interface.name, bindVersion, NULL);
if (output == NULL) {
return "Failed to bind zwlr_output_manager_v1";
}
if (wldata->ffwl_proxy_add_listener(output, (void (**)(void)) &outputListener, wldata) < 0) { if (wldata->ffwl_proxy_add_listener(output, (void (**)(void)) &outputListener, wldata) < 0) {
wldata->ffwl_proxy_destroy(output); wldata->ffwl_proxy_destroy(output);
return "Failed to add listener to zwlr_output_manager_v1"; return "Failed to add listener to zwlr_output_manager_v1";