C++ 列表屏幕以在第二个监视器中显示图像

C++ list screens to display images in the second monitor

我想在第二台显示器上显示图像。我在 Ubuntu 中连接并正确检测了两个 1920x1080px 的显示器。

我正在使用以下代码列出屏幕。问题是我总是只列出一个 screen0:1920x1080 用于单个显示器配置,3840x1080 用于多个显示器(扩展或复制)。

如何获取两个显示器的列表以便 select 只是屏幕 1(第二个显示器 1920x1080)?

Display *myDisplay = XOpenDisplay(NULL);

unsigned int numScreens = ScreenCount(myDisplay);

for(unsigned int i=0; i<numScreens; i++){

    Screen *myScreen = ScreenOfDisplay(myDisplay, i);
    ScreenInfo screen;
    screen.resX = myScreen->width;
    screen.resY = myScreen->height;
    char screenName[50];
    sprintf(screenName, "Screen number %d", i);
    screen.name = screenName;

}

更新:这是我的 xrandr 输出,显示两个显示器正确连接,我可以相应地使用它。但是,如果我访问可用的显示器,我只能在 3840x1080 的一个屏幕上获得 :0。如何获得两个显示(:0 和:1)?

vo@vo-ubuntu:~$ xrandr
Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 8192 x 8192
HDMI-1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 527mm x 296mm
   1920x1080     60.00*+  60.00    50.00    50.00    59.94  
   1920x1080i    60.00    60.00    50.00    59.94  
   1600x1200     60.00  
   1680x1050     59.88  
   1400x1050     59.95  
   1600x900      60.00  
   1280x1024     75.02    60.02  
   1440x900      59.90  
   1280x960      60.00  
   1152x864      75.00  
   1280x720      60.00    60.00    50.00    59.94  
   1024x768      75.03    70.07    60.00  
   832x624       74.55  
   800x600       72.19    75.00    60.32    56.25  
   720x576       50.00    50.00  
   720x576i      50.00    50.00  
   720x480       60.00    60.00    59.94    59.94    59.94  
   720x480i      60.00    60.00    59.94    59.94  
   640x480       75.00    72.81    66.67    60.00    59.94    59.94  
   720x400       70.08  
HDMI-2 disconnected (normal left inverted right x axis y axis)
DP-1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 527mm x 296mm
   1920x1080     60.00*+
   1600x1200     60.00  
   1680x1050     59.95  
   1400x1050     59.98  
   1600x900      60.00  
   1280x1024     75.02    60.02  
   1440x900      59.89  
   1280x960      60.00  
   1152x864      75.00  
   1280x720      60.00  
   1024x768      75.03    70.07    60.00  
   832x624       74.55  
   800x600       72.19    75.00    60.32    56.25  
   640x480       75.00    72.81    66.67    59.94  
   720x400       70.08  
DVI-D-1-1 disconnected (normal left inverted right x axis y axis)
HDMI-1-3 disconnected (normal left inverted right x axis y axis)
DP-1-2 disconnected (normal left inverted right x axis y axis)

检查可用的 X 显示器没有 return 两个连接的显示器,

vo@vo-ubuntu:~$ cd /tmp/.X11-unix && for x in X*; do echo ":${x#X}"; done
:0
:1024
vo@vo-ubuntu:/tmp/.X11-unix$ 

您可能需要查询 Xinerama,它可能正在将您的显示器拼接在一起。

This answer 对我有用。我编译了他们的示例:

g++ xinerama.c `pkg-config --cflags --libs x11 xinerama` -o test

在使用未记录的 libXrandr 和阅读使用它的各种应用程序的源代码进行数小时的试验和错误之后,我得出了这个

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

void printMonitorInfo()
{
    Display * display = XOpenDisplay( nullptr );
    if (!display)
    {
        std::cout << "cannot open X Display" << std::endl;
        return;
    }

    int dummy1, dummy2;
    int major, minor;
    if (!XRRQueryExtension( display, &dummy1, &dummy2 )
     || !XRRQueryVersion( display, &major, &minor ))
    {
        std::cout << "failed to retrieve XRandR version" << std::endl;
        XCloseDisplay( display );
        return;
    }

    if (major <= 1 && minor < 5)
    {
        std::cout << "RandR version at least 1.5 is required" << std::endl;
        XCloseDisplay( display );
        return;
    }

    Window rootWindow = RootWindow( display, DefaultScreen( display ) );

    Bool onlyActive = false;  // if set it returns only active monitors (non-0x0 monitors)
    int monitorCnt;
    XRRMonitorInfo * xMonitors = XRRGetMonitors( display, rootWindow, onlyActive, &monitorCnt );
    if (!xMonitors)
    {
        std::cout << "failed to retrieve monitor info" << std::endl;
        XCloseDisplay( display );
        return;
    }

    for (int monitorIdx = 0; monitorIdx < monitorCnt; monitorIdx++)
    {
        std::cout
            << "name: " << XGetAtomName( display, xMonitors[ monitorIdx ].name )
            << ", width: " << xMonitors[ monitorIdx ].width
            << ", height: " << xMonitors[ monitorIdx ].height
            << ", primary: " << xMonitors[ monitorIdx ].primary
            << std::endl;
    }

    XCloseDisplay( display );
}

结构XRRMonitorInfo包含更多有用的元素。 要获得有关监控模式的扩展信息,可以在 .outputs 成员上使用 XRRGetOutputInfo

来源:gitlab.freedesktop.org/xorg/app/xrandr/-/blob/master/xrandr.c