(<DENTISTRY SYMBOL *>): Add missing `general-category'.
[chise/xemacs-chise.git.1] / src / console.c
1 /* The console object.
2    Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
3    Copyright (C) 1996 Ben Wing.
4
5 This file is part of XEmacs.
6
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING.  If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* Synched up with: Not in FSF. */
23
24 /* Written by Ben Wing. */
25
26 #include <config.h>
27 #include "lisp.h"
28
29 #include "buffer.h"
30 #include "console-tty.h"
31 #include "events.h"
32 #include "frame.h"
33 #include "redisplay.h"
34 #include "sysdep.h"
35 #include "window.h"
36
37 Lisp_Object Vconsole_list, Vselected_console;
38
39 Lisp_Object Vcreate_console_hook, Vdelete_console_hook;
40
41 Lisp_Object Qconsolep, Qconsole_live_p;
42 Lisp_Object Qcreate_console_hook;
43 Lisp_Object Qdelete_console_hook;
44
45 Lisp_Object Qsuspend_hook;
46 Lisp_Object Qsuspend_resume_hook;
47
48 /* This structure holds the default values of the console-local
49    variables defined with DEFVAR_CONSOLE_LOCAL, that have special
50    slots in each console.  The default value occupies the same slot
51    in this structure as an individual console's value occupies in
52    that console.  Setting the default value also goes through the
53    list of consoles and stores into each console that does not say
54    it has a local value.  */
55 Lisp_Object Vconsole_defaults;
56 static void *console_defaults_saved_slots;
57
58 /* This structure marks which slots in a console have corresponding
59    default values in console_defaults.
60    Each such slot has a nonzero value in this structure.
61    The value has only one nonzero bit.
62
63    When a console has its own local value for a slot,
64    the bit for that slot (found in the same slot in this structure)
65    is turned on in the console's local_var_flags slot.
66
67    If a slot in this structure is 0, then there is a DEFVAR_CONSOLE_LOCAL
68    for the slot, but there is no default value for it; the corresponding
69    slot in console_defaults is not used except to initialize newly-created
70    consoles.
71
72    If a slot is -1, then there is a DEFVAR_CONSOLE_LOCAL for it
73   as well as a default value which is used to initialize newly-created
74    consoles and as a reset-value when local-vars are killed.
75
76    If a slot is -2, there is no DEFVAR_CONSOLE_LOCAL for it.
77    (The slot is always local, but there's no lisp variable for it.)
78    The default value is only used to initialize newly-creation consoles.
79
80    If a slot is -3, then there is no DEFVAR_CONSOLE_LOCAL for it but
81    there is a default which is used to initialize newly-creation
82    consoles and as a reset-value when local-vars are killed.
83
84
85    */
86 struct console console_local_flags;
87
88 /* This structure holds the names of symbols whose values may be
89    console-local.  It is indexed and accessed in the same way as the above. */
90 static Lisp_Object Vconsole_local_symbols;
91 static void *console_local_symbols_saved_slots;
92
93 DEFINE_CONSOLE_TYPE (dead);
94
95 Lisp_Object Vconsole_type_list;
96
97 console_type_entry_dynarr *the_console_type_entry_dynarr;
98
99 \f
100 static Lisp_Object
101 mark_console (Lisp_Object obj)
102 {
103   struct console *con = XCONSOLE (obj);
104
105 #define MARKED_SLOT(x) mark_object (con->x)
106 #include "conslots.h"
107 #undef MARKED_SLOT
108
109   /* Can be zero for Vconsole_defaults, Vconsole_local_symbols */
110   if (con->conmeths)
111     {
112       mark_object (con->conmeths->symbol);
113       MAYBE_CONMETH (con, mark_console, (con));
114     }
115
116   return Qnil;
117 }
118
119 static void
120 print_console (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
121 {
122   struct console *con = XCONSOLE (obj);
123   char buf[256];
124
125   if (print_readably)
126     error ("printing unreadable object #<console %s 0x%x>",
127            XSTRING_DATA (con->name), con->header.uid);
128
129   sprintf (buf, "#<%s-console", !CONSOLE_LIVE_P (con) ? "dead" :
130            CONSOLE_TYPE_NAME (con));
131   write_c_string (buf, printcharfun);
132   if (CONSOLE_LIVE_P (con) && !NILP (CONSOLE_CONNECTION (con)))
133     {
134       write_c_string (" on ", printcharfun);
135       print_internal (CONSOLE_CONNECTION (con), printcharfun, 1);
136     }
137   sprintf (buf, " 0x%x>", con->header.uid);
138   write_c_string (buf, printcharfun);
139 }
140
141 DEFINE_LRECORD_IMPLEMENTATION ("console", console,
142                                mark_console, print_console, 0, 0, 0, 0,
143                                struct console);
144 \f
145 static struct console *
146 allocate_console (void)
147 {
148   Lisp_Object console;
149   struct console *con = alloc_lcrecord_type (struct console, &lrecord_console);
150   struct gcpro gcpro1;
151
152   copy_lcrecord (con, XCONSOLE (Vconsole_defaults));
153
154   XSETCONSOLE (console, con);
155   GCPRO1 (console);
156
157   con->quit_char = 7; /* C-g */
158   con->command_builder = allocate_command_builder (console);
159   con->function_key_map = Fmake_sparse_keymap (Qnil);
160
161   UNGCPRO;
162   return con;
163 }
164
165 struct console *
166 decode_console (Lisp_Object console)
167 {
168   if (NILP (console))
169     console = Fselected_console ();
170   /* quietly accept devices and frames for the console arg */
171   if (DEVICEP (console) || FRAMEP (console))
172     console = DEVICE_CONSOLE (decode_device (console));
173   CHECK_LIVE_CONSOLE (console);
174   return XCONSOLE (console);
175 }
176
177
178 struct console_methods *
179 decode_console_type (Lisp_Object type, Error_behavior errb)
180 {
181   int i;
182
183   for (i = 0; i < Dynarr_length (the_console_type_entry_dynarr); i++)
184     if (EQ (type, Dynarr_at (the_console_type_entry_dynarr, i).symbol))
185       return Dynarr_at (the_console_type_entry_dynarr, i).meths;
186
187   maybe_signal_simple_error ("Invalid console type", type, Qconsole, errb);
188
189   return 0;
190 }
191
192 int
193 valid_console_type_p (Lisp_Object type)
194 {
195   return decode_console_type (type, ERROR_ME_NOT) != 0;
196 }
197
198 DEFUN ("valid-console-type-p", Fvalid_console_type_p, 1, 1, 0, /*
199 Return t if CONSOLE-TYPE is a valid console type.
200 Valid types are 'x, 'tty, and 'stream.
201 */
202        (console_type))
203 {
204   return valid_console_type_p (console_type) ? Qt : Qnil;
205 }
206
207 DEFUN ("console-type-list", Fconsole_type_list, 0, 0, 0, /*
208 Return a list of valid console types.
209 */
210        ())
211 {
212   return Fcopy_sequence (Vconsole_type_list);
213 }
214
215 DEFUN ("cdfw-console", Fcdfw_console, 1, 1, 0, /*
216 Given a console, device, frame, or window, return the associated console.
217 Return nil otherwise.
218 */
219        (object))
220 {
221   return CDFW_CONSOLE (object);
222 }
223
224 \f
225 DEFUN ("selected-console", Fselected_console, 0, 0, 0, /*
226 Return the console which is currently active.
227 */
228        ())
229 {
230   return Vselected_console;
231 }
232
233 /* Called from selected_device_1(), called from selected_frame_1(),
234    called from Fselect_window() */
235 void
236 select_console_1 (Lisp_Object console)
237 {
238   /* perhaps this should do something more complicated */
239   Vselected_console = console;
240
241   /* #### Schedule this to be removed in 19.14 */
242 #ifdef HAVE_X_WINDOWS
243   if (CONSOLE_X_P (XCONSOLE (console)))
244     Vwindow_system = Qx;
245   else
246 #endif
247 #ifdef HAVE_GTK
248   if (CONSOLE_GTK_P (XCONSOLE (console)))
249     Vwindow_system = Qgtk;
250   else
251 #endif
252 #ifdef HAVE_MS_WINDOWS
253   if (CONSOLE_MSWINDOWS_P (XCONSOLE (console)))
254     Vwindow_system = Qmswindows;
255   else
256 #endif
257     Vwindow_system = Qnil;
258 }
259
260 DEFUN ("select-console", Fselect_console, 1, 1, 0, /*
261 Select the console CONSOLE.
262 Subsequent editing commands apply to its selected device, selected frame,
263 and selected window.  The selection of CONSOLE lasts until the next time
264 the user does something to select a different console, or until the next
265 time this function is called.
266 */
267        (console))
268 {
269   Lisp_Object device;
270
271   CHECK_LIVE_CONSOLE (console);
272
273   device = CONSOLE_SELECTED_DEVICE (XCONSOLE (console));
274   if (!NILP (device))
275     {
276       struct device *d = XDEVICE (device);
277       Lisp_Object frame = DEVICE_SELECTED_FRAME (d);
278       if (!NILP (frame))
279         {
280           struct frame *f = XFRAME(frame);
281           Fselect_window (FRAME_SELECTED_WINDOW (f), Qnil);
282         }
283       else
284         error ("Can't select console with no frames.");
285     }
286   else
287     error ("Can't select a console with no devices");
288   return Qnil;
289 }
290
291 void
292 set_console_last_nonminibuf_frame (struct console *con,
293                                    Lisp_Object frame)
294 {
295   con->last_nonminibuf_frame = frame;
296 }
297
298 DEFUN ("consolep", Fconsolep, 1, 1, 0, /*
299 Return non-nil if OBJECT is a console.
300 */
301        (object))
302 {
303   return CONSOLEP (object) ? Qt : Qnil;
304 }
305
306 DEFUN ("console-live-p", Fconsole_live_p, 1, 1, 0, /*
307 Return non-nil if OBJECT is a console that has not been deleted.
308 */
309        (object))
310 {
311   return CONSOLEP (object) && CONSOLE_LIVE_P (XCONSOLE (object)) ? Qt : Qnil;
312 }
313
314 DEFUN ("console-type", Fconsole_type, 0, 1, 0, /*
315 Return the console type (e.g. `x' or `tty') of CONSOLE.
316 Value is `tty' for a tty console (a character-only terminal),
317 `x' for a console that is an X display,
318 `mswindows' for a console that is a Windows NT/95/97 connection,
319 `pc' for a console that is a direct-write MS-DOS connection (not yet
320   implemented),
321 `stream' for a stream console (which acts like a stdio stream), and
322 `dead' for a deleted console.
323 */
324        (console))
325 {
326   /* don't call decode_console() because we want to allow for dead
327      consoles. */
328   if (NILP (console))
329     console = Fselected_console ();
330   CHECK_CONSOLE (console);
331   return CONSOLE_TYPE (XCONSOLE (console));
332 }
333
334 DEFUN ("console-name", Fconsole_name, 0, 1, 0, /*
335 Return the name of CONSOLE.
336 */
337        (console))
338 {
339   return CONSOLE_NAME (decode_console (console));
340 }
341
342 DEFUN ("console-connection", Fconsole_connection, 0, 1, 0, /*
343 Return the connection of the specified console.
344 CONSOLE defaults to the selected console if omitted.
345 */
346        (console))
347 {
348   return CONSOLE_CONNECTION (decode_console (console));
349 }
350
351 Lisp_Object
352 make_console (struct console *con)
353 {
354   Lisp_Object console;
355   XSETCONSOLE (console, con);
356   return console;
357 }
358
359 static Lisp_Object
360 semi_canonicalize_console_connection (struct console_methods *meths,
361                                       Lisp_Object name, Error_behavior errb)
362 {
363   if (HAS_CONTYPE_METH_P (meths, semi_canonicalize_console_connection))
364     return CONTYPE_METH (meths, semi_canonicalize_console_connection,
365                          (name, errb));
366   else
367     return CONTYPE_METH_OR_GIVEN (meths, canonicalize_console_connection,
368                                   (name, errb), name);
369 }
370
371 static Lisp_Object
372 canonicalize_console_connection (struct console_methods *meths,
373                                  Lisp_Object name, Error_behavior errb)
374 {
375   if (HAS_CONTYPE_METH_P (meths, canonicalize_console_connection))
376     return CONTYPE_METH (meths, canonicalize_console_connection,
377                          (name, errb));
378   else
379     return CONTYPE_METH_OR_GIVEN (meths, semi_canonicalize_console_connection,
380                                   (name, errb), name);
381 }
382
383 static Lisp_Object
384 find_console_of_type (struct console_methods *meths, Lisp_Object canon)
385 {
386   Lisp_Object concons;
387
388   CONSOLE_LOOP (concons)
389     {
390       Lisp_Object console = XCAR (concons);
391
392       if (EQ (CONMETH_TYPE (meths), CONSOLE_TYPE (XCONSOLE (console)))
393           && internal_equal (CONSOLE_CANON_CONNECTION (XCONSOLE (console)),
394                              canon, 0))
395         return console;
396     }
397
398   return Qnil;
399 }
400
401 DEFUN ("find-console", Ffind_console, 1, 2, 0, /*
402 Look for an existing console attached to connection CONNECTION.
403 Return the console if found; otherwise, return nil.
404
405 If TYPE is specified, only return consoles of that type; otherwise,
406 return consoles of any type. (It is possible, although unlikely,
407 that two consoles of different types could have the same connection
408 name; in such a case, the first console found is returned.)
409 */
410        (connection, type))
411 {
412   Lisp_Object canon = Qnil;
413   struct gcpro gcpro1;
414
415   GCPRO1 (canon);
416
417   if (!NILP (type))
418     {
419       struct console_methods *conmeths = decode_console_type (type, ERROR_ME);
420       canon = canonicalize_console_connection (conmeths, connection,
421                                                ERROR_ME_NOT);
422       if (UNBOUNDP (canon))
423         RETURN_UNGCPRO (Qnil);
424
425       RETURN_UNGCPRO (find_console_of_type (conmeths, canon));
426     }
427   else
428     {
429       int i;
430
431       for (i = 0; i < Dynarr_length (the_console_type_entry_dynarr); i++)
432         {
433           struct console_methods *conmeths =
434             Dynarr_at (the_console_type_entry_dynarr, i).meths;
435           canon = canonicalize_console_connection (conmeths, connection,
436                                                    ERROR_ME_NOT);
437           if (!UNBOUNDP (canon))
438             {
439               Lisp_Object console = find_console_of_type (conmeths, canon);
440               if (!NILP (console))
441                 RETURN_UNGCPRO (console);
442             }
443         }
444
445       RETURN_UNGCPRO (Qnil);
446     }
447 }
448
449 DEFUN ("get-console", Fget_console, 1, 2, 0, /*
450 Look for an existing console attached to connection CONNECTION.
451 Return the console if found; otherwise, signal an error.
452
453 If TYPE is specified, only return consoles of that type; otherwise,
454 return consoles of any type. (It is possible, although unlikely,
455 that two consoles of different types could have the same connection
456 name; in such a case, the first console found is returned.)
457 */
458        (connection, type))
459 {
460   Lisp_Object console = Ffind_console (connection, type);
461   if (NILP (console))
462     {
463       if (NILP (type))
464         signal_simple_error ("No such console", connection);
465       else
466         signal_simple_error_2 ("No such console", type, connection);
467     }
468   return console;
469 }
470
471 Lisp_Object
472 create_console (Lisp_Object name, Lisp_Object type, Lisp_Object connection,
473                 Lisp_Object props)
474 {
475   /* This function can GC */
476   struct console *con;
477   Lisp_Object console;
478   struct gcpro gcpro1;
479
480   console = Ffind_console (connection, type);
481   if (!NILP (console))
482     return console;
483
484   con = allocate_console ();
485   XSETCONSOLE (console, con);
486
487   GCPRO1 (console);
488
489   con->conmeths = decode_console_type (type, ERROR_ME);
490
491   CONSOLE_NAME (con) = name;
492   CONSOLE_CONNECTION (con) =
493     semi_canonicalize_console_connection (con->conmeths, connection,
494                                           ERROR_ME);
495   CONSOLE_CANON_CONNECTION (con) =
496     canonicalize_console_connection (con->conmeths, connection,
497                                      ERROR_ME);
498
499   MAYBE_CONMETH (con, init_console, (con, props));
500
501   /* Do it this way so that the console list is in order of creation */
502   Vconsole_list = nconc2 (Vconsole_list, Fcons (console, Qnil));
503
504   if (CONMETH_OR_GIVEN (con, initially_selected_for_input, (con), 0))
505     event_stream_select_console (con);
506
507   UNGCPRO;
508   return console;
509 }
510
511 void
512 add_entry_to_console_type_list (Lisp_Object symbol,
513                                 struct console_methods *meths)
514 {
515   struct console_type_entry entry;
516
517   entry.symbol = symbol;
518   entry.meths = meths;
519   Dynarr_add (the_console_type_entry_dynarr, entry);
520   Vconsole_type_list = Fcons (symbol, Vconsole_type_list);
521 }
522
523 /* find a console other than the selected one.  Prefer non-stream
524    consoles over stream consoles. */
525
526 static Lisp_Object
527 find_other_console (Lisp_Object console)
528 {
529   Lisp_Object concons;
530
531   /* look for a non-stream console */
532   CONSOLE_LOOP (concons)
533     {
534       Lisp_Object con = XCAR (concons);
535       if (!CONSOLE_STREAM_P (XCONSOLE (con))
536           && !EQ (con, console)
537           && !NILP (CONSOLE_SELECTED_DEVICE (XCONSOLE (con)))
538           && !NILP (DEVICE_SELECTED_FRAME
539                     (XDEVICE (CONSOLE_SELECTED_DEVICE (XCONSOLE (con))))))
540         break;
541     }
542   if (!NILP (concons))
543     return XCAR (concons);
544
545   /* OK, now look for a stream console */
546   CONSOLE_LOOP (concons)
547     {
548       Lisp_Object con = XCAR (concons);
549       if (!EQ (con, console)
550           && !NILP (CONSOLE_SELECTED_DEVICE (XCONSOLE (con)))
551           && !NILP (DEVICE_SELECTED_FRAME
552                     (XDEVICE (CONSOLE_SELECTED_DEVICE (XCONSOLE (con))))))
553         break;
554     }
555   if (!NILP (concons))
556     return XCAR (concons);
557
558   /* Sorry, there ain't none */
559   return Qnil;
560 }
561
562 static int
563 find_nonminibuffer_frame_not_on_console_predicate (Lisp_Object frame,
564                                                    void *closure)
565 {
566   Lisp_Object console;
567
568   VOID_TO_LISP (console, closure);
569   if (FRAME_MINIBUF_ONLY_P (XFRAME (frame)))
570     return 0;
571   if (EQ (console, FRAME_CONSOLE (XFRAME (frame))))
572     return 0;
573   return 1;
574 }
575
576 static Lisp_Object
577 find_nonminibuffer_frame_not_on_console (Lisp_Object console)
578 {
579   return find_some_frame (find_nonminibuffer_frame_not_on_console_predicate,
580                           LISP_TO_VOID (console));
581 }
582
583 /* Delete console CON.
584
585    If FORCE is non-zero, allow deletion of the only frame.
586
587    If CALLED_FROM_KILL_EMACS is non-zero, then, if
588    deleting the last console, just delete it,
589    instead of calling `save-buffers-kill-emacs'.
590
591    If FROM_IO_ERROR is non-zero, then the console is gone due
592    to an I/O error.  This affects what happens if we exit
593    (we do an emergency exit instead of `save-buffers-kill-emacs'.)
594 */
595
596 void
597 delete_console_internal (struct console *con, int force,
598                          int called_from_kill_emacs, int from_io_error)
599 {
600   /* This function can GC */
601   Lisp_Object console;
602   struct gcpro gcpro1;
603
604   /* OK to delete an already-deleted console. */
605   if (!CONSOLE_LIVE_P (con))
606     return;
607
608   XSETCONSOLE (console, con);
609   GCPRO1 (console);
610
611   if (!called_from_kill_emacs)
612     {
613       int down_we_go = 0;
614
615       if ((XINT (Flength (Vconsole_list)) == 1)
616           /* if we just created the console, it might not be listed,
617              or something ... */
618           && !NILP (memq_no_quit (console, Vconsole_list)))
619         down_we_go = 1;
620       /* If there aren't any nonminibuffer frames that would
621          be left, then exit. */
622       else if (NILP (find_nonminibuffer_frame_not_on_console (console)))
623         down_we_go = 1;
624
625       if (down_we_go)
626         {
627           if (!force)
628             error ("Attempt to delete the only frame");
629           else if (from_io_error)
630             {
631               /* Mayday mayday!  We're going down! */
632               stderr_out ("  Autosaving and exiting...\n");
633               Vwindow_system = Qnil; /* let it lie! */
634               preparing_for_armageddon = 1;
635               Fkill_emacs (make_int (70));
636             }
637           else
638             {
639               call0 (Qsave_buffers_kill_emacs);
640               UNGCPRO;
641               /* If we get here, the user said they didn't want
642                  to exit, so don't. */
643               return;
644             }
645         }
646     }
647
648   /* Breathe a sigh of relief.  We're still alive. */
649
650   {
651     Lisp_Object frmcons, devcons;
652
653     /* First delete all frames without their own minibuffers,
654        to avoid errors coming from attempting to delete a frame
655        that is a surrogate for another frame.
656
657        We don't set "called_from_delete_console" because we want the
658        device to go ahead and get deleted if we delete the last frame
659        on a device.  We won't run into trouble here because for any
660        frame without a minibuffer, there has to be another one on
661        the same console with a minibuffer, and we're not deleting that,
662        so delete_console_internal() won't get recursively called.
663
664        WRONG!  With surrogate minibuffers this isn't true.  Frames
665        with only a minibuffer are not enough to prevent
666        delete_frame_internal from triggering a device deletion. */
667     CONSOLE_FRAME_LOOP_NO_BREAK (frmcons, devcons, con)
668       {
669         struct frame *f = XFRAME (XCAR (frmcons));
670         /* delete_frame_internal() might do anything such as run hooks,
671            so be defensive. */
672         if (FRAME_LIVE_P (f) && !FRAME_HAS_MINIBUF_P (f))
673           delete_frame_internal (f, 1, 1, from_io_error);
674
675         if (!CONSOLE_LIVE_P (con)) /* make sure the delete-*-hook didn't
676                                       go ahead and delete anything */
677           {
678             UNGCPRO;
679             return;
680           }
681       }
682
683     CONSOLE_DEVICE_LOOP (devcons, con)
684       {
685         struct device *d = XDEVICE (XCAR (devcons));
686         /* delete_device_internal() might do anything such as run hooks,
687            so be defensive. */
688         if (DEVICE_LIVE_P (d))
689           delete_device_internal (d, 1, 1, from_io_error);
690         if (!CONSOLE_LIVE_P (con)) /* make sure the delete-*-hook didn't
691                                       go ahead and delete anything */
692           {
693             UNGCPRO;
694             return;
695           }
696       }
697   }
698
699   CONSOLE_SELECTED_DEVICE (con) = Qnil;
700
701   /* try to select another console */
702
703   if (EQ (console, Fselected_console ()))
704     {
705       Lisp_Object other_dev = find_other_console (console);
706       if (!NILP (other_dev))
707         Fselect_console (other_dev);
708       else
709         {
710           /* necessary? */
711           Vselected_console = Qnil;
712           Vwindow_system = Qnil;
713         }
714     }
715
716   if (con->input_enabled)
717     event_stream_unselect_console (con);
718
719   MAYBE_CONMETH (con, delete_console, (con));
720
721   Vconsole_list = delq_no_quit (console, Vconsole_list);
722   RESET_CHANGED_SET_FLAGS;
723   con->conmeths = dead_console_methods;
724
725   UNGCPRO;
726 }
727
728 void
729 io_error_delete_console (Lisp_Object console)
730 {
731   delete_console_internal (XCONSOLE (console), 1, 0, 1);
732 }
733
734 DEFUN ("delete-console", Fdelete_console, 1, 2, 0, /*
735 Delete CONSOLE, permanently eliminating it from use.
736 Normally, you cannot delete the last non-minibuffer-only frame (you must
737 use `save-buffers-kill-emacs' or `kill-emacs').  However, if optional
738 second argument FORCE is non-nil, you can delete the last frame. (This
739 will automatically call `save-buffers-kill-emacs'.)
740 */
741        (console, force))
742 {
743   CHECK_CONSOLE (console);
744   delete_console_internal (XCONSOLE (console), !NILP (force), 0, 0);
745   return Qnil;
746 }
747
748 DEFUN ("console-list", Fconsole_list, 0, 0, 0, /*
749 Return a list of all consoles.
750 */
751        ())
752 {
753   return Fcopy_sequence (Vconsole_list);
754 }
755
756 DEFUN ("console-device-list", Fconsole_device_list, 0, 1, 0, /*
757 Return a list of all devices on CONSOLE.
758 If CONSOLE is nil, the selected console is used.
759 */
760        (console))
761 {
762   return Fcopy_sequence (CONSOLE_DEVICE_LIST (decode_console (console)));
763 }
764
765 DEFUN ("console-enable-input", Fconsole_enable_input, 1, 1, 0, /*
766 Enable input on console CONSOLE.
767 */
768        (console))
769 {
770   struct console *con = decode_console (console);
771   if (!con->input_enabled)
772     event_stream_select_console (con);
773   return Qnil;
774 }
775
776 DEFUN ("console-disable-input", Fconsole_disable_input, 1, 1, 0, /*
777 Disable input on console CONSOLE.
778 */
779        (console))
780 {
781   struct console *con = decode_console (console);
782   if (con->input_enabled)
783     event_stream_unselect_console (con);
784   return Qnil;
785 }
786
787 DEFUN ("console-on-window-system-p", Fconsole_on_window_system_p, 0, 1, 0, /*
788 Return t if CONSOLE is on a window system.
789 If CONSOLE is nil, the selected console is used.
790 This generally means that there is support for the mouse, the menubar,
791 the toolbar, glyphs, etc.
792 */
793        (console))
794 {
795   Lisp_Object type = CONSOLE_TYPE (decode_console (console));
796
797   return !EQ (type, Qtty) && !EQ (type, Qstream) ? Qt : Qnil;
798 }
799
800
801 \f
802 /**********************************************************************/
803 /*               Miscellaneous low-level functions                    */
804 /**********************************************************************/
805
806 static Lisp_Object
807 unwind_init_sys_modes (Lisp_Object console)
808 {
809   reinit_initial_console ();
810
811   if (!no_redraw_on_reenter &&
812       CONSOLEP (console) &&
813       CONSOLE_LIVE_P (XCONSOLE (console)))
814     {
815       struct frame *f =
816         XFRAME (DEVICE_SELECTED_FRAME
817                 (XDEVICE (CONSOLE_SELECTED_DEVICE (XCONSOLE (console)))));
818       MARK_FRAME_CHANGED (f);
819     }
820   return Qnil;
821 }
822
823 DEFUN ("suspend-emacs", Fsuspend_emacs, 0, 1, "", /*
824 Stop Emacs and return to superior process.  You can resume later.
825 On systems that don't have job control, run a subshell instead.
826
827 If optional arg STUFFSTRING is non-nil, its characters are stuffed
828 to be read as terminal input by Emacs's superior shell.
829
830 Before suspending, run the normal hook `suspend-hook'.
831 After resumption run the normal hook `suspend-resume-hook'.
832
833 Some operating systems cannot stop the Emacs process and resume it later.
834 On such systems, Emacs will start a subshell and wait for it to exit.
835 */
836        (stuffstring))
837 {
838   int speccount = specpdl_depth ();
839   struct gcpro gcpro1;
840
841   if (!NILP (stuffstring))
842     CHECK_STRING (stuffstring);
843   GCPRO1 (stuffstring);
844
845   /* There used to be a check that the initial console is TTY.
846      This is bogus.  Even checking to see whether any console
847      is a controlling terminal is not correct -- maybe
848      the user used the -t option or something.  If we want to
849      suspend, then we suspend.  Period. */
850
851   /* Call value of suspend-hook. */
852   run_hook (Qsuspend_hook);
853
854   reset_initial_console ();
855   /* sys_suspend can get an error if it tries to fork a subshell
856      and the system resources aren't available for that.  */
857   record_unwind_protect (unwind_init_sys_modes, Vcontrolling_terminal);
858   stuff_buffered_input (stuffstring);
859   sys_suspend ();
860   /* the console is un-reset inside of the unwind-protect. */
861   unbind_to (speccount, Qnil);
862
863 #ifdef SIGWINCH
864   /* It is possible that a size change occurred while we were
865      suspended.  Assume one did just to be safe.  It won't hurt
866      anything if one didn't. */
867   asynch_device_change_pending++;
868 #endif
869
870   /* Call value of suspend-resume-hook
871      if it is bound and value is non-nil.  */
872   run_hook (Qsuspend_resume_hook);
873
874   UNGCPRO;
875   return Qnil;
876 }
877
878 /* If STUFFSTRING is a string, stuff its contents as pending terminal input.
879    Then in any case stuff anything Emacs has read ahead and not used.  */
880
881 void
882 stuff_buffered_input (Lisp_Object stuffstring)
883 {
884 /* stuff_char works only in BSD, versions 4.2 and up.  */
885 #if defined (BSD)
886   if (!CONSOLEP (Vcontrolling_terminal) ||
887       !CONSOLE_LIVE_P (XCONSOLE (Vcontrolling_terminal)))
888     return;
889
890   if (STRINGP (stuffstring))
891     {
892       Extcount count;
893       Extbyte *p;
894
895       TO_EXTERNAL_FORMAT (LISP_STRING, stuffstring,
896                           ALLOCA, (p, count),
897                           Qkeyboard);
898       while (count-- > 0)
899         stuff_char (XCONSOLE (Vcontrolling_terminal), *p++);
900       stuff_char (XCONSOLE (Vcontrolling_terminal), '\n');
901     }
902   /* Anything we have read ahead, put back for the shell to read.  */
903 # if 0 /* oh, who cares about this silliness */
904   while (kbd_fetch_ptr != kbd_store_ptr)
905     {
906       if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
907         kbd_fetch_ptr = kbd_buffer;
908       stuff_char (XCONSOLE (Vcontrolling_terminal), *kbd_fetch_ptr++);
909     }
910 # endif
911 #endif /* BSD */
912 }
913
914 DEFUN ("suspend-console", Fsuspend_console, 0, 1, "", /*
915 Suspend a console.  For tty consoles, it sends a signal to suspend
916 the process in charge of the tty, and removes the devices and
917 frames of that console from the display.
918
919 If optional arg CONSOLE is non-nil, it is the console to be suspended.
920 Otherwise it is assumed to be the selected console.
921
922 Some operating systems cannot stop processes and resume them later.
923 On such systems, who knows what will happen.
924 */
925        (console))
926 {
927 #ifdef HAVE_TTY
928   struct console *con = decode_console (console);
929
930   if (CONSOLE_TTY_P (con))
931     {
932       /*
933        * hide all the unhidden frames so the display code won't update
934        * them while the console is suspended.
935        */
936       Lisp_Object device = CONSOLE_SELECTED_DEVICE (con);
937       if (!NILP (device))
938         {
939           struct device *d = XDEVICE (device);
940           Lisp_Object frame_list = DEVICE_FRAME_LIST (d);
941           while (CONSP (frame_list))
942             {
943               struct frame *f = XFRAME (XCAR (frame_list));
944               if (FRAME_REPAINT_P (f))
945                 f->visible = -1;
946               frame_list = XCDR (frame_list);
947             }
948         }
949       reset_one_console (con);
950       event_stream_unselect_console (con);
951       sys_suspend_process (XINT (Fconsole_tty_controlling_process (console)));
952     }
953 #endif /* HAVE_TTY */
954
955   return Qnil;
956 }
957
958 DEFUN ("resume-console", Fresume_console, 1, 1, "", /*
959 Re-initialize a previously suspended console.
960 For tty consoles, do stuff to the tty to make it sane again.
961 */
962        (console))
963 {
964 #ifdef HAVE_TTY
965   struct console *con = decode_console (console);
966
967   if (CONSOLE_TTY_P (con))
968     {
969       /* raise the selected frame */
970       Lisp_Object device = CONSOLE_SELECTED_DEVICE (con);
971       if (!NILP (device))
972         {
973           struct device *d = XDEVICE (device);
974           Lisp_Object frame = DEVICE_SELECTED_FRAME (d);
975           if (!NILP (frame))
976             {
977               /* force the frame to be cleared */
978               SET_FRAME_CLEAR (XFRAME (frame));
979               Fraise_frame (frame);
980             }
981         }
982       init_one_console (con);
983       event_stream_select_console (con);
984 #ifdef SIGWINCH
985       /* The same as in Fsuspend_emacs: it is possible that a size
986          change occurred while we were suspended.  Assume one did just
987          to be safe.  It won't hurt anything if one didn't. */
988       asynch_device_change_pending++;
989 #endif
990     }
991 #endif /* HAVE_TTY */
992
993   return Qnil;
994 }
995
996 DEFUN ("set-input-mode", Fset_input_mode, 3, 5, 0, /*
997 Set mode of reading keyboard input.
998 First arg is ignored, for backward compatibility.
999 Second arg FLOW non-nil means use ^S/^Q flow control for output to terminal
1000  (no effect except in CBREAK mode).
1001 Third arg META t means accept 8-bit input (for a Meta key).
1002  META nil means ignore the top bit, on the assumption it is parity.
1003  Otherwise, accept 8-bit input and don't use the top bit for Meta.
1004 First three arguments only apply to TTY consoles.
1005 Optional fourth arg QUIT if non-nil specifies character to use for quitting.
1006 Optional fifth arg CONSOLE specifies console to make changes to; nil means
1007  the selected console.
1008 See also `current-input-mode'.
1009 */
1010      (ignored, flow, meta, quit, console))
1011 {
1012   struct console *con = decode_console (console);
1013   int meta_key = (!CONSOLE_TTY_P (con) ? 1 :
1014                   EQ (meta, Qnil)      ? 0 :
1015                   EQ (meta, Qt)        ? 1 :
1016                   2);
1017
1018   if (!NILP (quit))
1019     {
1020       CHECK_CHAR_COERCE_INT (quit);
1021       CONSOLE_QUIT_CHAR (con) =
1022         ((unsigned int) XCHAR (quit)) & (meta_key ? 0377 : 0177);
1023     }
1024
1025 #ifdef HAVE_TTY
1026   if (CONSOLE_TTY_P (con))
1027     {
1028       reset_one_console (con);
1029       TTY_FLAGS (con).flow_control = !NILP (flow);
1030       TTY_FLAGS (con).meta_key = meta_key;
1031       init_one_console (con);
1032       MARK_FRAME_CHANGED (XFRAME (CONSOLE_SELECTED_FRAME (con)));
1033     }
1034 #endif
1035
1036   return Qnil;
1037 }
1038
1039 DEFUN ("current-input-mode", Fcurrent_input_mode, 0, 1, 0, /*
1040 Return information about the way Emacs currently reads keyboard input.
1041 Optional arg CONSOLE specifies console to return information about; nil means
1042  the selected console.
1043 The value is a list of the form (nil FLOW META QUIT), where
1044   FLOW is non-nil if Emacs uses ^S/^Q flow control for output to the
1045     terminal; this does not apply if Emacs uses interrupt-driven input.
1046   META is t if accepting 8-bit input with 8th bit as Meta flag.
1047     META nil means ignoring the top bit, on the assumption it is parity.
1048     META is neither t nor nil if accepting 8-bit input and using
1049     all 8 bits as the character code.
1050   QUIT is the character Emacs currently uses to quit.
1051 FLOW, and META are only meaningful for TTY consoles.
1052 The elements of this list correspond to the arguments of
1053 `set-input-mode'.
1054 */
1055        (console))
1056 {
1057   struct console *con = decode_console (console);
1058   Lisp_Object flow, meta, quit;
1059
1060 #ifdef HAVE_TTY
1061   flow = CONSOLE_TTY_P (con) && TTY_FLAGS (con).flow_control ? Qt : Qnil;
1062   meta = (!CONSOLE_TTY_P (con) ? Qt :
1063           TTY_FLAGS (con).meta_key == 1 ? Qt :
1064           TTY_FLAGS (con).meta_key == 2 ? Qzero :
1065           Qnil);
1066 #else
1067   flow = Qnil;
1068   meta = Qt;
1069 #endif
1070   quit = make_char (CONSOLE_QUIT_CHAR (con));
1071
1072   return list4 (Qnil, flow, meta, quit);
1073 }
1074
1075 \f
1076 /************************************************************************/
1077 /*                            initialization                            */
1078 /************************************************************************/
1079
1080 void
1081 syms_of_console (void)
1082 {
1083   INIT_LRECORD_IMPLEMENTATION (console);
1084
1085   DEFSUBR (Fvalid_console_type_p);
1086   DEFSUBR (Fconsole_type_list);
1087   DEFSUBR (Fcdfw_console);
1088   DEFSUBR (Fselected_console);
1089   DEFSUBR (Fselect_console);
1090   DEFSUBR (Fconsolep);
1091   DEFSUBR (Fconsole_live_p);
1092   DEFSUBR (Fconsole_type);
1093   DEFSUBR (Fconsole_name);
1094   DEFSUBR (Fconsole_connection);
1095   DEFSUBR (Ffind_console);
1096   DEFSUBR (Fget_console);
1097   DEFSUBR (Fdelete_console);
1098   DEFSUBR (Fconsole_list);
1099   DEFSUBR (Fconsole_device_list);
1100   DEFSUBR (Fconsole_enable_input);
1101   DEFSUBR (Fconsole_disable_input);
1102   DEFSUBR (Fconsole_on_window_system_p);
1103   DEFSUBR (Fsuspend_console);
1104   DEFSUBR (Fresume_console);
1105
1106   DEFSUBR (Fsuspend_emacs);
1107   DEFSUBR (Fset_input_mode);
1108   DEFSUBR (Fcurrent_input_mode);
1109
1110   defsymbol (&Qconsolep, "consolep");
1111   defsymbol (&Qconsole_live_p, "console-live-p");
1112
1113   defsymbol (&Qcreate_console_hook, "create-console-hook");
1114   defsymbol (&Qdelete_console_hook, "delete-console-hook");
1115
1116   defsymbol (&Qsuspend_hook, "suspend-hook");
1117   defsymbol (&Qsuspend_resume_hook, "suspend-resume-hook");
1118 }
1119
1120 static const struct lrecord_description cte_description_1[] = {
1121   { XD_LISP_OBJECT, offsetof (console_type_entry, symbol) },
1122   { XD_STRUCT_PTR,  offsetof (console_type_entry, meths), 1, &console_methods_description },
1123   { XD_END }
1124 };
1125
1126 static const struct struct_description cte_description = {
1127   sizeof (console_type_entry),
1128   cte_description_1
1129 };
1130
1131 static const struct lrecord_description cted_description_1[] = {
1132   XD_DYNARR_DESC (console_type_entry_dynarr, &cte_description),
1133   { XD_END }
1134 };
1135
1136 const struct struct_description cted_description = {
1137   sizeof (console_type_entry_dynarr),
1138   cted_description_1
1139 };
1140
1141 static const struct lrecord_description console_methods_description_1[] = {
1142   { XD_LISP_OBJECT, offsetof (struct console_methods, symbol) },
1143   { XD_LISP_OBJECT, offsetof (struct console_methods, predicate_symbol) },
1144   { XD_LISP_OBJECT, offsetof (struct console_methods, image_conversion_list) },
1145   { XD_END }
1146 };
1147
1148 const struct struct_description console_methods_description = {
1149   sizeof (struct console_methods),
1150   console_methods_description_1
1151 };
1152
1153
1154 void
1155 console_type_create (void)
1156 {
1157   the_console_type_entry_dynarr = Dynarr_new (console_type_entry);
1158   dump_add_root_struct_ptr (&the_console_type_entry_dynarr, &cted_description);
1159
1160   Vconsole_type_list = Qnil;
1161   staticpro (&Vconsole_type_list);
1162
1163   /* Initialize the dead console type */
1164   INITIALIZE_CONSOLE_TYPE (dead, "dead", "console-dead-p");
1165
1166   /* then reset the console-type lists, because `dead' is not really
1167      a valid console type */
1168   Dynarr_reset (the_console_type_entry_dynarr);
1169   Vconsole_type_list = Qnil;
1170 }
1171
1172 void
1173 reinit_vars_of_console (void)
1174 {
1175   staticpro_nodump (&Vconsole_list);
1176   Vconsole_list = Qnil;
1177   staticpro_nodump (&Vselected_console);
1178   Vselected_console = Qnil;
1179 }
1180
1181 void
1182 vars_of_console (void)
1183 {
1184   reinit_vars_of_console ();
1185
1186   DEFVAR_LISP ("create-console-hook", &Vcreate_console_hook /*
1187 Function or functions to call when a console is created.
1188 One argument, the newly-created console.
1189 This is called after the first frame has been created, but before
1190   calling the `create-device-hook' or `create-frame-hook'.
1191 Note that in general the console will not be selected.
1192 */ );
1193   Vcreate_console_hook = Qnil;
1194
1195   DEFVAR_LISP ("delete-console-hook", &Vdelete_console_hook /*
1196 Function or functions to call when a console is deleted.
1197 One argument, the to-be-deleted console.
1198 */ );
1199   Vdelete_console_hook = Qnil;
1200
1201 #ifdef HAVE_WINDOW_SYSTEM
1202   Fprovide (intern ("window-system"));
1203 #endif
1204 }
1205
1206 /* The docstrings for DEFVAR_* are recorded externally by make-docfile.  */
1207 #define DEFVAR_CONSOLE_LOCAL_1(lname, field_name, forward_type, magicfun) do {  \
1208   static const struct symbol_value_forward I_hate_C =                           \
1209   { /* struct symbol_value_forward */                                           \
1210     { /* struct symbol_value_magic */                                           \
1211       { /* struct lcrecord_header */                                            \
1212         { /* struct lrecord_header */                                           \
1213           lrecord_type_symbol_value_forward, /* lrecord_type_index */           \
1214           1, /* mark bit */                                                     \
1215           1, /* c_readonly bit */                                               \
1216           1  /* lisp_readonly bit */                                            \
1217         },                                                                      \
1218         0, /* next */                                                           \
1219         0, /* uid  */                                                           \
1220         0  /* free */                                                           \
1221       },                                                                        \
1222       &(console_local_flags.field_name),                                        \
1223       forward_type                                                              \
1224     },                                                                          \
1225     magicfun                                                                    \
1226   };                                                                            \
1227                                                                                 \
1228   {                                                                             \
1229     int offset = ((char *)symbol_value_forward_forward (&I_hate_C)              \
1230                   - (char *)&console_local_flags);                              \
1231                                                                                 \
1232     defvar_magic (lname, &I_hate_C);                                            \
1233                                                                                 \
1234     *((Lisp_Object *)(offset + (char *)XCONSOLE (Vconsole_local_symbols)))      \
1235       = intern (lname);                                                         \
1236   }                                                                             \
1237 } while (0)
1238
1239 #define DEFVAR_CONSOLE_LOCAL_MAGIC(lname, field_name, magicfun)         \
1240         DEFVAR_CONSOLE_LOCAL_1 (lname, field_name,                      \
1241                                 SYMVAL_SELECTED_CONSOLE_FORWARD, magicfun)
1242 #define DEFVAR_CONSOLE_LOCAL(lname, field_name)                         \
1243         DEFVAR_CONSOLE_LOCAL_MAGIC (lname, field_name, 0)
1244 #define DEFVAR_CONST_CONSOLE_LOCAL_MAGIC(lname, field_name, magicfun)   \
1245         DEFVAR_CONSOLE_LOCAL_1 (lname, field_name,                      \
1246                                 SYMVAL_CONST_SELECTED_CONSOLE_FORWARD, magicfun)
1247 #define DEFVAR_CONST_CONSOLE_LOCAL(lname, field_name)                   \
1248         DEFVAR_CONST_CONSOLE_LOCAL_MAGIC (lname, field_name, 0)
1249
1250 #define DEFVAR_CONSOLE_DEFAULTS_MAGIC(lname, field_name, magicfun)      \
1251         DEFVAR_SYMVAL_FWD(lname, &(console_local_flags.field_name),     \
1252                           SYMVAL_DEFAULT_CONSOLE_FORWARD, magicfun)
1253 #define DEFVAR_CONSOLE_DEFAULTS(lname, field_name)                      \
1254         DEFVAR_CONSOLE_DEFAULTS_MAGIC (lname, field_name, 0)
1255
1256 static void
1257 nuke_all_console_slots (struct console *con, Lisp_Object zap)
1258 {
1259   zero_lcrecord (con);
1260
1261 #define MARKED_SLOT(x)  con->x = zap
1262 #include "conslots.h"
1263 #undef MARKED_SLOT
1264 }
1265
1266 static void
1267 common_init_complex_vars_of_console (void)
1268 {
1269   /* Make sure all markable slots in console_defaults
1270      are initialized reasonably, so mark_console won't choke.
1271    */
1272   struct console *defs = alloc_lcrecord_type (struct console, &lrecord_console);
1273   struct console *syms = alloc_lcrecord_type (struct console, &lrecord_console);
1274
1275   staticpro_nodump (&Vconsole_defaults);
1276   staticpro_nodump (&Vconsole_local_symbols);
1277   XSETCONSOLE (Vconsole_defaults, defs);
1278   XSETCONSOLE (Vconsole_local_symbols, syms);
1279
1280   nuke_all_console_slots (syms, Qnil);
1281   nuke_all_console_slots (defs, Qnil);
1282
1283   /* Set up the non-nil default values of various console slots.
1284      Must do these before making the first console.
1285      */
1286   /* #### Anything needed here? */
1287
1288   {
1289     /*  0 means var is always local.  Default used only at creation.
1290      * -1 means var is always local.  Default used only at reset and
1291      *    creation.
1292      * -2 means there's no lisp variable corresponding to this slot
1293      *    and the default is only used at creation.
1294      * -3 means no Lisp variable.  Default used only at reset and creation.
1295      * >0 is mask.  Var is local if ((console->local_var_flags & mask) != 0)
1296      *              Otherwise default is used.
1297      *
1298      * #### We don't currently ever reset console variables, so there
1299      * is no current distinction between 0 and -1, and between -2 and -3.
1300      */
1301     Lisp_Object always_local_resettable = make_int (-1);
1302
1303 #if 0 /* not used */
1304     Lisp_Object always_local_no_default = make_int (0);
1305     Lisp_Object resettable = make_int (-3);
1306 #endif
1307
1308     /* Assign the local-flags to the slots that have default values.
1309        The local flag is a bit that is used in the console
1310        to say that it has its own local value for the slot.
1311        The local flag bits are in the local_var_flags slot of the
1312        console.  */
1313
1314     nuke_all_console_slots (&console_local_flags, make_int (-2));
1315     console_local_flags.defining_kbd_macro = always_local_resettable;
1316     console_local_flags.last_kbd_macro = always_local_resettable;
1317     console_local_flags.prefix_arg = always_local_resettable;
1318     console_local_flags.default_minibuffer_frame = always_local_resettable;
1319     console_local_flags.overriding_terminal_local_map =
1320       always_local_resettable;
1321 #ifdef HAVE_TTY
1322     console_local_flags.tty_erase_char = always_local_resettable;
1323 #endif
1324
1325     console_local_flags.function_key_map = make_int (1);
1326
1327     /* #### Warning, 0x4000000 (that's six zeroes) is the largest number
1328        currently allowable due to the XINT() handling of this value.
1329        With some rearrangement you can get 4 more bits. */
1330   }
1331 }
1332
1333
1334 #define CONSOLE_SLOTS_SIZE (offsetof (struct console, CONSOLE_SLOTS_LAST_NAME) - offsetof (struct console, CONSOLE_SLOTS_FIRST_NAME) + sizeof (Lisp_Object))
1335 #define CONSOLE_SLOTS_COUNT (CONSOLE_SLOTS_SIZE / sizeof (Lisp_Object))
1336
1337 void
1338 reinit_complex_vars_of_console (void)
1339 {
1340   struct console *defs, *syms;
1341
1342   common_init_complex_vars_of_console ();
1343
1344   defs = XCONSOLE (Vconsole_defaults);
1345   syms = XCONSOLE (Vconsole_local_symbols);
1346   memcpy (&defs->CONSOLE_SLOTS_FIRST_NAME,
1347           console_defaults_saved_slots,
1348           CONSOLE_SLOTS_SIZE);
1349   memcpy (&syms->CONSOLE_SLOTS_FIRST_NAME,
1350           console_local_symbols_saved_slots,
1351           CONSOLE_SLOTS_SIZE);
1352 }
1353
1354
1355 static const struct lrecord_description console_slots_description_1[] = {
1356   { XD_LISP_OBJECT_ARRAY, 0, CONSOLE_SLOTS_COUNT },
1357   { XD_END }
1358 };
1359
1360 static const struct struct_description console_slots_description = {
1361   CONSOLE_SLOTS_SIZE,
1362   console_slots_description_1
1363 };
1364
1365 void
1366 complex_vars_of_console (void)
1367 {
1368   struct console *defs, *syms;
1369
1370   common_init_complex_vars_of_console ();
1371
1372   defs = XCONSOLE (Vconsole_defaults);
1373   syms = XCONSOLE (Vconsole_local_symbols);
1374   console_defaults_saved_slots      = &defs->CONSOLE_SLOTS_FIRST_NAME;
1375   console_local_symbols_saved_slots = &syms->CONSOLE_SLOTS_FIRST_NAME;
1376   dump_add_root_struct_ptr (&console_defaults_saved_slots,      &console_slots_description);
1377   dump_add_root_struct_ptr (&console_local_symbols_saved_slots, &console_slots_description);
1378
1379   DEFVAR_CONSOLE_DEFAULTS ("default-function-key-map", function_key_map /*
1380 Default value of `function-key-map' for consoles that don't override it.
1381 This is the same as (default-value 'function-key-map).
1382 */ );
1383
1384   DEFVAR_CONSOLE_LOCAL ("function-key-map", function_key_map /*
1385 Keymap mapping ASCII function key sequences onto their preferred forms.
1386 This allows Emacs to recognize function keys sent from ASCII
1387 terminals at any point in a key sequence.
1388
1389 The `read-key-sequence' function replaces any subsequence bound by
1390 `function-key-map' with its binding.  More precisely, when the active
1391 keymaps have no binding for the current key sequence but
1392 `function-key-map' binds a suffix of the sequence to a vector or string,
1393 `read-key-sequence' replaces the matching suffix with its binding, and
1394 continues with the new sequence.
1395
1396 The events that come from bindings in `function-key-map' are not
1397 themselves looked up in `function-key-map'.
1398
1399 For example, suppose `function-key-map' binds `ESC O P' to [f1].
1400 Typing `ESC O P' to `read-key-sequence' would return
1401 \[#<keypress-event f1>].  Typing `C-x ESC O P' would return
1402 \[#<keypress-event control-X> #<keypress-event f1>].  If [f1]
1403 were a prefix key, typing `ESC O P x' would return
1404 \[#<keypress-event f1> #<keypress-event x>].
1405 */ );
1406
1407 #ifdef HAVE_TTY
1408   /* #### Should this somehow go to TTY data?  How do we make it
1409      accessible from Lisp, then?  */
1410   DEFVAR_CONSOLE_LOCAL ("tty-erase-char", tty_erase_char /*
1411 The ERASE character as set by the user with stty.
1412 When this value cannot be determined or would be meaningless (on non-TTY
1413 consoles, for example), it is set to nil.
1414 */ );
1415 #endif
1416
1417   /* While this should be const it can't be because some things
1418      (i.e. edebug) do manipulate it. */
1419   DEFVAR_CONSOLE_LOCAL ("defining-kbd-macro", defining_kbd_macro /*
1420 Non-nil while a keyboard macro is being defined.  Don't set this!
1421 */ );
1422
1423   DEFVAR_CONSOLE_LOCAL ("last-kbd-macro", last_kbd_macro /*
1424 Last keyboard macro defined, as a vector of events; nil if none defined.
1425 */ );
1426
1427   DEFVAR_CONSOLE_LOCAL ("prefix-arg", prefix_arg /*
1428 The value of the prefix argument for the next editing command.
1429 It may be a number, or the symbol `-' for just a minus sign as arg,
1430 or a list whose car is a number for just one or more C-U's
1431 or nil if no argument has been specified.
1432
1433 You cannot examine this variable to find the argument for this command
1434 since it has been set to nil by the time you can look.
1435 Instead, you should use the variable `current-prefix-arg', although
1436 normally commands can get this prefix argument with (interactive "P").
1437 */ );
1438
1439   DEFVAR_CONSOLE_LOCAL ("default-minibuffer-frame",
1440                         default_minibuffer_frame /*
1441 Minibufferless frames use this frame's minibuffer.
1442
1443 Emacs cannot create minibufferless frames unless this is set to an
1444 appropriate surrogate.
1445
1446 XEmacs consults this variable only when creating minibufferless
1447 frames; once the frame is created, it sticks with its assigned
1448 minibuffer, no matter what this variable is set to.  This means that
1449 this variable doesn't necessarily say anything meaningful about the
1450 current set of frames, or where the minibuffer is currently being
1451 displayed.
1452 */ );
1453
1454   DEFVAR_CONSOLE_LOCAL ("overriding-terminal-local-map",
1455                         overriding_terminal_local_map /*
1456 Keymap that overrides all other local keymaps, for the selected console only.
1457 If this variable is non-nil, it is used as a keymap instead of the
1458 buffer's local map, and the minor mode keymaps and text property keymaps.
1459 */ );
1460
1461   /* Check for DEFVAR_CONSOLE_LOCAL without initializing the corresponding
1462      slot of console_local_flags and vice-versa.  Must be done after all
1463      DEFVAR_CONSOLE_LOCAL() calls. */
1464 #define MARKED_SLOT(slot)                                       \
1465   if ((XINT (console_local_flags.slot) != -2 &&                 \
1466          XINT (console_local_flags.slot) != -3)                 \
1467       != !(NILP (XCONSOLE (Vconsole_local_symbols)->slot)))     \
1468   abort ()
1469 #include "conslots.h"
1470 #undef MARKED_SLOT
1471 }