XEmacs 21.2.36 "Notos"
[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 /* This file Mule-ized by Ben Wing, 7-10-00. */
24
25 /* Authorship:
26
27    Ben Wing: January 1996, for 19.14.
28  */
29
30 #include <config.h>
31 #include "lisp.h"
32
33 #include "console-x.h"
34 #include "buffer.h"
35 #include "process.h" /* canonicalize_host_name */
36 #include "redisplay.h" /* for display_arg */
37
38 DEFINE_CONSOLE_TYPE (x);
39
40 static int
41 x_initially_selected_for_input (struct console *con)
42 {
43   return 1;
44 }
45
46 static void
47 split_up_display_spec (Lisp_Object display, int *hostname_length,
48                        int *display_length, int *screen_length)
49 {
50   Bufbyte *dotptr;
51
52   dotptr = strrchr ((char *) XSTRING_DATA (display), ':');
53   if (!dotptr)
54     {
55       *hostname_length = XSTRING_LENGTH (display);
56       *display_length = 0;
57     }
58   else
59     {
60       *hostname_length = dotptr - XSTRING_DATA (display);
61
62       dotptr = strchr ((char *) dotptr, '.');
63       if (dotptr)
64         *display_length = (dotptr - XSTRING_DATA (display) - *hostname_length);
65       else
66         *display_length = XSTRING_LENGTH (display) - *hostname_length;
67     }
68
69   *screen_length = (XSTRING_LENGTH (display) - *display_length
70                     - *hostname_length);
71 }
72
73 /* Remember, in all of the following functions, we have to verify
74    the integrity of our input, because the generic functions don't. */
75
76 static Lisp_Object
77 x_device_to_console_connection (Lisp_Object connection, Error_behavior errb)
78 {
79   /* Strip the trailing .# off of the connection, if it's there. */
80
81   if (NILP (connection))
82     return Qnil;
83   else
84     {
85       int hostname_length, display_length, screen_length;
86
87       if (!ERRB_EQ (errb, ERROR_ME))
88         {
89           if (!STRINGP (connection))
90             return Qunbound;
91         }
92       else
93         CHECK_STRING (connection);
94
95       split_up_display_spec (connection, &hostname_length, &display_length,
96                              &screen_length);
97       connection = make_string (XSTRING_DATA (connection),
98                                 hostname_length + display_length);
99     }
100
101   return connection;
102 }
103
104 static Lisp_Object
105 get_display_arg_connection (void)
106 {
107   const Extbyte *disp_name;
108
109   /* If the user didn't explicitly specify a display to use when
110      they called make-x-device, then we first check to see if a
111      display was specified on the command line with -display.  If
112      so, we set disp_name to it.  Otherwise we use XDisplayName to
113      see what DISPLAY is set to.  XtOpenDisplay knows how to do
114      both of these things, but we need to know the name to use. */
115   if (display_arg)
116     {
117       int elt;
118       int argc;
119       Extbyte **argv;
120       Lisp_Object conn;
121
122       make_argc_argv (Vx_initial_argv_list, &argc, &argv);
123
124       disp_name = NULL;
125       for (elt = 0; elt < argc; elt++)
126         {
127           if (!strcmp (argv[elt], "-d") || !strcmp (argv[elt], "-display"))
128             {
129               if (elt + 1 == argc)
130                 {
131                   suppress_early_error_handler_backtrace = 1;
132                   type_error (Qinvalid_argument,
133                               "-display specified with no arg");
134                 }
135               else
136                 {
137                   disp_name = argv[elt + 1];
138                   break;
139                 }
140             }
141         }
142
143       /* assert: display_arg is only set if we found the display
144          arg earlier so we can't fail to find it now. */
145       assert (disp_name != NULL);
146       conn = build_ext_string (disp_name, Qcommand_argument_encoding);
147       free_argc_argv (argv);
148       return conn;
149     }
150   else
151     return build_ext_string (XDisplayName (0), Qx_display_name_encoding);
152 }
153
154 /* "semi-canonicalize" means convert to a nicer form for printing, but
155    don't completely canonicalize (into some likely ugly form) */
156
157 static Lisp_Object
158 x_semi_canonicalize_console_connection (Lisp_Object connection,
159                                         Error_behavior errb)
160 {
161   struct gcpro gcpro1;
162
163   GCPRO1 (connection);
164
165   if (NILP (connection))
166     connection = get_display_arg_connection ();
167   else
168     {
169       if (!ERRB_EQ (errb, ERROR_ME))
170         {
171           if (!STRINGP (connection))
172             RETURN_UNGCPRO (Qunbound);
173         }
174       else
175         CHECK_STRING (connection);
176     }
177
178
179   /* Be lenient, allow people to specify a device connection instead of
180      a console connection -- e.g. "foo:0.0" instead of "foo:0".  This
181      only happens in `find-console' and `get-console'. */
182   connection = x_device_to_console_connection (connection, errb);
183
184   /* Check for a couple of standard special cases */
185   if (string_byte (XSTRING (connection), 0) == ':')
186     connection = concat2 (build_string ("localhost"), connection);
187   else if (!strncmp (XSTRING_DATA (connection), "unix:", 5))
188     connection = concat2 (build_string ("localhost:"),
189                           Fsubstring (connection, make_int (5), Qnil));
190
191   RETURN_UNGCPRO (connection);
192 }
193
194 static Lisp_Object
195 x_canonicalize_console_connection (Lisp_Object connection, Error_behavior errb)
196 {
197   Lisp_Object hostname = Qnil;
198   struct gcpro gcpro1, gcpro2;
199
200   GCPRO2 (connection, hostname);
201
202   connection = x_semi_canonicalize_console_connection (connection, errb);
203   if (UNBOUNDP (connection))
204     RETURN_UNGCPRO (Qunbound);
205
206   {
207     int hostname_length, display_length, screen_length;
208
209     split_up_display_spec (connection, &hostname_length, &display_length,
210                            &screen_length);
211     hostname = Fsubstring (connection, Qzero, make_int (hostname_length));
212     hostname = canonicalize_host_name (hostname);
213     connection = concat2 (hostname,
214                           make_string (XSTRING_DATA (connection)
215                                        + hostname_length, display_length));
216   }
217
218   RETURN_UNGCPRO (connection);
219 }
220
221 static Lisp_Object
222 x_semi_canonicalize_device_connection (Lisp_Object connection,
223                                        Error_behavior errb)
224 {
225   int hostname_length, display_length, screen_length;
226   struct gcpro gcpro1;
227
228   GCPRO1 (connection);
229   if (NILP (connection))
230     connection = get_display_arg_connection ();
231   else
232     {
233       if (!ERRB_EQ (errb, ERROR_ME))
234         {
235           if (!STRINGP (connection))
236             RETURN_UNGCPRO (Qunbound);
237         }
238       else
239         CHECK_STRING (connection);
240     }
241
242   split_up_display_spec (connection, &hostname_length, &display_length,
243                          &screen_length);
244
245   if (!screen_length)
246     connection = concat2 (connection, build_string (".0"));
247   RETURN_UNGCPRO (connection);
248 }
249
250 static Lisp_Object
251 x_canonicalize_device_connection (Lisp_Object connection, Error_behavior errb)
252 {
253   int hostname_length, display_length, screen_length;
254   Lisp_Object screen_str = Qnil;
255   struct gcpro gcpro1, gcpro2;
256
257   GCPRO2 (screen_str, connection);
258   connection = x_semi_canonicalize_device_connection (connection, errb);
259   if (UNBOUNDP (connection))
260     RETURN_UNGCPRO (Qunbound);
261
262   split_up_display_spec (connection, &hostname_length, &display_length,
263                          &screen_length);
264
265   screen_str = build_string (XSTRING_DATA (connection)
266                              + hostname_length + display_length);
267   connection = x_canonicalize_console_connection (connection, errb);
268
269   RETURN_UNGCPRO (concat2 (connection, screen_str));
270 }
271
272 void
273 console_type_create_x (void)
274 {
275   INITIALIZE_CONSOLE_TYPE (x, "x", "console-x-p");
276
277   CONSOLE_HAS_METHOD (x, semi_canonicalize_console_connection);
278   CONSOLE_HAS_METHOD (x, canonicalize_console_connection);
279   CONSOLE_HAS_METHOD (x, semi_canonicalize_device_connection);
280   CONSOLE_HAS_METHOD (x, canonicalize_device_connection);
281   CONSOLE_HAS_METHOD (x, device_to_console_connection);
282   CONSOLE_HAS_METHOD (x, initially_selected_for_input);
283 }
284
285
286 void
287 reinit_console_type_create_x (void)
288 {
289   REINITIALIZE_CONSOLE_TYPE (x);
290 }