xrandr related, C programming
Asked Answered
G

3

11

Here is an example call to xrandr:

$ xrandr --output LVDS --mode 1680x1050 --pos 0x0 --rotate normal --output S-video --off --output DVI-0 --mode 1024x768 --pos 1680x104 --rotate normal

Think about a system where that call has success; there are two screens (LVDS and DVI-0) working with different resolutions. The DVI-0 one is on the right placed in the middle.

How can I get all this informations in a C program? I checked the xrandr source code, but I found it difficult to read and there is no apparent way to query the --pos value (edit: it is hidden in plain sight, thanks to ernestopheles' answer I got it).

I know I can ask a _NET_WORKAREA with XGetWindowProperty, but as far as I saw it does not tell the screen positions, just the size of the ideal rectangle that contains them all.

After some other study of xrandr code, this code seems a step forward the solution. Yet I am not convinced, xrandr.c around line 2940 assumes that crtc_info might be unavailable. I still miss the other way to get resolution and position.


    #include <stdio.h>
    #include <X11/extensions/Xrandr.h>

    int main() {
        Display *disp;
        XRRScreenResources *screen;
        XRROutputInfo *info;
        XRRCrtcInfo *crtc_info;
        int iscres;
        int icrtc;

        disp = XOpenDisplay(0);
        screen = XRRGetScreenResources (disp, DefaultRootWindow(disp));
        for (iscres = screen->noutput; iscres > 0; ) {
            --iscres;

            info = XRRGetOutputInfo (disp, screen, screen->outputs[iscres]);
            if (info->connection == RR_Connected) {
                for (icrtc = info->ncrtc; icrtc > 0;) {
                    --icrtc;

                    crtc_info = XRRGetCrtcInfo (disp, screen, screen->crtcs[icrtc]);
                    fprintf(stderr, "==> %dx%d+%dx%d\n", crtc_info->x, crtc_info->y, crtc_info->width, crtc_info->height);

                    XRRFreeCrtcInfo(crtc_info);
                }
            }
            XRRFreeOutputInfo (info);
        }
        XRRFreeScreenResources(screen);

        return 0;
    }

Gunlock answered 4/12, 2012 at 15:18 Comment(2)
Hi there I was wondering if you were convinced about your code today? Or if you found better way?Rame
I thought to use a combintation of this and xinerma in case xrandr is not available: https://mcmap.net/q/1019426/-programmatically-determining-individual-screen-widths-heights-in-linux-w-xinerama-twinview-and-or-bigdesktopRame
A
8

You can get each screen resolution by doing this:

Display *dpy;
XRRScreenResources *screen;
XRRCrtcInfo *crtc_info;

dpy = XOpenDisplay(":0");
screen = XRRGetScreenResources (dpy, DefaultRootWindow(dpy));
//0 to get the first monitor   
crtc_info = XRRGetCrtcInfo (dpy, screen, screen->crtcs[0]);     

After that crtc_info->width will contain the width of the monitor and crtc_info->x the x position.

dont forget the includes:

#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>

and compile with -lX11 -lXrandr to link the libraries

Aluminiferous answered 17/3, 2014 at 18:0 Comment(1)
It was really helpful. Thanks.Warlock
M
1

I am not sure, whether I understand the question correctly. Assuming, you want to read out the parameters of the current state of the x-server, use the following command:

xrandr -q
and parse its output:
LVDS connected 1680x1050+0+0 (normal left inverted right x axis y axis) 123mm x 123mm 
[...]

for the first screen and

TV_SVIDEO connected 1024x768+1680x104 (normal left inverted right x axis y axis) 123mm x 123mm
[...]

for the second. Running the command and parsing it can be done within a program written in C.

Molarity answered 4/12, 2012 at 17:55 Comment(1)
Thanks to your answer I noticed the position value is just near the resolution. At least I can check the xrandr code about how it determines it.Gunlock
C
0

You can use info->crtc instead of screen->crtcs[icrtc].

Coset answered 11/4, 2019 at 4:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.