mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 10:22:12 +02:00
DisplayServer (Windows): support precise refresh rate
This commit is contained in:
@@ -1,25 +1,7 @@
|
||||
#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 ffdsAppendDisplay(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate, uint32_t scaledWidth, uint32_t scaledHeight)
|
||||
bool ffdsAppendDisplay(FFDisplayServerResult* result, uint32_t width, uint32_t height, double refreshRate, uint32_t scaledWidth, uint32_t scaledHeight)
|
||||
{
|
||||
if(width == 0 || height == 0)
|
||||
return false;
|
||||
|
||||
@@ -38,7 +38,7 @@ typedef struct FFDisplayResult
|
||||
{
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t refreshRate;
|
||||
double refreshRate;
|
||||
uint32_t scaledWidth;
|
||||
uint32_t scaledHeight;
|
||||
} FFDisplayResult;
|
||||
@@ -55,9 +55,6 @@ typedef struct FFDisplayServerResult
|
||||
} FFDisplayServerResult;
|
||||
|
||||
const FFDisplayServerResult* ffConnectDisplayServer(const FFinstance* instance);
|
||||
|
||||
//Used internal
|
||||
uint32_t ffdsParseRefreshRate(int32_t refreshRate);
|
||||
bool ffdsAppendDisplay(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate, uint32_t scaledWidth, uint32_t scaledHeight);
|
||||
bool ffdsAppendDisplay(FFDisplayServerResult* result, uint32_t width, uint32_t height, double refreshRate, uint32_t scaledWidth, uint32_t scaledHeight);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
ffdsAppendDisplay(ds,
|
||||
(uint32_t)CGDisplayModeGetPixelWidth(mode),
|
||||
(uint32_t)CGDisplayModeGetPixelHeight(mode),
|
||||
(uint32_t)refreshRate,
|
||||
refreshRate,
|
||||
(uint32_t)CGDisplayModeGetWidth(mode),
|
||||
(uint32_t)CGDisplayModeGetHeight(mode)
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "displayserver.h"
|
||||
#include "detection/os/os.h"
|
||||
#include "util/windows/unicode.h"
|
||||
|
||||
#include <dwmapi.h>
|
||||
#include <WinUser.h>
|
||||
@@ -11,6 +12,7 @@ typedef struct
|
||||
uint32_t height;
|
||||
} DataBundle;
|
||||
|
||||
|
||||
static CALLBACK WINBOOL enumMonitorProc(HMONITOR hMonitor, FF_MAYBE_UNUSED HDC hDC, FF_MAYBE_UNUSED LPRECT rc, LPARAM lparam)
|
||||
{
|
||||
MONITORINFOEXW mi = { .cbSize = sizeof(mi) };
|
||||
@@ -45,22 +47,64 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins
|
||||
ffStrbufInit(&ds->deVersion);
|
||||
ffListInit(&ds->displays, sizeof(FFDisplayResult));
|
||||
|
||||
DISPLAY_DEVICEW displayDevice = { .cb = sizeof(DISPLAY_DEVICEW) };
|
||||
for(DWORD devNum = 0; EnumDisplayDevicesW(NULL, devNum, &displayDevice, 0) != 0; ++devNum)
|
||||
{
|
||||
if(!(displayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
||||
continue;
|
||||
DEVMODEW devMode = { .dmSize = sizeof(DEVMODEW) };
|
||||
if(EnumDisplaySettingsW(displayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &devMode) == 0)
|
||||
continue;
|
||||
DISPLAYCONFIG_PATH_INFO paths[128];
|
||||
uint32_t pathCount = sizeof(paths) / sizeof(paths[0]);
|
||||
DISPLAYCONFIG_MODE_INFO modes[256];
|
||||
uint32_t modeCount = sizeof(modes) / sizeof(modes[0]);
|
||||
|
||||
DataBundle data = {
|
||||
.deviceName = displayDevice.DeviceName,
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
};
|
||||
EnumDisplayMonitors(NULL, NULL, enumMonitorProc, (LPARAM)&data);
|
||||
ffdsAppendDisplay(ds, devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmDisplayFrequency, data.width, data.height);
|
||||
if (SUCCEEDED(QueryDisplayConfig(
|
||||
QDC_ONLY_ACTIVE_PATHS | QDC_VIRTUAL_MODE_AWARE | 0x00000040 /*QDC_VIRTUAL_REFRESH_RATE_AWARE*/,
|
||||
&pathCount,
|
||||
paths,
|
||||
&modeCount,
|
||||
modes,
|
||||
NULL)))
|
||||
{
|
||||
for (uint32_t i = 0; i < modeCount; ++i)
|
||||
{
|
||||
DISPLAYCONFIG_MODE_INFO* mode = &modes[i];
|
||||
if(mode->infoType != DISPLAYCONFIG_MODE_INFO_TYPE_TARGET)
|
||||
continue;
|
||||
|
||||
DISPLAYCONFIG_SOURCE_DEVICE_NAME sourceName = {
|
||||
.header = {
|
||||
.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME,
|
||||
.size = sizeof(sourceName),
|
||||
.adapterId = mode->adapterId,
|
||||
.id = mode->id,
|
||||
},
|
||||
};
|
||||
|
||||
DataBundle data = {};
|
||||
if(SUCCEEDED(DisplayConfigGetDeviceInfo(&sourceName.header)))
|
||||
{
|
||||
data.deviceName = sourceName.viewGdiDeviceName;
|
||||
EnumDisplayMonitors(NULL, NULL, enumMonitorProc, (LPARAM) &data);
|
||||
}
|
||||
|
||||
// Find the target (monitor) friendly name
|
||||
DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = {
|
||||
.header = {
|
||||
.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME,
|
||||
.size = sizeof(targetName),
|
||||
.adapterId = mode->adapterId,
|
||||
.id = mode->id,
|
||||
},
|
||||
};
|
||||
|
||||
FFstrbuf name;
|
||||
ffStrbufInit(&name);
|
||||
if(SUCCEEDED(DisplayConfigGetDeviceInfo(&targetName.header)) && targetName.flags.friendlyNameFromEdid)
|
||||
ffStrbufSetWS(&name, targetName.monitorFriendlyDeviceName);
|
||||
|
||||
ffdsAppendDisplay(
|
||||
ds,
|
||||
mode->targetMode.targetVideoSignalInfo.totalSize.cx,
|
||||
mode->targetMode.targetVideoSignalInfo.totalSize.cy,
|
||||
mode->targetMode.targetVideoSignalInfo.vSyncFreq.Numerator / (double) mode->targetMode.targetVideoSignalInfo.vSyncFreq.Denominator,
|
||||
data.width,
|
||||
data.height);
|
||||
}
|
||||
}
|
||||
|
||||
//https://github.com/hykilpikonna/hyfetch/blob/master/neofetch#L2067
|
||||
|
||||
@@ -123,7 +123,7 @@ static void waylandOutputHandler(WaylandData* wldata, struct wl_registry* regist
|
||||
ffdsAppendDisplay(wldata->result,
|
||||
(uint32_t) display.width,
|
||||
(uint32_t) display.height,
|
||||
ffdsParseRefreshRate(display.refreshRate / 1000),
|
||||
display.refreshRate / 1000.0,
|
||||
(uint32_t) (display.width / display.scale),
|
||||
(uint32_t) (display.height / display.scale)
|
||||
);
|
||||
|
||||
@@ -174,9 +174,7 @@ typedef struct XcbRandrData
|
||||
|
||||
static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* modeInfo)
|
||||
{
|
||||
uint32_t refreshRate = ffdsParseRefreshRate((int32_t) (
|
||||
modeInfo->dot_clock / (uint32_t) (modeInfo->htotal * modeInfo->vtotal)
|
||||
));
|
||||
double refreshRate = modeInfo->dot_clock / (double) (modeInfo->htotal * modeInfo->vtotal);
|
||||
|
||||
return ffdsAppendDisplay(
|
||||
data->result,
|
||||
|
||||
@@ -133,9 +133,7 @@ typedef struct XrandrData
|
||||
|
||||
static bool xrandrHandleModeInfo(XrandrData* data, XRRModeInfo* modeInfo)
|
||||
{
|
||||
uint32_t refreshRate = ffdsParseRefreshRate((int32_t) (
|
||||
modeInfo->dotClock / (modeInfo->hTotal * modeInfo->vTotal)
|
||||
));
|
||||
double refreshRate = modeInfo->dotClock / (double) (modeInfo->hTotal * modeInfo->vTotal);
|
||||
|
||||
return ffdsAppendDisplay(
|
||||
data->result,
|
||||
|
||||
@@ -25,7 +25,7 @@ void ffPrintDisplay(FFinstance* instance)
|
||||
printf("%ix%i", result->width, result->height);
|
||||
|
||||
if(result->refreshRate > 0)
|
||||
printf(" @ %iHz", result->refreshRate);
|
||||
printf(" @ %iHz", (uint32_t) (result->refreshRate + 0.5));
|
||||
|
||||
if(
|
||||
result->scaledWidth > 0 && result->scaledWidth != result->width &&
|
||||
@@ -39,7 +39,7 @@ void ffPrintDisplay(FFinstance* instance)
|
||||
ffPrintFormat(instance, FF_RESOLUTION_MODULE_NAME, moduleIndex, &instance->config.display, FF_RESOLUTION_NUM_FORMAT_ARGS, (FFformatarg[]) {
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &result->width},
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &result->height},
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &result->refreshRate},
|
||||
{FF_FORMAT_ARG_TYPE_DOUBLE, &result->refreshRate},
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &result->scaledWidth},
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &result->scaledHeight}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user