/* Keyboard and mouse input; editor command loop.
- Copyright (C) 1985,86,87,88,89,93,94,95,96,97,99,2000,01,02,03,04
- Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995, 1996, 1997,
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <setjmp.h>
#include <errno.h>
+#ifdef HAVE_GTK_AND_PTHREAD
+#include <pthread.h>
+#endif
#ifdef MSDOS
#include "msdos.h"
#include <time.h>
#include <unistd.h>
#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
/* This is to get the definitions of the XK_ symbols. */
#ifdef HAVE_X_WINDOWS
#include "xterm.h"
#endif
/* Non-nil disable property on a command means
- do not execute it; call disabled-command-hook's value instead. */
-Lisp_Object Qdisabled, Qdisabled_command_hook;
+ do not execute it; call disabled-command-function's value instead. */
+Lisp_Object Qdisabled, Qdisabled_command_function;
#define NUM_RECENT_KEYS (100)
int recent_keys_index; /* Index for storing next element into recent_keys */
/* We are unable to use interrupts if FIONREAD is not available,
so flush SIGIO so we won't try. */
-#ifndef FIONREAD
+#if !defined (FIONREAD)
#ifdef SIGIO
#undef SIGIO
#endif
\f
/* Global variable declarations. */
+/* Flags for readable_events. */
+#define READABLE_EVENTS_DO_TIMERS_NOW (1 << 0)
+#define READABLE_EVENTS_FILTER_EVENTS (1 << 1)
+#define READABLE_EVENTS_IGNORE_SQUEEZABLES (1 << 2)
+
/* Function for init_keyboard to call with no args (if nonzero). */
void (*keyboard_init_hook) ();
static int read_avail_input P_ ((int));
static void get_input_pending P_ ((int *, int));
-static void get_filtered_input_pending P_ ((int *, int, int));
static int readable_events P_ ((int));
-static int readable_filtered_events P_ ((int, int));
static Lisp_Object read_char_x_menu_prompt P_ ((int, Lisp_Object *,
Lisp_Object, int *));
static Lisp_Object read_char_x_menu_prompt ();
static void clear_event P_ ((struct input_event *));
static void any_kboard_state P_ ((void));
static SIGTYPE interrupt_signal P_ ((int signalnum));
+static void timer_start_idle P_ ((void));
+static void timer_stop_idle P_ ((void));
+static void timer_resume_idle P_ ((void));
/* Nonzero means don't try to suspend even if the operating system seems
to support it. */
resize_echo_area_exactly ();
if (!NILP (Vdeferred_action_list))
- call0 (Vdeferred_action_function);
+ safe_run_hooks (Qdeferred_action_function);
if (!NILP (Vpost_command_idle_hook) && !NILP (Vrun_hooks))
{
if (NILP (Vthis_command))
{
/* nil means key is undefined. */
+ Lisp_Object keys = Fvector (i, keybuf);
+ keys = Fkey_description (keys, Qnil);
bitch_at_user ();
+ message_with_string ("%s is undefined", keys, 0);
current_kboard->defining_kbd_macro = Qnil;
update_mode_lines = 1;
current_kboard->Vprefix_arg = Qnil;
if (!NILP (current_buffer->mark_active) && !NILP (Vrun_hooks))
{
+ /* Setting transient-mark-mode to `only' is a way of
+ turning it on for just one command. */
+
+ if (EQ (Vtransient_mark_mode, Qidentity))
+ Vtransient_mark_mode = Qnil;
+ if (EQ (Vtransient_mark_mode, Qonly))
+ Vtransient_mark_mode = Qidentity;
+
if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode))
{
/* We could also call `deactivate'mark'. */
call1 (Vrun_hooks, intern ("activate-mark-hook"));
}
- /* Setting transient-mark-mode to `only' is a way of
- turning it on for just one command. */
- if (!NILP (current_buffer->mark_active) && !NILP (Vrun_hooks))
- {
- if (EQ (Vtransient_mark_mode, Qidentity))
- Vtransient_mark_mode = Qnil;
- if (EQ (Vtransient_mark_mode, Qonly))
- Vtransient_mark_mode = Qidentity;
- }
-
finalize:
if (current_buffer == prev_buffer
volatile Lisp_Object also_record;
volatile int reread;
struct gcpro gcpro1, gcpro2;
- EMACS_TIME last_idle_start;
int polling_stopped_here = 0;
also_record = Qnil;
non_reread:
- /* Record the last idle start time so that we can reset it
- should the next event read be a help-echo. */
- last_idle_start = timer_idleness_start_time;
timer_stop_idle ();
RESUME_POLLING;
prevents automatic window selection (under
mouse_autoselect_window from acting as a real input event, for
example banishing the mouse under mouse-avoidance-mode. */
- timer_idleness_start_time = last_idle_start;
+ timer_resume_idle ();
/* Resume allowing input from any kboard, if that was true before. */
if (!was_locked)
/* Save the echo status. */
int saved_immediate_echo = current_kboard->immediate_echo;
struct kboard *saved_ok_to_echo = ok_to_echo_at_next_pause;
+ Lisp_Object saved_echo_string = current_kboard->echo_string;
int saved_echo_after_prompt = current_kboard->echo_after_prompt;
#if 0
cancel_echoing ();
ok_to_echo_at_next_pause = saved_ok_to_echo;
+ current_kboard->echo_string = saved_echo_string;
current_kboard->echo_after_prompt = saved_echo_after_prompt;
if (saved_immediate_echo)
echo_now ();
show_help_echo (help, window, object, position, 0);
/* We stopped being idle for this event; undo that. */
- timer_idleness_start_time = last_idle_start;
+ timer_resume_idle ();
goto retry;
}
input has been processed. If the only input available was
the sort that we have just disabled, then we need to call
redisplay. */
- if (!readable_events (1))
+ if (!readable_events (READABLE_EVENTS_DO_TIMERS_NOW))
{
redisplay_preserve_echo_area (6);
- get_input_pending (&input_pending, 1);
+ get_input_pending (&input_pending,
+ READABLE_EVENTS_DO_TIMERS_NOW);
}
}
return Qnil;
/* Return true iff there are any events in the queue that read-char
would return. If this returns false, a read-char would block. */
static int
-readable_filtered_events (do_timers_now, filter_events)
- int do_timers_now;
- int filter_events;
+readable_events (flags)
+ int flags;
{
- if (do_timers_now)
- timer_check (do_timers_now);
+ if (flags & READABLE_EVENTS_DO_TIMERS_NOW)
+ timer_check (1);
- /* If the buffer contains only FOCUS_IN_EVENT events,
- and FILTER_EVENTS is nonzero, report it as empty. */
+ /* If the buffer contains only FOCUS_IN_EVENT events, and
+ READABLE_EVENTS_FILTER_EVENTS is set, report it as empty. */
if (kbd_fetch_ptr != kbd_store_ptr)
{
int have_live_event = 1;
- if (filter_events)
+ if (flags & READABLE_EVENTS_FILTER_EVENTS)
{
struct input_event *event;
}
#ifdef HAVE_MOUSE
- if (!NILP (do_mouse_tracking) && some_mouse_moved ())
+ if (!(flags & READABLE_EVENTS_IGNORE_SQUEEZABLES)
+ && !NILP (do_mouse_tracking) && some_mouse_moved ())
return 1;
#endif
if (single_kboard)
return 0;
}
-/* Return true iff there are any events in the queue that read-char
- would return. If this returns false, a read-char would block. */
-static int
-readable_events (do_timers_now)
- int do_timers_now;
-{
- return readable_filtered_events (do_timers_now, 0);
-}
-
/* Set this for debugging, to have a way to get out */
int stop_character;
}
#endif
+
+Lisp_Object Vthrow_on_input;
+
/* Store an event obtained at interrupt level into kbd_buffer, fifo */
void
Discard the event if it would fill the last slot. */
if (kbd_fetch_ptr - 1 != kbd_store_ptr)
{
+ *kbd_store_ptr = *event;
+ ++kbd_store_ptr;
+ }
-#if 0 /* The SELECTION_REQUEST_EVENT case looks bogus, and it's error
- prone to assign individual members for other events, in case
- the input_event structure is changed. --2000-07-13, gerd. */
- struct input_event *sp = kbd_store_ptr;
- sp->kind = event->kind;
- if (event->kind == SELECTION_REQUEST_EVENT)
+ /* If we're inside while-no-input, and this event qualifies
+ as input, set quit-flag to cause an interrupt. */
+ if (!NILP (Vthrow_on_input)
+ && event->kind != FOCUS_IN_EVENT
+ && event->kind != HELP_EVENT
+ && event->kind != DEICONIFY_EVENT)
+ {
+ Vquit_flag = Vthrow_on_input;
+ /* If we're inside a function that wants immediate quits,
+ do it now. */
+ if (immediate_quit && NILP (Vinhibit_quit))
{
- /* We must not use the ordinary copying code for this case,
- since `part' is an enum and copying it might not copy enough
- in this case. */
- bcopy (event, (char *) sp, sizeof (*event));
+ immediate_quit = 0;
+ sigfree ();
+ QUIT;
}
- else
+ }
+}
- {
- sp->code = event->code;
- sp->part = event->part;
- sp->frame_or_window = event->frame_or_window;
- sp->arg = event->arg;
- sp->modifiers = event->modifiers;
- sp->x = event->x;
- sp->y = event->y;
- sp->timestamp = event->timestamp;
- }
-#else
- *kbd_store_ptr = *event;
-#endif
- ++kbd_store_ptr;
+/* Put an input event back in the head of the event queue. */
+
+void
+kbd_buffer_unget_event (event)
+ register struct input_event *event;
+{
+ if (kbd_fetch_ptr == kbd_buffer)
+ kbd_fetch_ptr = kbd_buffer + KBD_BUFFER_SIZE;
+
+ /* Don't let the very last slot in the buffer become full, */
+ if (kbd_fetch_ptr - 1 != kbd_store_ptr)
+ {
+ --kbd_fetch_ptr;
+ *kbd_fetch_ptr = *event;
}
}
break;
#endif
{
- Lisp_Object minus_one;
-
- XSETINT (minus_one, -1);
- wait_reading_process_input (0, 0, minus_one, 1);
+ wait_reading_process_output (0, 0, -1, 1, Qnil, NULL, 0);
if (!interrupt_input && kbd_fetch_ptr == kbd_store_ptr)
/* Pass 1 for EXPECT since we just waited to have input. */
/* These two kinds of events get special handling
and don't actually appear to the command loop.
We return nil for them. */
- if (event->kind == SELECTION_REQUEST_EVENT)
+ if (event->kind == SELECTION_REQUEST_EVENT
+ || event->kind == SELECTION_CLEAR_EVENT)
{
#ifdef HAVE_X11
struct input_event copy;
copy = *event;
kbd_fetch_ptr = event + 1;
input_pending = readable_events (0);
- x_handle_selection_request (©);
+ x_handle_selection_event (©);
#else
/* We're getting selection request events, but we don't have
a window system. */
#endif
}
- else if (event->kind == SELECTION_CLEAR_EVENT)
- {
-#ifdef HAVE_X11
- struct input_event copy;
-
- /* Remove it from the buffer before processing it. */
- copy = *event;
- kbd_fetch_ptr = event + 1;
- input_pending = readable_events (0);
- x_handle_selection_clear (©);
-#else
- /* We're getting selection request events, but we don't have
- a window system. */
- abort ();
-#endif
- }
#if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (MAC_OS)
else if (event->kind == DELETE_WINDOW_EVENT)
{
/* These two kinds of events get special handling
and don't actually appear to the command loop. */
- if (event->kind == SELECTION_REQUEST_EVENT)
+ if (event->kind == SELECTION_REQUEST_EVENT
+ || event->kind == SELECTION_CLEAR_EVENT)
{
#ifdef HAVE_X11
struct input_event copy;
copy = *event;
kbd_fetch_ptr = event + 1;
input_pending = readable_events (0);
- x_handle_selection_request (©);
-#else
- /* We're getting selection request events, but we don't have
- a window system. */
- abort ();
-#endif
- }
-
- else if (event->kind == SELECTION_CLEAR_EVENT)
- {
-#ifdef HAVE_X11
- struct input_event copy;
-
- /* Remove it from the buffer before processing it, */
- copy = *event;
-
- kbd_fetch_ptr = event + 1;
- input_pending = readable_events (0);
- x_handle_selection_clear (©);
+ x_handle_selection_event (©);
#else
/* We're getting selection request events, but we don't have
a window system. */
}
old_timers_run = timers_run;
- get_input_pending (&input_pending, 1);
+ get_input_pending (&input_pending, READABLE_EVENTS_DO_TIMERS_NOW);
if (timers_run != old_timers_run && do_display)
redisplay_preserve_echo_area (7);
/* Record the start of when Emacs is idle,
for the sake of running idle-time timers. */
-void
+static void
timer_start_idle ()
{
Lisp_Object timers;
/* Record that Emacs is no longer idle, so stop running idle-time timers. */
-void
+static void
timer_stop_idle ()
{
EMACS_SET_SECS_USECS (timer_idleness_start_time, -1, -1);
}
+/* Resume idle timer from last idle start time. */
+
+static void
+timer_resume_idle ()
+{
+ if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
+ return;
+
+ timer_idleness_start_time = timer_last_idleness_start_time;
+}
+
/* This is only for debugging. */
struct input_event last_timer_event;
but works even if FIONREAD does not exist.
(In fact, this may actually read some input.)
- If DO_TIMERS_NOW is nonzero, actually run timer events that are ripe.
- If FILTER_EVENTS is nonzero, ignore internal events (FOCUS_IN_EVENT). */
+ If READABLE_EVENTS_DO_TIMERS_NOW is set in FLAGS, actually run
+ timer events that are ripe.
+ If READABLE_EVENTS_FILTER_EVENTS is set in FLAGS, ignore internal
+ events (FOCUS_IN_EVENT).
+ If READABLE_EVENTS_IGNORE_SQUEEZABLES is set in FLAGS, ignore mouse
+ movements. */
static void
-get_filtered_input_pending (addr, do_timers_now, filter_events)
+get_input_pending (addr, flags)
int *addr;
- int do_timers_now;
- int filter_events;
+ int flags;
{
/* First of all, have we already counted some input? */
- *addr = (!NILP (Vquit_flag)
- || readable_filtered_events (do_timers_now, filter_events));
+ *addr = (!NILP (Vquit_flag) || readable_events (flags));
/* If input is being read as it arrives, and we have none, there is none. */
if (*addr > 0 || (interrupt_input && ! interrupts_deferred))
/* Try to read some input and see how much we get. */
gobble_input (0);
- *addr = (!NILP (Vquit_flag)
- || readable_filtered_events (do_timers_now, filter_events));
-}
-
-/* Store into *addr a value nonzero if terminal input chars are available.
- Serves the purpose of ioctl (0, FIONREAD, addr)
- but works even if FIONREAD does not exist.
- (In fact, this may actually read some input.)
-
- If DO_TIMERS_NOW is nonzero, actually run timer events that are ripe. */
-
-static void
-get_input_pending (addr, do_timers_now)
- int *addr;
- int do_timers_now;
-{
- get_filtered_input_pending (addr, do_timers_now, 0);
+ *addr = (!NILP (Vquit_flag) || readable_events (flags));
}
/* Interface to read_avail_input, blocking SIGIO or SIGALRM if necessary. */
if (read_socket_hook)
{
- int discard = 0;
int nr;
struct input_event hold_quit;
#ifdef BSD4_1
extern int select_alarmed;
#endif
+
interrupt_input_pending = 0;
while (1)
{
/* Must preserve main program's value of errno. */
int old_errno = errno;
-
#if defined (USG) && !defined (POSIX_SIGNALS)
/* USG systems forget handlers when they are used;
must reestablish each time */
sigisheld (SIGIO);
#endif
- if (input_available_clear_time)
- EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
-
#ifdef SYNC_INPUT
interrupt_input_pending = 1;
#else
+ SIGNAL_THREAD_CHECK (signo);
+#endif
+
+ if (input_available_clear_time)
+ EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
+
+#ifndef SYNC_INPUT
handle_async_input ();
#endif
keymap may have changed, so replay the sequence. */
if (BUFFERP (key))
{
- EMACS_TIME initial_idleness_start_time;
- EMACS_SET_SECS_USECS (initial_idleness_start_time,
- EMACS_SECS (timer_last_idleness_start_time),
- EMACS_USECS (timer_last_idleness_start_time));
-
- /* Resume idle state, using the same start-time as before. */
- timer_start_idle ();
- timer_idleness_start_time = initial_idleness_start_time;
+ timer_resume_idle ();
mock_input = t;
/* Reset the current buffer from the selected window
tem = Fget (cmd, Qdisabled);
if (!NILP (tem) && !NILP (Vrun_hooks))
{
- tem = Fsymbol_value (Qdisabled_command_hook);
+ tem = Fsymbol_value (Qdisabled_command_function);
if (!NILP (tem))
- return call1 (Vrun_hooks, Qdisabled_command_hook);
+ return call1 (Vrun_hooks, Qdisabled_command_function);
}
}
Lisp_Object saved_keys, saved_last_point_position_buffer;
Lisp_Object bindings, value;
struct gcpro gcpro1, gcpro2, gcpro3;
+#ifdef HAVE_X_WINDOWS
+ /* The call to Fcompleting_read wil start and cancel the hourglass,
+ but if the hourglass was already scheduled, this means that no
+ hourglass will be shown for the actual M-x command itself.
+ So we restart it if it is already scheduled. Note that checking
+ hourglass_shown_p is not enough, normally the hourglass is not shown,
+ just scheduled to be shown. */
+ int hstarted = hourglass_started ();
+#endif
saved_keys = Fvector (this_command_key_count,
XVECTOR (this_command_keys)->contents);
Qt, Qnil, Qextended_command_history, Qnil,
Qnil);
+#ifdef HAVE_X_WINDOWS
+ if (hstarted) start_hourglass ();
+#endif
+
if (STRINGP (function) && SCHARS (function) == 0)
error ("No command name given");
return input_pending;
}
+/* Return nonzero if input events other than mouse movements are
+ pending. */
+
+int
+detect_input_pending_ignore_squeezables ()
+{
+ if (!input_pending)
+ get_input_pending (&input_pending, READABLE_EVENTS_IGNORE_SQUEEZABLES);
+
+ return input_pending;
+}
+
/* Return nonzero if input events are pending, and run any pending timers. */
int
int old_timers_run = timers_run;
if (!input_pending)
- get_input_pending (&input_pending, 1);
+ get_input_pending (&input_pending, READABLE_EVENTS_DO_TIMERS_NOW);
if (old_timers_run != timers_run && do_display)
{
}
/* Return nonzero if there are pending requeued events.
- This isn't used yet. The hope is to make wait_reading_process_input
+ This isn't used yet. The hope is to make wait_reading_process_output
call it, and return if it runs Lisp code that unreads something.
The problem is, kbd_buffer_get_event needs to be fixed to know what
to do in that case. It isn't trivial. */
if (!NILP (Vunread_command_events) || unread_command_char != -1)
return (Qt);
- get_filtered_input_pending (&input_pending, 1, 1);
+ get_input_pending (&input_pending,
+ READABLE_EVENTS_DO_TIMERS_NOW
+ | READABLE_EVENTS_FILTER_EVENTS);
return input_pending > 0 ? Qt : Qnil;
}
}
#endif /* USG */
+ SIGNAL_THREAD_CHECK (signalnum);
cancel_echoing ();
if (!NILP (Vquit_flag)
return Flist (sizeof (val) / sizeof (val[0]), val);
}
-DEFUN ("posn-at-x-y", Fposn_at_x_y, Sposn_at_x_y, 2, 3, 0,
+DEFUN ("posn-at-x-y", Fposn_at_x_y, Sposn_at_x_y, 2, 4, 0,
doc: /* Return position information for pixel coordinates X and Y.
By default, X and Y are relative to text area of the selected window.
Optional third arg FRAME_OR_WINDOW non-nil specifies frame or window.
+If optional fourth arg WHOLE is non-nil, X is relative to the left
+edge of the window.
The return value is similar to a mouse click position:
(WINDOW AREA-OR-POS (X . Y) TIMESTAMP OBJECT POS (COL . ROW)
IMAGE (DX . DY) (WIDTH . HEIGHT))
The `posn-' functions access elements of such lists. */)
- (x, y, frame_or_window)
- Lisp_Object x, y, frame_or_window;
+ (x, y, frame_or_window, whole)
+ Lisp_Object x, y, frame_or_window, whole;
{
+ CHECK_NATNUM (x);
+ CHECK_NATNUM (y);
+
if (NILP (frame_or_window))
frame_or_window = selected_window;
w = XWINDOW (frame_or_window);
XSETINT (x, (WINDOW_TO_FRAME_PIXEL_X (w, XINT (x))
- + window_box_left_offset (w, TEXT_AREA)));
+ + (NILP (whole)
+ ? window_box_left_offset (w, TEXT_AREA)
+ : - (WINDOW_LEFT_SCROLL_BAR_COLS (w)
+ * WINDOW_FRAME_COLUMN_WIDTH (w)))));
XSETINT (y, WINDOW_TO_FRAME_PIXEL_Y (w, XINT (y)));
frame_or_window = w->frame;
}
to the given buffer position:
(WINDOW AREA-OR-POS (X . Y) TIMESTAMP OBJECT POS (COL . ROW)
IMAGE (DX . DY) (WIDTH . HEIGHT))
-The `posn-' functions access elements of such lists. */*/)
+The `posn-' functions access elements of such lists. */)
(pos, window)
Lisp_Object pos, window;
{
tem = Fpos_visible_in_window_p (pos, window, Qt);
if (!NILP (tem))
- tem = Fposn_at_x_y (XCAR (tem), XCAR (XCDR (tem)), window);
+ tem = Fposn_at_x_y (XCAR (tem), XCAR (XCDR (tem)), window, Qnil);
return tem;
}
Qtimer_event_handler = intern ("timer-event-handler");
staticpro (&Qtimer_event_handler);
- Qdisabled_command_hook = intern ("disabled-command-hook");
- staticpro (&Qdisabled_command_hook);
+ Qdisabled_command_function = intern ("disabled-command-function");
+ staticpro (&Qdisabled_command_function);
Qself_insert_command = intern ("self-insert-command");
staticpro (&Qself_insert_command);
doc: /* Per-terminal keymap that overrides all other local keymaps.
If this variable is non-nil, it is used as a keymap instead of the
buffer's local map, and the minor mode keymaps and text property keymaps.
+It also replaces `overriding-local-map'.
+
This variable is intended to let commands such as `universal-argument'
set up a different keymap for reading the next command. */);
DEFVAR_LISP ("overriding-local-map", &Voverriding_local_map,
doc: /* Keymap that overrides all other local keymaps.
-If this variable is non-nil, it is used as a keymap instead of the
-buffer's local map, and the minor mode keymaps and text property keymaps. */);
+If this variable is non-nil, it is used as a keymap--replacing the
+buffer's local map, the minor mode keymaps, and char property keymaps. */);
Voverriding_local_map = Qnil;
DEFVAR_LISP ("overriding-local-map-menu-flag", &Voverriding_local_map_menu_flag,
After a command is executed, if point is moved into a region that has
special properties (e.g. composition, display), we adjust point to
-the boundary of the region. But, several special commands sets this
-variable to non-nil, then we suppress the point adjustment.
+the boundary of the region. But, when a command sets this variable to
+non-nil, we suppress the point adjustment.
This variable is set to nil before reading a command, and is checked
just after executing the command. */);
doc: /* *How long to display an echo-area message when the minibuffer is active.
If the value is not a number, such messages don't time out. */);
Vminibuffer_message_timeout = make_number (2);
+
+ DEFVAR_LISP ("throw-on-input", &Vthrow_on_input,
+ doc: /* If non-nil, any keyboard input throws to this symbol.
+The value of that variable is passed to `quit-flag' and later causes a
+peculiar kind of quitting. */);
+ Vthrow_on_input = Qnil;
}
void
{
if (event == kbd_buffer + KBD_BUFFER_SIZE)
event = kbd_buffer;
- if (event->kind != SELECTION_REQUEST_EVENT)
+ if (event->kind != SELECTION_REQUEST_EVENT
+ && event->kind != SELECTION_CLEAR_EVENT)
{
mark_object (event->x);
mark_object (event->y);