I was trying to find all monitors and their coordinates (width w
, height h
, x origin/top-left-most x
, and y origin/top-left-most y
) and was using this code, it works good on some systems. But on other systems I get false and duplicate entries. Would I be able to avoid these dupilcate/false monitor entries if I tested if monitor is mirror? How to test if its mirror?
So this is my code:
// start - get all monitor resolutions
var screen = XRRGetScreenResources(getXOpenDisplay(), getDefaultRootWindow(getXOpenDisplay()));
var noutputs = screen.noutput;
for (var i=noutputs-1; i>=0; i--) {
var info = XRRGetOutputInfo(getXOpenDisplay(), screen, screen.outputs[i]);
if (info.connection == RR_Connected) {
var ncrtcs = info.ncrtc;
for (var j=ncrtcs-1; j>=0; j--) {
var crtc_info = XRRGetCrtcInfo(getXOpenDisplay(), screen, infoCrtcs[j]);
console.info('screen #' + i + ' mon#' + j + ' details:', crtc_info.x, crtc_info.y, crtc_info.width, crtc_info.height);
collMonInfos.push({
x: crtc_info.x,
y: crtc_info.y,
w: crtc_info.width,
h: crtc_info.height
});
XRRFreeCrtcInfo(crtc_info);
}
}
XRRFreeOutputInfo(info);
}
XRRFreeScreenResources(screen);
console.info('JSON:', JSON.stringify(collMonInfos));
// end - get all monitor resolutions
And this outputs this to log:
"screen #4 mon#0 details:" 0 0 0 0
"screen #3 mon#1 details:" 0 0 1920 1200
"screen #3 mon#0 details:" 1920 469 1366 768
"screen #2 mon#1 details:" 0 0 1920 1200
"screen #2 mon#0 details:" 1920 469 1366 768
"screen #1 mon#1 details:" 0 0 1920 1200
"screen #1 mon#0 details:" 1920 469 1366 768
"screen #0 mon#1 details:" 0 0 1920 1200
"screen #0 mon#0 details:" 1920 469 1366 768
This is it in JSON format:
[{
"x": 0,
"y": 0,
"w": 0,
"h": 0
}, {
"x": 0,
"y": 0,
"w": 1920,
"h": 1200
}, {
"x": 1920,
"y": 469,
"w": 1366,
"h": 768
}, {
"x": 0,
"y": 0,
"w": 1920,
"h": 1200
}, {
"x": 1920,
"y": 469,
"w": 1366,
"h": 768
}, {
"x": 0,
"y": 0,
"w": 1920,
"h": 1200
}, {
"x": 1920,
"y": 469,
"w": 1366,
"h": 768
}, {
"x": 0,
"y": 0,
"w": 1920,
"h": 1200
}, {
"x": 1920,
"y": 469,
"w": 1366,
"h": 768
}]
I really only have 2 monitors, the 1920x1200 one and the 1366x768 one. How come all the other entries and how to test to avoid (rather then filter out in retrospect based on duplicates or 0 h/w)?
You are unnecessarily iterating over each output and then over each monitor. So you receive a duplicate entries. You do not have to call XRRGetOutputInfo
for each output, since all data you need (number of monitors) can be found in structure returned by XRRGetScreenResources
.
Here is the C code that works (at least for me):
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
int main(void) {
Display *d = XOpenDisplay(getenv("DISPLAY"));
Window w = DefaultRootWindow(d);
XRRScreenResources *xrrr = XRRGetScreenResources(d, w);
XRRCrtcInfo *xrrci;
int i;
int ncrtc = xrrr->ncrtc;
for (i = 0; i < ncrtc; ++i) {
xrrci = XRRGetCrtcInfo(d, xrrr, xrrr->crtcs[i]);
printf("%dx%d+%d+%d\n", xrrci->width, xrrci->height, xrrci->x, xrrci->y);
XRRFreeCrtcInfo(xrrci);
}
XRRFreeScreenResources(xrrr);
return 0;
}