diff options
Diffstat (limited to 'src/keyboard.c')
-rw-r--r-- | src/keyboard.c | 181 |
1 files changed, 161 insertions, 20 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index 2f4879da110..656a642c666 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -684,6 +684,9 @@ static void handle_interrupt P_ ((void)); static void timer_start_idle P_ ((void)); static void timer_stop_idle P_ ((void)); static void timer_resume_idle P_ ((void)); +static SIGTYPE handle_user_signal P_ ((int)); +static char *find_user_signal_name P_ ((int)); +static int store_user_signal_events P_ ((void)); /* Nonzero means don't try to suspend even if the operating system seems to support it. */ @@ -1506,13 +1509,25 @@ usage: (track-mouse BODY ...) */) } /* If mouse has moved on some frame, return one of those frames. - Return 0 otherwise. */ + + Return 0 otherwise. + + If ignore_mouse_drag_p is non-zero, ignore (implicit) mouse movement + after resizing the tool-bar window. */ + +int ignore_mouse_drag_p; static FRAME_PTR some_mouse_moved () { Lisp_Object tail, frame; + if (ignore_mouse_drag_p) + { + /* ignore_mouse_drag_p = 0; */ + return 0; + } + FOR_EACH_FRAME (tail, frame) { if (XFRAME (frame)->mouse_moved) @@ -5182,15 +5197,6 @@ Lisp_Object *scroll_bar_parts[] = { &Qup, &Qdown, &Qtop, &Qbottom, &Qend_scroll, &Qratio }; -/* User signal events. */ -Lisp_Object Qusr1_signal, Qusr2_signal; - -Lisp_Object *lispy_user_signals[] = -{ - &Qusr1_signal, &Qusr2_signal -}; - - /* A vector, indexed by button number, giving the down-going location of currently depressed buttons, both scroll bar and non-scroll bar. @@ -5704,6 +5710,7 @@ make_lispy_event (event) double_click_count = 1; button_down_time = event->timestamp; *start_pos_ptr = Fcopy_alist (position); + ignore_mouse_drag_p = 0; } /* Now we're releasing a button - check the co-ordinates to @@ -5739,8 +5746,13 @@ make_lispy_event (event) ydiff = XINT (event->y) - XINT (XCDR (down)); } - if (xdiff < double_click_fuzz && xdiff > - double_click_fuzz - && ydiff < double_click_fuzz && ydiff > - double_click_fuzz + if (ignore_mouse_drag_p) + { + event->modifiers |= click_modifier; + ignore_mouse_drag_p = 0; + } + else if (xdiff < double_click_fuzz && xdiff > - double_click_fuzz + && ydiff < double_click_fuzz && ydiff > - double_click_fuzz /* Maybe the mouse has moved a lot, caused scrolling, and eventually ended up at the same screen position (but not buffer position) in which case it is a drag, not @@ -6063,7 +6075,12 @@ make_lispy_event (event) case USER_SIGNAL_EVENT: /* A user signal. */ - return *lispy_user_signals[event->code]; + { + char *name = find_user_signal_name (event->code); + if (!name) + abort (); + return intern (name); + } case SAVE_SESSION_EVENT: return Qsave_session; @@ -6904,6 +6921,10 @@ read_avail_input (expected) int err = 0; struct terminal *t; + /* Store pending user signal events, if any. */ + if (store_user_signal_events ()) + expected = 0; + /* Loop through the available terminals, and call their input hooks. */ t = terminal_list; while (t) @@ -7197,6 +7218,131 @@ reinvoke_input_signal () +/* User signal events. */ + +struct user_signal_info +{ + /* Signal number. */ + int sig; + + /* Name of the signal. */ + char *name; + + /* Number of pending signals. */ + int npending; + + struct user_signal_info *next; +}; + +/* List of user signals. */ +static struct user_signal_info *user_signals = NULL; + +void +add_user_signal (sig, name) + int sig; + const char *name; +{ + struct user_signal_info *p; + + for (p = user_signals; p; p = p->next) + if (p->sig == sig) + /* Already added. */ + return; + + p = xmalloc (sizeof (struct user_signal_info)); + p->sig = sig; + p->name = xstrdup (name); + p->npending = 0; + p->next = user_signals; + user_signals = p; + + signal (sig, handle_user_signal); +} + +static SIGTYPE +handle_user_signal (sig) + int sig; +{ + int old_errno = errno; + struct user_signal_info *p; + +#if defined (USG) && !defined (POSIX_SIGNALS) + /* USG systems forget handlers when they are used; + must reestablish each time */ + signal (sig, handle_user_signal); +#endif + + SIGNAL_THREAD_CHECK (sig); + + for (p = user_signals; p; p = p->next) + if (p->sig == sig) + { + p->npending++; +#ifdef SIGIO + if (interrupt_input) + kill (getpid (), SIGIO); + else +#endif + { + /* Tell wait_reading_process_output that it needs to wake + up and look around. */ + if (input_available_clear_time) + EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); + } + break; + } + + errno = old_errno; +} + +static char * +find_user_signal_name (sig) + int sig; +{ + struct user_signal_info *p; + + for (p = user_signals; p; p = p->next) + if (p->sig == sig) + return p->name; + + return NULL; +} + +static int +store_user_signal_events () +{ + struct user_signal_info *p; + struct input_event buf; + int nstored = 0; + + for (p = user_signals; p; p = p->next) + if (p->npending > 0) + { + SIGMASKTYPE mask; + + if (nstored == 0) + { + bzero (&buf, sizeof buf); + buf.kind = USER_SIGNAL_EVENT; + buf.frame_or_window = selected_frame; + } + nstored += p->npending; + + mask = sigblock (sigmask (p->sig)); + do + { + buf.code = p->sig; + kbd_buffer_store_event (&buf); + p->npending--; + } + while (p->npending > 0); + sigsetmask (mask); + } + + return nstored; +} + + static void menu_bar_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, void*)); static Lisp_Object menu_bar_one_keymap_changed_items; @@ -11422,11 +11568,6 @@ syms_of_keyboard () staticpro (&Qmac_apple_event); #endif - Qusr1_signal = intern ("usr1-signal"); - staticpro (&Qusr1_signal); - Qusr2_signal = intern ("usr2-signal"); - staticpro (&Qusr2_signal); - Qmenu_enable = intern ("menu-enable"); staticpro (&Qmenu_enable); Qmenu_alias = intern ("menu-alias"); @@ -11724,8 +11865,8 @@ Polling is automatically disabled in all other cases. */); DEFVAR_LISP ("double-click-time", &Vdouble_click_time, doc: /* *Maximum time between mouse clicks to make a double-click. -Measured in milliseconds. nil means disable double-click recognition; -t means double-clicks have no time limit and are detected +Measured in milliseconds. The value nil means disable double-click +recognition; t means double-clicks have no time limit and are detected by position only. */); Vdouble_click_time = make_number (500); |