XEmacs 21.2-b1
[chise/xemacs-chise.git.1] / src / console-x.c
diff --git a/src/console-x.c b/src/console-x.c
new file mode 100644 (file)
index 0000000..67c0bd5
--- /dev/null
@@ -0,0 +1,282 @@
+/* Console functions for X windows.
+   Copyright (C) 1996 Ben Wing.
+
+This file is part of XEmacs.
+
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with XEmacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Synched up with: Not in FSF. */
+
+/* Authorship:
+
+   Ben Wing: January 1996, for 19.14.
+ */
+
+#include <config.h>
+#include "lisp.h"
+
+#include "console-x.h"
+#include "process.h" /* canonicalize_host_name */
+#include "redisplay.h" /* for display_arg */
+
+DEFINE_CONSOLE_TYPE (x);
+
+static int
+x_initially_selected_for_input (struct console *con)
+{
+  return 1;
+}
+
+static void
+split_up_display_spec (Lisp_Object display, int *hostname_length,
+                      int *display_length, int *screen_length)
+{
+  char *dotptr;
+
+  dotptr = strrchr ((char *) XSTRING_DATA (display), ':');
+  if (!dotptr)
+    {
+      *hostname_length = XSTRING_LENGTH (display);
+      *display_length = 0;
+    }
+  else
+    {
+      *hostname_length = dotptr - (char *) XSTRING_DATA (display);
+
+      dotptr = strchr (dotptr, '.');
+      if (dotptr)
+       *display_length = (dotptr - (char *) XSTRING_DATA (display)
+                          - *hostname_length);
+      else
+       *display_length = XSTRING_LENGTH (display) - *hostname_length;
+    }
+
+  *screen_length = (XSTRING_LENGTH (display) - *display_length
+                   - *hostname_length);
+}
+
+/* Remember, in all of the following functions, we have to verify
+   the integrity of our input, because the generic functions don't. */
+
+static Lisp_Object
+x_device_to_console_connection (Lisp_Object connection, Error_behavior errb)
+{
+  /* Strip the trailing .# off of the connection, if it's there. */
+
+  if (NILP (connection))
+    return Qnil;
+  else
+    {
+      int hostname_length, display_length, screen_length;
+
+      if (!ERRB_EQ (errb, ERROR_ME))
+       {
+         if (!STRINGP (connection))
+           return Qunbound;
+       }
+      else
+       CHECK_STRING (connection);
+
+      split_up_display_spec (connection, &hostname_length, &display_length,
+                            &screen_length);
+      connection = make_string (XSTRING_DATA (connection),
+                               hostname_length + display_length);
+    }
+
+  return connection;
+}
+
+static Lisp_Object
+get_display_arg_connection (void)
+{
+  CONST char *disp_name;
+
+  /* If the user didn't explicitly specifify a display to use when
+     they called make-x-device, then we first check to see if a
+     display was specified on the command line with -display.  If
+     so, we set disp_name to it.  Otherwise we use XDisplayName to
+     see what DISPLAY is set to.  XtOpenDisplay knows how to do
+     both of these things, but we need to know the name to use. */
+  if (display_arg)
+    {
+      int elt;
+      int argc;
+      char **argv;
+      Lisp_Object conn;
+
+      make_argc_argv (Vx_initial_argv_list, &argc, &argv);
+
+      disp_name = NULL;
+      for (elt = 0; elt < argc; elt++)
+       {
+         if (!strcmp (argv[elt], "-d") || !strcmp (argv[elt], "-display"))
+           {
+             if (elt + 1 == argc)
+               {
+                 suppress_early_error_handler_backtrace = 1;
+                 error ("-display specified with no arg");
+               }
+             else
+               {
+                 disp_name = argv[elt + 1];
+                 break;
+               }
+           }
+       }
+
+      /* assert: display_arg is only set if we found the display
+        arg earlier so we can't fail to find it now. */
+      assert (disp_name != NULL);
+      conn = build_ext_string (disp_name, FORMAT_CTEXT);
+      free_argc_argv (argv);
+      return conn;
+    }
+  else
+    return build_ext_string (XDisplayName (0), FORMAT_CTEXT);
+}
+
+/* "semi-canonicalize" means convert to a nicer form for printing, but
+   don't completely canonicalize (into some likely ugly form) */
+
+static Lisp_Object
+x_semi_canonicalize_console_connection (Lisp_Object connection,
+                                       Error_behavior errb)
+{
+  struct gcpro gcpro1;
+
+  GCPRO1 (connection);
+
+  if (NILP (connection))
+    connection = get_display_arg_connection ();
+  else
+    {
+      if (!ERRB_EQ (errb, ERROR_ME))
+       {
+         if (!STRINGP (connection))
+           RETURN_UNGCPRO (Qunbound);
+       }
+      else
+       CHECK_STRING (connection);
+    }
+
+
+  /* Be lenient, allow people to specify a device connection instead of
+     a console connection -- e.g. "foo:0.0" instead of "foo:0".  This
+     only happens in `find-console' and `get-console'. */
+  connection = x_device_to_console_connection (connection, errb);
+
+  /* Check for a couple of standard special cases */
+  if (string_byte (XSTRING (connection), 0) == ':')
+    connection = concat2 (build_string ("localhost"), connection);
+  else if (!strncmp ((CONST char *) XSTRING_DATA (connection),
+                    "unix:", 5))
+    connection = concat2 (build_string ("localhost:"),
+                         Fsubstring (connection, make_int (5), Qnil));
+
+  RETURN_UNGCPRO (connection);
+}
+
+static Lisp_Object
+x_canonicalize_console_connection (Lisp_Object connection, Error_behavior errb)
+{
+  Lisp_Object hostname = Qnil;
+  struct gcpro gcpro1, gcpro2;
+
+  GCPRO2 (connection, hostname);
+
+  connection = x_semi_canonicalize_console_connection (connection, errb);
+  if (UNBOUNDP (connection))
+    RETURN_UNGCPRO (Qunbound);
+
+  {
+    int hostname_length, display_length, screen_length;
+
+    split_up_display_spec (connection, &hostname_length, &display_length,
+                          &screen_length);
+    hostname = Fsubstring (connection, Qzero, make_int (hostname_length));
+    hostname = canonicalize_host_name (hostname);
+    connection = concat2 (hostname,
+                         make_string (XSTRING_DATA (connection)
+                                      + hostname_length, display_length));
+  }
+
+  RETURN_UNGCPRO (connection);
+}
+
+static Lisp_Object
+x_semi_canonicalize_device_connection (Lisp_Object connection,
+                                      Error_behavior errb)
+{
+  int hostname_length, display_length, screen_length;
+  struct gcpro gcpro1;
+
+  GCPRO1 (connection);
+  if (NILP (connection))
+    connection = get_display_arg_connection ();
+  else
+    {
+      if (!ERRB_EQ (errb, ERROR_ME))
+       {
+         if (!STRINGP (connection))
+           RETURN_UNGCPRO (Qunbound);
+       }
+      else
+       CHECK_STRING (connection);
+    }
+
+  split_up_display_spec (connection, &hostname_length, &display_length,
+                        &screen_length);
+
+  if (!screen_length)
+    connection = concat2 (connection, build_string (".0"));
+  RETURN_UNGCPRO (connection);
+}
+
+static Lisp_Object
+x_canonicalize_device_connection (Lisp_Object connection, Error_behavior errb)
+{
+  int hostname_length, display_length, screen_length;
+  Lisp_Object screen_str = Qnil;
+  struct gcpro gcpro1, gcpro2;
+
+  GCPRO2 (screen_str, connection);
+  connection = x_semi_canonicalize_device_connection (connection, errb);
+  if (UNBOUNDP (connection))
+    RETURN_UNGCPRO (Qunbound);
+
+  split_up_display_spec (connection, &hostname_length, &display_length,
+                        &screen_length);
+
+  screen_str = build_string ((CONST char *) XSTRING_DATA (connection)
+                            + hostname_length + display_length);
+  connection = x_canonicalize_console_connection (connection, errb);
+
+  RETURN_UNGCPRO (concat2 (connection, screen_str));
+}
+
+void
+console_type_create_x (void)
+{
+  INITIALIZE_CONSOLE_TYPE (x, "x", "console-x-p");
+
+  CONSOLE_HAS_METHOD (x, semi_canonicalize_console_connection);
+  CONSOLE_HAS_METHOD (x, canonicalize_console_connection);
+  CONSOLE_HAS_METHOD (x, semi_canonicalize_device_connection);
+  CONSOLE_HAS_METHOD (x, canonicalize_device_connection);
+  CONSOLE_HAS_METHOD (x, device_to_console_connection);
+  CONSOLE_HAS_METHOD (x, initially_selected_for_input);
+}
+