From 959540f17cec811ed57eab4c28c930bbdf4ac420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 7 Jan 2023 19:46:56 +0800 Subject: [PATCH] DisplayServer: support brightness detection (macOS) --- CMakeLists.txt | 1 + README.md | 1 + src/detection/displayserver/displayserver.c | 3 ++- src/detection/displayserver/displayserver.h | 3 ++- src/detection/displayserver/displayserver_apple.c | 9 ++++++++- .../displayserver/displayserver_windows.c | 2 +- src/detection/displayserver/linux/xcb.c | 15 ++++++++++----- src/detection/displayserver/linux/xlib.c | 15 ++++++++++----- src/modules/resolution.c | 6 +++++- 9 files changed, 40 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b777ba3b..88e079485 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -652,6 +652,7 @@ if(APPLE) PRIVATE "-framework Cocoa" PRIVATE "-framework CoreWLAN" PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks" + PRIVATE "-weak_framework DisplayServices -F /System/Library/PrivateFrameworks" ) elseif(WIN32) target_compile_definitions(libfastfetch PRIVATE -D_WIN32_WINNT=0x0601) diff --git a/README.md b/README.md index 42ec1e3d0..8bce6372b 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ The following libraries are used if present at runtime: ### macOS * [`MediaRemote`](https://iphonedev.wiki/index.php/MediaRemote.framework): Need for Media detection. It's a private framework provided by newer macOS system. +* [`DisplayServices`](https://developer.apple.com/forums/thread/666383#663154022): Need for screen brightness detection. It's a private framework provided by newer macOS system. * [`MoltenVK`](https://github.com/KhronosGroup/MoltenVK): Vulkan driver for macOS. [`molten-vk`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/molten-vk.rb) * [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel graphics protocol. [`imagemagick`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/imagemagick.rb) * [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art. [`chafa`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/chafa.rb) diff --git a/src/detection/displayserver/displayserver.c b/src/detection/displayserver/displayserver.c index 4a42a21a1..e82279f4f 100644 --- a/src/detection/displayserver/displayserver.c +++ b/src/detection/displayserver/displayserver.c @@ -19,7 +19,7 @@ uint32_t ffdsParseRefreshRate(int32_t refreshRate) return (uint32_t) refreshRate; } -bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate) +bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate, int32_t brightness) { if(width == 0 || height == 0) return false; @@ -28,6 +28,7 @@ bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_ resolution->width = width; resolution->height = height; resolution->refreshRate = refreshRate; + resolution->brightness = brightness; return true; } diff --git a/src/detection/displayserver/displayserver.h b/src/detection/displayserver/displayserver.h index d31d5edee..16e6e67a6 100644 --- a/src/detection/displayserver/displayserver.h +++ b/src/detection/displayserver/displayserver.h @@ -10,6 +10,7 @@ typedef struct FFResolutionResult uint32_t width; uint32_t height; uint32_t refreshRate; + int32_t brightness; } FFResolutionResult; typedef struct FFDisplayServerResult @@ -27,6 +28,6 @@ const FFDisplayServerResult* ffConnectDisplayServer(const FFinstance* instance); //Used internal uint32_t ffdsParseRefreshRate(int32_t refreshRate); -bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate); +bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate, int32_t brightness); #endif diff --git a/src/detection/displayserver/displayserver_apple.c b/src/detection/displayserver/displayserver_apple.c index 4d0d802c2..88fd16477 100644 --- a/src/detection/displayserver/displayserver_apple.c +++ b/src/detection/displayserver/displayserver_apple.c @@ -7,6 +7,8 @@ #include #include +extern int DisplayServicesGetBrightness(CGDirectDisplayID display, float *brightness) __attribute__((weak_import)); + static void detectResolution(FFDisplayServerResult* ds) { CGDirectDisplayID screens[128]; @@ -20,10 +22,15 @@ static void detectResolution(FFDisplayServerResult* ds) CGDisplayModeRef mode = CGDisplayCopyDisplayMode(screen); if(mode) { + float brightness; + if(DisplayServicesGetBrightness == NULL || DisplayServicesGetBrightness(screen, &brightness) != kCGErrorSuccess) + brightness = -1; + ffdsAppendResolution(ds, (uint32_t)CGDisplayModeGetWidth(mode), (uint32_t)CGDisplayModeGetHeight(mode), - (uint32_t)CGDisplayModeGetRefreshRate(mode) + (uint32_t)CGDisplayModeGetRefreshRate(mode), + (int32_t)(brightness * 100) ); CGDisplayModeRelease(mode); } diff --git a/src/detection/displayserver/displayserver_windows.c b/src/detection/displayserver/displayserver_windows.c index f39955b8b..988d790a3 100644 --- a/src/detection/displayserver/displayserver_windows.c +++ b/src/detection/displayserver/displayserver_windows.c @@ -34,7 +34,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins if(EnumDisplaySettingsW(displayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &devMode) == 0) continue; - ffdsAppendResolution(ds, devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmDisplayFrequency); + ffdsAppendResolution(ds, devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmDisplayFrequency, -1); } //https://github.com/hykilpikonna/hyfetch/blob/master/neofetch#L2067 diff --git a/src/detection/displayserver/linux/xcb.c b/src/detection/displayserver/linux/xcb.c index 692be7808..f92e91e5a 100644 --- a/src/detection/displayserver/linux/xcb.c +++ b/src/detection/displayserver/linux/xcb.c @@ -119,7 +119,8 @@ void ffdsConnectXcb(const FFinstance* instance, FFDisplayServerResult* result) result, (uint32_t) iterator.data->width_in_pixels, (uint32_t) iterator.data->height_in_pixels, - 0 + 0, + -1 ); ffxcb_screen_next(&iterator); } @@ -184,7 +185,8 @@ static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* mo data->result, (uint32_t) modeInfo->width, (uint32_t) modeInfo->height, - refreshRate == 0 ? data->defaultRefreshRate : refreshRate + refreshRate == 0 ? data->defaultRefreshRate : refreshRate, + -1 ); } @@ -219,7 +221,8 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc) data->result, (uint32_t) crtcInfoReply->width, (uint32_t) crtcInfoReply->height, - data->defaultRefreshRate + data->defaultRefreshRate, + -1 ); free(crtcInfoReply); @@ -262,7 +265,8 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t* data->result, (uint32_t) monitor->width, (uint32_t) monitor->height, - data->defaultRefreshRate + data->defaultRefreshRate, + -1 ); } @@ -320,7 +324,8 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen) data->result, (uint32_t) screen->width_in_pixels, (uint32_t) screen->height_in_pixels, - data->defaultRefreshRate + data->defaultRefreshRate, + -1 ); } diff --git a/src/detection/displayserver/linux/xlib.c b/src/detection/displayserver/linux/xlib.c index 108de5946..d7429713f 100644 --- a/src/detection/displayserver/linux/xlib.c +++ b/src/detection/displayserver/linux/xlib.c @@ -83,7 +83,8 @@ void ffdsConnectXlib(const FFinstance* instance, FFDisplayServerResult* result) result, (uint32_t) screen->width, (uint32_t) screen->height, - 0 + 0, + -1 ); } @@ -142,7 +143,8 @@ static bool xrandrHandleModeInfo(XrandrData* data, XRRModeInfo* modeInfo) data->result, (uint32_t) modeInfo->width, (uint32_t) modeInfo->height, - refreshRate == 0 ? data->defaultRefreshRate : refreshRate + refreshRate == 0 ? data->defaultRefreshRate : refreshRate, + -1 ); } @@ -171,7 +173,8 @@ static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc) data->result, (uint32_t) crtcInfo->width, (uint32_t) crtcInfo->height, - data->defaultRefreshRate + data->defaultRefreshRate, + -1 ); data->ffXRRFreeCrtcInfo(crtcInfo); @@ -205,7 +208,8 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo) data->result, (uint32_t) monitorInfo->width, (uint32_t) monitorInfo->height, - data->defaultRefreshRate + data->defaultRefreshRate, + -1 ); } @@ -257,7 +261,8 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen) data->result, (uint32_t) WidthOfScreen(screen), (uint32_t) HeightOfScreen(screen), - data->defaultRefreshRate + data->defaultRefreshRate, + -1 ); } diff --git a/src/modules/resolution.c b/src/modules/resolution.c index 396d435b1..85c1b506a 100644 --- a/src/modules/resolution.c +++ b/src/modules/resolution.c @@ -27,6 +27,9 @@ void ffPrintResolution(FFinstance* instance) if(result->refreshRate > 0) printf(" @ %iHz", result->refreshRate); + if(result->brightness >= 0) + printf(" (☀️ %d%%)", result->brightness); + putchar('\n'); } else @@ -34,7 +37,8 @@ void ffPrintResolution(FFinstance* instance) ffPrintFormat(instance, FF_RESOLUTION_MODULE_NAME, moduleIndex, &instance->config.resolution, FF_RESOLUTION_NUM_FORMAT_ARGS, (FFformatarg[]) { {FF_FORMAT_ARG_TYPE_INT, &result->width}, {FF_FORMAT_ARG_TYPE_INT, &result->height}, - {FF_FORMAT_ARG_TYPE_INT, &result->refreshRate} + {FF_FORMAT_ARG_TYPE_INT, &result->refreshRate}, + {FF_FORMAT_ARG_TYPE_INT, &result->brightness}, }); } }