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