[GRASSLIST:1641] Re: grass-5.0.3rc5 on cygwin

Glynn Clements glynn.clements at virgin.net
Sun Nov 2 00:30:20 EST 2003

Richard Greenwood wrote:

> Thank you for your prompt reply. After I examined the differences between 
> my configure scripts for builds that worked and those that did not I found 
> that by REMOVING the following two option I was able to build 5.0.3rc5 on 
> cygwin with functional monitors.
>     --x-includes=`pwd`/src/display/devices/windows/libW11
>     --x-libraries=`pwd`/src/display/devices/windows/libW11/lib
> I am working ion Windows 2000. I was not specifying --enable-w11 and I was 
> specifying  -D__W98__
> If I understand your reply and extrapolate it bit;
> 1. I was including the 'generic' drivers by specifying --x-includes... and 
> --x-libraries...
> 2. But I was doing a 'native' build because I did not specify --enable-w11

You were almost doing a "W11" build. The --enable-w11 switch basically
does three things:

1. Adds src/display/devices/windows (the libW11 code) to the list of
subdirectories to build.

2. Sets X_CFLAGS and X_LIBS so that libW11 (and its headers) are used
instead of Xlib.

3. Defines __W98__ to make mon.start use spawnl().

However, without step 1, libW11 won't actually be built. The probable
result is that you were compiling with the W11 X headers but linking
against Cygwin's Xlib.

If you are building an "xserver" version on Win2K, you shouldn't need
to use any Windows-specific switches; Cygwin with XFree86 should look
enough like Unix/X11 that the fact that it's Windows underneath
shouldn't matter (at least, not to XDRIVER; Cygwin's Tcl/Tk may cause
problems for tcltkgrass and NVIZ).

> I am still pretty confused by the 'generic' versus the 'native' cygwin 
> versions. From a user perspective I understand the differences, but from a 
> functional perspective I am rather unclear on what the differences are. And 
> from a build perspective I am obviously confused. I do not mean to impose 
> on your time for a tutorial on the subject, but if there is an existing 
> discussion of the topic I would surely be interested in it.

The "generic" version uses libW11 (which is basically an Xlib
emulation for Windows), and doesn't require an X server. The "xserver"
version is built the same way as on Unix, and requires X libraries and
an X server.

However, there is one aspect of X which libW11 doesn't quite get right
(for obvious reasons). That is the fact that, with a real X11
implementation, the only "OS resource" which the application uses is a
(socket) connection to an X server. This would be irrelevant for many
X applications, but not for XDRIVER.

The way that the display drivers normally work is that they do all of
the initialisation first, then call listen() on the socket (via which
the various d.* programs access the driver). Once the socket is ready
to accept connections, the driver calls fork() and the parent process

This works fine for X, as the child process inherits the connection to
the X server, and so can still make use of the Window which was
created by the parent. However, this doesn't work on Windows; Win32
resources (e.g. windows) aren't "inherited" across Cygwin's fork().

There is a reason for the ordering (initialise first, only fork() when
ready to accept connections). "d.mon start=..." basically does:

	system("$GISBASE/etc/mon.start <monitor name>");
	system("$GISBASE/etc/mon.select <monitor name>");

mon.start looks up the monitor parameters in etc/monitorcap then
executes the driver with execl(), so the driver's parent process is
the same process on which system() is waiting. When the driver's
parent process exits, the first system() above completes, and it goes
on to run mon.select. Because the driver's parent process doesn't exit
until the driver is initialised and accepting connections,
mon.select's connect to the driver will succeed unless the driver has

Because this doesn't work for the libW11 version, mon.start has to be
changed to:

a) pass a "-" as the second argument to the driver; this prevents the
fork/exit, and

b) start the driver with spawnl(_P_DETACH,...), which starts the
driver in the background.

One side effect of this is that mon.start returns as soon as it has
started the driver. Consequently, mon.select's connection attempt may
fail, in which case you have to select the driver manually with
"d.mon select=...".

The above should only be relevant to the "generic" version. However,
it appears that there is a problem with Cygwin's fork() on Windows
95/98/ME, meaning that the above mechanism doesn't work with the
"xserver" version either. However, it should work with NT/2K/XP.

Glynn Clements <glynn.clements at virgin.net>

More information about the grass-user mailing list