使用Xinerama进行多个显示的可能分辨率

时间:2014-05-26 15:33:49

标签: c linux xlib xrandr

我正在尝试使用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列出所有显示的所有分辨率?

1 个答案:

答案 0 :(得分: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;
}