Re: X or console?
by skyknight (Hermit) on Jul 23, 2003 at 18:09 UTC
|
Just check that the DISPLAY environment variable is set to something. I believe that is the only thing that emacs does. | [reply] |
|
|
This probably is not the way to go. Even if the DISPLAY env var is set, you might not have permissions in the server access control list for X. This probably also still applies to checking to see if the tcp port is open.
~~
naChoZ
| [reply] |
|
|
From my understanding, it's hardly ever the case these days that people do X over straight TCP. It's woefully insecure so almost all smart admins shut it off. Typically it's configured such that only requests from the local machine will be accepted. This works over ssh because your ssh client and the ssh server tunnel the information so it looks like it's happening from the localhost. I would imagine that virtually all X usage these days is either on the work station itself, or over such a tunnel.
I really do think that emacs just tests the DISPLAY variable, and I'll explain why... When I'm working under Windows, I don't always have an X server up and running. I have to remember to turn on Exceed when I want to do work. When I use SecureCRT to ssh into something, the DISPLAY environment var gets set no matter what. When I fire up emacs, and I've remembered to turn on Exceed I get a nice little X emacs window. When I forget to turn on Exceed, however, emacs fails to start, and SecureCRT puts up a popup window saying that there was an error, the text of which I forget, but it's something like "display not found".
I think that this is a reasonable guess, but if you've got a better idea as to the reason for the behavior of that software triad I'd like to hear it, because I can't think of one off the top of my head.
| [reply] |
|
|
Re: X or console?
by halley (Prior) on Jul 23, 2003 at 18:12 UTC
|
I made a quickie module (sorry, can't post it) for work. A first-check is for the environment variable DISPLAY. If you don't have it, the user's not accessing the shell with an X service available. This is pseudocode:
sub hasX
{
return undef if not defined $ENV{DISPLAY};
return undef if port_not_listening($ENV{DISPLAY});
return 1;
}
It's not foolproof. But after you get a hint from these, you can look at CPAN's X11 modules for more support.
-- [ e d @ h a l l e y . c c ] | [reply] [d/l] |
|
|
sub port_not_listening
{
# UNTESTED
my $timeout = 10;
my ($remote, $port) = split(/:/, $_[0]);
$iaddr = inet_aton($remote) or return 1;
$paddr = sockaddr_in($port, $iaddr);
$proto = getprotobyname('tcp'); # X uses tcp, right?
socket(SOCK, PF_INET, SOCK_STREAM, $proto) or die "socket: $!";
eval
{
local $SIG{ALRM} = sub { die "connection timeout\n" };
alarm $timeout;
connect(SOCK, $paddr) or die "$! for $remote\n";
alarm 0;
};
return 1 if ( $@ );
return 0;
}
Update: Halley points out correctly (below) that the line my ($remote, $port) = split(/:/, $_[0]); is unlikely to actually yield a correct port number.
--Bob Niederman, http://bob-n.com | [reply] [d/l] [select] |
|
|
| [reply] [d/l] |
|
|
Re: X or console?
by adrianh (Chancellor) on Jul 23, 2003 at 20:21 UTC
|
In general the easiest thing to do is try to talk to an X11 server. If you can't then you haven't got access to X.
I've not used X11 in Perl in anger, but the following should do the trick:
use X11::Protocol;
my $display = $ENV{DISPLAY} || 'localhost:0';
my $has_x11 = eval { X11::Protocol->new($display) } ? 1 : 0;
While checking for $DISPLAY and an open port is better than nothing it can still give an incorrect result because that open port may not be an X11 server, and that X11 server may not allow you to connect even if it exists.
I presume whatever X API you're using has some kind of initialisation code - try it. If it succeeds you have access :-) | [reply] [d/l] [select] |
Re: X or console?
by mr_mischief (Monsignor) on Jul 23, 2003 at 19:55 UTC
|
First off, let me say that these are not the droids you're looking for -- err, I mean this is not the advice you asked about.
I don't write much for X. My main reason for using X (other than games and graphical browsing ;-) is to have multiple terminal windows open side by side. When I do write one program which must have an X interface and a term interface in the same program, I force the issue into the user's hands. I use a command-line switch such as '--Xmode', '-x', or '-g' to mean it should present its X face instead of its term face. It's not hard to type '-g' and it's very little trouble if you intend to use it from an icon. Also, it simplifies testing the term version while in X.
I wouldn't dare try to sway you towards this, but I thought I'd mention it as an off-the-wall option.
Christopher E. Stith | [reply] |
Re: X or console?
by greenFox (Vicar) on Jul 24, 2003 at 07:21 UTC
|
This isn't perl but it's a reasonably comprehensive test for X. You could just go straight to xdpyinfo but then you have to wait for it to time out if no x server is present. It's bash syntax and was provided to me by an instructor on a training course (thanks Boyd!), conversion to perl left as an exercise for the reader :)
declare displayhost=${DISPLAY%:*}
declare pingcmd
case $OSTYPE in
solaris*) pingcmd="ping $displayhost 1";;
linux*) pingcmd="ping -c 1 $displayhost";;
*) : ;;
# TODO insert other flavors of ping here
esac
# If displayhost is blank DISPLAY is probably ":0" so we
# shouldn't ping
[[ -z "$displayhost" ]] && pingcmd=""
if ! ( $pingcmd && xdpyinfo ) >/dev/null 2>&1; then
# Either we can't ping the machine or xdpyinfo failed.
# Either way, X is probably not going to work!
unset _running_X
fi
-- Do not seek to follow in the footsteps of the wise. Seek what they sought. -Basho | [reply] [d/l] |