6

Windows では、winapi はモニターに関する情報を報告する機能を提供します。

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

EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);

int FPS = dm.dmDisplayFrequency;

Linuxでこれに相当するものは何ですか? Linux のマニュアル ページは allegro ライブラリ関数を案内してくれますが、私は allegro を使用していないだけでなく、その関数は前述のライブラリの非常に古いバージョンのものであり、Windows でしか動作しないと報告されています。

4

3 に答える 3

5

XRandr API (man 3 Xrandr) を使用します。例については、ここを参照してください。

xrandr(1) のコードも参照できます。


Edit1:後世のために:

サンプルコードは少し調整されているため、デモのようになります。

#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);
}

コンパイル:

g++ 17797636.cpp -o 17797636 -lX11 -lXrandr

出力:

$ ./17797636 
current_rate = 50
current_width = 1920
current_height = 1080
于 2013-07-22T22:05:49.523 に答える
1

イワンの答えはうまくいきませんでした。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 :(
}
于 2019-11-04T10:10:53.230 に答える