From 66fbda954295030971891b3fd07c165479f43806 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Tue, 21 Jan 2025 08:44:24 +0800 Subject: [PATCH] Display (Linux): return reason if errored --- .../linux/wayland/global-output.c | 26 +++++++++---- .../displayserver/linux/wayland/kde-output.c | 39 ++++++++++++++----- .../displayserver/linux/wayland/wayland.c | 9 +++-- .../displayserver/linux/wayland/wayland.h | 10 ++--- .../displayserver/linux/wayland/zwlr-output.c | 18 +++++++-- 5 files changed, 74 insertions(+), 28 deletions(-) diff --git a/src/detection/displayserver/linux/wayland/global-output.c b/src/detection/displayserver/linux/wayland/global-output.c index 8b3671d16..206dc14f2 100644 --- a/src/detection/displayserver/linux/wayland/global-output.c +++ b/src/detection/displayserver/linux/wayland/global-output.c @@ -78,11 +78,11 @@ static struct zxdg_output_v1_listener zxdgOutputListener = { .description = (void*) ffWaylandOutputDescriptionListener, }; -void 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); if(output == NULL) - return; + return "Failed to create wl_output"; WaylandDisplay display = { .parent = wldata, @@ -94,8 +94,16 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist .edidName = ffStrbufCreate(), }; - wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, &display); - wldata->ffwl_display_roundtrip(wldata->display); + if (wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, &display) < 0) + { + wldata->ffwl_proxy_destroy(output); + return "Failed to add listener to wl_output"; + } + if (wldata->ffwl_display_roundtrip(wldata->display) < 0) + { + wldata->ffwl_proxy_destroy(output); + return "Failed to roundtrip wl_output"; + } if (wldata->zxdgOutputManager) { @@ -112,7 +120,7 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist wldata->ffwl_proxy_destroy(output); if(display.width <= 0 || display.height <= 0) - return; + return "Failed to get display information from wl_output"; uint32_t rotation = ffWaylandHandleRotation(&display); @@ -156,15 +164,19 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist ffStrbufDestroy(&display.description); ffStrbufDestroy(&display.name); ffStrbufDestroy(&display.edidName); + + return NULL; } -void 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); if(manager == NULL) - return; + return "Failed to create zxdg_output_manager_v1"; wldata->zxdgOutputManager = manager; + + return NULL; } #endif diff --git a/src/detection/displayserver/linux/wayland/kde-output.c b/src/detection/displayserver/linux/wayland/kde-output.c index 4f7d8ece1..70dcb9108 100644 --- a/src/detection/displayserver/linux/wayland/kde-output.c +++ b/src/detection/displayserver/linux/wayland/kde-output.c @@ -167,11 +167,11 @@ static struct kde_output_device_v2_listener outputListener = { .dimming = (void*) stubListener, }; -void 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); if(output == NULL) - return; + return "Failed to create kde_output_device_v2"; FF_LIST_AUTO_DESTROY modes = ffListCreate(sizeof(WaylandKdeMode)); WaylandDisplay display = { @@ -185,12 +185,21 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, .internal = &modes, }; - wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, &display); - wldata->ffwl_display_roundtrip(wldata->display); + if (wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, &display) < 0) + { + wldata->ffwl_proxy_destroy(output); + return "Failed to add listener to kde_output_device_v2"; + } + + if (wldata->ffwl_display_roundtrip(wldata->display) < 0) + { + wldata->ffwl_proxy_destroy(output); + return "Failed to roundtrip kde_output_device_v2"; + } wldata->ffwl_proxy_destroy(output); if(display.width <= 0 || display.height <= 0 || !display.internal) - return; + return "Failed to get display information from kde_output_device_v2"; uint32_t rotation = ffWaylandHandleRotation(&display); @@ -233,6 +242,8 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, ffStrbufDestroy(&display.description); ffStrbufDestroy(&display.name); ffStrbufDestroy(&display.edidName); + + return NULL; } @@ -243,20 +254,30 @@ static void waylandKdeOutputOrderListener(void *data, FF_MAYBE_UNUSED struct kde *id = ffWaylandGenerateIdFromName(output_name); } -void ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) +const char* 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; + return "Failed to create kde_output_order_v1"; 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); + if (wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &orderListener, &wldata->primaryDisplayId) < 0) + { + wldata->ffwl_proxy_destroy(output); + return "Failed to add listener to kde_output_order_v1"; + } + if (wldata->ffwl_display_roundtrip(wldata->display) < 0) + { + wldata->ffwl_proxy_destroy(output); + return "Failed to roundtrip kde_output_order_v1"; + } wldata->ffwl_proxy_destroy(output); + + return NULL; } #endif diff --git a/src/detection/displayserver/linux/wayland/wayland.c b/src/detection/displayserver/linux/wayland/wayland.c index d19e3733c..b2cdb3da8 100644 --- a/src/detection/displayserver/linux/wayland/wayland.c +++ b/src/detection/displayserver/linux/wayland/wayland.c @@ -80,17 +80,20 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u if((wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_NONE || wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_GLOBAL) && ffStrEquals(interface, wldata->ffwl_output_interface->name)) { wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_GLOBAL; - ffWaylandHandleGlobalOutput(wldata, registry, name, version); + if (ffWaylandHandleGlobalOutput(wldata, registry, name, version) != NULL) + wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_NONE; } else if((wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_NONE || wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_ZWLR) && ffStrEquals(interface, zwlr_output_manager_v1_interface.name)) { wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_ZWLR; - ffWaylandHandleZwlrOutput(wldata, registry, name, version); + if (ffWaylandHandleZwlrOutput(wldata, registry, name, version) != NULL) + wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_NONE; } else if((wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_NONE || wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_KDE) && ffStrEquals(interface, kde_output_device_v2_interface.name)) { wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_KDE; - ffWaylandHandleKdeOutput(wldata, registry, name, version); + if (ffWaylandHandleKdeOutput(wldata, registry, name, version) != NULL) + wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_NONE; } else if(ffStrEquals(interface, kde_output_order_v1_interface.name)) { diff --git a/src/detection/displayserver/linux/wayland/wayland.h b/src/detection/displayserver/linux/wayland/wayland.h index ab11d0538..a509e4386 100644 --- a/src/detection/displayserver/linux/wayland/wayland.h +++ b/src/detection/displayserver/linux/wayland/wayland.h @@ -79,10 +79,10 @@ void ffWaylandOutputDescriptionListener(void* data, FF_MAYBE_UNUSED void* output // Modifies content of display. Don't call this function when calling ffdsAppendDisplay uint32_t ffWaylandHandleRotation(WaylandDisplay* display); -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); -void ffWaylandHandleZxdgOutput(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); +const char* ffWaylandHandleZwlrOutput(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); +const char* ffWaylandHandleKdeOutputOrder(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); #endif diff --git a/src/detection/displayserver/linux/wayland/zwlr-output.c b/src/detection/displayserver/linux/wayland/zwlr-output.c index a19ec9fb6..560a19478 100644 --- a/src/detection/displayserver/linux/wayland/zwlr-output.c +++ b/src/detection/displayserver/linux/wayland/zwlr-output.c @@ -188,11 +188,11 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output wldata->ffwl_proxy_destroy((void*) head); } -void ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) +const char* ffWaylandHandleZwlrOutput(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, &zwlr_output_manager_v1_interface, version, name, zwlr_output_manager_v1_interface.name, version, NULL); if(output == NULL) - return; + return "Failed to bind zwlr_output_manager_v1"; const struct zwlr_output_manager_v1_listener outputListener = { .head = waylandHandleZwlrHead, @@ -200,9 +200,19 @@ void ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry .finished = (void*) stubListener, }; - wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, wldata); - wldata->ffwl_display_roundtrip(wldata->display); + if (wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, wldata) < 0) + { + wldata->ffwl_proxy_destroy(output); + return "Failed to add listener to zwlr_output_manager_v1"; + } + if (wldata->ffwl_display_roundtrip(wldata->display) < 0) + { + wldata->ffwl_proxy_destroy(output); + return "Failed to roundtrip display"; + } wldata->ffwl_proxy_destroy(output); + + return NULL; } #endif