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