Mercurial > hg > xemacs-beta
annotate src/event-stream.c @ 5803:b79e1e02bf01
Preserve extent information in the command builder code.
src/ChangeLog addition:
2014-07-14 Aidan Kehoe <kehoea@parhasard.net>
* event-stream.c:
* event-stream.c (mark_command_builder):
* event-stream.c (finalize_command_builder): Removed.
* event-stream.c (allocate_command_builder):
* event-stream.c (free_command_builder): Removed. Use
free_normal_lisp_object() instead.
* event-stream.c (echo_key_event):
* event-stream.c (regenerate_echo_keys_from_this_command_keys):
Detach all extents here.
* event-stream.c (maybe_echo_keys):
* event-stream.c (reset_key_echo):
* event-stream.c (execute_help_form):
* event-stream.c (Fnext_event):
* event-stream.c (command_builder_find_leaf_no_jit_binding):
* event-stream.c (command_builder_find_leaf):
* event-stream.c (lookup_command_event):
* events.h (struct command_builder):
Move the command builder's echo_buf to being a Lisp string rather
than a malloced Ibyte array. This allows passing through extent
information, which was previously dropped. It also simplifies the
allocation and release code for the command builder.
Rename echo_buf_index to echo_buf_fill_pointer, better reflecting
its function.
Don't rely on zero-termination (something not particularly
compatible with Lisp-level code) when showing a substring of
echo_buf that differs from that designated by
echo_buf_fill_pointer, keep a separate counter instead and use
that.
* minibuf.c:
* minibuf.c (echo_area_append):
Use the new START and END keyword arguments to #'append-message,
rather than consing a new string for basically every #'next-event
prompt displayed.
test/ChangeLog addition:
2014-07-14 Aidan Kehoe <kehoea@parhasard.net>
* automated/extent-tests.el:
Check that extent information is passed through to the echo area
correctly with #'next-event's PROMPT argument.
lisp/ChangeLog addition:
2014-07-14 Aidan Kehoe <kehoea@parhasard.net>
* simple.el (raw-append-message):
Use #'write-sequence in this, take its START and END keyword
arguments, so our callers don't have to cons as much.
* simple.el (append-message):
Pass through START and END here.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Mon, 14 Jul 2014 13:42:42 +0100 |
parents | 0e9f791cc655 |
children | 75435be92103 |
rev | line source |
---|---|
428 | 1 /* The portable interface to event streams. |
2 Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. | |
3 Copyright (C) 1995 Board of Trustees, University of Illinois. | |
4 Copyright (C) 1995 Sun Microsystems, Inc. | |
5125 | 5 Copyright (C) 1995, 1996, 2001, 2002, 2003, 2005, 2010 Ben Wing. |
428 | 6 |
7 This file is part of XEmacs. | |
8 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5191
diff
changeset
|
9 XEmacs is free software: you can redistribute it and/or modify it |
428 | 10 under the terms of the GNU General Public License as published by the |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5191
diff
changeset
|
11 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5191
diff
changeset
|
12 option) any later version. |
428 | 13 |
14 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5191
diff
changeset
|
20 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 21 |
22 /* Synched up with: Not in FSF. */ | |
23 | |
442 | 24 /* Authorship: |
25 | |
26 Created 1991 by Jamie Zawinski. | |
27 A great deal of work over the ages by Ben Wing (Mule-ization for 19.12, | |
28 device abstraction for 19.12/19.13, async timers for 19.14, | |
29 rewriting of focus code for 19.12, pre-idle hook for 19.12, | |
30 redoing of signal and quit handling for 19.9 and 19.12, | |
31 misc-user events to clean up menu/scrollbar handling for 19.11, | |
32 function-key-map/key-translation-map/keyboard-translate-table for | |
33 19.13/19.14, open-dribble-file for 19.13, much other cleanup). | |
34 focus-follows-mouse from Chuck Thompson, 1995. | |
35 XIM stuff by Martin Buchholz, c. 1996?. | |
36 */ | |
37 | |
428 | 38 /* This file has been Mule-ized. */ |
39 | |
40 /* | |
41 * DANGER!! | |
42 * | |
43 * If you ever change ANYTHING in this file, you MUST run the | |
44 * testcases at the end to make sure that you haven't changed | |
45 * the semantics of recent-keys, last-input-char, or keyboard | |
46 * macros. You'd be surprised how easy it is to break this. | |
47 * | |
48 */ | |
49 | |
50 /* TODO: | |
1204 | 51 [This stuff is way too hard to maintain - needs rework.] |
52 I don't think it's that bad in the main. I've done a fair amount of | |
53 cleanup work over the ages; the only stuff that's probably still somewhat | |
54 messy is the command-builder handling, which is that way because it's | |
55 trying to be "compatible" with pseudo-standards established by Emacs | |
56 v18. | |
428 | 57 |
58 The command builder should deal only with key and button events. | |
59 Other command events should be able to come in the MIDDLE of a key | |
60 sequence, without disturbing the key sequence composition, or the | |
61 command builder structure representing it. | |
62 | |
63 Someone should rethink universal-argument and figure out how an | |
64 arbitrary command can influence the next command (universal-argument | |
65 or universal-coding-system-argument) or the next key (hyperify). | |
66 | |
67 Both C-h and Help in the middle of a key sequence should trigger | |
68 prefix-help-command. help-char is stupid. Maybe we need | |
69 keymap-of-last-resort? | |
70 | |
71 After prefix-help is run, one should be able to CONTINUE TYPING, | |
72 instead of RETYPING, the key sequence. | |
73 */ | |
74 | |
75 #include <config.h> | |
76 #include "lisp.h" | |
77 | |
78 #include "blocktype.h" | |
79 #include "buffer.h" | |
80 #include "commands.h" | |
872 | 81 #include "device-impl.h" |
428 | 82 #include "elhash.h" |
83 #include "events.h" | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
84 #include "extents.h" |
872 | 85 #include "frame-impl.h" |
428 | 86 #include "insdel.h" /* for buffer_reset_changes */ |
87 #include "keymap.h" | |
88 #include "lstream.h" | |
89 #include "macros.h" /* for defining_keyboard_macro */ | |
442 | 90 #include "menubar.h" /* #### for evil kludges. */ |
428 | 91 #include "process.h" |
1292 | 92 #include "profile.h" |
872 | 93 #include "window-impl.h" |
428 | 94 |
95 #include "sysdep.h" /* init_poll_for_quit() */ | |
96 #include "syssignal.h" /* SIGCHLD, etc. */ | |
97 #include "sysfile.h" | |
98 #include "systime.h" /* to set Vlast_input_time */ | |
99 | |
100 #include "file-coding.h" | |
101 | |
102 #include <errno.h> | |
103 | |
104 /* The number of keystrokes between auto-saves. */ | |
458 | 105 static Fixnum auto_save_interval; |
428 | 106 |
107 Lisp_Object Qundefined_keystroke_sequence; | |
563 | 108 Lisp_Object Qinvalid_key_binding; |
428 | 109 |
110 Lisp_Object Qcommand_event_p; | |
111 | |
112 /* Hooks to run before and after each command. */ | |
113 Lisp_Object Vpre_command_hook, Vpost_command_hook; | |
114 Lisp_Object Qpre_command_hook, Qpost_command_hook; | |
115 | |
442 | 116 /* See simple.el */ |
117 Lisp_Object Qhandle_pre_motion_command, Qhandle_post_motion_command; | |
118 | |
428 | 119 /* Hook run when XEmacs is about to be idle. */ |
120 Lisp_Object Qpre_idle_hook, Vpre_idle_hook; | |
121 | |
122 /* Control gratuitous keyboard focus throwing. */ | |
123 int focus_follows_mouse; | |
124 | |
444 | 125 /* When true, modifier keys are sticky. */ |
442 | 126 int modifier_keys_are_sticky; |
444 | 127 /* Modifier keys are sticky for this many milliseconds. */ |
128 Lisp_Object Vmodifier_keys_sticky_time; | |
129 | |
2828 | 130 /* If true, "Russian C-x processing" is enabled. */ |
131 int try_alternate_layouts_for_commands; | |
132 | |
444 | 133 /* Here FSF Emacs 20.7 defines Vpost_command_idle_hook, |
134 post_command_idle_delay, Vdeferred_action_list, and | |
135 Vdeferred_action_function, but we don't because that stuff is crap, | |
1315 | 136 and we're smarter than them, and their mommas are fat. */ |
444 | 137 |
138 /* FSF Emacs 20.7 also defines Vinput_method_function, | |
139 Qinput_method_exit_on_first_char and Qinput_method_use_echo_area. | |
1315 | 140 I don't know whether this should be imported or not. */ |
428 | 141 |
142 /* Non-nil disable property on a command means | |
143 do not execute it; call disabled-command-hook's value instead. */ | |
733 | 144 Lisp_Object Qdisabled; |
428 | 145 |
146 /* Last keyboard or mouse input event read as a command. */ | |
147 Lisp_Object Vlast_command_event; | |
148 | |
149 /* The nearest ASCII equivalent of the above. */ | |
150 Lisp_Object Vlast_command_char; | |
151 | |
152 /* Last keyboard or mouse event read for any purpose. */ | |
153 Lisp_Object Vlast_input_event; | |
154 | |
155 /* The nearest ASCII equivalent of the above. */ | |
156 Lisp_Object Vlast_input_char; | |
157 | |
158 Lisp_Object Vcurrent_mouse_event; | |
159 | |
160 /* This is fbound in cmdloop.el, see the commentary there */ | |
161 Lisp_Object Qcancel_mode_internal; | |
162 | |
163 /* If not Qnil, event objects to be read as the next command input */ | |
164 Lisp_Object Vunread_command_events; | |
165 Lisp_Object Vunread_command_event; /* obsoleteness support */ | |
166 | |
167 static Lisp_Object Qunread_command_events, Qunread_command_event; | |
168 | |
169 /* Previous command, represented by a Lisp object. | |
442 | 170 Does not include prefix commands and arg setting commands. */ |
428 | 171 Lisp_Object Vlast_command; |
172 | |
442 | 173 /* Contents of this-command-properties for the last command. */ |
174 Lisp_Object Vlast_command_properties; | |
175 | |
428 | 176 /* If a command sets this, the value goes into |
442 | 177 last-command for the next command. */ |
428 | 178 Lisp_Object Vthis_command; |
179 | |
442 | 180 /* If a command sets this, the value goes into |
181 last-command-properties for the next command. */ | |
182 Lisp_Object Vthis_command_properties; | |
183 | |
428 | 184 /* The value of point when the last command was executed. */ |
665 | 185 Charbpos last_point_position; |
428 | 186 |
187 /* The frame that was current when the last command was started. */ | |
188 Lisp_Object Vlast_selected_frame; | |
189 | |
190 /* The buffer that was current when the last command was started. */ | |
191 Lisp_Object last_point_position_buffer; | |
192 | |
193 /* A (16bit . 16bit) representation of the time of the last-command-event. */ | |
194 Lisp_Object Vlast_input_time; | |
195 | |
196 /* A (16bit 16bit usec) representation of the time | |
197 of the last-command-event. */ | |
198 Lisp_Object Vlast_command_event_time; | |
199 | |
200 /* Character to recognize as the help char. */ | |
201 Lisp_Object Vhelp_char; | |
202 | |
203 /* Form to execute when help char is typed. */ | |
204 Lisp_Object Vhelp_form; | |
205 | |
206 /* Command to run when the help character follows a prefix key. */ | |
207 Lisp_Object Vprefix_help_command; | |
208 | |
209 /* Flag to tell QUIT that some interesting occurrence (e.g. a keypress) | |
210 may have happened. */ | |
211 volatile int something_happened; | |
212 | |
213 /* Hash table to translate keysyms through */ | |
214 Lisp_Object Vkeyboard_translate_table; | |
215 | |
216 /* If control-meta-super-shift-X is undefined, try control-meta-super-x */ | |
217 Lisp_Object Vretry_undefined_key_binding_unshifted; | |
218 Lisp_Object Qretry_undefined_key_binding_unshifted; | |
219 | |
220 /* Console that corresponds to our controlling terminal */ | |
221 Lisp_Object Vcontrolling_terminal; | |
222 | |
223 /* An event (actually an event chain linked through event_next) or Qnil. | |
224 */ | |
225 Lisp_Object Vthis_command_keys; | |
226 Lisp_Object Vthis_command_keys_tail; | |
227 | |
228 /* #### kludge! */ | |
229 Lisp_Object Qauto_show_make_point_visible; | |
230 | |
231 /* File in which we write all commands we read; an lstream */ | |
232 static Lisp_Object Vdribble_file; | |
233 | |
234 /* Recent keys ring location; a vector of events or nil-s */ | |
235 Lisp_Object Vrecent_keys_ring; | |
236 int recent_keys_ring_size; | |
237 int recent_keys_ring_index; | |
238 | |
239 /* Boolean specifying whether keystrokes should be added to | |
240 recent-keys. */ | |
241 int inhibit_input_event_recording; | |
242 | |
430 | 243 Lisp_Object Qself_insert_defer_undo; |
244 | |
5139
a48ef26d87ee
Clean up prototypes for Lisp variables/symbols. Put decls for them with
Ben Wing <ben@xemacs.org>
parents:
5050
diff
changeset
|
245 Lisp_Object Qsans_modifiers; |
a48ef26d87ee
Clean up prototypes for Lisp variables/symbols. Put decls for them with
Ben Wing <ben@xemacs.org>
parents:
5050
diff
changeset
|
246 |
1268 | 247 int in_modal_loop; |
248 | |
249 /* the number of keyboard characters read. callint.c wants this. */ | |
250 Charcount num_input_chars; | |
428 | 251 |
1292 | 252 static Lisp_Object Qnext_event, Qdispatch_event, QSnext_event_internal; |
253 static Lisp_Object QSexecute_internal_event; | |
254 | |
428 | 255 #ifdef DEBUG_XEMACS |
458 | 256 Fixnum debug_emacs_events; |
428 | 257 |
258 static void | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
259 external_debugging_print_event (const Ascbyte *event_description, |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
260 Lisp_Object event) |
428 | 261 { |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
262 write_ascstring (Qexternal_debugging_output, "("); |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
263 write_ascstring (Qexternal_debugging_output, event_description); |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
264 write_ascstring (Qexternal_debugging_output, ") "); |
428 | 265 print_internal (event, Qexternal_debugging_output, 1); |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
266 write_ascstring (Qexternal_debugging_output, "\n"); |
428 | 267 } |
268 #define DEBUG_PRINT_EMACS_EVENT(event_description, event) do { \ | |
269 if (debug_emacs_events) \ | |
270 external_debugging_print_event (event_description, event); \ | |
271 } while (0) | |
272 #else | |
273 #define DEBUG_PRINT_EMACS_EVENT(string, event) | |
274 #endif | |
275 | |
276 | |
277 /* The callback routines for the window system or terminal driver */ | |
278 struct event_stream *event_stream; | |
279 | |
2367 | 280 |
281 /* | |
282 | |
283 See also | |
284 | |
285 (Info-goto-node "(internals)Event Stream Callback Routines") | |
286 */ | |
1204 | 287 |
428 | 288 static Lisp_Object command_event_queue; |
289 static Lisp_Object command_event_queue_tail; | |
290 | |
1204 | 291 Lisp_Object dispatch_event_queue; |
292 static Lisp_Object dispatch_event_queue_tail; | |
293 | |
428 | 294 /* Nonzero means echo unfinished commands after this many seconds of pause. */ |
295 static Lisp_Object Vecho_keystrokes; | |
296 | |
297 /* The number of keystrokes since the last auto-save. */ | |
298 static int keystrokes_since_auto_save; | |
299 | |
300 /* Used by the C-g signal handler so that it will never "hard quit" | |
301 when waiting for an event. Otherwise holding down C-g could | |
302 cause a suspension back to the shell, which is generally | |
303 undesirable. (#### This doesn't fully work.) */ | |
304 | |
305 int emacs_is_blocking; | |
306 | |
307 /* Handlers which run during sit-for, sleep-for and accept-process-output | |
308 are not allowed to recursively call these routines. We record here | |
309 if we are in that situation. */ | |
310 | |
1268 | 311 static int recursive_sit_for; |
312 | |
313 static void pre_command_hook (void); | |
314 static void post_command_hook (void); | |
315 static void maybe_kbd_translate (Lisp_Object event); | |
316 static void push_this_command_keys (Lisp_Object event); | |
317 static void push_recent_keys (Lisp_Object event); | |
318 static void dribble_out_event (Lisp_Object event); | |
319 static void execute_internal_event (Lisp_Object event); | |
320 static int is_scrollbar_event (Lisp_Object event); | |
428 | 321 |
322 | |
323 /**********************************************************************/ | |
324 /* Command-builder object */ | |
325 /**********************************************************************/ | |
326 | |
327 #define XCOMMAND_BUILDER(x) \ | |
328 XRECORD (x, command_builder, struct command_builder) | |
771 | 329 #define wrap_command_builder(p) wrap_record (p, command_builder) |
428 | 330 #define COMMAND_BUILDERP(x) RECORDP (x, command_builder) |
331 #define CHECK_COMMAND_BUILDER(x) CHECK_RECORD (x, command_builder) | |
771 | 332 #define CONCHECK_COMMAND_BUILDER(x) CONCHECK_RECORD (x, command_builder) |
333 | |
1204 | 334 static const struct memory_description command_builder_description [] = { |
934 | 335 { XD_LISP_OBJECT, offsetof (struct command_builder, current_events) }, |
336 { XD_LISP_OBJECT, offsetof (struct command_builder, most_current_event) }, | |
337 { XD_LISP_OBJECT, offsetof (struct command_builder, last_non_munged_event) }, | |
338 { XD_LISP_OBJECT, offsetof (struct command_builder, console) }, | |
1204 | 339 { XD_LISP_OBJECT_ARRAY, offsetof (struct command_builder, first_mungeable_event), 2 }, |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
340 { XD_LISP_OBJECT, offsetof (struct command_builder, echo_buf) }, |
934 | 341 { XD_END } |
342 }; | |
343 | |
428 | 344 static Lisp_Object |
345 mark_command_builder (Lisp_Object obj) | |
346 { | |
347 struct command_builder *builder = XCOMMAND_BUILDER (obj); | |
348 mark_object (builder->current_events); | |
349 mark_object (builder->most_current_event); | |
350 mark_object (builder->last_non_munged_event); | |
1204 | 351 mark_object (builder->first_mungeable_event[0]); |
352 mark_object (builder->first_mungeable_event[1]); | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
353 mark_object (builder->echo_buf); |
428 | 354 return builder->console; |
355 } | |
356 | |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
357 DEFINE_NODUMP_LISP_OBJECT ("command-builder", command_builder, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
358 mark_command_builder, |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
359 internal_object_printer, 0, 0, 0, |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
360 command_builder_description, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
361 struct command_builder); |
771 | 362 |
428 | 363 static void |
364 reset_command_builder_event_chain (struct command_builder *builder) | |
365 { | |
366 builder->current_events = Qnil; | |
367 builder->most_current_event = Qnil; | |
368 builder->last_non_munged_event = Qnil; | |
1204 | 369 builder->first_mungeable_event[0] = Qnil; |
370 builder->first_mungeable_event[1] = Qnil; | |
428 | 371 } |
372 | |
373 Lisp_Object | |
771 | 374 allocate_command_builder (Lisp_Object console, int with_echo_buf) |
428 | 375 { |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5126
diff
changeset
|
376 Lisp_Object builder_obj = ALLOC_NORMAL_LISP_OBJECT (command_builder); |
771 | 377 struct command_builder *builder = XCOMMAND_BUILDER (builder_obj); |
428 | 378 |
379 builder->console = console; | |
380 reset_command_builder_event_chain (builder); | |
771 | 381 if (with_echo_buf) |
382 { | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
383 builder->echo_buf = make_uninit_string (300 * MAX_ICHAR_LEN); |
771 | 384 } |
385 else | |
386 { | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
387 builder->echo_buf = Qnil; |
771 | 388 } |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
389 builder->echo_buf_fill_pointer = builder->echo_buf_end = -1; |
428 | 390 builder->self_insert_countdown = 0; |
391 | |
392 return builder_obj; | |
393 } | |
394 | |
771 | 395 /* Copy or clone COLLAPSING (copy to NEW_BUILDINGS if non-zero, |
396 otherwise clone); but don't copy the echo-buf stuff. (The calling | |
397 routines don't need it and will reset it, and we would rather avoid | |
398 malloc.) */ | |
399 | |
400 static Lisp_Object | |
401 copy_command_builder (struct command_builder *collapsing, | |
402 struct command_builder *new_buildings) | |
403 { | |
404 if (!new_buildings) | |
405 new_buildings = XCOMMAND_BUILDER (allocate_command_builder (Qnil, 0)); | |
406 | |
3358 | 407 new_buildings->console = collapsing->console; |
408 | |
771 | 409 new_buildings->self_insert_countdown = collapsing->self_insert_countdown; |
410 | |
411 deallocate_event_chain (new_buildings->current_events); | |
412 new_buildings->current_events = | |
413 copy_event_chain (collapsing->current_events); | |
414 | |
415 new_buildings->most_current_event = | |
416 transfer_event_chain_pointer (collapsing->most_current_event, | |
417 collapsing->current_events, | |
418 new_buildings->current_events); | |
419 new_buildings->last_non_munged_event = | |
420 transfer_event_chain_pointer (collapsing->last_non_munged_event, | |
421 collapsing->current_events, | |
422 new_buildings->current_events); | |
1204 | 423 new_buildings->first_mungeable_event[0] = |
424 transfer_event_chain_pointer (collapsing->first_mungeable_event[0], | |
771 | 425 collapsing->current_events, |
426 new_buildings->current_events); | |
1204 | 427 new_buildings->first_mungeable_event[1] = |
428 transfer_event_chain_pointer (collapsing->first_mungeable_event[1], | |
771 | 429 collapsing->current_events, |
430 new_buildings->current_events); | |
431 | |
432 return wrap_command_builder (new_buildings); | |
433 } | |
434 | |
435 static void | |
428 | 436 command_builder_append_event (struct command_builder *builder, |
437 Lisp_Object event) | |
438 { | |
439 assert (EVENTP (event)); | |
440 | |
771 | 441 event = Fcopy_event (event, Qnil); |
428 | 442 if (EVENTP (builder->most_current_event)) |
443 XSET_EVENT_NEXT (builder->most_current_event, event); | |
444 else | |
445 builder->current_events = event; | |
446 | |
447 builder->most_current_event = event; | |
1204 | 448 if (NILP (builder->first_mungeable_event[0])) |
449 builder->first_mungeable_event[0] = event; | |
450 if (NILP (builder->first_mungeable_event[1])) | |
451 builder->first_mungeable_event[1] = event; | |
428 | 452 } |
453 | |
454 | |
455 /**********************************************************************/ | |
456 /* Low-level interfaces onto event methods */ | |
457 /**********************************************************************/ | |
458 | |
459 static void | |
1268 | 460 check_event_stream_ok (void) |
428 | 461 { |
462 if (!event_stream && noninteractive) | |
814 | 463 /* See comment in init_event_stream() */ |
464 init_event_stream (); | |
465 else assert (event_stream); | |
428 | 466 } |
467 | |
468 void | |
440 | 469 event_stream_handle_magic_event (Lisp_Event *event) |
428 | 470 { |
1268 | 471 check_event_stream_ok (); |
428 | 472 event_stream->handle_magic_event_cb (event); |
473 } | |
474 | |
788 | 475 void |
476 event_stream_format_magic_event (Lisp_Event *event, Lisp_Object pstream) | |
477 { | |
1268 | 478 check_event_stream_ok (); |
788 | 479 event_stream->format_magic_event_cb (event, pstream); |
480 } | |
481 | |
482 int | |
483 event_stream_compare_magic_event (Lisp_Event *e1, Lisp_Event *e2) | |
484 { | |
1268 | 485 check_event_stream_ok (); |
788 | 486 return event_stream->compare_magic_event_cb (e1, e2); |
487 } | |
488 | |
489 Hashcode | |
490 event_stream_hash_magic_event (Lisp_Event *e) | |
491 { | |
1268 | 492 check_event_stream_ok (); |
788 | 493 return event_stream->hash_magic_event_cb (e); |
494 } | |
495 | |
428 | 496 static int |
497 event_stream_add_timeout (EMACS_TIME timeout) | |
498 { | |
1268 | 499 check_event_stream_ok (); |
428 | 500 return event_stream->add_timeout_cb (timeout); |
501 } | |
502 | |
503 static void | |
504 event_stream_remove_timeout (int id) | |
505 { | |
1268 | 506 check_event_stream_ok (); |
428 | 507 event_stream->remove_timeout_cb (id); |
508 } | |
509 | |
510 void | |
511 event_stream_select_console (struct console *con) | |
512 { | |
1268 | 513 check_event_stream_ok (); |
428 | 514 if (!con->input_enabled) |
515 { | |
516 event_stream->select_console_cb (con); | |
517 con->input_enabled = 1; | |
518 } | |
519 } | |
520 | |
521 void | |
522 event_stream_unselect_console (struct console *con) | |
523 { | |
1268 | 524 check_event_stream_ok (); |
428 | 525 if (con->input_enabled) |
526 { | |
527 event_stream->unselect_console_cb (con); | |
528 con->input_enabled = 0; | |
529 } | |
530 } | |
531 | |
532 void | |
853 | 533 event_stream_select_process (Lisp_Process *proc, int doin, int doerr) |
428 | 534 { |
853 | 535 int cur_in, cur_err; |
536 | |
1268 | 537 check_event_stream_ok (); |
853 | 538 |
539 cur_in = get_process_selected_p (proc, 0); | |
540 if (cur_in) | |
541 doin = 0; | |
542 | |
543 if (!process_has_separate_stderr (wrap_process (proc))) | |
428 | 544 { |
853 | 545 doerr = 0; |
546 cur_err = 0; | |
547 } | |
548 else | |
549 { | |
550 cur_err = get_process_selected_p (proc, 1); | |
551 if (cur_err) | |
552 doerr = 0; | |
553 } | |
554 | |
555 if (doin || doerr) | |
556 { | |
557 event_stream->select_process_cb (proc, doin, doerr); | |
558 set_process_selected_p (proc, cur_in || doin, cur_err || doerr); | |
428 | 559 } |
560 } | |
561 | |
562 void | |
853 | 563 event_stream_unselect_process (Lisp_Process *proc, int doin, int doerr) |
428 | 564 { |
853 | 565 int cur_in, cur_err; |
566 | |
1268 | 567 check_event_stream_ok (); |
853 | 568 |
569 cur_in = get_process_selected_p (proc, 0); | |
570 if (!cur_in) | |
571 doin = 0; | |
572 | |
573 if (!process_has_separate_stderr (wrap_process (proc))) | |
428 | 574 { |
853 | 575 doerr = 0; |
576 cur_err = 0; | |
577 } | |
578 else | |
579 { | |
580 cur_err = get_process_selected_p (proc, 1); | |
581 if (!cur_err) | |
582 doerr = 0; | |
583 } | |
584 | |
585 if (doin || doerr) | |
586 { | |
587 event_stream->unselect_process_cb (proc, doin, doerr); | |
588 set_process_selected_p (proc, cur_in && !doin, cur_err && !doerr); | |
428 | 589 } |
590 } | |
591 | |
853 | 592 void |
593 event_stream_create_io_streams (void *inhandle, void *outhandle, | |
594 void *errhandle, Lisp_Object *instream, | |
595 Lisp_Object *outstream, | |
596 Lisp_Object *errstream, | |
597 USID *in_usid, | |
598 USID *err_usid, | |
599 int flags) | |
428 | 600 { |
1268 | 601 check_event_stream_ok (); |
853 | 602 event_stream->create_io_streams_cb |
603 (inhandle, outhandle, errhandle, instream, outstream, errstream, | |
604 in_usid, err_usid, flags); | |
428 | 605 } |
606 | |
853 | 607 void |
608 event_stream_delete_io_streams (Lisp_Object instream, | |
609 Lisp_Object outstream, | |
610 Lisp_Object errstream, | |
611 USID *in_usid, | |
612 USID *err_usid) | |
428 | 613 { |
1268 | 614 check_event_stream_ok (); |
853 | 615 event_stream->delete_io_streams_cb (instream, outstream, errstream, |
616 in_usid, err_usid); | |
428 | 617 } |
618 | |
442 | 619 static int |
620 event_stream_current_event_timestamp (struct console *c) | |
621 { | |
622 if (event_stream && event_stream->current_event_timestamp_cb) | |
623 return event_stream->current_event_timestamp_cb (c); | |
624 else | |
625 return 0; | |
626 } | |
428 | 627 |
628 | |
629 /**********************************************************************/ | |
630 /* Character prompting */ | |
631 /**********************************************************************/ | |
632 | |
633 static void | |
634 echo_key_event (struct command_builder *command_builder, | |
635 Lisp_Object event) | |
636 { | |
637 /* This function can GC */ | |
793 | 638 DECLARE_EISTRING_MALLOC (buf); |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
639 Bytecount buf_fill_pointer = command_builder->echo_buf_fill_pointer; |
428 | 640 Bytecount len; |
641 | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
642 if (buf_fill_pointer < 0) |
428 | 643 { |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
644 buf_fill_pointer = 0; |
428 | 645 clear_echo_area (selected_frame (), Qnil, 0); |
646 } | |
647 | |
934 | 648 format_event_object (buf, event, 1); |
793 | 649 len = eilen (buf); |
428 | 650 |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
651 if (NILP (command_builder->echo_buf) || |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
652 (len + buf_fill_pointer + 4 > XSTRING_LENGTH (command_builder->echo_buf))) |
793 | 653 { |
654 eifree (buf); | |
655 return; | |
656 } | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
657 |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
658 eicat_ascii (buf, " - "); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
659 |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
660 memcpy (XSTRING_DATA (command_builder->echo_buf) + buf_fill_pointer, |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
661 eidata (buf), eilen (buf)); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
662 init_string_ascii_begin (command_builder->echo_buf); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
663 bump_string_modiff (command_builder->echo_buf); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
664 sledgehammer_check_ascii_begin (command_builder->echo_buf); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
665 |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
666 command_builder->echo_buf_end = buf_fill_pointer + eilen (buf); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
667 /* *Not* including the trailing " - ". */ |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
668 command_builder->echo_buf_fill_pointer = buf_fill_pointer + len + 1; |
793 | 669 eifree (buf); |
428 | 670 } |
671 | |
672 static void | |
673 regenerate_echo_keys_from_this_command_keys (struct command_builder * | |
674 builder) | |
675 { | |
676 Lisp_Object event; | |
677 | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
678 builder->echo_buf_fill_pointer = builder->echo_buf_end = 0; |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
679 if (STRINGP (builder->echo_buf)) |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
680 { |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
681 detach_all_extents (builder->echo_buf); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
682 } |
428 | 683 |
684 EVENT_CHAIN_LOOP (event, Vthis_command_keys) | |
685 echo_key_event (builder, event); | |
686 } | |
687 | |
688 static void | |
689 maybe_echo_keys (struct command_builder *command_builder, int no_snooze) | |
690 { | |
691 /* This function can GC */ | |
692 double echo_keystrokes; | |
693 struct frame *f = selected_frame (); | |
853 | 694 int depth = begin_dont_check_for_quit (); |
695 | |
428 | 696 /* Message turns off echoing unless more keystrokes turn it on again. */ |
697 if (echo_area_active (f) && !EQ (Qcommand, echo_area_status (f))) | |
853 | 698 goto done; |
428 | 699 |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
700 if (FIXNUMP (Vecho_keystrokes) || FLOATP (Vecho_keystrokes)) |
428 | 701 echo_keystrokes = extract_float (Vecho_keystrokes); |
702 else | |
703 echo_keystrokes = 0; | |
704 | |
705 if (minibuf_level == 0 | |
706 && echo_keystrokes > 0.0 | |
442 | 707 #if defined (HAVE_X_WINDOWS) && defined (LWLIB_MENUBARS_LUCID) |
708 && !x_kludge_lw_menu_active () | |
709 #endif | |
710 ) | |
428 | 711 { |
712 if (!no_snooze) | |
713 { | |
714 if (NILP (Fsit_for (Vecho_keystrokes, Qnil))) | |
715 /* input came in, so don't echo. */ | |
853 | 716 goto done; |
428 | 717 } |
718 | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
719 echo_area_message (f, NULL, command_builder->echo_buf, 0, |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
720 command_builder->echo_buf_end, Qcommand); |
428 | 721 } |
853 | 722 |
723 done: | |
724 Vquit_flag = Qnil; /* see begin_dont_check_for_quit() */ | |
725 unbind_to (depth); | |
428 | 726 } |
727 | |
728 static void | |
729 reset_key_echo (struct command_builder *command_builder, | |
730 int remove_echo_area_echo) | |
731 { | |
732 /* This function can GC */ | |
733 struct frame *f = selected_frame (); | |
734 | |
757 | 735 if (command_builder) |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
736 { |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
737 command_builder->echo_buf_fill_pointer = |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
738 command_builder->echo_buf_end = -1; |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
739 } |
428 | 740 |
741 if (remove_echo_area_echo) | |
742 clear_echo_area (f, Qcommand, 0); | |
743 } | |
744 | |
745 | |
746 /**********************************************************************/ | |
747 /* random junk */ | |
748 /**********************************************************************/ | |
749 | |
750 /* NB: The following auto-save stuff is in keyboard.c in FSFmacs, and | |
751 keystrokes_since_auto_save is equivalent to the difference between | |
752 num_nonmacro_input_chars and last_auto_save. */ | |
753 | |
444 | 754 /* When an auto-save happens, record the number of keystrokes, and |
755 don't do again soon. */ | |
428 | 756 |
757 void | |
758 record_auto_save (void) | |
759 { | |
760 keystrokes_since_auto_save = 0; | |
761 } | |
762 | |
763 /* Make an auto save happen as soon as possible at command level. */ | |
764 | |
765 void | |
766 force_auto_save_soon (void) | |
767 { | |
768 keystrokes_since_auto_save = 1 + max (auto_save_interval, 20); | |
769 } | |
770 | |
771 static void | |
772 maybe_do_auto_save (void) | |
773 { | |
774 /* This function can call lisp */ | |
775 keystrokes_since_auto_save++; | |
776 if (auto_save_interval > 0 && | |
777 keystrokes_since_auto_save > max (auto_save_interval, 20) && | |
1268 | 778 !detect_input_pending (1)) |
428 | 779 { |
780 Fdo_auto_save (Qnil, Qnil); | |
781 record_auto_save (); | |
782 } | |
783 } | |
784 | |
785 static Lisp_Object | |
786 print_help (Lisp_Object object) | |
787 { | |
788 Fprinc (object, Qnil); | |
789 return Qnil; | |
790 } | |
791 | |
792 static void | |
793 execute_help_form (struct command_builder *command_builder, | |
794 Lisp_Object event) | |
795 { | |
796 /* This function can GC */ | |
797 Lisp_Object help = Qnil; | |
798 int speccount = specpdl_depth (); | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
799 Bytecount buf_fill_pointer = command_builder->echo_buf_fill_pointer; |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
800 Bytecount buf_end = command_builder->echo_buf_end; |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
801 Lisp_Object echo = ((buf_fill_pointer <= 0) ? Qnil |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
802 : Fcopy_sequence (command_builder->echo_buf)); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
803 |
428 | 804 struct gcpro gcpro1, gcpro2; |
805 GCPRO2 (echo, help); | |
806 | |
4775
1d61580e0cf7
Remove Fsave_window_excursion from window.c, it's overridden by Lisp.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4718
diff
changeset
|
807 record_unwind_protect (Feval, |
1d61580e0cf7
Remove Fsave_window_excursion from window.c, it's overridden by Lisp.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4718
diff
changeset
|
808 list2 (Qset_window_configuration, |
1d61580e0cf7
Remove Fsave_window_excursion from window.c, it's overridden by Lisp.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4718
diff
changeset
|
809 call0 (Qcurrent_window_configuration))); |
428 | 810 reset_key_echo (command_builder, 1); |
811 | |
4677
8f1ee2d15784
Support full Common Lisp multiple values in C.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4528
diff
changeset
|
812 help = IGNORE_MULTIPLE_VALUES (Feval (Vhelp_form)); |
428 | 813 if (STRINGP (help)) |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
814 internal_with_output_to_temp_buffer (build_ascstring ("*Help*"), |
428 | 815 print_help, help, Qnil); |
816 Fnext_command_event (event, Qnil); | |
817 /* Remove the help from the frame */ | |
771 | 818 unbind_to (speccount); |
428 | 819 /* Hmmmm. Tricky. The unbind restores an old window configuration, |
820 apparently bypassing any setting of windows_structure_changed. | |
821 So we need to set it so that things get redrawn properly. */ | |
822 /* #### This is massive overkill. Look at doing it better once the | |
823 new redisplay is fully in place. */ | |
824 { | |
825 Lisp_Object frmcons, devcons, concons; | |
826 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons) | |
827 { | |
828 struct frame *f = XFRAME (XCAR (frmcons)); | |
829 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f); | |
830 } | |
831 } | |
832 | |
833 redisplay (); | |
1204 | 834 if (event_matches_key_specifier_p (event, make_char (' '))) |
428 | 835 { |
836 /* Discard next key if it is a space */ | |
837 reset_key_echo (command_builder, 1); | |
838 Fnext_command_event (event, Qnil); | |
839 } | |
840 | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
841 command_builder->echo_buf_fill_pointer = buf_fill_pointer; |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
842 command_builder->echo_buf_end = buf_end; |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
843 |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
844 if (buf_fill_pointer > 0) |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
845 { |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
846 command_builder->echo_buf = echo; |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
847 } |
428 | 848 UNGCPRO; |
849 } | |
850 | |
851 | |
852 /**********************************************************************/ | |
853 /* timeouts */ | |
854 /**********************************************************************/ | |
855 | |
593 | 856 /* NOTE: "Low-level" or "interval" timeouts are one-shot timeouts that |
857 measure single intervals. "High-level timeouts" or "wakeups" are | |
858 the objects generated by `add-timeout' or `add-async-timout' -- | |
859 they can fire repeatedly (and in fact can have a different initial | |
860 time and resignal time). Given the nature of both setitimer() and | |
861 select() -- i.e. all we get is a single one-shot timer -- we have | |
862 to decompose all high-level timeouts into a series of intervals or | |
863 low-level timeouts. | |
864 | |
865 Low-level timeouts are of two varieties: synchronous and asynchronous. | |
866 The former are handled at the window-system level, the latter in | |
867 signal.c. | |
868 */ | |
869 | |
870 /**** Low-level timeout helper functions. **** | |
428 | 871 |
872 These functions maintain a sorted list of one-shot timeouts (where | |
593 | 873 the timeouts are in absolute time so we never lose any time as a |
874 result of the delay between noting an interval and firing the next | |
875 one). They are intended for use by functions that need to convert | |
876 a list of absolute timeouts into a series of intervals to wait | |
877 for. */ | |
428 | 878 |
879 /* We ensure that 0 is never a valid ID, so that a value of 0 can be | |
880 used to indicate an absence of a timer. */ | |
881 static int low_level_timeout_id_tick; | |
882 | |
883 static struct low_level_timeout_blocktype | |
884 { | |
885 Blocktype_declare (struct low_level_timeout); | |
886 } *the_low_level_timeout_blocktype; | |
887 | |
888 /* Add a one-shot timeout at time TIME to TIMEOUT_LIST. Return | |
889 a unique ID identifying the timeout. */ | |
890 | |
891 int | |
892 add_low_level_timeout (struct low_level_timeout **timeout_list, | |
893 EMACS_TIME thyme) | |
894 { | |
895 struct low_level_timeout *tm; | |
896 struct low_level_timeout *t, **tt; | |
897 | |
898 /* Allocate a new time struct. */ | |
899 | |
900 tm = Blocktype_alloc (the_low_level_timeout_blocktype); | |
901 tm->next = NULL; | |
593 | 902 /* Don't just use ++low_level_timeout_id_tick, for the (admittedly |
903 rare) case in which numbers wrap around. */ | |
428 | 904 if (low_level_timeout_id_tick == 0) |
905 low_level_timeout_id_tick++; | |
906 tm->id = low_level_timeout_id_tick++; | |
907 tm->time = thyme; | |
908 | |
909 /* Add it to the queue. */ | |
910 | |
911 tt = timeout_list; | |
912 t = *tt; | |
913 while (t && EMACS_TIME_EQUAL_OR_GREATER (tm->time, t->time)) | |
914 { | |
915 tt = &t->next; | |
916 t = *tt; | |
917 } | |
918 tm->next = t; | |
919 *tt = tm; | |
920 | |
921 return tm->id; | |
922 } | |
923 | |
924 /* Remove the low-level timeout identified by ID from TIMEOUT_LIST. | |
925 If the timeout is not there, do nothing. */ | |
926 | |
927 void | |
928 remove_low_level_timeout (struct low_level_timeout **timeout_list, int id) | |
929 { | |
930 struct low_level_timeout *t, *prev; | |
931 | |
932 /* find it */ | |
933 | |
934 for (t = *timeout_list, prev = NULL; t && t->id != id; t = t->next) | |
935 prev = t; | |
936 | |
937 if (!t) | |
938 return; /* couldn't find it */ | |
939 | |
940 if (!prev) | |
941 *timeout_list = t->next; | |
942 else prev->next = t->next; | |
943 | |
944 Blocktype_free (the_low_level_timeout_blocktype, t); | |
945 } | |
946 | |
947 /* If there are timeouts on TIMEOUT_LIST, store the relative time | |
948 interval to the first timeout on the list into INTERVAL and | |
949 return 1. Otherwise, return 0. */ | |
950 | |
951 int | |
952 get_low_level_timeout_interval (struct low_level_timeout *timeout_list, | |
953 EMACS_TIME *interval) | |
954 { | |
955 if (!timeout_list) /* no timer events; block indefinitely */ | |
956 return 0; | |
957 else | |
958 { | |
959 EMACS_TIME current_time; | |
960 | |
961 /* The time to block is the difference between the first | |
962 (earliest) timer on the queue and the current time. | |
963 If that is negative, then the timer will fire immediately | |
964 but we still have to call select(), with a zero-valued | |
965 timeout: user events must have precedence over timer events. */ | |
966 EMACS_GET_TIME (current_time); | |
967 if (EMACS_TIME_GREATER (timeout_list->time, current_time)) | |
968 EMACS_SUB_TIME (*interval, timeout_list->time, | |
969 current_time); | |
970 else | |
971 EMACS_SET_SECS_USECS (*interval, 0, 0); | |
972 return 1; | |
973 } | |
974 } | |
975 | |
976 /* Pop the first (i.e. soonest) timeout off of TIMEOUT_LIST and return | |
977 its ID. Also, if TIME_OUT is not 0, store the absolute time of the | |
978 timeout into TIME_OUT. */ | |
979 | |
980 int | |
981 pop_low_level_timeout (struct low_level_timeout **timeout_list, | |
982 EMACS_TIME *time_out) | |
983 { | |
984 struct low_level_timeout *tm = *timeout_list; | |
985 int id; | |
986 | |
987 assert (tm); | |
988 id = tm->id; | |
989 if (time_out) | |
990 *time_out = tm->time; | |
991 *timeout_list = tm->next; | |
992 Blocktype_free (the_low_level_timeout_blocktype, tm); | |
993 return id; | |
994 } | |
995 | |
996 | |
593 | 997 /**** High-level timeout functions. **** */ |
998 | |
999 /* We ensure that 0 is never a valid ID, so that a value of 0 can be | |
1000 used to indicate an absence of a timer. */ | |
428 | 1001 static int timeout_id_tick; |
1002 | |
1003 static Lisp_Object pending_timeout_list, pending_async_timeout_list; | |
1004 | |
1005 static Lisp_Object | |
1006 mark_timeout (Lisp_Object obj) | |
1007 { | |
440 | 1008 Lisp_Timeout *tm = XTIMEOUT (obj); |
428 | 1009 mark_object (tm->function); |
1010 return tm->object; | |
1011 } | |
1012 | |
1204 | 1013 static const struct memory_description timeout_description[] = { |
440 | 1014 { XD_LISP_OBJECT, offsetof (Lisp_Timeout, function) }, |
1015 { XD_LISP_OBJECT, offsetof (Lisp_Timeout, object) }, | |
428 | 1016 { XD_END } |
1017 }; | |
1018 | |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
1019 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("timeout", timeout, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
1020 mark_timeout, timeout_description, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
1021 Lisp_Timeout); |
428 | 1022 |
1023 /* Generate a timeout and return its ID. */ | |
1024 | |
1025 int | |
1026 event_stream_generate_wakeup (unsigned int milliseconds, | |
1027 unsigned int vanilliseconds, | |
1028 Lisp_Object function, Lisp_Object object, | |
1029 int async_p) | |
1030 { | |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5126
diff
changeset
|
1031 Lisp_Object op = ALLOC_NORMAL_LISP_OBJECT (timeout); |
440 | 1032 Lisp_Timeout *timeout = XTIMEOUT (op); |
428 | 1033 EMACS_TIME current_time; |
1034 EMACS_TIME interval; | |
1035 | |
593 | 1036 /* Don't just use ++timeout_id_tick, for the (admittedly rare) case |
1037 in which numbers wrap around. */ | |
1038 if (timeout_id_tick == 0) | |
1039 timeout_id_tick++; | |
428 | 1040 timeout->id = timeout_id_tick++; |
1041 timeout->resignal_msecs = vanilliseconds; | |
1042 timeout->function = function; | |
1043 timeout->object = object; | |
1044 | |
1045 EMACS_GET_TIME (current_time); | |
1046 EMACS_SET_SECS_USECS (interval, milliseconds / 1000, | |
1047 1000 * (milliseconds % 1000)); | |
1048 EMACS_ADD_TIME (timeout->next_signal_time, current_time, interval); | |
1049 | |
1050 if (async_p) | |
1051 { | |
1052 timeout->interval_id = | |
593 | 1053 signal_add_async_interval_timeout (timeout->next_signal_time); |
1054 pending_async_timeout_list = | |
1055 noseeum_cons (op, pending_async_timeout_list); | |
428 | 1056 } |
1057 else | |
1058 { | |
1059 timeout->interval_id = | |
1060 event_stream_add_timeout (timeout->next_signal_time); | |
1061 pending_timeout_list = noseeum_cons (op, pending_timeout_list); | |
1062 } | |
1063 return timeout->id; | |
1064 } | |
1065 | |
1066 /* Given the INTERVAL-ID of a timeout just signalled, resignal the timeout | |
1067 as necessary and return the timeout's ID and function and object slots. | |
1068 | |
1069 This should be called as a result of receiving notice that a timeout | |
1070 has fired. INTERVAL-ID is *not* the timeout's ID, but is the ID that | |
1071 identifies this particular firing of the timeout. INTERVAL-ID's and | |
1072 timeout ID's are in separate number spaces and bear no relation to | |
1073 each other. The INTERVAL-ID is all that the event callback routines | |
1074 work with: they work only with one-shot intervals, not with timeouts | |
1075 that may fire repeatedly. | |
1076 | |
1077 NOTE: The returned FUNCTION and OBJECT are *not* GC-protected at all. | |
1078 */ | |
1079 | |
593 | 1080 int |
428 | 1081 event_stream_resignal_wakeup (int interval_id, int async_p, |
1082 Lisp_Object *function, Lisp_Object *object) | |
1083 { | |
1084 Lisp_Object op = Qnil, rest; | |
440 | 1085 Lisp_Timeout *timeout; |
428 | 1086 Lisp_Object *timeout_list; |
1087 struct gcpro gcpro1; | |
1088 int id; | |
1089 | |
1090 GCPRO1 (op); /* just in case ... because it's removed from the list | |
1091 for awhile. */ | |
1092 | |
1093 timeout_list = async_p ? &pending_async_timeout_list : &pending_timeout_list; | |
1094 | |
1095 /* Find the timeout on the list of pending ones. */ | |
1096 LIST_LOOP (rest, *timeout_list) | |
1097 { | |
1098 timeout = XTIMEOUT (XCAR (rest)); | |
1099 if (timeout->interval_id == interval_id) | |
1100 break; | |
1101 } | |
1102 | |
1103 assert (!NILP (rest)); | |
1104 op = XCAR (rest); | |
1105 timeout = XTIMEOUT (op); | |
1106 /* We make sure to snarf the data out of the timeout object before | |
5142
f965e31a35f0
reduce lcrecord headers to 2 words, rename printing_unreadable_object
Ben Wing <ben@xemacs.org>
parents:
5127
diff
changeset
|
1107 we free it with free_normal_lisp_object(). */ |
428 | 1108 id = timeout->id; |
1109 *function = timeout->function; | |
1110 *object = timeout->object; | |
1111 | |
1112 /* Remove this one from the list of pending timeouts */ | |
1113 *timeout_list = delq_no_quit_and_free_cons (op, *timeout_list); | |
1114 | |
1115 /* If this timeout wants to be resignalled, do it now. */ | |
1116 if (timeout->resignal_msecs) | |
1117 { | |
1118 EMACS_TIME current_time; | |
1119 EMACS_TIME interval; | |
1120 | |
1121 /* Determine the time that the next resignalling should occur. | |
1122 We do that by adding the interval time to the last signalled | |
1123 time until we get a time that's current. | |
1124 | |
1125 (This way, it doesn't matter if the timeout was signalled | |
1126 exactly when we asked for it, or at some time later.) | |
1127 */ | |
1128 EMACS_GET_TIME (current_time); | |
1129 EMACS_SET_SECS_USECS (interval, timeout->resignal_msecs / 1000, | |
1130 1000 * (timeout->resignal_msecs % 1000)); | |
1131 do | |
1132 { | |
1133 EMACS_ADD_TIME (timeout->next_signal_time, timeout->next_signal_time, | |
1134 interval); | |
1135 } while (EMACS_TIME_GREATER (current_time, timeout->next_signal_time)); | |
1136 | |
1137 if (async_p) | |
1138 timeout->interval_id = | |
593 | 1139 signal_add_async_interval_timeout (timeout->next_signal_time); |
428 | 1140 else |
1141 timeout->interval_id = | |
1142 event_stream_add_timeout (timeout->next_signal_time); | |
1143 /* Add back onto the list. Note that the effect of this | |
1144 is to move frequently-hit timeouts to the front of the | |
1145 list, which is a good thing. */ | |
1146 *timeout_list = noseeum_cons (op, *timeout_list); | |
1147 } | |
1148 else | |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5126
diff
changeset
|
1149 free_normal_lisp_object (op); |
428 | 1150 |
1151 UNGCPRO; | |
1152 return id; | |
1153 } | |
1154 | |
1155 void | |
1156 event_stream_disable_wakeup (int id, int async_p) | |
1157 { | |
440 | 1158 Lisp_Timeout *timeout = 0; |
428 | 1159 Lisp_Object rest; |
1160 Lisp_Object *timeout_list; | |
1161 | |
1162 if (async_p) | |
1163 timeout_list = &pending_async_timeout_list; | |
1164 else | |
1165 timeout_list = &pending_timeout_list; | |
1166 | |
1167 /* Find the timeout on the list of pending ones, if it's still there. */ | |
1168 LIST_LOOP (rest, *timeout_list) | |
1169 { | |
1170 timeout = XTIMEOUT (XCAR (rest)); | |
1171 if (timeout->id == id) | |
1172 break; | |
1173 } | |
1174 | |
1175 /* If we found it, remove it from the list and disable the pending | |
1176 one-shot. */ | |
1177 if (!NILP (rest)) | |
1178 { | |
1179 Lisp_Object op = XCAR (rest); | |
1180 *timeout_list = | |
1181 delq_no_quit_and_free_cons (op, *timeout_list); | |
1182 if (async_p) | |
593 | 1183 signal_remove_async_interval_timeout (timeout->interval_id); |
428 | 1184 else |
1185 event_stream_remove_timeout (timeout->interval_id); | |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5126
diff
changeset
|
1186 free_normal_lisp_object (op); |
428 | 1187 } |
1188 } | |
1189 | |
1190 static int | |
1191 event_stream_wakeup_pending_p (int id, int async_p) | |
1192 { | |
440 | 1193 Lisp_Timeout *timeout; |
428 | 1194 Lisp_Object rest; |
1195 Lisp_Object timeout_list; | |
1196 int found = 0; | |
1197 | |
1198 | |
1199 if (async_p) | |
1200 timeout_list = pending_async_timeout_list; | |
1201 else | |
1202 timeout_list = pending_timeout_list; | |
1203 | |
1204 /* Find the element on the list of pending ones, if it's still there. */ | |
1205 LIST_LOOP (rest, timeout_list) | |
1206 { | |
1207 timeout = XTIMEOUT (XCAR (rest)); | |
1208 if (timeout->id == id) | |
1209 { | |
1210 found = 1; | |
1211 break; | |
1212 } | |
1213 } | |
1214 | |
1215 return found; | |
1216 } | |
1217 | |
1218 | |
1219 /**** Lisp-level timeout functions. ****/ | |
1220 | |
1221 static unsigned long | |
1222 lisp_number_to_milliseconds (Lisp_Object secs, int allow_0) | |
1223 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1224 Lisp_Object args[] = { allow_0 ? Qzero : make_fixnum (1), |
5307
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1225 secs, |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1226 /* (((unsigned int) 0xFFFFFFFF) / 1000) - 1 */ |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1227 make_fixnum (4294967 - 1) }; |
5307
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1228 |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1229 if (!allow_0 && FLOATP (secs) && XFLOAT_DATA (secs) > 0) |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1230 { |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1231 args[0] = secs; |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1232 } |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1233 |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1234 if (NILP (Fleq (countof (args), args))) |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1235 { |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1236 args_out_of_range_3 (secs, args[0], args[2]); |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1237 } |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1238 |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1239 args[0] = make_fixnum (1000); |
5307
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1240 args[0] = Ftimes (2, args); |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1241 |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1242 if (FIXNUMP (args[0])) |
5307
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1243 { |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1244 return XFIXNUM (args[0]); |
5307
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1245 } |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1246 |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
1247 return (unsigned long) extract_float (args[0]); |
428 | 1248 } |
1249 | |
1250 DEFUN ("add-timeout", Fadd_timeout, 3, 4, 0, /* | |
1251 Add a timeout, to be signaled after the timeout period has elapsed. | |
1252 SECS is a number of seconds, expressed as an integer or a float. | |
1253 FUNCTION will be called after that many seconds have elapsed, with one | |
1254 argument, the given OBJECT. If the optional RESIGNAL argument is provided, | |
1255 then after this timeout expires, `add-timeout' will automatically be called | |
1256 again with RESIGNAL as the first argument. | |
1257 | |
1258 This function returns an object which is the id number of this particular | |
1259 timeout. You can pass that object to `disable-timeout' to turn off the | |
1260 timeout before it has been signalled. | |
1261 | |
1262 NOTE: Id numbers as returned by this function are in a distinct namespace | |
1263 from those returned by `add-async-timeout'. This means that the same id | |
1264 number could refer to a pending synchronous timeout and a different pending | |
1265 asynchronous timeout, and that you cannot pass an id from `add-timeout' | |
1266 to `disable-async-timeout', or vice-versa. | |
1267 | |
1268 The number of seconds may be expressed as a floating-point number, in which | |
1269 case some fractional part of a second will be used. Caveat: the usable | |
1270 timeout granularity will vary from system to system. | |
1271 | |
1272 Adding a timeout causes a timeout event to be returned by `next-event', and | |
1273 the function will be invoked by `dispatch-event,' so if emacs is in a tight | |
1274 loop, the function will not be invoked until the next call to sit-for or | |
1275 until the return to top-level (the same is true of process filters). | |
1276 | |
1277 If you need to have a timeout executed even when XEmacs is in the midst of | |
1278 running Lisp code, use `add-async-timeout'. | |
1279 | |
1280 WARNING: if you are thinking of calling add-timeout from inside of a | |
1281 callback function as a way of resignalling a timeout, think again. There | |
1282 is a race condition. That's why the RESIGNAL argument exists. | |
1283 */ | |
1284 (secs, function, object, resignal)) | |
1285 { | |
1286 unsigned long msecs = lisp_number_to_milliseconds (secs, 0); | |
1287 unsigned long msecs2 = (NILP (resignal) ? 0 : | |
1288 lisp_number_to_milliseconds (resignal, 0)); | |
1289 int id; | |
1290 Lisp_Object lid; | |
1291 id = event_stream_generate_wakeup (msecs, msecs2, function, object, 0); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1292 lid = make_fixnum (id); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1293 assert (id == XFIXNUM (lid)); |
428 | 1294 return lid; |
1295 } | |
1296 | |
1297 DEFUN ("disable-timeout", Fdisable_timeout, 1, 1, 0, /* | |
1298 Disable a timeout from signalling any more. | |
1299 ID should be a timeout id number as returned by `add-timeout'. If ID | |
1300 corresponds to a one-shot timeout that has already signalled, nothing | |
1301 will happen. | |
1302 | |
1303 It will not work to call this function on an id number returned by | |
1304 `add-async-timeout'. Use `disable-async-timeout' for that. | |
1305 */ | |
1306 (id)) | |
1307 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1308 CHECK_FIXNUM (id); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1309 event_stream_disable_wakeup (XFIXNUM (id), 0); |
428 | 1310 return Qnil; |
1311 } | |
1312 | |
1313 DEFUN ("add-async-timeout", Fadd_async_timeout, 3, 4, 0, /* | |
1314 Add an asynchronous timeout, to be signaled after an interval has elapsed. | |
1315 SECS is a number of seconds, expressed as an integer or a float. | |
1316 FUNCTION will be called after that many seconds have elapsed, with one | |
1317 argument, the given OBJECT. If the optional RESIGNAL argument is provided, | |
1318 then after this timeout expires, `add-async-timeout' will automatically be | |
1319 called again with RESIGNAL as the first argument. | |
1320 | |
1321 This function returns an object which is the id number of this particular | |
1322 timeout. You can pass that object to `disable-async-timeout' to turn off | |
1323 the timeout before it has been signalled. | |
1324 | |
1325 NOTE: Id numbers as returned by this function are in a distinct namespace | |
1326 from those returned by `add-timeout'. This means that the same id number | |
1327 could refer to a pending synchronous timeout and a different pending | |
1328 asynchronous timeout, and that you cannot pass an id from | |
1329 `add-async-timeout' to `disable-timeout', or vice-versa. | |
1330 | |
1331 The number of seconds may be expressed as a floating-point number, in which | |
1332 case some fractional part of a second will be used. Caveat: the usable | |
1333 timeout granularity will vary from system to system. | |
1334 | |
1335 Adding an asynchronous timeout causes the function to be invoked as soon | |
1336 as the timeout occurs, even if XEmacs is in the midst of executing some | |
1337 other code. (This is unlike the synchronous timeouts added with | |
1338 `add-timeout', where the timeout will only be signalled when XEmacs is | |
1339 waiting for events, i.e. the next return to top-level or invocation of | |
1340 `sit-for' or related functions.) This means that the function that is | |
1341 called *must* not signal an error or change any global state (e.g. switch | |
1342 buffers or windows) except when locking code is in place to make sure | |
1343 that race conditions don't occur in the interaction between the | |
1344 asynchronous timeout function and other code. | |
1345 | |
1346 Under most circumstances, you should use `add-timeout' instead, as it is | |
1347 much safer. Asynchronous timeouts should only be used when such behavior | |
1348 is really necessary. | |
1349 | |
1350 Asynchronous timeouts are blocked and will not occur when `inhibit-quit' | |
1351 is non-nil. As soon as `inhibit-quit' becomes nil again, any pending | |
1352 asynchronous timeouts will get called immediately. (Multiple occurrences | |
1353 of the same asynchronous timeout are not queued, however.) While the | |
1354 callback function of an asynchronous timeout is invoked, `inhibit-quit' | |
1355 is automatically bound to non-nil, and thus other asynchronous timeouts | |
1356 will be blocked unless the callback function explicitly sets `inhibit-quit' | |
1357 to nil. | |
1358 | |
1359 WARNING: if you are thinking of calling `add-async-timeout' from inside of a | |
1360 callback function as a way of resignalling a timeout, think again. There | |
1361 is a race condition. That's why the RESIGNAL argument exists. | |
1362 */ | |
1363 (secs, function, object, resignal)) | |
1364 { | |
1365 unsigned long msecs = lisp_number_to_milliseconds (secs, 0); | |
1366 unsigned long msecs2 = (NILP (resignal) ? 0 : | |
1367 lisp_number_to_milliseconds (resignal, 0)); | |
1368 int id; | |
1369 Lisp_Object lid; | |
1370 id = event_stream_generate_wakeup (msecs, msecs2, function, object, 1); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1371 lid = make_fixnum (id); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1372 assert (id == XFIXNUM (lid)); |
428 | 1373 return lid; |
1374 } | |
1375 | |
1376 DEFUN ("disable-async-timeout", Fdisable_async_timeout, 1, 1, 0, /* | |
1377 Disable an asynchronous timeout from signalling any more. | |
1378 ID should be a timeout id number as returned by `add-async-timeout'. If ID | |
1379 corresponds to a one-shot timeout that has already signalled, nothing | |
1380 will happen. | |
1381 | |
1382 It will not work to call this function on an id number returned by | |
1383 `add-timeout'. Use `disable-timeout' for that. | |
1384 */ | |
1385 (id)) | |
1386 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1387 CHECK_FIXNUM (id); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1388 event_stream_disable_wakeup (XFIXNUM (id), 1); |
428 | 1389 return Qnil; |
1390 } | |
1391 | |
1392 | |
1393 /**********************************************************************/ | |
1394 /* enqueuing and dequeuing events */ | |
1395 /**********************************************************************/ | |
1396 | |
1397 /* Add an event to the back of the command-event queue: it will be the next | |
1398 event read after all pending events. This only works on keyboard, | |
1399 mouse-click, misc-user, and eval events. | |
1400 */ | |
1401 static void | |
1402 enqueue_command_event (Lisp_Object event) | |
1403 { | |
1404 enqueue_event (event, &command_event_queue, &command_event_queue_tail); | |
1405 } | |
1406 | |
1407 static Lisp_Object | |
1408 dequeue_command_event (void) | |
1409 { | |
1410 return dequeue_event (&command_event_queue, &command_event_queue_tail); | |
1411 } | |
1412 | |
1204 | 1413 void |
1414 enqueue_dispatch_event (Lisp_Object event) | |
1415 { | |
1416 enqueue_event (event, &dispatch_event_queue, &dispatch_event_queue_tail); | |
1417 } | |
1418 | |
1419 Lisp_Object | |
1420 dequeue_dispatch_event (void) | |
1421 { | |
1422 return dequeue_event (&dispatch_event_queue, &dispatch_event_queue_tail); | |
1423 } | |
1424 | |
428 | 1425 static void |
1426 enqueue_command_event_1 (Lisp_Object event_to_copy) | |
1427 { | |
853 | 1428 enqueue_command_event (Fcopy_event (event_to_copy, Qnil)); |
428 | 1429 } |
1430 | |
1431 void | |
1432 enqueue_magic_eval_event (void (*fun) (Lisp_Object), Lisp_Object object) | |
1433 { | |
1434 Lisp_Object event = Fmake_event (Qnil, Qnil); | |
934 | 1435 XSET_EVENT_TYPE (event, magic_eval_event); |
1436 /* channel for magic_eval events is nil */ | |
1204 | 1437 XSET_EVENT_MAGIC_EVAL_INTERNAL_FUNCTION (event, fun); |
1438 XSET_EVENT_MAGIC_EVAL_OBJECT (event, object); | |
428 | 1439 enqueue_command_event (event); |
1440 } | |
1441 | |
1442 DEFUN ("enqueue-eval-event", Fenqueue_eval_event, 2, 2, 0, /* | |
1443 Add an eval event to the back of the eval event queue. | |
1444 When this event is dispatched, FUNCTION (which should be a function | |
1445 of one argument) will be called with OBJECT as its argument. | |
1446 See `next-event' for a description of event types and how events | |
1447 are received. | |
1448 */ | |
1449 (function, object)) | |
1450 { | |
1451 Lisp_Object event = Fmake_event (Qnil, Qnil); | |
1452 | |
934 | 1453 XSET_EVENT_TYPE (event, eval_event); |
1454 /* channel for eval events is nil */ | |
1204 | 1455 XSET_EVENT_EVAL_FUNCTION (event, function); |
1456 XSET_EVENT_EVAL_OBJECT (event, object); | |
428 | 1457 enqueue_command_event (event); |
1458 | |
1459 return event; | |
1460 } | |
1461 | |
1462 Lisp_Object | |
1463 enqueue_misc_user_event (Lisp_Object channel, Lisp_Object function, | |
1464 Lisp_Object object) | |
1465 { | |
1466 Lisp_Object event = Fmake_event (Qnil, Qnil); | |
934 | 1467 XSET_EVENT_TYPE (event, misc_user_event); |
1468 XSET_EVENT_CHANNEL (event, channel); | |
1204 | 1469 XSET_EVENT_MISC_USER_FUNCTION (event, function); |
1470 XSET_EVENT_MISC_USER_OBJECT (event, object); | |
1471 XSET_EVENT_MISC_USER_BUTTON (event, 0); | |
1472 XSET_EVENT_MISC_USER_MODIFIERS (event, 0); | |
1473 XSET_EVENT_MISC_USER_X (event, -1); | |
1474 XSET_EVENT_MISC_USER_Y (event, -1); | |
428 | 1475 enqueue_command_event (event); |
1476 | |
1477 return event; | |
1478 } | |
1479 | |
1480 Lisp_Object | |
1481 enqueue_misc_user_event_pos (Lisp_Object channel, Lisp_Object function, | |
1482 Lisp_Object object, | |
1483 int button, int modifiers, int x, int y) | |
1484 { | |
1485 Lisp_Object event = Fmake_event (Qnil, Qnil); | |
1486 | |
934 | 1487 XSET_EVENT_TYPE (event, misc_user_event); |
1488 XSET_EVENT_CHANNEL (event, channel); | |
1204 | 1489 XSET_EVENT_MISC_USER_FUNCTION (event, function); |
1490 XSET_EVENT_MISC_USER_OBJECT (event, object); | |
1491 XSET_EVENT_MISC_USER_BUTTON (event, button); | |
1492 XSET_EVENT_MISC_USER_MODIFIERS (event, modifiers); | |
1493 XSET_EVENT_MISC_USER_X (event, x); | |
1494 XSET_EVENT_MISC_USER_Y (event, y); | |
428 | 1495 enqueue_command_event (event); |
1496 | |
1497 return event; | |
1498 } | |
1499 | |
1500 | |
1501 /**********************************************************************/ | |
1502 /* focus-event handling */ | |
1503 /**********************************************************************/ | |
1504 | |
1505 /* | |
1506 | |
2367 | 1507 See also |
1508 | |
1509 (Info-goto-node "(internals)Focus Handling") | |
428 | 1510 */ |
1511 | |
2367 | 1512 |
428 | 1513 static void |
1514 run_select_frame_hook (void) | |
1515 { | |
1516 run_hook (Qselect_frame_hook); | |
1517 } | |
1518 | |
1519 static void | |
1520 run_deselect_frame_hook (void) | |
1521 { | |
1522 run_hook (Qdeselect_frame_hook); | |
1523 } | |
1524 | |
1525 /* When select-frame is called and focus_follows_mouse is false, we want | |
1526 to tell the window system that the focus should be changed to point to | |
1527 the new frame. However, | |
1528 sometimes Lisp functions will temporarily change the selected frame | |
1529 (e.g. to call a function that operates on the selected frame), | |
1530 and it's annoying if this focus-change happens exactly when | |
1531 select-frame is called, because then you get some flickering of the | |
1532 window-manager border and perhaps other undesirable results. We | |
1533 really only want to change the focus when we're about to retrieve | |
1534 an event from the user. To do this, we keep track of the frame | |
1535 where the window-manager focus lies on, and just before waiting | |
1536 for user events, check the currently selected frame and change | |
1537 the focus as necessary. | |
1538 | |
1539 On the other hand, if focus_follows_mouse is true, we need to switch the | |
1540 selected frame back to the frame with window manager focus just before we | |
1541 execute the next command in Fcommand_loop_1, just as the selected buffer is | |
1542 reverted after a set-buffer. | |
1543 | |
1544 Both cases are handled by this function. It must be called as appropriate | |
1545 from these two places, depending on the value of focus_follows_mouse. */ | |
1546 | |
1547 void | |
1548 investigate_frame_change (void) | |
1549 { | |
1550 Lisp_Object devcons, concons; | |
1551 | |
1552 /* if the selected frame was changed, change the window-system | |
1553 focus to the new frame. We don't do it when select-frame was | |
1554 called, to avoid flickering and other unwanted side effects when | |
1555 the frame is just changed temporarily. */ | |
1556 DEVICE_LOOP_NO_BREAK (devcons, concons) | |
1557 { | |
1558 struct device *d = XDEVICE (XCAR (devcons)); | |
1559 Lisp_Object sel_frame = DEVICE_SELECTED_FRAME (d); | |
1560 | |
1561 /* You'd think that maybe we should use FRAME_WITH_FOCUS_REAL, | |
1562 but that can cause us to end up in an infinite loop focusing | |
1563 between two frames. It seems that since the call to `select-frame' | |
1564 in emacs_handle_focus_change_final() is based on the _FOR_HOOKS | |
1565 value, we need to do so too. */ | |
1566 if (!NILP (sel_frame) && | |
1567 !EQ (DEVICE_FRAME_THAT_OUGHT_TO_HAVE_FOCUS (d), sel_frame) && | |
1568 !NILP (DEVICE_FRAME_WITH_FOCUS_FOR_HOOKS (d)) && | |
1569 !EQ (DEVICE_FRAME_WITH_FOCUS_FOR_HOOKS (d), sel_frame)) | |
1570 { | |
1571 /* At this point, we know that the frame has been changed. Now, if | |
1572 * focus_follows_mouse is not set, we finish off the frame change, | |
1573 * so that user events will now come from the new frame. Otherwise, | |
1574 * if focus_follows_mouse is set, no gratuitous frame changing | |
1575 * should take place. Set the focus back to the frame which was | |
1576 * originally selected for user input. | |
1577 */ | |
1578 if (!focus_follows_mouse) | |
1579 { | |
1580 /* prevent us from issuing the same request more than once */ | |
1581 DEVICE_FRAME_THAT_OUGHT_TO_HAVE_FOCUS (d) = sel_frame; | |
1582 MAYBE_DEVMETH (d, focus_on_frame, (XFRAME (sel_frame))); | |
1583 } | |
1584 else | |
1585 { | |
1586 Lisp_Object old_frame = Qnil; | |
1587 | |
1588 /* #### Do we really want to check OUGHT ?? | |
1589 * It seems to make sense, though I have never seen us | |
1590 * get here and have it be non-nil. | |
1591 */ | |
1592 if (FRAMEP (DEVICE_FRAME_THAT_OUGHT_TO_HAVE_FOCUS (d))) | |
1593 old_frame = DEVICE_FRAME_THAT_OUGHT_TO_HAVE_FOCUS (d); | |
1594 else if (FRAMEP (DEVICE_FRAME_WITH_FOCUS_FOR_HOOKS (d))) | |
1595 old_frame = DEVICE_FRAME_WITH_FOCUS_FOR_HOOKS (d); | |
1596 | |
1597 /* #### Can old_frame ever be NIL? play it safe.. */ | |
1598 if (!NILP (old_frame)) | |
1599 { | |
1600 /* Fselect_frame is not really the right thing: it frobs the | |
1601 * buffer stack. But there's no easy way to do the right | |
1602 * thing, and this code already had this problem anyway. | |
1603 */ | |
1604 Fselect_frame (old_frame); | |
1605 } | |
1606 } | |
1607 } | |
1608 } | |
1609 } | |
1610 | |
1611 static Lisp_Object | |
1612 cleanup_after_missed_defocusing (Lisp_Object frame) | |
1613 { | |
1614 if (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame))) | |
1615 Fselect_frame (frame); | |
1616 return Qnil; | |
1617 } | |
1618 | |
1619 void | |
1620 emacs_handle_focus_change_preliminary (Lisp_Object frame_inp_and_dev) | |
1621 { | |
1622 Lisp_Object frame = Fcar (frame_inp_and_dev); | |
1623 Lisp_Object device = Fcar (Fcdr (frame_inp_and_dev)); | |
1624 int in_p = !NILP (Fcdr (Fcdr (frame_inp_and_dev))); | |
1625 struct device *d; | |
1626 | |
1627 if (!DEVICE_LIVE_P (XDEVICE (device))) | |
1628 return; | |
1629 else | |
1630 d = XDEVICE (device); | |
1631 | |
1632 /* Any received focus-change notifications render invalid any | |
1633 pending focus-change requests. */ | |
1634 DEVICE_FRAME_THAT_OUGHT_TO_HAVE_FOCUS (d) = Qnil; | |
1635 if (in_p) | |
1636 { | |
1637 Lisp_Object focus_frame; | |
1638 | |
1639 if (!FRAME_LIVE_P (XFRAME (frame))) | |
1640 return; | |
1641 else | |
1642 focus_frame = DEVICE_FRAME_WITH_FOCUS_REAL (d); | |
1643 | |
1644 /* Mark the minibuffer as changed to make sure it gets updated | |
1645 properly if the echo area is active. */ | |
1646 { | |
1647 struct window *w = XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame))); | |
1648 MARK_WINDOWS_CHANGED (w); | |
1649 } | |
1650 | |
452 | 1651 if (FRAMEP (focus_frame) && FRAME_LIVE_P (XFRAME (focus_frame)) |
1652 && !EQ (frame, focus_frame)) | |
428 | 1653 { |
1654 /* Oops, we missed a focus-out event. */ | |
1655 DEVICE_FRAME_WITH_FOCUS_REAL (d) = Qnil; | |
1656 redisplay_redraw_cursor (XFRAME (focus_frame), 1); | |
1657 } | |
1658 DEVICE_FRAME_WITH_FOCUS_REAL (d) = frame; | |
1659 if (!EQ (frame, focus_frame)) | |
1660 { | |
1661 redisplay_redraw_cursor (XFRAME (frame), 1); | |
1662 } | |
1663 } | |
1664 else | |
1665 { | |
1666 /* We ignore the frame reported in the event. If it's different | |
1667 from where we think the focus was, oh well -- we messed up. | |
1668 Nonetheless, we pretend we were right, for sensible behavior. */ | |
1669 frame = DEVICE_FRAME_WITH_FOCUS_REAL (d); | |
1670 if (!NILP (frame)) | |
1671 { | |
1672 DEVICE_FRAME_WITH_FOCUS_REAL (d) = Qnil; | |
1673 | |
1674 if (FRAME_LIVE_P (XFRAME (frame))) | |
1675 redisplay_redraw_cursor (XFRAME (frame), 1); | |
1676 } | |
1677 } | |
1678 } | |
1679 | |
1680 /* Called from the window-system-specific code when we receive a | |
1681 notification that the focus lies on a particular frame. | |
1682 Argument is a cons: (frame . (device . in-p)) where in-p is non-nil | |
1683 for focus-in. | |
1684 */ | |
1685 void | |
1686 emacs_handle_focus_change_final (Lisp_Object frame_inp_and_dev) | |
1687 { | |
1688 Lisp_Object frame = Fcar (frame_inp_and_dev); | |
1689 Lisp_Object device = Fcar (Fcdr (frame_inp_and_dev)); | |
1690 int in_p = !NILP (Fcdr (Fcdr (frame_inp_and_dev))); | |
1691 struct device *d; | |
1692 int count; | |
1693 | |
1694 if (!DEVICE_LIVE_P (XDEVICE (device))) | |
1695 return; | |
1696 else | |
1697 d = XDEVICE (device); | |
1698 | |
1699 if (in_p) | |
1700 { | |
1701 Lisp_Object focus_frame; | |
1702 | |
1703 if (!FRAME_LIVE_P (XFRAME (frame))) | |
1704 return; | |
1705 else | |
1706 focus_frame = DEVICE_FRAME_WITH_FOCUS_FOR_HOOKS (d); | |
1707 | |
1708 DEVICE_FRAME_WITH_FOCUS_FOR_HOOKS (d) = frame; | |
1709 if (FRAMEP (focus_frame) && !EQ (frame, focus_frame)) | |
1710 { | |
1711 /* Oops, we missed a focus-out event. */ | |
1712 Fselect_frame (focus_frame); | |
1713 /* Do an unwind-protect in case an error occurs in | |
1714 the deselect-frame-hook */ | |
1715 count = specpdl_depth (); | |
1716 record_unwind_protect (cleanup_after_missed_defocusing, frame); | |
1717 run_deselect_frame_hook (); | |
771 | 1718 unbind_to (count); |
428 | 1719 /* the cleanup method changed the focus frame to nil, so |
1720 we need to reflect this */ | |
1721 focus_frame = Qnil; | |
1722 } | |
1723 else | |
1724 Fselect_frame (frame); | |
1725 if (!EQ (frame, focus_frame)) | |
1726 run_select_frame_hook (); | |
1727 } | |
1728 else | |
1729 { | |
1730 /* We ignore the frame reported in the event. If it's different | |
1731 from where we think the focus was, oh well -- we messed up. | |
1732 Nonetheless, we pretend we were right, for sensible behavior. */ | |
1733 frame = DEVICE_FRAME_WITH_FOCUS_FOR_HOOKS (d); | |
1734 if (!NILP (frame)) | |
1735 { | |
1736 DEVICE_FRAME_WITH_FOCUS_FOR_HOOKS (d) = Qnil; | |
1737 run_deselect_frame_hook (); | |
1738 } | |
1739 } | |
1740 } | |
1741 | |
1742 | |
1743 /**********************************************************************/ | |
1268 | 1744 /* input pending/quit checking */ |
1745 /**********************************************************************/ | |
1746 | |
1747 /* If HOW_MANY is 0, return true if there are any user or non-user events | |
1748 pending. If HOW_MANY is > 0, return true if there are that many *user* | |
1749 events pending, irrespective of non-user events. */ | |
1750 | |
1751 static int | |
1752 event_stream_event_pending_p (int how_many) | |
1753 { | |
1754 /* #### Hmmm ... There may be some duplication in "drain queue" and | |
1755 "event pending". Couldn't we just drain the queue and see what's in | |
1756 it, and not maybe need a separate event method for this? Would this | |
1757 work when HOW_MANY is 0? Maybe this would be slow? */ | |
1758 return event_stream && event_stream->event_pending_p (how_many); | |
1759 } | |
1760 | |
1761 static void | |
1762 event_stream_force_event_pending (struct frame *f) | |
1763 { | |
1764 if (event_stream->force_event_pending_cb) | |
1765 event_stream->force_event_pending_cb (f); | |
1766 } | |
1767 | |
1768 void | |
1769 event_stream_drain_queue (void) | |
1770 { | |
1318 | 1771 /* This can call Lisp */ |
1268 | 1772 if (event_stream && event_stream->drain_queue_cb) |
1773 event_stream->drain_queue_cb (); | |
1774 } | |
1775 | |
1776 /* Return non-zero if at least HOW_MANY user events are pending. */ | |
1777 int | |
1778 detect_input_pending (int how_many) | |
1779 { | |
1318 | 1780 /* This can call Lisp */ |
1268 | 1781 Lisp_Object event; |
1782 | |
1783 if (!NILP (Vunread_command_event)) | |
1784 how_many--; | |
1785 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1786 how_many -= XFIXNUM (Fsafe_length (Vunread_command_events)); |
1268 | 1787 |
1788 if (how_many <= 0) | |
1789 return 1; | |
1790 | |
1791 EVENT_CHAIN_LOOP (event, command_event_queue) | |
1792 { | |
1793 if (XEVENT_TYPE (event) != eval_event | |
1794 && XEVENT_TYPE (event) != magic_eval_event) | |
1795 { | |
1796 how_many--; | |
1797 if (how_many <= 0) | |
1798 return 1; | |
1799 } | |
1800 } | |
1801 | |
1802 return event_stream_event_pending_p (how_many); | |
1803 } | |
1804 | |
1805 DEFUN ("input-pending-p", Finput_pending_p, 0, 0, 0, /* | |
1806 Return t if command input is currently available with no waiting. | |
1807 Actually, the value is nil only if we can be sure that no input is available. | |
1808 */ | |
1809 ()) | |
1810 { | |
1318 | 1811 /* This can call Lisp */ |
1268 | 1812 return detect_input_pending (1) ? Qt : Qnil; |
1813 } | |
1814 | |
1815 static int | |
1816 maybe_read_quit_event (Lisp_Event *event) | |
1817 { | |
1818 /* A C-g that came from `sigint_happened' will always come from the | |
1819 controlling terminal. If that doesn't exist, however, then the | |
1820 user manually sent us a SIGINT, and we pretend the C-g came from | |
1821 the selected console. */ | |
1822 struct console *con; | |
1823 | |
1824 if (CONSOLEP (Vcontrolling_terminal) && | |
1825 CONSOLE_LIVE_P (XCONSOLE (Vcontrolling_terminal))) | |
1826 con = XCONSOLE (Vcontrolling_terminal); | |
1827 else | |
1828 con = XCONSOLE (Fselected_console ()); | |
1829 | |
1830 if (sigint_happened) | |
1831 { | |
1832 sigint_happened = 0; | |
1833 Vquit_flag = Qnil; | |
1834 Fcopy_event (CONSOLE_QUIT_EVENT (con), wrap_event (event)); | |
1835 return 1; | |
1836 } | |
1837 return 0; | |
1838 } | |
1839 | |
1840 struct remove_quit_p_data | |
1841 { | |
1842 int critical; | |
1843 }; | |
1844 | |
1845 static int | |
1846 remove_quit_p_event (Lisp_Object ev, void *the_data) | |
1847 { | |
1848 struct remove_quit_p_data *data = (struct remove_quit_p_data *) the_data; | |
1849 struct console *con = event_console_or_selected (ev); | |
1850 | |
1851 if (XEVENT_TYPE (ev) == key_press_event) | |
1852 { | |
1853 if (event_matches_key_specifier_p (ev, CONSOLE_QUIT_EVENT (con))) | |
1854 return 1; | |
1855 if (event_matches_key_specifier_p (ev, | |
1856 CONSOLE_CRITICAL_QUIT_EVENT (con))) | |
1857 { | |
1858 data->critical = 1; | |
1859 return 1; | |
1860 } | |
1861 } | |
1862 | |
1863 return 0; | |
1864 } | |
1865 | |
1866 void | |
1867 event_stream_quit_p (void) | |
1868 { | |
1318 | 1869 /* This can call Lisp */ |
1268 | 1870 struct remove_quit_p_data data; |
1871 | |
1872 /* Quit checking cannot happen in modal loop. Because it attempts to | |
1873 retrieve and dispatch events, it will cause lots of problems if we try | |
1874 to do this when already in the process of doing this -- deadlocking | |
1875 under Windows, crashes in lwlib etc. under X due to non-reentrant | |
1876 code. This is automatically caught, however, in | |
1877 event_stream_drain_queue() (checks for in_modal_loop in the | |
1878 event-specific code). */ | |
1879 | |
1880 /* Drain queue so we can check for pending C-g events. */ | |
1881 event_stream_drain_queue (); | |
1882 data.critical = 0; | |
1883 | |
1884 if (map_event_chain_remove (remove_quit_p_event, | |
1885 &dispatch_event_queue, | |
1886 &dispatch_event_queue_tail, | |
1887 &data, MECR_DEALLOCATE_EVENT)) | |
1888 Vquit_flag = data.critical ? Qcritical : Qt; | |
1889 } | |
1890 | |
1891 Lisp_Object | |
1892 event_stream_protect_modal_loop (const char *error_string, | |
1893 Lisp_Object (*bfun) (void *barg), | |
1894 void *barg, int flags) | |
1895 { | |
1896 Lisp_Object tmp; | |
1897 | |
1898 ++in_modal_loop; | |
1899 tmp = call_trapping_problems (Qevent, error_string, flags, 0, bfun, barg); | |
1900 --in_modal_loop; | |
1901 | |
1902 return tmp; | |
1903 } | |
1904 | |
1905 | |
1906 /**********************************************************************/ | |
428 | 1907 /* retrieving the next event */ |
1908 /**********************************************************************/ | |
1909 | |
1910 static int in_single_console; | |
1911 | |
1912 /* #### These functions don't currently do anything. */ | |
1913 void | |
1914 single_console_state (void) | |
1915 { | |
1916 in_single_console = 1; | |
1917 } | |
1918 | |
1919 void | |
1920 any_console_state (void) | |
1921 { | |
1922 in_single_console = 0; | |
1923 } | |
1924 | |
1925 int | |
1926 in_single_console_state (void) | |
1927 { | |
1928 return in_single_console; | |
1929 } | |
1930 | |
1268 | 1931 static void |
1932 event_stream_next_event (Lisp_Event *event) | |
1933 { | |
1934 Lisp_Object event_obj; | |
1935 | |
1936 check_event_stream_ok (); | |
1937 | |
1938 event_obj = wrap_event (event); | |
1939 zero_event (event); | |
1940 /* SIGINT occurs when C-g was pressed on a TTY. (SIGINT might have | |
1941 been sent manually by the user, but we don't care; we treat it | |
1942 the same.) | |
1943 | |
1944 The SIGINT signal handler sets Vquit_flag as well as sigint_happened | |
1945 and write a byte on our "fake pipe", which unblocks us when we are | |
1946 waiting for an event. */ | |
1947 | |
1948 /* If SIGINT was received after we disabled quit checking (because | |
1949 we want to read C-g's as characters), but before we got a chance | |
1950 to start reading, notice it now and treat it as a character to be | |
1951 read. If above callers wanted this to be QUIT, they can | |
1952 determine this by comparing the event against quit-char. */ | |
1953 | |
1954 if (maybe_read_quit_event (event)) | |
1955 { | |
1956 DEBUG_PRINT_EMACS_EVENT ("SIGINT", event_obj); | |
1957 return; | |
1958 } | |
1959 | |
1960 /* If a longjmp() happens in the callback, we're screwed. | |
1961 Let's hope it doesn't. I think the code here is fairly | |
1962 clean and doesn't do this. */ | |
1963 emacs_is_blocking = 1; | |
1964 event_stream->next_event_cb (event); | |
1965 emacs_is_blocking = 0; | |
1966 | |
1967 /* Now check to see if C-g was pressed while we were blocking. | |
1968 We treat it as an event, just like above. */ | |
1969 if (maybe_read_quit_event (event)) | |
1970 { | |
1971 DEBUG_PRINT_EMACS_EVENT ("SIGINT", event_obj); | |
1972 return; | |
1973 } | |
1974 | |
1975 #ifdef DEBUG_XEMACS | |
1976 /* timeout events have more info set later, so | |
1977 print the event out in next_event_internal(). */ | |
1978 if (event->event_type != timeout_event) | |
1979 DEBUG_PRINT_EMACS_EVENT ("real", event_obj); | |
1980 #endif | |
1981 maybe_kbd_translate (event_obj); | |
1982 } | |
428 | 1983 |
853 | 1984 /* Read an event from the window system (or tty). If ALLOW_QUEUED is |
1985 non-zero, read from the command-event queue first. | |
1986 | |
1987 If C-g was pressed, this function will attempt to QUIT. If you want | |
1988 to read C-g as an event, wrap this function with a call to | |
1989 begin_dont_check_for_quit(), and set Vquit_flag to Qnil just before | |
1990 you unbind. In this case, TARGET_EVENT will contain a C-g. | |
1991 | |
1992 Note that even if you are interested in C-g doing QUIT, a caller of you | |
1993 might not be. | |
1994 */ | |
1995 | |
428 | 1996 static void |
1997 next_event_internal (Lisp_Object target_event, int allow_queued) | |
1998 { | |
1999 struct gcpro gcpro1; | |
1292 | 2000 PROFILE_DECLARE (); |
2001 | |
853 | 2002 QUIT; |
428 | 2003 |
1292 | 2004 PROFILE_RECORD_ENTERING_SECTION (QSnext_event_internal); |
2005 | |
428 | 2006 assert (NILP (XEVENT_NEXT (target_event))); |
2007 | |
2008 GCPRO1 (target_event); | |
2009 | |
2010 /* When focus_follows_mouse is nil, if a frame change took place, we need | |
2011 * to actually switch window manager focus to the selected window now. | |
2012 */ | |
2013 if (!focus_follows_mouse) | |
2014 investigate_frame_change (); | |
2015 | |
2016 if (allow_queued && !NILP (command_event_queue)) | |
2017 { | |
2018 Lisp_Object event = dequeue_command_event (); | |
2019 Fcopy_event (event, target_event); | |
2020 Fdeallocate_event (event); | |
2021 DEBUG_PRINT_EMACS_EVENT ("command event queue", target_event); | |
2022 } | |
2023 else | |
2024 { | |
440 | 2025 Lisp_Event *e = XEVENT (target_event); |
428 | 2026 |
2027 /* The command_event_queue was empty. Wait for an event. */ | |
2028 event_stream_next_event (e); | |
2029 /* If this was a timeout, then we need to extract some data | |
2030 out of the returned closure and might need to resignal | |
2031 it. */ | |
934 | 2032 if (EVENT_TYPE (e) == timeout_event) |
428 | 2033 { |
2034 Lisp_Object tristan, isolde; | |
2035 | |
1204 | 2036 SET_EVENT_TIMEOUT_ID_NUMBER (e, |
2037 event_stream_resignal_wakeup (EVENT_TIMEOUT_INTERVAL_ID (e), 0, &tristan, &isolde)); | |
2038 | |
2039 SET_EVENT_TIMEOUT_FUNCTION (e, tristan); | |
2040 SET_EVENT_TIMEOUT_OBJECT (e, isolde); | |
934 | 2041 /* next_event_internal() doesn't print out timeout events |
2042 because of the extra info we just set. */ | |
428 | 2043 DEBUG_PRINT_EMACS_EVENT ("real, timeout", target_event); |
2044 } | |
2045 | |
853 | 2046 /* If we read a ^G, then set quit-flag and try to QUIT. |
2047 This may be blocked (see above). | |
428 | 2048 */ |
934 | 2049 if (EVENT_TYPE (e) == key_press_event && |
428 | 2050 event_matches_key_specifier_p |
1204 | 2051 (target_event, CONSOLE_QUIT_EVENT (XCONSOLE (EVENT_CHANNEL (e))))) |
428 | 2052 { |
2053 Vquit_flag = Qt; | |
853 | 2054 QUIT; |
428 | 2055 } |
2056 } | |
2057 | |
2058 UNGCPRO; | |
1292 | 2059 |
2060 PROFILE_RECORD_EXITING_SECTION (QSnext_event_internal); | |
428 | 2061 } |
2062 | |
853 | 2063 void |
428 | 2064 run_pre_idle_hook (void) |
2065 { | |
1318 | 2066 /* This can call Lisp */ |
428 | 2067 if (!NILP (Vpre_idle_hook) |
1268 | 2068 && !detect_input_pending (1)) |
853 | 2069 safe_run_hook_trapping_problems |
1333 | 2070 (Qredisplay, Qpre_idle_hook, |
1268 | 2071 /* Quit is inhibited as a result of being within next-event so |
2072 we need to fix that. */ | |
2073 INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION | UNINHIBIT_QUIT); | |
428 | 2074 } |
2075 | |
2076 DEFUN ("next-event", Fnext_event, 0, 2, 0, /* | |
2077 Return the next available event. | |
2078 Pass this object to `dispatch-event' to handle it. | |
2079 In most cases, you will want to use `next-command-event', which returns | |
2080 the next available "user" event (i.e. keypress, button-press, | |
2081 button-release, or menu selection) instead of this function. | |
2082 | |
2083 If EVENT is non-nil, it should be an event object and will be filled in | |
2084 and returned; otherwise a new event object will be created and returned. | |
2085 If PROMPT is non-nil, it should be a string and will be displayed in the | |
2086 echo area while this function is waiting for an event. | |
2087 | |
2088 The next available event will be | |
2089 | |
2090 -- any events in `unread-command-events' or `unread-command-event'; else | |
2091 -- the next event in the currently executing keyboard macro, if any; else | |
442 | 2092 -- an event queued by `enqueue-eval-event', if any, or any similar event |
2093 queued internally, such as a misc-user event. (For example, when an item | |
2094 is selected from a menu or from a `question'-type dialog box, the item's | |
2095 callback is not immediately executed, but instead a misc-user event | |
2096 is generated and placed onto this queue; when it is dispatched, the | |
2097 callback is executed.) Else | |
428 | 2098 -- the next available event from the window system or terminal driver. |
2099 | |
2100 In the last case, this function will block until an event is available. | |
2101 | |
2102 The returned event will be one of the following types: | |
2103 | |
2104 -- a key-press event. | |
2105 -- a button-press or button-release event. | |
2106 -- a misc-user-event, meaning the user selected an item on a menu or used | |
2107 the scrollbar. | |
2108 -- a process event, meaning that output from a subprocess is available. | |
2109 -- a timeout event, meaning that a timeout has elapsed. | |
2110 -- an eval event, which simply causes a function to be executed when the | |
2111 event is dispatched. Eval events are generated by `enqueue-eval-event' | |
2112 or by certain other conditions happening. | |
2113 -- a magic event, indicating that some window-system-specific event | |
2114 happened (such as a focus-change notification) that must be handled | |
2115 synchronously with other events. `dispatch-event' knows what to do with | |
2116 these events. | |
2117 */ | |
2118 (event, prompt)) | |
2119 { | |
2120 /* This function can call lisp */ | |
2121 /* #### We start out using the selected console before an event | |
2122 is received, for echoing the partially completed command. | |
2123 This is most definitely wrong -- there needs to be a separate | |
2124 echo area for each console! */ | |
2125 struct console *con = XCONSOLE (Vselected_console); | |
2126 struct command_builder *command_builder = | |
2127 XCOMMAND_BUILDER (con->command_builder); | |
2128 int store_this_key = 0; | |
2129 struct gcpro gcpro1; | |
853 | 2130 int depth; |
1292 | 2131 PROFILE_DECLARE (); |
428 | 2132 |
2133 GCPRO1 (event); | |
853 | 2134 |
1268 | 2135 /* This is not strictly necessary. Trying to retrieve an event inside of |
2136 a modal loop can cause major problems (see event_stream_quit_p()), but | |
2137 the event-specific code knows about this and will make sure we don't | |
2138 do anything dangerous. However, if we've gotten here, it's highly | |
2139 likely that some code is trying to fetch user events (e.g. in custom | |
2140 dialog-box code), and will almost certainly deadlock, so it's probably | |
2141 best to error out. #### This could cause problems because there are | |
2142 (potentially, at least) legitimate reasons for calling next-event | |
2143 inside of a modal loop, in particular if the code is trying to search | |
2144 for a timeout event, which will still get retrieved in such a case. | |
2145 However, the code to error in such a case has already been present for | |
2146 a long time without obvious problems so leaving it in isn't so | |
1279 | 2147 bad. |
2148 | |
2149 #### I used to conditionalize on in_modal_loop but that fails utterly | |
2150 because event-msw.c specifically calls Fnext_event() inside of a modal | |
2151 loop to clear the dispatch queue. --ben */ | |
1315 | 2152 #ifdef HAVE_MENUBARS |
1279 | 2153 if (in_menu_callback) |
2154 invalid_operation ("Attempt to call next-event inside menu callback", | |
1268 | 2155 Qunbound); |
1315 | 2156 #endif /* HAVE_MENUBARS */ |
1268 | 2157 |
1292 | 2158 PROFILE_RECORD_ENTERING_SECTION (Qnext_event); |
2159 | |
853 | 2160 depth = begin_dont_check_for_quit (); |
428 | 2161 |
2162 if (NILP (event)) | |
2163 event = Fmake_event (Qnil, Qnil); | |
2164 else | |
2165 CHECK_LIVE_EVENT (event); | |
2166 | |
2167 if (!NILP (prompt)) | |
2168 { | |
2169 Bytecount len; | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2170 Lisp_Object args[] = { Qnil, prompt }; |
428 | 2171 CHECK_STRING (prompt); |
2172 | |
2173 len = XSTRING_LENGTH (prompt); | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2174 |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2175 detach_all_extents (command_builder->echo_buf); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2176 if (XSTRING_LENGTH (command_builder->echo_buf) < len) |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2177 { |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2178 command_builder->echo_buf |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2179 = make_uninit_string (len + 200 * MAX_ICHAR_LEN); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2180 } |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2181 |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2182 args[0] = command_builder->echo_buf; |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2183 Freplace (countof (args), args); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2184 copy_string_extents (command_builder->echo_buf, prompt, 0, 0, |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2185 XSTRING_LENGTH (prompt)); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2186 command_builder->echo_buf_fill_pointer |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2187 = command_builder->echo_buf_end = len; |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2188 |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2189 echo_area_message (XFRAME (CONSOLE_SELECTED_FRAME (con)), NULL, |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2190 command_builder->echo_buf, 0, |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
2191 command_builder->echo_buf_end, Qcommand); |
428 | 2192 } |
2193 | |
2194 start_over_and_avoid_hosage: | |
2195 | |
2196 /* If there is something in unread-command-events, simply return it. | |
2197 But do some error checking to make sure the user hasn't put something | |
2198 in the unread-command-events that they shouldn't have. | |
2199 This does not update this-command-keys and recent-keys. | |
2200 */ | |
2201 if (!NILP (Vunread_command_events)) | |
2202 { | |
2203 if (!CONSP (Vunread_command_events)) | |
2204 { | |
2205 Vunread_command_events = Qnil; | |
563 | 2206 signal_error_1 (Qwrong_type_argument, |
428 | 2207 list3 (Qconsp, Vunread_command_events, |
2208 Qunread_command_events)); | |
2209 } | |
2210 else | |
2211 { | |
2212 Lisp_Object e = XCAR (Vunread_command_events); | |
2213 Vunread_command_events = XCDR (Vunread_command_events); | |
2214 if (!EVENTP (e) || !command_event_p (e)) | |
563 | 2215 signal_error_1 (Qwrong_type_argument, |
428 | 2216 list3 (Qcommand_event_p, e, Qunread_command_events)); |
853 | 2217 redisplay_no_pre_idle_hook (); |
428 | 2218 if (!EQ (e, event)) |
2219 Fcopy_event (e, event); | |
2220 DEBUG_PRINT_EMACS_EVENT ("unread-command-events", event); | |
2221 } | |
2222 } | |
2223 | |
2224 /* Do similar for unread-command-event (obsoleteness support). */ | |
2225 else if (!NILP (Vunread_command_event)) | |
2226 { | |
2227 Lisp_Object e = Vunread_command_event; | |
2228 Vunread_command_event = Qnil; | |
2229 | |
2230 if (!EVENTP (e) || !command_event_p (e)) | |
2231 { | |
563 | 2232 signal_error_1 (Qwrong_type_argument, |
428 | 2233 list3 (Qeventp, e, Qunread_command_event)); |
2234 } | |
2235 if (!EQ (e, event)) | |
2236 Fcopy_event (e, event); | |
853 | 2237 redisplay_no_pre_idle_hook (); |
428 | 2238 DEBUG_PRINT_EMACS_EVENT ("unread-command-event", event); |
2239 } | |
2240 | |
2241 /* If we're executing a keyboard macro, take the next event from that, | |
2242 and update this-command-keys and recent-keys. | |
2243 Note that the unread-command-events take precedence over kbd macros. | |
2244 */ | |
2245 else | |
2246 { | |
2247 if (!NILP (Vexecuting_macro)) | |
2248 { | |
853 | 2249 redisplay_no_pre_idle_hook (); |
428 | 2250 pop_kbd_macro_event (event); /* This throws past us at |
2251 end-of-macro. */ | |
2252 store_this_key = 1; | |
2253 DEBUG_PRINT_EMACS_EVENT ("keyboard macro", event); | |
2254 } | |
2255 /* Otherwise, read a real event, possibly from the | |
2256 command_event_queue, and update this-command-keys and | |
2257 recent-keys. */ | |
2258 else | |
2259 { | |
2260 redisplay (); | |
2261 next_event_internal (event, 1); | |
2262 store_this_key = 1; | |
2263 } | |
2264 } | |
2265 | |
853 | 2266 /* temporarily reenable quit checking here, because arbitrary lisp |
2267 is executed */ | |
2268 Vquit_flag = Qnil; /* see begin_dont_check_for_quit() */ | |
2269 unbind_to (depth); | |
428 | 2270 status_notify (); /* Notice process change */ |
853 | 2271 depth = begin_dont_check_for_quit (); |
428 | 2272 |
2273 /* Since we can free the most stuff here | |
2274 * (since this is typically called from | |
2275 * the command-loop top-level). */ | |
851 | 2276 if (need_to_check_c_alloca) |
2277 xemacs_c_alloca (0); /* Cause a garbage collection now */ | |
428 | 2278 |
2279 if (object_dead_p (XEVENT (event)->channel)) | |
2280 /* event_console_or_selected may crash if the channel is dead. | |
2281 Best just to eat it and get the next event. */ | |
2282 goto start_over_and_avoid_hosage; | |
2283 | |
2284 /* OK, now we can stop the selected-console kludge and use the | |
2285 actual console from the event. */ | |
2286 con = event_console_or_selected (event); | |
2287 command_builder = XCOMMAND_BUILDER (con->command_builder); | |
2288 | |
2289 switch (XEVENT_TYPE (event)) | |
2290 { | |
2291 case button_release_event: | |
2292 case misc_user_event: | |
2293 /* don't echo menu accelerator keys */ | |
2294 reset_key_echo (command_builder, 1); | |
2295 goto EXECUTE_KEY; | |
2296 case button_press_event: /* key or mouse input can trigger prompting */ | |
2297 goto STORE_AND_EXECUTE_KEY; | |
2298 case key_press_event: /* any key input can trigger autosave */ | |
2299 break; | |
898 | 2300 default: |
2301 goto RETURN; | |
428 | 2302 } |
2303 | |
853 | 2304 /* temporarily reenable quit checking here, because we could get stuck */ |
2305 Vquit_flag = Qnil; /* see begin_dont_check_for_quit() */ | |
2306 unbind_to (depth); | |
428 | 2307 maybe_do_auto_save (); |
853 | 2308 depth = begin_dont_check_for_quit (); |
2309 | |
428 | 2310 num_input_chars++; |
2311 STORE_AND_EXECUTE_KEY: | |
2312 if (store_this_key) | |
2313 { | |
2314 echo_key_event (command_builder, event); | |
2315 } | |
2316 | |
2317 EXECUTE_KEY: | |
2318 /* Store the last-input-event. The semantics of this is that it is | |
2319 the thing most recently returned by next-command-event. It need | |
2320 not have come from the keyboard or a keyboard macro, it may have | |
2321 come from unread-command-events. It's always a command-event (a | |
2322 key, click, or menu selection), never a motion or process event. | |
2323 */ | |
2324 if (!EVENTP (Vlast_input_event)) | |
2325 Vlast_input_event = Fmake_event (Qnil, Qnil); | |
2326 if (XEVENT_TYPE (Vlast_input_event) == dead_event) | |
2327 { | |
2328 Vlast_input_event = Fmake_event (Qnil, Qnil); | |
563 | 2329 invalid_state ("Someone deallocated last-input-event!", Qunbound); |
428 | 2330 } |
2331 if (! EQ (event, Vlast_input_event)) | |
2332 Fcopy_event (event, Vlast_input_event); | |
2333 | |
2334 /* last-input-char and last-input-time are derived from | |
2335 last-input-event. | |
2336 Note that last-input-char will never have its high-bit set, in an | |
2337 effort to sidestep the ambiguity between M-x and oslash. | |
2338 */ | |
2862 | 2339 Vlast_input_char = Fevent_to_character (Vlast_input_event, Qnil, Qnil, Qnil); |
428 | 2340 { |
2341 EMACS_TIME t; | |
2342 EMACS_GET_TIME (t); | |
2343 if (!CONSP (Vlast_input_time)) | |
2344 Vlast_input_time = Fcons (Qnil, Qnil); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2345 XCAR (Vlast_input_time) = make_fixnum ((EMACS_SECS (t) >> 16) & 0xffff); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2346 XCDR (Vlast_input_time) = make_fixnum ((EMACS_SECS (t) >> 0) & 0xffff); |
428 | 2347 if (!CONSP (Vlast_command_event_time)) |
2348 Vlast_command_event_time = list3 (Qnil, Qnil, Qnil); | |
2349 XCAR (Vlast_command_event_time) = | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2350 make_fixnum ((EMACS_SECS (t) >> 16) & 0xffff); |
428 | 2351 XCAR (XCDR (Vlast_command_event_time)) = |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2352 make_fixnum ((EMACS_SECS (t) >> 0) & 0xffff); |
428 | 2353 XCAR (XCDR (XCDR (Vlast_command_event_time))) |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2354 = make_fixnum (EMACS_USECS (t)); |
428 | 2355 } |
2356 /* If this key came from the keyboard or from a keyboard macro, then | |
2357 it goes into the recent-keys and this-command-keys vectors. | |
2358 If this key came from the keyboard, and we're defining a keyboard | |
2359 macro, then it goes into the macro. | |
2360 */ | |
2361 if (store_this_key) | |
2362 { | |
479 | 2363 if (!is_scrollbar_event (event)) /* #### not quite right, see |
2364 comment in execute_command_event */ | |
2365 push_this_command_keys (event); | |
428 | 2366 if (!inhibit_input_event_recording) |
2367 push_recent_keys (event); | |
2368 dribble_out_event (event); | |
2369 if (!NILP (con->defining_kbd_macro) && NILP (Vexecuting_macro)) | |
2370 { | |
2371 if (!EVENTP (command_builder->current_events)) | |
2372 finalize_kbd_macro_chars (con); | |
2373 store_kbd_macro_event (event); | |
2374 } | |
2375 } | |
853 | 2376 /* If this is the help char and there is a help form, then execute |
2377 the help form and swallow this character. Note that | |
2378 execute_help_form() calls Fnext_command_event(), which calls this | |
2379 function, as well as Fdispatch_event. */ | |
428 | 2380 if (!NILP (Vhelp_form) && |
1204 | 2381 event_matches_key_specifier_p (event, Vhelp_char)) |
853 | 2382 { |
2383 /* temporarily reenable quit checking here, because we could get stuck */ | |
2384 Vquit_flag = Qnil; /* see begin_dont_check_for_quit() */ | |
2385 unbind_to (depth); | |
2386 execute_help_form (command_builder, event); | |
2387 depth = begin_dont_check_for_quit (); | |
2388 } | |
428 | 2389 |
2390 RETURN: | |
853 | 2391 Vquit_flag = Qnil; /* see begin_dont_check_for_quit() */ |
2392 unbind_to (depth); | |
2393 | |
1292 | 2394 PROFILE_RECORD_EXITING_SECTION (Qnext_event); |
2395 | |
428 | 2396 UNGCPRO; |
853 | 2397 |
428 | 2398 return event; |
2399 } | |
2400 | |
2401 DEFUN ("next-command-event", Fnext_command_event, 0, 2, 0, /* | |
2402 Return the next available "user" event. | |
2403 Pass this object to `dispatch-event' to handle it. | |
2404 | |
2405 If EVENT is non-nil, it should be an event object and will be filled in | |
2406 and returned; otherwise a new event object will be created and returned. | |
2407 If PROMPT is non-nil, it should be a string and will be displayed in the | |
2408 echo area while this function is waiting for an event. | |
2409 | |
2410 The event returned will be a keyboard, mouse press, or mouse release event. | |
2411 If there are non-command events available (mouse motion, sub-process output, | |
2412 etc) then these will be executed (with `dispatch-event') and discarded. This | |
2413 function is provided as a convenience; it is roughly equivalent to the lisp code | |
2414 | |
2415 (while (progn | |
2416 (next-event event prompt) | |
2417 (not (or (key-press-event-p event) | |
2418 (button-press-event-p event) | |
2419 (button-release-event-p event) | |
2420 (misc-user-event-p event)))) | |
2421 (dispatch-event event)) | |
2422 | |
2423 but it also makes a provision for displaying keystrokes in the echo area. | |
2424 */ | |
2425 (event, prompt)) | |
2426 { | |
2427 /* This function can GC */ | |
2428 struct gcpro gcpro1; | |
2429 GCPRO1 (event); | |
934 | 2430 |
428 | 2431 maybe_echo_keys (XCOMMAND_BUILDER |
2432 (XCONSOLE (Vselected_console)-> | |
5801
0e9f791cc655
Support `function-key-map' in #'read-char{,-exclusive}, sync API with GNU
Aidan Kehoe <kehoea@parhasard.net>
parents:
5736
diff
changeset
|
2433 command_builder), |
0e9f791cc655
Support `function-key-map' in #'read-char{,-exclusive}, sync API with GNU
Aidan Kehoe <kehoea@parhasard.net>
parents:
5736
diff
changeset
|
2434 /* Only snooze displaying keystrokes if we don't have a |
0e9f791cc655
Support `function-key-map' in #'read-char{,-exclusive}, sync API with GNU
Aidan Kehoe <kehoea@parhasard.net>
parents:
5736
diff
changeset
|
2435 prompt. (If we have a prompt, our callers want us to |
0e9f791cc655
Support `function-key-map' in #'read-char{,-exclusive}, sync API with GNU
Aidan Kehoe <kehoea@parhasard.net>
parents:
5736
diff
changeset
|
2436 show it!) */ |
0e9f791cc655
Support `function-key-map' in #'read-char{,-exclusive}, sync API with GNU
Aidan Kehoe <kehoea@parhasard.net>
parents:
5736
diff
changeset
|
2437 !NILP (prompt)); |
853 | 2438 |
428 | 2439 for (;;) |
2440 { | |
2441 event = Fnext_event (event, prompt); | |
2442 if (command_event_p (event)) | |
2443 break; | |
2444 else | |
2445 execute_internal_event (event); | |
2446 } | |
2447 UNGCPRO; | |
2448 return event; | |
2449 } | |
2450 | |
442 | 2451 DEFUN ("dispatch-non-command-events", Fdispatch_non_command_events, 0, 0, 0, /* |
2452 Dispatch any pending "magic" events. | |
2453 | |
2454 This function is useful for forcing the redisplay of native | |
2455 widgets. Normally these are redisplayed through a native window-system | |
2456 event encoded as magic event, rather than by the redisplay code. This | |
2457 function does not call redisplay or do any of the other things that | |
2458 `next-event' does. | |
2459 */ | |
2460 ()) | |
2461 { | |
2462 /* This function can GC */ | |
2463 Lisp_Object event = Qnil; | |
2464 struct gcpro gcpro1; | |
2465 GCPRO1 (event); | |
2466 event = Fmake_event (Qnil, Qnil); | |
2467 | |
2468 /* Make sure that there will be something in the native event queue | |
2469 so that externally managed things (e.g. widgets) get some CPU | |
2470 time. */ | |
2471 event_stream_force_event_pending (selected_frame ()); | |
2472 | |
2473 while (event_stream_event_pending_p (0)) | |
2474 { | |
2475 /* We're a generator of the command_event_queue, so we can't be a | |
2476 consumer as well. Also, we have no reason to consult the | |
2477 command_event_queue; there are only user and eval-events there, | |
2478 and we'd just have to put them back anyway. | |
2479 */ | |
2480 next_event_internal (event, 0); /* blocks */ | |
2481 if (XEVENT_TYPE (event) == magic_event || | |
2482 XEVENT_TYPE (event) == timeout_event || | |
2483 XEVENT_TYPE (event) == process_event || | |
2484 XEVENT_TYPE (event) == pointer_motion_event) | |
2485 execute_internal_event (event); | |
2486 else | |
2487 { | |
2488 enqueue_command_event_1 (event); | |
2489 break; | |
2490 } | |
2491 } | |
2492 | |
2493 Fdeallocate_event (event); | |
2494 UNGCPRO; | |
2495 return Qnil; | |
2496 } | |
2497 | |
428 | 2498 static void |
2499 reset_current_events (struct command_builder *command_builder) | |
2500 { | |
2501 Lisp_Object event = command_builder->current_events; | |
2502 reset_command_builder_event_chain (command_builder); | |
2503 if (EVENTP (event)) | |
2504 deallocate_event_chain (event); | |
2505 } | |
2506 | |
1268 | 2507 static int |
2286 | 2508 command_event_p_cb (Lisp_Object ev, void *UNUSED (the_data)) |
1268 | 2509 { |
2510 return command_event_p (ev); | |
2511 } | |
2512 | |
428 | 2513 DEFUN ("discard-input", Fdiscard_input, 0, 0, 0, /* |
2514 Discard any pending "user" events. | |
2515 Also cancel any kbd macro being defined. | |
2516 A user event is a key press, button press, button release, or | |
2517 "misc-user" event (menu selection or scrollbar action). | |
2518 */ | |
2519 ()) | |
2520 { | |
1318 | 2521 /* This can call Lisp */ |
1268 | 2522 Lisp_Object concons; |
2523 | |
2524 CONSOLE_LOOP (concons) | |
428 | 2525 { |
1268 | 2526 struct console *con = XCONSOLE (XCAR (concons)); |
2527 | |
2528 /* If a macro was being defined then we have to mark the modeline | |
2529 has changed to ensure that it gets updated correctly. */ | |
2530 if (!NILP (con->defining_kbd_macro)) | |
2531 MARK_MODELINE_CHANGED; | |
2532 con->defining_kbd_macro = Qnil; | |
2533 reset_current_events (XCOMMAND_BUILDER (con->command_builder)); | |
428 | 2534 } |
2535 | |
1268 | 2536 /* This function used to be a lot more complicated. Now, we just |
2537 drain the pending queue and discard all user events from the | |
2538 command and dispatch queues. */ | |
2539 event_stream_drain_queue (); | |
2540 | |
2541 map_event_chain_remove (command_event_p_cb, | |
2542 &dispatch_event_queue, &dispatch_event_queue_tail, | |
2543 0, MECR_DEALLOCATE_EVENT); | |
2544 map_event_chain_remove (command_event_p_cb, | |
2545 &command_event_queue, &command_event_queue_tail, | |
2546 0, MECR_DEALLOCATE_EVENT); | |
428 | 2547 |
2548 return Qnil; | |
2549 } | |
2550 | |
2551 | |
2552 /**********************************************************************/ | |
2553 /* pausing until an action occurs */ | |
2554 /**********************************************************************/ | |
2555 | |
2556 /* This is used in accept-process-output, sleep-for and sit-for. | |
2557 Before running any process_events in these routines, we set | |
1268 | 2558 recursive_sit_for to 1, and use this unwind protect to reset it to |
2559 Qnil upon exit. When recursive_sit_for is 1, calling sit-for will | |
428 | 2560 cause it to return immediately. |
2561 | |
2562 All of these routines install timeouts, so we clear the installed | |
2563 timeout as well. | |
2564 | |
2565 Note: It's very easy to break the desired behaviors of these | |
2566 3 routines. If you make any changes to anything in this area, run | |
2567 the regression tests at the bottom of the file. -- dmoore */ | |
2568 | |
2569 | |
2570 static Lisp_Object | |
2571 sit_for_unwind (Lisp_Object timeout_id) | |
2572 { | |
2573 if (!NILP(timeout_id)) | |
2574 Fdisable_timeout (timeout_id); | |
2575 | |
1268 | 2576 recursive_sit_for = 0; |
428 | 2577 return Qnil; |
2578 } | |
2579 | |
2580 /* #### Is (accept-process-output nil 3) supposed to be like (sleep-for 3)? | |
2581 */ | |
2582 | |
2583 DEFUN ("accept-process-output", Faccept_process_output, 0, 3, 0, /* | |
2584 Allow any pending output from subprocesses to be read by Emacs. | |
2585 It is read into the process' buffers or given to their filter functions. | |
2586 Non-nil arg PROCESS means do not return until some output has been received | |
2587 from PROCESS. Nil arg PROCESS means do not return until some output has | |
2588 been received from any process. | |
2589 If the second arg is non-nil, it is the maximum number of seconds to wait: | |
2590 this function will return after that much time even if no input has arrived | |
2591 from PROCESS. This argument may be a float, meaning wait some fractional | |
2592 part of a second. | |
2593 If the third arg is non-nil, it is a number of milliseconds that is added | |
2594 to the second arg. (This exists only for compatibility.) | |
2595 Return non-nil iff we received any output before the timeout expired. | |
2596 */ | |
2597 (process, timeout_secs, timeout_msecs)) | |
2598 { | |
2599 /* This function can GC */ | |
2600 struct gcpro gcpro1, gcpro2; | |
2601 Lisp_Object event = Qnil; | |
2602 Lisp_Object result = Qnil; | |
2603 int timeout_id = -1; | |
2604 int timeout_enabled = 0; | |
2605 int done = 0; | |
2606 struct buffer *old_buffer = current_buffer; | |
2607 int count; | |
2608 | |
2609 /* We preserve the current buffer but nothing else. If a focus | |
2610 change alters the selected window then the top level event loop | |
2611 will eventually alter current_buffer to match. In the mean time | |
2612 we don't want to mess up whatever called this function. */ | |
2613 | |
2614 if (!NILP (process)) | |
2615 CHECK_PROCESS (process); | |
2616 | |
2617 GCPRO2 (event, process); | |
2618 | |
2619 if (!NILP (timeout_secs) || !NILP (timeout_msecs)) | |
2620 { | |
2621 unsigned long msecs = 0; | |
2622 if (!NILP (timeout_secs)) | |
2623 msecs = lisp_number_to_milliseconds (timeout_secs, 1); | |
2624 if (!NILP (timeout_msecs)) | |
2625 { | |
5307
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
2626 check_integer_range (timeout_msecs, Qzero, |
5736
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5722
diff
changeset
|
2627 make_fixnum (MOST_POSITIVE_FIXNUM)); |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2628 msecs += XFIXNUM (timeout_msecs); |
428 | 2629 } |
2630 if (msecs) | |
2631 { | |
2632 timeout_id = event_stream_generate_wakeup (msecs, 0, Qnil, Qnil, 0); | |
2633 timeout_enabled = 1; | |
2634 } | |
2635 } | |
2636 | |
2637 event = Fmake_event (Qnil, Qnil); | |
2638 | |
2639 count = specpdl_depth (); | |
2640 record_unwind_protect (sit_for_unwind, | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2641 timeout_enabled ? make_fixnum (timeout_id) : Qnil); |
1268 | 2642 recursive_sit_for = 1; |
428 | 2643 |
2644 while (!done && | |
2645 ((NILP (process) && timeout_enabled) || | |
2646 (NILP (process) && event_stream_event_pending_p (0)) || | |
2647 (!NILP (process)))) | |
2648 /* Calling detect_input_pending() is the wrong thing here, because | |
2649 that considers the Vunread_command_events and command_event_queue. | |
2650 We don't need to look at the command_event_queue because we are | |
2651 only interested in process events, which don't go on that. In | |
2652 fact, we can't read from it anyway, because we put stuff on it. | |
2653 | |
2654 Note that event_stream->event_pending_p must be called in such | |
2655 a way that it says whether any events *of any kind* are ready, | |
2656 not just user events, or (accept-process-output nil) will fail | |
2657 to dispatch any process events that may be on the queue. It is | |
2658 not clear to me that this is important, because the top-level | |
2659 loop will process it, and I don't think that there is ever a | |
2660 time when one calls accept-process-output with a nil argument | |
2661 and really need the processes to be handled. */ | |
2662 { | |
2663 /* If our timeout has arrived, we move along. */ | |
2664 if (timeout_enabled && !event_stream_wakeup_pending_p (timeout_id, 0)) | |
2665 { | |
2666 timeout_enabled = 0; | |
2667 done = 1; /* We're done. */ | |
2668 continue; /* Don't call next_event_internal */ | |
2669 } | |
2670 | |
2671 next_event_internal (event, 0); | |
2672 switch (XEVENT_TYPE (event)) | |
2673 { | |
2674 case process_event: | |
2675 { | |
2676 if (NILP (process) || | |
1204 | 2677 EQ (XEVENT_PROCESS_PROCESS (event), process)) |
428 | 2678 { |
2679 done = 1; | |
2680 /* RMS's version always returns nil when proc is nil, | |
2681 and only returns t if input ever arrived on proc. */ | |
2682 result = Qt; | |
2683 } | |
2684 | |
2685 execute_internal_event (event); | |
2686 break; | |
2687 } | |
2688 case timeout_event: | |
2689 /* We execute the event even if it's ours, and notice that it's | |
2690 happened above. */ | |
2691 case pointer_motion_event: | |
2692 case magic_event: | |
2693 { | |
2694 execute_internal_event (event); | |
2695 break; | |
2696 } | |
2697 default: | |
2698 { | |
2699 enqueue_command_event_1 (event); | |
2700 break; | |
2701 } | |
2702 } | |
2703 } | |
2704 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2705 unbind_to_1 (count, timeout_enabled ? make_fixnum (timeout_id) : Qnil); |
428 | 2706 |
2707 Fdeallocate_event (event); | |
853 | 2708 |
2709 status_notify (); | |
2710 | |
428 | 2711 UNGCPRO; |
2712 current_buffer = old_buffer; | |
2713 return result; | |
2714 } | |
2715 | |
2716 DEFUN ("sleep-for", Fsleep_for, 1, 1, 0, /* | |
444 | 2717 Pause, without updating display, for SECONDS seconds. |
2718 SECONDS may be a float, allowing pauses for fractional parts of a second. | |
428 | 2719 |
2720 It is recommended that you never call sleep-for from inside of a process | |
444 | 2721 filter function or timer event (either synchronous or asynchronous). |
428 | 2722 */ |
2723 (seconds)) | |
2724 { | |
2725 /* This function can GC */ | |
2726 unsigned long msecs = lisp_number_to_milliseconds (seconds, 1); | |
2727 int id; | |
2728 Lisp_Object event = Qnil; | |
2729 int count; | |
2730 struct gcpro gcpro1; | |
2731 | |
2732 GCPRO1 (event); | |
2733 | |
2734 id = event_stream_generate_wakeup (msecs, 0, Qnil, Qnil, 0); | |
2735 event = Fmake_event (Qnil, Qnil); | |
2736 | |
2737 count = specpdl_depth (); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2738 record_unwind_protect (sit_for_unwind, make_fixnum (id)); |
1268 | 2739 recursive_sit_for = 1; |
428 | 2740 |
2741 while (1) | |
2742 { | |
2743 /* If our timeout has arrived, we move along. */ | |
2744 if (!event_stream_wakeup_pending_p (id, 0)) | |
2745 goto DONE_LABEL; | |
2746 | |
2747 /* We're a generator of the command_event_queue, so we can't be a | |
2748 consumer as well. We don't care about command and eval-events | |
2749 anyway. | |
2750 */ | |
2751 next_event_internal (event, 0); /* blocks */ | |
2752 switch (XEVENT_TYPE (event)) | |
2753 { | |
2754 case timeout_event: | |
2755 /* We execute the event even if it's ours, and notice that it's | |
2756 happened above. */ | |
2757 case process_event: | |
2758 case pointer_motion_event: | |
2759 case magic_event: | |
2760 { | |
2761 execute_internal_event (event); | |
2762 break; | |
2763 } | |
2764 default: | |
2765 { | |
2766 enqueue_command_event_1 (event); | |
2767 break; | |
2768 } | |
2769 } | |
2770 } | |
2771 DONE_LABEL: | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2772 unbind_to_1 (count, make_fixnum (id)); |
428 | 2773 Fdeallocate_event (event); |
2774 UNGCPRO; | |
2775 return Qnil; | |
2776 } | |
2777 | |
2778 DEFUN ("sit-for", Fsit_for, 1, 2, 0, /* | |
444 | 2779 Perform redisplay, then wait SECONDS seconds or until user input is available. |
2780 SECONDS may be a float, meaning a fractional part of a second. | |
2781 Optional second arg NODISPLAY non-nil means don't redisplay; just wait. | |
428 | 2782 Redisplay is preempted as always if user input arrives, and does not |
2783 happen if input is available before it starts. | |
2784 Value is t if waited the full time with no input arriving. | |
2785 | |
2786 If sit-for is called from within a process filter function or timer | |
2787 event (either synchronous or asynchronous) it will return immediately. | |
2788 */ | |
2789 (seconds, nodisplay)) | |
2790 { | |
2791 /* This function can GC */ | |
2792 unsigned long msecs = lisp_number_to_milliseconds (seconds, 1); | |
2793 Lisp_Object event, result; | |
2794 struct gcpro gcpro1; | |
2795 int id; | |
2796 int count; | |
2797 | |
2798 /* The unread-command-events count as pending input */ | |
2799 if (!NILP (Vunread_command_events) || !NILP (Vunread_command_event)) | |
2800 return Qnil; | |
2801 | |
2802 /* If the command-builder already has user-input on it (not eval events) | |
2803 then that means we're done too. | |
2804 */ | |
2805 if (!NILP (command_event_queue)) | |
2806 { | |
2807 EVENT_CHAIN_LOOP (event, command_event_queue) | |
2808 { | |
2809 if (command_event_p (event)) | |
2810 return Qnil; | |
2811 } | |
2812 } | |
2813 | |
2814 /* If we're in a macro, or noninteractive, or early in temacs, then | |
2815 don't wait. */ | |
2816 if (noninteractive || !NILP (Vexecuting_macro)) | |
2817 return Qnil; | |
2818 | |
2819 /* Recursive call from a filter function or timeout handler. */ | |
1268 | 2820 if (recursive_sit_for) |
428 | 2821 { |
2822 if (!event_stream_event_pending_p (1) && NILP (nodisplay)) | |
2823 redisplay (); | |
2824 return Qnil; | |
2825 } | |
2826 | |
2827 | |
2828 /* Otherwise, start reading events from the event_stream. | |
2829 Do this loop at least once even if (sit-for 0) so that we | |
2830 redisplay when no input pending. | |
2831 */ | |
2832 GCPRO1 (event); | |
2833 event = Fmake_event (Qnil, Qnil); | |
2834 | |
2835 /* Generate the wakeup even if MSECS is 0, so that existing timeout/etc. | |
2836 events get processed. The old (pre-19.12) code special-cased this | |
2837 and didn't generate a wakeup, but the resulting behavior was less than | |
2838 ideal; viz. the occurrence of (sit-for 0.001) scattered throughout | |
2839 the E-Lisp universe. */ | |
2840 | |
2841 id = event_stream_generate_wakeup (msecs, 0, Qnil, Qnil, 0); | |
2842 | |
2843 count = specpdl_depth (); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2844 record_unwind_protect (sit_for_unwind, make_fixnum (id)); |
1268 | 2845 recursive_sit_for = 1; |
428 | 2846 |
2847 while (1) | |
2848 { | |
2849 /* If there is no user input pending, then redisplay. | |
2850 */ | |
2851 if (!event_stream_event_pending_p (1) && NILP (nodisplay)) | |
2852 redisplay (); | |
2853 | |
2854 /* If our timeout has arrived, we move along. */ | |
2855 if (!event_stream_wakeup_pending_p (id, 0)) | |
2856 { | |
2857 result = Qt; | |
2858 goto DONE_LABEL; | |
2859 } | |
2860 | |
2861 /* We're a generator of the command_event_queue, so we can't be a | |
2862 consumer as well. In fact, we know there's nothing on the | |
2863 command_event_queue that we didn't just put there. | |
2864 */ | |
2865 next_event_internal (event, 0); /* blocks */ | |
2866 | |
2867 if (command_event_p (event)) | |
2868 { | |
2869 result = Qnil; | |
2870 goto DONE_LABEL; | |
2871 } | |
2872 switch (XEVENT_TYPE (event)) | |
2873 { | |
2874 case eval_event: | |
2875 { | |
2876 /* eval-events get delayed until later. */ | |
2877 enqueue_command_event (Fcopy_event (event, Qnil)); | |
2878 break; | |
2879 } | |
2880 | |
2881 case timeout_event: | |
2882 /* We execute the event even if it's ours, and notice that it's | |
2883 happened above. */ | |
2884 default: | |
2885 { | |
2886 execute_internal_event (event); | |
2887 break; | |
2888 } | |
2889 } | |
2890 } | |
2891 | |
2892 DONE_LABEL: | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2893 unbind_to_1 (count, make_fixnum (id)); |
428 | 2894 |
2895 /* Put back the event (if any) that made Fsit_for() exit before the | |
2896 timeout. Note that it is being added to the back of the queue, which | |
2897 would be inappropriate if there were any user events on the queue | |
2898 already: we would be misordering them. But we know that there are | |
2899 no user-events on the queue, or else we would not have reached this | |
2900 point at all. | |
2901 */ | |
2902 if (NILP (result)) | |
2903 enqueue_command_event (event); | |
2904 else | |
2905 Fdeallocate_event (event); | |
2906 | |
2907 UNGCPRO; | |
2908 return result; | |
2909 } | |
2910 | |
442 | 2911 /* This handy little function is used by select-x.c to wait for replies |
2912 from processes that aren't really processes (e.g. the X server) */ | |
428 | 2913 void |
2914 wait_delaying_user_input (int (*predicate) (void *arg), void *predicate_arg) | |
2915 { | |
2916 /* This function can GC */ | |
2917 Lisp_Object event = Fmake_event (Qnil, Qnil); | |
2918 struct gcpro gcpro1; | |
2919 GCPRO1 (event); | |
2920 | |
2921 while (!(*predicate) (predicate_arg)) | |
2922 { | |
2923 /* We're a generator of the command_event_queue, so we can't be a | |
2924 consumer as well. Also, we have no reason to consult the | |
2925 command_event_queue; there are only user and eval-events there, | |
2926 and we'd just have to put them back anyway. | |
2927 */ | |
2928 next_event_internal (event, 0); | |
2929 if (command_event_p (event) | |
2930 || (XEVENT_TYPE (event) == eval_event) | |
2931 || (XEVENT_TYPE (event) == magic_eval_event)) | |
2932 enqueue_command_event_1 (event); | |
2933 else | |
2934 execute_internal_event (event); | |
2935 } | |
2936 UNGCPRO; | |
2937 } | |
2938 | |
2939 | |
2940 /**********************************************************************/ | |
2941 /* dispatching events; command builder */ | |
2942 /**********************************************************************/ | |
2943 | |
2944 static void | |
2945 execute_internal_event (Lisp_Object event) | |
2946 { | |
1292 | 2947 PROFILE_DECLARE (); |
2948 | |
428 | 2949 /* events on dead channels get silently eaten */ |
2950 if (object_dead_p (XEVENT (event)->channel)) | |
2951 return; | |
2952 | |
1292 | 2953 PROFILE_RECORD_ENTERING_SECTION (QSexecute_internal_event); |
2954 | |
428 | 2955 /* This function can GC */ |
2956 switch (XEVENT_TYPE (event)) | |
2957 { | |
2958 case empty_event: | |
1292 | 2959 goto done; |
428 | 2960 |
2961 case eval_event: | |
2962 { | |
1204 | 2963 call1 (XEVENT_EVAL_FUNCTION (event), |
2964 XEVENT_EVAL_OBJECT (event)); | |
1292 | 2965 goto done; |
428 | 2966 } |
2967 | |
2968 case magic_eval_event: | |
2969 { | |
1204 | 2970 XEVENT_MAGIC_EVAL_INTERNAL_FUNCTION (event) |
2971 XEVENT_MAGIC_EVAL_OBJECT (event); | |
1292 | 2972 goto done; |
428 | 2973 } |
2974 | |
2975 case pointer_motion_event: | |
2976 { | |
2977 if (!NILP (Vmouse_motion_handler)) | |
2978 call1 (Vmouse_motion_handler, event); | |
1292 | 2979 goto done; |
428 | 2980 } |
2981 | |
2982 case process_event: | |
2983 { | |
1204 | 2984 Lisp_Object p = XEVENT_PROCESS_PROCESS (event); |
428 | 2985 Charcount readstatus; |
853 | 2986 int iter; |
2987 | |
2988 assert (PROCESSP (p)); | |
2989 for (iter = 0; iter < 2; iter++) | |
2990 { | |
2991 if (iter == 1 && !process_has_separate_stderr (p)) | |
2992 break; | |
2993 while ((readstatus = read_process_output (p, iter)) > 0) | |
2994 ; | |
2995 if (readstatus > 0) | |
2996 ; /* this clauses never gets executed but | |
2997 allows the #ifdefs to work cleanly. */ | |
428 | 2998 #ifdef EWOULDBLOCK |
853 | 2999 else if (readstatus == -1 && errno == EWOULDBLOCK) |
3000 ; | |
428 | 3001 #endif /* EWOULDBLOCK */ |
3002 #ifdef EAGAIN | |
853 | 3003 else if (readstatus == -1 && errno == EAGAIN) |
3004 ; | |
428 | 3005 #endif /* EAGAIN */ |
853 | 3006 else if ((readstatus == 0 && |
3007 /* Note that we cannot distinguish between no input | |
3008 available now and a closed pipe. | |
3009 With luck, a closed pipe will be accompanied by | |
3010 subprocess termination and SIGCHLD. */ | |
3011 (!network_connection_p (p) || | |
3012 /* | |
3013 When connected to ToolTalk (i.e. | |
3014 connected_via_filedesc_p()), it's not possible to | |
3015 reliably determine whether there is a message | |
3016 waiting for ToolTalk to receive. ToolTalk expects | |
3017 to have tt_message_receive() called exactly once | |
3018 every time the file descriptor becomes active, so | |
3019 the filter function forces this by returning 0. | |
3020 Emacs must not interpret this as a closed pipe. */ | |
3021 connected_via_filedesc_p (XPROCESS (p)))) | |
3022 | |
3023 /* On some OSs with ptys, when the process on one end of | |
3024 a pty exits, the other end gets an error reading with | |
3025 errno = EIO instead of getting an EOF (0 bytes read). | |
3026 Therefore, if we get an error reading and errno = | |
3027 EIO, just continue, because the child process has | |
3028 exited and should clean itself up soon (e.g. when we | |
3029 get a SIGCHLD). */ | |
535 | 3030 #ifdef EIO |
853 | 3031 || (readstatus == -1 && errno == EIO) |
428 | 3032 #endif |
535 | 3033 |
853 | 3034 ) |
3035 { | |
3036 /* Currently, we rely on SIGCHLD to indicate that the | |
3037 process has terminated. Unfortunately, on some systems | |
3038 the SIGCHLD gets missed some of the time. So we put an | |
3039 additional check in status_notify() to see whether a | |
3040 process has terminated. We must tell status_notify() | |
3041 to enable that check, and we do so now. */ | |
3042 kick_status_notify (); | |
3043 } | |
898 | 3044 else |
3045 { | |
3046 /* Deactivate network connection */ | |
3047 Lisp_Object status = Fprocess_status (p); | |
3048 if (EQ (status, Qopen) | |
3049 /* In case somebody changes the theory of whether to | |
3050 return open as opposed to run for network connection | |
3051 "processes"... */ | |
3052 || EQ (status, Qrun)) | |
3053 update_process_status (p, Qexit, 256, 0); | |
3054 deactivate_process (p); | |
3055 status_notify (); | |
3056 } | |
853 | 3057 |
3058 /* We must call status_notify here to allow the | |
3059 event_stream->unselect_process_cb to be run if appropriate. | |
3060 Otherwise, dead fds may be selected for, and we will get a | |
3061 continuous stream of process events for them. Since we don't | |
3062 return until all process events have been flushed, we would | |
3063 get stuck here, processing events on a process whose status | |
3025 | 3064 was `exit'. Call this after dispatch-event, or the fds will |
853 | 3065 have been closed before we read the last data from them. |
3066 It's safe for the filter to signal an error because | |
3067 status_notify() will be called on return to top-level. | |
3068 */ | |
3069 status_notify (); | |
428 | 3070 } |
1292 | 3071 goto done; |
428 | 3072 } |
3073 | |
3074 case timeout_event: | |
3075 { | |
440 | 3076 Lisp_Event *e = XEVENT (event); |
934 | 3077 |
1204 | 3078 if (!NILP (EVENT_TIMEOUT_FUNCTION (e))) |
3079 call1 (EVENT_TIMEOUT_FUNCTION (e), | |
3080 EVENT_TIMEOUT_OBJECT (e)); | |
1292 | 3081 goto done; |
428 | 3082 } |
3083 case magic_event: | |
3084 event_stream_handle_magic_event (XEVENT (event)); | |
1292 | 3085 goto done; |
428 | 3086 default: |
2500 | 3087 ABORT (); |
428 | 3088 } |
1292 | 3089 |
3090 done: | |
3091 PROFILE_RECORD_EXITING_SECTION (QSexecute_internal_event); | |
428 | 3092 } |
3093 | |
3094 | |
3095 | |
3096 static void | |
3097 this_command_keys_replace_suffix (Lisp_Object suffix, Lisp_Object chain) | |
3098 { | |
3099 Lisp_Object first_before_suffix = | |
3100 event_chain_find_previous (Vthis_command_keys, suffix); | |
3101 | |
3102 if (NILP (first_before_suffix)) | |
3103 Vthis_command_keys = chain; | |
3104 else | |
3105 XSET_EVENT_NEXT (first_before_suffix, chain); | |
3106 deallocate_event_chain (suffix); | |
3107 Vthis_command_keys_tail = event_chain_tail (chain); | |
3108 } | |
3109 | |
3110 static void | |
3111 command_builder_replace_suffix (struct command_builder *builder, | |
3112 Lisp_Object suffix, Lisp_Object chain) | |
3113 { | |
3114 Lisp_Object first_before_suffix = | |
3115 event_chain_find_previous (builder->current_events, suffix); | |
3116 | |
3117 if (NILP (first_before_suffix)) | |
3118 builder->current_events = chain; | |
3119 else | |
3120 XSET_EVENT_NEXT (first_before_suffix, chain); | |
3121 deallocate_event_chain (suffix); | |
3122 builder->most_current_event = event_chain_tail (chain); | |
3123 } | |
3124 | |
3125 static Lisp_Object | |
3126 command_builder_find_leaf_1 (struct command_builder *builder) | |
3127 { | |
3128 Lisp_Object event0 = builder->current_events; | |
3129 | |
3130 if (NILP (event0)) | |
3131 return Qnil; | |
3132 | |
3133 return event_binding (event0, 1); | |
3134 } | |
3135 | |
1268 | 3136 static void |
3137 maybe_kbd_translate (Lisp_Object event) | |
3138 { | |
3139 Ichar c; | |
3140 int did_translate = 0; | |
3141 | |
3142 if (XEVENT_TYPE (event) != key_press_event) | |
3143 return; | |
3144 if (!HASH_TABLEP (Vkeyboard_translate_table)) | |
3145 return; | |
3146 if (EQ (Fhash_table_count (Vkeyboard_translate_table), Qzero)) | |
3147 return; | |
3148 | |
2828 | 3149 c = event_to_character (event, 0, 0); |
1268 | 3150 if (c != -1) |
3151 { | |
3152 Lisp_Object traduit = Fgethash (make_char (c), Vkeyboard_translate_table, | |
3153 Qnil); | |
3154 if (!NILP (traduit) && SYMBOLP (traduit)) | |
3155 { | |
3156 XSET_EVENT_KEY_KEYSYM (event, traduit); | |
3157 XSET_EVENT_KEY_MODIFIERS (event, 0); | |
3158 did_translate = 1; | |
3159 } | |
3160 else if (CHARP (traduit)) | |
3161 { | |
3162 /* This used to call Fcharacter_to_event() directly into EVENT, | |
3163 but that can eradicate timestamps and other such stuff. | |
3164 This way is safer. */ | |
3165 Lisp_Object ev2 = Fmake_event (Qnil, Qnil); | |
3166 | |
3167 character_to_event (XCHAR (traduit), XEVENT (ev2), | |
4780
2fd201d73a92
Call character_to_event on characters received from XIM, event-Xt.c
Aidan Kehoe <kehoea@parhasard.net>
parents:
4775
diff
changeset
|
3168 XCONSOLE (XEVENT_CHANNEL (event)), |
2fd201d73a92
Call character_to_event on characters received from XIM, event-Xt.c
Aidan Kehoe <kehoea@parhasard.net>
parents:
4775
diff
changeset
|
3169 high_bit_is_meta, 1); |
1268 | 3170 XSET_EVENT_KEY_KEYSYM (event, XEVENT_KEY_KEYSYM (ev2)); |
3171 XSET_EVENT_KEY_MODIFIERS (event, XEVENT_KEY_MODIFIERS (ev2)); | |
3172 Fdeallocate_event (ev2); | |
3173 did_translate = 1; | |
3174 } | |
3175 } | |
3176 | |
3177 if (!did_translate) | |
3178 { | |
3179 Lisp_Object traduit = Fgethash (XEVENT_KEY_KEYSYM (event), | |
3180 Vkeyboard_translate_table, Qnil); | |
3181 if (!NILP (traduit) && SYMBOLP (traduit)) | |
3182 { | |
3183 XSET_EVENT_KEY_KEYSYM (event, traduit); | |
3184 did_translate = 1; | |
3185 } | |
3186 else if (CHARP (traduit)) | |
3187 { | |
3188 /* This used to call Fcharacter_to_event() directly into EVENT, | |
3189 but that can eradicate timestamps and other such stuff. | |
3190 This way is safer. */ | |
3191 Lisp_Object ev2 = Fmake_event (Qnil, Qnil); | |
3192 | |
3193 character_to_event (XCHAR (traduit), XEVENT (ev2), | |
4780
2fd201d73a92
Call character_to_event on characters received from XIM, event-Xt.c
Aidan Kehoe <kehoea@parhasard.net>
parents:
4775
diff
changeset
|
3194 XCONSOLE (XEVENT_CHANNEL (event)), |
2fd201d73a92
Call character_to_event on characters received from XIM, event-Xt.c
Aidan Kehoe <kehoea@parhasard.net>
parents:
4775
diff
changeset
|
3195 high_bit_is_meta, 1); |
1268 | 3196 XSET_EVENT_KEY_KEYSYM (event, XEVENT_KEY_KEYSYM (ev2)); |
3197 XSET_EVENT_KEY_MODIFIERS (event, | |
3198 XEVENT_KEY_MODIFIERS (event) | | |
3199 XEVENT_KEY_MODIFIERS (ev2)); | |
3200 | |
3201 Fdeallocate_event (ev2); | |
3202 did_translate = 1; | |
3203 } | |
3204 } | |
3205 | |
3206 #ifdef DEBUG_XEMACS | |
3207 if (did_translate) | |
3208 DEBUG_PRINT_EMACS_EVENT ("->keyboard-translate-table", event); | |
3209 #endif | |
3210 } | |
3211 | |
428 | 3212 /* See if we can do function-key-map or key-translation-map translation |
3213 on the current events in the command builder. If so, do this, and | |
771 | 3214 return the resulting binding, if any. |
3215 | |
3216 DID_MUNGE must be initialized before calling this function. If munging | |
3217 happened, DID_MUNGE will be non-zero; otherwise, it will be left alone. | |
3218 */ | |
428 | 3219 |
3220 static Lisp_Object | |
3221 munge_keymap_translate (struct command_builder *builder, | |
3222 enum munge_me_out_the_door munge, | |
771 | 3223 int has_normal_binding_p, int *did_munge) |
428 | 3224 { |
3225 Lisp_Object suffix; | |
3226 | |
1204 | 3227 EVENT_CHAIN_LOOP (suffix, builder->first_mungeable_event[munge]) |
428 | 3228 { |
3229 Lisp_Object result = munging_key_map_event_binding (suffix, munge); | |
3230 | |
3231 if (NILP (result)) | |
3232 continue; | |
3233 | |
3234 if (KEYMAPP (result)) | |
3235 { | |
3236 if (NILP (builder->last_non_munged_event) | |
3237 && !has_normal_binding_p) | |
3238 builder->last_non_munged_event = builder->most_current_event; | |
3239 } | |
3240 else | |
3241 builder->last_non_munged_event = Qnil; | |
3242 | |
3243 if (!KEYMAPP (result) && | |
3244 !VECTORP (result) && | |
3245 !STRINGP (result)) | |
3246 { | |
3247 struct gcpro gcpro1; | |
3248 GCPRO1 (suffix); | |
3249 result = call1 (result, Qnil); | |
3250 UNGCPRO; | |
3251 if (NILP (result)) | |
3252 return Qnil; | |
3253 } | |
3254 | |
3255 if (KEYMAPP (result)) | |
3256 return result; | |
3257 | |
3258 if (VECTORP (result) || STRINGP (result)) | |
3259 { | |
3260 Lisp_Object new_chain = key_sequence_to_event_chain (result); | |
3261 Lisp_Object tempev; | |
3262 | |
3263 /* If the first_mungeable_event of the other munger is | |
3264 within the events we're munging, then it will point to | |
3265 deallocated events afterwards, which is bad -- so make it | |
3266 point at the beginning of the munged events. */ | |
3267 EVENT_CHAIN_LOOP (tempev, suffix) | |
3268 { | |
3269 Lisp_Object *mungeable_event = | |
1204 | 3270 &builder->first_mungeable_event[1 - munge]; |
428 | 3271 if (EQ (tempev, *mungeable_event)) |
3272 { | |
3273 *mungeable_event = new_chain; | |
3274 break; | |
3275 } | |
3276 } | |
3277 | |
771 | 3278 /* Now munge the current event chain in the command builder. */ |
428 | 3279 command_builder_replace_suffix (builder, suffix, new_chain); |
1204 | 3280 builder->first_mungeable_event[munge] = Qnil; |
771 | 3281 |
3282 *did_munge = 1; | |
428 | 3283 |
793 | 3284 return command_builder_find_leaf_1 (builder); |
428 | 3285 } |
3286 | |
563 | 3287 signal_error (Qinvalid_key_binding, |
3288 (munge == MUNGE_ME_FUNCTION_KEY ? | |
3289 "Invalid binding in function-key-map" : | |
3290 "Invalid binding in key-translation-map"), | |
3291 result); | |
428 | 3292 } |
3293 | |
3294 return Qnil; | |
3295 } | |
3296 | |
2828 | 3297 /* Same as command_builder_find_leaf() below, but without offering the |
3298 platform-specific event code the opportunity to give a default binding of | |
3299 an unseen keysym to self-insert-command, and without the fallback to | |
3300 other keymaps for lookups that allows someone with a Cyrillic keyboard | |
3301 to pretend it's Qwerty for C-x C-f, for example. */ | |
771 | 3302 |
428 | 3303 static Lisp_Object |
2828 | 3304 command_builder_find_leaf_no_jit_binding (struct command_builder *builder, |
771 | 3305 int allow_misc_user_events_p, |
3306 int *did_munge) | |
428 | 3307 { |
3308 /* This function can GC */ | |
3309 Lisp_Object result; | |
3310 Lisp_Object evee = builder->current_events; | |
3311 | |
3312 if (XEVENT_TYPE (evee) == misc_user_event) | |
3313 { | |
3314 if (allow_misc_user_events_p && (NILP (XEVENT_NEXT (evee)))) | |
1204 | 3315 return list2 (XEVENT_EVAL_FUNCTION (evee), |
3316 XEVENT_EVAL_OBJECT (evee)); | |
428 | 3317 else |
3318 return Qnil; | |
3319 } | |
3320 | |
442 | 3321 /* if we're currently in a menu accelerator, check there for further |
3322 events */ | |
3323 /* #### fuck me! who wrote this crap? think "abstraction", baby. */ | |
771 | 3324 /* #### this horribly-written crap can mess with global state, which |
3325 this function should not do. i'm not fixing it now. someone | |
3326 needs to go and rewrite that shit correctly. --ben */ | |
1268 | 3327 #if defined (HAVE_X_WINDOWS) && defined (LWLIB_MENUBARS_LUCID) |
442 | 3328 if (x_kludge_lw_menu_active ()) |
428 | 3329 { |
3330 return command_builder_operate_menu_accelerator (builder); | |
3331 } | |
3332 else | |
3333 { | |
3334 result = Qnil; | |
3335 if (EQ (Vmenu_accelerator_enabled, Qmenu_force)) | |
3336 result = command_builder_find_menu_accelerator (builder); | |
3337 if (NILP (result)) | |
3338 #endif | |
3339 result = command_builder_find_leaf_1 (builder); | |
1268 | 3340 #if defined (HAVE_X_WINDOWS) && defined (LWLIB_MENUBARS_LUCID) |
428 | 3341 if (NILP (result) |
3342 && EQ (Vmenu_accelerator_enabled, Qmenu_fallback)) | |
3343 result = command_builder_find_menu_accelerator (builder); | |
3344 } | |
3345 #endif | |
3346 | |
3347 /* Check to see if we have a potential function-key-map match. */ | |
3348 if (NILP (result)) | |
771 | 3349 result = munge_keymap_translate (builder, MUNGE_ME_FUNCTION_KEY, 0, |
3350 did_munge); | |
3351 | |
428 | 3352 /* Check to see if we have a potential key-translation-map match. */ |
3353 { | |
3354 Lisp_Object key_translate_result = | |
3355 munge_keymap_translate (builder, MUNGE_ME_KEY_TRANSLATION, | |
771 | 3356 !NILP (result), did_munge); |
428 | 3357 if (!NILP (key_translate_result)) |
771 | 3358 result = key_translate_result; |
428 | 3359 } |
3360 | |
3361 if (!NILP (result)) | |
3362 return result; | |
3363 | |
3364 /* If key-sequence wasn't bound, we'll try some fallbacks. */ | |
3365 | |
3366 /* If we didn't find a binding, and the last event in the sequence is | |
3367 a shifted character, then try again with the lowercase version. */ | |
3368 | |
3369 if (XEVENT_TYPE (builder->most_current_event) == key_press_event | |
3370 && !NILP (Vretry_undefined_key_binding_unshifted)) | |
3371 { | |
1204 | 3372 if (event_upshifted_p (builder->most_current_event)) |
428 | 3373 { |
771 | 3374 Lisp_Object neubauten = copy_command_builder (builder, 0); |
3375 struct command_builder *neub = XCOMMAND_BUILDER (neubauten); | |
3376 struct gcpro gcpro1; | |
3377 | |
3378 GCPRO1 (neubauten); | |
1204 | 3379 downshift_event (event_chain_tail (neub->current_events)); |
771 | 3380 result = |
2828 | 3381 command_builder_find_leaf_no_jit_binding |
771 | 3382 (neub, allow_misc_user_events_p, did_munge); |
3383 | |
428 | 3384 if (!NILP (result)) |
771 | 3385 { |
3386 copy_command_builder (neub, builder); | |
3387 *did_munge = 1; | |
3388 } | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
3389 free_normal_lisp_object (wrap_command_builder (neub)); |
771 | 3390 UNGCPRO; |
3391 if (!NILP (result)) | |
428 | 3392 return result; |
3393 } | |
3394 } | |
3395 | |
3396 /* help-char is `auto-bound' in every keymap */ | |
3397 if (!NILP (Vprefix_help_command) && | |
1204 | 3398 event_matches_key_specifier_p (builder->most_current_event, Vhelp_char)) |
428 | 3399 return Vprefix_help_command; |
3400 | |
771 | 3401 return Qnil; |
3402 } | |
3403 | |
3404 /* Compare the current state of the command builder against the local and | |
3405 global keymaps, and return the binding. If there is no match, try again, | |
3406 case-insensitively. The return value will be one of: | |
3407 -- nil (there is no binding) | |
3408 -- a keymap (part of a command has been specified) | |
3409 -- a command (anything that satisfies `commandp'; this includes | |
3410 some symbols, lists, subrs, strings, vectors, and | |
3411 compiled-function objects) | |
3412 | |
3413 This may "munge" the current event chain in the command builder; | |
3414 i.e. the sequence might be mutated into a different sequence, | |
3415 which we then pretend is what the user actually typed instead of | |
3416 the passed-in sequence. This happens as a result of: | |
3417 | |
3418 -- key-translation-map changes | |
3419 -- function-key-map changes | |
3420 -- retry-undefined-key-binding-unshifted (q.v.) | |
3421 -- "Russian C-x problem" changes (see definition of struct key_data, | |
3422 events.h) | |
3423 | |
3424 DID_MUNGE must be initialized before calling this function. If munging | |
3425 happened, DID_MUNGE will be non-zero; otherwise, it will be left alone. | |
2828 | 3426 |
3427 (The above was Ben, I think.) | |
3428 | |
3429 It might be nice to have lookup-key call this function, directly or | |
3430 indirectly. Though it is arguably the right thing if lookup-key fails on | |
3431 a keysym that the X11 event code hasn't seen. There's no way to know if | |
3432 that keysym is generatable by the keyboard until it's generated, | |
3433 therefore there's no reasonable expectation that it be bound before it's | |
3434 generated--all the other default bindings depend on our knowing the | |
3435 keyboard layout and relying on it. And describe-key works without it, so | |
3436 I think we're fine. | |
3437 | |
3438 Some weirdness with this code--try this on a keyboard where X11 will | |
3439 produce ediaeresis with dead-diaeresis and e, but it's not produced by | |
3440 any other combination of keys on the keyboard; | |
3441 | |
3442 (defun ding-command () | |
3443 (interactive) | |
3444 (ding)) | |
3445 | |
3446 (define-key global-map 'ediaeresis 'ding-command) | |
3447 | |
3448 Now, pressing dead-diaeresis and then e will ding. Next; | |
3449 | |
3450 (define-key global-map 'ediaeresis 'self-insert-command) | |
3451 | |
3452 and press dead-diaeresis and then e. It'll give you "Invalid argument: | |
3453 typed key has no ASCII equivalent" Then; | |
3454 | |
3455 (define-key global-map 'ediaeresis nil) | |
3456 | |
3457 and press the combination again; it'll self-insert. The moral of the | |
3458 story is, if you want to suppress all bindings to a non-ASCII X11 key, | |
3459 bind it to a trivial no-op command, because the automatic mapping to | |
3460 self-insert-command will happen if there's no existing binding for the | |
3461 symbol. I can't see a way around this. -- Aidan Kehoe, 2005-05-14 */ | |
771 | 3462 |
3463 static Lisp_Object | |
3464 command_builder_find_leaf (struct command_builder *builder, | |
3465 int allow_misc_user_events_p, | |
3466 int *did_munge) | |
3467 { | |
3468 Lisp_Object result = | |
2828 | 3469 command_builder_find_leaf_no_jit_binding |
771 | 3470 (builder, allow_misc_user_events_p, did_munge); |
2828 | 3471 Lisp_Object event, console, channel, lookup_res; |
3472 int redolookup = 0, i; | |
771 | 3473 |
3474 if (!NILP (result)) | |
3475 return result; | |
3476 | |
2828 | 3477 /* If some of the events are keyboard events, and this is the first time |
3478 the platform event code has seen their keysyms--which will be the case | |
3479 the first time we see a composed keysym on X11, for example--offer it | |
3480 the chance to define them as a self-insert-command, and do the lookup | |
3481 again. | |
3482 | |
3483 This isn't Mule-specific; in a world where x-iso8859-1.el is gone, it's | |
3484 needed for non-Mule too. | |
3485 | |
3486 Probably this can just be limited to the checking the last | |
3487 keypress. */ | |
3488 | |
3489 EVENT_CHAIN_LOOP (event, builder->current_events) | |
3490 { | |
3491 /* We can ignore key release events because the preceding presses will | |
3492 have initiated the mapping. */ | |
3493 if (key_press_event != XEVENT_TYPE (event)) | |
3494 continue; | |
3495 | |
3496 channel = XEVENT_CHANNEL (event); | |
3497 if (object_dead_p (channel)) | |
3498 continue; | |
3499 | |
3500 console = CDFW_CONSOLE (channel); | |
3501 if (NILP (console)) | |
3502 console = Vselected_console; | |
3503 | |
3504 if (CONSOLE_LIVE_P(XCONSOLE(console))) | |
3505 { | |
3506 lookup_res = MAYBE_LISP_CONMETH(XCONSOLE(console), | |
3507 perhaps_init_unseen_key_defaults, | |
3508 (XCONSOLE(console), | |
3509 XEVENT_KEY_KEYSYM(event))); | |
3510 if (EQ(lookup_res, Qt)) | |
3511 { | |
3512 redolookup += 1; | |
3513 } | |
3514 } | |
3515 } | |
3516 | |
3517 if (redolookup) | |
428 | 3518 { |
2828 | 3519 result = command_builder_find_leaf_no_jit_binding |
3520 (builder, allow_misc_user_events_p, did_munge); | |
3521 if (!NILP (result)) | |
3522 { | |
3523 return result; | |
3524 } | |
3525 } | |
3526 | |
3527 /* The old composed-character-default-binding handling that used to be | |
3528 here was wrong--if a user wants to bind a given key to something other | |
3529 than self-insert-command, then they should go ahead and do it, we won't | |
3530 override it, and the sane thing to do with any key that has a known | |
3531 character correspondence is _always_ to default it to | |
3532 self-insert-command, nothing else. | |
3533 | |
3534 I'm adding the variable to control whether "Russian C-x processing" is | |
3535 used because I have a feeling that it's not always the most appropriate | |
3536 thing to do--in cases where people are using a non-Qwerty | |
3537 Roman-alphabet layout, do they really want C-x with some random letter | |
3538 to call `switch-to-buffer'? I can imagine that being very confusing, | |
3539 certainly for new users, and it might be that defaulting the value for | |
3540 `try-alternate-layouts-for-commands' as part of the language | |
3541 environment is the right thing to do, only defaulting to `t' for those | |
3542 languages that don't use the Roman alphabet. | |
3543 | |
3544 Much of that reasoning is tentative on my part, and feel free to change | |
3545 this code if you have more experience with the problem and an intuition | |
3546 that differs from mine. (Aidan Kehoe, 2005-05-29)*/ | |
3547 | |
3548 if (!try_alternate_layouts_for_commands) | |
3549 { | |
3550 return Qnil; | |
428 | 3551 } |
2828 | 3552 |
3553 if (key_press_event == XEVENT_TYPE (builder->most_current_event)) | |
3554 { | |
3555 Lisp_Object ev = builder->most_current_event, newbuilder; | |
3556 Ichar this_alternative; | |
3557 | |
3558 struct command_builder *newb; | |
3559 struct gcpro gcpro1; | |
3560 | |
3561 /* Ignore the value for CURRENT_LANGENV, because we've checked it | |
3562 already, above. */ | |
3563 for (i = KEYCHAR_CURRENT_LANGENV, ++i; i < KEYCHAR_LAST; ++i) | |
3564 { | |
3565 this_alternative = XEVENT_KEY_ALT_KEYCHARS(ev, i); | |
3566 | |
3567 if (0 == this_alternative) | |
3568 continue; | |
3569 | |
3570 newbuilder = copy_command_builder(builder, 0); | |
3571 GCPRO1(newbuilder); | |
3572 | |
3573 newb = XCOMMAND_BUILDER(newbuilder); | |
3574 | |
2830 | 3575 XSET_EVENT_KEY_KEYSYM(event_chain_tail |
3576 (XCOMMAND_BUILDER(newbuilder)->current_events), | |
2828 | 3577 make_char(this_alternative)); |
3578 | |
3579 result = command_builder_find_leaf_no_jit_binding | |
3580 (newb, allow_misc_user_events_p, did_munge); | |
3581 | |
3582 if (!NILP (result)) | |
3583 { | |
3584 copy_command_builder (newb, builder); | |
3585 *did_munge = 1; | |
3586 } | |
2830 | 3587 else if (event_upshifted_p |
3588 (XCOMMAND_BUILDER(newbuilder)->most_current_event) && | |
2828 | 3589 !NILP (Vretry_undefined_key_binding_unshifted) |
3590 && isascii(this_alternative)) | |
3591 { | |
2830 | 3592 downshift_event (event_chain_tail |
3593 (XCOMMAND_BUILDER(newbuilder)->current_events)); | |
3594 XSET_EVENT_KEY_KEYSYM(event_chain_tail | |
3595 (newb->current_events), | |
2828 | 3596 make_char(tolower(this_alternative))); |
3597 result = command_builder_find_leaf_no_jit_binding | |
3598 (newb, allow_misc_user_events_p, did_munge); | |
3599 } | |
3600 | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
3601 free_normal_lisp_object (wrap_command_builder (newb)); |
2828 | 3602 UNGCPRO; |
3603 | |
3604 if (!NILP (result)) | |
3605 return result; | |
3606 } | |
3607 } | |
428 | 3608 |
3609 return Qnil; | |
3610 } | |
3611 | |
771 | 3612 /* Like command_builder_find_leaf but update this-command-keys and the |
3613 echo area as necessary when the current event chain was munged. */ | |
3614 | |
3615 static Lisp_Object | |
3616 command_builder_find_leaf_and_update_global_state (struct command_builder * | |
3617 builder, | |
3618 int | |
3619 allow_misc_user_events_p) | |
3620 { | |
3621 int did_munge = 0; | |
3622 int orig_length = event_chain_count (builder->current_events); | |
3623 Lisp_Object result = command_builder_find_leaf (builder, | |
3624 allow_misc_user_events_p, | |
3625 &did_munge); | |
3626 | |
3627 if (did_munge) | |
3628 { | |
3629 int tck_length = event_chain_count (Vthis_command_keys); | |
3630 | |
3631 /* We just assume that the events we just replaced are | |
3632 sitting in copied form at the end of this-command-keys. | |
3633 If the user did weird things with `dispatch-event' this | |
3634 may not be the case, but at least we make sure we won't | |
3635 crash. */ | |
3636 | |
3637 if (tck_length >= orig_length) | |
3638 { | |
3639 Lisp_Object new_chain = | |
3640 copy_event_chain (builder->current_events); | |
3641 this_command_keys_replace_suffix | |
3642 (event_chain_nth (Vthis_command_keys, tck_length - orig_length), | |
3643 new_chain); | |
3644 | |
3645 regenerate_echo_keys_from_this_command_keys (builder); | |
3646 } | |
3647 } | |
3648 | |
3649 if (NILP (result)) | |
3650 { | |
3651 /* If we read extra events attempting to match a function key but end | |
3652 up failing, then we release those events back to the command loop | |
3653 and fail on the original lookup. The released events will then be | |
3654 reprocessed in the context of the first part having failed. */ | |
3655 if (!NILP (builder->last_non_munged_event)) | |
3656 { | |
3657 Lisp_Object event0 = builder->last_non_munged_event; | |
3658 | |
3659 /* Put the commands back on the event queue. */ | |
3660 enqueue_event_chain (XEVENT_NEXT (event0), | |
3661 &command_event_queue, | |
3662 &command_event_queue_tail); | |
3663 | |
3664 /* Then remove them from the command builder. */ | |
3665 XSET_EVENT_NEXT (event0, Qnil); | |
3666 builder->most_current_event = event0; | |
3667 builder->last_non_munged_event = Qnil; | |
3668 } | |
3669 } | |
3670 | |
3671 return result; | |
3672 } | |
428 | 3673 |
3674 /* Every time a command-event (a key, button, or menu selection) is read by | |
3675 Fnext_event(), it is stored in the recent_keys_ring, in Vlast_input_event, | |
3676 and in Vthis_command_keys. (Eval-events are not stored there.) | |
3677 | |
3678 Every time a command is invoked, Vlast_command_event is set to the last | |
3679 event in the sequence. | |
3680 | |
3681 This means that Vthis_command_keys is really about "input read since the | |
3682 last command was executed" rather than about "what keys invoked this | |
3683 command." This is a little counterintuitive, but that's the way it | |
3684 has always worked. | |
3685 | |
3686 As an extra kink, the function read-key-sequence resets/updates the | |
3687 last-command-event and this-command-keys. It doesn't append to the | |
3688 command-keys as read-char does. Such are the pitfalls of having to | |
3689 maintain compatibility with a program for which the only specification | |
3690 is the code itself. | |
3691 | |
3692 (We could implement recent_keys_ring and Vthis_command_keys as the same | |
3693 data structure.) | |
3694 */ | |
3695 | |
3696 DEFUN ("recent-keys", Frecent_keys, 0, 1, 0, /* | |
3697 Return a vector of recent keyboard or mouse button events read. | |
3698 If NUMBER is non-nil, not more than NUMBER events will be returned. | |
3699 Change number of events stored using `set-recent-keys-ring-size'. | |
3700 | |
3701 This copies the event objects into a new vector; it is safe to keep and | |
3702 modify them. | |
3703 */ | |
3704 (number)) | |
3705 { | |
3706 struct gcpro gcpro1; | |
3707 Lisp_Object val = Qnil; | |
3708 int nwanted; | |
3709 int start, nkeys, i, j; | |
3710 GCPRO1 (val); | |
3711 | |
3712 if (NILP (number)) | |
3713 nwanted = recent_keys_ring_size; | |
3714 else | |
3715 { | |
5307
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
3716 check_integer_range (number, Qzero, |
5736
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5722
diff
changeset
|
3717 make_fixnum (ARRAY_DIMENSION_LIMIT)); |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3718 nwanted = XFIXNUM (number); |
428 | 3719 } |
3720 | |
3721 /* Create the keys ring vector, if none present. */ | |
3722 if (NILP (Vrecent_keys_ring)) | |
3723 { | |
3724 Vrecent_keys_ring = make_vector (recent_keys_ring_size, Qnil); | |
3725 /* And return nothing in particular. */ | |
446 | 3726 RETURN_UNGCPRO (make_vector (0, Qnil)); |
428 | 3727 } |
3728 | |
3729 if (NILP (XVECTOR_DATA (Vrecent_keys_ring)[recent_keys_ring_index])) | |
3730 /* This means the vector has not yet wrapped */ | |
3731 { | |
3732 nkeys = recent_keys_ring_index; | |
3733 start = 0; | |
3734 } | |
3735 else | |
3736 { | |
3737 nkeys = recent_keys_ring_size; | |
3738 start = ((recent_keys_ring_index == nkeys) ? 0 : recent_keys_ring_index); | |
3739 } | |
3740 | |
3741 if (nwanted < nkeys) | |
3742 { | |
3743 start += nkeys - nwanted; | |
3744 if (start >= recent_keys_ring_size) | |
3745 start -= recent_keys_ring_size; | |
3746 nkeys = nwanted; | |
3747 } | |
3748 else | |
3749 nwanted = nkeys; | |
3750 | |
3751 val = make_vector (nwanted, Qnil); | |
3752 | |
3753 for (i = 0, j = start; i < nkeys; i++) | |
3754 { | |
3755 Lisp_Object e = XVECTOR_DATA (Vrecent_keys_ring)[j]; | |
3756 | |
5050
6f2158fa75ed
Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
3757 assert (!NILP (e)); |
428 | 3758 XVECTOR_DATA (val)[i] = Fcopy_event (e, Qnil); |
3759 if (++j >= recent_keys_ring_size) | |
3760 j = 0; | |
3761 } | |
3762 UNGCPRO; | |
3763 return val; | |
3764 } | |
3765 | |
3766 | |
3767 DEFUN ("recent-keys-ring-size", Frecent_keys_ring_size, 0, 0, 0, /* | |
3768 The maximum number of events `recent-keys' can return. | |
3769 */ | |
3770 ()) | |
3771 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3772 return make_fixnum (recent_keys_ring_size); |
428 | 3773 } |
3774 | |
3775 DEFUN ("set-recent-keys-ring-size", Fset_recent_keys_ring_size, 1, 1, 0, /* | |
3776 Set the maximum number of events to be stored internally. | |
3777 */ | |
3778 (size)) | |
3779 { | |
3780 Lisp_Object new_vector = Qnil; | |
3781 int i, j, nkeys, start, min; | |
3782 struct gcpro gcpro1; | |
3783 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3784 CHECK_FIXNUM (size); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3785 if (XFIXNUM (size) <= 0) |
563 | 3786 invalid_argument ("Recent keys ring size must be positive", size); |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3787 if (XFIXNUM (size) == recent_keys_ring_size) |
428 | 3788 return size; |
3789 | |
446 | 3790 GCPRO1 (new_vector); |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3791 new_vector = make_vector (XFIXNUM (size), Qnil); |
428 | 3792 |
3793 if (NILP (Vrecent_keys_ring)) | |
3794 { | |
3795 Vrecent_keys_ring = new_vector; | |
446 | 3796 RETURN_UNGCPRO (size); |
428 | 3797 } |
3798 | |
3799 if (NILP (XVECTOR_DATA (Vrecent_keys_ring)[recent_keys_ring_index])) | |
3800 /* This means the vector has not yet wrapped */ | |
3801 { | |
3802 nkeys = recent_keys_ring_index; | |
3803 start = 0; | |
3804 } | |
3805 else | |
3806 { | |
3807 nkeys = recent_keys_ring_size; | |
3808 start = ((recent_keys_ring_index == nkeys) ? 0 : recent_keys_ring_index); | |
3809 } | |
3810 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3811 if (XFIXNUM (size) > nkeys) |
428 | 3812 min = nkeys; |
3813 else | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3814 min = XFIXNUM (size); |
428 | 3815 |
3816 for (i = 0, j = start; i < min; i++) | |
3817 { | |
3818 XVECTOR_DATA (new_vector)[i] = XVECTOR_DATA (Vrecent_keys_ring)[j]; | |
3819 if (++j >= recent_keys_ring_size) | |
3820 j = 0; | |
3821 } | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3822 recent_keys_ring_size = XFIXNUM (size); |
428 | 3823 recent_keys_ring_index = (i < recent_keys_ring_size) ? i : 0; |
3824 | |
3825 Vrecent_keys_ring = new_vector; | |
3826 | |
3827 UNGCPRO; | |
3828 return size; | |
3829 } | |
3830 | |
3831 /* Vthis_command_keys having value Qnil means that the next time | |
3832 push_this_command_keys is called, it should start over. | |
3833 The times at which the command-keys are reset | |
3834 (instead of merely being augmented) are pretty counterintuitive. | |
3835 (More specifically: | |
3836 | |
3837 -- We do not reset this-command-keys when we finish reading a | |
3838 command. This is because some commands (e.g. C-u) act | |
3839 like command prefixes; they signal this by setting prefix-arg | |
3840 to non-nil. | |
3841 -- Therefore, we reset this-command-keys when we finish | |
3842 executing a command, unless prefix-arg is set. | |
3843 -- However, if we ever do a non-local exit out of a command | |
3844 loop (e.g. an error in a command), we need to reset | |
3845 this-command-keys. We do this by calling reset_this_command_keys() | |
3846 from cmdloop.c, whenever an error causes an invocation of the | |
3847 default error handler, and whenever there's a throw to top-level.) | |
3848 */ | |
3849 | |
3850 void | |
3851 reset_this_command_keys (Lisp_Object console, int clear_echo_area_p) | |
3852 { | |
757 | 3853 if (!NILP (console)) |
3854 { | |
3855 /* console is nil if we just deleted the console as a result of C-x 5 | |
3856 0. Unfortunately things are currently in a messy situation where | |
3857 some stuff is console-local and other stuff isn't, so we need to | |
3858 do everything that's not console-local. */ | |
3859 struct command_builder *command_builder = | |
3860 XCOMMAND_BUILDER (XCONSOLE (console)->command_builder); | |
3861 | |
3862 reset_key_echo (command_builder, clear_echo_area_p); | |
3863 reset_current_events (command_builder); | |
3864 } | |
3865 else | |
3866 reset_key_echo (0, clear_echo_area_p); | |
428 | 3867 |
3868 deallocate_event_chain (Vthis_command_keys); | |
3869 Vthis_command_keys = Qnil; | |
3870 Vthis_command_keys_tail = Qnil; | |
3871 } | |
3872 | |
3873 static void | |
3874 push_this_command_keys (Lisp_Object event) | |
3875 { | |
3025 | 3876 Lisp_Object new_ = Fmake_event (Qnil, Qnil); |
3877 | |
3878 Fcopy_event (event, new_); | |
3879 enqueue_event (new_, &Vthis_command_keys, &Vthis_command_keys_tail); | |
428 | 3880 } |
3881 | |
3882 /* The following two functions are used in call-interactively, | |
3883 for the @ and e specifications. We used to just use | |
3884 `current-mouse-event' (i.e. the last mouse event in this-command-keys), | |
3885 but FSF does it more generally so we follow their lead. */ | |
3886 | |
3887 Lisp_Object | |
3888 extract_this_command_keys_nth_mouse_event (int n) | |
3889 { | |
3890 Lisp_Object event; | |
3891 | |
3892 EVENT_CHAIN_LOOP (event, Vthis_command_keys) | |
3893 { | |
3894 if (EVENTP (event) | |
3895 && (XEVENT_TYPE (event) == button_press_event | |
3896 || XEVENT_TYPE (event) == button_release_event | |
3897 || XEVENT_TYPE (event) == misc_user_event)) | |
3898 { | |
3899 if (!n) | |
3900 { | |
2500 | 3901 /* must copy to avoid an ABORT() in next_event_internal() */ |
428 | 3902 if (!NILP (XEVENT_NEXT (event))) |
3903 return Fcopy_event (event, Qnil); | |
3904 else | |
3905 return event; | |
3906 } | |
3907 n--; | |
3908 } | |
3909 } | |
3910 | |
3911 return Qnil; | |
3912 } | |
3913 | |
3914 Lisp_Object | |
3915 extract_vector_nth_mouse_event (Lisp_Object vector, int n) | |
3916 { | |
3917 int i; | |
3918 int len = XVECTOR_LENGTH (vector); | |
3919 | |
3920 for (i = 0; i < len; i++) | |
3921 { | |
3922 Lisp_Object event = XVECTOR_DATA (vector)[i]; | |
3923 if (EVENTP (event)) | |
3924 switch (XEVENT_TYPE (event)) | |
3925 { | |
3926 case button_press_event : | |
3927 case button_release_event : | |
3928 case misc_user_event : | |
3929 if (n == 0) | |
3930 return event; | |
3931 n--; | |
3932 break; | |
3933 default: | |
3934 continue; | |
3935 } | |
3936 } | |
3937 | |
3938 return Qnil; | |
3939 } | |
3940 | |
3941 static void | |
3942 push_recent_keys (Lisp_Object event) | |
3943 { | |
3944 Lisp_Object e; | |
3945 | |
3946 if (NILP (Vrecent_keys_ring)) | |
3947 Vrecent_keys_ring = make_vector (recent_keys_ring_size, Qnil); | |
3948 | |
3949 e = XVECTOR_DATA (Vrecent_keys_ring) [recent_keys_ring_index]; | |
3950 | |
3951 if (NILP (e)) | |
3952 { | |
3953 e = Fmake_event (Qnil, Qnil); | |
3954 XVECTOR_DATA (Vrecent_keys_ring) [recent_keys_ring_index] = e; | |
3955 } | |
3956 Fcopy_event (event, e); | |
3957 if (++recent_keys_ring_index == recent_keys_ring_size) | |
3958 recent_keys_ring_index = 0; | |
3959 } | |
3960 | |
3961 | |
3962 static Lisp_Object | |
3963 current_events_into_vector (struct command_builder *command_builder) | |
3964 { | |
3965 Lisp_Object vector; | |
3966 Lisp_Object event; | |
3967 int n = event_chain_count (command_builder->current_events); | |
3968 | |
3969 /* Copy the vector and the events in it. */ | |
3970 /* No need to copy the events, since they're already copies, and | |
3971 nobody other than the command-builder has pointers to them */ | |
3972 vector = make_vector (n, Qnil); | |
3973 n = 0; | |
3974 EVENT_CHAIN_LOOP (event, command_builder->current_events) | |
3975 XVECTOR_DATA (vector)[n++] = event; | |
3976 reset_command_builder_event_chain (command_builder); | |
3977 return vector; | |
3978 } | |
3979 | |
3980 | |
3981 /* | |
3982 Given the current state of the command builder and a new command event | |
3983 that has just been dispatched: | |
3984 | |
3985 -- add the event to the event chain forming the current command | |
3986 (doing meta-translation as necessary) | |
3987 -- return the binding of this event chain; this will be one of: | |
3988 -- nil (there is no binding) | |
3989 -- a keymap (part of a command has been specified) | |
3990 -- a command (anything that satisfies `commandp'; this includes | |
3991 some symbols, lists, subrs, strings, vectors, and | |
3992 compiled-function objects) | |
3993 */ | |
3994 static Lisp_Object | |
3995 lookup_command_event (struct command_builder *command_builder, | |
3996 Lisp_Object event, int allow_misc_user_events_p) | |
3997 { | |
3998 /* This function can GC */ | |
3999 struct frame *f = selected_frame (); | |
4000 /* Clear output from previous command execution */ | |
4001 if (!EQ (Qcommand, echo_area_status (f)) | |
4002 /* but don't let mouse-up clear what mouse-down just printed */ | |
4003 && (XEVENT (event)->event_type != button_release_event)) | |
4004 clear_echo_area (f, Qnil, 0); | |
4005 | |
4006 /* Add the given event to the command builder. | |
4007 Extra hack: this also updates the recent_keys_ring and Vthis_command_keys | |
4008 vectors to translate "ESC x" to "M-x" (for any "x" of course). | |
4009 */ | |
4010 { | |
4011 Lisp_Object recent = command_builder->most_current_event; | |
4012 | |
4013 if (EVENTP (recent) | |
1204 | 4014 && event_matches_key_specifier_p (recent, Vmeta_prefix_char)) |
428 | 4015 { |
440 | 4016 Lisp_Event *e; |
428 | 4017 /* When we see a sequence like "ESC x", pretend we really saw "M-x". |
4018 DoubleThink the recent-keys and this-command-keys as well. */ | |
4019 | |
4020 /* Modify the previous most-recently-pushed event on the command | |
4021 builder to be a copy of this one with the meta-bit set instead of | |
4022 pushing a new event. | |
4023 */ | |
4024 Fcopy_event (event, recent); | |
4025 e = XEVENT (recent); | |
934 | 4026 if (EVENT_TYPE (e) == key_press_event) |
1204 | 4027 SET_EVENT_KEY_MODIFIERS (e, EVENT_KEY_MODIFIERS (e) | |
4028 XEMACS_MOD_META); | |
934 | 4029 else if (EVENT_TYPE (e) == button_press_event |
4030 || EVENT_TYPE (e) == button_release_event) | |
1204 | 4031 SET_EVENT_BUTTON_MODIFIERS (e, EVENT_BUTTON_MODIFIERS (e) | |
4032 XEMACS_MOD_META); | |
428 | 4033 else |
2500 | 4034 ABORT (); |
428 | 4035 |
4036 { | |
4037 int tckn = event_chain_count (Vthis_command_keys); | |
4038 if (tckn >= 2) | |
4039 /* ??? very strange if it's < 2. */ | |
4040 this_command_keys_replace_suffix | |
4041 (event_chain_nth (Vthis_command_keys, tckn - 2), | |
4042 Fcopy_event (recent, Qnil)); | |
4043 } | |
4044 | |
4045 regenerate_echo_keys_from_this_command_keys (command_builder); | |
4046 } | |
4047 else | |
771 | 4048 command_builder_append_event (command_builder, event); |
428 | 4049 } |
4050 | |
4051 { | |
771 | 4052 Lisp_Object leaf = |
4053 command_builder_find_leaf_and_update_global_state | |
4054 (command_builder, | |
4055 allow_misc_user_events_p); | |
428 | 4056 struct gcpro gcpro1; |
4057 GCPRO1 (leaf); | |
4058 | |
4059 if (KEYMAPP (leaf)) | |
4060 { | |
442 | 4061 #if defined (HAVE_X_WINDOWS) && defined (LWLIB_MENUBARS_LUCID) |
4062 if (!x_kludge_lw_menu_active ()) | |
4063 #else | |
4064 if (1) | |
4065 #endif | |
428 | 4066 { |
4067 Lisp_Object prompt = Fkeymap_prompt (leaf, Qt); | |
4068 if (STRINGP (prompt)) | |
4069 { | |
4070 /* Append keymap prompt to key echo buffer */ | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4071 int buf_fill_pointer = command_builder->echo_buf_fill_pointer; |
428 | 4072 Bytecount len = XSTRING_LENGTH (prompt); |
4073 | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4074 if (len + buf_fill_pointer + 1 |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4075 <= XSTRING_LENGTH (command_builder->echo_buf)) |
428 | 4076 { |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4077 memcpy (XSTRING_DATA (command_builder->echo_buf) |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4078 + buf_fill_pointer, |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4079 XSTRING_DATA (prompt), |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4080 len); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4081 copy_string_extents (command_builder->echo_buf, prompt, |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4082 buf_fill_pointer, 0, len); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4083 |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4084 init_string_ascii_begin (command_builder->echo_buf); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4085 bump_string_modiff (command_builder->echo_buf); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4086 sledgehammer_check_ascii_begin (command_builder->echo_buf); |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4087 |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4088 /* Show the keymap prompt, but don't adjust the fill |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4089 pointer to reflect it. */ |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4090 command_builder->echo_buf_end |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4091 = command_builder->echo_buf_fill_pointer + len; |
428 | 4092 } |
4093 maybe_echo_keys (command_builder, 1); | |
4094 } | |
4095 else | |
4096 maybe_echo_keys (command_builder, 0); | |
4097 } | |
853 | 4098 /* #### i don't trust this at all. --ben */ |
4099 #if 0 | |
442 | 4100 else if (!NILP (Vquit_flag)) |
4101 { | |
4102 /* if quit happened during menu acceleration, pretend we read it */ | |
4103 struct console *con = XCONSOLE (Fselected_console ()); | |
1204 | 4104 |
4105 enqueue_command_event (Fcopy_event (CONSOLE_QUIT_EVENT (con), | |
4106 Qnil)); | |
442 | 4107 Vquit_flag = Qnil; |
4108 } | |
853 | 4109 #endif |
428 | 4110 } |
4111 else if (!NILP (leaf)) | |
4112 { | |
4113 if (EQ (Qcommand, echo_area_status (f)) | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4114 && command_builder->echo_buf_fill_pointer > 0) |
428 | 4115 { |
4116 /* If we had been echoing keys, echo the last one (without | |
4117 the trailing dash) and redisplay before executing the | |
4118 command. */ | |
5803
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4119 command_builder->echo_buf_end = |
b79e1e02bf01
Preserve extent information in the command builder code.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5801
diff
changeset
|
4120 command_builder->echo_buf_fill_pointer; |
428 | 4121 maybe_echo_keys (command_builder, 1); |
4122 Fsit_for (Qzero, Qt); | |
4123 } | |
4124 } | |
4125 RETURN_UNGCPRO (leaf); | |
4126 } | |
4127 } | |
4128 | |
479 | 4129 static int |
4932 | 4130 is_scrollbar_event (Lisp_Object USED_IF_SCROLLBARS (event)) |
479 | 4131 { |
516 | 4132 #ifdef HAVE_SCROLLBARS |
479 | 4133 Lisp_Object fun; |
4134 | |
934 | 4135 if (XEVENT_TYPE (event) != misc_user_event) |
4136 return 0; | |
1204 | 4137 fun = XEVENT_MISC_USER_FUNCTION (event); |
479 | 4138 |
4139 return (EQ (fun, Qscrollbar_line_up) || | |
4140 EQ (fun, Qscrollbar_line_down) || | |
4141 EQ (fun, Qscrollbar_page_up) || | |
4142 EQ (fun, Qscrollbar_page_down) || | |
4143 EQ (fun, Qscrollbar_to_top) || | |
4144 EQ (fun, Qscrollbar_to_bottom) || | |
4145 EQ (fun, Qscrollbar_vertical_drag) || | |
4146 EQ (fun, Qscrollbar_char_left) || | |
4147 EQ (fun, Qscrollbar_char_right) || | |
4148 EQ (fun, Qscrollbar_page_left) || | |
4149 EQ (fun, Qscrollbar_page_right) || | |
4150 EQ (fun, Qscrollbar_to_left) || | |
4151 EQ (fun, Qscrollbar_to_right) || | |
4152 EQ (fun, Qscrollbar_horizontal_drag)); | |
516 | 4153 #else |
4154 return 0; | |
4155 #endif /* HAVE_SCROLLBARS */ | |
479 | 4156 } |
4157 | |
428 | 4158 static void |
4159 execute_command_event (struct command_builder *command_builder, | |
4160 Lisp_Object event) | |
4161 { | |
4162 /* This function can GC */ | |
4163 struct console *con = XCONSOLE (command_builder->console); | |
4164 struct gcpro gcpro1; | |
4165 | |
4166 GCPRO1 (event); /* event may be freshly created */ | |
444 | 4167 |
479 | 4168 /* #### This call to is_scrollbar_event() isn't quite right, but |
4169 fixing properly it requires more work than can go into 21.4. | |
4170 (We really need to split out menu, scrollbar, dialog, and other | |
4171 types of events from misc-user, and put the remaining ones in a | |
4172 new `user-eval' type that behaves like an eval event but is a | |
4173 user event and thus has all of its semantics -- e.g. being | |
4174 delayed during `accept-process-output' and similar wait states.) | |
4175 | |
4176 The real issue here is that "user events" and "command events" | |
4177 are not the same thing, but are very much confused in | |
4178 event-stream.c. User events are, essentially, any event that | |
4179 should be delayed by accept-process-output, should terminate a | |
4180 sit-for, etc. -- basically, any event that needs to be processed | |
4181 synchronously with key and mouse events. Command events are | |
4182 those that participate in command building; scrollbar events | |
4183 clearly don't belong because they should be transparent in a | |
4184 sequence like C-x @ h <scrollbar-drag> x, which used to cause a | |
4185 crash before checks similar to the is_scrollbar_event() call were | |
4186 added. Do other events belong with scrollbar events? I'm not | |
4187 sure; we need to categorize all misc-user events and see what | |
4188 their semantics are. | |
4189 | |
4190 (You might ask, why do scrollbar events need to be user events? | |
4191 That's a good question. The answer seems to be that they can | |
4192 change point, and having this happen asynchronously would be a | |
4193 very bad idea. According to the "proper" functioning of | |
4194 scrollbars, this should not happen, but XEmacs does not allow | |
4195 point to go outside of the window.) | |
4196 | |
4197 Scrollbar events and similar non-command events should obviously | |
4198 not be recorded in this-command-keys, so we need to check for | |
4199 this in next-event. | |
4200 | |
4201 #### We call reset_current_events() twice in this function -- | |
4202 #### here, and later as a result of reset_this_command_keys(). | |
4203 #### This is almost certainly wrong; need to figure out what's | |
4204 #### correct. | |
4205 | |
4206 #### We need to figure out what's really correct w.r.t. scrollbar | |
4207 #### events. With these new fixes in, it actually works to do | |
4208 #### C-x <scrollbar-drag> 5 2, but the key echo gets messed up | |
4209 #### (starts over at 5). We really need to be special-casing | |
4210 #### scrollbar events at a lower level, and not really passing | |
4211 #### them through the command builder at all. (e.g. do scrollbar | |
4212 #### events belong in macros??? doubtful; probably only the | |
4213 #### point movement, if any, belongs, special-cased as a | |
4214 #### pseudo-issued M-x goto-char command). #### Need more work | |
4215 #### here. Do this when separating out scrollbar events. | |
4216 */ | |
4217 | |
4218 if (!is_scrollbar_event (event)) | |
444 | 4219 reset_current_events (command_builder); |
428 | 4220 |
4221 switch (XEVENT (event)->event_type) | |
4222 { | |
4223 case key_press_event: | |
4224 Vcurrent_mouse_event = Qnil; | |
4225 break; | |
4226 case button_press_event: | |
4227 case button_release_event: | |
4228 case misc_user_event: | |
4229 Vcurrent_mouse_event = Fcopy_event (event, Qnil); | |
4230 break; | |
4231 default: break; | |
4232 } | |
4233 | |
4234 /* Store the last-command-event. The semantics of this is that it | |
4235 is the last event most recently involved in command-lookup. */ | |
4236 if (!EVENTP (Vlast_command_event)) | |
4237 Vlast_command_event = Fmake_event (Qnil, Qnil); | |
4238 if (XEVENT (Vlast_command_event)->event_type == dead_event) | |
4239 { | |
4240 Vlast_command_event = Fmake_event (Qnil, Qnil); | |
563 | 4241 invalid_state ("Someone deallocated the last-command-event!", Qunbound); |
428 | 4242 } |
4243 | |
4244 if (! EQ (event, Vlast_command_event)) | |
4245 Fcopy_event (event, Vlast_command_event); | |
4246 | |
4247 /* Note that last-command-char will never have its high-bit set, in | |
4248 an effort to sidestep the ambiguity between M-x and oslash. */ | |
4249 Vlast_command_char = Fevent_to_character (Vlast_command_event, | |
2862 | 4250 Qnil, Qnil, Qnil); |
428 | 4251 |
4252 /* Actually call the command, with all sorts of hair to preserve or clear | |
4253 the echo-area and region as appropriate and call the pre- and post- | |
4254 command-hooks. */ | |
4255 { | |
4256 int old_kbd_macro = con->kbd_macro_end; | |
4257 struct window *w = XWINDOW (Fselected_window (Qnil)); | |
4258 | |
4259 /* We're executing a new command, so the old value is irrelevant. */ | |
4260 zmacs_region_stays = 0; | |
4261 | |
4262 /* If the previous command tried to force a specific window-start, | |
4263 reset the flag in case this command moves point far away from | |
4264 that position. Also, reset the window's buffer's change | |
4265 information so that we don't trigger an incremental update. */ | |
4266 if (w->force_start) | |
4267 { | |
4268 w->force_start = 0; | |
4269 buffer_reset_changes (XBUFFER (w->buffer)); | |
4270 } | |
4271 | |
4272 pre_command_hook (); | |
4273 | |
934 | 4274 if (XEVENT_TYPE (event) == misc_user_event) |
4275 { | |
1204 | 4276 call1 (XEVENT_MISC_USER_FUNCTION (event), |
4277 XEVENT_MISC_USER_OBJECT (event)); | |
934 | 4278 } |
428 | 4279 else |
4280 { | |
4281 Fcommand_execute (Vthis_command, Qnil, Qnil); | |
4282 } | |
4283 | |
4284 post_command_hook (); | |
4285 | |
757 | 4286 /* Console might have been deleted by command */ |
4287 if (CONSOLE_LIVE_P (con) && !NILP (con->prefix_arg)) | |
428 | 4288 { |
4289 /* Commands that set the prefix arg don't update last-command, don't | |
4290 reset the echoing state, and don't go into keyboard macros unless | |
444 | 4291 followed by another command. Also don't quit here. */ |
4292 int speccount = specpdl_depth (); | |
4293 specbind (Qinhibit_quit, Qt); | |
428 | 4294 maybe_echo_keys (command_builder, 0); |
771 | 4295 unbind_to (speccount); |
428 | 4296 |
4297 /* If we're recording a keyboard macro, and the last command | |
4298 executed set a prefix argument, then decrement the pointer to | |
4299 the "last character really in the macro" to be just before this | |
4300 command. This is so that the ^U in "^U ^X )" doesn't go onto | |
4301 the end of macro. */ | |
4302 if (!NILP (con->defining_kbd_macro)) | |
4303 con->kbd_macro_end = old_kbd_macro; | |
4304 } | |
4305 else | |
4306 { | |
4307 /* Start a new command next time */ | |
4308 Vlast_command = Vthis_command; | |
442 | 4309 Vlast_command_properties = Vthis_command_properties; |
4310 Vthis_command_properties = Qnil; | |
4311 | |
428 | 4312 /* Emacs 18 doesn't unconditionally clear the echoed keystrokes, |
4313 so we don't either */ | |
479 | 4314 |
4315 if (!is_scrollbar_event (event)) | |
771 | 4316 reset_this_command_keys (CONSOLE_LIVE_P (con) ? wrap_console (con) |
757 | 4317 : Qnil, 0); |
428 | 4318 } |
4319 } | |
4320 | |
4321 UNGCPRO; | |
4322 } | |
4323 | |
4324 /* Run the pre command hook. */ | |
4325 | |
4326 static void | |
4327 pre_command_hook (void) | |
4328 { | |
4329 last_point_position = BUF_PT (current_buffer); | |
793 | 4330 last_point_position_buffer = wrap_buffer (current_buffer); |
428 | 4331 /* This function can GC */ |
853 | 4332 safe_run_hook_trapping_problems |
1333 | 4333 (Qcommand, Qpre_command_hook, |
4334 INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION); | |
442 | 4335 |
4336 /* This is a kludge, but necessary; see simple.el */ | |
4337 call0 (Qhandle_pre_motion_command); | |
428 | 4338 } |
4339 | |
4340 /* Run the post command hook. */ | |
4341 | |
4342 static void | |
4343 post_command_hook (void) | |
4344 { | |
4345 /* This function can GC */ | |
4346 /* Turn off region highlighting unless this command requested that | |
4347 it be left on, or we're in the minibuffer. We don't turn it off | |
4348 when we're in the minibuffer so that things like M-x write-region | |
4349 still work! | |
4350 | |
4351 This could be done via a function on the post-command-hook, but | |
4352 we don't want the user to accidentally remove it. | |
4353 */ | |
4354 | |
4355 Lisp_Object win = Fselected_window (Qnil); | |
4356 | |
4357 /* If the last command deleted the frame, `win' might be nil. | |
4358 It seems safest to do nothing in this case. */ | |
442 | 4359 /* Note: Someone added the following comment and put #if 0's around |
4360 this code, not realizing that doing this invites a crash in the | |
4361 line after. */ | |
440 | 4362 /* #### This doesn't really fix the problem, |
428 | 4363 if delete-frame is called by some hook */ |
4364 if (NILP (win)) | |
4365 return; | |
442 | 4366 |
4367 /* This is a kludge, but necessary; see simple.el */ | |
4368 call0 (Qhandle_post_motion_command); | |
428 | 4369 |
4370 if (! zmacs_region_stays | |
4371 && (!MINI_WINDOW_P (XWINDOW (win)) | |
4372 || EQ (zmacs_region_buffer (), WINDOW_BUFFER (XWINDOW (win))))) | |
4373 zmacs_deactivate_region (); | |
4374 else | |
4375 zmacs_update_region (); | |
4376 | |
853 | 4377 safe_run_hook_trapping_problems |
1333 | 4378 (Qcommand, Qpost_command_hook, |
5722
fffa15138019
Don't complain about throws out of `post-command-hook'.
Mike Sperber <sperber@deinprogramm.de>
parents:
5691
diff
changeset
|
4379 NO_INHIBIT_THROWS); |
853 | 4380 |
4381 #if 0 /* FSF Emacs */ | |
4382 if (!NILP (current_buffer->mark_active)) | |
4383 { | |
4384 if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode)) | |
4385 { | |
4386 current_buffer->mark_active = Qnil; | |
4387 run_hook (intern ("deactivate-mark-hook")); | |
4388 } | |
4389 else if (current_buffer != prev_buffer || | |
4390 BUF_MODIFF (current_buffer) != prev_modiff) | |
4391 run_hook (intern ("activate-mark-hook")); | |
4392 } | |
4393 #endif /* FSF Emacs */ | |
428 | 4394 |
4395 /* #### Kludge!!! This is necessary to make sure that things | |
4396 are properly positioned even if post-command-hook moves point. | |
4397 #### There should be a cleaner way of handling this. */ | |
4398 call0 (Qauto_show_make_point_visible); | |
4399 } | |
4400 | |
4401 | |
4402 DEFUN ("dispatch-event", Fdispatch_event, 1, 1, 0, /* | |
444 | 4403 Given an event object EVENT as returned by `next-event', execute it. |
428 | 4404 |
4405 Key-press, button-press, and button-release events get accumulated | |
4406 until a complete key sequence (see `read-key-sequence') is reached, | |
4407 at which point the sequence is looked up in the current keymaps and | |
4408 acted upon. | |
4409 | |
4410 Mouse motion events cause the low-level handling function stored in | |
4411 `mouse-motion-handler' to be called. (There are very few circumstances | |
4412 under which you should change this handler. Use `mode-motion-hook' | |
4413 instead.) | |
4414 | |
4415 Menu, timeout, and eval events cause the associated function or handler | |
4416 to be called. | |
4417 | |
4418 Process events cause the subprocess's output to be read and acted upon | |
4419 appropriately (see `start-process'). | |
4420 | |
4421 Magic events are handled as necessary. | |
4422 */ | |
4423 (event)) | |
4424 { | |
4425 /* This function can GC */ | |
4426 struct command_builder *command_builder; | |
440 | 4427 Lisp_Event *ev; |
428 | 4428 Lisp_Object console; |
4429 Lisp_Object channel; | |
1292 | 4430 PROFILE_DECLARE (); |
428 | 4431 |
4432 CHECK_LIVE_EVENT (event); | |
4433 ev = XEVENT (event); | |
4434 | |
4435 /* events on dead channels get silently eaten */ | |
4436 channel = EVENT_CHANNEL (ev); | |
4437 if (object_dead_p (channel)) | |
4438 return Qnil; | |
4439 | |
1292 | 4440 PROFILE_RECORD_ENTERING_SECTION (Qdispatch_event); |
4441 | |
428 | 4442 /* Some events don't have channels (e.g. eval events). */ |
4443 console = CDFW_CONSOLE (channel); | |
4444 if (NILP (console)) | |
4445 console = Vselected_console; | |
4446 else if (!EQ (console, Vselected_console)) | |
4447 Fselect_console (console); | |
4448 | |
4449 command_builder = XCOMMAND_BUILDER (XCONSOLE (console)->command_builder); | |
934 | 4450 switch (XEVENT_TYPE (event)) |
428 | 4451 { |
4452 case button_press_event: | |
4453 case button_release_event: | |
4454 case key_press_event: | |
4455 { | |
4456 Lisp_Object leaf = lookup_command_event (command_builder, event, 1); | |
4457 | |
5371
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4458 lookedup: |
428 | 4459 if (KEYMAPP (leaf)) |
4460 /* Incomplete key sequence */ | |
4461 break; | |
4462 if (NILP (leaf)) | |
4463 { | |
4464 /* At this point, we know that the sequence is not bound to a | |
4465 command. Normally, we beep and print a message informing the | |
4466 user of this. But we do not beep or print a message when: | |
4467 | |
4468 o the last event in this sequence is a mouse-up event; or | |
4469 o the last event in this sequence is a mouse-down event and | |
4470 there is a binding for the mouse-up version. | |
4471 | |
4472 That is, if the sequence ``C-x button1'' is typed, and is not | |
4473 bound to a command, but the sequence ``C-x button1up'' is bound | |
4474 to a command, we do not complain about the ``C-x button1'' | |
4475 sequence. If neither ``C-x button1'' nor ``C-x button1up'' is | |
4476 bound to a command, then we complain about the ``C-x button1'' | |
4477 sequence, but later will *not* complain about the | |
4478 ``C-x button1up'' sequence, which would be redundant. | |
4479 | |
4480 This is pretty hairy, but I think it's the most intuitive | |
4481 behavior. | |
4482 */ | |
4483 Lisp_Object terminal = command_builder->most_current_event; | |
4484 | |
4485 if (XEVENT_TYPE (terminal) == button_press_event) | |
4486 { | |
4487 int no_bitching; | |
4488 /* Temporarily pretend the last event was an "up" instead of a | |
4489 "down", and look up its binding. */ | |
4490 XEVENT_TYPE (terminal) = button_release_event; | |
4491 /* If the "up" version is bound, don't complain. */ | |
4492 no_bitching | |
771 | 4493 = !NILP (command_builder_find_leaf_and_update_global_state |
4494 (command_builder, 0)); | |
428 | 4495 /* Undo the temporary changes we just made. */ |
4496 XEVENT_TYPE (terminal) = button_press_event; | |
4497 if (no_bitching) | |
4498 { | |
4499 /* Pretend this press was not seen (treat as a prefix) */ | |
4500 if (EQ (command_builder->current_events, terminal)) | |
4501 { | |
4502 reset_current_events (command_builder); | |
4503 } | |
4504 else | |
4505 { | |
4506 Lisp_Object eve; | |
4507 | |
4508 EVENT_CHAIN_LOOP (eve, command_builder->current_events) | |
4509 if (EQ (XEVENT_NEXT (eve), terminal)) | |
4510 break; | |
4511 | |
4512 Fdeallocate_event (command_builder-> | |
4513 most_current_event); | |
4514 XSET_EVENT_NEXT (eve, Qnil); | |
4515 command_builder->most_current_event = eve; | |
4516 } | |
4517 maybe_echo_keys (command_builder, 1); | |
4518 break; | |
4519 } | |
4520 } | |
4521 | |
4522 /* Complain that the typed sequence is not defined, if this is the | |
4523 kind of sequence that warrants a complaint. */ | |
4524 XCONSOLE (console)->defining_kbd_macro = Qnil; | |
4525 XCONSOLE (console)->prefix_arg = Qnil; | |
4526 /* Don't complain about undefined button-release events */ | |
4527 if (XEVENT_TYPE (terminal) != button_release_event) | |
4528 { | |
4529 Lisp_Object keys = current_events_into_vector (command_builder); | |
4530 struct gcpro gcpro1; | |
4531 | |
4532 /* Run the pre-command-hook before barfing about an undefined | |
4533 key. */ | |
4534 Vthis_command = Qnil; | |
4535 GCPRO1 (keys); | |
4536 pre_command_hook (); | |
4537 UNGCPRO; | |
5371
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4538 |
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4539 if (!NILP (Vthis_command)) |
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4540 { |
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4541 /* Allow pre-command-hook to change the command to |
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4542 something more useful, and avoid barfing. */ |
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4543 leaf = Vthis_command; |
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4544 if (!EQ (command_builder->most_current_event, |
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4545 Vlast_command_event)) |
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4546 { |
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4547 reset_current_events (command_builder); |
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4548 command_builder_append_event (command_builder, |
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4549 Vlast_command_event); |
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4550 } |
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4551 goto lookedup; |
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4552 } |
6f10ac29bf40
Be better about searching for chars typed via XIM and x-compose.el, isearch
Aidan Kehoe <kehoea@parhasard.net>
parents:
5307
diff
changeset
|
4553 |
428 | 4554 /* The post-command-hook doesn't run. */ |
4555 Fsignal (Qundefined_keystroke_sequence, list1 (keys)); | |
4556 } | |
4557 /* Reset the command builder for reading the next sequence. */ | |
4558 reset_this_command_keys (console, 1); | |
4559 } | |
4560 else /* key sequence is bound to a command */ | |
4561 { | |
430 | 4562 int magic_undo = 0; |
5307
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
4563 Elemcount magic_undo_count = 20; |
430 | 4564 |
5691
b490ddbd42aa
Back out 7371081ce8f7, I have a better approach.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5689
diff
changeset
|
4565 Vthis_command = leaf; |
b490ddbd42aa
Back out 7371081ce8f7, I have a better approach.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5689
diff
changeset
|
4566 |
428 | 4567 /* Don't push an undo boundary if the command set the prefix arg, |
4568 or if we are executing a keyboard macro, or if in the | |
4569 minibuffer. If the command we are about to execute is | |
4570 self-insert, it's tricky: up to 20 consecutive self-inserts may | |
4571 be done without an undo boundary. This counter is reset as | |
4572 soon as a command other than self-insert-command is executed. | |
430 | 4573 |
442 | 4574 Programmers can also use the `self-insert-defer-undo' |
4575 property to install that behavior on functions other | |
430 | 4576 than `self-insert-command', or to change the magic |
442 | 4577 number 20 to something else. #### DOCUMENT THIS! */ |
430 | 4578 |
4579 if (SYMBOLP (leaf)) | |
4580 { | |
4581 Lisp_Object prop = Fget (leaf, Qself_insert_defer_undo, Qnil); | |
4582 if (NATNUMP (prop)) | |
5307
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
4583 { |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
4584 magic_undo = 1; |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4585 if (FIXNUMP (prop)) |
5307
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
4586 { |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4587 magic_undo_count = XFIXNUM (prop); |
5307
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
4588 } |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
4589 #ifdef HAVE_BIGNUM |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
4590 else if (BIGNUMP (prop) |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
4591 && bignum_fits_emacs_int_p (XBIGNUM_DATA (prop))) |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
4592 { |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
4593 magic_undo_count |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
4594 = bignum_to_emacs_int (XBIGNUM_DATA (prop)); |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
4595 } |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
4596 #endif |
c096d8051f89
Have NATNUMP give t for positive bignums; check limits appropriately.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
4597 } |
430 | 4598 else if (!NILP (prop)) |
4599 magic_undo = 1; | |
4600 else if (EQ (leaf, Qself_insert_command)) | |
4601 magic_undo = 1; | |
4602 } | |
4603 | |
4604 if (!magic_undo) | |
428 | 4605 command_builder->self_insert_countdown = 0; |
4606 if (NILP (XCONSOLE (console)->prefix_arg) | |
4607 && NILP (Vexecuting_macro) | |
4608 && command_builder->self_insert_countdown == 0) | |
4609 Fundo_boundary (); | |
4610 | |
430 | 4611 if (magic_undo) |
428 | 4612 { |
4613 if (--command_builder->self_insert_countdown < 0) | |
430 | 4614 command_builder->self_insert_countdown = magic_undo_count; |
428 | 4615 } |
4616 execute_command_event | |
4617 (command_builder, | |
444 | 4618 internal_equal (event, command_builder->most_current_event, 0) |
428 | 4619 ? event |
4620 /* Use the translated event that was most recently seen. | |
4621 This way, last-command-event becomes f1 instead of | |
4622 the P from ESC O P. But we must copy it, else we'll | |
4623 lose when the command-builder events are deallocated. */ | |
444 | 4624 : Fcopy_event (command_builder->most_current_event, Qnil)); |
428 | 4625 } |
4626 break; | |
4627 } | |
4628 case misc_user_event: | |
4629 { | |
4630 /* Jamie said: | |
4631 | |
4632 We could just always use the menu item entry, whatever it is, but | |
4633 this might break some Lisp code that expects `this-command' to | |
4634 always contain a symbol. So only store it if this is a simple | |
4635 `call-interactively' sort of menu item. | |
4636 | |
4637 But this is bogus. `this-command' could be a string or vector | |
4638 anyway (for keyboard macros). There's even one instance | |
4639 (in pending-del.el) of `this-command' getting set to a cons | |
4640 (a lambda expression). So in the `eval' case I'll just | |
4641 convert it into a lambda expression. | |
4642 */ | |
1204 | 4643 if (EQ (XEVENT_MISC_USER_FUNCTION (event), Qcall_interactively) |
4644 && SYMBOLP (XEVENT_MISC_USER_OBJECT (event))) | |
4645 Vthis_command = XEVENT_MISC_USER_OBJECT (event); | |
4646 else if (EQ (XEVENT_MISC_USER_FUNCTION (event), Qeval)) | |
934 | 4647 Vthis_command = |
1204 | 4648 Fcons (Qlambda, Fcons (Qnil, XEVENT_MISC_USER_OBJECT (event))); |
4649 else if (SYMBOLP (XEVENT_MISC_USER_FUNCTION (event))) | |
934 | 4650 /* A scrollbar command or the like. */ |
1204 | 4651 Vthis_command = XEVENT_MISC_USER_FUNCTION (event); |
428 | 4652 else |
4653 /* Huh? */ | |
4654 Vthis_command = Qnil; | |
4655 | |
4656 /* clear the echo area */ | |
4657 reset_key_echo (command_builder, 1); | |
4658 | |
4659 command_builder->self_insert_countdown = 0; | |
4660 if (NILP (XCONSOLE (console)->prefix_arg) | |
4661 && NILP (Vexecuting_macro) | |
4662 && !EQ (minibuf_window, Fselected_window (Qnil))) | |
4663 Fundo_boundary (); | |
4664 execute_command_event (command_builder, event); | |
4665 break; | |
4666 } | |
4667 default: | |
4668 execute_internal_event (event); | |
4669 break; | |
4670 } | |
1292 | 4671 |
4672 PROFILE_RECORD_EXITING_SECTION (Qdispatch_event); | |
428 | 4673 return Qnil; |
4674 } | |
4675 | |
4676 DEFUN ("read-key-sequence", Fread_key_sequence, 1, 3, 0, /* | |
4677 Read a sequence of keystrokes or mouse clicks. | |
4678 Returns a vector of the event objects read. The vector and the event | |
444 | 4679 objects it contains are freshly created (and so will not be side-effected |
428 | 4680 by subsequent calls to this function). |
4681 | |
4682 The sequence read is sufficient to specify a non-prefix command starting | |
4683 from the current local and global keymaps. A C-g typed while in this | |
4684 function is treated like any other character, and `quit-flag' is not set. | |
4685 | |
4686 First arg PROMPT is a prompt string. If nil, do not prompt specially. | |
444 | 4687 |
4688 Second optional arg CONTINUE-ECHO non-nil means this key echoes as a | |
4689 continuation of the previous key. | |
4690 | |
4691 Third optional arg DONT-DOWNCASE-LAST non-nil means do not convert the | |
4692 last event to lower case. (Normally any upper case event is converted | |
4693 to lower case if the original event is undefined and the lower case | |
4694 equivalent is defined.) This argument is provided mostly for FSF | |
4695 compatibility; the equivalent effect can be achieved more generally by | |
4696 binding `retry-undefined-key-binding-unshifted' to nil around the call | |
4697 to `read-key-sequence'. | |
428 | 4698 |
4699 If the user selects a menu item while we are prompting for a key-sequence, | |
4700 the returned value will be a vector of a single menu-selection event. | |
4701 An error will be signalled if you pass this value to `lookup-key' or a | |
4702 related function. | |
4703 | |
4704 `read-key-sequence' checks `function-key-map' for function key | |
444 | 4705 sequences, where they wouldn't conflict with ordinary bindings. |
4706 See `function-key-map' for more details. | |
428 | 4707 */ |
4708 (prompt, continue_echo, dont_downcase_last)) | |
4709 { | |
4710 /* This function can GC */ | |
4711 struct console *con = XCONSOLE (Vselected_console); /* #### correct? | |
4712 Probably not -- see | |
4713 comment in | |
4714 next-event */ | |
4715 struct command_builder *command_builder = | |
4716 XCOMMAND_BUILDER (con->command_builder); | |
4717 Lisp_Object result; | |
4718 Lisp_Object event = Fmake_event (Qnil, Qnil); | |
4719 int speccount = specpdl_depth (); | |
4720 struct gcpro gcpro1; | |
4721 GCPRO1 (event); | |
4722 | |
707 | 4723 record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); |
428 | 4724 if (!NILP (prompt)) |
4725 CHECK_STRING (prompt); | |
4726 /* else prompt = Fkeymap_prompt (current_buffer->keymap); may GC */ | |
4727 QUIT; | |
4728 | |
4729 if (NILP (continue_echo)) | |
771 | 4730 reset_this_command_keys (wrap_console (con), 1); |
428 | 4731 |
4732 if (!NILP (dont_downcase_last)) | |
4733 specbind (Qretry_undefined_key_binding_unshifted, Qnil); | |
4734 | |
4735 for (;;) | |
4736 { | |
4737 Fnext_event (event, prompt); | |
4738 /* restore the selected-console damage */ | |
4739 con = event_console_or_selected (event); | |
4740 command_builder = XCOMMAND_BUILDER (con->command_builder); | |
4741 if (! command_event_p (event)) | |
4742 execute_internal_event (event); | |
4743 else | |
4744 { | |
934 | 4745 if (XEVENT_TYPE (event) == misc_user_event) |
428 | 4746 reset_current_events (command_builder); |
4747 result = lookup_command_event (command_builder, event, 1); | |
4748 if (!KEYMAPP (result)) | |
4749 { | |
4750 result = current_events_into_vector (command_builder); | |
4751 reset_key_echo (command_builder, 0); | |
4752 break; | |
4753 } | |
4754 prompt = Qnil; | |
4755 } | |
4756 } | |
4757 | |
4758 Fdeallocate_event (event); | |
771 | 4759 RETURN_UNGCPRO (unbind_to_1 (speccount, result)); |
428 | 4760 } |
4761 | |
4762 DEFUN ("this-command-keys", Fthis_command_keys, 0, 0, 0, /* | |
4763 Return a vector of the keyboard or mouse button events that were used | |
4764 to invoke this command. This copies the vector and the events; it is safe | |
4765 to keep and modify them. | |
4766 */ | |
4767 ()) | |
4768 { | |
4769 Lisp_Object event; | |
4770 Lisp_Object result; | |
4771 int len; | |
4772 | |
4773 if (NILP (Vthis_command_keys)) | |
4774 return make_vector (0, Qnil); | |
4775 | |
4776 len = event_chain_count (Vthis_command_keys); | |
4777 | |
4778 result = make_vector (len, Qnil); | |
4779 len = 0; | |
4780 EVENT_CHAIN_LOOP (event, Vthis_command_keys) | |
4781 XVECTOR_DATA (result)[len++] = Fcopy_event (event, Qnil); | |
4782 return result; | |
4783 } | |
4784 | |
4785 DEFUN ("reset-this-command-lengths", Freset_this_command_lengths, 0, 0, 0, /* | |
4786 Used for complicated reasons in `universal-argument-other-key'. | |
4787 | |
4788 `universal-argument-other-key' rereads the event just typed. | |
4789 It then gets translated through `function-key-map'. | |
4790 The translated event gets included in the echo area and in | |
4791 the value of `this-command-keys' in addition to the raw original event. | |
4792 That is not right. | |
4793 | |
4794 Calling this function directs the translated event to replace | |
4795 the original event, so that only one version of the event actually | |
430 | 4796 appears in the echo area and in the value of `this-command-keys'. |
428 | 4797 */ |
4798 ()) | |
4799 { | |
4800 /* #### I don't understand this at all, so currently it does nothing. | |
4801 If there is ever a problem, maybe someone should investigate. */ | |
4802 return Qnil; | |
4803 } | |
4804 | |
4805 | |
4806 static void | |
4807 dribble_out_event (Lisp_Object event) | |
4808 { | |
4809 if (NILP (Vdribble_file)) | |
4810 return; | |
4811 | |
934 | 4812 if (XEVENT_TYPE (event) == key_press_event && |
1204 | 4813 !XEVENT_KEY_MODIFIERS (event)) |
934 | 4814 { |
1204 | 4815 Lisp_Object keysym = XEVENT_KEY_KEYSYM (event); |
4816 if (CHARP (XEVENT_KEY_KEYSYM (event))) | |
428 | 4817 { |
867 | 4818 Ichar ch = XCHAR (keysym); |
4819 Ibyte str[MAX_ICHAR_LEN]; | |
4820 Bytecount len = set_itext_ichar (str, ch); | |
428 | 4821 Lstream_write (XLSTREAM (Vdribble_file), str, len); |
4822 } | |
826 | 4823 else if (string_char_length (XSYMBOL (keysym)->name) == 1) |
428 | 4824 /* one-char key events are printed with just the key name */ |
4825 Fprinc (keysym, Vdribble_file); | |
4826 else if (EQ (keysym, Qreturn)) | |
4827 Lstream_putc (XLSTREAM (Vdribble_file), '\n'); | |
4828 else if (EQ (keysym, Qspace)) | |
4829 Lstream_putc (XLSTREAM (Vdribble_file), ' '); | |
4830 else | |
4831 Fprinc (event, Vdribble_file); | |
4832 } | |
4833 else | |
4834 Fprinc (event, Vdribble_file); | |
4835 Lstream_flush (XLSTREAM (Vdribble_file)); | |
4836 } | |
4837 | |
4838 DEFUN ("open-dribble-file", Fopen_dribble_file, 1, 1, | |
4839 "FOpen dribble file: ", /* | |
444 | 4840 Start writing all keyboard characters to a dribble file called FILENAME. |
4841 If FILENAME is nil, close any open dribble file. | |
428 | 4842 */ |
444 | 4843 (filename)) |
428 | 4844 { |
4845 /* This function can GC */ | |
4846 /* XEmacs change: always close existing dribble file. */ | |
4847 /* FSFmacs uses FILE *'s here. With lstreams, that's unnecessary. */ | |
4848 if (!NILP (Vdribble_file)) | |
4849 { | |
4850 Lstream_close (XLSTREAM (Vdribble_file)); | |
4851 Vdribble_file = Qnil; | |
4852 } | |
444 | 4853 if (!NILP (filename)) |
428 | 4854 { |
4855 int fd; | |
4856 | |
444 | 4857 filename = Fexpand_file_name (filename, Qnil); |
771 | 4858 fd = qxe_open (XSTRING_DATA (filename), |
4859 O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY, | |
4860 CREAT_MODE); | |
428 | 4861 if (fd < 0) |
563 | 4862 report_file_error ("Unable to create dribble file", filename); |
428 | 4863 Vdribble_file = make_filedesc_output_stream (fd, 0, 0, LSTR_CLOSING); |
4864 #ifdef MULE | |
4865 Vdribble_file = | |
771 | 4866 make_coding_output_stream |
4867 (XLSTREAM (Vdribble_file), | |
800 | 4868 Qescape_quoted, CODING_ENCODE, 0); |
428 | 4869 #endif |
4870 } | |
4871 return Qnil; | |
4872 } | |
4873 | |
4874 | |
442 | 4875 |
4876 DEFUN ("current-event-timestamp", Fcurrent_event_timestamp, 0, 1, 0, /* | |
4877 Return the current event timestamp of the window system associated with CONSOLE. | |
4878 CONSOLE defaults to the selected console if omitted. | |
4879 */ | |
4880 (console)) | |
4881 { | |
4882 struct console *c = decode_console (console); | |
4883 int tiempo = event_stream_current_event_timestamp (c); | |
4884 | |
4885 /* This junk is so that timestamps don't get to be negative, but contain | |
4886 as many bits as this particular emacs will allow. | |
4887 */ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4888 return make_fixnum (MOST_POSITIVE_FIXNUM & tiempo); |
442 | 4889 } |
4890 | |
4891 | |
428 | 4892 /************************************************************************/ |
4893 /* initialization */ | |
4894 /************************************************************************/ | |
4895 | |
4896 void | |
4897 syms_of_event_stream (void) | |
4898 { | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
4899 INIT_LISP_OBJECT (command_builder); |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
4900 INIT_LISP_OBJECT (timeout); |
442 | 4901 |
563 | 4902 DEFSYMBOL (Qdisabled); |
4903 DEFSYMBOL (Qcommand_event_p); | |
4904 | |
4905 DEFERROR_STANDARD (Qundefined_keystroke_sequence, Qsyntax_error); | |
4906 DEFERROR_STANDARD (Qinvalid_key_binding, Qinvalid_state); | |
428 | 4907 |
4908 DEFSUBR (Frecent_keys); | |
4909 DEFSUBR (Frecent_keys_ring_size); | |
4910 DEFSUBR (Fset_recent_keys_ring_size); | |
4911 DEFSUBR (Finput_pending_p); | |
4912 DEFSUBR (Fenqueue_eval_event); | |
4913 DEFSUBR (Fnext_event); | |
4914 DEFSUBR (Fnext_command_event); | |
4915 DEFSUBR (Fdiscard_input); | |
4916 DEFSUBR (Fsit_for); | |
4917 DEFSUBR (Fsleep_for); | |
4918 DEFSUBR (Faccept_process_output); | |
4919 DEFSUBR (Fadd_timeout); | |
4920 DEFSUBR (Fdisable_timeout); | |
4921 DEFSUBR (Fadd_async_timeout); | |
4922 DEFSUBR (Fdisable_async_timeout); | |
4923 DEFSUBR (Fdispatch_event); | |
442 | 4924 DEFSUBR (Fdispatch_non_command_events); |
428 | 4925 DEFSUBR (Fread_key_sequence); |
4926 DEFSUBR (Fthis_command_keys); | |
4927 DEFSUBR (Freset_this_command_lengths); | |
4928 DEFSUBR (Fopen_dribble_file); | |
442 | 4929 DEFSUBR (Fcurrent_event_timestamp); |
428 | 4930 |
563 | 4931 DEFSYMBOL (Qpre_command_hook); |
4932 DEFSYMBOL (Qpost_command_hook); | |
4933 DEFSYMBOL (Qunread_command_events); | |
4934 DEFSYMBOL (Qunread_command_event); | |
4935 DEFSYMBOL (Qpre_idle_hook); | |
4936 DEFSYMBOL (Qhandle_pre_motion_command); | |
4937 DEFSYMBOL (Qhandle_post_motion_command); | |
4938 DEFSYMBOL (Qretry_undefined_key_binding_unshifted); | |
4939 DEFSYMBOL (Qauto_show_make_point_visible); | |
4940 | |
4941 DEFSYMBOL (Qself_insert_defer_undo); | |
4942 DEFSYMBOL (Qcancel_mode_internal); | |
1292 | 4943 |
4944 DEFSYMBOL (Qnext_event); | |
4945 DEFSYMBOL (Qdispatch_event); | |
5139
a48ef26d87ee
Clean up prototypes for Lisp variables/symbols. Put decls for them with
Ben Wing <ben@xemacs.org>
parents:
5050
diff
changeset
|
4946 |
a48ef26d87ee
Clean up prototypes for Lisp variables/symbols. Put decls for them with
Ben Wing <ben@xemacs.org>
parents:
5050
diff
changeset
|
4947 DEFSYMBOL (Qsans_modifiers); |
428 | 4948 } |
4949 | |
4950 void | |
4951 reinit_vars_of_event_stream (void) | |
4952 { | |
4953 recent_keys_ring_index = 0; | |
4954 recent_keys_ring_size = 100; | |
4955 num_input_chars = 0; | |
4956 the_low_level_timeout_blocktype = | |
4957 Blocktype_new (struct low_level_timeout_blocktype); | |
4958 something_happened = 0; | |
1268 | 4959 recursive_sit_for = 0; |
4960 in_modal_loop = 0; | |
428 | 4961 } |
4962 | |
4963 void | |
4964 vars_of_event_stream (void) | |
4965 { | |
4966 Vrecent_keys_ring = Qnil; | |
4967 staticpro (&Vrecent_keys_ring); | |
4968 | |
4969 Vthis_command_keys = Qnil; | |
4970 staticpro (&Vthis_command_keys); | |
4971 Vthis_command_keys_tail = Qnil; | |
1204 | 4972 dump_add_root_lisp_object (&Vthis_command_keys_tail); |
428 | 4973 |
4974 command_event_queue = Qnil; | |
4975 staticpro (&command_event_queue); | |
4976 command_event_queue_tail = Qnil; | |
1204 | 4977 dump_add_root_lisp_object (&command_event_queue_tail); |
4978 | |
4979 dispatch_event_queue = Qnil; | |
4980 staticpro (&dispatch_event_queue); | |
4981 dispatch_event_queue_tail = Qnil; | |
4982 dump_add_root_lisp_object (&dispatch_event_queue_tail); | |
428 | 4983 |
4984 Vlast_selected_frame = Qnil; | |
4985 staticpro (&Vlast_selected_frame); | |
4986 | |
4987 pending_timeout_list = Qnil; | |
4988 staticpro (&pending_timeout_list); | |
4989 | |
4990 pending_async_timeout_list = Qnil; | |
4991 staticpro (&pending_async_timeout_list); | |
4992 | |
4993 last_point_position_buffer = Qnil; | |
4994 staticpro (&last_point_position_buffer); | |
4995 | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
4996 QSnext_event_internal = build_ascstring ("next_event_internal()"); |
1292 | 4997 staticpro (&QSnext_event_internal); |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
4998 QSexecute_internal_event = build_ascstring ("execute_internal_event()"); |
1292 | 4999 staticpro (&QSexecute_internal_event); |
5000 | |
428 | 5001 DEFVAR_LISP ("echo-keystrokes", &Vecho_keystrokes /* |
5002 *Nonzero means echo unfinished commands after this many seconds of pause. | |
5003 */ ); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5004 Vecho_keystrokes = make_fixnum (1); |
428 | 5005 |
5006 DEFVAR_INT ("auto-save-interval", &auto_save_interval /* | |
5007 *Number of keyboard input characters between auto-saves. | |
5008 Zero means disable autosaving due to number of characters typed. | |
5009 See also the variable `auto-save-timeout'. | |
5010 */ ); | |
5011 auto_save_interval = 300; | |
5012 | |
5013 DEFVAR_LISP ("pre-command-hook", &Vpre_command_hook /* | |
5014 Function or functions to run before every command. | |
5015 This may examine the `this-command' variable to find out what command | |
5016 is about to be run, or may change it to cause a different command to run. | |
853 | 5017 Errors while running the hook are caught and turned into warnings. |
428 | 5018 */ ); |
5019 Vpre_command_hook = Qnil; | |
5020 | |
5021 DEFVAR_LISP ("post-command-hook", &Vpost_command_hook /* | |
5022 Function or functions to run after every command. | |
5023 This may examine the `this-command' variable to find out what command | |
5024 was just executed. | |
5025 */ ); | |
5026 Vpost_command_hook = Qnil; | |
5027 | |
5028 DEFVAR_LISP ("pre-idle-hook", &Vpre_idle_hook /* | |
5029 Normal hook run when XEmacs it about to be idle. | |
5030 This occurs whenever it is going to block, waiting for an event. | |
5031 This generally happens as a result of a call to `next-event', | |
5032 `next-command-event', `sit-for', `sleep-for', `accept-process-output', | |
853 | 5033 or `get-selection'. Errors while running the hook are caught and |
5034 turned into warnings. | |
428 | 5035 */ ); |
5036 Vpre_idle_hook = Qnil; | |
5037 | |
5038 DEFVAR_BOOL ("focus-follows-mouse", &focus_follows_mouse /* | |
5039 *Variable to control XEmacs behavior with respect to focus changing. | |
5040 If this variable is set to t, then XEmacs will not gratuitously change | |
5041 the keyboard focus. XEmacs cannot in general detect when this mode is | |
5042 used by the window manager, so it is up to the user to set it. | |
5043 */ ); | |
5044 focus_follows_mouse = 0; | |
5045 | |
5046 DEFVAR_LISP ("last-command-event", &Vlast_command_event /* | |
5047 Last keyboard or mouse button event that was part of a command. This | |
5048 variable is off limits: you may not set its value or modify the event that | |
5049 is its value, as it is destructively modified by `read-key-sequence'. If | |
5050 you want to keep a pointer to this value, you must use `copy-event'. | |
5051 */ ); | |
5052 Vlast_command_event = Qnil; | |
5053 | |
5054 DEFVAR_LISP ("last-command-char", &Vlast_command_char /* | |
5055 If the value of `last-command-event' is a keyboard event, then | |
5056 this is the nearest ASCII equivalent to it. This is the value that | |
5057 `self-insert-command' will put in the buffer. Remember that there is | |
5058 NOT a 1:1 mapping between keyboard events and ASCII characters: the set | |
5059 of keyboard events is much larger, so writing code that examines this | |
5060 variable to determine what key has been typed is bad practice, unless | |
5061 you are certain that it will be one of a small set of characters. | |
5062 */ ); | |
5063 Vlast_command_char = Qnil; | |
5064 | |
5065 DEFVAR_LISP ("last-input-event", &Vlast_input_event /* | |
5066 Last keyboard or mouse button event received. This variable is off | |
5067 limits: you may not set its value or modify the event that is its value, as | |
5068 it is destructively modified by `next-event'. If you want to keep a pointer | |
5069 to this value, you must use `copy-event'. | |
5070 */ ); | |
5071 Vlast_input_event = Qnil; | |
5072 | |
5073 DEFVAR_LISP ("current-mouse-event", &Vcurrent_mouse_event /* | |
5074 The mouse-button event which invoked this command, or nil. | |
5075 This is usually what `(interactive "e")' returns. | |
5076 */ ); | |
5077 Vcurrent_mouse_event = Qnil; | |
5078 | |
5079 DEFVAR_LISP ("last-input-char", &Vlast_input_char /* | |
5080 If the value of `last-input-event' is a keyboard event, then | |
5081 this is the nearest ASCII equivalent to it. Remember that there is | |
5082 NOT a 1:1 mapping between keyboard events and ASCII characters: the set | |
5083 of keyboard events is much larger, so writing code that examines this | |
5084 variable to determine what key has been typed is bad practice, unless | |
5085 you are certain that it will be one of a small set of characters. | |
5086 */ ); | |
5087 Vlast_input_char = Qnil; | |
5088 | |
5089 DEFVAR_LISP ("last-input-time", &Vlast_input_time /* | |
5090 The time (in seconds since Jan 1, 1970) of the last-command-event, | |
5091 represented as a cons of two 16-bit integers. This is destructively | |
5092 modified, so copy it if you want to keep it. | |
5093 */ ); | |
5094 Vlast_input_time = Qnil; | |
5095 | |
5096 DEFVAR_LISP ("last-command-event-time", &Vlast_command_event_time /* | |
5097 The time (in seconds since Jan 1, 1970) of the last-command-event, | |
5098 represented as a list of three integers. The first integer contains | |
5099 the most significant 16 bits of the number of seconds, and the second | |
5100 integer contains the least significant 16 bits. The third integer | |
5101 contains the remainder number of microseconds, if the current system | |
5102 supports microsecond clock resolution. This list is destructively | |
5103 modified, so copy it if you want to keep it. | |
5104 */ ); | |
5105 Vlast_command_event_time = Qnil; | |
5106 | |
5107 DEFVAR_LISP ("unread-command-events", &Vunread_command_events /* | |
5108 List of event objects to be read as next command input events. | |
5109 This can be used to simulate the receipt of events from the user. | |
5110 Normally this is nil. | |
5111 Events are removed from the front of this list. | |
5112 */ ); | |
5113 Vunread_command_events = Qnil; | |
5114 | |
5115 DEFVAR_LISP ("unread-command-event", &Vunread_command_event /* | |
5116 Obsolete. Use `unread-command-events' instead. | |
5117 */ ); | |
5118 Vunread_command_event = Qnil; | |
5119 | |
5120 DEFVAR_LISP ("last-command", &Vlast_command /* | |
5121 The last command executed. Normally a symbol with a function definition, | |
5122 but can be whatever was found in the keymap, or whatever the variable | |
5123 `this-command' was set to by that command. | |
5124 */ ); | |
5125 Vlast_command = Qnil; | |
5126 | |
5127 DEFVAR_LISP ("this-command", &Vthis_command /* | |
5128 The command now being executed. | |
5129 The command can set this variable; whatever is put here | |
5130 will be in `last-command' during the following command. | |
5131 */ ); | |
5132 Vthis_command = Qnil; | |
5133 | |
442 | 5134 DEFVAR_LISP ("last-command-properties", &Vlast_command_properties /* |
5135 Value of `this-command-properties' for the last command. | |
5136 Used by commands to help synchronize consecutive commands, in preference | |
5137 to looking at `last-command' directly. | |
5138 */ ); | |
5139 Vlast_command_properties = Qnil; | |
5140 | |
5141 DEFVAR_LISP ("this-command-properties", &Vthis_command_properties /* | |
5142 Properties set by the current command. | |
5143 At the beginning of each command, the current value of this variable is | |
5144 copied to `last-command-properties', and then it is set to nil. Use `putf' | |
5145 to add properties to this variable. Commands should use this to communicate | |
5146 with pre/post-command hooks, subsequent commands, wrapping commands, etc. | |
5147 in preference to looking at and/or setting `this-command'. | |
5148 */ ); | |
5149 Vthis_command_properties = Qnil; | |
5150 | |
428 | 5151 DEFVAR_LISP ("help-char", &Vhelp_char /* |
5152 Character to recognize as meaning Help. | |
5153 When it is read, do `(eval help-form)', and display result if it's a string. | |
5154 If the value of `help-form' is nil, this char can be read normally. | |
5155 This can be any form recognized as a single key specifier. | |
5156 The help-char cannot be a negative number in XEmacs. | |
5157 */ ); | |
5158 Vhelp_char = make_char (8); /* C-h */ | |
5159 | |
5160 DEFVAR_LISP ("help-form", &Vhelp_form /* | |
5161 Form to execute when character help-char is read. | |
5162 If the form returns a string, that string is displayed. | |
5163 If `help-form' is nil, the help char is not recognized. | |
5164 */ ); | |
5165 Vhelp_form = Qnil; | |
5166 | |
5167 DEFVAR_LISP ("prefix-help-command", &Vprefix_help_command /* | |
5168 Command to run when `help-char' character follows a prefix key. | |
5169 This command is used only when there is no actual binding | |
5170 for that character after that prefix key. | |
5171 */ ); | |
5172 Vprefix_help_command = Qnil; | |
5173 | |
5174 DEFVAR_CONST_LISP ("keyboard-translate-table", &Vkeyboard_translate_table /* | |
5175 Hash table used as translate table for keyboard input. | |
5176 Use `keyboard-translate' to portably add entries to this table. | |
5177 Each key-press event is looked up in this table as follows: | |
5178 | |
5179 -- If an entry maps a symbol to a symbol, then a key-press event whose | |
5180 keysym is the former symbol (with any modifiers at all) gets its | |
5181 keysym changed and its modifiers left alone. This is useful for | |
5182 dealing with non-standard X keyboards, such as the grievous damage | |
5183 that Sun has inflicted upon the world. | |
442 | 5184 -- If an entry maps a symbol to a character, then a key-press event |
5185 whose keysym is the former symbol (with any modifiers at all) gets | |
5186 changed into a key-press event matching the latter character, and the | |
5187 resulting modifiers are the union of the original and new modifiers. | |
428 | 5188 -- If an entry maps a character to a character, then a key-press event |
5189 matching the former character gets converted to a key-press event | |
5190 matching the latter character. This is useful on ASCII terminals | |
5191 for (e.g.) making C-\\ look like C-s, to get around flow-control | |
5192 problems. | |
5193 -- If an entry maps a character to a symbol, then a key-press event | |
5194 matching the character gets converted to a key-press event whose | |
5195 keysym is the given symbol and which has no modifiers. | |
442 | 5196 |
5197 Here's an example: This makes typing parens and braces easier by rerouting | |
5198 their positions to eliminate the need to use the Shift key. | |
5199 | |
5200 (keyboard-translate ?[ ?() | |
5201 (keyboard-translate ?] ?)) | |
5202 (keyboard-translate ?{ ?[) | |
5203 (keyboard-translate ?} ?]) | |
5204 (keyboard-translate 'f11 ?{) | |
5205 (keyboard-translate 'f12 ?}) | |
428 | 5206 */ ); |
5207 | |
5208 DEFVAR_LISP ("retry-undefined-key-binding-unshifted", | |
5209 &Vretry_undefined_key_binding_unshifted /* | |
5210 If a key-sequence which ends with a shifted keystroke is undefined | |
5211 and this variable is non-nil then the command lookup is retried again | |
5212 with the last key unshifted. (e.g. C-X C-F would be retried as C-X C-f.) | |
5213 If lookup still fails, a normal error is signalled. In general, | |
5214 you should *bind* this, not set it. | |
5215 */ ); | |
5216 Vretry_undefined_key_binding_unshifted = Qt; | |
5217 | |
442 | 5218 DEFVAR_BOOL ("modifier-keys-are-sticky", &modifier_keys_are_sticky /* |
5219 *Non-nil makes modifier keys sticky. | |
5220 This means that you can release the modifier key before pressing down | |
5221 the key that you wish to be modified. Although this is non-standard | |
5222 behavior, it is recommended because it reduces the strain on your hand, | |
5223 thus reducing the incidence of the dreaded Emacs-pinky syndrome. | |
444 | 5224 |
5225 Modifier keys are sticky within the inverval specified by | |
5226 `modifier-keys-sticky-time'. | |
442 | 5227 */ ); |
5228 modifier_keys_are_sticky = 0; | |
5229 | |
444 | 5230 DEFVAR_LISP ("modifier-keys-sticky-time", &Vmodifier_keys_sticky_time /* |
5231 *Modifier keys are sticky within this many milliseconds. | |
5232 If you don't want modifier keys sticking to be bounded, set this to | |
5233 non-integer value. | |
5234 | |
5235 This variable has no effect when `modifier-keys-are-sticky' is nil. | |
5236 Currently only implemented under X Window System. | |
5237 */ ); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5238 Vmodifier_keys_sticky_time = make_fixnum (500); |
444 | 5239 |
428 | 5240 Vcontrolling_terminal = Qnil; |
5241 staticpro (&Vcontrolling_terminal); | |
5242 | |
5243 Vdribble_file = Qnil; | |
5244 staticpro (&Vdribble_file); | |
5245 | |
5246 #ifdef DEBUG_XEMACS | |
5247 DEFVAR_INT ("debug-emacs-events", &debug_emacs_events /* | |
5248 If non-zero, display debug information about Emacs events that XEmacs sees. | |
5249 Information is displayed on stderr. | |
5250 | |
5251 Before the event, the source of the event is displayed in parentheses, | |
5252 and is one of the following: | |
5253 | |
5254 \(real) A real event from the window system or | |
5255 terminal driver, as far as XEmacs can tell. | |
5256 | |
5257 \(keyboard macro) An event generated from a keyboard macro. | |
5258 | |
5259 \(unread-command-events) An event taken from `unread-command-events'. | |
5260 | |
5261 \(unread-command-event) An event taken from `unread-command-event'. | |
5262 | |
5263 \(command event queue) An event taken from an internal queue. | |
5264 Events end up on this queue when | |
5265 `enqueue-eval-event' is called or when | |
5266 user or eval events are received while | |
5267 XEmacs is blocking (e.g. in `sit-for', | |
5268 `sleep-for', or `accept-process-output', | |
5269 or while waiting for the reply to an | |
5270 X selection). | |
5271 | |
5272 \(->keyboard-translate-table) The result of an event translated through | |
5273 keyboard-translate-table. Note that in | |
5274 this case, two events are printed even | |
5275 though only one is really generated. | |
5276 | |
5277 \(SIGINT) A faked C-g resulting when XEmacs receives | |
5278 a SIGINT (e.g. C-c was pressed in XEmacs' | |
5279 controlling terminal or the signal was | |
5280 explicitly sent to the XEmacs process). | |
5281 */ ); | |
5282 debug_emacs_events = 0; | |
5283 #endif | |
5284 | |
2828 | 5285 DEFVAR_BOOL ("inhibit-input-event-recording", |
5286 &inhibit_input_event_recording /* | |
428 | 5287 Non-nil inhibits recording of input-events to recent-keys ring. |
5288 */ ); | |
5289 inhibit_input_event_recording = 0; | |
771 | 5290 |
428 | 5291 Vkeyboard_translate_table = |
5191
71ee43b8a74d
Add #'equalp as a hash test by default; add #'define-hash-table-test, GNU API
Aidan Kehoe <kehoea@parhasard.net>
parents:
5143
diff
changeset
|
5292 make_lisp_hash_table (100, HASH_TABLE_NON_WEAK, Qequal); |
2828 | 5293 |
5294 DEFVAR_BOOL ("try-alternate-layouts-for-commands", | |
5295 &try_alternate_layouts_for_commands /* | |
5296 Non-nil means that if looking up a command from a sequence of keys typed by | |
5297 the user would otherwise fail, try it again with some other keyboard | |
5298 layout. On X11, the only alternative to the default mapping is American | |
5299 QWERTY; on Windows, other mappings may be available, depending on things | |
5300 like the default language environment for the current user, for the system, | |
5301 &c. | |
5302 | |
5303 With a Russian keyboard layout on X11, for example, this means that | |
5304 C-Cyrillic_che C-Cyrillic_a, if you haven't given that sequence a binding | |
5305 yourself, will invoke `find-file.' This is because `Cyrillic_che' is | |
5306 physically where `x' is, and `Cyrillic_a' is where `f' is, on an American | |
5307 Qwerty layout, and, of course, C-x C-f is a default emacs binding for that | |
5308 command. | |
5309 */ ); | |
5310 try_alternate_layouts_for_commands = 1; | |
428 | 5311 } |
5312 | |
5313 void | |
5314 init_event_stream (void) | |
5315 { | |
814 | 5316 /* Normally we don't initialize the event stream when running a bare |
5317 temacs (the check for initialized) because it may do various things | |
5318 (e.g. under Xt) that we don't want any traces of in a dumped xemacs. | |
5319 However, sometimes we need to process events in a bare temacs (in | |
5320 particular, when make-docfile.el is executed); so we initialize as | |
5321 necessary in check_event_stream_ok(). */ | |
428 | 5322 if (initialized) |
5323 { | |
5324 #ifdef HAVE_UNIXOID_EVENT_LOOP | |
5325 init_event_unixoid (); | |
5326 #endif | |
5327 #ifdef HAVE_X_WINDOWS | |
5328 if (!strcmp (display_use, "x")) | |
5329 init_event_Xt_late (); | |
5330 else | |
5331 #endif | |
462 | 5332 #ifdef HAVE_GTK |
5333 if (!strcmp (display_use, "gtk")) | |
5334 init_event_gtk_late (); | |
5335 else | |
5336 #endif | |
428 | 5337 #ifdef HAVE_MS_WINDOWS |
5338 if (!strcmp (display_use, "mswindows")) | |
5339 init_event_mswindows_late (); | |
5340 else | |
5341 #endif | |
5342 { | |
5343 /* For TTY's, use the Xt event loop if we can; it allows | |
5344 us to later open an X connection. */ | |
5345 #if defined (HAVE_MS_WINDOWS) && (!defined (HAVE_TTY) \ | |
5346 || (defined (HAVE_MSG_SELECT) \ | |
5347 && !defined (DEBUG_TTY_EVENT_STREAM))) | |
5348 init_event_mswindows_late (); | |
5349 #elif defined (HAVE_X_WINDOWS) && !defined (DEBUG_TTY_EVENT_STREAM) | |
5350 init_event_Xt_late (); | |
5351 #elif defined (HAVE_TTY) | |
5352 init_event_tty_late (); | |
5353 #endif | |
5354 } | |
5355 init_interrupts_late (); | |
5356 } | |
5357 } | |
5358 | |
5359 | |
5360 /* | |
853 | 5361 #### this comment is at least 8 years old and some may no longer apply. |
5362 | |
428 | 5363 useful testcases for v18/v19 compatibility: |
5364 | |
5365 (defun foo () | |
5366 (interactive) | |
5367 (setq unread-command-event (character-to-event ?A (allocate-event))) | |
5368 (setq x (list (read-char) | |
5369 ; (read-key-sequence "") ; try it with and without this | |
5370 last-command-char last-input-char | |
5371 (recent-keys) (this-command-keys)))) | |
5372 (global-set-key "\^Q" 'foo) | |
5373 | |
5374 without the read-key-sequence: | |
444 | 5375 ^Q ==> (?A ?\^Q ?A [... ^Q] [^Q]) |
5376 ^U^U^Q ==> (?A ?\^Q ?A [... ^U ^U ^Q] [^U ^U ^Q]) | |
5377 ^U^U^U^G^Q ==> (?A ?\^Q ?A [... ^U ^U ^U ^G ^Q] [^Q]) | |
428 | 5378 |
5379 with the read-key-sequence: | |
444 | 5380 ^Qb ==> (?A [b] ?\^Q ?b [... ^Q b] [b]) |
5381 ^U^U^Qb ==> (?A [b] ?\^Q ?b [... ^U ^U ^Q b] [b]) | |
5382 ^U^U^U^G^Qb ==> (?A [b] ?\^Q ?b [... ^U ^U ^U ^G ^Q b] [b]) | |
428 | 5383 |
5384 ;the evi-mode command "4dlj.j.j.j.j.j." is also a good testcase (gag) | |
5385 | |
5386 ;(setq x (list (read-char) quit-flag))^J^G | |
5387 ;(let ((inhibit-quit t)) (setq x (list (read-char) quit-flag)))^J^G | |
5388 ;for BOTH, x should get set to (7 t), but no result should be printed. | |
444 | 5389 ;; #### According to the doc of quit-flag, second test should return |
5384
3889ef128488
Fix misspelled words, and some grammar, across the entire source tree.
Jerry James <james@xemacs.org>
parents:
5371
diff
changeset
|
5390 ;; (?\^G nil). XEmacs accidentally returns the correct value. However, |
3889ef128488
Fix misspelled words, and some grammar, across the entire source tree.
Jerry James <james@xemacs.org>
parents:
5371
diff
changeset
|
5391 ;; XEmacs 21.1.12 and 21.2.36 both fail on the first test. |
428 | 5392 |
5393 ;also do this: make two frames, one viewing "*scratch*", the other "foo". | |
5394 ;in *scratch*, type (sit-for 20)^J | |
5395 ;wait a couple of seconds, move cursor to foo, type "a" | |
5396 ;a should be inserted in foo. Cursor highlighting should not change in | |
5397 ;the meantime. | |
5398 | |
5399 ;do it with sleep-for. move cursor into foo, then back into *scratch* | |
5400 ;before typing. | |
5401 ;repeat also with (accept-process-output nil 20) | |
5402 | |
5403 ;make sure ^G aborts sit-for, sleep-for and accept-process-output: | |
5404 | |
5405 (defun tst () | |
5406 (list (condition-case c | |
5407 (sleep-for 20) | |
5408 (quit c)) | |
5409 (read-char))) | |
5410 | |
444 | 5411 (tst)^Ja^G ==> ((quit) ?a) with no signal |
5412 (tst)^J^Ga ==> ((quit) ?a) with no signal | |
5413 (tst)^Jabc^G ==> ((quit) ?a) with no signal, and "bc" inserted in buffer | |
428 | 5414 |
5415 ; with sit-for only do the 2nd test. | |
5416 ; Do all 3 tests with (accept-process-output nil 20) | |
5417 | |
5418 Do this: | |
5419 (setq enable-recursive-minibuffers t | |
5420 minibuffer-max-depth nil) | |
5421 ESC ESC ESC ESC - there are now two minibuffers active | |
5422 C-g C-g C-g - there should be active 0, not 1 | |
5423 Similarly: | |
5424 C-x C-f ~ / ? - wait for "Making completion list..." to display | |
5425 C-g - wait for "Quit" to display | |
5426 C-g - minibuffer should not be active | |
5427 however C-g before "Quit" is displayed should leave minibuffer active. | |
5428 | |
5429 ;do it all in both v18 and v19 and make sure all results are the same. | |
5430 ;all of these cases matter a lot, but some in quite subtle ways. | |
5431 */ | |
5432 | |
5433 /* | |
5434 Additional test cases for accept-process-output, sleep-for, sit-for. | |
5435 Be sure you do all of the above checking for C-g and focus, too! | |
5436 | |
5437 ; Make sure that timer handlers are run during, not after sit-for: | |
5438 (defun timer-check () | |
5439 (add-timeout 2 '(lambda (ignore) (message "timer ran")) nil) | |
5440 (sit-for 5) | |
5441 (message "after sit-for")) | |
5442 | |
5443 ; The first message should appear after 2 seconds, and the final message | |
5444 ; 3 seconds after that. | |
5445 ; repeat above test with (sleep-for 5) and (accept-process-output nil 5) | |
5446 | |
5447 | |
5448 | |
5449 ; Make sure that process filters are run during, not after sit-for. | |
5450 (defun fubar () | |
5451 (message "sit-for = %s" (sit-for 30))) | |
5452 (add-hook 'post-command-hook 'fubar) | |
5453 | |
5454 ; Now type M-x shell RET | |
5455 ; wait for the shell prompt then send: ls RET | |
5456 ; the output of ls should fill immediately, and not wait 30 seconds. | |
5457 | |
5458 ; repeat above test with (sleep-for 30) and (accept-process-output nil 30) | |
5459 | |
5460 | |
5461 | |
5462 ; Make sure that recursive invocations return immediately: | |
5463 (defmacro test-diff-time (start end) | |
5464 `(+ (* (- (car ,end) (car ,start)) 65536.0) | |
5465 (- (cadr ,end) (cadr ,start)) | |
5466 (/ (- (caddr ,end) (caddr ,start)) 1000000.0))) | |
5467 | |
5468 (defun testee (ignore) | |
5469 (sit-for 10)) | |
5470 | |
5471 (defun test-them () | |
5472 (let ((start (current-time)) | |
5473 end) | |
5474 (add-timeout 2 'testee nil) | |
5475 (sit-for 5) | |
5476 (add-timeout 2 'testee nil) | |
5477 (sleep-for 5) | |
5478 (add-timeout 2 'testee nil) | |
5479 (accept-process-output nil 5) | |
5480 (setq end (current-time)) | |
5481 (test-diff-time start end))) | |
5482 | |
5483 (test-them) should sit for 15 seconds. | |
5484 Repeat with testee set to sleep-for and accept-process-output. | |
5485 These should each delay 36 seconds. | |
5486 | |
5487 */ |