mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2025-02-20 11:43:27 +08:00
PhycialDisplay (macOS): add support
This commit is contained in:
parent
bb0279bae1
commit
1d1ce83567
@ -541,7 +541,7 @@ elseif(APPLE)
|
||||
src/detection/gamepad/gamepad_apple.c
|
||||
src/detection/media/media_apple.m
|
||||
src/detection/memory/memory_apple.c
|
||||
src/detection/phycialdisplay/phycialdisplay_nosupport.c
|
||||
src/detection/phycialdisplay/phycialdisplay_apple.c
|
||||
src/detection/opengl/opengl_apple.c
|
||||
src/detection/os/os_apple.m
|
||||
src/detection/packages/packages_apple.c
|
||||
|
@ -1,20 +1,11 @@
|
||||
#include "brightness.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
#include "util/apple/cf_helpers.h"
|
||||
#include "util/apple/ddcci.h"
|
||||
#include "util/edidHelper.h"
|
||||
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
|
||||
extern int DisplayServicesGetBrightness(CGDirectDisplayID display, float *brightness) __attribute__((weak_import));
|
||||
|
||||
// DDC/CI
|
||||
typedef CFTypeRef IOAVServiceRef;
|
||||
extern IOAVServiceRef IOAVServiceCreate(CFAllocatorRef allocator) __attribute__((weak_import));
|
||||
extern IOAVServiceRef IOAVServiceCreateWithService(CFAllocatorRef allocator, io_service_t service) __attribute__((weak_import));
|
||||
extern IOReturn IOAVServiceCopyEDID(IOAVServiceRef service, CFDataRef* x2) __attribute__((weak_import));
|
||||
extern IOReturn IOAVServiceReadI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t offset, void* outputBuffer, uint32_t outputBufferSize) __attribute__((weak_import));
|
||||
extern IOReturn IOAVServiceWriteI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t dataAddress, void* inputBuffer, uint32_t inputBufferSize) __attribute__((weak_import));
|
||||
|
||||
// Works for internal display
|
||||
static const char* detectWithDisplayServices(const FFDisplayServerResult* displayServer, FFlist* result)
|
||||
{
|
||||
@ -23,12 +14,15 @@ static const char* detectWithDisplayServices(const FFDisplayServerResult* displa
|
||||
|
||||
FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays)
|
||||
{
|
||||
float value;
|
||||
if(DisplayServicesGetBrightness((CGDirectDisplayID) display->id, &value) == kCGErrorSuccess)
|
||||
if (display->type == FF_DISPLAY_TYPE_BUILTIN || display->type == FF_DISPLAY_TYPE_UNKNOWN)
|
||||
{
|
||||
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
|
||||
brightness->value = value * 100;
|
||||
ffStrbufInitCopy(&brightness->name, &display->name);
|
||||
float value;
|
||||
if(DisplayServicesGetBrightness((CGDirectDisplayID) display->id, &value) == kCGErrorSuccess)
|
||||
{
|
||||
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
|
||||
brightness->value = value * 100;
|
||||
ffStrbufInitCopy(&brightness->name, &display->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,22 +102,11 @@ static const char* detectWithDdcci(FFlist* result)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool hasBuiltinDisplay(const FFDisplayServerResult* displayServer)
|
||||
{
|
||||
FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays)
|
||||
{
|
||||
if (display->type == FF_DISPLAY_TYPE_BUILTIN || display->type == FF_DISPLAY_TYPE_UNKNOWN)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* ffDetectBrightness(FFlist* result)
|
||||
{
|
||||
const FFDisplayServerResult* displayServer = ffConnectDisplayServer();
|
||||
|
||||
if (hasBuiltinDisplay(displayServer))
|
||||
detectWithDisplayServices(displayServer, result);
|
||||
detectWithDisplayServices(displayServer, result);
|
||||
|
||||
if (instance.config.allowSlowOperations && displayServer->displays.length > result->length)
|
||||
detectWithDdcci(result);
|
||||
|
107
src/detection/phycialdisplay/phycialdisplay_apple.c
Normal file
107
src/detection/phycialdisplay/phycialdisplay_apple.c
Normal file
@ -0,0 +1,107 @@
|
||||
#include "phycialdisplay.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
#include "util/apple/cf_helpers.h"
|
||||
#include "util/apple/ddcci.h"
|
||||
#include "util/edidHelper.h"
|
||||
|
||||
extern CFDictionaryRef CoreDisplay_DisplayCreateInfoDictionary(CGDirectDisplayID display) __attribute__((weak_import));
|
||||
|
||||
static const char* detectWithDisplayServices(const FFDisplayServerResult* displayServer, FFlist* results)
|
||||
{
|
||||
if(!CoreDisplay_DisplayCreateInfoDictionary) return "CoreDisplay_DisplayCreateInfoDictionary is not available";
|
||||
|
||||
FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays)
|
||||
{
|
||||
if (display->type == FF_DISPLAY_TYPE_BUILTIN || display->type == FF_DISPLAY_TYPE_UNKNOWN)
|
||||
{
|
||||
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_DisplayCreateInfoDictionary((CGDirectDisplayID) display->id);
|
||||
if(displayInfo)
|
||||
{
|
||||
int width, height;
|
||||
if (ffCfDictGetInt(displayInfo, CFSTR("kCGDisplayPixelWidth"), &width) ||
|
||||
ffCfDictGetInt(displayInfo, CFSTR("kCGDisplayPixelHeight"), &height) ||
|
||||
width <= 0 || height <= 0)
|
||||
continue;
|
||||
|
||||
FFPhycialDisplayResult* display = (FFPhycialDisplayResult*) ffListAdd(results);
|
||||
display->width = (uint32_t) width;
|
||||
display->height = (uint32_t) height;
|
||||
ffStrbufInit(&display->name);
|
||||
|
||||
CFDictionaryRef productNames;
|
||||
if(!ffCfDictGetDict(displayInfo, CFSTR(kDisplayProductName), &productNames))
|
||||
ffCfDictGetString(productNames, CFSTR("en_US"), &display->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* detectWithDdcci(FFlist* results)
|
||||
{
|
||||
if (!IOAVServiceCreate || !IOAVServiceReadI2C)
|
||||
return "IOAVService is not available";
|
||||
|
||||
CFMutableDictionaryRef matchDict = IOServiceMatching("DCPAVServiceProxy");
|
||||
if (matchDict == NULL)
|
||||
return "IOServiceMatching(\"DCPAVServiceProxy\") failed";
|
||||
|
||||
io_iterator_t iterator;
|
||||
if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
|
||||
return "IOServiceGetMatchingServices() failed";
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY location = ffStrbufCreate();
|
||||
|
||||
io_registry_entry_t registryEntry;
|
||||
while((registryEntry = IOIteratorNext(iterator)) != 0)
|
||||
{
|
||||
CFMutableDictionaryRef properties;
|
||||
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
|
||||
{
|
||||
IOObjectRelease(registryEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
ffStrbufClear(&location);
|
||||
if(ffCfDictGetString(properties, CFSTR("Location"), &location) || ffStrbufEqualS(&location, "Embedded"))
|
||||
{
|
||||
// Builtin display should be handled by DisplayServices
|
||||
IOObjectRelease(registryEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
FF_CFTYPE_AUTO_RELEASE IOAVServiceRef service = IOAVServiceCreateWithService(kCFAllocatorDefault, (io_service_t) registryEntry);
|
||||
IOObjectRelease(registryEntry);
|
||||
|
||||
if (!service) continue;
|
||||
|
||||
FF_CFTYPE_AUTO_RELEASE CFDataRef edid = NULL;
|
||||
if (IOAVServiceCopyEDID(service, &edid) != KERN_SUCCESS )
|
||||
continue;
|
||||
|
||||
if (CFDataGetLength(edid) < 128)
|
||||
continue;
|
||||
|
||||
uint32_t width, height;
|
||||
ffEdidGetPhycialDisplay(CFDataGetBytePtr(edid), &width, &height);
|
||||
if (width == 0 || height == 0) continue;
|
||||
|
||||
FFPhycialDisplayResult* display = (FFPhycialDisplayResult*) ffListAdd(results);
|
||||
display->width = width;
|
||||
display->height = height;
|
||||
ffStrbufInit(&display->name);
|
||||
ffEdidGetName(CFDataGetBytePtr(edid), &display->name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* ffDetectPhycialDisplay(FFlist* results)
|
||||
{
|
||||
const FFDisplayServerResult* displayServer = ffConnectDisplayServer();
|
||||
|
||||
detectWithDisplayServices(displayServer, results);
|
||||
|
||||
if (displayServer->displays.length > results->length)
|
||||
detectWithDdcci(results);
|
||||
return NULL;
|
||||
}
|
15
src/util/apple/ddcci.h
Normal file
15
src/util/apple/ddcci.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FASTFETCH_INCLUDED_util_apple_ddcci_h
|
||||
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
|
||||
// DDC/CI
|
||||
typedef CFTypeRef IOAVServiceRef;
|
||||
extern IOAVServiceRef IOAVServiceCreate(CFAllocatorRef allocator) __attribute__((weak_import));
|
||||
extern IOAVServiceRef IOAVServiceCreateWithService(CFAllocatorRef allocator, io_service_t service) __attribute__((weak_import));
|
||||
extern IOReturn IOAVServiceCopyEDID(IOAVServiceRef service, CFDataRef* x2) __attribute__((weak_import));
|
||||
extern IOReturn IOAVServiceReadI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t offset, void* outputBuffer, uint32_t outputBufferSize) __attribute__((weak_import));
|
||||
extern IOReturn IOAVServiceWriteI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t dataAddress, void* inputBuffer, uint32_t inputBufferSize) __attribute__((weak_import));
|
||||
|
||||
#endif
|
@ -1,13 +1,13 @@
|
||||
#include "edidHelper.h"
|
||||
|
||||
void ffEdidGetPhycialDisplay(uint8_t edid[128], uint32_t* width, uint32_t* height)
|
||||
void ffEdidGetPhycialDisplay(const uint8_t edid[128], uint32_t* width, uint32_t* height)
|
||||
{
|
||||
const int dtd = 54;
|
||||
*width = (((uint32_t) edid[dtd + 4] >> 4) << 8) | edid[dtd + 2];
|
||||
*height = (((uint32_t) edid[dtd + 7] >> 4) << 8) | edid[dtd + 5];
|
||||
}
|
||||
|
||||
void ffEdidGetName(uint8_t edid[128], FFstrbuf* name)
|
||||
void ffEdidGetName(const uint8_t edid[128], FFstrbuf* name)
|
||||
{
|
||||
// https://github.com/jinksong/read_edid/blob/master/parse-edid/parse-edid.c
|
||||
for (uint32_t i = 0x36; i < 0x7E; i += 0x12)
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <stdint.h>
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
void ffEdidGetPhycialDisplay(uint8_t edid[128], uint32_t* width, uint32_t* height);
|
||||
void ffEdidGetName(uint8_t edid[128], FFstrbuf* name);
|
||||
void ffEdidGetPhycialDisplay(const uint8_t edid[128], uint32_t* width, uint32_t* height);
|
||||
void ffEdidGetName(const uint8_t edid[128], FFstrbuf* name);
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user