3

I would like to display images in the second monitor. I have two displays of 1920x1080px connected and detected properly in Ubuntu.

I am listing the screens with the following code. The problem is that I am listing always just one screen0: 1920x1080 for a single display configuration and a 3840x1080 for a multiple display (exended or duplicated).

How can I get the list of two displays in order to select just screen1 (second display 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;

}

update: here is my xrandr output, that shows the two displays properly connected, and I can use it accordingly. However, if I access to the available displays, I can get only :0 with one screen with 3840x1080. How to get two displays (:0 and :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)

Check available X displays doesn't return the two connected displays,

vo@vo-ubuntu:~$ cd /tmp/.X11-unix && for x in X*; do echo ":${x#X}"; done
:0
:1024
vo@vo-ubuntu:/tmp/.X11-unix$ 
Jaume
  • 3,672
  • 19
  • 60
  • 119
  • Have a look at [this answer](https://stackoverflow.com/a/11368019/485343). You might need to query display :1. – rustyx Sep 23 '19 at 07:36
  • Useful post, thanks. I am trying to first list the available X displays in the console before coding. Then, I am getting only display :0 and :1024... I don't know exactly what 1024 means but it accessible through code. However, it returns 0 screens. How can I list 0&1 displays using console? – Jaume Sep 24 '19 at 14:02

2 Answers2

2

It's likely that you need to query Xinerama, which is probably stitching your displays together.

This answer worked for me. I compiled their sample with:

g++ xinerama.c `pkg-config --cflags --libs x11 xinerama` -o test
abarry
  • 425
  • 3
  • 16
  • useful starting point, thanks. With this base, I found a useful information about linux screening, https://wiki.archlinux.org/index.php/Multihead. Then, current method should be using Randr, so I'm using Ubuntu 18.04. Then, I should create a xorg.conf (or conf.d?) with desired information. What will be the proper configuration to get the two independent displays? – Jaume Sep 30 '19 at 10:23
  • That code sample should work most of the time. It supports TwinView and xinerama, so if you try it, I expect it will return the information you want, even without changing your xorg.conf – abarry Sep 30 '19 at 14:25
  • Beside of a couple of modifications for Ubuntu 18.04, it works! Thank you. – Jaume Oct 01 '19 at 00:14
0

After many hours of trial&error with undocumented libXrandr and reading sources of various applications using it, i came out with this

#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 );
}

The struct XRRMonitorInfo contains more useful elements. And to get extended info about the monitor modes, one can use XRRGetOutputInfo on the .outputs member.

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

Youda008
  • 1,788
  • 1
  • 17
  • 35