/* TODO:
This stuff is way too hard to maintain - needs rework.
- C-x @ h <scrollbar-drag> x causes a crash.
-
The command builder should deal only with key and button events.
Other command events should be able to come in the MIDDLE of a key
sequence, without disturbing the key sequence composition, or the
#include <errno.h>
/* The number of keystrokes between auto-saves. */
-static int auto_save_interval;
+static Fixnum auto_save_interval;
Lisp_Object Qundefined_keystroke_sequence;
/* Control gratuitous keyboard focus throwing. */
int focus_follows_mouse;
-#if 0 /* FSF Emacs crap */
-/* Hook run after a command if there's no more input soon. */
-Lisp_Object Qpost_command_idle_hook, Vpost_command_idle_hook;
-
-/* Delay time in microseconds before running post-command-idle-hook. */
-int post_command_idle_delay;
+/* When true, modifier keys are sticky. */
+int modifier_keys_are_sticky;
+/* Modifier keys are sticky for this many milliseconds. */
+Lisp_Object Vmodifier_keys_sticky_time;
-/* List of deferred actions to be performed at a later time.
- The precise format isn't relevant here; we just check whether it is nil. */
-Lisp_Object Vdeferred_action_list;
+/* Here FSF Emacs 20.7 defines Vpost_command_idle_hook,
+ post_command_idle_delay, Vdeferred_action_list, and
+ Vdeferred_action_function, but we don't because that stuff is crap,
+ and we're smarter than them, and their momas are fat. */
-/* Function to call to handle deferred actions, when there are any. */
-Lisp_Object Vdeferred_action_function;
-Lisp_Object Qdeferred_action_function;
-#endif /* FSF Emacs crap */
+/* FSF Emacs 20.7 also defines Vinput_method_function,
+ Qinput_method_exit_on_first_char and Qinput_method_use_echo_area.
+ I don't know this should be imported or not. */
/* Non-nil disable property on a command means
do not execute it; call disabled-command-hook's value instead. */
extern Lisp_Object Fmake_keymap (Lisp_Object name);
#ifdef DEBUG_XEMACS
-int debug_emacs_events;
+Fixnum debug_emacs_events;
static void
external_debugging_print_event (char *event_description, Lisp_Object event)
case EVENT_STREAM_READ:
error ("Can't read events in -batch mode");
default:
- abort ();
+ ABORT ();
}
}
else if (!event_stream)
Let's hope it doesn't. I think the code here is fairly
clean and doesn't do this. */
emacs_is_blocking = 1;
-#if 0
- /* Do this if the poll-for-quit timer seems to be taking too
- much CPU time when idle ... */
- reset_poll_for_quit ();
-#endif
event_stream->next_event_cb (event);
-#if 0
- init_poll_for_quit ();
-#endif
emacs_is_blocking = 0;
#ifdef DEBUG_XEMACS
event_stream->quit_p_cb ();
}
+static int
+event_stream_current_event_timestamp (struct console *c)
+{
+ if (event_stream && event_stream->current_event_timestamp_cb)
+ return event_stream->current_event_timestamp_cb (c);
+ else
+ return 0;
+}
\f
/**********************************************************************/
/* This function can GC */
struct frame *f = selected_frame ();
- command_builder->echo_buf_index = -1;
+ if (command_builder)
+ command_builder->echo_buf_index = -1;
if (remove_echo_area_echo)
clear_echo_area (f, Qcommand, 0);
This way is safer. */
zero_event (&ev2);
character_to_event (XCHAR (traduit), &ev2,
- XCONSOLE (EVENT_CHANNEL (XEVENT (event))), 1, 1);
+ XCONSOLE (EVENT_CHANNEL (XEVENT (event))), 0, 1);
XEVENT (event)->event.key.keysym = ev2.event.key.keysym;
XEVENT (event)->event.key.modifiers = ev2.event.key.modifiers;
did_translate = 1;
XEVENT (event)->event.key.keysym = traduit;
did_translate = 1;
}
+ else if (CHARP (traduit))
+ {
+ Lisp_Event ev2;
+
+ zero_event (&ev2);
+ character_to_event (XCHAR (traduit), &ev2,
+ XCONSOLE (EVENT_CHANNEL (XEVENT (event))), 0, 1);
+ XEVENT (event)->event.key.keysym = ev2.event.key.keysym;
+ XEVENT (event)->event.key.modifiers |= ev2.event.key.modifiers;
+ did_translate = 1;
+ }
}
#ifdef DEBUG_XEMACS
keystrokes_since_auto_save is equivalent to the difference between
num_nonmacro_input_chars and last_auto_save. */
-/* When an auto-save happens, record the "time", and don't do again soon. */
+/* When an auto-save happens, record the number of keystrokes, and
+ don't do again soon. */
void
record_auto_save (void)
force_auto_save_soon (void)
{
keystrokes_since_auto_save = 1 + max (auto_save_interval, 20);
-
-#if 0 /* FSFmacs */
- record_asynch_buffer_change ();
-#endif
}
static void
Lisp_Object lid;
id = event_stream_generate_wakeup (msecs, msecs2, function, object, 0);
lid = make_int (id);
- if (id != XINT (lid)) abort ();
+ if (id != XINT (lid)) ABORT ();
return lid;
}
Lisp_Object lid;
id = event_stream_generate_wakeup (msecs, msecs2, function, object, 1);
lid = make_int (id);
- if (id != XINT (lid)) abort ();
+ if (id != XINT (lid)) ABORT ();
return lid;
}
static void
run_deselect_frame_hook (void)
{
-#if 0 /* unclean! FSF calls this at all sorts of random places,
- including a bunch of places in their mouse.el. If this
- is implemented, it has to be done cleanly. */
- run_hook (Qmouse_leave_buffer_hook); /* #### Correct? It's also
- called in `call-interactively'.
- Does this mean it will be
- called twice? Oh well, FSF
- bug -- FSF calls it in
- `handle-switch-frame',
- which is approximately the
- same as the caller of this
- function. */
-#endif
run_hook (Qdeselect_frame_hook);
}
MARK_WINDOWS_CHANGED (w);
}
- if (FRAMEP (focus_frame) && !EQ (frame, focus_frame))
+ if (FRAMEP (focus_frame) && FRAME_LIVE_P (XFRAME (focus_frame))
+ && !EQ (frame, focus_frame))
{
/* Oops, we missed a focus-out event. */
DEVICE_FRAME_WITH_FOCUS_REAL (d) = Qnil;
static void push_recent_keys (Lisp_Object event);
static void dribble_out_event (Lisp_Object event);
static void execute_internal_event (Lisp_Object event);
+static int is_scrollbar_event (Lisp_Object event);
DEFUN ("next-event", Fnext_event, 0, 2, 0, /*
Return the next available event.
-- any events in `unread-command-events' or `unread-command-event'; else
-- the next event in the currently executing keyboard macro, if any; else
--- an event queued by `enqueue-eval-event', if any; else
+-- an event queued by `enqueue-eval-event', if any, or any similar event
+ queued internally, such as a misc-user event. (For example, when an item
+ is selected from a menu or from a `question'-type dialog box, the item's
+ callback is not immediately executed, but instead a misc-user event
+ is generated and placed onto this queue; when it is dispatched, the
+ callback is executed.) Else
-- the next available event from the window system or terminal driver.
In the last case, this function will block until an event is available.
switch (XEVENT_TYPE (event))
{
- default:
- goto RETURN;
case button_release_event:
case misc_user_event:
/* don't echo menu accelerator keys */
goto STORE_AND_EXECUTE_KEY;
case key_press_event: /* any key input can trigger autosave */
break;
+ default:
+ goto RETURN;
}
maybe_do_auto_save ();
*/
if (store_this_key)
{
- push_this_command_keys (event);
+ if (!is_scrollbar_event (event)) /* #### not quite right, see
+ comment in execute_command_event */
+ push_this_command_keys (event);
if (!inhibit_input_event_recording)
push_recent_keys (event);
dribble_out_event (event);
widgets. Normally these are redisplayed through a native window-system
event encoded as magic event, rather than by the redisplay code. This
function does not call redisplay or do any of the other things that
-`next-event' does.
+`next-event' does.
*/
())
{
}
if (!NILP (command_event_queue) || !NILP (command_event_queue_tail))
- abort ();
+ ABORT ();
/* Now tack our chain of events back on to the front of the queue.
Actually, since the queue is now drained, we can just replace it.
}
DEFUN ("sleep-for", Fsleep_for, 1, 1, 0, /*
-Pause, without updating display, for ARG seconds.
-ARG may be a float, meaning pause for some fractional part of a second.
+Pause, without updating display, for SECONDS seconds.
+SECONDS may be a float, allowing pauses for fractional parts of a second.
It is recommended that you never call sleep-for from inside of a process
- filter function or timer event (either synchronous or asynchronous).
+filter function or timer event (either synchronous or asynchronous).
*/
(seconds))
{
}
DEFUN ("sit-for", Fsit_for, 1, 2, 0, /*
-Perform redisplay, then wait ARG seconds or until user input is available.
-ARG may be a float, meaning a fractional part of a second.
-Optional second arg non-nil means don't redisplay, just wait for input.
+Perform redisplay, then wait SECONDS seconds or until user input is available.
+SECONDS may be a float, meaning a fractional part of a second.
+Optional second arg NODISPLAY non-nil means don't redisplay; just wait.
Redisplay is preempted as always if user input arrives, and does not
happen if input is available before it starts.
Value is t if waited the full time with no input arriving.
return result;
}
-/* This handy little function is used by xselect.c and energize.c to
- wait for replies from processes that aren't really processes (that is,
- the X server and the Energize server).
- */
+/* This handy little function is used by select-x.c to wait for replies
+ from processes that aren't really processes (e.g. the X server) */
void
wait_delaying_user_input (int (*predicate) (void *arg), void *predicate_arg)
{
return;
}
default:
- abort ();
+ ABORT ();
}
}
{
Vrecent_keys_ring = make_vector (recent_keys_ring_size, Qnil);
/* And return nothing in particular. */
- return make_vector (0, Qnil);
+ RETURN_UNGCPRO (make_vector (0, Qnil));
}
if (NILP (XVECTOR_DATA (Vrecent_keys_ring)[recent_keys_ring_index]))
Lisp_Object e = XVECTOR_DATA (Vrecent_keys_ring)[j];
if (NILP (e))
- abort ();
+ ABORT ();
XVECTOR_DATA (val)[i] = Fcopy_event (e, Qnil);
if (++j >= recent_keys_ring_size)
j = 0;
Lisp_Object new_vector = Qnil;
int i, j, nkeys, start, min;
struct gcpro gcpro1;
- GCPRO1 (new_vector);
CHECK_INT (size);
if (XINT (size) <= 0)
if (XINT (size) == recent_keys_ring_size)
return size;
+ GCPRO1 (new_vector);
new_vector = make_vector (XINT (size), Qnil);
if (NILP (Vrecent_keys_ring))
{
Vrecent_keys_ring = new_vector;
- return size;
+ RETURN_UNGCPRO (size);
}
if (NILP (XVECTOR_DATA (Vrecent_keys_ring)[recent_keys_ring_index]))
void
reset_this_command_keys (Lisp_Object console, int clear_echo_area_p)
{
- struct command_builder *command_builder =
- XCOMMAND_BUILDER (XCONSOLE (console)->command_builder);
-
- reset_key_echo (command_builder, clear_echo_area_p);
+ if (!NILP (console))
+ {
+ /* console is nil if we just deleted the console as a result of C-x 5
+ 0. Unfortunately things are currently in a messy situation where
+ some stuff is console-local and other stuff isn't, so we need to
+ do everything that's not console-local. */
+ struct command_builder *command_builder =
+ XCOMMAND_BUILDER (XCONSOLE (console)->command_builder);
+
+ reset_key_echo (command_builder, clear_echo_area_p);
+ reset_current_events (command_builder);
+ }
+ else
+ reset_key_echo (0, clear_echo_area_p);
deallocate_event_chain (Vthis_command_keys);
Vthis_command_keys = Qnil;
Vthis_command_keys_tail = Qnil;
-
- reset_current_events (command_builder);
}
static void
{
if (!n)
{
- /* must copy to avoid an abort() in next_event_internal() */
+ /* must copy to avoid an ABORT() in next_event_internal() */
if (!NILP (XEVENT_NEXT (event)))
return Fcopy_event (event, Qnil);
else
|| e->event_type == button_release_event)
e->event.button.modifiers |= XEMACS_MOD_META;
else
- abort ();
+ ABORT ();
{
int tckn = event_chain_count (Vthis_command_keys);
}
}
+static int
+is_scrollbar_event (Lisp_Object event)
+{
+#ifdef HAVE_SCROLLBARS
+ Lisp_Object fun;
+
+ if (XEVENT (event)->event_type != misc_user_event)
+ return 0;
+ fun = XEVENT (event)->event.misc.function;
+
+ return (EQ (fun, Qscrollbar_line_up) ||
+ EQ (fun, Qscrollbar_line_down) ||
+ EQ (fun, Qscrollbar_page_up) ||
+ EQ (fun, Qscrollbar_page_down) ||
+ EQ (fun, Qscrollbar_to_top) ||
+ EQ (fun, Qscrollbar_to_bottom) ||
+ EQ (fun, Qscrollbar_vertical_drag) ||
+ EQ (fun, Qscrollbar_char_left) ||
+ EQ (fun, Qscrollbar_char_right) ||
+ EQ (fun, Qscrollbar_page_left) ||
+ EQ (fun, Qscrollbar_page_right) ||
+ EQ (fun, Qscrollbar_to_left) ||
+ EQ (fun, Qscrollbar_to_right) ||
+ EQ (fun, Qscrollbar_horizontal_drag));
+#else
+ return 0;
+#endif /* HAVE_SCROLLBARS */
+}
+
static void
execute_command_event (struct command_builder *command_builder,
Lisp_Object event)
struct gcpro gcpro1;
GCPRO1 (event); /* event may be freshly created */
- reset_current_events (command_builder);
+
+ /* #### This call to is_scrollbar_event() isn't quite right, but
+ fixing properly it requires more work than can go into 21.4.
+ (We really need to split out menu, scrollbar, dialog, and other
+ types of events from misc-user, and put the remaining ones in a
+ new `user-eval' type that behaves like an eval event but is a
+ user event and thus has all of its semantics -- e.g. being
+ delayed during `accept-process-output' and similar wait states.)
+
+ The real issue here is that "user events" and "command events"
+ are not the same thing, but are very much confused in
+ event-stream.c. User events are, essentially, any event that
+ should be delayed by accept-process-output, should terminate a
+ sit-for, etc. -- basically, any event that needs to be processed
+ synchronously with key and mouse events. Command events are
+ those that participate in command building; scrollbar events
+ clearly don't belong because they should be transparent in a
+ sequence like C-x @ h <scrollbar-drag> x, which used to cause a
+ crash before checks similar to the is_scrollbar_event() call were
+ added. Do other events belong with scrollbar events? I'm not
+ sure; we need to categorize all misc-user events and see what
+ their semantics are.
+
+ (You might ask, why do scrollbar events need to be user events?
+ That's a good question. The answer seems to be that they can
+ change point, and having this happen asynchronously would be a
+ very bad idea. According to the "proper" functioning of
+ scrollbars, this should not happen, but XEmacs does not allow
+ point to go outside of the window.)
+
+ Scrollbar events and similar non-command events should obviously
+ not be recorded in this-command-keys, so we need to check for
+ this in next-event.
+
+ #### We call reset_current_events() twice in this function --
+ #### here, and later as a result of reset_this_command_keys().
+ #### This is almost certainly wrong; need to figure out what's
+ #### correct.
+
+ #### We need to figure out what's really correct w.r.t. scrollbar
+ #### events. With these new fixes in, it actually works to do
+ #### C-x <scrollbar-drag> 5 2, but the key echo gets messed up
+ #### (starts over at 5). We really need to be special-casing
+ #### scrollbar events at a lower level, and not really passing
+ #### them through the command builder at all. (e.g. do scrollbar
+ #### events belong in macros??? doubtful; probably only the
+ #### point movement, if any, belongs, special-cased as a
+ #### pseudo-issued M-x goto-char command). #### Need more work
+ #### here. Do this when separating out scrollbar events.
+ */
+
+ if (!is_scrollbar_event (event))
+ reset_current_events (command_builder);
switch (XEVENT (event)->event_type)
{
post_command_hook ();
-#if 0 /* #### here was an attempted fix that didn't work */
- if (XEVENT (event)->event_type == misc_user_event)
- ;
- else
-#endif
- if (!NILP (con->prefix_arg))
+ /* Console might have been deleted by command */
+ if (CONSOLE_LIVE_P (con) && !NILP (con->prefix_arg))
{
/* Commands that set the prefix arg don't update last-command, don't
reset the echoing state, and don't go into keyboard macros unless
- followed by another command. */
+ followed by another command. Also don't quit here. */
+ int speccount = specpdl_depth ();
+ specbind (Qinhibit_quit, Qt);
maybe_echo_keys (command_builder, 0);
+ unbind_to (speccount, Qnil);
/* If we're recording a keyboard macro, and the last command
executed set a prefix argument, then decrement the pointer to
/* Emacs 18 doesn't unconditionally clear the echoed keystrokes,
so we don't either */
- reset_this_command_keys (make_console (con), 0);
+
+ if (!is_scrollbar_event (event))
+ reset_this_command_keys (CONSOLE_LIVE_P (con) ? make_console (con)
+ : Qnil, 0);
}
}
("Error in `post-command-hook' (setting hook to nil)",
Qpost_command_hook, 1);
-#if 0 /* FSF Emacs crap */
- if (!NILP (Vdeferred_action_list))
- call0 (Vdeferred_action_function);
-
- if (NILP (Vunread_command_events)
- && NILP (Vexecuting_macro)
- && !NILP (Vpost_command_idle_hook)
- && !NILP (Fsit_for (make_float ((double) post_command_idle_delay
- / 1000000), Qnil)))
- safe_run_hook_trapping_errors
- ("Error in `post-command-idle-hook' (setting hook to nil)",
- Qpost_command_idle_hook, 1);
-#endif /* FSF Emacs crap */
-
-#if 0 /* FSF Emacs */
- if (!NILP (current_buffer->mark_active))
- {
- if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode))
- {
- current_buffer->mark_active = Qnil;
- run_hook (intern ("deactivate-mark-hook"));
- }
- else if (current_buffer != prev_buffer ||
- BUF_MODIFF (current_buffer) != prev_modiff)
- run_hook (intern ("activate-mark-hook"));
- }
-#endif /* FSF Emacs */
-
/* #### Kludge!!! This is necessary to make sure that things
are properly positioned even if post-command-hook moves point.
#### There should be a cleaner way of handling this. */
\f
DEFUN ("dispatch-event", Fdispatch_event, 1, 1, 0, /*
-Given an event object as returned by `next-event', execute it.
+Given an event object EVENT as returned by `next-event', execute it.
Key-press, button-press, and button-release events get accumulated
until a complete key sequence (see `read-key-sequence') is reached,
be done without an undo boundary. This counter is reset as
soon as a command other than self-insert-command is executed.
- Programmers can also use the `self-insert-undo-magic'
- property to install that behaviour on functions other
+ Programmers can also use the `self-insert-defer-undo'
+ property to install that behavior on functions other
than `self-insert-command', or to change the magic
- number 20 to something else. */
+ number 20 to something else. #### DOCUMENT THIS! */
if (SYMBOLP (leaf))
{
command_builder->self_insert_countdown = 0;
if (NILP (XCONSOLE (console)->prefix_arg)
&& NILP (Vexecuting_macro)
-#if 0
- /* This was done in the days when there was no undo
- in the minibuffer. If we don't disable this code,
- then each instance of "undo" undoes everything in
- the minibuffer. */
- && !EQ (minibuf_window, Fselected_window (Qnil))
-#endif
&& command_builder->self_insert_countdown == 0)
Fundo_boundary ();
}
execute_command_event
(command_builder,
- internal_equal (event, command_builder-> most_current_event, 0)
+ internal_equal (event, command_builder->most_current_event, 0)
? event
/* Use the translated event that was most recently seen.
This way, last-command-event becomes f1 instead of
the P from ESC O P. But we must copy it, else we'll
lose when the command-builder events are deallocated. */
- : Fcopy_event (command_builder-> most_current_event, Qnil));
+ : Fcopy_event (command_builder->most_current_event, Qnil));
}
break;
}
DEFUN ("read-key-sequence", Fread_key_sequence, 1, 3, 0, /*
Read a sequence of keystrokes or mouse clicks.
Returns a vector of the event objects read. The vector and the event
-objects it contains are freshly created (and will not be side-effected
+objects it contains are freshly created (and so will not be side-effected
by subsequent calls to this function).
The sequence read is sufficient to specify a non-prefix command starting
function is treated like any other character, and `quit-flag' is not set.
First arg PROMPT is a prompt string. If nil, do not prompt specially.
-Second (optional) arg CONTINUE-ECHO, if non-nil, means this key echoes
-as a continuation of the previous key.
-The third (optional) arg DONT-DOWNCASE-LAST, if non-nil, means do not
-convert the last event to lower case. (Normally any upper case event
-is converted to lower case if the original event is undefined and the lower
-case equivalent is defined.) This argument is provided mostly for
-FSF compatibility; the equivalent effect can be achieved more generally
-by binding `retry-undefined-key-binding-unshifted' to nil around the
-call to `read-key-sequence'.
+Second optional arg CONTINUE-ECHO non-nil means this key echoes as a
+continuation of the previous key.
-A C-g typed while in this function is treated like any other character,
-and `quit-flag' is not set.
+Third optional arg DONT-DOWNCASE-LAST non-nil means do not convert the
+last event to lower case. (Normally any upper case event is converted
+to lower case if the original event is undefined and the lower case
+equivalent is defined.) This argument is provided mostly for FSF
+compatibility; the equivalent effect can be achieved more generally by
+binding `retry-undefined-key-binding-unshifted' to nil around the call
+to `read-key-sequence'.
If the user selects a menu item while we are prompting for a key-sequence,
the returned value will be a vector of a single menu-selection event.
related function.
`read-key-sequence' checks `function-key-map' for function key
-sequences, where they wouldn't conflict with ordinary bindings. See
-`function-key-map' for more details.
+sequences, where they wouldn't conflict with ordinary bindings.
+See `function-key-map' for more details.
*/
(prompt, continue_echo, dont_downcase_last))
{
struct gcpro gcpro1;
GCPRO1 (event);
+ record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
if (!NILP (prompt))
CHECK_STRING (prompt);
/* else prompt = Fkeymap_prompt (current_buffer->keymap); may GC */
DEFUN ("open-dribble-file", Fopen_dribble_file, 1, 1,
"FOpen dribble file: ", /*
-Start writing all keyboard characters to a dribble file called FILE.
-If FILE is nil, close any open dribble file.
+Start writing all keyboard characters to a dribble file called FILENAME.
+If FILENAME is nil, close any open dribble file.
*/
- (file))
+ (filename))
{
/* This function can GC */
/* XEmacs change: always close existing dribble file. */
Lstream_close (XLSTREAM (Vdribble_file));
Vdribble_file = Qnil;
}
- if (!NILP (file))
+ if (!NILP (filename))
{
int fd;
- file = Fexpand_file_name (file, Qnil);
- fd = open ((char*) XSTRING_DATA (file),
+ filename = Fexpand_file_name (filename, Qnil);
+ fd = open ((char*) XSTRING_DATA (filename),
O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY,
CREAT_MODE);
if (fd < 0)
}
\f
+
+DEFUN ("current-event-timestamp", Fcurrent_event_timestamp, 0, 1, 0, /*
+Return the current event timestamp of the window system associated with CONSOLE.
+CONSOLE defaults to the selected console if omitted.
+*/
+ (console))
+{
+ struct console *c = decode_console (console);
+ int tiempo = event_stream_current_event_timestamp (c);
+
+ /* This junk is so that timestamps don't get to be negative, but contain
+ as many bits as this particular emacs will allow.
+ */
+ return make_int (EMACS_INT_MAX & tiempo);
+}
+
+\f
/************************************************************************/
/* initialization */
/************************************************************************/
defsymbol (&Qdisabled, "disabled");
defsymbol (&Qcommand_event_p, "command-event-p");
- deferror (&Qundefined_keystroke_sequence, "undefined-keystroke-sequence",
- "Undefined keystroke sequence", Qerror);
+ DEFERROR_STANDARD (Qundefined_keystroke_sequence, Qinvalid_argument);
DEFSUBR (Frecent_keys);
DEFSUBR (Frecent_keys_ring_size);
DEFSUBR (Fthis_command_keys);
DEFSUBR (Freset_this_command_lengths);
DEFSUBR (Fopen_dribble_file);
+ DEFSUBR (Fcurrent_event_timestamp);
defsymbol (&Qpre_command_hook, "pre-command-hook");
defsymbol (&Qpost_command_hook, "post-command-hook");
defsymbol (&Qpre_idle_hook, "pre-idle-hook");
defsymbol (&Qhandle_pre_motion_command, "handle-pre-motion-command");
defsymbol (&Qhandle_post_motion_command, "handle-post-motion-command");
-#if 0 /* FSF Emacs crap */
- defsymbol (&Qpost_command_idle_hook, "post-command-idle-hook");
- defsymbol (&Qdeferred_action_function, "deferred-action-function");
-#endif
defsymbol (&Qretry_undefined_key_binding_unshifted,
"retry-undefined-key-binding-unshifted");
defsymbol (&Qauto_show_make_point_visible,
Vthis_command_keys = Qnil;
staticpro (&Vthis_command_keys);
Vthis_command_keys_tail = Qnil;
- pdump_wire (&Vthis_command_keys_tail);
+ dump_add_root_object (&Vthis_command_keys_tail);
command_event_queue = Qnil;
staticpro (&command_event_queue);
command_event_queue_tail = Qnil;
- pdump_wire (&command_event_queue_tail);
+ dump_add_root_object (&command_event_queue_tail);
Vlast_selected_frame = Qnil;
staticpro (&Vlast_selected_frame);
This occurs whenever it is going to block, waiting for an event.
This generally happens as a result of a call to `next-event',
`next-command-event', `sit-for', `sleep-for', `accept-process-output',
-`x-get-selection', or various Energize-specific commands.
+or `x-get-selection'.
Errors running the hook are caught and ignored.
*/ );
Vpre_idle_hook = Qnil;
*/ );
focus_follows_mouse = 0;
-#if 0 /* FSF Emacs crap */
- /* Ill-conceived because it's not run in all sorts of cases
- where XEmacs is blocking. That's what `pre-idle-hook'
- is designed to solve. */
- xxDEFVAR_LISP ("post-command-idle-hook", &Vpost_command_idle_hook /*
-Normal hook run after each command is executed, if idle.
-`post-command-idle-delay' specifies a time in microseconds that XEmacs
-must be idle for in order for the functions on this hook to be called.
-Errors running the hook are caught and ignored.
-*/ );
- Vpost_command_idle_hook = Qnil;
-
- xxDEFVAR_INT ("post-command-idle-delay", &post_command_idle_delay /*
-Delay time before running `post-command-idle-hook'.
-This is measured in microseconds.
-*/ );
- post_command_idle_delay = 5000;
-
- /* Random FSFmacs crap. There is absolutely nothing to gain,
- and a great deal to lose, in using this in place of just
- setting `post-command-hook'. */
- xxDEFVAR_LISP ("deferred-action-list", &Vdeferred_action_list /*
-List of deferred actions to be performed at a later time.
-The precise format isn't relevant here; we just check whether it is nil.
-*/ );
- Vdeferred_action_list = Qnil;
-
- xxDEFVAR_LISP ("deferred-action-function", &Vdeferred_action_function /*
-Function to call to handle deferred actions, after each command.
-This function is called with no arguments after each command
-whenever `deferred-action-list' is non-nil.
-*/ );
- Vdeferred_action_function = Qnil;
-#endif /* FSF Emacs crap */
-
DEFVAR_LISP ("last-command-event", &Vlast_command_event /*
Last keyboard or mouse button event that was part of a command. This
variable is off limits: you may not set its value or modify the event that
keysym changed and its modifiers left alone. This is useful for
dealing with non-standard X keyboards, such as the grievous damage
that Sun has inflicted upon the world.
+-- If an entry maps a symbol to a character, then a key-press event
+ whose keysym is the former symbol (with any modifiers at all) gets
+ changed into a key-press event matching the latter character, and the
+ resulting modifiers are the union of the original and new modifiers.
-- If an entry maps a character to a character, then a key-press event
matching the former character gets converted to a key-press event
matching the latter character. This is useful on ASCII terminals
-- If an entry maps a character to a symbol, then a key-press event
matching the character gets converted to a key-press event whose
keysym is the given symbol and which has no modifiers.
+
+Here's an example: This makes typing parens and braces easier by rerouting
+their positions to eliminate the need to use the Shift key.
+
+ (keyboard-translate ?[ ?()
+ (keyboard-translate ?] ?))
+ (keyboard-translate ?{ ?[)
+ (keyboard-translate ?} ?])
+ (keyboard-translate 'f11 ?{)
+ (keyboard-translate 'f12 ?})
*/ );
DEFVAR_LISP ("retry-undefined-key-binding-unshifted",
*/ );
Vretry_undefined_key_binding_unshifted = Qt;
+ DEFVAR_BOOL ("modifier-keys-are-sticky", &modifier_keys_are_sticky /*
+*Non-nil makes modifier keys sticky.
+This means that you can release the modifier key before pressing down
+the key that you wish to be modified. Although this is non-standard
+behavior, it is recommended because it reduces the strain on your hand,
+thus reducing the incidence of the dreaded Emacs-pinky syndrome.
+
+Modifier keys are sticky within the inverval specified by
+`modifier-keys-sticky-time'.
+*/ );
+ modifier_keys_are_sticky = 0;
+
+ DEFVAR_LISP ("modifier-keys-sticky-time", &Vmodifier_keys_sticky_time /*
+*Modifier keys are sticky within this many milliseconds.
+If you don't want modifier keys sticking to be bounded, set this to
+non-integer value.
+
+This variable has no effect when `modifier-keys-are-sticky' is nil.
+Currently only implemented under X Window System.
+*/ );
+ Vmodifier_keys_sticky_time = make_int (500);
+
#ifdef HAVE_XIM
DEFVAR_LISP ("composed-character-default-binding",
&Vcomposed_character_default_binding /*
init_event_Xt_late ();
else
#endif
+#ifdef HAVE_GTK
+ if (!strcmp (display_use, "gtk"))
+ init_event_gtk_late ();
+ else
+#endif
#ifdef HAVE_MS_WINDOWS
if (!strcmp (display_use, "mswindows"))
init_event_mswindows_late ();
(global-set-key "\^Q" 'foo)
without the read-key-sequence:
- ^Q ==> (65 17 65 [... ^Q] [^Q])
- ^U^U^Q ==> (65 17 65 [... ^U ^U ^Q] [^U ^U ^Q])
- ^U^U^U^G^Q ==> (65 17 65 [... ^U ^U ^U ^G ^Q] [^Q])
+ ^Q ==> (?A ?\^Q ?A [... ^Q] [^Q])
+ ^U^U^Q ==> (?A ?\^Q ?A [... ^U ^U ^Q] [^U ^U ^Q])
+ ^U^U^U^G^Q ==> (?A ?\^Q ?A [... ^U ^U ^U ^G ^Q] [^Q])
with the read-key-sequence:
- ^Qb ==> (65 [b] 17 98 [... ^Q b] [b])
- ^U^U^Qb ==> (65 [b] 17 98 [... ^U ^U ^Q b] [b])
- ^U^U^U^G^Qb ==> (65 [b] 17 98 [... ^U ^U ^U ^G ^Q b] [b])
+ ^Qb ==> (?A [b] ?\^Q ?b [... ^Q b] [b])
+ ^U^U^Qb ==> (?A [b] ?\^Q ?b [... ^U ^U ^Q b] [b])
+ ^U^U^U^G^Qb ==> (?A [b] ?\^Q ?b [... ^U ^U ^U ^G ^Q b] [b])
;the evi-mode command "4dlj.j.j.j.j.j." is also a good testcase (gag)
;(setq x (list (read-char) quit-flag))^J^G
;(let ((inhibit-quit t)) (setq x (list (read-char) quit-flag)))^J^G
;for BOTH, x should get set to (7 t), but no result should be printed.
+;; #### According to the doc of quit-flag, second test should return
+;; (?\^G nil). Accidentaly XEmacs returns correct value. However,
+;; XEmacs 21.1.12 and 21.2.36 both fails on first test.
;also do this: make two frames, one viewing "*scratch*", the other "foo".
;in *scratch*, type (sit-for 20)^J
(quit c))
(read-char)))
- (tst)^Ja^G ==> ((quit) 97) with no signal
- (tst)^J^Ga ==> ((quit) 97) with no signal
- (tst)^Jabc^G ==> ((quit) 97) with no signal, and "bc" inserted in buffer
+ (tst)^Ja^G ==> ((quit) ?a) with no signal
+ (tst)^J^Ga ==> ((quit) ?a) with no signal
+ (tst)^Jabc^G ==> ((quit) ?a) with no signal, and "bc" inserted in buffer
; with sit-for only do the 2nd test.
; Do all 3 tests with (accept-process-output nil 20)