diff --git a/src/detection/displayserver/displayserver.c b/src/detection/displayserver/displayserver.c index 12e273dc5..d2499e349 100644 --- a/src/detection/displayserver/displayserver.c +++ b/src/detection/displayserver/displayserver.c @@ -11,7 +11,9 @@ bool ffdsAppendDisplay( FFstrbuf* name, FFDisplayType type, bool primary, - uint64_t id) + uint64_t id, + uint32_t physicalWidth, + uint32_t physicalHeight) { if(width == 0 || height == 0) return false; @@ -27,6 +29,8 @@ bool ffdsAppendDisplay( display->type = type; display->primary = primary; display->id = id; + display->physicalWidth = physicalWidth; + display->physicalHeight = physicalHeight; return true; } diff --git a/src/detection/displayserver/displayserver.h b/src/detection/displayserver/displayserver.h index 13c6452f6..7467ef56a 100644 --- a/src/detection/displayserver/displayserver.h +++ b/src/detection/displayserver/displayserver.h @@ -60,6 +60,8 @@ typedef struct FFDisplayResult uint32_t rotation; bool primary; uint64_t id; // platform dependent + uint32_t physicalWidth; + uint32_t physicalHeight; } FFDisplayResult; typedef struct FFDisplayServerResult @@ -85,4 +87,6 @@ bool ffdsAppendDisplay( FFstrbuf* name, FFDisplayType type, bool primary, - uint64_t id); + uint64_t id, + uint32_t physicalWidth, + uint32_t physicalHeight); diff --git a/src/detection/displayserver/displayserver_android.c b/src/detection/displayserver/displayserver_android.c index 8d3aa20a3..a81f763b2 100644 --- a/src/detection/displayserver/displayserver_android.c +++ b/src/detection/displayserver/displayserver_android.c @@ -1,8 +1,9 @@ #include "displayserver.h" #include "common/settings.h" - #include "common/processing.h" +#include + static void detectWithDumpsys(FFDisplayServerResult* ds) { FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate(); @@ -63,6 +64,8 @@ static void detectWithDumpsys(FFDisplayServerResult* ds) &name, FF_DISPLAY_TYPE_UNKNOWN, false, + 0, + 0, 0 ); } @@ -83,6 +86,8 @@ static bool detectWithGetprop(FFDisplayServerResult* ds) uint32_t width = (uint32_t) ffStrbufToUInt(&buffer, 0); ffStrbufSubstrAfterFirstC(&buffer, ','); uint32_t height = (uint32_t) ffStrbufToUInt(&buffer, 0); + ffStrbufSubstrAfterFirstC(&buffer, ','); + uint32_t ppi = (uint32_t) ffStrbufToUInt(&buffer, 0); return ffdsAppendDisplay(ds, width, height, @@ -93,7 +98,9 @@ static bool detectWithGetprop(FFDisplayServerResult* ds) 0, FF_DISPLAY_TYPE_BUILTIN, false, - 0 + 0, + (uint32_t) (width / ppi * 25.4), + (uint32_t) (height / ppi * 25.4) ); } diff --git a/src/detection/displayserver/displayserver_apple.c b/src/detection/displayserver/displayserver_apple.c index 964a6981f..a668ce961 100644 --- a/src/detection/displayserver/displayserver_apple.c +++ b/src/detection/displayserver/displayserver_apple.c @@ -57,7 +57,7 @@ static void detectDisplays(FFDisplayServerResult* ds) if(CoreDisplay_IODisplayCreateInfoDictionary) { io_service_t servicePort = CGDisplayIOServicePort(screen); - CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName); + CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName); if(displayInfo) { CFDictionaryRef productNames; @@ -67,6 +67,8 @@ static void detectDisplays(FFDisplayServerResult* ds) } #endif + CGSize size = CGDisplayScreenSize(screen); + ffdsAppendDisplay(ds, (uint32_t)CGDisplayModeGetPixelWidth(mode), (uint32_t)CGDisplayModeGetPixelHeight(mode), @@ -77,7 +79,9 @@ static void detectDisplays(FFDisplayServerResult* ds) &name, CGDisplayIsBuiltin(screen) ? FF_DISPLAY_TYPE_BUILTIN : FF_DISPLAY_TYPE_EXTERNAL, CGDisplayIsMain(screen), - (uint64_t)screen + (uint64_t)screen, + (uint32_t) (size.width + 0.5), + (uint32_t) (size.height + 0.5) ); CGDisplayModeRelease(mode); } diff --git a/src/detection/displayserver/displayserver_windows.c b/src/detection/displayserver/displayserver_windows.c index c57c03992..a7774b162 100644 --- a/src/detection/displayserver/displayserver_windows.c +++ b/src/detection/displayserver/displayserver_windows.c @@ -1,6 +1,9 @@ #include "displayserver.h" #include "detection/os/os.h" #include "util/windows/unicode.h" +#include "util/windows/registry.h" +#include "util/mallocHelper.h" +#include "util/edidHelper.h" #include #include @@ -73,6 +76,7 @@ static void detectDisplays(FFDisplayServerResult* ds) if (!monitorInfo) continue; FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); + uint32_t physicalWidth = 0, physicalHeight = 0; DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = { .header = { @@ -84,13 +88,39 @@ static void detectDisplays(FFDisplayServerResult* ds) }; if(DisplayConfigGetDeviceInfo(&targetName.header) == ERROR_SUCCESS) { - if (targetName.flags.friendlyNameFromEdid) - ffStrbufSetWS(&name, targetName.monitorFriendlyDeviceName); + wchar_t regPath[256] = L"SYSTEM\\CurrentControlSet\\Enum"; + wchar_t* pRegPath = regPath + strlen("SYSTEM\\CurrentControlSet\\Enum"); + wchar_t* pDevPath = targetName.monitorDevicePath + strlen("\\\\?"); + while (*pDevPath && *pDevPath != L'{') + { + if (*pDevPath == L'#') + *pRegPath = L'\\'; + else + *pRegPath = *pDevPath; + ++pRegPath; + ++pDevPath; + assert(pRegPath < regPath + sizeof(regPath) / sizeof(wchar_t) + strlen("Device Parameters")); + } + wcscpy(pRegPath, L"Device Parameters"); + + uint8_t edidData[1024]; + DWORD edidLength = sizeof(edidData); + if (RegGetValueW(HKEY_LOCAL_MACHINE, regPath, L"EDID", RRF_RT_REG_BINARY, NULL, edidData, &edidLength) == ERROR_SUCCESS && + edidLength > 0 && edidLength % 128 == 0) + { + ffEdidGetName(edidData, &name); + ffEdidGetPhysicalSize(edidData, &physicalWidth, &physicalHeight); + } else { - ffStrbufSetWS(&name, targetName.monitorDevicePath); - ffStrbufSubstrAfterFirstC(&name, '#'); - ffStrbufSubstrBeforeFirstC(&name, '#'); + if (targetName.flags.friendlyNameFromEdid) + ffStrbufSetWS(&name, targetName.monitorFriendlyDeviceName); + else + { + ffStrbufSetWS(&name, targetName.monitorDevicePath); + ffStrbufSubstrAfterFirstC(&name, '#'); + ffStrbufSubstrBeforeFirstC(&name, '#'); + } } } @@ -107,18 +137,10 @@ static void detectDisplays(FFDisplayServerResult* ds) uint32_t rotation; switch (path->targetInfo.rotation) { - case DISPLAYCONFIG_ROTATION_ROTATE90: - rotation = 90; - break; - case DISPLAYCONFIG_ROTATION_ROTATE180: - rotation = 180; - break; - case DISPLAYCONFIG_ROTATION_ROTATE270: - rotation = 270; - break; - default: - rotation = 0; - break; + case DISPLAYCONFIG_ROTATION_ROTATE90: rotation = 90; break; + case DISPLAYCONFIG_ROTATION_ROTATE180: rotation = 180; break; + case DISPLAYCONFIG_ROTATION_ROTATE270: rotation = 270; break; + default: rotation = 0; break; } ffdsAppendDisplay(ds, @@ -135,7 +157,9 @@ static void detectDisplays(FFDisplayServerResult* ds) path->targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED ? FF_DISPLAY_TYPE_BUILTIN : FF_DISPLAY_TYPE_EXTERNAL, !!(monitorInfo->info.dwFlags & MONITORINFOF_PRIMARY), - (uint64_t)(uintptr_t) monitorInfo->handle + (uint64_t)(uintptr_t) monitorInfo->handle, + physicalWidth, + physicalHeight ); } } diff --git a/src/detection/displayserver/linux/displayserver_linux.c b/src/detection/displayserver/linux/displayserver_linux.c index 807facd9e..14a4fd9aa 100644 --- a/src/detection/displayserver/linux/displayserver_linux.c +++ b/src/detection/displayserver/linux/displayserver_linux.c @@ -50,7 +50,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, NULL, FF_DISPLAY_TYPE_UNKNOWN, false, 0); + ffdsAppendDisplay(ds, width, height, 0, 0, 0, 0, NULL, FF_DISPLAY_TYPE_UNKNOWN, false, 0, 0, 0); } } } diff --git a/src/detection/displayserver/linux/drm.c b/src/detection/displayserver/linux/drm.c index eb8d09847..8fe92c5b8 100644 --- a/src/detection/displayserver/linux/drm.c +++ b/src/detection/displayserver/linux/drm.c @@ -37,7 +37,7 @@ static const char* drmParseSysfs(FFDisplayServerResult* result) continue; } - unsigned width = 0, height = 0; + unsigned width = 0, height = 0, physicalWidth = 0, physicalHeight = 0; double refreshRate = 0; FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); @@ -49,6 +49,7 @@ static const char* drmParseSysfs(FFDisplayServerResult* result) { ffEdidGetName(edidData, &name); ffEdidGetPreferredResolutionAndRefreshRate(edidData, &width, &height, &refreshRate); + ffEdidGetPhysicalSize(edidData, &physicalWidth, &physicalHeight); } else { @@ -78,7 +79,9 @@ static const char* drmParseSysfs(FFDisplayServerResult* result) &name, FF_DISPLAY_TYPE_UNKNOWN, false, - 0 + 0, + physicalWidth, + physicalHeight ); ffStrbufSubstrBefore(&drmDir, drmDirLength); @@ -344,7 +347,9 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result) : conn->connector_type == DRM_MODE_CONNECTOR_HDMIA || conn->connector_type == DRM_MODE_CONNECTOR_HDMIB ? FF_DISPLAY_TYPE_EXTERNAL : FF_DISPLAY_TYPE_UNKNOWN, false, - conn->connector_id + conn->connector_id, + conn->mmWidth, + conn->mmHeight ); } diff --git a/src/detection/displayserver/linux/wayland/global-output.c b/src/detection/displayserver/linux/wayland/global-output.c index 8d868ea75..e318fc0db 100644 --- a/src/detection/displayserver/linux/wayland/global-output.c +++ b/src/detection/displayserver/linux/wayland/global-output.c @@ -25,14 +25,16 @@ static void waylandOutputGeometryListener(void *data, FF_MAYBE_UNUSED struct wl_output *output, FF_MAYBE_UNUSED int32_t x, FF_MAYBE_UNUSED int32_t y, - FF_MAYBE_UNUSED int32_t physical_width, - FF_MAYBE_UNUSED int32_t physical_height, + int32_t physical_width, + int32_t physical_height, FF_MAYBE_UNUSED int32_t subpixel, FF_MAYBE_UNUSED const char *make, FF_MAYBE_UNUSED const char *model, int32_t transform) { WaylandDisplay* display = data; + display->physicalWidth = physical_width; + display->physicalHeight = physical_height; display->transform = (enum wl_output_transform) transform; } @@ -156,7 +158,9 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist : &display.name, display.type, false, - display.id + display.id, + (uint32_t) display.physicalWidth, + (uint32_t) display.physicalHeight ); ffStrbufDestroy(&display.description); diff --git a/src/detection/displayserver/linux/wayland/kde-output.c b/src/detection/displayserver/linux/wayland/kde-output.c index 8d7ab51ab..951b3aa36 100644 --- a/src/detection/displayserver/linux/wayland/kde-output.c +++ b/src/detection/displayserver/linux/wayland/kde-output.c @@ -92,14 +92,16 @@ static void waylandKdeGeometryListener(void *data, FF_MAYBE_UNUSED struct kde_output_device_v2 *kde_output_device_v2, FF_MAYBE_UNUSED int32_t x, FF_MAYBE_UNUSED int32_t y, - FF_MAYBE_UNUSED int32_t physical_width, - FF_MAYBE_UNUSED int32_t physical_height, + int32_t physical_width, + int32_t physical_height, FF_MAYBE_UNUSED int32_t subpixel, FF_MAYBE_UNUSED const char *make, FF_MAYBE_UNUSED const char *model, int32_t transform) { WaylandDisplay* display = data; + display->physicalWidth = physical_width; + display->physicalHeight = physical_height; display->transform = (enum wl_output_transform) transform; } @@ -215,7 +217,9 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, : &display.name, display.type, false, - display.id + display.id, + (uint32_t) display.physicalWidth, + (uint32_t) display.physicalHeight ); ffStrbufDestroy(&display.description); diff --git a/src/detection/displayserver/linux/wayland/wayland.h b/src/detection/displayserver/linux/wayland/wayland.h index 21f1979c3..025b0b299 100644 --- a/src/detection/displayserver/linux/wayland/wayland.h +++ b/src/detection/displayserver/linux/wayland/wayland.h @@ -36,6 +36,8 @@ typedef struct WaylandDisplay WaylandData* parent; int32_t width; int32_t height; + int32_t physicalWidth; + int32_t physicalHeight; int32_t refreshRate; double scale; enum wl_output_transform transform; diff --git a/src/detection/displayserver/linux/wayland/zwlr-output.c b/src/detection/displayserver/linux/wayland/zwlr-output.c index 861d7dc2e..dd9b83289 100644 --- a/src/detection/displayserver/linux/wayland/zwlr-output.c +++ b/src/detection/displayserver/linux/wayland/zwlr-output.c @@ -71,10 +71,17 @@ static void waylandZwlrCurrentModeListener(void* data, FF_MAYBE_UNUSED struct zw wldata->refreshRate = current->refreshRate; } +static void waylandZwlrPhysicalSizeListener(void* data, FF_MAYBE_UNUSED struct zwlr_output_head_v1 *zwlr_output_head_v1, int32_t width, int32_t height) +{ + WaylandDisplay* wldata = (WaylandDisplay*) data; + wldata->physicalWidth = width; + wldata->physicalHeight = height; +} + static const struct zwlr_output_head_v1_listener headListener = { .name = (void*) ffWaylandOutputNameListener, .description = (void*) ffWaylandOutputDescriptionListener, - .physical_size = (void*) stubListener, + .physical_size = waylandZwlrPhysicalSizeListener, .mode = waylandZwlrModeListener, .enabled = (void*) stubListener, .current_mode = waylandZwlrCurrentModeListener, @@ -160,7 +167,9 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output : &display.name, display.type, false, - display.id + display.id, + (uint32_t) display.physicalWidth, + (uint32_t) display.physicalHeight ); ffStrbufDestroy(&display.description); diff --git a/src/detection/displayserver/linux/xcb.c b/src/detection/displayserver/linux/xcb.c index c4c4b1551..2cd7f349b 100644 --- a/src/detection/displayserver/linux/xcb.c +++ b/src/detection/displayserver/linux/xcb.c @@ -41,32 +41,25 @@ static bool xcbInitPropertyData(void* libraryHandle, XcbPropertyData* propertyDa static void* xcbGetProperty(XcbPropertyData* data, xcb_connection_t* connection, xcb_window_t window, const char* request) { xcb_intern_atom_cookie_t requestAtomCookie = data->ffxcb_intern_atom(connection, true, (uint16_t) strlen(request), request); - xcb_intern_atom_reply_t* requestAtomReply = data->ffxcb_intern_atom_reply(connection, requestAtomCookie, NULL); + FF_AUTO_FREE xcb_intern_atom_reply_t* requestAtomReply = data->ffxcb_intern_atom_reply(connection, requestAtomCookie, NULL); if(requestAtomReply == NULL) return NULL; xcb_get_property_cookie_t propertyCookie = data->ffxcb_get_property(connection, false, window, requestAtomReply->atom, XCB_ATOM_ANY, 0, 64); - free(requestAtomReply); - - xcb_get_property_reply_t* propertyReply = data->ffxcb_get_property_reply(connection, propertyCookie, NULL); + FF_AUTO_FREE xcb_get_property_reply_t* propertyReply = data->ffxcb_get_property_reply(connection, propertyCookie, NULL); if(propertyReply == NULL) return NULL; int length = data->ffxcb_get_property_value_length(propertyReply); if(length <= 0) - { - free(propertyReply); return NULL; - } //Why are xcb property strings not null terminated??? void* replyValue = malloc((size_t)length + 1); memcpy(replyValue, data->ffxcb_get_property_value(propertyReply), (size_t) length); ((char*) replyValue)[length] = '\0'; - free(propertyReply); - return replyValue; } @@ -75,28 +68,18 @@ static void xcbDetectWMfromEWMH(XcbPropertyData* data, xcb_connection_t* connect if(result->wmProcessName.length > 0 || ffStrbufCompS(&result->wmProtocolName, FF_WM_PROTOCOL_WAYLAND) == 0) return; - xcb_window_t* wmWindow = (xcb_window_t*) xcbGetProperty(data, connection, rootWindow, "_NET_SUPPORTING_WM_CHECK"); + FF_AUTO_FREE xcb_window_t* wmWindow = (xcb_window_t*) xcbGetProperty(data, connection, rootWindow, "_NET_SUPPORTING_WM_CHECK"); if(wmWindow == NULL) return; - char* wmName = (char*) xcbGetProperty(data, connection, *wmWindow, "_NET_WM_NAME"); + FF_AUTO_FREE char* wmName = (char*) xcbGetProperty(data, connection, *wmWindow, "_NET_WM_NAME"); if(wmName == NULL) wmName = (char*) xcbGetProperty(data, connection, *wmWindow, "WM_NAME"); - free(wmWindow); - - if(wmName == NULL) + if(wmName == NULL || *wmName == '\0') return; - if(*wmName == '\0') - { - free(wmName); - return; - } - ffStrbufSetS(&result->wmProcessName, wmName); - - free(wmName); } void ffdsConnectXcb(FFDisplayServerResult* result) @@ -122,17 +105,20 @@ void ffdsConnectXcb(FFDisplayServerResult* result) while(iterator.rem > 0) { + xcb_screen_t* screen = iterator.data; ffdsAppendDisplay(result, - (uint32_t) iterator.data->width_in_pixels, - (uint32_t) iterator.data->height_in_pixels, + (uint32_t) screen->width_in_pixels, + (uint32_t) screen->height_in_pixels, 0, - (uint32_t) iterator.data->width_in_pixels, - (uint32_t) iterator.data->height_in_pixels, + (uint32_t) screen->width_in_pixels, + (uint32_t) screen->height_in_pixels, 0, NULL, FF_DISPLAY_TYPE_UNKNOWN, false, - 0 + 0, + (uint32_t) screen->width_in_millimeters, + (uint32_t) screen->height_in_millimeters ); ffxcb_screen_next(&iterator); } @@ -191,7 +177,7 @@ typedef struct XcbRandrData xcb_randr_get_screen_resources_current_reply_t* screenResources; } XcbRandrData; -static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* modeInfo, FFstrbuf* name, uint32_t rotation, bool primary) +static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* modeInfo, FFstrbuf* name, uint32_t rotation, bool primary, xcb_randr_get_output_info_reply_t* output) { double refreshRate = (double) modeInfo->dot_clock / (double) (modeInfo->htotal * modeInfo->vtotal); @@ -206,11 +192,13 @@ static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* mo name, FF_DISPLAY_TYPE_UNKNOWN, primary, - 0 + 0, + (uint32_t) output->mm_width, + (uint32_t) output->mm_height ); } -static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrbuf* name, uint32_t rotation, bool primary) +static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrbuf* name, uint32_t rotation, bool primary, xcb_randr_get_output_info_reply_t* output) { //We do the check here, because we want the best fallback display if this call failed if(data->screenResources == NULL) @@ -221,7 +209,7 @@ static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrb while(modesIterator.rem > 0) { if(modesIterator.data->id == mode) - return xcbRandrHandleModeInfo(data, modesIterator.data, name, rotation, primary); + return xcbRandrHandleModeInfo(data, modesIterator.data, name, rotation, primary, output); data->ffxcb_randr_mode_info_next(&modesIterator); } @@ -229,10 +217,10 @@ static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrb return false; } -static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrbuf* name, bool primary) +static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrbuf* name, bool primary, xcb_randr_get_output_info_reply_t* output) { xcb_randr_get_crtc_info_cookie_t crtcInfoCookie = data->ffxcb_randr_get_crtc_info(data->connection, crtc, XCB_CURRENT_TIME); - xcb_randr_get_crtc_info_reply_t* crtcInfoReply = data->ffxcb_randr_get_crtc_info_reply(data->connection, crtcInfoCookie, NULL); + FF_AUTO_FREE xcb_randr_get_crtc_info_reply_t* crtcInfoReply = data->ffxcb_randr_get_crtc_info_reply(data->connection, crtcInfoCookie, NULL); if(crtcInfoReply == NULL) return false; @@ -252,7 +240,7 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrb rotation = 0; break; } - bool res = xcbRandrHandleMode(data, crtcInfoReply->mode, name, rotation, primary); + bool res = xcbRandrHandleMode(data, crtcInfoReply->mode, name, rotation, primary, output); res = res ? true : ffdsAppendDisplay( data->result, (uint32_t) crtcInfoReply->width, @@ -264,10 +252,11 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrb name, FF_DISPLAY_TYPE_UNKNOWN, primary, - 0 + 0, + (uint32_t) output->mm_width, + (uint32_t) output->mm_height ); - free(crtcInfoReply); return res; } @@ -294,7 +283,7 @@ static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output, } } - bool res = xcbRandrHandleCrtc(data, outputInfoReply->crtc, name, primary); + bool res = xcbRandrHandleCrtc(data, outputInfoReply->crtc, name, primary, outputInfoReply); return res; } @@ -338,14 +327,16 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t* &name, FF_DISPLAY_TYPE_UNKNOWN, !!monitor->primary, - 0 + 0, + (uint32_t) monitor->width_in_millimeters, + (uint32_t) monitor->height_in_millimeters ); } static bool xcbRandrHandleMonitors(XcbRandrData* data, xcb_screen_t* screen) { xcb_randr_get_monitors_cookie_t monitorsCookie = data->ffxcb_randr_get_monitors(data->connection, screen->root, true); - xcb_randr_get_monitors_reply_t* monitorsReply = data->ffxcb_randr_get_monitors_reply(data->connection, monitorsCookie, NULL); + FF_AUTO_FREE xcb_randr_get_monitors_reply_t* monitorsReply = data->ffxcb_randr_get_monitors_reply(data->connection, monitorsCookie, NULL); if(monitorsReply == NULL) return false; @@ -360,8 +351,6 @@ static bool xcbRandrHandleMonitors(XcbRandrData* data, xcb_screen_t* screen) data->ffxcb_randr_monitor_info_next(&monitorInfoIterator); } - free(monitorsReply); - return foundMonitor; } @@ -392,7 +381,9 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen) NULL, FF_DISPLAY_TYPE_UNKNOWN, false, - 0 + 0, + (uint32_t) screen->width_in_millimeters, + (uint32_t) screen->height_in_millimeters ); } diff --git a/src/detection/displayserver/linux/xlib.c b/src/detection/displayserver/linux/xlib.c index 567cdd25b..10e428e95 100644 --- a/src/detection/displayserver/linux/xlib.c +++ b/src/detection/displayserver/linux/xlib.c @@ -87,7 +87,9 @@ void ffdsConnectXlib(FFDisplayServerResult* result) NULL, FF_DISPLAY_TYPE_UNKNOWN, false, - 0 + 0, + (uint32_t) WidthMMOfScreen(screen), + (uint32_t) HeightMMOfScreen(screen) ); } @@ -149,7 +151,7 @@ static double xrandrHandleMode(XrandrData* data, RRMode mode) return 0; } -static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc, FFstrbuf* name, bool primary) +static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc, FFstrbuf* name, bool primary, XRROutputInfo* output) { //We do the check here, because we want the best fallback display if this call failed if(data->screenResources == NULL) @@ -187,7 +189,9 @@ static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc, FFstrbuf* name, bool name, FF_DISPLAY_TYPE_UNKNOWN, primary, - 0 + 0, + (uint32_t) output->mm_width, + (uint32_t) output->mm_height ); data->ffXRRFreeCrtcInfo(crtcInfo); @@ -218,7 +222,7 @@ static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name if (edidData) data->ffXFree(edidData); } - bool res = xrandrHandleCrtc(data, outputInfo->crtc, name, primary); + bool res = xrandrHandleCrtc(data, outputInfo->crtc, name, primary, outputInfo); data->ffXRRFreeOutputInfo(outputInfo); @@ -248,7 +252,9 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo) &name, FF_DISPLAY_TYPE_UNKNOWN, !!monitorInfo->primary, - 0 + 0, + (uint32_t) monitorInfo->mwidth, + (uint32_t) monitorInfo->mheight ); } @@ -296,7 +302,9 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen) NULL, FF_DISPLAY_TYPE_UNKNOWN, false, - 0 + 0, + (uint32_t) WidthMMOfScreen(screen), + (uint32_t) HeightMMOfScreen(screen) ); } diff --git a/src/detection/monitor/monitor_apple.m b/src/detection/monitor/monitor_apple.m index 31b7ab9e3..8d99e5c11 100644 --- a/src/detection/monitor/monitor_apple.m +++ b/src/detection/monitor/monitor_apple.m @@ -19,7 +19,7 @@ static bool detectHdrSupportWithNSScreen(FFDisplayResult* display) NSScreen* mainScreen = NSScreen.mainScreen; if (display->primary) { - #ifdef MAC_OS_X_VERSION_10_15 + #ifdef MAC_OS_X_VERSION_10_15 return mainScreen.maximumPotentialExtendedDynamicRangeColorComponentValue > 1; #else return mainScreen.maximumExtendedDynamicRangeColorComponentValue > 1; @@ -100,10 +100,9 @@ const char* ffDetectMonitor(FFlist* results) monitor->physicalHeight = (uint32_t) (size.height + 0.5); monitor->hdrCompatible = CFDictionaryContainsKey(displayInfo, CFSTR("ReferencePeakHDRLuminance")) || detectHdrSupportWithNSScreen(display); + monitor->serial = CGDisplaySerialNumber((CGDirectDisplayID) display->id); - int64_t serial, year, week; - if (ffCfDictGetInt64(displayInfo, CFSTR("DisplaySerialNumber"), &serial) == NULL) - monitor->serial = (uint32_t) (uint64_t) serial; + int64_t year, week; if (ffCfDictGetInt64(displayInfo, CFSTR("DisplayYearManufacture"), &year) == NULL) monitor->manufactureYear = (uint16_t) year; if (ffCfDictGetInt64(displayInfo, CFSTR("DisplayWeekManufacture"), &week) == NULL) diff --git a/src/modules/display/display.c b/src/modules/display/display.c index 008f4ce66..dcfc6fad8 100644 --- a/src/modules/display/display.c +++ b/src/modules/display/display.c @@ -4,7 +4,7 @@ #include "modules/display/display.h" #include "util/stringUtils.h" -#define FF_DISPLAY_NUM_FORMAT_ARGS 9 +#define FF_DISPLAY_NUM_FORMAT_ARGS 11 static int sortByNameAsc(FFDisplayResult* a, FFDisplayResult* b) { @@ -135,6 +135,8 @@ void ffPrintDisplay(FFDisplayOptions* options) {FF_FORMAT_ARG_TYPE_STRING, displayType, "type"}, {FF_FORMAT_ARG_TYPE_UINT, &result->rotation, "rotation"}, {FF_FORMAT_ARG_TYPE_BOOL, &result->primary, "is-primary"}, + {FF_FORMAT_ARG_TYPE_UINT, &result->physicalWidth, "physical-width"}, + {FF_FORMAT_ARG_TYPE_UINT, &result->physicalHeight, "physical-height"}, })); } } @@ -291,8 +293,11 @@ void ffGenerateDisplayJsonResult(FF_MAYBE_UNUSED FFDisplayOptions* options, yyjs yyjson_mut_obj_add_bool(doc, obj, "primary", item->primary); yyjson_mut_obj_add_real(doc, obj, "refreshRate", item->refreshRate); yyjson_mut_obj_add_uint(doc, obj, "rotation", item->rotation); - yyjson_mut_obj_add_uint(doc, obj, "scaledHeight", item->scaledHeight); yyjson_mut_obj_add_uint(doc, obj, "scaledWidth", item->scaledWidth); + yyjson_mut_obj_add_uint(doc, obj, "scaledHeight", item->scaledHeight); + yyjson_mut_obj_add_uint(doc, obj, "physicalWidth", item->physicalWidth); + yyjson_mut_obj_add_uint(doc, obj, "physicalHeight", item->physicalHeight); + switch (item->type) { case FF_DISPLAY_TYPE_BUILTIN: @@ -320,6 +325,8 @@ void ffPrintDisplayHelpFormat(void) "Screen type (builtin, external or unknown) - type", "Screen rotation (in degrees) - rotation", "True if being the primary screen - is-primary", + "Screen physical width (in millimeters) - physical-width", + "Screen physical height (in millimeters) - physical-height", })); }