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