changeset 2289:7fa4bc78a35d

[xemacs-hg @ 2004-09-21 02:59:59 by james] Darryl Okahata's patch to add current-pixel-row.
author james
date Tue, 21 Sep 2004 03:00:27 +0000
parents 63d767a4650c
children 21f73f4563a7
files man/ChangeLog man/lispref/windows.texi src/ChangeLog src/window.c
diffstat 4 files changed, 154 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/man/ChangeLog	Mon Sep 20 21:52:52 2004 +0000
+++ b/man/ChangeLog	Tue Sep 21 03:00:27 2004 +0000
@@ -1,3 +1,8 @@
+2004-05-14  Darryl Okahata  <darrylo@xemacs.org>
+
+	* lispref/windows.texi.  Added documentation for the functions,
+	``current-pixel-row'' and ``current-pixel-column''.
+
 2004-09-13  Jerry James  <james@xemacs.org>
 
 	* internals/internals.texi (Modules for Interfacing with the
--- a/man/lispref/windows.texi	Mon Sep 20 21:52:52 2004 +0000
+++ b/man/lispref/windows.texi	Tue Sep 21 03:00:27 2004 +0000
@@ -1049,6 +1049,7 @@
 @cindex window point
 @cindex position in window
 @cindex point in window
+@cindex cursor in window
 
   Each window has its own value of point, independent of the value of
 point in other windows displaying the same buffer.  This makes it useful
@@ -1099,6 +1100,74 @@
 @var{position} in @var{window}'s buffer.
 @end defun
 
+@defun current-pixel-row &optional window pos
+@defunx current-pixel-column &optional window pos
+@cindex cursor pixel row
+@cindex window point pixel row
+@cindex cursor pixel column
+@cindex window point pixel column
+The function, @code{current-pixel-row}, returns the vertical location,
+in pixels, of the point @var{pos} within the specified @var{window};
+similarly, @code{current-pixel-column} returns the corresponding
+horizontal location.  The position returned is that of the upper-left
+corner of the cursor, and is relative to the upper-left location of the
+window.  If @var{window} is @code{nil}, the function uses the selected
+window.  If @var{pos} is @code{nil}, the value of @code{window-point} is
+used.
+
+Note that the coordinates are relative to the current XEmacs window, and
+are not relative to the XEmacs X11 window.  To obtain the coordinates
+relative to the X11 window, you must also take into account the spacings
+of any menubars, gutters, toolbars, margins, etc., as well as any window
+offsets.  The function, @code{window-pixel-edges} (@pxref{Position of
+Window}), can be used to help calculate the location relative to the
+frame.
+
+@emph{Important note}: in order for these functions to return a correct,
+non-nil value, two criteria @emph{must} be satisfied:
+
+@itemize @bullet
+
+@item
+The location of @code{pos} must be visible within the specified window.
+If @var{pos} is outside the visible area, @code{nil} is returned.
+
+@item
+As the pixel location is determined from the redisplay tables, the
+redisplay tables must be up-to-date.  In other words, the XEmacs
+window(s), as seen by the user, must be correct (to improve performance,
+XEmacs generally defers display updates until control returns back to
+the idle loop).  To insure that the redisplay tables are up-to-date, one
+of the following must generally be done @emph{before} calling
+@code{current-pixel-row} or @code{current-pixel-column}:
+
+@itemize @bullet
+
+@item
+If the window in question is not in a new frame, you can force a
+redisplay using @code{(sit-for 0)}.  See @code{sit-for} in
+@ref{Waiting}.
+
+@item
+If the window in question is in a new frame, you must call code like the
+following:
+
+@example
+@group
+(while (not (frame-visible-p frame))
+  (sleep-for .5))
+@end group
+@end example
+
+@end itemize
+
+@end itemize
+
+If one of these is not done, the return value may be incorrect, even if
+it is non-nil.
+
+@end defun
+
 @node Window Start
 @section The Window Start Position
 
--- a/src/ChangeLog	Mon Sep 20 21:52:52 2004 +0000
+++ b/src/ChangeLog	Tue Sep 21 03:00:27 2004 +0000
@@ -1,3 +1,8 @@
+2004-05-14  Darryl Okahata  <darrylo@xemacs.org>
+
+	* lispref/windows.texi.  Added documentation for the functions,
+	``current-pixel-row'' and ``current-pixel-column''.
+
 2004-09-14  Jerry James  <james@xemacs.org>
 
 	* compiler.h: Change old UNUSED_ARG into UNUSED_ARG and
--- a/src/window.c	Mon Sep 20 21:52:52 2004 +0000
+++ b/src/window.c	Tue Sep 21 03:00:27 2004 +0000
@@ -5212,26 +5212,23 @@
   return unbind_to_1 (speccount, Fprogn (args));
 }
 
-DEFUN ("current-pixel-column", Fcurrent_pixel_column, 0, 2, 0, /*
-Return the horizontal pixel position of POS in window.
-Beginning of line is column 0. This is calculated using the redisplay
-display tables.  If WINDOW is nil, the current window is assumed.
-If POS is nil, point is assumed. Note that POS must be visible for
-a non-nil result to be returned.
-*/
-       (window, pos))
+static int
+get_current_pixel_pos (Lisp_Object window, Lisp_Object pos,
+		       struct window **w,
+		       struct rune **rb, struct display_line **dl)
 {
-  struct window* w = decode_window (window);
-  display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
-
-  struct display_line *dl = 0;
-  struct display_block *db = 0;
-  struct rune* rb = 0;
-  int y = w->last_point_y[CURRENT_DISP];
-  int x = w->last_point_x[CURRENT_DISP];
-
-  if (MINI_WINDOW_P (w))
-    return Qnil;
+  display_line_dynarr *dla;
+  struct display_block *db = NULL;
+  int x, y;
+
+  *rb = NULL;
+  *dl = NULL;
+  *w = decode_window (window);
+  dla = window_display_lines (*w, CURRENT_DISP);
+  x = (*w)->last_point_x[CURRENT_DISP];    
+  y = (*w)->last_point_y[CURRENT_DISP];
+  if (MINI_WINDOW_P (*w))
+    return 0;
 
   if (y<0 || x<0 || y >= Dynarr_length (dla) || !NILP (pos))
     {
@@ -5251,39 +5248,85 @@
 
       for (i = first_line; i < Dynarr_length (dla); i++)
 	{
-	  dl = Dynarr_atp (dla, i);
+	  *dl = Dynarr_atp (dla, i);
 	  /* find the vertical location first */
-	  if (point >= dl->charpos && point <= dl->end_charpos)
+	  if (point >= (*dl)->charpos && point <= (*dl)->end_charpos)
 	    {
-	      db = get_display_block_from_line (dl, TEXT);
+	      db = get_display_block_from_line (*dl, TEXT);
 	      for (i = 0; i < Dynarr_length (db->runes); i++)
 		{
-		  rb = Dynarr_atp (db->runes, i);
-		  if (point <= rb->charpos)
+		  *rb = Dynarr_atp (db->runes, i);
+		  if (point <= *rb->charpos)
 		    goto found_charpos;
 		}
-	      return Qnil;
+	      return 0;
 	    }
 	}
-      return Qnil;
+      return 0;
     found_charpos:
       ;
     }
   else
     {
       /* optimized case */
-      dl = Dynarr_atp (dla, y);
-      db = get_display_block_from_line (dl, TEXT);
+      *dl = Dynarr_atp (dla, y);
+      db = get_display_block_from_line (*dl, TEXT);
 
       if (x >= Dynarr_length (db->runes))
-	return Qnil;
-
-      rb = Dynarr_atp (db->runes, x);
+	return 0;
+
+      *rb = Dynarr_atp (db->runes, x);
     }
 
+  return 1;
+}
+
+DEFUN ("current-pixel-column", Fcurrent_pixel_column, 0, 2, 0, /*
+Return the horizontal pixel position of point POS in window.
+Beginning of line is column 0.  If WINDOW is nil, the current window
+is assumed.  If POS is nil, point is assumed.  Note that POS must be
+visible for a non-nil result to be returned.  This is calculated using
+the redisplay display tables; because of this, the returned value will
+only be correct if the redisplay tables are up-to-date.  Use
+\"(sit-for 0)\" to insure that they are; however, if WINDOW is part of
+a new frame, use the following instead:
+    (while (not (frame-visible-p frame)) (sleep-for .5))
+*/
+       (window, pos))
+{
+  struct window* w;
+  struct display_line *dl;
+  struct rune* rb;
+
+  if (!get_current_pixel_pos(window, pos, &w, &rb, &dl))
+    return Qnil;
+
   return make_int (rb->xpos - WINDOW_LEFT (w));
 }
 
+DEFUN ("current-pixel-row", Fcurrent_pixel_row, 0, 2, 0, /*
+Return the vertical pixel position of point POS in window.  Top of
+window is row 0.  If WINDOW is nil, the current window is assumed.  If
+POS is nil, point is assumed.  Note that POS must be visible for a
+non-nil result to be returned.  This is calculated using the redisplay
+display tables; because of this, the returned value will only be
+correct if the redisplay tables are up-to-date.  Use \"(sit-for 0)\"
+to insure that they are; however, if WINDOW is part of a new frame,
+use the following instead:
+    (while (not (frame-visible-p frame)) (sleep-for .5))
+*/
+       (window, pos))
+{
+  struct window* w;
+  struct display_line *dl;
+  struct rune* rb;
+
+  if (!get_current_pixel_pos(window, pos, &w, &rb, &dl))
+    return Qnil;
+
+  return make_int (dl->ypos - dl->ascent - WINDOW_TOP (w));
+}
+
 
 #ifdef DEBUG_XEMACS
 /* This is short and simple in elisp, but... it was written to debug
@@ -5431,6 +5474,7 @@
 #endif
   DEFSUBR (Fsave_window_excursion);
   DEFSUBR (Fcurrent_pixel_column);
+  DEFSUBR (Fcurrent_pixel_row);
 }
 
 void