diff src/keyboard.c @ 90729:6588c6259dfb

Merge from emacs--devo--0 Patches applied: * emacs--devo--0 (patch 545-562) - Update from CVS - Update from erc--emacs--22 - Merge from gnus--rel--5.10 - erc-iswitchb: Temporarily enable iswitchb mode * gnus--rel--5.10 (patch 172-176) - Merge from emacs--devo--0 - Update from CVS - Update from CVS: lisp/legacy-gnus-agent.el: Add Copyright notice. Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-156
author Miles Bader <miles@gnu.org>
date Sat, 16 Dec 2006 01:29:26 +0000
parents f1d13e615070 130738a27be7
children bc10a33dd40b
line wrap: on
line diff
--- a/src/keyboard.c	Fri Dec 15 01:34:17 2006 +0000
+++ b/src/keyboard.c	Sat Dec 16 01:29:26 2006 +0000
@@ -699,6 +699,9 @@
 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.  */
@@ -1435,13 +1438,25 @@
 }
 
 /* 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)
@@ -5589,6 +5604,7 @@
 	      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
@@ -5624,8 +5640,13 @@
 		    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
@@ -5948,20 +5969,16 @@
 
     case USER_SIGNAL_EVENT:
       /* A user signal.  */
-      switch (event->code)
-	{
-	case 0:
-	  return Qsignal;
-#ifdef SIGUSR1
-	case SIGUSR1:
-	  return intern ("usr1");
-#endif
-#ifdef SIGUSR2
-	case SIGUSR2:
-	  return intern ("usr2");
-#endif
-	default:
-	  return make_number (event->code);
+      if (event->code == 0)
+	return Qsignal;
+      else
+	{
+	  char *name = find_user_signal_name (event->code);
+
+	  if (name)
+	    return intern (name);
+	  else
+	    return make_number (event->code);
 	}
 
     case SAVE_SESSION_EVENT:
@@ -6799,6 +6816,10 @@
   register int i;
   int nread = 0;
 
+  /* Store pending user signal events, if any.  */
+  if (store_user_signal_events ())
+    expected = 0;
+
   if (read_socket_hook)
     {
       int nr;
@@ -7022,6 +7043,133 @@
 
 
 
+/* 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 = 0;
+	    kbd_buffer_store_event (&buf);
+	    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;