Display: fetch text serial if available instead of the 4-byte integer

This commit is contained in:
Carter Li
2026-06-19 18:53:10 +08:00
parent 240928138e
commit 5fd059827d
14 changed files with 72 additions and 38 deletions
+2 -1
View File
@@ -8,6 +8,7 @@ bool ffEdidGetName(const uint8_t edid[128], FFstrbuf* name);
void ffEdidGetPreferredResolutionAndRefreshRate(const uint8_t edid[128], uint32_t* width, uint32_t* height, double* refreshRate);
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);
void ffEdidGetManufactureDate(const uint8_t edid[128], uint16_t* year, uint16_t* week);
bool ffEdidGetSerial(const uint8_t edid[128], FFstrbuf* result);
bool ffEdidGetHdrCompatible(const uint8_t* edid, uint32_t length);
bool ffEdidIsValid(const uint8_t edid[128], uint32_t length);
+43 -2
View File
@@ -66,7 +66,7 @@ void ffEdidGetPhysicalSize(const uint8_t edid[128], uint32_t* width, uint32_t* h
}
}
void ffEdidGetSerialAndManufactureDate(const uint8_t edid[128], uint32_t* serial, uint16_t* year, uint16_t* week) {
void ffEdidGetManufactureDate(const uint8_t edid[128], uint16_t* year, uint16_t* week) {
if (edid[17] > 0 && edid[17] < 0xFF) {
*year = (uint16_t) (edid[17] + 1990);
*week = (uint16_t) edid[16];
@@ -76,8 +76,49 @@ void ffEdidGetSerialAndManufactureDate(const uint8_t edid[128], uint32_t* serial
} else {
*year = *week = 0;
}
}
*serial = *(uint32_t*) &edid[12];
bool ffEdidGetSerial(const uint8_t edid[128], FFstrbuf* result) {
int descriptor_offsets[4] = {54, 72, 90, 108};
for (int i = 0; i < 4; i++) {
int offset = descriptor_offsets[i];
const uint8_t* desc = edid + offset;
if (desc[0] == 0x00 && desc[1] == 0x00) { // Monitor Descriptor
uint8_t tag = desc[3]; // Descriptor Type Tag
if (tag == 0xFF) { // Display Product Serial Number
ffStrbufClear(result);
for (int j = 0; j < 13; j++) {
uint8_t ch = desc[5 + j];
if (ch == 0x0A || ch == 0x00) {
break;
}
ffStrbufAppendC(result, (char) ch);
}
ffStrbufTrim(result, ' ');
if (result->length > 0) {
return true;
}
}
}
}
uint32_t int_serial = 0;
int_serial |= (uint32_t)edid[12];
int_serial |= (uint32_t)edid[13] << 8;
int_serial |= (uint32_t)edid[14] << 16;
int_serial |= (uint32_t)edid[15] << 24;
if (int_serial != 0 && int_serial != 0xFFFFFFFF) {
ffStrbufSetF(result, "0x%08X", int_serial);
return 0;
}
return false;
}
bool ffEdidGetHdrCompatible(const uint8_t* edid, uint32_t length) {
+1 -1
View File
@@ -42,7 +42,7 @@ FFDisplayResult* ffdsAppendDisplay(
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNKNOWN;
display->manufactureYear = 0;
display->manufactureWeek = 0;
display->serial = 0;
ffStrbufInit(&display->serial);
display->drrStatus = FF_DISPLAY_DRR_STATUS_UNKNOWN;
return display;
+1 -1
View File
@@ -89,7 +89,7 @@ typedef struct FFDisplayResult {
FFDisplayHdrStatus hdrStatus;
uint16_t manufactureYear;
uint16_t manufactureWeek;
uint32_t serial;
FFstrbuf serial;
FFDisplayVrrStatus drrStatus;
} FFDisplayResult;
@@ -196,7 +196,8 @@ static void detectDisplays(FFDisplayServerResult* ds) {
}
}
if (edid.length > 0) {
ffEdidGetSerialAndManufactureDate(edid.data, &display->serial, &display->manufactureYear, &display->manufactureWeek);
ffEdidGetManufactureDate(edid.data, &display->manufactureYear, &display->manufactureWeek);
ffEdidGetSerial(edid.data, &display->serial);
}
display->drrStatus = path->flags & DISPLAYCONFIG_PATH_BOOST_REFRESH_RATE ? FF_DISPLAY_DRR_STATUS_ENABLED : FF_DISPLAY_DRR_STATUS_DISABLED;
}
+8 -5
View File
@@ -96,7 +96,8 @@ static const char* drmParseSysfs(FFDisplayServerResult* result) {
"sysfs-drm");
if (item && edidLength) {
item->hdrStatus = ffEdidGetHdrCompatible(edidData, (uint32_t) edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
ffEdidGetSerialAndManufactureDate(edidData, &item->serial, &item->manufactureYear, &item->manufactureWeek);
ffEdidGetManufactureDate(edidData, &item->manufactureYear, &item->manufactureWeek);
ffEdidGetSerial(edidData, &item->serial);
}
ffStrbufSubstrBefore(&drmDir, drmDirLength);
@@ -327,7 +328,7 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result) {
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
uint16_t myear = 0, mweak = 0;
uint32_t serial = 0;
FF_STRBUF_AUTO_DESTROY serial = ffStrbufCreate();
FFDisplayHdrStatus hdrStatus = FF_DISPLAY_HDR_STATUS_UNKNOWN;
uint32_t* props = malloc(conn.count_props * sizeof(uint32_t));
@@ -363,7 +364,8 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result) {
if (ioctl(primaryFd, DRM_IOCTL_MODE_GETPROPBLOB, &blob) >= 0 && ffEdidIsValid(blobData, blob.length)) {
ffEdidGetName(blobData, &name);
hdrStatus = ffEdidGetHdrCompatible(blobData, blob.length) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
ffEdidGetSerialAndManufactureDate(blobData, &serial, &myear, &mweak);
ffEdidGetManufactureDate(blobData, &myear, &mweak);
ffEdidGetSerial(blobData, &serial);
}
}
break;
@@ -380,7 +382,8 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result) {
if (edidLength > 0 && edidLength % 128 == 0) {
ffEdidGetName(edidData, &name);
hdrStatus = ffEdidGetHdrCompatible(edidData, (uint32_t) edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
ffEdidGetSerialAndManufactureDate(edidData, &serial, &myear, &mweak);
ffEdidGetManufactureDate(edidData, &myear, &mweak);
ffEdidGetSerial(edidData, &serial);
}
}
#endif
@@ -416,7 +419,7 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result) {
if (item) {
item->hdrStatus = hdrStatus;
item->serial = serial;
ffStrbufInitMove(&item->serial, &serial);
item->manufactureYear = myear;
item->manufactureWeek = mweak;
item->bitDepth = bitDepth;
@@ -198,7 +198,7 @@ const char* ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry*
item->manufactureYear = display.myear;
item->manufactureWeek = display.mweek;
item->serial = display.serial;
ffStrbufInitMove(&item->serial, &display.serial);
}
ffStrbufDestroy(&display.description);
@@ -95,7 +95,8 @@ static void waylandKdeEdidListener(void* data, FF_A_UNUSED struct kde_output_dev
}
ffEdidGetName((const uint8_t*) edid.chars, &wldata->edidName);
wldata->hdrSupported = ffEdidGetHdrCompatible((const uint8_t*) edid.chars, edid.length);
ffEdidGetSerialAndManufactureDate((const uint8_t*) edid.chars, &wldata->serial, &wldata->myear, &wldata->mweek);
ffEdidGetManufactureDate((const uint8_t*) edid.chars, &wldata->myear, &wldata->mweek);
ffEdidGetSerial((const uint8_t*) edid.chars, &wldata->serial);
wldata->hdrInfoAvailable = true;
}
@@ -259,7 +260,7 @@ static const char* waylandKdeHandleOutput(WaylandData* wldata, struct wl_proxy*
item->manufactureYear = display.myear;
item->manufactureWeek = display.mweek;
item->serial = display.serial;
ffStrbufInitMove(&item->serial, &display.serial);
item->bitDepth = display.bitDepth;
}
@@ -130,7 +130,8 @@ static FF_A_UNUSED bool matchDrmConnector(const char* connName, WaylandDisplay*
if (edidLength > 0 && ffEdidIsValid(edidData, (uint32_t) edidLength)) {
ffEdidGetName(edidData, &wldata->edidName);
wldata->hdrSupported = ffEdidGetHdrCompatible(edidData, (uint32_t) edidLength);
ffEdidGetSerialAndManufactureDate(edidData, &wldata->serial, &wldata->myear, &wldata->mweek);
ffEdidGetManufactureDate((const uint8_t*) edidData, &wldata->myear, &wldata->mweek);
ffEdidGetSerial((const uint8_t*) edidData, &wldata->serial);
wldata->hdrInfoAvailable = true;
return true;
}
@@ -55,7 +55,7 @@ typedef struct WaylandDisplay {
bool hdrEnabled;
uint16_t myear;
uint16_t mweek;
uint32_t serial;
FFstrbuf serial;
uint8_t bitDepth;
bool primary;
} WaylandDisplay;
+2 -1
View File
@@ -227,7 +227,8 @@ static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output,
if (item) {
if (edidData && edidLength >= 128) {
item->hdrStatus = ffEdidGetHdrCompatible(edidData, (uint32_t) edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
ffEdidGetSerialAndManufactureDate(edidData, &item->serial, &item->manufactureYear, &item->manufactureWeek);
ffEdidGetManufactureDate(edidData, &item->manufactureYear, &item->manufactureWeek);
ffEdidGetSerial(edidData, &item->serial);
}
item->bitDepth = bitDepth;
if ((rotation == 90 || rotation == 180) && !randrEmulation) {
+2 -1
View File
@@ -161,7 +161,8 @@ static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf*
if (item) {
if (edidLength) {
item->hdrStatus = ffEdidGetHdrCompatible(edidData, edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
ffEdidGetSerialAndManufactureDate(edidData, &item->serial, &item->manufactureYear, &item->manufactureWeek);
ffEdidGetManufactureDate(edidData, &item->manufactureYear, &item->manufactureWeek);
ffEdidGetSerial(edidData, &item->serial);
}
item->bitDepth = bitDepth;
if ((rotation == 90 || rotation == 180) && !randrEmulation) {
+3 -11
View File
@@ -166,14 +166,6 @@ bool ffPrintDisplay(FFDisplayOptions* options) {
preferredRefreshRate[0] = 0;
}
char buf[32];
if (result->serial) {
const uint8_t* nums = (uint8_t*) &result->serial;
snprintf(buf, ARRAY_SIZE(buf), "%2X-%2X-%2X-%2X", nums[0], nums[1], nums[2], nums[3]);
} else {
buf[0] = '\0';
}
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, ((FFformatarg[]) {
FF_ARG(result->width, "width"),
FF_ARG(result->height, "height"),
@@ -192,7 +184,7 @@ bool ffPrintDisplay(FFDisplayOptions* options) {
FF_ARG(hdrEnabled, "hdr-enabled"),
FF_ARG(result->manufactureYear, "manufacture-year"),
FF_ARG(result->manufactureWeek, "manufacture-week"),
FF_ARG(buf, "serial"),
FF_ARG(result->serial, "serial"),
FF_ARG(result->platformApi, "platform-api"),
FF_ARG(hdrCompatible, "hdr-compatible"),
FF_ARG(scaleFactor, "scale-factor"),
@@ -395,8 +387,8 @@ bool ffGenerateDisplayJsonResult(FF_A_UNUSED FFDisplayOptions* options, yyjson_m
yyjson_mut_obj_add_null(doc, obj, "manufactureDate");
}
if (item->serial) {
yyjson_mut_obj_add_uint(doc, obj, "serial", item->serial);
if (item->serial.length) {
yyjson_mut_obj_add_strbuf(doc, obj, "serial", &item->serial);
} else {
yyjson_mut_obj_add_null(doc, obj, "serial");
}
+1 -9
View File
@@ -51,14 +51,6 @@ bool ffPrintMonitor(FFMonitorOptions* options) {
}
putchar('\n');
} 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';
}
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, ((FFformatarg[]) {
FF_ARG(display->name, "name"),
FF_ARG(display->width, "width"),
@@ -69,7 +61,7 @@ bool ffPrintMonitor(FFMonitorOptions* options) {
FF_ARG(ppi, "ppi"),
FF_ARG(display->manufactureYear, "manufacture-year"),
FF_ARG(display->manufactureWeek, "manufacture-week"),
FF_ARG(buf, "serial"),
FF_ARG(display->serial, "serial"),
FF_ARG(display->refreshRate, "refresh-rate"),
FF_ARG(hdrCompatible, "hdr-compatible"),
}));