changeset 53128:c9aeaeb38318

(make_lispy_position): New function for generating mouse click positions from frame and pixel coordinates. Enhanced to return buffer position and actual row/column for events outside the text area using updated mode_line_string and marginal_area_string functions. Return left-fringe and right-fringe clicks as such, rather than clicks in text area. (make_lispy_event) [USE_X_TOOLKIT, USE_GTK]: Don't call pixel_to_glyph_coords, as we never use the results. (make_lispy_event): Use make_lispy_position for MOUSE_CLICK_EVENT, WHEEL_EVENT, and DRAG_N_DROP_EVENT to replace redundant code. Eliminate unused code in WHEEL_EVENT handling. (make_lispy_movement): Use make_lispy_position.
author Kim F. Storm <storm@cua.dk>
date Sun, 23 Nov 2003 00:09:39 +0000
parents bc14fd4782c3
children 070325c3884d
files src/keyboard.c
diffstat 1 files changed, 142 insertions(+), 262 deletions(-) [+]
line wrap: on
line diff
--- a/src/keyboard.c	Sun Nov 23 00:09:19 2003 +0000
+++ b/src/keyboard.c	Sun Nov 23 00:09:39 2003 +0000
@@ -586,6 +586,7 @@
 Lisp_Object Qvertical_scroll_bar;
 Lisp_Object Qmenu_bar;
 extern Lisp_Object Qleft_margin, Qright_margin;
+extern Lisp_Object Qleft_fringe, Qright_fringe;
 
 Lisp_Object recursive_edit_unwind (), command_loop ();
 Lisp_Object Fthis_command_keys ();
@@ -4955,6 +4956,123 @@
 
 int double_click_count;
 
+/* Return position of a mouse click or wheel event */
+
+static Lisp_Object
+make_lispy_position (f, x, y, time)
+     struct frame *f;
+     Lisp_Object *x, *y;
+     unsigned long time;
+{
+  Lisp_Object window;
+  enum window_part part;
+  Lisp_Object posn = Qnil;
+  Lisp_Object extra_info = Qnil;
+  int wx, wy;
+
+  /* Set `window' to the window under frame pixel coordinates (x,y)  */
+  if (f)
+    window = window_from_coordinates (f, XINT (*x), XINT (*y),
+				      &part, &wx, &wy, 0);
+  else
+    window = Qnil;
+
+  if (WINDOWP (window))
+    {
+      /* It's a click in window window at frame coordinates (x,y)  */
+      struct window *w = XWINDOW (window);
+      Lisp_Object object = Qnil;
+      int textpos = -1, rx = -1, ry = -1;
+
+      /* Set event coordinates to window-relative coordinates
+	 for constructing the Lisp event below.  */
+      XSETINT (*x, wx);
+      XSETINT (*y, wy);
+
+      if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
+	{
+	  /* Mode line or header line.  Look for a string under
+	     the mouse that may have a `local-map' property.  */
+	  Lisp_Object string;
+	  int charpos;
+
+	  posn = part == ON_MODE_LINE ? Qmode_line : Qheader_line;
+	  rx = wx, ry = wy;
+	  string = mode_line_string (w, &rx, &ry, part, &charpos);
+	  if (STRINGP (string))
+	    object = Fcons (string, make_number (charpos));
+	  if (w == XWINDOW (selected_window))
+	    textpos = PT;
+	  else
+	    textpos = XMARKER (w->pointm)->charpos;
+	}
+      else if (part == ON_VERTICAL_BORDER)
+	{
+	  posn = Qvertical_line;
+	  wx = -1;
+	}
+      else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
+	{
+	  Lisp_Object string;
+	  int charpos;
+	  
+	  posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin;
+	  rx = wx, ry = wy;
+	  string = marginal_area_string (w, &rx, &ry, part, &charpos);
+	  if (STRINGP (string))
+	    object = Fcons (string, make_number (charpos));
+	}
+      else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE)
+	{
+	  posn = (part == ON_LEFT_FRINGE) ? Qleft_fringe : Qright_fringe;
+	  rx = 0;
+	}
+
+      if (textpos < 0)
+	{
+	  Lisp_Object string;
+	  struct display_pos p;
+	  wx = max (WINDOW_LEFT_MARGIN_WIDTH (w), wx);
+	  buffer_posn_from_coords (w, &wx, &wy, &string, &p);
+	  textpos = CHARPOS (p.pos);
+	  if (rx < 0)
+	    rx = wx;
+	  if (ry < 0)
+	    ry = wy;
+
+	  if (NILP (posn))
+	    {
+	      posn = make_number (textpos);
+	      if (STRINGP (string))
+		object = Fcons (string,
+				make_number (CHARPOS (p.string_pos)));
+	    }
+	}
+
+      extra_info = Fcons (object,
+			  Fcons (make_number (textpos),
+				 Fcons (Fcons (make_number (rx),
+					       make_number (ry)),
+					Qnil)));
+    }
+  else if (f != 0)
+    {
+      XSETFRAME (window, f);
+    }
+  else
+    {
+      window = Qnil;
+      XSETFASTINT (*x, 0);
+      XSETFASTINT (*y, 0);
+    }
+
+  return Fcons (window,
+		Fcons (posn,
+		       Fcons (Fcons (*x, *y),
+			      Fcons (make_number (time),
+				     extra_info))));
+}
+
 /* Given a struct input_event, build the lisp event which represents
    it.  If EVENT is 0, build a mouse movement event from the mouse
    movement buffer, which should have a movement event in it.
@@ -5089,25 +5207,23 @@
 	Lisp_Object position;
 	Lisp_Object *start_pos_ptr;
 	Lisp_Object start_pos;
-	Lisp_Object window;
 
 	position = Qnil;
 
 	/* Build the position as appropriate for this mouse click.  */
 	if (event->kind == MOUSE_CLICK_EVENT)
 	  {
-	    enum window_part part;
 	    struct frame *f = XFRAME (event->frame_or_window);
-	    Lisp_Object posn;
-	    Lisp_Object string_info = Qnil;
+#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
 	    int row, column;
-	    int wx, wy;
+#endif
 
 	    /* Ignore mouse events that were made on frame that
 	       have been deleted.  */
 	    if (! FRAME_LIVE_P (f))
 	      return Qnil;
 
+#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
 	    /* EVENT->x and EVENT->y are frame-relative pixel
 	       coordinates at this place.  Under old redisplay, COLUMN
 	       and ROW are set to frame relative glyph coordinates
@@ -5116,7 +5232,6 @@
  	    pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
 	 			   &column, &row, NULL, 1);
 
-#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
 	    /* In the non-toolkit version, clicks on the menu bar
 	       are ordinary button events in the event buffer.
 	       Distinguish them, and invoke the menu.
@@ -5170,77 +5285,14 @@
 	      }
 #endif /* not USE_X_TOOLKIT && not USE_GTK */
 
-	    /* Set `window' to the window under frame pixel coordinates
-	       event->x/event->y.  */
-	    window = window_from_coordinates (f, XINT (event->x),
-					      XINT (event->y),
-					      &part, &wx, &wy, 0);
-
-	    if (!WINDOWP (window))
-	      {
-		window = event->frame_or_window;
-		posn = Qnil;
-	      }
-	    else
-	      {
-		/* It's a click in window window at frame coordinates
-		   event->x/ event->y.  */
-		struct window *w = XWINDOW (window);
-
-		/* Set event coordinates to window-relative coordinates
-		   for constructing the Lisp event below.  */
-		XSETINT (event->x, wx);
-		XSETINT (event->y, wy);
-
-		if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
-		  {
-		    /* Mode line or header line.  Look for a string under
-		       the mouse that may have a `local-map' property.  */
-		    Lisp_Object string;
-		    int charpos;
-
-		    posn = part == ON_MODE_LINE ? Qmode_line : Qheader_line;
-		    string = mode_line_string (w, wx, wy, part, &charpos);
-		    if (STRINGP (string))
-		      string_info = Fcons (string, make_number (charpos));
-		  }
-		else if (part == ON_VERTICAL_BORDER)
-		  posn = Qvertical_line;
-		else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
-		  {
-		    int charpos;
-		    Lisp_Object object = marginal_area_string (w, wx, wy, part,
-							       &charpos);
-		    posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin;
-		    if (STRINGP (object))
-		      string_info = Fcons (object, make_number (charpos));
-		  }
-		else
-		  {
-		    Lisp_Object object;
-		    struct display_pos p;
-		    buffer_posn_from_coords (w, &wx, &wy, &object, &p);
-		    posn = make_number (CHARPOS (p.pos));
-		    if (STRINGP (object))
-		      string_info
-			= Fcons (object,
-				 make_number (CHARPOS (p.string_pos)));
-		  }
-	      }
-
-	    position
-	      = Fcons (window,
-		       Fcons (posn,
-			      Fcons (Fcons (event->x, event->y),
-				     Fcons (make_number (event->timestamp),
-					    (NILP (string_info)
-					     ? Qnil
-					     : Fcons (string_info, Qnil))))));
+	    position = make_lispy_position (f, &event->x, &event->y,
+					    event->timestamp);
 	  }
 #ifndef USE_TOOLKIT_SCROLL_BARS
 	else
 	  {
 	    /* It's a scrollbar click.  */
+	    Lisp_Object window;
 	    Lisp_Object portion_whole;
 	    Lisp_Object part;
 
@@ -5405,97 +5457,18 @@
     case WHEEL_EVENT:
       {
 	Lisp_Object position;
-	Lisp_Object window;
 	Lisp_Object head;
 	
 	/* Build the position as appropriate for this mouse click.  */
-	enum window_part part;
 	struct frame *f = XFRAME (event->frame_or_window);
-	Lisp_Object posn;
-	Lisp_Object string_info = Qnil;
-	int row, column;
-	int wx, wy;
-	position = Qnil;
 
 	/* Ignore wheel events that were made on frame that have been
 	   deleted.  */
 	if (! FRAME_LIVE_P (f))
 	  return Qnil;
 
-	/* EVENT->x and EVENT->y are frame-relative pixel
-	   coordinates at this place.  Under old redisplay, COLUMN
-	   and ROW are set to frame relative glyph coordinates
-	   which are then used to determine whether this click is
-	   in a menu (non-toolkit version).  */
-	pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
-			       &column, &row, NULL, 1);
-
-	/* Set `window' to the window under frame pixel coordinates
-	   event->x/event->y.  */
-	window = window_from_coordinates (f, XINT (event->x),
-					  XINT (event->y),
-					  &part, &wx, &wy, 0);
-
-	if (!WINDOWP (window))
-	  {
-	    window = event->frame_or_window;
-	    posn = Qnil;
-	  }
-	else
-	  {
-	    /* It's a click in window window at frame coordinates
-	       event->x/ event->y.  */
-	    struct window *w = XWINDOW (window);
-	
-	    /* Set event coordinates to window-relative coordinates
-	       for constructing the Lisp event below.  */
-	    XSETINT (event->x, wx);
-	    XSETINT (event->y, wy);
-	
-	    if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
-	      {
-		/* Mode line or header line.  Look for a string under
-		   the mouse that may have a `local-map' property.  */
-		Lisp_Object string;
-		int charpos;
-
-		posn = part == ON_MODE_LINE ? Qmode_line : Qheader_line;
-		string = mode_line_string (w, wx, wy, part, &charpos);
-		if (STRINGP (string))
-		  string_info = Fcons (string, make_number (charpos));
-	      }
-	    else if (part == ON_VERTICAL_BORDER)
-	      posn = Qvertical_line;
-	    else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
-	      {
-		int charpos;
-		Lisp_Object object = marginal_area_string (w, wx, wy, part,
-							   &charpos);
-		posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin;
-		if (STRINGP (object))
-		  string_info = Fcons (object, make_number (charpos));
-	      }
-	    else
-	      {
-		Lisp_Object object;
-		struct display_pos p;
-		buffer_posn_from_coords (w, &wx, &wy, &object, &p);
-		posn = make_number (CHARPOS (p.pos));
-		if (STRINGP (object))
-		  string_info
-		    = Fcons (object,
-			     make_number (CHARPOS (p.string_pos)));
-	      }
-	  }
-	
-	position
-	  = Fcons (window,
-		   Fcons (posn,
-			  Fcons (Fcons (event->x, event->y),
-				 Fcons (make_number (event->timestamp),
-					(NILP (string_info)
-					 ? Qnil
-					 : Fcons (string_info, Qnil))))));
+	position = make_lispy_position (f, &event->x, &event->y,
+					event->timestamp);
 
 	/* Set double or triple modifiers to indicate the wheel speed.	*/
 	{
@@ -5689,12 +5662,9 @@
 
     case DRAG_N_DROP_EVENT:
       {
-	enum window_part part;
 	FRAME_PTR f;
-	Lisp_Object window;
-	Lisp_Object posn;
+	Lisp_Object head, position;
 	Lisp_Object files;
-	int wx, wy;
 
 	/* The frame_or_window field should be a cons of the frame in
 	   which the event occurred and a list of the filenames
@@ -5710,60 +5680,17 @@
 	if (! FRAME_LIVE_P (f))
 	  return Qnil;
 
-	window = window_from_coordinates (f, XINT (event->x),
-                                          XINT (event->y),
-					  &part, &wx, &wy, 0);
-
-	if (!WINDOWP (window))
-	  {
-	    window = XCAR (event->frame_or_window);
-	    posn = Qnil;
-	  }
-	else
-	  {
-	    /* It's an event in window `window' at frame coordinates
-	       event->x/ event->y.  */
-	    struct window *w = XWINDOW (window);
-
-	    /* Set event coordinates to window-relative coordinates
-	       for constructing the Lisp event below.  */
-	    XSETINT (event->x, wx);
-	    XSETINT (event->y, wy);
-
-	    if (part == ON_MODE_LINE)
-	      posn = Qmode_line;
-	    else if (part == ON_VERTICAL_BORDER)
-	      posn = Qvertical_line;
-	    else if (part == ON_HEADER_LINE)
-	      posn = Qheader_line;
-	    else
-	      {
-		Lisp_Object object;
-		struct display_pos p;
-		buffer_posn_from_coords (w, &wx, &wy, &object, &p);
-		posn = make_number (CHARPOS (p.pos));
-	      }
-	  }
-
-	{
-	  Lisp_Object head, position;
-
-	  position
-	    = Fcons (window,
-		     Fcons (posn,
-			    Fcons (Fcons (event->x, event->y),
-				   Fcons (make_number (event->timestamp),
-					  Qnil))));
-
-	  head = modify_event_symbol (0, event->modifiers,
-				      Qdrag_n_drop, Qnil,
-				      lispy_drag_n_drop_names,
-				      &drag_n_drop_syms, 1);
-	  return Fcons (head,
-			Fcons (position,
-			       Fcons (files,
-				      Qnil)));
-	}
+	position = make_lispy_position (f, &event->x, &event->y,
+					event->timestamp);
+
+	head = modify_event_symbol (0, event->modifiers,
+				    Qdrag_n_drop, Qnil,
+				    lispy_drag_n_drop_names,
+				    &drag_n_drop_syms, 1);
+	return Fcons (head,
+		      Fcons (position,
+			     Fcons (files,
+				    Qnil)));
       }
 #endif /* HAVE_MOUSE */
 
@@ -5836,59 +5763,12 @@
   /* Or is it an ordinary mouse movement?  */
   else
     {
-      enum window_part area;
-      Lisp_Object window;
-      Lisp_Object posn;
-      int wx, wy;
-
-      if (frame)
-	/* It's in a frame; which window on that frame?  */
-	window = window_from_coordinates (frame, XINT (x), XINT (y),
-					  &area, &wx, &wy, 0);
-      else
-	window = Qnil;
-
-      if (WINDOWP (window))
-	{
-	  struct window *w = XWINDOW (window);
-
-	  /* Set window relative coordinates.  */
-	  XSETINT (x, wx);
-	  XSETINT (y, wy);
-
-	  if (area == ON_MODE_LINE)
-	    posn = Qmode_line;
-	  else if (area == ON_VERTICAL_BORDER)
-	    posn = Qvertical_line;
-	  else if (area == ON_HEADER_LINE)
-	    posn = Qheader_line;
-	  else
-	    {
-	      Lisp_Object object;
-	      struct display_pos p;
-	      buffer_posn_from_coords (w, &wx, &wy, &object, &p);
-	      posn = make_number (CHARPOS (p.pos));
-	    }
-	}
-      else if (frame != 0)
-	{
-	  XSETFRAME (window, frame);
-	  posn = Qnil;
-	}
-      else
-	{
-	  window = Qnil;
-	  posn = Qnil;
-	  XSETFASTINT (x, 0);
-	  XSETFASTINT (y, 0);
-	}
+      Lisp_Object position;
+
+      position = make_lispy_position (frame, &x, &y, time);
 
       return Fcons (Qmouse_movement,
-		    Fcons (Fcons (window,
-				  Fcons (posn,
-					 Fcons (Fcons (x, y),
-						Fcons (make_number (time),
-						       Qnil)))),
+		    Fcons (position,
 			   Qnil));
     }
 }