[英]C++ Linux: Get the refresh rate of a monitor
在 Windows 中,winapi 提供了一个函数来报告有关监视器的信息:
DEVMODE dm;
dm.dmSize = sizeof(DEVMODE);
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
int FPS = dm.dmDisplayFrequency;
这在 Linux 上的等价物是什么? Linux 手册页将我引导到一个快板库函数,但我不仅没有使用快板,而且该函数来自所述库的一个非常过时的版本,据报道仅适用于 Windows。
使用 XRandr API (man 3 Xrandr)。 请参见此处的示例:
您还可以查看 xrandr(1) 的代码。
编辑1:为了后代:
示例代码略有调整,因此更像是一个演示:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <iostream>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
int main()
{
int num_sizes;
Rotation current_rotation;
Display *dpy = XOpenDisplay(NULL);
Window root = RootWindow(dpy, 0);
XRRScreenSize *xrrs = XRRSizes(dpy, 0, &num_sizes);
//
// GET CURRENT RESOLUTION AND FREQUENCY
//
XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
short current_rate = XRRConfigCurrentRate(conf);
SizeID current_size_id = XRRConfigCurrentConfiguration(conf, ¤t_rotation);
int current_width = xrrs[current_size_id].width;
int current_height = xrrs[current_size_id].height;
std::cout << "current_rate = " << current_rate << std::endl;
std::cout << "current_width = " << current_width << std::endl;
std::cout << "current_height = " << current_height << std::endl;
XCloseDisplay(dpy);
}
编译:
g++ 17797636.cpp -o 17797636 -lX11 -lXrandr
输出:
$ ./17797636
current_rate = 50
current_width = 1920
current_height = 1080
伊万的回答对我不起作用; xrandr 自 2013 年以来发生了变化,我猜? 命令行工具xrandr
可以正确读取我的刷新率,但它的源代码太复杂了,我不愿意复制它这样做的方式。 相反,我选择笨拙地将工作委托给整个xrandr
程序。 我糟糕的解决方案粘贴在下面。
请注意,当连接多个显示设备时,此解决方案可能不可靠,并且可能有一天当xrandr
再次更改时会中断。
(pstream.h 由 Jonathan Wakely 的 PStreams 库提供,参考此处: https ://stackoverflow.com/a/10702464/1364776
我只是用它来将命令的输出转换为std::string
; 显然还有其他各种方法可以做到这一点,因此如果您愿意,请使用其中一种方法。)
#include <pstream.h>
#include <cctype>
#include <cstdlib>
#include <cmath>
float getRefreshRate()
{
try
{
redi::ipstream queryStream("xrandr");
std::string chunk;
while (queryStream >> chunk)
{
auto rateEnd = chunk.find("*");
if (rateEnd != std::string::npos)
{
auto rateBeginning = rateEnd;
while (std::isdigit(chunk[rateBeginning]) || std::ispunct(chunk[rateBeginning]))
--rateBeginning;
++rateBeginning;
auto numberString = chunk.substr(rateBeginning, rateEnd - rateBeginning);
float rate = std::strtof(numberString.data(), nullptr);
if (rate != 0 && rate != HUGE_VALF)
return rate;
}
}
}
catch (...)
{
}
return 60; // I am not proud of any of this :(
}
一个简单的例子:
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
int main(int argc, char *argv[])
{
Display *display = XOpenDisplay(NULL);
Window default_root_window = XDefaultRootWindow(display);
XRRScreenResources *screen_resources = XRRGetScreenResources(display, default_root_window);
RRMode active_mode_id = 0;
for (int i = 0; i < screen_resources->ncrtc; ++i) {
XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(display, screen_resources, screen_resources->crtcs[i]);
// If None, then is not displaying the screen contents
if (crtc_info->mode != None) {
active_mode_id = crtc_info->mode;
}
}
double active_rate = 0;
for (int i = 0; i < screen_resources->nmode; ++i) {
XRRModeInfo mode_info = screen_resources->modes[i];
if (mode_info.id == active_mode_id) {
active_rate = (double)mode_info.dotClock / ((double)mode_info.hTotal * (double)mode_info.vTotal);
}
}
printf("Active rate is: %.1f\n", active_rate);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.