[comp.windows.x] GNU Emacs shell mode and DISPLAY env variable

barmar@think.COM (Barry Margolin) (02/01/89)

In GNU Emacs 18.52:

When running GNU Emacs in an X window (using its "-d" option), is
there any way to get shell mode to automatically set the subprocess's
DISPLAY environment variable appropriately, as xterm does?  I'm
putting some customization into my .cshrc that wants to do certain
things if it's being run in an X11 window (specifically, it's checking
to see whether DISPLAY contains a ".", so it can tell whether it's in
an X10 or X11 window, since we haven't yet fully converted).

I did an apropos of "^x-" and "display" in Emacs, looking for a
variable or function that would return the current display, but didn't
see anything.  Can anyone help me?

Barry Margolin
Thinking Machines Corp.

barmar@think.com
{uunet,harvard}!think!barmar

fkittred@bbn.com (Fletcher Kittredge) (02/01/89)

Check in your config.h file for a line which looks like:

#define MAINTAIN_ENVIRONMENT

If you don't have such a line, add it and remake emacs.  This will allow you
to use the elisp function setenv.  Example

(setenv "DISPLAY" "unix:0")

It will also allow you to use the getenv function.

regards,
fletcher


Fletcher E. Kittredge  fkittred@bbn.com

jr@bbn.com (John Robinson) (02/01/89)

In article <35945@think.UUCP>, barmar@think (Barry Margolin) writes:
>In GNU Emacs 18.52:
>
>When running GNU Emacs in an X window (using its "-d" option), is
>there any way to get shell mode to automatically set the subprocess's
>DISPLAY environment variable appropriately, as xterm does?

If you set the DISPLAY variable coming into emacs, it will be
inherited by the shell.  So instead of starting emacs this way:

  emacs -d unix:0

say (to csh):

  setenv DISPLAY unix:0 ; emacs

Otherwise, you can put a default into .emacs_csh (see help for
function shell).

>I did an apropos of "^x-" and "display" in Emacs, looking for a
>variable or function that would return the current display, but didn't
>see anything.  Can anyone help me?

You can get any environment varilable in emacs' environment with
(getenv "VARNAME").

Now, the variable command-line-args ought to have your "-d" and
display-name in it, but the X code strips away its args from this list
when it starts up.  This seems to be a bug.  I suspect it is due to
the X code really being a graft onto emacs at this point.  Really, the
switches should be handled in the same loop that handles the rest of
the switches to emacs, but it has to run sooner in order to set up the
new X window, etc.  Maybe v19 will get this better...
--
/jr
jr@bbn.com or bbn!jr

rlk@THINK.COM (Robert L. Krawitz) (02/01/89)

The problem is that if I start up an emacs with

emacs -d foobar:0.0

then I have no way of knowing the value of foobar (it's not part of
the environment).

I think that the -d foobar:0.0 is kept in the command line that
emacs-lisp sees, though, so you (barmar, actually) can extract it from
the list of arguments.

harvard >>>>>>  |	Robert Krawitz <rlk@think.com>	245 First St.
bloom-beacon >  |think!rlk	(postmaster)		Cambridge, MA  02142
topaz >>>>>>>>  .	Thinking Machines Corp.		(617)876-1111

rlk@THINK.COM (Robert L. Krawitz) (02/02/89)

   Date: 1 Feb 89 14:56:56 GMT
   From: jr%bbn.com@bbn.com  (John Robinson)

   In article <35945@think.UUCP>, barmar@think (Barry Margolin) writes:

   If you set the DISPLAY variable coming into emacs, it will be
   inherited by the shell.  So instead of starting emacs this way:

     emacs -d unix:0

   say (to csh):

     setenv DISPLAY unix:0 ; emacs

This can be done, but in the local environment it's a pain.  Having to
bootstrap the display into emacs lisp by means of the underlying shell
isn't a very effective solution.

   Now, the variable command-line-args ought to have your "-d" and
   display-name in it, but the X code strips away its args from this list
   when it starts up.  This seems to be a bug.  I suspect it is due to
   the X code really being a graft onto emacs at this point.  Really, the
   switches should be handled in the same loop that handles the rest of
   the switches to emacs, but it has to run sooner in order to set up the
   new X window, etc.  Maybe v19 will get this better...

The danger with handling the X switches in the same loop as the other
switches is that if the startup.el code fails, your window will never
come up.  The initial X code handled the switches in just this
fashion, but it wound up being very slow and flaky (when startup
failed).  I fixed this in X10 emacs to force processing of
switches/defaults early on, but I did all my operations on a copy of
argv and never nuked the command line switches, but rather hacked the
x init file to handle the X command line switches and ignore them
(this can, of course, be overridden by your .emacs file).  Most people
running emacs with X10 are using the "old" command line processing
rather than the "new" (the only places using the "new" processing are
Thinking Machines and Project Athena before they converted to X11).
If the X11 code is splicing out the X command line arguments, then
it's doing something wrong.

The emacs 18 X code (and emacs 17, and even emacs 16) X code was
indeed a graft onto emacs.  RMS did put in various display and startup
hooks in version 17 so that Yakim Martillo and later I could do the X
code without it being overly dirty.  The problem, though, is that
emacs treats X as being simply a terminal emulator (not in the sense
of xterm, but rather in the sense of there being a set of display
primitives that are very terminal based; the system is somewhat like
curses in the sense of having a set of primitive operations), because
emacs 18 is still terminal-based.  I have not been involved in the
development of X11/emacs (which based on a quick study of the code
appears to be a straight port of emacs/X10 without use of the
toolkit), nor have I been involved in the development of emacs 19.

harvard >>>>>>  |	Robert Krawitz <rlk@think.com>	245 First St.
bloom-beacon >  |think!rlk	(postmaster)		Cambridge, MA  02142
topaz >>>>>>>>  .	Thinking Machines Corp.		(617)876-1111

jr@CHIPS.BBN.COM (John Robinson) (02/02/89)

>    say (to csh):
> 
>      setenv DISPLAY unix:0 ; emacs
> 
> This can be done, but in the local environment it's a pain.  Having to
> bootstrap the display into emacs lisp by means of the underlying shell
> isn't a very effective solution.

Agreed, I didn't like it much either.

> If the X11 code is splicing out the X command line arguments, then
> it's doing something wrong.

It seems to be.  Arguments like -geometry and -fn stay in
command-line-args just fine.  -d and its argument, however, are
stripped by the skip_args mechanism for some reason; they are among
the class that have to be "first" in the arg list (actually there is
an order), like -t and -batch.  Excerpts from emacs.c:main():

#ifdef HAVE_X_WINDOWS
/* Handle the -d switch, which means use a different display for X */
  if (skip_args + 2 < argc && (!strcmp (argv[skip_args + 1], "-d") ||
			       !strcmp (argv[skip_args + 1], "-display")))
    {
      skip_args += 2;
      alternate_display = argv[skip_args];
    } 
  else
    alternate_display = 0;
#endif	/* HAVE_X_WINDOWS */

... and later on ...

  init_cmdargs (argc, argv, skip_args);	/* Create list Vcommand_line_args */

init_cmdargs only puts arguments whose index is 0 (i.e., "emacs") or
greater than skip_args into the Vcommand_line_args.

So I have to conclude that this is a bug, and I think you agree.

Any xpert want to hazard a fix?

/jr
jr@bbn.com or bbn!jr

meissner@tiktok.dg.com (Michael Meissner) (02/02/89)

In article <35945@think.UUCP> barmar@think.UUCP (Barry Margolin) writes:
| In GNU Emacs 18.52:
| 
| When running GNU Emacs in an X window (using its "-d" option), is
| there any way to get shell mode to automatically set the subprocess's
| DISPLAY environment variable appropriately, as xterm does?  I'm
| putting some customization into my .cshrc that wants to do certain
| things if it's being run in an X11 window (specifically, it's checking
| to see whether DISPLAY contains a ".", so it can tell whether it's in
| an X10 or X11 window, since we haven't yet fully converted).

Go into the source directory for emacs, and add a define to config.h
for MAINTAIN_ENVIRONMENT, do a make clean, followed by a make.  If
this is defined, emacs passes the entire environment to subprocesses.
You can also do (setenv "variable" "value") then from within emacs.
Note, the documentation for setenv is messed up....
--
Michael Meissner, Data General.
Uucp:	...!mcnc!rti!xyzzy!meissner
Arpa:	meissner@dg-rtp.DG.COM   (or) meissner%dg-rtp.DG.COM@relay.cs.net

jr@bbn.com (John Robinson) (02/02/89)

In article <3195@xyzzy.UUCP>, meissner@tiktok (Michael Meissner) writes:
>Go into the source directory for emacs, and add a define to config.h
>for MAINTAIN_ENVIRONMENT, do a make clean, followed by a make.  If
>this is defined, emacs passes the entire environment to subprocesses.
>You can also do (setenv "variable" "value") then from within emacs.
>Note, the documentation for setenv is messed up....

I don't believe this is quite right.  Emacs always passes its
environment to its children.  MAINTAIN_ENVIRONMENT adds (setenv) so
that you can manipulate it.  (getenv) is there regardless.  I (and
others) have never understood why setenv is not always built-in.
--
/jr
jr@bbn.com or bbn!jr