Contents of release-21-2 at 1999-07-02-10.
[chise/xemacs-chise.git.1] / src / console-x.c
1 /* Console functions for X windows.
2    Copyright (C) 1996 Ben Wing.
3
4 This file is part of XEmacs.
5
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING.  If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 /* Synched up with: Not in FSF. */
22
23 /* Authorship:
24
25    Ben Wing: January 1996, for 19.14.
26  */
27
28 #include <config.h>
29 #include "lisp.h"
30
31 #include "console-x.h"
32 #include "process.h" /* canonicalize_host_name */
33 #include "redisplay.h" /* for display_arg */
34
35 DEFINE_CONSOLE_TYPE (x);
36
37 static int
38 x_initially_selected_for_input (struct console *con)
39 {
40   return 1;
41 }
42
43 static void
44 split_up_display_spec (Lisp_Object display, int *hostname_length,
45                        int *display_length, int *screen_length)
46 {
47   char *dotptr;
48
49   dotptr = strrchr ((char *) XSTRING_DATA (display), ':');
50   if (!dotptr)
51     {
52       *hostname_length = XSTRING_LENGTH (display);
53       *display_length = 0;
54     }
55   else
56     {
57       *hostname_length = dotptr - (char *) XSTRING_DATA (display);
58
59       dotptr = strchr (dotptr, '.');
60       if (dotptr)
61         *display_length = (dotptr - (char *) XSTRING_DATA (display)
62                            - *hostname_length);
63       else
64         *display_length = XSTRING_LENGTH (display) - *hostname_length;
65     }
66
67   *screen_length = (XSTRING_LENGTH (display) - *display_length
68                     - *hostname_length);
69 }
70
71 /* Remember, in all of the following functions, we have to verify
72    the integrity of our input, because the generic functions don't. */
73
74 static Lisp_Object
75 x_device_to_console_connection (Lisp_Object connection, Error_behavior errb)
76 {
77   /* Strip the trailing .# off of the connection, if it's there. */
78
79   if (NILP (connection))
80     return Qnil;
81   else
82     {
83       int hostname_length, display_length, screen_length;
84
85       if (!ERRB_EQ (errb, ERROR_ME))
86         {
87           if (!STRINGP (connection))
88             return Qunbound;
89         }
90       else
91         CHECK_STRING (connection);
92
93       split_up_display_spec (connection, &hostname_length, &display_length,
94                              &screen_length);
95       connection = make_string (XSTRING_DATA (connection),
96                                 hostname_length + display_length);
97     }
98
99   return connection;
100 }
101
102 static Lisp_Object
103 get_display_arg_connection (void)
104 {
105   CONST char *disp_name;
106
107   /* If the user didn't explicitly specify a display to use when
108      they called make-x-device, then we first check to see if a
109      display was specified on the command line with -display.  If
110      so, we set disp_name to it.  Otherwise we use XDisplayName to
111      see what DISPLAY is set to.  XtOpenDisplay knows how to do
112      both of these things, but we need to know the name to use. */
113   if (display_arg)
114     {
115       int elt;
116       int argc;
117       char **argv;
118       Lisp_Object conn;
119
120       make_argc_argv (Vx_initial_argv_list, &argc, &argv);
121
122       disp_name = NULL;
123       for (elt = 0; elt < argc; elt++)
124         {
125           if (!strcmp (argv[elt], "-d") || !strcmp (argv[elt], "-display"))
126             {
127               if (elt + 1 == argc)
128                 {
129                   suppress_early_error_handler_backtrace = 1;
130                   error ("-display specified with no arg");
131                 }
132               else
133                 {
134                   disp_name = argv[elt + 1];
135                   break;
136                 }
137             }
138         }
139
140       /* assert: display_arg is only set if we found the display
141          arg earlier so we can't fail to find it now. */
142       assert (disp_name != NULL);
143       conn = build_ext_string (disp_name, FORMAT_CTEXT);
144       free_argc_argv (argv);
145       return conn;
146     }
147   else
148     return build_ext_string (XDisplayName (0), FORMAT_CTEXT);
149 }
150
151 /* "semi-canonicalize" means convert to a nicer form for printing, but
152    don't completely canonicalize (into some likely ugly form) */
153
154 static Lisp_Object
155 x_semi_canonicalize_console_connection (Lisp_Object connection,
156                                         Error_behavior errb)
157 {
158   struct gcpro gcpro1;
159
160   GCPRO1 (connection);
161
162   if (NILP (connection))
163     connection = get_display_arg_connection ();
164   else
165     {
166       if (!ERRB_EQ (errb, ERROR_ME))
167         {
168           if (!STRINGP (connection))
169             RETURN_UNGCPRO (Qunbound);
170         }
171       else
172         CHECK_STRING (connection);
173     }
174
175
176   /* Be lenient, allow people to specify a device connection instead of
177      a console connection -- e.g. "foo:0.0" instead of "foo:0".  This
178      only happens in `find-console' and `get-console'. */
179   connection = x_device_to_console_connection (connection, errb);
180
181   /* Check for a couple of standard special cases */
182   if (string_byte (XSTRING (connection), 0) == ':')
183     connection = concat2 (build_string ("localhost"), connection);
184   else if (!strncmp ((CONST char *) XSTRING_DATA (connection),
185                      "unix:", 5))
186     connection = concat2 (build_string ("localhost:"),
187                           Fsubstring (connection, make_int (5), Qnil));
188
189   RETURN_UNGCPRO (connection);
190 }
191
192 static Lisp_Object
193 x_canonicalize_console_connection (Lisp_Object connection, Error_behavior errb)
194 {
195   Lisp_Object hostname = Qnil;
196   struct gcpro gcpro1, gcpro2;
197
198   GCPRO2 (connection, hostname);
199
200   connection = x_semi_canonicalize_console_connection (connection, errb);
201   if (UNBOUNDP (connection))
202     RETURN_UNGCPRO (Qunbound);
203
204   {
205     int hostname_length, display_length, screen_length;
206
207     split_up_display_spec (connection, &hostname_length, &display_length,
208                            &screen_length);
209     hostname = Fsubstring (connection, Qzero, make_int (hostname_length));
210     hostname = canonicalize_host_name (hostname);
211     connection = concat2 (hostname,
212                           make_string (XSTRING_DATA (connection)
213                                        + hostname_length, display_length));
214   }
215
216   RETURN_UNGCPRO (connection);
217 }
218
219 static Lisp_Object
220 x_semi_canonicalize_device_connection (Lisp_Object connection,
221                                        Error_behavior errb)
222 {
223   int hostname_length, display_length, screen_length;
224   struct gcpro gcpro1;
225
226   GCPRO1 (connection);
227   if (NILP (connection))
228     connection = get_display_arg_connection ();
229   else
230     {
231       if (!ERRB_EQ (errb, ERROR_ME))
232         {
233           if (!STRINGP (connection))
234             RETURN_UNGCPRO (Qunbound);
235         }
236       else
237         CHECK_STRING (connection);
238     }
239
240   split_up_display_spec (connection, &hostname_length, &display_length,
241                          &screen_length);
242
243   if (!screen_length)
244     connection = concat2 (connection, build_string (".0"));
245   RETURN_UNGCPRO (connection);
246 }
247
248 static Lisp_Object
249 x_canonicalize_device_connection (Lisp_Object connection, Error_behavior errb)
250 {
251   int hostname_length, display_length, screen_length;
252   Lisp_Object screen_str = Qnil;
253   struct gcpro gcpro1, gcpro2;
254
255   GCPRO2 (screen_str, connection);
256   connection = x_semi_canonicalize_device_connection (connection, errb);
257   if (UNBOUNDP (connection))
258     RETURN_UNGCPRO (Qunbound);
259
260   split_up_display_spec (connection, &hostname_length, &display_length,
261                          &screen_length);
262
263   screen_str = build_string ((CONST char *) XSTRING_DATA (connection)
264                              + hostname_length + display_length);
265   connection = x_canonicalize_console_connection (connection, errb);
266
267   RETURN_UNGCPRO (concat2 (connection, screen_str));
268 }
269
270 void
271 console_type_create_x (void)
272 {
273   INITIALIZE_CONSOLE_TYPE (x, "x", "console-x-p");
274
275   CONSOLE_HAS_METHOD (x, semi_canonicalize_console_connection);
276   CONSOLE_HAS_METHOD (x, canonicalize_console_connection);
277   CONSOLE_HAS_METHOD (x, semi_canonicalize_device_connection);
278   CONSOLE_HAS_METHOD (x, canonicalize_device_connection);
279   CONSOLE_HAS_METHOD (x, device_to_console_connection);
280   CONSOLE_HAS_METHOD (x, initially_selected_for_input);
281 }
282