diff --git a/src/detection/displayserver/displayserver.c b/src/detection/displayserver/displayserver.c index 7defa401e..4a42a21a1 100644 --- a/src/detection/displayserver/displayserver.c +++ b/src/detection/displayserver/displayserver.c @@ -1,6 +1,37 @@ #include "displayserver.h" #include "detection/internal.h" +uint32_t ffdsParseRefreshRate(int32_t refreshRate) +{ + if(refreshRate <= 0) + return 0; + + int remainder = refreshRate % 5; + if(remainder >= 3) + refreshRate += (5 - remainder); + else + refreshRate -= remainder; + + //All other typicall refresh rates are dividable by 5 + if(refreshRate == 145) + refreshRate = 144; + + return (uint32_t) refreshRate; +} + +bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate) +{ + if(width == 0 || height == 0) + return false; + + FFResolutionResult* resolution = ffListAdd(&result->resolutions); + resolution->width = width; + resolution->height = height; + resolution->refreshRate = refreshRate; + + return true; +} + void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance); const FFDisplayServerResult* ffConnectDisplayServer(const FFinstance* instance) diff --git a/src/detection/displayserver/displayserver.h b/src/detection/displayserver/displayserver.h index beafe73b0..d31d5edee 100644 --- a/src/detection/displayserver/displayserver.h +++ b/src/detection/displayserver/displayserver.h @@ -25,5 +25,8 @@ typedef struct FFDisplayServerResult const FFDisplayServerResult* ffConnectDisplayServer(const FFinstance* instance); -#endif +//Used internal +uint32_t ffdsParseRefreshRate(int32_t refreshRate); +bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate); +#endif diff --git a/src/detection/displayserver/displayserver_apple.c b/src/detection/displayserver/displayserver_apple.c index ec3aa08f3..66371e306 100644 --- a/src/detection/displayserver/displayserver_apple.c +++ b/src/detection/displayserver/displayserver_apple.c @@ -1,4 +1,68 @@ #include "displayserver.h" +#include "common/library.h" + +#include +#include + +//Resolution code heavily inspired by displayplacer <3 + +typedef union +{ + uint8_t rawData[0xDC]; + struct + { + uint32_t mode; + uint32_t flags; // 0x4 + uint32_t width; // 0x8 + uint32_t height; // 0xC + uint32_t depth; // 0x10 + uint32_t dc2[42]; + uint16_t dc3; + uint16_t freq; // 0xBC + uint32_t dc4[4]; + float density; // 0xD0 + } derived; +} modes_D4; + +void CGSGetCurrentDisplayMode(CGDirectDisplayID display, int* modeNum); +void CGSGetDisplayModeDescriptionOfLength(CGDirectDisplayID display, int idx, modes_D4* mode, int length); + +static void detectResolution(FFDisplayServerResult* ds) +{ + void* iokit = dlopen(FASTFETCH_TARGET_DIR_ROOT"/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics", RTLD_LAZY); + if(iokit == NULL) + return; + + FF_LIBRARY_LOAD_SYMBOL(iokit, CGGetOnlineDisplayList, ) + FF_LIBRARY_LOAD_SYMBOL(iokit, CGDisplayScreenSize, ) + FF_LIBRARY_LOAD_SYMBOL(iokit, CGSGetCurrentDisplayMode, ) + FF_LIBRARY_LOAD_SYMBOL(iokit, CGSGetDisplayModeDescriptionOfLength, ) + + CGDisplayCount screenCount; + ffCGGetOnlineDisplayList(INT_MAX, NULL, &screenCount); + if(screenCount == 0) + { + dlclose(iokit); + return; + } + + CGDirectDisplayID* screens = malloc(screenCount * sizeof(CGDirectDisplayID)); + ffCGGetOnlineDisplayList(INT_MAX, screens, &screenCount); + + for(uint32_t i = 0; i < screenCount; i++) + { + int modeID; + ffCGSGetCurrentDisplayMode(screens[i], &modeID); + modes_D4 mode; + ffCGSGetDisplayModeDescriptionOfLength(screens[i], modeID, &mode, 0xD4); + + uint32_t refreshRate = ffdsParseRefreshRate(mode.derived.freq); + ffdsAppendResolution(ds, mode.derived.width, mode.derived.height, refreshRate); + } + + free(screens); + dlclose(iokit); +} void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance) { @@ -16,7 +80,9 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins ffStrbufInit(&ds->dePrettyName); ffStrbufAppendS(&ds->dePrettyName, "Aqua"); + ffListInitA(&ds->resolutions, sizeof(FFResolutionResult), 4); + detectResolution(ds); + ffStrbufInitA(&ds->deVersion, 0); ffStrbufInitA(&ds->wmProtocolName, 0); - ffListInitA(&ds->resolutions, sizeof(FFResolutionResult), 0); } diff --git a/src/detection/displayserver/linux/displayserver_linux.c b/src/detection/displayserver/linux/displayserver_linux.c index 906f78044..68812cec2 100644 --- a/src/detection/displayserver/linux/displayserver_linux.c +++ b/src/detection/displayserver/linux/displayserver_linux.c @@ -2,37 +2,6 @@ #include -uint32_t ffdsParseRefreshRate(int32_t refreshRate) -{ - if(refreshRate <= 0) - return 0; - - int remainder = refreshRate % 5; - if(remainder >= 3) - refreshRate += (5 - remainder); - else - refreshRate -= remainder; - - //All other typicall refresh rates are dividable by 5 - if(refreshRate == 145) - refreshRate = 144; - - return (uint32_t) refreshRate; -} - -bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate) -{ - if(width == 0 || height == 0) - return false; - - FFResolutionResult* resolution = ffListAdd(&result->resolutions); - resolution->width = width; - resolution->height = height; - resolution->refreshRate = refreshRate; - - return true; -} - static void parseDRM(FFDisplayServerResult* result) { const char* drmDirPath = "/sys/class/drm/"; diff --git a/src/detection/displayserver/linux/displayserver_linux.h b/src/detection/displayserver/linux/displayserver_linux.h index f08ea9a61..9c7588058 100644 --- a/src/detection/displayserver/linux/displayserver_linux.h +++ b/src/detection/displayserver/linux/displayserver_linux.h @@ -9,9 +9,6 @@ #define FF_DISPLAYSERVER_PROTOCOL_X11 "X11" #define FF_DISPLAYSERVER_PROTOCOL_TTY "TTY" -uint32_t ffdsParseRefreshRate(int32_t refreshRate); -bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate); - void ffdsConnectWayland(const FFinstance* instance, FFDisplayServerResult* result); void ffdsConnectXcbRandr(const FFinstance* instance, FFDisplayServerResult* result);