Ask Your Question
1

How can I check if the monitor is connected in Windows / Linux?

asked 2019-01-18 13:27:56 -0600

AlexB gravatar image

How can I check if the monitor is connected in Windows / Linux?

The following program behavior is required, when I run my application:

  • if monitor is connected, then results will be showed in the window
  • if monitor isn't connected, or if I run application by SSH, then results will be saved to the image.jpg

Currently, if monitor isn't connected or if I run my application by using SSH, I get an error, that I can't catch as exception:

QXcbConnection: Could not connect to display

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;

int main( int argc, char** argv )
{
    if( argc != 2) return -1;
    Mat image = imread(argv[1], CV_LOAD_IMAGE_COLOR); 
    if(! image.data )  return -1;
    try {
        namedWindow( "Display window", WINDOW_AUTOSIZE );
        imshow( "Display window", image );
        waitKey(0);
    } catch(...) {
       imwrite( "output.jpg", image );
    }
    return 0;
}

Currently OpenCV application requires addition flag -monitor to enable/disable output to the window, that isn't very usable.

There is not required a full-fledged API, which would replace the OS API. But it would be very useful if there was a function that returns whether the monitor is connected or not.

edit retag flag offensive close merge delete

Comments

off topics

LBerger gravatar imageLBerger ( 2019-01-18 13:57:07 -0600 )edit

3 answers

Sort by ยป oldest newest most voted
4

answered 2019-01-18 16:18:40 -0600

kbarni gravatar image

updated 2019-01-18 16:33:46 -0600

Here's the solution for Linux. You need to use the Xlib library:

#include <X11/Xlib.h>

int main(int argc, char *argv[])
{
    bool hasgui=true;
    Display *display;
    display=XOpenDisplay(NULL);
    if(!display)
        hasgui=false;
    else XCloseDisplay(display);
    //... your code here...
    if(hasgui) imshow("Yipee", image");
    else imwrite( "output.jpg", image );
    return 0;
}

You need to install xlib11-xcb-dev package (on ubuntu/debian) and link your program to libx11 (-lx11)

I don't know for Windows, if it can run without graphical interface (even if there is no screen attached) - but probably there is no simple access to low-level features. Maybe you can try to query screen resolution or something similar to see if there's a screen. I have no idea how to deal with this case.

edit flag offensive delete link more

Comments

You can avoid installing or linking extra libraries by simply checking the DISPLAYenvironment variable: std::getenv("DISPLAY") == nullptr (if this is true, then there isn't a display available)

Antonio gravatar imageAntonio ( 2020-12-21 10:11:59 -0600 )edit
2

answered 2019-01-18 18:38:23 -0600

sjhalayka gravatar image

updated 2019-01-20 19:44:13 -0600

The following version for Windows uses a global variable to keep track of the number of monitors (real and virtual):

#include <windows.h>
#include <iostream>
using namespace std;

size_t monitor_count = 0;

BOOL monitor_enum_proc(HMONITOR Arg1, HDC Arg2, LPRECT Arg3, LPARAM Arg4)
{
    monitor_count++;
    return TRUE;
}

int main(void)
{
    EnumDisplayMonitors(NULL, NULL, monitor_enum_proc, NULL);
    cout << monitor_count << endl;

    return 0;
}

... or if you abhor global variables, then you can use the following version instead. It isn't intentionally obfuscated, it's just plain old pointer use. I've included comments regarding this pointer use:

#include <windows.h>
#include <iostream>
using namespace std;

BOOL monitor_enum_proc(HMONITOR Arg1, HDC Arg2, LPRECT Arg3, LPARAM Arg4)
{
    // Regarding pointer use and the fourth parameter:
    // 1) Reinterpret the LPARAM as a size_t*
    // 2) Dereference the size_t* to get the variable
    // 3) Add one to the value of the variable
    (*reinterpret_cast<size_t *>(Arg4))++;

    return TRUE;
}

int main(void)
{
    size_t monitor_count = 0;

    // Regarding pointer use and the fourth parameter:
    // 1) Get address of variable
    // 2) Reinterpret the size_t* as an LPARAM
    EnumDisplayMonitors(NULL, NULL, monitor_enum_proc, reinterpret_cast<LPARAM>(&monitor_count));

    cout << monitor_count << endl;

    return 0;
}
edit flag offensive delete link more
0

answered 2020-12-21 10:10:43 -0600

Antonio gravatar image

In Linux you should be able to check the display availability by retrieving the environment variable DISPLAY

#if __linux__
    has_display = !(std::getenv("DISPLAY") == nullptr);
#endif
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2019-01-18 13:27:56 -0600

Seen: 4,812 times

Last updated: Dec 21 '20