mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 10:22:12 +02:00
DisplayServer (Linux): check if RANDR is running in Emulation mode
This commit is contained in:
@@ -78,6 +78,19 @@ static void* xcbGetProperty(XcbRandrData* data, xcb_window_t window, const char*
|
||||
return replyValue;
|
||||
}
|
||||
|
||||
static xcb_randr_get_output_property_reply_t* xcbRandrGetProperty(XcbRandrData* data, xcb_randr_output_t output, const char* name)
|
||||
{
|
||||
xcb_intern_atom_cookie_t requestAtomCookie = data->ffxcb_intern_atom(data->connection, true, (uint16_t) strlen(name), name);
|
||||
FF_AUTO_FREE xcb_intern_atom_reply_t* requestAtomReply = data->ffxcb_intern_atom_reply(data->connection, requestAtomCookie, NULL);
|
||||
|
||||
if(requestAtomReply)
|
||||
{
|
||||
xcb_randr_get_output_property_cookie_t outputPropertyCookie = data->ffxcb_randr_get_output_property(data->connection, output, requestAtomReply->atom, XCB_GET_PROPERTY_TYPE_ANY, 0, 100, false, false);
|
||||
return data->ffxcb_randr_get_output_property_reply(data->connection, outputPropertyCookie, NULL);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void xcbDetectWMfromEWMH(XcbRandrData* data, xcb_window_t rootWindow, FFDisplayServerResult* result)
|
||||
{
|
||||
if(result->wmProcessName.length > 0 || ffStrbufCompS(&result->wmProtocolName, FF_WM_PROTOCOL_WAYLAND) == 0)
|
||||
@@ -121,28 +134,34 @@ static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output,
|
||||
if(outputInfoReply == NULL)
|
||||
return false;
|
||||
|
||||
xcb_intern_atom_cookie_t requestAtomCookie = data->ffxcb_intern_atom(data->connection, true, (uint16_t) strlen("EDID"), "EDID");
|
||||
FF_AUTO_FREE xcb_intern_atom_reply_t* requestAtomReply = data->ffxcb_intern_atom_reply(data->connection, requestAtomCookie, NULL);
|
||||
FF_AUTO_FREE xcb_randr_get_output_property_reply_t* outputPropertyReply = NULL;
|
||||
FF_AUTO_FREE xcb_randr_get_output_property_reply_t* edidReply = xcbRandrGetProperty(data, output, "EDID");
|
||||
uint8_t* edidData = NULL;
|
||||
uint32_t edidLength = 0;
|
||||
if(requestAtomReply)
|
||||
if(edidReply)
|
||||
{
|
||||
xcb_randr_get_output_property_cookie_t outputPropertyCookie = data->ffxcb_randr_get_output_property(data->connection, output, requestAtomReply->atom, XCB_GET_PROPERTY_TYPE_ANY, 0, 100, false, false);
|
||||
outputPropertyReply = data->ffxcb_randr_get_output_property_reply(data->connection, outputPropertyCookie, NULL);
|
||||
if(outputPropertyReply)
|
||||
int len = data->ffxcb_randr_get_output_property_data_length(edidReply);
|
||||
if(len >= 128)
|
||||
{
|
||||
int len = data->ffxcb_randr_get_output_property_data_length(outputPropertyReply);
|
||||
if(len >= 128)
|
||||
{
|
||||
ffStrbufClear(name);
|
||||
edidData = data->ffxcb_randr_get_output_property_data(outputPropertyReply);
|
||||
ffEdidGetName(edidData, name);
|
||||
edidLength = (uint32_t) len;
|
||||
}
|
||||
edidData = data->ffxcb_randr_get_output_property_data(edidReply);
|
||||
edidLength = (uint32_t) len;
|
||||
}
|
||||
}
|
||||
|
||||
if(edidData)
|
||||
{
|
||||
ffStrbufClear(name);
|
||||
ffEdidGetName(edidData, name);
|
||||
}
|
||||
|
||||
uint8_t randrEmulation = 0;
|
||||
FF_AUTO_FREE xcb_randr_get_output_property_reply_t* randrEmulationReply = xcbRandrGetProperty(data, output, "RANDR Emulation");
|
||||
if(randrEmulationReply)
|
||||
{
|
||||
int len = data->ffxcb_randr_get_output_property_data_length(randrEmulationReply);
|
||||
if(len >= 1)
|
||||
randrEmulation = data->ffxcb_randr_get_output_property_data(randrEmulationReply)[0];
|
||||
}
|
||||
|
||||
xcb_randr_get_crtc_info_cookie_t crtcInfoCookie = data->ffxcb_randr_get_crtc_info(data->connection, outputInfoReply->crtc, XCB_CURRENT_TIME);
|
||||
FF_AUTO_FREE xcb_randr_get_crtc_info_reply_t* crtcInfoReply = data->ffxcb_randr_get_crtc_info_reply(data->connection, crtcInfoCookie, NULL);
|
||||
if(crtcInfoReply == NULL)
|
||||
@@ -204,9 +223,12 @@ static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output,
|
||||
0,
|
||||
(uint32_t) outputInfoReply->mm_width,
|
||||
(uint32_t) outputInfoReply->mm_height,
|
||||
currentMode ? "xcb-randr-mode" : "xcb-randr-crtc"
|
||||
randrEmulation
|
||||
? (currentMode ? "xcb-randr-emu-mode" : "xcb-randr-emu-crtc")
|
||||
: (currentMode ? "xcb-randr-mode" : "xcb-randr-crtc")
|
||||
|
||||
);
|
||||
if (item && edidLength)
|
||||
if (item && 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);
|
||||
|
||||
@@ -48,6 +48,32 @@ static unsigned char* x11GetProperty(XrandrData* data, Display* display, Window
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint8_t* xrandrGetProperty(XrandrData* data, RROutput output, const char* name, uint32_t* bufSize)
|
||||
{
|
||||
unsigned long size = 0;
|
||||
uint8_t* result = NULL;
|
||||
Atom atomEdid = data->ffXInternAtom(data->display, name, true);
|
||||
if (atomEdid != None)
|
||||
{
|
||||
int actual_format = 0;
|
||||
unsigned long bytes_after = 0;
|
||||
Atom actual_type = None;
|
||||
if (data->ffXRRGetOutputProperty(data->display, output, atomEdid, 0, 100, false, false, AnyPropertyType, &actual_type, &actual_format, &size, &bytes_after, &result) == Success)
|
||||
{
|
||||
if (size == 0)
|
||||
data->ffXFree(result);
|
||||
else
|
||||
{
|
||||
if (bufSize)
|
||||
*bufSize = (uint32_t) size;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void x11DetectWMFromEWMH(XrandrData* data, FFDisplayServerResult* result)
|
||||
{
|
||||
if(result->wmProcessName.length > 0 || ffStrbufCompS(&result->wmProtocolName, FF_WM_PROTOCOL_WAYLAND) == 0)
|
||||
@@ -75,7 +101,7 @@ static void x11FetchServerVendor(XrandrData* data, FFDisplayServerResult* result
|
||||
ffStrbufSetS(&result->wmProtocolName, serverVendor);
|
||||
}
|
||||
|
||||
static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf* name, bool primary, FFDisplayType displayType, uint8_t* edidData, uint32_t edidLength, XRRScreenResources* screenResources, uint8_t bitDepth, double scaleFactor)
|
||||
static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf* name, bool primary, FFDisplayType displayType, uint8_t* edidData, uint32_t edidLength, XRRScreenResources* screenResources, uint8_t bitDepth, double scaleFactor, bool randrEmulation)
|
||||
{
|
||||
//We do the check here, because we want the best fallback display if this call failed
|
||||
if(screenResources == NULL)
|
||||
@@ -131,7 +157,9 @@ static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf*
|
||||
0,
|
||||
(uint32_t) output->mm_width,
|
||||
(uint32_t) output->mm_height,
|
||||
currentMode ? "xlib-randr-mode" : "xlib-randr-crtc"
|
||||
randrEmulation
|
||||
? (currentMode ? "xlib-randr-emu-mode" : "xlib-randr-emu-crtc")
|
||||
: (currentMode ? "xlib-randr-mode" : "xlib-randr-crtc")
|
||||
);
|
||||
|
||||
if (item)
|
||||
@@ -154,30 +182,25 @@ static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name
|
||||
if(outputInfo == NULL)
|
||||
return false;
|
||||
|
||||
uint8_t* edidData = NULL;
|
||||
unsigned long edidLength = 0;
|
||||
Atom atomEdid = data->ffXInternAtom(data->display, "EDID", true);
|
||||
if (atomEdid != None)
|
||||
{
|
||||
int actual_format = 0;
|
||||
unsigned long bytes_after = 0;
|
||||
Atom actual_type = None;
|
||||
if (data->ffXRRGetOutputProperty(data->display, output, atomEdid, 0, 100, false, false, AnyPropertyType, &actual_type, &actual_format, &edidLength, &bytes_after, &edidData) == Success)
|
||||
{
|
||||
if (edidLength >= 128)
|
||||
{
|
||||
ffStrbufClear(name);
|
||||
ffEdidGetName(edidData, name);
|
||||
}
|
||||
else
|
||||
edidLength = 0;
|
||||
}
|
||||
}
|
||||
uint32_t edidLength = 0;
|
||||
uint8_t* edidData = xrandrGetProperty(data, output, RR_PROPERTY_RANDR_EDID, &edidLength);
|
||||
|
||||
bool res = xrandrHandleCrtc(data, outputInfo, name, primary, displayType, edidData, (uint32_t) edidLength, screenResources, bitDepth, scaleFactor);
|
||||
if (edidLength >= 128)
|
||||
{
|
||||
ffStrbufClear(name);
|
||||
ffEdidGetName(edidData, name);
|
||||
}
|
||||
else
|
||||
edidLength = 0;
|
||||
|
||||
uint8_t* randrEmulation = xrandrGetProperty(data, output, "RANDR Emulation", NULL);
|
||||
|
||||
bool res = xrandrHandleCrtc(data, outputInfo, name, primary, displayType, edidData, edidLength, screenResources, bitDepth, scaleFactor, randrEmulation ? !!randrEmulation[0] : false);
|
||||
|
||||
if (edidData)
|
||||
data->ffXFree(edidData);
|
||||
if (randrEmulation)
|
||||
data->ffXFree(randrEmulation);
|
||||
data->ffXRRFreeOutputInfo(outputInfo);
|
||||
|
||||
return res;
|
||||
|
||||
Reference in New Issue
Block a user