[GRASS-dev] 'g.gui wxpython' won't work in wingrass as wxgui is a shell script

Hello,

as wxgui is a shell script, g.gui wxpython (which does:

else if (strcmp(type->answer, "wxpython") == 0) {
        sprintf (progname, "%s/etc/wxpython/scripts/wxgui", G_gisbase());
        if (rc_file->answer) {
            G_spawn(progname, "wxgui", rc_file->answer, NULL);
)

will not work.

I don't really see the need for this script and it is a nuisance for
wingrass ot require a shell to launch the python gui...

Moritz

Moritz Lennert wrote:

as wxgui is a shell script, g.gui wxpython (which does:

else if (strcmp(type->answer, "wxpython") == 0) {
        sprintf (progname, "%s/etc/wxpython/scripts/wxgui", G_gisbase());
        if (rc_file->answer) {
            G_spawn(progname, "wxgui", rc_file->answer, NULL);
)

will not work.

I don't really see the need for this script and it is a nuisance for
wingrass ot require a shell to launch the python gui...

Right; it may as well just do:

  sprintf(progname, "%s/etc/wxpython/wxgui.py", G_gisbase());
        if (rc_file->answer) {
      G_spawn("python", "wxgui", progname, "--workspace", rc_file->answer, NULL);
  }
  else {
      G_spawn("python", "wxgui", progname, NULL);
  }

AFAICT, the only reason for making g.gui a C program rather than a
script is so that you don't need a Bourne shell (MSys etc) to start
the GUI.

--
Glynn Clements <glynn@gclements.plus.com>

Hi,

2008/2/21, Glynn Clements <glynn@gclements.plus.com>:

> as wxgui is a shell script, g.gui wxpython (which does:
>
> else if (strcmp(type->answer, "wxpython") == 0) {
> sprintf (progname, "%s/etc/wxpython/scripts/wxgui", G_gisbase());
> if (rc_file->answer) {
> G_spawn(progname, "wxgui", rc_file->answer, NULL);
> )
>
> will not work.
>
> I don't really see the need for this script and it is a nuisance for
> wingrass ot require a shell to launch the python gui...

Glynn:

Right; it may as well just do:

        sprintf(progname, "%s/etc/wxpython/wxgui.py", G_gisbase());
        if (rc_file->answer) {
            G_spawn("python", "wxgui", progname, "--workspace", rc_file->answer, NULL);
        }
        else {
            G_spawn("python", "wxgui", progname, NULL);
        }

AFAICT, the only reason for making g.gui a C program rather than a
script is so that you don't need a Bourne shell (MSys etc) to start
the GUI.

thanks, now in SVN.

Martin

--
Martin Landa <landa.martin gmail.com> * http://gama.fsv.cvut.cz/~landa *

Hi,

2008/2/21, Glynn Clements <glynn@gclements.plus.com>:

Moritz Lennert wrote:
> as wxgui is a shell script, g.gui wxpython (which does:
>
> else if (strcmp(type->answer, "wxpython") == 0) {
> sprintf (progname, "%s/etc/wxpython/scripts/wxgui", G_gisbase());
> if (rc_file->answer) {
> G_spawn(progname, "wxgui", rc_file->answer, NULL);
> )
>
> will not work.

since gis.m and d.m are also shell scripts, g.gui tcltk|oldtcktk will
not work too(?)

> I don't really see the need for this script and it is a nuisance for
> wingrass ot require a shell to launch the python gui...

Right; it may as well just do:

        sprintf(progname, "%s/etc/wxpython/wxgui.py", G_gisbase());
        if (rc_file->answer) {
            G_spawn("python", "wxgui", progname, "--workspace", rc_file->answer, NULL);
        }
        else {
            G_spawn("python", "wxgui", progname, NULL);
        }

AFAICT, the only reason for making g.gui a C program rather than a
script is so that you don't need a Bourne shell (MSys etc) to start
the GUI.

There is one problem, when you run `g.gui wxpython`, the program is
waiting for thread termination. So you cannot use xterm when wxGUI is
running. I am not sure how to fix it since I am not so familiar with
G_spawn*.

Martin

--
Martin Landa <landa.martin gmail.com> * http://gama.fsv.cvut.cz/~landa *

On 27/02/08 21:05, Martin Landa wrote:

Hi,

2008/2/21, Glynn Clements <glynn@gclements.plus.com>:

Moritz Lennert wrote:
> as wxgui is a shell script, g.gui wxpython (which does:
>
> else if (strcmp(type->answer, "wxpython") == 0) {
> sprintf (progname, "%s/etc/wxpython/scripts/wxgui", G_gisbase());
> if (rc_file->answer) {
> G_spawn(progname, "wxgui", rc_file->answer, NULL);
> )
>
> will not work.

since gis.m and d.m are also shell scripts, g.gui tcltk|oldtcktk will
not work too(?)

I have never tried d.m, but for gis.m there is a gis.m.bat replacement [1] which directly call the tcltk code.

There is one problem, when you run `g.gui wxpython`, the program is
waiting for thread termination. So you cannot use xterm when wxGUI is
running. I am not sure how to fix it since I am not so familiar with
G_spawn*.

I guess you will have to fork before you G_spawn ?

Moritz

[1] http://trac.osgeo.org/grass/browser/grass/trunk/gui/tcltk/gis.m/gis.m.bat

Martin Landa wrote:

Hi,

2008/2/21, Glynn Clements <glynn@gclements.plus.com>:

> Moritz Lennert wrote:
> > as wxgui is a shell script, g.gui wxpython (which does:
> >
> > else if (strcmp(type->answer, "wxpython") == 0) {
> > sprintf (progname, "%s/etc/wxpython/scripts/wxgui", G_gisbase());
> > if (rc_file->answer) {
> > G_spawn(progname, "wxgui", rc_file->answer, NULL);
> > )
> >
> > will not work.

since gis.m and d.m are also shell scripts, g.gui tcltk|oldtcktk will
not work too(?)

The batch file may work, but I would suggest invoking gm.tcl directly,
similar to the above.

The gis.m script ends up executing either:

  exec "$GRASS_WISH" "$GISBASE/etc/gm/gm.tcl" -name gm_tcl &
or:
  exec "$GRASS_WISH" "$GISBASE/etc/gm/gm.tcl" -name gm_tcl "$GIS_OPT_DMRC" sh &

So the corresponding C code should be roughly:

  sprintf(progname, "%s/etc/gm/gm.tcl", G_gisbase());
        if (rc_file->answer) {
      G_spawn(getenv("GRASS_WISH"), "gis.m", progname, "-name", "gm_tcl", rc_file->answer, NULL);
  }
  else {
      G_spawn(getenv("GRASS_WISH"), "gis.m", progname, "-name", "gm_tcl", NULL);
  }

Similarly for d.m.

BTW, I have no idea what that trailing "sh" is doing there. I think
that it's just getting ignored, anyhow.

There is one problem, when you run `g.gui wxpython`, the program is
waiting for thread termination. So you cannot use xterm when wxGUI is
running. I am not sure how to fix it since I am not so familiar with
G_spawn*.

G_spawn() behaves like system() in that it waits for termination.

You could use G_spawn_ex() with the SF_BACKGROUND flag (although we're
still waiting for a Windows implementation of G_spawn_ex()), or you
could fork() before calling G_spawn() (but fork() doesn't exist on
windows).

So far as a Windows implementation of G_spawn_ex() is concerned, a
partial implementation using spawnvp() or spawnvpe() should be
relatively straightforward, and better than nothing.

That wouldn't support redirection, current directory, or signal
handling (I don't think that signal handling can be implemented on
Windows in any case). But implementing SF_BACKGROUND is
straightforward (don't use P_WAIT), and implementing environment
bindings isn't particularly problematic (the existing environment is
in the global variable "_environ").

AFAICT, a version based upon CreateProcess() would also allow the
redirection and current directory flags to be implemented.

FWIW, the primary function which needs to be re-implemented is
do_spawn(), in lib/gis/spawn.c.

Off the top of my head, the following seems about right:

static int do_spawn(const char *command)
{
  char **env;
  int status;
#if 0
  /* these also need implementing, eventually */
  do_redirects(redirects, num_redirects);
  env = do_bindings(_environ, bindings, num_bindings);
#else
  env = _environ;
#endif

  status = spawnvpe(background ? _P_NOWAIT : _P_WAIT, command, (char **) args, env);

  if (!background && status < 0)
    G_warning(_("Unable to execute command"));

  return status;
}

--
Glynn Clements <glynn@gclements.plus.com>

Glynn Clements wrote:

> > > as wxgui is a shell script, g.gui wxpython (which does:
> > >
> > > else if (strcmp(type->answer, "wxpython") == 0) {
> > > sprintf (progname, "%s/etc/wxpython/scripts/wxgui", G_gisbase());
> > > if (rc_file->answer) {
> > > G_spawn(progname, "wxgui", rc_file->answer, NULL);
> > > )
> > >
> > > will not work.
>
> since gis.m and d.m are also shell scripts, g.gui tcltk|oldtcktk will
> not work too(?)

The batch file may work, but I would suggest invoking gm.tcl directly,
similar to the above.

I have committed changes to g.gui to invoke gm.tcl and d.m.tcl
directly, rather than via the shell scripts.

One consequence of this is that all three GUIs currently run in the
foreground, so you need to run g.gui itself in the background (i.e.
"g.gui &") to avoid locking up the terminal (or you can use Ctrl-Z
then "bg" after starting g.gui).

> There is one problem, when you run `g.gui wxpython`, the program is
> waiting for thread termination. So you cannot use xterm when wxGUI is
> running. I am not sure how to fix it since I am not so familiar with
> G_spawn*.

G_spawn() behaves like system() in that it waits for termination.

You could use G_spawn_ex() with the SF_BACKGROUND flag (although we're
still waiting for a Windows implementation of G_spawn_ex()), or you
could fork() before calling G_spawn() (but fork() doesn't exist on
windows).

So far as a Windows implementation of G_spawn_ex() is concerned, a
partial implementation using spawnvp() or spawnvpe() should be
relatively straightforward, and better than nothing.

I have also committed a minimal Windows implementation of
G_[v]spawn_ex(), as outlined below. It hasn't been tested yet, though.

That wouldn't support redirection, current directory, or signal
handling (I don't think that signal handling can be implemented on
Windows in any case). But implementing SF_BACKGROUND is
straightforward (don't use P_WAIT), and implementing environment
bindings isn't particularly problematic (the existing environment is
in the global variable "_environ").

AFAICT, a version based upon CreateProcess() would also allow the
redirection and current directory flags to be implemented.

FWIW, the primary function which needs to be re-implemented is
do_spawn(), in lib/gis/spawn.c.

Off the top of my head, the following seems about right:

static int do_spawn(const char *command)
{
  char **env;
  int status;
#if 0
  /* these also need implementing, eventually */
  do_redirects(redirects, num_redirects);
  env = do_bindings(_environ, bindings, num_bindings);
#else
  env = _environ;
#endif

  status = spawnvpe(background ? _P_NOWAIT : _P_WAIT, command, (char **) args, env);

  if (!background && status < 0)
    G_warning(_("Unable to execute command"));

  return status;
}

--
Glynn Clements <glynn@gclements.plus.com>

Glynn Clements <glynn@gclements.plus.com> writes:

[...]

>> So far as a Windows implementation of G_spawn_ex() is concerned, a
>> partial implementation using spawnvp() or spawnvpe() should be
>> relatively straightforward, and better than nothing.

> I have also committed a minimal Windows implementation of
> G_[v]spawn_ex(), as outlined below. It hasn't been tested yet,
> though.

  JFYI: Gnulib contains execute (), which is meant to spawn
  processes on the POSIX and W32 systems in a portable manner:

$ nl -ba gnulib/lib/execute.h
...
    23 /* Execute a command, optionally redirecting any of the three standard file
    24 descriptors to /dev/null. Return its exit code.
    25 If it didn't terminate correctly, exit if exit_on_error is true, otherwise
    26 return 127.
    27 If ignore_sigpipe is true, consider a subprocess termination due to SIGPIPE
    28 as equivalent to a success. This is suitable for processes whose only
    29 purpose is to write to standard output.
    30 If slave_process is true, the child process will be terminated when its
    31 creator receives a catchable fatal signal.
    32 It is recommended that no signal is blocked or ignored while execute()
    33 is called. See pipe.h for the reason. */
    34 extern int execute (const char *progname,
    35 const char *prog_path, char **prog_argv,
    36 bool ignore_sigpipe,
    37 bool null_stdin, bool null_stdout, bool null_stderr,
    38 bool slave_process, bool exit_on_error);
...
$

  Apparently, the only problem preventing the use of Gnulib in
  GRASS is that it may require a newer Autoconf. (I'm still
  planning to get my hands on both of these problems.)

[...]

Ivan Shmakov wrote:

  Apparently, the only problem preventing the use of Gnulib in
  GRASS is that it may require a newer Autoconf.

A C file won't care about which autoconf version (if any) was used, so
long as the right macros are defined.

--
Glynn Clements <glynn@gclements.plus.com>

Glynn Clements <glynn@gclements.plus.com> writes:

>> Apparently, the only problem preventing the use of Gnulib in GRASS
>> is that it may require a newer Autoconf.

> A C file won't care about which autoconf version (if any) was used,
> so long as the right macros are defined.

  Surely, but that's exactly the point. In order to decide which
  functions are not supported or defective on the host platform,
  and thus are to be provided by Gnulib, an appropriate testing is
  to be done. To relieve the Gnulib user of the responsibility to
  maintain the proper set of Autoconf macros invocations (as
  Gnulib dependencies do change), Gnulib provides its own set of
  Autoconf macros.

  And I guess, these macros aren't 2.13-compatible.