aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2008-03-29 01:46:10 +0000
committerStefan Monnier2008-03-29 01:46:10 +0000
commit58555d8187f3425f69e57316cfcd296f8fe08433 (patch)
tree6483ae1ed8053ad2f3ec7c41241a2e7ab443a5f1 /src
parent769087cead629d7ad1fd5cfc15ce75625a78e6b3 (diff)
downloademacs-58555d8187f3425f69e57316cfcd296f8fe08433.tar.gz
emacs-58555d8187f3425f69e57316cfcd296f8fe08433.zip
* keyboard.c (pending_funcalls): New var.
(timer_check): Run it. (syms_of_keyboard): Initialize it. * terminal.c (Qrun_hook_with_args, Qdelete_terminal_functions) (Vdelete_terminal_functions): New vars. (syms_of_terminal): Initialize them. (Fdelete_terminal): Run delete-terminal-functions. * xdisp.c (safe_eval): Rewrite. (safe_call2): New fun. * frame.c (Qdelete_frame_functions): New var. (syms_of_frame): Initialize it. (Fdelete_frame): Use it and use safe_call2 and pending_funcalls. * lisp.h (safe_call2, pending_funcalls): Declare.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog16
-rw-r--r--src/frame.c39
-rw-r--r--src/keyboard.c17
-rw-r--r--src/lisp.h2
-rw-r--r--src/terminal.c25
-rw-r--r--src/xdisp.c53
-rw-r--r--src/xterm.c13
7 files changed, 110 insertions, 55 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 391ea05e7aa..33c1b324e97 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,19 @@
12008-03-29 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * keyboard.c (pending_funcalls): New var.
4 (timer_check): Run it.
5 (syms_of_keyboard): Initialize it.
6 * terminal.c (Qrun_hook_with_args, Qdelete_terminal_functions)
7 (Vdelete_terminal_functions): New vars.
8 (syms_of_terminal): Initialize them.
9 (Fdelete_terminal): Run delete-terminal-functions.
10 * xdisp.c (safe_eval): Rewrite.
11 (safe_call2): New fun.
12 * frame.c (Qdelete_frame_functions): New var.
13 (syms_of_frame): Initialize it.
14 (Fdelete_frame): Use it and use safe_call2 and pending_funcalls.
15 * lisp.h (safe_call2, pending_funcalls): Declare.
16
12008-03-28 Andreas Schwab <schwab@suse.de> 172008-03-28 Andreas Schwab <schwab@suse.de>
2 18
3 * indent.c (Fmove_to_column): Move declaration before statements. 19 * indent.c (Fmove_to_column): Move declaration before statements.
diff --git a/src/frame.c b/src/frame.c
index 35d00e51552..81b91924d2f 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -129,7 +129,7 @@ Lisp_Object Vdefault_frame_alist;
129Lisp_Object Vdefault_frame_scroll_bars; 129Lisp_Object Vdefault_frame_scroll_bars;
130Lisp_Object Vmouse_position_function; 130Lisp_Object Vmouse_position_function;
131Lisp_Object Vmouse_highlight; 131Lisp_Object Vmouse_highlight;
132Lisp_Object Vdelete_frame_functions; 132static Lisp_Object Vdelete_frame_functions, Qdelete_frame_functions;
133 133
134int focus_follows_mouse; 134int focus_follows_mouse;
135 135
@@ -1334,6 +1334,8 @@ delete_frame_handler (Lisp_Object arg)
1334 return Qnil; 1334 return Qnil;
1335} 1335}
1336 1336
1337extern Lisp_Object Qrun_hook_with_args;
1338
1337DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "", 1339DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1338 doc: /* Delete FRAME, permanently eliminating it from use. 1340 doc: /* Delete FRAME, permanently eliminating it from use.
1339If omitted, FRAME defaults to the selected frame. 1341If omitted, FRAME defaults to the selected frame.
@@ -1410,21 +1412,14 @@ But FORCE inhibits this too. */)
1410 unless FORCE is `noelisp' or frame is a tooltip. 1412 unless FORCE is `noelisp' or frame is a tooltip.
1411 FORCE is set to `noelisp' when handling a disconnect from the terminal, 1413 FORCE is set to `noelisp' when handling a disconnect from the terminal,
1412 so we don't dare call Lisp code. */ 1414 so we don't dare call Lisp code. */
1413 if (!NILP (Vrun_hooks) && !EQ (force, Qnoelisp) 1415 if (NILP (Vrun_hooks) || !NILP (Fframe_parameter (frame, intern ("tooltip"))))
1414 && NILP (Fframe_parameter (frame, intern ("tooltip")))) 1416 ;
1415 { 1417 if (EQ (force, Qnoelisp))
1416 Lisp_Object args[2]; 1418 pending_funcalls
1417 struct gcpro gcpro1, gcpro2; 1419 = Fcons (list3 (Qrun_hook_with_args, Qdelete_frame_functions, frame),
1418 1420 pending_funcalls);
1419 /* Don't let a rogue function in `delete-frame-functions' 1421 else
1420 prevent the frame deletion. */ 1422 safe_call2 (Qrun_hook_with_args, Qdelete_frame_functions, frame);
1421 GCPRO2 (args[0], args[1]);
1422 args[0] = intern ("delete-frame-functions");
1423 args[1] = frame;
1424 internal_condition_case_2 (Frun_hook_with_args, 2, args,
1425 Qt, delete_frame_handler);
1426 UNGCPRO;
1427 }
1428 1423
1429 /* The hook may sometimes (indirectly) cause the frame to be deleted. */ 1424 /* The hook may sometimes (indirectly) cause the frame to be deleted. */
1430 if (! FRAME_LIVE_P (f)) 1425 if (! FRAME_LIVE_P (f))
@@ -4526,13 +4521,13 @@ when the mouse is over clickable text. */);
4526The functions are run with one arg, the frame to be deleted. 4521The functions are run with one arg, the frame to be deleted.
4527See `delete-frame'. 4522See `delete-frame'.
4528 4523
4529Note that functions in this list may be called twice on the same 4524Note that functions in this list may be called just before the frame is
4530frame. In the second invocation, the frame is already deleted, and 4525actually deleted, or some time later (or even both when an earlier function
4531the function should do nothing. (You can use `frame-live-p' to check 4526in `delete-frame-functions' (indirectly) calls `delete-frame'
4532for this.) This wrinkle happens when an earlier function in 4527recursively). */);
4533`delete-frame-functions' (indirectly) calls `delete-frame'
4534recursively. */);
4535 Vdelete_frame_functions = Qnil; 4528 Vdelete_frame_functions = Qnil;
4529 Qdelete_frame_functions = intern ("delete-frame-functions");
4530 staticpro (&Qdelete_frame_functions);
4536 4531
4537 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame, 4532 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
4538 doc: /* Minibufferless frames use this frame's minibuffer. 4533 doc: /* Minibufferless frames use this frame's minibuffer.
diff --git a/src/keyboard.c b/src/keyboard.c
index cdcf4c6b608..a930fe74289 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4505,6 +4505,13 @@ timer_resume_idle ()
4505/* This is only for debugging. */ 4505/* This is only for debugging. */
4506struct input_event last_timer_event; 4506struct input_event last_timer_event;
4507 4507
4508/* List of elisp functions to call, delayed because they were generated in
4509 a context where Elisp could not be safely run (e.g. redisplay, signal,
4510 ...). Each lement has the form (FUN . ARGS). */
4511Lisp_Object pending_funcalls;
4512
4513extern Lisp_Object Qapply;
4514
4508/* Check whether a timer has fired. To prevent larger problems we simply 4515/* Check whether a timer has fired. To prevent larger problems we simply
4509 disregard elements that are not proper timers. Do not make a circular 4516 disregard elements that are not proper timers. Do not make a circular
4510 timer list for the time being. 4517 timer list for the time being.
@@ -4541,6 +4548,14 @@ timer_check (do_it_now)
4541 chosen_timer = Qnil; 4548 chosen_timer = Qnil;
4542 GCPRO3 (timers, idle_timers, chosen_timer); 4549 GCPRO3 (timers, idle_timers, chosen_timer);
4543 4550
4551 /* First run the code that was delayed. */
4552 while (CONSP (pending_funcalls))
4553 {
4554 Lisp_Object funcall = XCAR (pending_funcalls);
4555 pending_funcalls = XCDR (pending_funcalls);
4556 safe_call2 (Qapply, XCAR (funcall), XCDR (funcall));
4557 }
4558
4544 if (CONSP (timers) || CONSP (idle_timers)) 4559 if (CONSP (timers) || CONSP (idle_timers))
4545 { 4560 {
4546 EMACS_GET_TIME (now); 4561 EMACS_GET_TIME (now);
@@ -11726,6 +11741,8 @@ struct event_head head_table[] = {
11726void 11741void
11727syms_of_keyboard () 11742syms_of_keyboard ()
11728{ 11743{
11744 pending_funcalls = Qnil;
11745
11729 Vpre_help_message = Qnil; 11746 Vpre_help_message = Qnil;
11730 staticpro (&Vpre_help_message); 11747 staticpro (&Vpre_help_message);
11731 11748
diff --git a/src/lisp.h b/src/lisp.h
index 333b6a2a92f..c9a33307bc4 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2776,6 +2776,7 @@ EXFUN (Ffetch_bytecode, 1);
2776extern void init_eval_once P_ ((void)); 2776extern void init_eval_once P_ ((void));
2777extern Lisp_Object safe_call P_ ((int, Lisp_Object *)); 2777extern Lisp_Object safe_call P_ ((int, Lisp_Object *));
2778extern Lisp_Object safe_call1 P_ ((Lisp_Object, Lisp_Object)); 2778extern Lisp_Object safe_call1 P_ ((Lisp_Object, Lisp_Object));
2779extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object);
2779extern void init_eval P_ ((void)); 2780extern void init_eval P_ ((void));
2780extern void syms_of_eval P_ ((void)); 2781extern void syms_of_eval P_ ((void));
2781 2782
@@ -3025,6 +3026,7 @@ EXFUN (Fset_output_flow_control, 2);
3025EXFUN (Fset_input_meta_mode, 2); 3026EXFUN (Fset_input_meta_mode, 2);
3026EXFUN (Fset_quit_char, 1); 3027EXFUN (Fset_quit_char, 1);
3027EXFUN (Fset_input_mode, 4); 3028EXFUN (Fset_input_mode, 4);
3029extern Lisp_Object pending_funcalls;
3028extern int detect_input_pending P_ ((void)); 3030extern int detect_input_pending P_ ((void));
3029extern int detect_input_pending_ignore_squeezables P_ ((void)); 3031extern int detect_input_pending_ignore_squeezables P_ ((void));
3030extern int detect_input_pending_run_timers P_ ((int)); 3032extern int detect_input_pending_run_timers P_ ((int));
diff --git a/src/terminal.c b/src/terminal.c
index bbc2fd74c2e..6a7cd37929c 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -295,6 +295,10 @@ delete_terminal (struct terminal *terminal)
295#endif 295#endif
296} 296}
297 297
298Lisp_Object Qrun_hook_with_args;
299static Lisp_Object Qdelete_terminal_functions;
300static Lisp_Object Vdelete_terminal_functions;
301
298DEFUN ("delete-terminal", Fdelete_terminal, Sdelete_terminal, 0, 2, 0, 302DEFUN ("delete-terminal", Fdelete_terminal, Sdelete_terminal, 0, 2, 0,
299 doc: /* Delete TERMINAL by deleting all frames on it and closing the terminal. 303 doc: /* Delete TERMINAL by deleting all frames on it and closing the terminal.
300TERMINAL may be a terminal id, a frame, or nil (meaning the selected 304TERMINAL may be a terminal id, a frame, or nil (meaning the selected
@@ -320,6 +324,16 @@ but if the second argument FORCE is non-nil, you may do so. */)
320 error ("Attempt to delete the sole active display terminal"); 324 error ("Attempt to delete the sole active display terminal");
321 } 325 }
322 326
327 if (NILP (Vrun_hooks))
328 ;
329 else if (EQ (force, Qnoelisp))
330 pending_funcalls
331 = Fcons (list3 (Qrun_hook_with_args,
332 Qdelete_terminal_functions, terminal),
333 pending_funcalls);
334 else
335 safe_call2 (Qrun_hook_with_args, Qdelete_terminal_functions, terminal);
336
323 if (t->delete_terminal_hook) 337 if (t->delete_terminal_hook)
324 (*t->delete_terminal_hook) (t); 338 (*t->delete_terminal_hook) (t);
325 else 339 else
@@ -552,6 +566,17 @@ syms_of_terminal ()
552The function should accept no arguments. */); 566The function should accept no arguments. */);
553 Vring_bell_function = Qnil; 567 Vring_bell_function = Qnil;
554 568
569 DEFVAR_LISP ("delete-terminal-functions", &Vdelete_terminal_functions,
570 doc: /* Special hook run when a terminal is deleted.
571Each function is called with argument, the terminal.
572This may be called just before actually deleting the terminal,
573or some time later. */);
574 Vdelete_terminal_functions = Qnil;
575 Qdelete_terminal_functions = intern ("delete-terminal-functions");
576 staticpro (&Qdelete_terminal_functions);
577 Qrun_hook_with_args = intern ("run-hook-with-args");
578 staticpro (&Qrun_hook_with_args);
579
555 defsubr (&Sdelete_terminal); 580 defsubr (&Sdelete_terminal);
556 defsubr (&Sframe_terminal); 581 defsubr (&Sframe_terminal);
557 defsubr (&Sterminal_live_p); 582 defsubr (&Sterminal_live_p);
diff --git a/src/xdisp.c b/src/xdisp.c
index 70db580bb0d..073d6a79068 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2316,33 +2316,6 @@ safe_eval_handler (arg)
2316/* Evaluate SEXPR and return the result, or nil if something went 2316/* Evaluate SEXPR and return the result, or nil if something went
2317 wrong. Prevent redisplay during the evaluation. */ 2317 wrong. Prevent redisplay during the evaluation. */
2318 2318
2319Lisp_Object
2320safe_eval (sexpr)
2321 Lisp_Object sexpr;
2322{
2323 Lisp_Object val;
2324
2325 if (inhibit_eval_during_redisplay)
2326 val = Qnil;
2327 else
2328 {
2329 int count = SPECPDL_INDEX ();
2330 struct gcpro gcpro1;
2331
2332 GCPRO1 (sexpr);
2333 specbind (Qinhibit_redisplay, Qt);
2334 /* Use Qt to ensure debugger does not run,
2335 so there is no possibility of wanting to redisplay. */
2336 val = internal_condition_case_1 (Feval, sexpr, Qt,
2337 safe_eval_handler);
2338 UNGCPRO;
2339 val = unbind_to (count, val);
2340 }
2341
2342 return val;
2343}
2344
2345
2346/* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1]. 2319/* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2347 Return the result, or nil if something went wrong. Prevent 2320 Return the result, or nil if something went wrong. Prevent
2348 redisplay during the evaluation. */ 2321 redisplay during the evaluation. */
@@ -2389,6 +2362,27 @@ safe_call1 (fn, arg)
2389 return safe_call (2, args); 2362 return safe_call (2, args);
2390} 2363}
2391 2364
2365static Lisp_Object Qeval;
2366
2367Lisp_Object
2368safe_eval (Lisp_Object sexpr)
2369{
2370 return safe_call1 (Qeval, sexpr);
2371}
2372
2373/* Call function FN with one argument ARG.
2374 Return the result, or nil if something went wrong. */
2375
2376Lisp_Object
2377safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2378{
2379 Lisp_Object args[3];
2380 args[0] = fn;
2381 args[1] = arg1;
2382 args[2] = arg2;
2383 return safe_call (3, args);
2384}
2385
2392 2386
2393 2387
2394/*********************************************************************** 2388/***********************************************************************
@@ -8634,7 +8628,7 @@ current_message ()
8634{ 8628{
8635 Lisp_Object msg; 8629 Lisp_Object msg;
8636 8630
8637 if (NILP (echo_area_buffer[0])) 8631 if (!BUFFERP (echo_area_buffer[0]))
8638 msg = Qnil; 8632 msg = Qnil;
8639 else 8633 else
8640 { 8634 {
@@ -24359,6 +24353,9 @@ syms_of_xdisp ()
24359 staticpro (&Qinhibit_point_motion_hooks); 24353 staticpro (&Qinhibit_point_motion_hooks);
24360 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks"); 24354 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
24361 24355
24356 Qeval = intern ("eval");
24357 staticpro (&Qeval);
24358
24362 QCdata = intern (":data"); 24359 QCdata = intern (":data");
24363 staticpro (&QCdata); 24360 staticpro (&QCdata);
24364 Qdisplay = intern ("display"); 24361 Qdisplay = intern ("display");
diff --git a/src/xterm.c b/src/xterm.c
index f8ef761c5f5..147e492e7d5 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8144,7 +8144,11 @@ x_connection_closed (dpy, error_message)
8144 /* We have just closed all frames on this display. */ 8144 /* We have just closed all frames on this display. */
8145 abort (); 8145 abort ();
8146 8146
8147 x_delete_display (dpyinfo); 8147 {
8148 Lisp_Object tmp;
8149 XSETTERMINAL (tmp, dpyinfo->terminal);
8150 Fdelete_terminal (tmp, Qnoelisp);
8151 }
8148 } 8152 }
8149 8153
8150 x_uncatch_errors (); 8154 x_uncatch_errors ();
@@ -8165,10 +8169,9 @@ x_connection_closed (dpy, error_message)
8165 8169
8166 unbind_to (index, Qnil); 8170 unbind_to (index, Qnil);
8167 clear_waiting_for_input (); 8171 clear_waiting_for_input ();
8168 /* FIXME: This is an asynchronous interrupt w.r.t elisp, so signalling an 8172 /* Here, we absolutely have to use a non-local exit (e.g. signal, throw,
8169 error might not be the best thing to do. I'd vote for creating an 8173 longjmp), because returning from this function would get us back into
8170 elisp event and stuffing it in the queue so people can bind to it via 8174 Xlib's code which will directly call `exit'. */
8171 the global map. --Stef */
8172 error ("%s", error_msg); 8175 error ("%s", error_msg);
8173} 8176}
8174 8177