From 6f9167c725161a701696984ca4d5c7881625733b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 12 Jun 2023 10:35:28 +0800 Subject: [PATCH] Display: detect screen rotation --- src/detection/displayserver/displayserver.c | 2 + src/detection/displayserver/displayserver.h | 2 + .../displayserver/displayserver_apple.c | 7 ++- .../displayserver/displayserver_windows.c | 55 ++++++++++++------- src/detection/displayserver/linux/wayland.c | 42 +++++++++----- src/detection/displayserver/linux/xcb.c | 5 ++ src/detection/displayserver/linux/xlib.c | 5 ++ src/fastfetch.c | 7 ++- src/modules/display/display.c | 5 +- 9 files changed, 89 insertions(+), 41 deletions(-) diff --git a/src/detection/displayserver/displayserver.c b/src/detection/displayserver/displayserver.c index 270f4a93c..062f3be12 100644 --- a/src/detection/displayserver/displayserver.c +++ b/src/detection/displayserver/displayserver.c @@ -8,6 +8,7 @@ bool ffdsAppendDisplay( double refreshRate, uint32_t scaledWidth, uint32_t scaledHeight, + uint32_t rotation, FFstrbuf* name, FFDisplayType type) { @@ -20,6 +21,7 @@ bool ffdsAppendDisplay( display->refreshRate = refreshRate; display->scaledWidth = scaledWidth; display->scaledHeight = scaledHeight; + display->rotation = rotation; ffStrbufInitMove(&display->name, name); display->type = type; diff --git a/src/detection/displayserver/displayserver.h b/src/detection/displayserver/displayserver.h index be4ed37a4..52d0f34c9 100644 --- a/src/detection/displayserver/displayserver.h +++ b/src/detection/displayserver/displayserver.h @@ -50,6 +50,7 @@ typedef struct FFDisplayResult uint32_t scaledHeight; FFstrbuf name; FFDisplayType type; + uint32_t rotation; } FFDisplayResult; typedef struct FFDisplayServerResult @@ -72,6 +73,7 @@ bool ffdsAppendDisplay( double refreshRate, uint32_t scaledWidth, uint32_t scaledHeight, + uint32_t rotation, FFstrbuf* name, FFDisplayType type); diff --git a/src/detection/displayserver/displayserver_apple.c b/src/detection/displayserver/displayserver_apple.c index e2ae57c5d..a49e5f74b 100644 --- a/src/detection/displayserver/displayserver_apple.c +++ b/src/detection/displayserver/displayserver_apple.c @@ -12,7 +12,7 @@ extern CFDictionaryRef CoreDisplay_DisplayCreateInfoDictionary(CGDirectDisplayID display) __attribute__((weak_import)); -static void detectDisplays(FFDisplayServerResult* ds, bool detectName) +static void detectDisplays(FFDisplayServerResult* ds) { CGDirectDisplayID screens[128]; uint32_t screenCount; @@ -41,7 +41,7 @@ static void detectDisplays(FFDisplayServerResult* ds, bool detectName) } FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); - if(detectName && CoreDisplay_DisplayCreateInfoDictionary) + if(CoreDisplay_DisplayCreateInfoDictionary) { CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_DisplayCreateInfoDictionary(screen); if(displayInfo) @@ -58,6 +58,7 @@ static void detectDisplays(FFDisplayServerResult* ds, bool detectName) refreshRate, (uint32_t)CGDisplayModeGetWidth(mode), (uint32_t)CGDisplayModeGetHeight(mode), + (uint32_t)CGDisplayRotation(screen), &name, CGDisplayIsBuiltin(screen) ? FF_DISPLAY_TYPE_BUILTIN : FF_DISPLAY_TYPE_EXTERNAL ); @@ -120,5 +121,5 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins ffStrbufAppendS(&ds->dePrettyName, "Aqua"); ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4); - detectDisplays(ds, instance->config.display.detectName); + detectDisplays(ds); } diff --git a/src/detection/displayserver/displayserver_windows.c b/src/detection/displayserver/displayserver_windows.c index 9b7bec99b..12921f4e7 100644 --- a/src/detection/displayserver/displayserver_windows.c +++ b/src/detection/displayserver/displayserver_windows.c @@ -5,7 +5,7 @@ #include #include -static void detectDisplays(FFDisplayServerResult* ds, bool detectName) +static void detectDisplays(FFDisplayServerResult* ds) { DISPLAYCONFIG_PATH_INFO paths[128]; uint32_t pathCount = sizeof(paths) / sizeof(paths[0]); @@ -44,26 +44,23 @@ static void detectDisplays(FFDisplayServerResult* ds, bool detectName) FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); - if (detectName) + DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = { + .header = { + .type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME, + .size = sizeof(targetName), + .adapterId = path->targetInfo.adapterId, + .id = path->targetInfo.id, + }, + }; + if(DisplayConfigGetDeviceInfo(&targetName.header) == ERROR_SUCCESS) { - DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = { - .header = { - .type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME, - .size = sizeof(targetName), - .adapterId = path->targetInfo.adapterId, - .id = path->targetInfo.id, - }, - }; - if(DisplayConfigGetDeviceInfo(&targetName.header) == ERROR_SUCCESS) + if (targetName.flags.friendlyNameFromEdid) + ffStrbufSetWS(&name, targetName.monitorFriendlyDeviceName); + else { - if (targetName.flags.friendlyNameFromEdid) - ffStrbufSetWS(&name, targetName.monitorFriendlyDeviceName); - else - { - ffStrbufSetWS(&name, targetName.monitorDevicePath); - ffStrbufSubstrAfterFirstC(&name, '#'); - ffStrbufSubstrBeforeFirstC(&name, '#'); - } + ffStrbufSetWS(&name, targetName.monitorDevicePath); + ffStrbufSubstrAfterFirstC(&name, '#'); + ffStrbufSubstrBeforeFirstC(&name, '#'); } } @@ -77,12 +74,30 @@ static void detectDisplays(FFDisplayServerResult* ds, bool detectName) height = temp; } + 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; + } + ffdsAppendDisplay(ds, width, height, path->targetInfo.refreshRate.Numerator / (double) path->targetInfo.refreshRate.Denominator, scaledWidth, scaledHeight, + rotation, &name, path->targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL || path->targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED || @@ -112,7 +127,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins ffStrbufInit(&ds->deVersion); ffListInit(&ds->displays, sizeof(FFDisplayResult)); - detectDisplays(ds, instance->config.display.detectName); + detectDisplays(ds); //https://github.com/hykilpikonna/hyfetch/blob/master/neofetch#L2067 const FFOSResult* os = ffDetectOS(instance); diff --git a/src/detection/displayserver/linux/wayland.c b/src/detection/displayserver/linux/wayland.c index b4e31f77e..9e95eb1c5 100644 --- a/src/detection/displayserver/linux/wayland.c +++ b/src/detection/displayserver/linux/wayland.c @@ -19,7 +19,6 @@ typedef struct WaylandData FF_LIBRARY_SYMBOL(wl_display_roundtrip) struct wl_display* display; const struct wl_interface* ffwl_output_interface; - bool detectName; } WaylandData; typedef struct WaylandDisplay @@ -31,7 +30,6 @@ typedef struct WaylandDisplay enum wl_output_transform transform; FFDisplayType type; FFstrbuf name; - bool detectName; } WaylandDisplay; #ifndef __FreeBSD__ @@ -92,16 +90,14 @@ static void waylandOutputGeometryListener(void *data, { WaylandDisplay* display = data; display->transform = (enum wl_output_transform) transform; - if(display->detectName) + + if(make && strcmp(make, "unknown") != 0) + ffStrbufAppendS(&display->name, make); + if(model && strcmp(model, "unknown") != 0) { - if(make && strcmp(make, "unknown") != 0) - ffStrbufAppendS(&display->name, make); - if(model && strcmp(model, "unknown") != 0) - { - if(display->name.length > 0) - ffStrbufAppendC(&display->name, '-'); - ffStrbufAppendS(&display->name, model); - } + if(display->name.length > 0) + ffStrbufAppendC(&display->name, '-'); + ffStrbufAppendS(&display->name, model); } } @@ -123,7 +119,6 @@ static void waylandOutputHandler(WaylandData* wldata, struct wl_registry* regist return; WaylandDisplay display = { - .detectName = wldata->detectName, .width = 0, .height = 0, .refreshRate = 0, @@ -179,12 +174,33 @@ static void waylandOutputHandler(WaylandData* wldata, struct wl_registry* regist break; } + uint32_t rotation; + switch(display.transform) + { + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + case WL_OUTPUT_TRANSFORM_90: + rotation = 90; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + case WL_OUTPUT_TRANSFORM_180: + rotation = 180; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + case WL_OUTPUT_TRANSFORM_270: + rotation = 270; + break; + default: + rotation = 0; + break; + } + ffdsAppendDisplay(wldata->result, (uint32_t) display.width, (uint32_t) display.height, display.refreshRate / 1000.0, (uint32_t) (display.width / display.scale), (uint32_t) (display.height / display.scale), + rotation, &display.name, display.type ); @@ -223,8 +239,6 @@ bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result) if(data.display == NULL) return false; - data.detectName = instance->config.display.detectName; - waylandDetectWM(ffwl_display_get_fd(data.display), result); struct wl_proxy* registry = ffwl_proxy_marshal_constructor((struct wl_proxy*) data.display, WL_DISPLAY_GET_REGISTRY, ffwl_registry_interface, NULL); diff --git a/src/detection/displayserver/linux/xcb.c b/src/detection/displayserver/linux/xcb.c index 447c76bb2..c81bf46db 100644 --- a/src/detection/displayserver/linux/xcb.c +++ b/src/detection/displayserver/linux/xcb.c @@ -118,6 +118,7 @@ void ffdsConnectXcb(const FFinstance* instance, FFDisplayServerResult* result) 0, (uint32_t) iterator.data->width_in_pixels, (uint32_t) iterator.data->height_in_pixels, + 0, NULL, FF_DISPLAY_TYPE_UNKNOWN ); @@ -184,6 +185,7 @@ static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* mo refreshRate == 0 ? data->defaultRefreshRate : refreshRate, (uint32_t) modeInfo->width, (uint32_t) modeInfo->height, + 0, NULL, FF_DISPLAY_TYPE_UNKNOWN ); @@ -223,6 +225,7 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc) data->defaultRefreshRate, (uint32_t) crtcInfoReply->width, (uint32_t) crtcInfoReply->height, + 0, NULL, FF_DISPLAY_TYPE_UNKNOWN ); @@ -270,6 +273,7 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t* data->defaultRefreshRate, (uint32_t) monitor->width, (uint32_t) monitor->height, + 0, NULL, FF_DISPLAY_TYPE_UNKNOWN ); @@ -332,6 +336,7 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen) data->defaultRefreshRate, (uint32_t) screen->width_in_pixels, (uint32_t) screen->height_in_pixels, + 0, NULL, FF_DISPLAY_TYPE_UNKNOWN ); diff --git a/src/detection/displayserver/linux/xlib.c b/src/detection/displayserver/linux/xlib.c index 13a08b2a5..56a72ddf5 100644 --- a/src/detection/displayserver/linux/xlib.c +++ b/src/detection/displayserver/linux/xlib.c @@ -83,6 +83,7 @@ void ffdsConnectXlib(const FFinstance* instance, FFDisplayServerResult* result) 0, (uint32_t) WidthOfScreen(screen), (uint32_t) HeightOfScreen(screen), + 0, NULL, FF_DISPLAY_TYPE_UNKNOWN ); @@ -143,6 +144,7 @@ static bool xrandrHandleModeInfo(XrandrData* data, XRRModeInfo* modeInfo) refreshRate == 0 ? data->defaultRefreshRate : refreshRate, (uint32_t) modeInfo->width, (uint32_t) modeInfo->height, + 0, NULL, FF_DISPLAY_TYPE_UNKNOWN ); @@ -176,6 +178,7 @@ static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc) data->defaultRefreshRate, (uint32_t) crtcInfo->width, (uint32_t) crtcInfo->height, + 0, NULL, FF_DISPLAY_TYPE_UNKNOWN ); @@ -214,6 +217,7 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo) data->defaultRefreshRate, (uint32_t) monitorInfo->width, (uint32_t) monitorInfo->height, + 0, NULL, FF_DISPLAY_TYPE_UNKNOWN ); @@ -270,6 +274,7 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen) data->defaultRefreshRate, (uint32_t) WidthOfScreen(screen), (uint32_t) HeightOfScreen(screen), + 0, NULL, FF_DISPLAY_TYPE_UNKNOWN ); diff --git a/src/fastfetch.c b/src/fastfetch.c index 2b5e5600d..cfd9e7190 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -177,12 +177,15 @@ static inline void printCommandHelp(const char* command) } else if(strcasecmp(command, "display-format") == 0) { - constructAndPrintCommandHelpFormat("display", "{}x{} @ {}Hz", 5, + constructAndPrintCommandHelpFormat("display", "{}x{} @ {}Hz", 7, "Screen width", "Screen height", "Screen refresh rate", "Screen scaled width", - "Screen scaled height" + "Screen scaled height", + "Screen name", + "Screen type", + "Screen rotation" ); } else if(strcasecmp(command, "de-format") == 0) diff --git a/src/modules/display/display.c b/src/modules/display/display.c index 53ccf74aa..f97f130ec 100644 --- a/src/modules/display/display.c +++ b/src/modules/display/display.c @@ -3,7 +3,7 @@ #include "detection/displayserver/displayserver.h" #include "modules/display/display.h" -#define FF_DISPLAY_NUM_FORMAT_ARGS 7 +#define FF_DISPLAY_NUM_FORMAT_ARGS 8 void ffPrintDisplay(FFinstance* instance, FFDisplayOptions* options) { @@ -53,7 +53,7 @@ void ffPrintDisplay(FFinstance* instance, FFDisplayOptions* options) if(options->moduleArgs.outputFormat.length == 0) { - if(result->name.length || (moduleIndex > 0 && displayType)) + if((options->detectName && result->name.length) || (moduleIndex > 0 && displayType)) { ffStrbufClear(&key); if(options->moduleArgs.key.length == 0) @@ -102,6 +102,7 @@ void ffPrintDisplay(FFinstance* instance, FFDisplayOptions* options) {FF_FORMAT_ARG_TYPE_UINT, &result->scaledHeight}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, {FF_FORMAT_ARG_TYPE_STRING, displayType}, + {FF_FORMAT_ARG_TYPE_UINT, &result->rotation}, }); }