5

wすべてのモニターとその座標 ( width 、 height h、 x origin/top-left-most x、および y origin/top-left-most )を見つけようとしていてy、このコードを使用していましたが、一部のシステムではうまく機能します。しかし、他のシステムでは、間違った重複したエントリが表示されます。モニターがミラーかどうかをテストした場合、これらの重複/誤ったモニター エントリを回避できますか? そのミラーかどうかをテストする方法は?

これは私のコードです:

// 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

そして、これはこれをログに出力します:

"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

これは JSON 形式です。

[{
    "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
}]

私は実際には 1920x1200 と 1366x768 の 2 つのモニターしか持っていません。他のすべてのエントリと、回避するためにテストする方法 (むしろ、重複または 0 h/w に基づいてレトロスペクティブに除外する方法) はどうしてですか?

4

2 に答える 2

4

各出力を不必要に繰り返し、次に各モニターを繰り返しています。したがって、重複したエントリを受け取ります。XRRGetOutputInfo必要なすべてのデータ (モニターの数) は によって返される構造体で見つかるため、出力ごとに呼び出す必要はありませんXRRGetScreenResources。動作するCコードは次のとおりです(少なくとも私にとっては):

#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;
}
于 2015-07-20T22:13:46.527 に答える
3

受け入れられた答えは私にはうまくいきませんでした。これを行う正しい方法は次のとおりです。

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

int main(void) {
    Display *display = XOpenDisplay(NULL);

    if (NULL == display) {
        perror("No DISPLAY in environment!");
        exit(EXIT_FAILURE);
    }

    Window window = DefaultRootWindow(display);
    XRRScreenResources *screenr = XRRGetScreenResources(display, window);

    // This is the key right here. Use XRRScreenResources::noutput
    int output = screenr->noutput;

    for (int i = 0; i < output; ++i) {
        XRROutputInfo* out_info = XRRGetOutputInfo(display, screenr, screenr->outputs[i]);

        if (NULL != out_info && out_info->connection == RR_Connected) {
            XRRCrtcInfo* crt_info = XRRGetCrtcInfo(display, screenr, out_info->crtc);
            printf("%s\t%dx%d+%d+%d\n", out_info->name, 
                                        crt_info->width, 
                                        crt_info->height,
                                        crt_info->x,
                                        crt_info->y);
            XRRFreeCrtcInfo(crt_info);
        }

        XRRFreeOutputInfo(out_info);
    }

    XRRFreeScreenResources(screenr);
    XCloseDisplay(display);

    return 0;
}

コードのコメントで述べたように、トリックはXRRScreenResources::noutput代わりに使用していますXRRScreenResources::ncrtc

于 2020-10-23T06:23:03.887 に答える