Detecting if GUI environment is available without terminating

Hi,

I want to be able to detect if a program does not have a GUI interface
available (for instance, not running under X11 or doesn't have DISPLAY
set) and use a substitute interface instead. However, in this
situation, wxpython always terminates like this:

$ ./test.py

Gtk-WARNING **: cannot open display:

There is no exception thrown, no error code returned, nothing. And
MANY wxPython calls, if they're the first in the program, do this --
and it's not documented anywhere.

Is there a way around this problem?

-- John

John Goerzen wrote:

Hi,

I want to be able to detect if a program does not have a GUI interface
available (for instance, not running under X11 or doesn't have DISPLAY
set) and use a substitute interface instead. However, in this
situation, wxpython always terminates like this:

$ ./test.py

Gtk-WARNING **: cannot open display:

There is no exception thrown, no error code returned, nothing. And
MANY wxPython calls, if they're the first in the program, do this --
and it's not documented anywhere.

Is there a way around this problem?

In 2.4 you'll need to test before you import wxPython, as there is some toolkit initialization that happens upon import. (When 2.5 is available that won't be neccessary anymore as the initialization won't happen until a wxApp object is created.) So probably the easiest way to manage it for now is to start the app with a .py module that does not import wxPython at all, check for the display and then import the module that implements your GUI (and imports wxPython) only if it can safely run.

There isn't a single wxPython API for testing if a GUI interface available, alhtough there probably could be, but it's easy to work it out in other ways. On Windows it is effectivly always available so no worries there. On OS X there is some code in wxApp that does it that you could pull out into your prelude module. On X-Windows systems just check for os.environ['DISPLAY'] or for -display on the command line.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

John Goerzen wrote:
>
>I want to be able to detect if a program does not have a GUI interface
>available (for instance, not running under X11 or doesn't have DISPLAY
>set) and use a substitute interface instead. However, in this
>situation, wxpython always terminates[...]
>
>Is there a way around this problem?
>

In 2.4 you'll need to test before you import wxPython, as there is some
toolkit initialization that happens upon import. (When 2.5 is available
that won't be neccessary anymore as the initialization won't happen
until a wxApp object is created.) So probably the easiest way to manage
it for now is to start the app with a .py module that does not import
wxPython at all, check for the display and then import the module that
implements your GUI (and imports wxPython) only if it can safely run.

[...]

On X-Windows systems just check for os.environ['DISPLAY'] or for
-display on the command line.

And if the value found is bogus...?

···

On Tue, Sep 16, 2003 at 10:12:07PM -0700, Robin Dunn wrote:

Joshua Judson Rosen <rozzin@geekspace.com> writes:

On X-Windows systems just check for os.environ['DISPLAY'] or for
-display on the command line.

And if the value found is bogus...?

Indeed. Plus, the whole thing is ambiguous... If I'm on OS X, I may
be using X11 and GTK or I may be using Aqua -- lack of DISPLAY doesn't
mean no GUI is available. Not to mention that all these approaches
violate the cross-platform idea that wx* is supposed to be good for.

My very ugly, works-on-Unix, nasty, annoying, hack is this:

def testforwx():
    pid = os.fork()
    if pid:
        # parent
        return not os.WEXITSTATUS(os.waitpid(pid, 0)[1])
    else:
        # child
        try:
            import wxPython.wx
        except: sys.exit(1)
        try:
            if not wxPython.wx.wxFrame(None, -1, "Test").Destroy(): sys.exit(1)
        except: sys.exit(1)
        sys.exit(0)

Experimentation has shown that the program could terminate at any of
these points:

* the import
* the wxFrame

if $DISPLAY is not set or is set badly.

I still think that is rather ridiculous. The system should raise an
exception, not just terminate outright. Terminating outright is
completely broken, IMHO.

(BTW, I am using 2.4)

-- John

Chris Barker wrote:

#include <X11/Xlib.h>
#include <stdio.h>
int main(int argc,char *argv)
{
  Display *display;
  display=XOpenDisplay(NULL);
  if(display==(Display *) NULL) {
                printf("Server not accepting connections\n");
                return(1);
  }
  return(0);
}

This should be pretty easy to include in wxWindows and/or wxPython.

Maybe I'll test if out tomorrow

Allright, it's tomorrow, and I tried to test it out, but I can't get the
above simple C program to link. I get:

IsX.o: In function `main':
IsX.o(.text+0xc): undefined reference to `XOpenDisplay'
collect2: ld returned 1 exit status

XOPenDisplay is in Xlib.h, or it wouldn't have compiled (also the man
pages say it is). I have:

/usr/X11R6/lib

in ld.so.conf (I also tried specifying it on the gcc command line)

I've got X running on this machine just fine, so I must have the
required libraries!

I imagine this is a simple linking issue that reflects that I have no
idea what I'm doing, but I'm curious enough to want to know..anyone have
an idea what library I might be missing?

(RedHat Linux 7.2)

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer
                                        
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Chris Barker wrote:

Chris Barker wrote:

#include <X11/Xlib.h>
#include <stdio.h>
int main(int argc,char *argv)
{
Display *display;
display=XOpenDisplay(NULL);
if(display==(Display *) NULL) {
               printf("Server not accepting connections\n");
               return(1);
}
return(0);
}

This should be pretty easy to include in wxWindows and/or wxPython.

Maybe I'll test if out tomorrow

Allright, it's tomorrow, and I tried to test it out, but I can't get the
above simple C program to link. I get:

IsX.o: In function `main':
IsX.o(.text+0xc): undefined reference to `XOpenDisplay'
collect2: ld returned 1 exit status

XOPenDisplay is in Xlib.h, or it wouldn't have compiled (also the man
pages say it is). I have:

/usr/X11R6/lib

in ld.so.conf (I also tried specifying it on the gcc command line)

I've got X running on this machine just fine, so I must have the
required libraries!

Probably a stupid question, but did you link with -lX ?

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Robin Dunn wrote:

Probably a stupid question, but did you link with -lX ?

There is no limit to the number od stup things I could have been doing
wrong, and no, I did not link with -lX, nor did it work when I tried.
However, linking with -lX11 does work. Thanks for the hint.

I've got that silly littel C program working, I hope tomorrow I'll be
able to compile it into a Pyton extension, and we'll have a nifty
utility. Another option is to keep it a C program and jsut call it with
os.system(), but I'm thinking it might be a nifty utility to put in
wxPython directly.

I'll let you know how it goes.

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer
                                        
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Chris Barker wrote:

Robin Dunn wrote:

Probably a stupid question, but did you link with -lX ?

There is no limit to the number od stup things I could have been doing
wrong, and no, I did not link with -lX, nor did it work when I tried.
However, linking with -lX11 does work. Thanks for the hint.

I've got that silly littel C program working, I hope tomorrow I'll be
able to compile it into a Pyton extension, and we'll have a nifty
utility. Another option is to keep it a C program and jsut call it with
os.system(), but I'm thinking it might be a nifty utility to put in
wxPython directly.

Yep, but in 2.4 it will need to be in a separate module that can be imported without having to import wxPython first because of when the gtk_init is currently called. In 2.5 it can easily be put in the core wxPython module if we wanted to, or at least in the package.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!