Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;Linux:获取监视器的刷新率_C++_Linux_Frame Rate_Xorg - Fatal编程技术网

C++ C++;Linux:获取监视器的刷新率

C++ C++;Linux:获取监视器的刷新率,c++,linux,frame-rate,xorg,C++,Linux,Frame Rate,Xorg,在Windows中,winapi提供了一个报告有关监视器信息的函数: DEVMODE dm; dm.dmSize = sizeof(DEVMODE); EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm); int FPS = dm.dmDisplayFrequency; 这在Linux上的等价物是什么?Linux手册页将我引向allegro库函数,但我不仅没有使用allegro,而且该函数来自该库的一个非常过时的版本,据说只在

在Windows中,winapi提供了一个报告有关监视器信息的函数:

DEVMODE dm;
dm.dmSize = sizeof(DEVMODE);

EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);

int FPS = dm.dmDisplayFrequency;
这在Linux上的等价物是什么?Linux手册页将我引向allegro库函数,但我不仅没有使用allegro,而且该函数来自该库的一个非常过时的版本,据说只在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, &current_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);
}
输出:

$ ./17797636 
current_rate = 50
current_width = 1920
current_height = 1080

伊万的回答对我不起作用;自2013年以来,xrandr发生了变化,我想是吧?命令行工具
xrandr
可以正确读取我的刷新率,但它的源代码太复杂,我不愿意复制它的方式。相反,我选择笨拙地将工作委托给整个
xrandr
程序。我糟糕的解决方案贴在下面

请注意,当连接多个显示设备时,此解决方案可能不可靠,并且当
xrandr
再次更改时,可能有一天会中断

(pstream.h由Jonathan Wakely的pstream库提供,此处引用:

我只是用它将命令的输出转换为
std::string
;显然还有其他多种方法可以实现这一点,所以如果您愿意,可以使用其中一种方法。)

#包括
#包括
#包括
#包括
float getRefreshRate()
{
尝试
{
redi::ipstream queryStream(“xrandr”);
std::字符串块;
while(查询流>>块)
{
auto rateEnd=chunk.find(“*”);
if(rateEnd!=std::string::npos)
{
自动费率开始=费率结束;
while(std::isdigit(chunk[ratestings])| | std::ispunt(chunk[ratestings]))
--费率起始;
++费率起始;
autonumberstring=chunk.substr(rateStart,rateEnd-rateStart);
浮动率=std::strof(numberString.data(),nullptr);
如果(速率!=0&&rate!=巨大值)
回报率;
}
}
}
捕获(…)
{
}
return 60;//我对这些都不感到自豪:(
}
一个简单的例子:

#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;
}
#包括
#包括
int main(int argc,char*argv[])
{
Display*Display=XOpenDisplay(空);
窗口默认值\u根\u窗口=XDefaultRootWindow(显示);
XRRScreenResources*screen\u resources=XRRGetScreenResources(显示,默认根窗口);
RRMode active_mode_id=0;
对于(inti=0;incrtc;++i){
XRRCrtcInfo*crtc_info=XRRGetCrtcInfo(显示、屏幕资源、屏幕资源->crtcs[i]);
//如果没有,则不显示屏幕内容
如果(crtc_信息->模式!=无){
活动模式\u id=crtc\u信息->模式;
}
}
双激活率=0;
对于(inti=0;inmode;++i){
XRRModeInfo mode_info=屏幕资源->模式[i];
如果(模式信息id==活动模式id){
活动速率=(双)模式信息点时钟/((双)模式信息点总*(双)模式信息点总);
}
}
printf(“有效率为:%.1f\n”,有效率);
返回0;
}

sudo-ddcprobe | grep monitorange基本上执行lp-grep?这在所有发行版上有效吗,或者至少在大多数发行版上有效吗?据我所知,在大多数可用发行版上都有效。如果您使用的是基于debian的,请尝试:sudo-apt-get-install-xreprobe,然后可以运行:sudo-ddcprobe | grep monitorange以获得水平和垂直刷新率…我实际上需要一种方法来实现这一点,以便FPS存储在程序中,而不是将FPS输出到终端。execlp实际上不会将信息中继回调用它的程序,因此是否有其他功能可以执行?如果您有两个带扩展桌面的显示器呢?在我的情况下,它只打印我的笔记本电脑刷新率,而不是我的外部显示器的。这现在为我提供了一个不正确的刷新率;虽然我的刷新率是60赫兹,但显示的是50赫兹。有关更多信息,请参阅。我从xrandr--q1中获得了50赫兹,但从xrandr--q12中获得了60赫兹(以及我尝试的所有其他工具),就像那个人那样。我还不知道读取代码的正确刷新率是多少……我乐观地联系到的答案是,xrandr.c应该告诉我们如何去做,我想这是必须的,但代码太复杂和脆弱了,我无法从中取出正确的部分。(我希望在我当前的项目中,我真正的、长期的解决这个问题的方法是忘记所有这些胡说八道,向Qt询问刷新率,这似乎是人们可以通过QScreen或类似的方式来做的事情。但我不会提供这一点作为原始问题的正确答案,因为显然不是每个项目都在使用Qt。)
#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;
}