Search code examples
c++linuxframe-ratexorg

C++ Linux: Get the refresh rate of a monitor


In Windows, winapi provides a function that reports information about a monitor:

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

EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);

int FPS = dm.dmDisplayFrequency;

What is the equivalent of this on Linux? The Linux man pages direct me to an allegro library function, but not only am I not using allegro, that function is from a very outdated version of said library and reportedly only works on Windows.


Solution

  • Use XRandr API (man 3 Xrandr). See here for an example:

    You can also look at the code for xrandr(1).


    Edit1: For posterity sake:

    Sample code slightly adjusted so its more of a demo:

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

    Compile with:

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

    Output:

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