Programming OpenGL in Linux: Changing the Screen Resolution

From OpenGL.org
Jump to: navigation, search

Change Screen Resolution?

Some programs- probably games- may require to change the screen resolution, e.g. for performance reasons. The program could ask the user to change the screen resolution- which is, of course, bad style- or use the Xrandr extension (Xrandr stands for X Resize, Rotate and Reflection). There are two ways for using this extension:

Using the xrandr command line tool

First, make yourself familiar with the xrandr command. Calling xrandr without arguments lists all possible resolutions and frequencies. Using xrandr with the -s option selects a screen size from this list. Although this sounds like it is easy to use- which it surely is- note that xrandr is a command line tool. If you want to use it in your application, you have to call it twice: First, to get all possible resolution, directing the output to a temporary file. Then, parse the file to get all possible resolutions. Finally, call xrandr again with a certain resolution.

For those who do not know: Calling any command line tool from an application can be achieved with the system function (defined in stdlib.h). What you have to do could look like this:


#include<stdlib.h>

system("xrandr > resolutions.tmp"); // direct output to 'resolutions.tmp'

//
// retrieve possible resolutions from 'resolutions.tmp'
//

system("xrandr -s resolution_id"); // select a certain screen resolution

Using library functions

If your Linux System is set up properly, there should be a /usr/include/X11 directory (in which you find Xlib.h and other header files) and a subdirectory /usr/include/X11/extensions with Xrandr.h. Furthermore, the libXrandr.so library is needed. The following program shows how to use the Xrandr functions to get all possible screen resolutions and display frequencies:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<X11/Xlib.h>
#include<X11/extensions/Xrandr.h>

Display                 *dpy;
Window                  root;
int                     num_sizes;
XRRScreenSize           *xrrs;
XRRScreenConfiguration  *conf;
short                   possible_frequencies[64][64];
short                   original_rate;
Rotation                original_rotation;
SizeID                  original_size_id;

int main(int argc, char *argv[]){
 //
 //     CONNECT TO X-SERVER, GET ROOT WINDOW ID
 //
 dpy    = XOpenDisplay(NULL);
 root   = RootWindow(dpy, 0);
 //
 //     GET POSSIBLE SCREEN RESOLUTIONS
 //
 xrrs   = XRRSizes(dpy, 0, &num_sizes);
 //
 //     LOOP THROUGH ALL POSSIBLE RESOLUTIONS,
 //     GETTING THE SELECTABLE DISPLAY FREQUENCIES
 //
 for(int i = 0; i < num_sizes; i ++) {
        short   *rates;
        int     num_rates;

        printf("\n\t%2i : %4i x %4i   (%4imm x%4imm ) ", i, xrrs[i].width, xrrs[i].height, xrrs[i].mwidth, xrrs[i].mheight);

        rates = XRRRates(dpy, 0, i, &num_rates);

        for(int j = 0; j < num_rates; j ++) {
                possible_frequencies[i][j] = rates[j];
                printf("%4i ", rates[j]); } }

 printf("\n");
 //
 //     GET CURRENT RESOLUTION AND FREQUENCY
 //
 conf                   = XRRGetScreenInfo(dpy, root);
 original_rate          = XRRConfigCurrentRate(conf);
 original_size_id       = XRRConfigCurrentConfiguration(conf, &original_rotation);

 printf("\n\tCURRENT SIZE ID  : %i\n", original_size_id);
 printf("\tCURRENT ROTATION : %i \n", original_rotation);
 printf("\tCURRENT RATE     : %i Hz\n\n", original_rate);
 //
 //     CHANGE RESOLUTION
 //
 printf("\tCHANGED TO %i x %i PIXELS, %i Hz\n\n", xrrs[1].width, xrrs[1].height, possible_frequencies[1][0]);
 XRRSetScreenConfigAndRate(dpy, conf, root, 1, RR_Rotate_0, possible_frequencies[1][0], CurrentTime);
 //
 //     SLEEP A WHILE
 //
 usleep(6000000);
 //
 //     RESTORE ORIGINAL CONFIGURATION
 //
 printf("\tRESTORING %i x %i PIXELS, %i Hz\n\n", xrrs[original_size_id].width, xrrs[original_size_id].height, original_rate);
 XRRSetScreenConfigAndRate(dpy, conf, root, original_size_id, original_rotation, original_rate, CurrentTime);
 //
 //     EXIT
 //
 XCloseDisplay(dpy); }
//
//      gcc -o Xrandr Xrandr.cc -lX11 -lXrandr -lstdc++
//

The Program, with its comments, should explain itself: First all possible resolutions and frequencies are acquired. Then the original parameters are stored. The resolution is changed for some seconds, and finally, the original resolution is restored.

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox