From 37b8bb4fc01d998af41807543f8c95d5f5990a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 13 Mar 2026 17:46:39 +0800 Subject: [PATCH] DisplayServer: reports DPI instead of scaled resolution Fixes #2224 --- src/detection/displayserver/displayserver.c | 6 ++-- src/detection/displayserver/displayserver.h | 6 ++-- .../displayserver/displayserver_android.c | 6 ++-- .../displayserver/displayserver_apple.c | 10 +++--- .../displayserver/displayserver_haiku.cpp | 4 +-- .../displayserver/displayserver_windows.c | 22 ++++++------- .../displayserver/linux/displayserver_linux.c | 2 +- src/detection/displayserver/linux/drm.c | 4 +-- .../linux/wayland/global-output.c | 8 ++--- .../displayserver/linux/wayland/kde-output.c | 6 ++-- .../displayserver/linux/wayland/wayland.h | 2 +- .../displayserver/linux/wayland/zwlr-output.c | 6 ++-- src/detection/displayserver/linux/xcb.c | 27 +++++++--------- src/detection/displayserver/linux/xlib.c | 31 +++++++++---------- src/modules/display/display.c | 25 +++++++++------ 15 files changed, 76 insertions(+), 89 deletions(-) diff --git a/src/detection/displayserver/displayserver.c b/src/detection/displayserver/displayserver.c index 5da347401..d8b7ac3ba 100644 --- a/src/detection/displayserver/displayserver.c +++ b/src/detection/displayserver/displayserver.c @@ -5,8 +5,7 @@ FFDisplayResult* ffdsAppendDisplay( uint32_t width, uint32_t height, double refreshRate, - uint32_t scaledWidth, - uint32_t scaledHeight, + uint32_t dpi, uint32_t preferredWidth, uint32_t preferredHeight, double preferredRefreshRate, @@ -26,8 +25,7 @@ FFDisplayResult* ffdsAppendDisplay( display->width = width; display->height = height; display->refreshRate = refreshRate; - display->scaledWidth = scaledWidth; - display->scaledHeight = scaledHeight; + display->dpi = dpi ?: 96; // 0 means unknown display->preferredWidth = preferredWidth; display->preferredHeight = preferredHeight; display->preferredRefreshRate = preferredRefreshRate; diff --git a/src/detection/displayserver/displayserver.h b/src/detection/displayserver/displayserver.h index 54788cfaa..81f754bea 100644 --- a/src/detection/displayserver/displayserver.h +++ b/src/detection/displayserver/displayserver.h @@ -72,8 +72,7 @@ typedef struct FFDisplayResult uint32_t width; // in px uint32_t height; // in px double refreshRate; // in Hz - uint32_t scaledWidth; // in px - uint32_t scaledHeight; // in px + uint32_t dpi; // Base 96 uint32_t preferredWidth; // in px uint32_t preferredHeight; // in px double preferredRefreshRate; // in Hz @@ -110,8 +109,7 @@ FFDisplayResult* ffdsAppendDisplay( uint32_t width, uint32_t height, double refreshRate, - uint32_t scaledWidth, - uint32_t scaledHeight, + uint32_t dpi, uint32_t preferredWidth, uint32_t preferredHeight, double preferredRefreshRate, diff --git a/src/detection/displayserver/displayserver_android.c b/src/detection/displayserver/displayserver_android.c index d90e7bd02..a0eb7192e 100644 --- a/src/detection/displayserver/displayserver_android.c +++ b/src/detection/displayserver/displayserver_android.c @@ -85,7 +85,7 @@ static void detectWithDumpsys(FFDisplayServerResult* ds) FFDisplayResult* display = ffdsAppendDisplay(ds, (uint32_t)width, (uint32_t)height, refreshRate, - 0, 0, + 0, 0, 0, 0, 0, @@ -117,11 +117,11 @@ static bool detectWithGetprop(FFDisplayServerResult* ds) ffStrbufSubstrAfterFirstC(&buffer, ','); uint32_t height = (uint32_t) ffStrbufToUInt(&buffer, 0); ffStrbufSubstrAfterFirstC(&buffer, ','); - double scaleFactor = (double) ffStrbufToUInt(&buffer, 0) / 160.; + uint32_t dpi = (uint32_t) ffStrbufToUInt(&buffer, 0) * 96 / 160; FFDisplayResult* display = ffdsAppendDisplay(ds, width, height, 0, - (uint32_t) (width / scaleFactor + .5), (uint32_t) (height / scaleFactor + .5), + dpi, 0, 0, 0, 0, diff --git a/src/detection/displayserver/displayserver_apple.c b/src/detection/displayserver/displayserver_apple.c index 7f34bfb73..83444892c 100644 --- a/src/detection/displayserver/displayserver_apple.c +++ b/src/detection/displayserver/displayserver_apple.c @@ -116,12 +116,14 @@ static void detectDisplays(FFDisplayServerResult* ds) physicalHeight = (uint32_t) (size.height + 0.5); } + uint32_t pixelWidth = (uint32_t) CGDisplayModeGetPixelWidth(mode); + uint32_t pixelHeight = (uint32_t) CGDisplayModeGetPixelHeight(mode); + FFDisplayResult* display = ffdsAppendDisplay(ds, - (uint32_t)CGDisplayModeGetPixelWidth(mode), - (uint32_t)CGDisplayModeGetPixelHeight(mode), + pixelWidth, + pixelHeight, refreshRate, - (uint32_t)CGDisplayModeGetWidth(mode), - (uint32_t)CGDisplayModeGetHeight(mode), + pixelHeight * 96 / (uint32_t)CGDisplayModeGetHeight(mode), preferredWidth, preferredHeight, preferredRefreshRate, diff --git a/src/detection/displayserver/displayserver_haiku.cpp b/src/detection/displayserver/displayserver_haiku.cpp index 438bfb09f..05ad64f41 100644 --- a/src/detection/displayserver/displayserver_haiku.cpp +++ b/src/detection/displayserver/displayserver_haiku.cpp @@ -37,13 +37,11 @@ static void detectDisplays(FFDisplayServerResult* ds) uint32_t width = (uint32_t) s.Frame().Width() + 1; uint32_t height = (uint32_t) (uint32_t)s.Frame().Height() + 1; - double scaleFactor = (double) 1.0; FFDisplayResult* res = ffdsAppendDisplay(ds, width, height, (double)mode.timing.pixel_clock * 1000 / (mode.timing.v_total * mode.timing.h_total), - (uint32_t) (width / scaleFactor + .5), - (uint32_t) (height / scaleFactor + .5), + 0, 0, 0, 0, diff --git a/src/detection/displayserver/displayserver_windows.c b/src/detection/displayserver/displayserver_windows.c index 62555339f..4351ebc0f 100644 --- a/src/detection/displayserver/displayserver_windows.c +++ b/src/detection/displayserver/displayserver_windows.c @@ -93,17 +93,6 @@ static void detectDisplays(FFDisplayServerResult* ds) uint32_t width = sourceMode->width; uint32_t height = sourceMode->height; - if (path->targetInfo.rotation == DISPLAYCONFIG_ROTATION_ROTATE90 || - path->targetInfo.rotation == DISPLAYCONFIG_ROTATION_ROTATE270) - { - uint32_t temp = width; - width = height; - height = temp; - temp = physicalWidth; - physicalWidth = physicalHeight; - physicalHeight = temp; - } - uint32_t rotation; switch (path->targetInfo.rotation) { @@ -144,12 +133,19 @@ static void detectDisplays(FFDisplayServerResult* ds) ReleaseDC(NULL, hdc); } + if (path->targetInfo.rotation == DISPLAYCONFIG_ROTATION_ROTATE90 || + path->targetInfo.rotation == DISPLAYCONFIG_ROTATION_ROTATE270) + { + uint32_t temp = width; + width = height; + height = temp; + } + FFDisplayResult* display = ffdsAppendDisplay(ds, width, height, path->targetInfo.refreshRate.Numerator / (double) path->targetInfo.refreshRate.Denominator, - width * 96 / systemDpi, - height * 96 / systemDpi, + systemDpi, preferredMode.width, preferredMode.height, preferredRefreshRate, diff --git a/src/detection/displayserver/linux/displayserver_linux.c b/src/detection/displayserver/linux/displayserver_linux.c index d54eab452..62b3d1fb3 100644 --- a/src/detection/displayserver/linux/displayserver_linux.c +++ b/src/detection/displayserver/linux/displayserver_linux.c @@ -79,7 +79,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds) if (ffSettingsGetFreeBSDKenv("screen.height", &buf)) { uint32_t height = (uint32_t) ffStrbufToUInt(&buf, 0); - ffdsAppendDisplay(ds, width, height, 0, 0, 0, 0, 0, 0, 0, NULL, FF_DISPLAY_TYPE_UNKNOWN, false, 0, 0, 0, "kenv"); + ffdsAppendDisplay(ds, width, height, 0, 0, 0, 0, 0, 0, NULL, FF_DISPLAY_TYPE_UNKNOWN, false, 0, 0, 0, "kenv"); } } } diff --git a/src/detection/displayserver/linux/drm.c b/src/detection/displayserver/linux/drm.c index 90f784bf1..ddb80ec93 100644 --- a/src/detection/displayserver/linux/drm.c +++ b/src/detection/displayserver/linux/drm.c @@ -83,7 +83,7 @@ static const char* drmParseSysfs(FFDisplayServerResult* result) result, width, height, refreshRate, - 0, 0, + 0, 0, 0, 0, 0, @@ -398,7 +398,7 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result) FFDisplayResult* item = ffdsAppendDisplay(result, width, height, refreshRate, - 0, 0, + 0, preferredWidth, preferredHeight, preferredRefreshRate, 0, diff --git a/src/detection/displayserver/linux/wayland/global-output.c b/src/detection/displayserver/linux/wayland/global-output.c index 4f2889c92..2e4574464 100644 --- a/src/detection/displayserver/linux/wayland/global-output.c +++ b/src/detection/displayserver/linux/wayland/global-output.c @@ -25,7 +25,7 @@ static void waylandOutputModeListener(void* data, FF_MAYBE_UNUSED struct wl_outp static void waylandOutputScaleListener(void* data, FF_MAYBE_UNUSED struct wl_output* output, int32_t scale) { WaylandDisplay* display = data; - display->scale = scale; + display->dpi = 96 * (uint32_t) scale; } static void waylandOutputGeometryListener(void *data, @@ -51,7 +51,7 @@ static void handleXdgLogicalSize(void *data, FF_MAYBE_UNUSED struct zxdg_output_ // Seems the values are only useful when ractional scale is enabled if (width < display->width) { - display->scale = (double) display->width / width; + display->dpi = (uint32_t) (display->width * 96 / width); } } @@ -86,7 +86,6 @@ const char* ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* WaylandDisplay display = { .parent = wldata, - .scale = 1, .transform = WL_OUTPUT_TRANSFORM_NORMAL, .type = FF_DISPLAY_TYPE_UNKNOWN, .name = ffStrbufCreate(), @@ -128,8 +127,7 @@ const char* ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* (uint32_t) display.width, (uint32_t) display.height, display.refreshRate / 1000.0, - (uint32_t) (display.width / display.scale + .5), - (uint32_t) (display.height / display.scale + .5), + display.dpi, (uint32_t) display.preferredWidth, (uint32_t) display.preferredHeight, display.preferredRefreshRate / 1000.0, diff --git a/src/detection/displayserver/linux/wayland/kde-output.c b/src/detection/displayserver/linux/wayland/kde-output.c index eb4a041d0..ca7e9a50a 100644 --- a/src/detection/displayserver/linux/wayland/kde-output.c +++ b/src/detection/displayserver/linux/wayland/kde-output.c @@ -83,7 +83,7 @@ static void waylandKdeCurrentModeListener(void* data, FF_MAYBE_UNUSED struct kde static void waylandKdeScaleListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* _, wl_fixed_t scale) { WaylandDisplay* wldata = (WaylandDisplay*) data; - wldata->scale = wl_fixed_to_double(scale); + wldata->dpi = (uint32_t) scale * 3 / 8; // wl_fixed_to_double(scale) * 96; } static void waylandKdeEdidListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* _, const char* raw) @@ -193,7 +193,6 @@ const char* ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* re FF_LIST_AUTO_DESTROY modes = ffListCreate(sizeof(WaylandKdeMode)); WaylandDisplay display = { .parent = wldata, - .scale = 1, .transform = WL_OUTPUT_TRANSFORM_NORMAL, .type = FF_DISPLAY_TYPE_UNKNOWN, .name = ffStrbufCreate(), @@ -224,8 +223,7 @@ const char* ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* re (uint32_t) display.width, (uint32_t) display.height, display.refreshRate / 1000.0, - (uint32_t) (display.width / display.scale + .5), - (uint32_t) (display.height / display.scale + .5), + display.dpi, (uint32_t) display.preferredWidth, (uint32_t) display.preferredHeight, display.preferredRefreshRate / 1000.0, diff --git a/src/detection/displayserver/linux/wayland/wayland.h b/src/detection/displayserver/linux/wayland/wayland.h index 8d87f230a..4466bf36a 100644 --- a/src/detection/displayserver/linux/wayland/wayland.h +++ b/src/detection/displayserver/linux/wayland/wayland.h @@ -43,7 +43,7 @@ typedef struct WaylandDisplay int32_t preferredRefreshRate; int32_t physicalWidth; int32_t physicalHeight; - double scale; + uint32_t dpi; enum wl_output_transform transform; FFDisplayType type; FFstrbuf name; diff --git a/src/detection/displayserver/linux/wayland/zwlr-output.c b/src/detection/displayserver/linux/wayland/zwlr-output.c index 560a19478..d9dfa65f9 100644 --- a/src/detection/displayserver/linux/wayland/zwlr-output.c +++ b/src/detection/displayserver/linux/wayland/zwlr-output.c @@ -12,7 +12,7 @@ static void waylandZwlrTransformListener(void* data, FF_MAYBE_UNUSED struct zwlr static void waylandZwlrScaleListener(void* data, FF_MAYBE_UNUSED struct zwlr_output_head_v1 *zwlr_output_head_v1, wl_fixed_t scale) { WaylandDisplay* wldata = (WaylandDisplay*) data; - wldata->scale = wl_fixed_to_double(scale); + wldata->dpi = (uint32_t) scale * 3 / 8; // wl_fixed_to_double(scale) * 96; } typedef struct WaylandZwlrMode @@ -125,7 +125,6 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output FF_LIST_AUTO_DESTROY modes = ffListCreate(sizeof(WaylandZwlrMode)); WaylandDisplay display = { .parent = wldata, - .scale = 1, .transform = WL_OUTPUT_TRANSFORM_NORMAL, .type = FF_DISPLAY_TYPE_UNKNOWN, .name = ffStrbufCreate(), @@ -146,8 +145,7 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output (uint32_t) display.width, (uint32_t) display.height, display.refreshRate / 1000.0, - (uint32_t) (display.width / display.scale + 0.5), - (uint32_t) (display.height / display.scale + 0.5), + (uint32_t) display.dpi, (uint32_t) display.preferredWidth, (uint32_t) display.preferredHeight, display.preferredRefreshRate / 1000.0, diff --git a/src/detection/displayserver/linux/xcb.c b/src/detection/displayserver/linux/xcb.c index ce19f02c1..eaa8ac63a 100644 --- a/src/detection/displayserver/linux/xcb.c +++ b/src/detection/displayserver/linux/xcb.c @@ -93,7 +93,7 @@ static xcb_randr_get_output_property_reply_t* xcbRandrGetProperty(XcbRandrData* static void xcbDetectWMfromEWMH(XcbRandrData* data, xcb_window_t rootWindow, FFDisplayServerResult* result) { - if(result->wmProcessName.length > 0 || ffStrbufCompS(&result->wmProtocolName, FF_WM_PROTOCOL_WAYLAND) == 0) + if(result->wmProcessName.length > 0 || ffStrbufEqualS(&result->wmProtocolName, FF_WM_PROTOCOL_WAYLAND)) return; FF_AUTO_FREE xcb_window_t* wmWindow = (xcb_window_t*) xcbGetProperty(data, rootWindow, "_NET_SUPPORTING_WM_CHECK"); @@ -127,7 +127,7 @@ static void xcbFetchServerVendor(XcbRandrData* data, FFDisplayServerResult* resu } } -static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output, FFstrbuf* name, bool primary, FFDisplayType displayType, struct xcb_randr_get_screen_resources_current_reply_t* screenResources, uint8_t bitDepth, double scaleFactor) +static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output, FFstrbuf* name, bool primary, FFDisplayType displayType, struct xcb_randr_get_screen_resources_current_reply_t* screenResources, uint8_t bitDepth, uint32_t dpi) { xcb_randr_get_output_info_cookie_t outputInfoCookie = data->ffxcb_randr_get_output_info(data->connection, output, XCB_CURRENT_TIME); FF_AUTO_FREE xcb_randr_get_output_info_reply_t* outputInfoReply = data->ffxcb_randr_get_output_info_reply(data->connection, outputInfoCookie, NULL); @@ -211,8 +211,7 @@ static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output, (uint32_t) (currentMode ? currentMode->width : crtcInfoReply->width), (uint32_t) (currentMode ? currentMode->height : crtcInfoReply->height), currentMode ? (double) currentMode->dot_clock / (double) ((uint32_t) currentMode->htotal * currentMode->vtotal) : 0, - (uint32_t) (crtcInfoReply->width / scaleFactor + .5), - (uint32_t) (crtcInfoReply->height / scaleFactor + .5), + dpi, preferredMode ? (uint32_t) preferredMode->width : 0, preferredMode ? (uint32_t) preferredMode->height : 0, preferredMode ? (double) preferredMode->dot_clock / (double) ((uint32_t) preferredMode->htotal * preferredMode->vtotal) : 0, @@ -238,7 +237,7 @@ static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output, return !!item; } -static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t* monitor, struct xcb_randr_get_screen_resources_current_reply_t* screenResources, uint8_t bitDepth, double scaleFactor) +static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t* monitor, struct xcb_randr_get_screen_resources_current_reply_t* screenResources, uint8_t bitDepth, uint32_t dpi) { //for some reasons, we have to construct this our self xcb_randr_output_iterator_t outputIterator = { @@ -262,7 +261,7 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t* while(outputIterator.rem > 0) { - if(xcbRandrHandleOutput(data, *outputIterator.data, &name, monitor->primary, displayType, screenResources, bitDepth, scaleFactor)) + if(xcbRandrHandleOutput(data, *outputIterator.data, &name, monitor->primary, displayType, screenResources, bitDepth, dpi)) foundOutput = true; data->ffxcb_randr_output_next(&outputIterator); } @@ -274,8 +273,7 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t* (uint32_t) monitor->width, (uint32_t) monitor->height, 0, - (uint32_t) (monitor->width / scaleFactor + .5), - (uint32_t) (monitor->height / scaleFactor + .5), + dpi, 0, 0, 0, 0, &name, @@ -301,13 +299,13 @@ static bool xcbRandrHandleMonitors(XcbRandrData* data, xcb_screen_t* screen) xcb_randr_get_screen_resources_current_cookie_t screenResourcesCookie = data->ffxcb_randr_get_screen_resources_current(data->connection, screen->root); FF_AUTO_FREE struct xcb_randr_get_screen_resources_current_reply_t* screenResources = data->ffxcb_randr_get_screen_resources_current_reply(data->connection, screenResourcesCookie, NULL); - double scaleFactor = 1; + uint32_t dpi = 0; FF_AUTO_FREE const char* resourceManager = xcbGetProperty(data, screen->root, "RESOURCE_MANAGER"); if (resourceManager) { - FF_STRBUF_AUTO_DESTROY dpi = ffStrbufCreate(); - if (ffParsePropLines(resourceManager, "Xft.dpi:", &dpi)) - scaleFactor = ffStrbufToDouble(&dpi, 96) / 96; + FF_STRBUF_AUTO_DESTROY dpiStr = ffStrbufCreate(); + if (ffParsePropLines(resourceManager, "Xft.dpi:", &dpiStr)) + dpi = (uint32_t) ffStrbufToUInt(&dpiStr, 96); } uint8_t bitDepth = (uint8_t) (screen->root_depth / 3); @@ -317,7 +315,7 @@ static bool xcbRandrHandleMonitors(XcbRandrData* data, xcb_screen_t* screen) while(monitorInfoIterator.rem > 0) { - if(xcbRandrHandleMonitor(data, monitorInfoIterator.data, screenResources, bitDepth, scaleFactor)) + if(xcbRandrHandleMonitor(data, monitorInfoIterator.data, screenResources, bitDepth, dpi)) foundMonitor = true; data->ffxcb_randr_monitor_info_next(&monitorInfoIterator); } @@ -337,8 +335,7 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen) (uint32_t) screen->width_in_pixels, (uint32_t) screen->height_in_pixels, 0, - (uint32_t) screen->width_in_pixels, - (uint32_t) screen->height_in_pixels, + 0, 0, 0, 0, 0, NULL, diff --git a/src/detection/displayserver/linux/xlib.c b/src/detection/displayserver/linux/xlib.c index eb407f7b5..8f54a2d5a 100644 --- a/src/detection/displayserver/linux/xlib.c +++ b/src/detection/displayserver/linux/xlib.c @@ -76,7 +76,7 @@ static uint8_t* xrandrGetProperty(XrandrData* data, RROutput output, const char* static void x11DetectWMFromEWMH(XrandrData* data, FFDisplayServerResult* result) { - if(result->wmProcessName.length > 0 || ffStrbufCompS(&result->wmProtocolName, FF_WM_PROTOCOL_WAYLAND) == 0) + if(result->wmProcessName.length > 0 || ffStrbufEqualS(&result->wmProtocolName, FF_WM_PROTOCOL_WAYLAND)) return; Window* wmWindow = (Window*) x11GetProperty(data, data->display, DefaultRootWindow(data->display), "_NET_SUPPORTING_WM_CHECK"); @@ -101,7 +101,7 @@ static void x11FetchServerVendor(XrandrData* data, FFDisplayServerResult* result ffStrbufSetS(&result->wmProtocolName, serverVendor); } -static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf* name, bool primary, FFDisplayType displayType, uint8_t* edidData, uint32_t edidLength, XRRScreenResources* screenResources, uint8_t bitDepth, double scaleFactor, bool randrEmulation) +static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf* name, bool primary, FFDisplayType displayType, uint8_t* edidData, uint32_t edidLength, XRRScreenResources* screenResources, uint8_t bitDepth, uint32_t dpi, bool randrEmulation) { //We do the check here, because we want the best fallback display if this call failed if(screenResources == NULL) @@ -145,8 +145,7 @@ static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf* (uint32_t) (currentMode ? currentMode->width : crtcInfo->width), (uint32_t) (currentMode ? currentMode->height : crtcInfo->height), currentMode ? (double) currentMode->dotClock / (double) ((uint32_t) currentMode->hTotal * currentMode->vTotal) : 0, - (uint32_t) (crtcInfo->width / scaleFactor + .5), - (uint32_t) (crtcInfo->height / scaleFactor + .5), + dpi, preferredMode ? (uint32_t) preferredMode->width : 0, preferredMode ? (uint32_t) preferredMode->height : 0, preferredMode ? (double) preferredMode->dotClock / (double) ((uint32_t) preferredMode->hTotal * preferredMode->vTotal) : 0, @@ -176,7 +175,7 @@ static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf* return !!item; } -static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name, bool primary, FFDisplayType displayType, XRRScreenResources* screenResources, uint8_t bitDepth, double scaleFactor) +static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name, bool primary, FFDisplayType displayType, XRRScreenResources* screenResources, uint8_t bitDepth, uint32_t dpi) { XRROutputInfo* outputInfo = data->ffXRRGetOutputInfo(data->display, screenResources, output); if(outputInfo == NULL) @@ -195,7 +194,7 @@ static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name uint8_t* randrEmulation = xrandrGetProperty(data, output, "RANDR Emulation", NULL); - bool res = xrandrHandleCrtc(data, outputInfo, name, primary, displayType, edidData, edidLength, screenResources, bitDepth, scaleFactor, randrEmulation ? !!randrEmulation[0] : false); + bool res = xrandrHandleCrtc(data, outputInfo, name, primary, displayType, edidData, edidLength, screenResources, bitDepth, dpi, randrEmulation ? !!randrEmulation[0] : false); if (edidData) data->ffXFree(edidData); @@ -206,7 +205,7 @@ static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name return res; } -static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo, XRRScreenResources* screenResources, uint8_t bitDepth, double scaleFactor) +static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo, XRRScreenResources* screenResources, uint8_t bitDepth, uint32_t dpi) { bool foundOutput = false; char* xname = data->ffXGetAtomName(data->display, monitorInfo->name); @@ -215,7 +214,7 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo, X FFDisplayType displayType = ffdsGetDisplayType(name.chars); for(int i = 0; i < monitorInfo->noutput; i++) { - if(xrandrHandleOutput(data, monitorInfo->outputs[i], &name, monitorInfo->primary, displayType, screenResources, bitDepth, scaleFactor)) + if(xrandrHandleOutput(data, monitorInfo->outputs[i], &name, monitorInfo->primary, displayType, screenResources, bitDepth, dpi)) foundOutput = true; } @@ -226,8 +225,7 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo, X (uint32_t) monitorInfo->width, (uint32_t) monitorInfo->height, 0, - (uint32_t) (monitorInfo->width / scaleFactor + .5), - (uint32_t) (monitorInfo->height / scaleFactor + .5), + dpi, 0, 0, 0, 0, &name, @@ -251,13 +249,13 @@ static bool xrandrHandleMonitors(XrandrData* data, Screen* screen) XRRScreenResources* screenResources = data->ffXRRGetScreenResourcesCurrent(data->display, RootWindowOfScreen(screen)); - double scaleFactor = 1; + uint32_t dpi = 1; char* resourceManager = (char*) x11GetProperty(data, data->display, screen->root, "RESOURCE_MANAGER"); if (resourceManager) { - FF_STRBUF_AUTO_DESTROY dpi = ffStrbufCreate(); - if (ffParsePropLines(resourceManager, "Xft.dpi:", &dpi)) - scaleFactor = ffStrbufToDouble(&dpi, 96) / 96; + FF_STRBUF_AUTO_DESTROY dpiStr = ffStrbufCreate(); + if (ffParsePropLines(resourceManager, "Xft.dpi:", &dpiStr)) + dpi = (uint32_t) ffStrbufToUInt(&dpiStr, 96); data->ffXFree(resourceManager); } uint8_t bitDepth = (uint8_t) (screen->root_depth / 3); @@ -266,7 +264,7 @@ static bool xrandrHandleMonitors(XrandrData* data, Screen* screen) for(int i = 0; i < numberOfMonitors; i++) { - if(xrandrHandleMonitor(data, &monitorInfos[i], screenResources, bitDepth, scaleFactor)) + if(xrandrHandleMonitor(data, &monitorInfos[i], screenResources, bitDepth, dpi)) foundAMonitor = true; } @@ -287,8 +285,7 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen) (uint32_t) WidthOfScreen(screen), (uint32_t) HeightOfScreen(screen), 0, - (uint32_t) WidthOfScreen(screen), - (uint32_t) HeightOfScreen(screen), + 0, 0, 0, 0, 0, NULL, diff --git a/src/modules/display/display.c b/src/modules/display/display.c index f25ff49a1..7b6fa6977 100644 --- a/src/modules/display/display.c +++ b/src/modules/display/display.c @@ -45,7 +45,9 @@ bool ffPrintDisplay(FFDisplayOptions* options) } else { - ffStrbufAppendF(&buffer, "%ix%i", result->scaledWidth, result->scaledHeight); + uint32_t scaledWidth = result->width * 96 / result->dpi; + uint32_t scaledHeight = result->height * 96 / result->dpi; + ffStrbufAppendF(&buffer, "%ix%i", scaledWidth, scaledHeight); } if (options->compactType & FF_DISPLAY_COMPACT_TYPE_REFRESH_RATE_BIT) @@ -101,7 +103,9 @@ bool ffPrintDisplay(FFDisplayOptions* options) FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); double inch = sqrt(result->physicalWidth * result->physicalWidth + result->physicalHeight * result->physicalHeight) / 25.4; - double scaleFactor = (double) result->height / (double) result->scaledHeight; + uint32_t scaledWidth = result->width * 96 / result->dpi; + uint32_t scaledHeight = result->height * 96 / result->dpi; + double scaleFactor = (double) result->dpi / 96.; if(options->moduleArgs.outputFormat.length == 0) { @@ -109,9 +113,7 @@ bool ffPrintDisplay(FFDisplayOptions* options) ffStrbufAppendF(&buffer, "%ix%i", result->width, result->height); - if( - result->scaledWidth > 0 && result->scaledWidth != result->width && - result->scaledHeight > 0 && result->scaledHeight != result->height) + if(result->dpi != 96) { ffStrbufAppendS(&buffer, " @ "); ffStrbufAppendDouble(&buffer, scaleFactor, instance.config.display.fractionNdigits, instance.config.display.fractionTrailingZeros == FF_FRACTION_TRAILING_ZEROS_TYPE_ALWAYS); @@ -195,8 +197,8 @@ bool ffPrintDisplay(FFDisplayOptions* options) FF_ARG(result->width, "width"), FF_ARG(result->height, "height"), FF_ARG(refreshRate, "refresh-rate"), - FF_ARG(result->scaledWidth, "scaled-width"), - FF_ARG(result->scaledHeight, "scaled-height"), + FF_ARG(scaledWidth, "scaled-width"), + FF_ARG(scaledHeight, "scaled-height"), FF_ARG(result->name, "name"), FF_ARG(displayType, "type"), FF_ARG(result->rotation, "rotation"), @@ -216,6 +218,7 @@ bool ffPrintDisplay(FFDisplayOptions* options) FF_ARG(result->preferredWidth, "preferred-width"), FF_ARG(result->preferredHeight, "preferred-height"), FF_ARG(preferredRefreshRate, "preferred-refresh-rate"), + FF_ARG(result->dpi, "dpi"), })); } } @@ -362,10 +365,13 @@ bool ffGenerateDisplayJsonResult(FF_MAYBE_UNUSED FFDisplayOptions* options, yyjs yyjson_mut_obj_add_str(doc, output, "drrStatus", "Unknown"); break; } + yyjson_mut_obj_add_uint(doc, output, "dpi", item->dpi); + uint32_t scaledWidth = item->width * 96 / item->dpi; + uint32_t scaledHeight = item->height * 96 / item->dpi; yyjson_mut_val* scaled = yyjson_mut_obj_add_obj(doc, obj, "scaled"); - yyjson_mut_obj_add_uint(doc, scaled, "width", item->scaledWidth); - yyjson_mut_obj_add_uint(doc, scaled, "height", item->scaledHeight); + yyjson_mut_obj_add_uint(doc, scaled, "width", scaledWidth); + yyjson_mut_obj_add_uint(doc, scaled, "height", scaledHeight); yyjson_mut_val* preferred = yyjson_mut_obj_add_obj(doc, obj, "preferred"); yyjson_mut_obj_add_uint(doc, preferred, "width", item->preferredWidth); @@ -478,5 +484,6 @@ FFModuleBaseInfo ffDisplayModuleInfo = { {"Screen preferred width (in pixels)", "preferred-width"}, {"Screen preferred height (in pixels)", "preferred-height"}, {"Screen preferred refresh rate (in Hz)", "preferred-refresh-rate"}, + {"DPI", "dpi"}, })) };