0

我正在尝试列出所有带有 Xinerama 和 Xrandr 的显示器。这是应该这样做的代码:

int i, j, screenCount, sizeCount, eventBase, errorBase;
char displayName[64];
DIR *dir;
struct dirent *direntry;
XRRScreenSize *sizes;
XRRScreenConfiguration *screenConfig;
XineramaScreenInfo *xineramaInfo;
Display *disp;
Window root;

dir = opendir("/tmp/.X11-unix");
while((direntry = readdir(dir)) != NULL){
    if(direntry->d_name[0] != 'X'){
        continue;
    }
    snprintf(displayName, 64, ":%s", direntry->d_name + 1);
    disp = XOpenDisplay(displayName);
    if(disp != NULL){
        if(XineramaQueryExtension(disp, &eventBase, &errorBase) && XineramaIsActive(disp)){
            xineramaInfo = XineramaQueryScreens(disp, &screenCount);
        }else{
            break;
        }
        printf("Display %s has %d screens\n", displayName, screenCount);
        for(i = 0; i < screenCount; i++){
            root = RootWindow(disp, i);
            screenConfig = XRRGetScreenInfo(disp, root);
            sizes = XRRConfigSizes(screenConfig, &sizeCount);
            for(j = 0; j < sizeCount; j++){
                printf("%d x %d\n", sizes[j].width, sizes[j].height);
            }
        }
        XCloseDisplay(disp);
        XFree(xineramaInfo);
    }
}

但它会引发以下错误:

Display :0 has 3 screens
1680 x 1050
1600 x 1200
1280 x 1024
1024 x 768
832 x 624
800 x 600
640 x 480
720 x 400
X Error of failed request:  BadWindow (invalid Window parameter)
  Major opcode of failed request:  140 (RANDR)
  Minor opcode of failed request:  5 (RRGetScreenInfo)
  Resource id in failed request:  0x18
  Serial number of failed request:  16
  Current serial number in output stream:  16

我的代码有问题还是无法使用 Xinerama 列出所有显示器的所有分辨率?

4

1 回答 1

0

经过长时间查看 Xrandr 的源代码后,我找到了解决方案:

bool findResolutions(Display *display)
{
    int i, j, k, eventBase, errorBase;
    Window root;
    XRRScreenResources *resources;
    XRROutputInfo *outputInfo;

    if(!XineramaQueryExtension(display, &eventBase, &errorBase) || !XineramaIsActive(display)){
        printf("Xinerama not supported or active\n");
        return false;
    }

    root = RootWindow(display, 0);
    resources = XRRGetScreenResources(display, root);

    for(i = 0; i < resources->noutput; i++){
        outputInfo = XRRGetOutputInfo(display, resources, resources->outputs[i]);
        for(j = 0; j < outputInfo->nmode; j++){
            for(k = 0; k < resources->nmode; k++){
                if(outputInfo->modes[j] == resources->modes[k].id){
                    printf("%dx%d", resources->modes[k].width, resources->modes[k].height);
                    break;
                }
            }
        }

        XRRFreeOutputInfo(outputInfo);
    }

    XRRFreeScreenResources(resources);

    return true;
}
于 2014-06-03T15:40:31.207 回答