Monitor: detect serial number and manufacture date

This commit is contained in:
李通洲
2024-01-10 16:34:14 +08:00
parent f5a57ab747
commit 0645f559af
7 changed files with 72 additions and 6 deletions
+3
View File
@@ -8,6 +8,9 @@ typedef struct FFMonitorResult
uint32_t physicalWidth; // in mm
uint32_t physicalHeight; // in mm
bool hdrCompatible;
uint16_t manufactureYear;
uint16_t manufactureWeek;
uint32_t serial;
} FFMonitorResult;
const char* ffDetectMonitor(FFlist* results);
+13 -1
View File
@@ -40,9 +40,13 @@ const char* ffDetectMonitor(FFlist* results)
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_DisplayCreateInfoDictionary((CGDirectDisplayID) display->id);
if(!displayInfo) continue;
bool isVirtual = false;
if (ffCfDictGetBool(displayInfo, CFSTR("kCGDisplayIsVirtualDevice"), &isVirtual) == NULL && isVirtual)
continue;
uint8_t edidData[128] = {};
uint32_t edidLength = 0;
if (false || !ffCfDictGetData(displayInfo, CFSTR("IODisplayEDID"), 0, sizeof(edidData), edidData, &edidLength))
if (ffCfDictGetData(displayInfo, CFSTR("IODisplayEDID"), 0, sizeof(edidData), edidData, &edidLength) == NULL)
{
uint32_t width, height;
ffEdidGetPhysicalResolution(edidData, &width, &height);
@@ -75,6 +79,14 @@ const char* ffDetectMonitor(FFlist* results)
monitor->physicalHeight = (uint32_t) (size.height + 0.5);
monitor->hdrCompatible = CFDictionaryContainsKey(displayInfo, CFSTR("ReferencePeakHDRLuminance")) ||
detectHdrSupportWithNSScreen(display);
int64_t serial, year, week;
if (ffCfDictGetInt64(displayInfo, CFSTR("DisplaySerialNumber"), &serial) == NULL)
monitor->serial = (uint32_t) (uint64_t) serial;
if (ffCfDictGetInt64(displayInfo, CFSTR("DisplayYearManufacture"), &year) == NULL)
monitor->manufactureYear = (uint16_t) year;
if (ffCfDictGetInt64(displayInfo, CFSTR("DisplayWeekManufacture"), &week) == NULL)
monitor->manufactureWeek = (uint16_t) week;
}
return NULL;
+1
View File
@@ -59,6 +59,7 @@ const char* ffDetectMonitor(FFlist* results)
ffStrbufInit(&display->name);
ffEdidGetName(edidData, &display->name);
ffEdidGetPhysicalSize(edidData, &display->physicalWidth, &display->physicalHeight);
ffEdidGetSerialAndManufactureDate(edidData, &display->serial, &display->manufactureYear, &display->manufactureWeek);
display->hdrCompatible = ffEdidGetHdrCompatible(edidData, (uint32_t) edidLength);
}
+1
View File
@@ -44,6 +44,7 @@ const char* ffDetectMonitor(FFlist* results)
FFMonitorResult* display = (FFMonitorResult*) ffListAdd(results);
display->width = width;
display->height = height;
ffEdidGetSerialAndManufactureDate(edidData, &display->serial, &display->manufactureYear, &display->manufactureWeek);
display->hdrCompatible = ffEdidGetHdrCompatible(edidData, edidLength); // Doesn't work. edidLength is always 128
ffStrbufInit(&display->name);
ffEdidGetName(edidData, &display->name);
+39 -5
View File
@@ -59,6 +59,15 @@ void ffPrintMonitor(FFMonitorOptions* options)
}
else
{
char buf[32];
if (display->serial)
{
const uint8_t* nums = (uint8_t*) &display->serial;
snprintf(buf, sizeof(buf), "%2X-%2X-%2X-%2X", nums[0], nums[1], nums[2], nums[3]);
}
else
buf[0] = '\0';
ffPrintFormatString(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_MONITOR_NUM_FORMAT_ARGS, (FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &display->name},
{FF_FORMAT_ARG_TYPE_UINT, &display->width},
@@ -67,6 +76,9 @@ void ffPrintMonitor(FFMonitorOptions* options)
{FF_FORMAT_ARG_TYPE_UINT, &display->physicalHeight},
{FF_FORMAT_ARG_TYPE_DOUBLE, &inch},
{FF_FORMAT_ARG_TYPE_DOUBLE, &ppi},
{FF_FORMAT_ARG_TYPE_UINT16, &display->manufactureYear},
{FF_FORMAT_ARG_TYPE_UINT16, &display->manufactureWeek},
{FF_FORMAT_ARG_TYPE_STRING, buf},
});
}
@@ -131,11 +143,31 @@ void ffGenerateMonitorJsonResult(FF_MAYBE_UNUSED FFMonitorOptions* options, yyjs
{
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
yyjson_mut_obj_add_bool(doc, obj, "hdrCompatible", item->hdrCompatible);
yyjson_mut_obj_add_uint(doc, obj, "width", item->width);
yyjson_mut_obj_add_uint(doc, obj, "height", item->height);
yyjson_mut_obj_add_strbuf(doc, obj, "name", &item->name);
yyjson_mut_obj_add_uint(doc, obj, "physicalHeight", item->physicalHeight);
yyjson_mut_obj_add_uint(doc, obj, "physicalWidth", item->physicalWidth);
yyjson_mut_val* resolution = yyjson_mut_obj_add_obj(doc, obj, "resolution");
yyjson_mut_obj_add_uint(doc, resolution, "width", item->width);
yyjson_mut_obj_add_uint(doc, resolution, "height", item->height);
yyjson_mut_val* physical = yyjson_mut_obj_add_obj(doc, obj, "physical");
yyjson_mut_obj_add_uint(doc, physical, "height", item->physicalHeight);
yyjson_mut_obj_add_uint(doc, physical, "width", item->physicalWidth);
if (item->manufactureYear)
{
yyjson_mut_val* manufactureDate = yyjson_mut_obj_add_obj(doc, obj, "manufactureDate");
yyjson_mut_obj_add_uint(doc, manufactureDate, "year", item->manufactureYear);
yyjson_mut_obj_add_uint(doc, manufactureDate, "week", item->manufactureWeek);
}
else
{
yyjson_mut_obj_add_null(doc, obj, "manufactureDate");
}
if (item->serial)
yyjson_mut_obj_add_uint(doc, obj, "serial", item->serial);
else
yyjson_mut_obj_add_null(doc, obj, "serial");
}
}
@@ -154,7 +186,9 @@ void ffPrintMonitorHelpFormat(void)
"Display physical width in millimeters",
"Display physical height in millimeters",
"Display physical diagonal length in inches",
"Display physical pixels per inch (PPI)"
"Year of manufacturing",
"Nth week of manufacturing in the year",
"Serial number",
});
}
+14
View File
@@ -50,6 +50,20 @@ void ffEdidGetPhysicalSize(const uint8_t edid[128], uint32_t* width, uint32_t* h
*height = (((uint32_t) edid[68] & 0x0F) << 8) + edid[67];
}
void ffEdidGetSerialAndManufactureDate(const uint8_t edid[128], uint32_t* serial, uint16_t* year, uint16_t* week)
{
if (edid[17] > 0 && edid[17] < 0xFF)
{
*year = edid[17] + 1990;
*week = edid[16];
if (*week == 0xFF) *week = 0;
}
else
*year = *week = 0;
*serial = *(uint32_t*) &edid[12];
}
bool ffEdidGetHdrCompatible(const uint8_t* edid, uint32_t length)
{
if (length <= 128) return false;
+1
View File
@@ -7,4 +7,5 @@ void ffEdidGetVendorAndModel(const uint8_t edid[128], FFstrbuf* result);
bool ffEdidGetName(const uint8_t edid[128], FFstrbuf* name);
void ffEdidGetPhysicalResolution(const uint8_t edid[128], uint32_t* width, uint32_t* height);
void ffEdidGetPhysicalSize(const uint8_t edid[128], uint32_t* width, uint32_t* height); // in mm
void ffEdidGetSerialAndManufactureDate(const uint8_t edid[128], uint32_t* serial, uint16_t* year, uint16_t* week);
bool ffEdidGetHdrCompatible(const uint8_t* edid, uint32_t length);