Include <unistd.h> unilaterally.
[bpt/emacs.git] / src / dispnew.c
index 3589387..ae13cfc 100644 (file)
@@ -23,10 +23,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <stdio.h>
 #include <ctype.h>
 #include <setjmp.h>
-
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 
 #include "lisp.h"
 #include "termchar.h"
@@ -121,6 +118,8 @@ static unsigned line_draw_cost (struct glyph_matrix *, int);
 static void update_frame_line (struct frame *, int);
 static struct dim allocate_matrices_for_frame_redisplay
      (Lisp_Object, int, int, int, int *);
+static int required_matrix_height (struct window *);
+static int required_matrix_width (struct window *);
 static void allocate_matrices_for_window_redisplay (struct window *);
 static int realloc_glyph_pool (struct glyph_pool *, struct dim);
 static void adjust_frame_glyphs (struct frame *);
@@ -167,14 +166,8 @@ static int update_window_tree (struct window *, int);
 static int update_window (struct window *, int);
 static int update_frame_1 (struct frame *, int, int);
 static void set_window_cursor_after_update (struct window *);
-static int row_equal_p (struct window *, struct glyph_row *,
-                        struct glyph_row *, int);
 static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
 static void adjust_frame_glyphs_for_frame_redisplay (struct frame *);
-static void reverse_rows (struct glyph_matrix *, int, int);
-static int margin_glyphs_to_reserve (struct window *, int, Lisp_Object);
-static void sync_window_with_frame_matrix_rows (struct window *);
-struct window *frame_row_to_window (struct window *, int);
 
 \f
 /* Non-zero means don't pause redisplay for pending input.  (This is
@@ -358,10 +351,7 @@ static void add_window_display_history (struct window *, char *, int);
    has been interrupted for pending input.  */
 
 static void
-add_window_display_history (w, msg, paused_p)
-     struct window *w;
-     char *msg;
-     int paused_p;
+add_window_display_history (struct window *w, char *msg, int paused_p)
 {
   char *buf;
 
@@ -387,9 +377,7 @@ add_window_display_history (w, msg, paused_p)
    pending input.  */
 
 static void
-add_frame_display_history (f, paused_p)
-     struct frame *f;
-     int paused_p;
+add_frame_display_history (struct frame *f, int paused_p)
 {
   char *buf;
 
@@ -849,7 +837,8 @@ rotate_matrix (struct glyph_matrix *matrix, int first, int last, int by)
    DELTA_BYTES.  */
 
 void
-increment_matrix_positions (struct glyph_matrix *matrix, int start, int end, int delta, int delta_bytes)
+increment_matrix_positions (struct glyph_matrix *matrix, int start, int end,
+                           EMACS_INT delta, EMACS_INT delta_bytes)
 {
   /* Check that START and END are reasonable values.  */
   xassert (start >= 0 && start <= matrix->nrows);
@@ -1088,7 +1077,8 @@ blank_row (struct window *w, struct glyph_row *row, int y)
    ends.  */
 
 void
-increment_row_positions (struct glyph_row *row, int delta, int delta_bytes)
+increment_row_positions (struct glyph_row *row,
+                        EMACS_INT delta, EMACS_INT delta_bytes)
 {
   int area, i;
 
@@ -1178,7 +1168,7 @@ swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b)
 /* Copy glyph row structure FROM to glyph row structure TO, except
    that glyph pointers in the structures are left unchanged.  */
 
-INLINE void
+static INLINE void
 copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from)
 {
   struct glyph *pointers[1 + LAST_AREA];
@@ -1200,7 +1190,8 @@ copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from)
    positions in row TO by DELTA/ DELTA_BYTES.  */
 
 void
-copy_glyph_row_contents (struct glyph_row *to, struct glyph_row *from, int delta, int delta_bytes)
+copy_glyph_row_contents (struct glyph_row *to, struct glyph_row *from,
+                        EMACS_INT delta, EMACS_INT delta_bytes)
 {
   int area;
 
@@ -1241,8 +1232,7 @@ assign_row (struct glyph_row *to, struct glyph_row *from)
 #if GLYPH_DEBUG
 
 static int
-glyph_row_slice_p (window_row, frame_row)
-     struct glyph_row *window_row, *frame_row;
+glyph_row_slice_p (struct glyph_row *window_row, struct glyph_row *frame_row)
 {
   struct glyph *window_glyph_start = window_row->glyphs[0];
   struct glyph *frame_glyph_start = frame_row->glyphs[0];
@@ -1261,9 +1251,8 @@ glyph_row_slice_p (window_row, frame_row)
    in WINDOW_MATRIX is found satisfying the condition.  */
 
 static struct glyph_row *
-find_glyph_row_slice (window_matrix, frame_matrix, row)
-     struct glyph_matrix *window_matrix, *frame_matrix;
-     int row;
+find_glyph_row_slice (struct glyph_matrix *window_matrix,
+                     struct glyph_matrix *frame_matrix, int row)
 {
   int i;
 
@@ -1300,7 +1289,7 @@ prepare_desired_row (struct glyph_row *row)
 
 /* Return a hash code for glyph row ROW.  */
 
-int
+static int
 line_hash_code (struct glyph_row *row)
 {
   int hash = 0;
@@ -1567,7 +1556,7 @@ realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim)
 */
 
 void
-flush_stdout ()
+flush_stdout (void)
 {
   fflush (stdout);
 }
@@ -1579,8 +1568,7 @@ flush_stdout ()
    MATRIX.  */
 
 void
-check_matrix_pointer_lossage (matrix)
-     struct glyph_matrix *matrix;
+check_matrix_pointer_lossage (struct glyph_matrix *matrix)
 {
   int i, j;
 
@@ -1595,9 +1583,7 @@ check_matrix_pointer_lossage (matrix)
 /* Get a pointer to glyph row ROW in MATRIX, with bounds checks.  */
 
 struct glyph_row *
-matrix_row (matrix, row)
-     struct glyph_matrix *matrix;
-     int row;
+matrix_row (struct glyph_matrix *matrix, int row)
 {
   xassert (matrix && matrix->rows);
   xassert (row >= 0 && row < matrix->nrows);
@@ -1621,8 +1607,7 @@ matrix_row (matrix, row)
    window W.  */
 
 static void
-check_matrix_invariants (w)
-     struct window *w;
+check_matrix_invariants (struct window *w)
 {
   struct glyph_matrix *matrix = w->current_matrix;
   int yb = window_text_bottom_y (w);
@@ -1890,7 +1875,7 @@ allocate_matrices_for_frame_redisplay (Lisp_Object window, int x, int y,
 
 /* Return the required height of glyph matrices for window W.  */
 
-int
+static int
 required_matrix_height (struct window *w)
 {
 #ifdef HAVE_WINDOW_SYSTEM
@@ -1916,7 +1901,7 @@ required_matrix_height (struct window *w)
 
 /* Return the required width of glyph matrices for window W.  */
 
-int
+static int
 required_matrix_width (struct window *w)
 {
 #ifdef HAVE_WINDOW_SYSTEM
@@ -2890,6 +2875,14 @@ mirror_make_current (struct window *w, int frame_row)
              else
                swap_glyph_pointers (desired_row, current_row);
              current_row->enabled_p = 1;
+
+             /* Set the Y coordinate of the mode/header line's row.
+                It is needed in draw_row_with_mouse_face to find the
+                screen coordinates.  (Window-based redisplay sets
+                this in update_window, but no one seems to do that
+                for frame-based redisplay.)  */
+             if (current_row->mode_line_p)
+               current_row->y = row;
            }
        }
 
@@ -3135,8 +3128,7 @@ mirror_line_dance (struct window *w, int unchanged_at_top, int nlines, int *copy
    glyph pointers.  */
 
 void
-check_window_matrix_pointers (w)
-     struct window *w;
+check_window_matrix_pointers (struct window *w)
 {
   while (w)
     {
@@ -3162,8 +3154,8 @@ check_window_matrix_pointers (w)
    corresponding frame row.  If it isn't, abort.  */
 
 static void
-check_matrix_pointers (window_matrix, frame_matrix)
-     struct glyph_matrix *window_matrix, *frame_matrix;
+check_matrix_pointers (struct glyph_matrix *window_matrix,
+                      struct glyph_matrix *frame_matrix)
 {
   /* Row number in WINDOW_MATRIX.  */
   int i = 0;
@@ -3197,9 +3189,7 @@ check_matrix_pointers (window_matrix, frame_matrix)
    vertical position relative to W's frame.  */
 
 static int
-window_to_frame_vpos (w, vpos)
-     struct window *w;
-     int vpos;
+window_to_frame_vpos (struct window *w, int vpos)
 {
   struct frame *f = XFRAME (w->frame);
 
@@ -3215,9 +3205,7 @@ window_to_frame_vpos (w, vpos)
    a horizontal position relative to W's frame.  */
 
 static int
-window_to_frame_hpos (w, hpos)
-     struct window *w;
-     int hpos;
+window_to_frame_hpos (struct window *w, int hpos)
 {
   xassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
   hpos += WINDOW_LEFT_EDGE_COL (w);
@@ -3436,7 +3424,9 @@ update_frame (struct frame *f, int force_p, int inhibit_hairy_id_p)
 #endif
     }
 
+#if PERIODIC_PREEMPTION_CHECKING
  do_pause:
+#endif
   /* Reset flags indicating that a window should be updated.  */
   set_window_update_flags (root_window, 0);
 
@@ -4897,7 +4887,9 @@ update_frame_1 (struct frame *f, int force_p, int inhibit_id_p)
        }
     }
 
+#if !PERIODIC_PREEMPTION_CHECKING
  do_pause:
+#endif
 
   clear_desired_matrices (f);
   return pause;
@@ -5351,9 +5343,15 @@ update_frame_line (struct frame *f, int vpos)
  ***********************************************************************/
 
 /* Determine what's under window-relative pixel position (*X, *Y).
-   Return the object (string or buffer) that's there.
+   Return the OBJECT (string or buffer) that's there.
    Return in *POS the position in that object.
-   Adjust *X and *Y to character positions.  */
+   Adjust *X and *Y to character positions.
+   Return in *DX and *DY the pixel coordinates of the click,
+   relative to the top left corner of OBJECT, or relative to
+   the top left corner of the character glyph at (*X, *Y)
+   if OBJECT is nil.
+   Return WIDTH and HEIGHT of the object at (*X, *Y), or zero
+   if the coordinates point to an empty area of the display.  */
 
 Lisp_Object
 buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *pos, Lisp_Object *object, int *dx, int *dy, int *width, int *height)
@@ -5366,7 +5364,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
 #ifdef HAVE_WINDOW_SYSTEM
   struct image *img = 0;
 #endif
-  int x0, x1;
+  int x0, x1, to_x;
 
   /* We used to set current_buffer directly here, but that does the
      wrong thing with `face-remapping-alist' (bug#2044).  */
@@ -5376,9 +5374,34 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
   BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
   start_display (&it, w, startp);
 
-  x0 = *x - WINDOW_LEFT_MARGIN_WIDTH (w);
-  move_it_to (&it, -1, x0 + it.first_visible_x, *y, -1,
-             MOVE_TO_X | MOVE_TO_Y);
+  x0 = *x;
+
+  /* First, move to the beginning of the row corresponding to *Y.  We
+     need to be in that row to get the correct value of base paragraph
+     direction for the text at (*X, *Y).  */
+  move_it_to (&it, -1, 0, *y, -1, MOVE_TO_X | MOVE_TO_Y);
+
+  /* TO_X is the pixel position that the iterator will compute for the
+     glyph at *X.  We add it.first_visible_x because iterator
+     positions include the hscroll.  */
+  to_x = x0 + it.first_visible_x;
+  if (it.bidi_it.paragraph_dir == R2L)
+    /* For lines in an R2L paragraph, we need to mirror TO_X wrt the
+       text area.  This is because the iterator, even in R2L
+       paragraphs, delivers glyphs as if they started at the left
+       margin of the window.  (When we actually produce glyphs for
+       display, we reverse their order in PRODUCE_GLYPHS, but the
+       iterator doesn't know about that.)  The following line adjusts
+       the pixel position to the iterator geometry, which is what
+       move_it_* routines use.  (The -1 is because in a window whose
+       text-area width is W, the rightmost pixel position is W-1, and
+       it should be mirrored into zero pixel position.)  */
+    to_x = window_box_width (w, TEXT_AREA) - to_x - 1;
+
+  /* Now move horizontally in the row to the glyph under *X.  Second
+     argument is ZV to prevent move_it_in_display_line from matching
+     based on buffer positions.  */
+  move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X);
 
   Fset_buffer (old_current_buffer);
 
@@ -5389,6 +5412,22 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
   if (STRINGP (it.string))
     string = it.string;
   *pos = it.current;
+  if (it.what == IT_COMPOSITION
+      && it.cmp_it.nchars > 1
+      && it.cmp_it.reversed_p)
+    {
+      /* The current display element is a grapheme cluster in a
+        composition.  In that case, we need the position of the first
+        character of the cluster.  But, as it.cmp_it.reversed_p is 1,
+        it.current points to the last character of the cluster, thus
+        we must move back to the first character of the same
+        cluster.  */
+      CHARPOS (pos->pos) -= it.cmp_it.nchars - 1;
+      if (STRINGP (it.string))
+       BYTEPOS (pos->pos) = string_char_to_byte (string, CHARPOS (pos->pos));
+      else
+       BYTEPOS (pos->pos) = CHAR_TO_BYTE (CHARPOS (pos->pos));
+    }
 
 #ifdef HAVE_WINDOW_SYSTEM
   if (it.what == IT_IMAGE)
@@ -5410,8 +5449,8 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
          if (img)
            {
              *dy -= row->ascent - glyph->ascent;
-             *dx += glyph->slice.x;
-             *dy += glyph->slice.y;
+             *dx += glyph->slice.img.x;
+             *dy += glyph->slice.img.y;
              /* Image slices positions are still relative to the entire image */
              *width = img->width;
              *height = img->height;
@@ -5451,7 +5490,9 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
    *CHARPOS is set to the position in the string returned.  */
 
 Lisp_Object
-mode_line_string (struct window *w, enum window_part part, int *x, int *y, int *charpos, Lisp_Object *object, int *dx, int *dy, int *width, int *height)
+mode_line_string (struct window *w, enum window_part part,
+                 int *x, int *y, EMACS_INT *charpos, Lisp_Object *object,
+                 int *dx, int *dy, int *width, int *height)
 {
   struct glyph_row *row;
   struct glyph *glyph, *end;
@@ -5518,7 +5559,9 @@ mode_line_string (struct window *w, enum window_part part, int *x, int *y, int *
    the string returned.  */
 
 Lisp_Object
-marginal_area_string (struct window *w, enum window_part part, int *x, int *y, int *charpos, Lisp_Object *object, int *dx, int *dy, int *width, int *height)
+marginal_area_string (struct window *w, enum window_part part,
+                     int *x, int *y, EMACS_INT *charpos, Lisp_Object *object,
+                     int *dx, int *dy, int *width, int *height)
 {
   struct glyph_row *row = w->current_matrix->rows;
   struct glyph *glyph, *end;
@@ -5573,8 +5616,8 @@ marginal_area_string (struct window *w, enum window_part part, int *x, int *y, i
              if (img != NULL)
                *object = img->spec;
              y0 -= row->ascent - glyph->ascent;
-             x0 += glyph->slice.x;
-             y0 += glyph->slice.y;
+             x0 += glyph->slice.img.x;
+             y0 += glyph->slice.img.y;
            }
 #endif
        }
@@ -6362,6 +6405,12 @@ init_display (void)
     f->terminal = t;
 
     t->reference_count++;
+#ifdef MSDOS
+    f->output_data.tty->display_info = &the_only_display_info;
+#else
+    if (f->output_method == output_termcap)
+      create_tty_output (f);
+#endif
     t->display_info.tty->top_frame = selected_frame;
     change_frame_size (XFRAME (selected_frame),
                        FrameRows (t->display_info.tty),
@@ -6529,13 +6578,29 @@ It is up to you to set this variable if your terminal can do that.  */);
 
   DEFVAR_LISP ("initial-window-system", &Vinitial_window_system,
               doc: /* Name of the window system that Emacs uses for the first frame.
-The value is a symbol--for instance, `x' for X windows.
-The value is nil if Emacs is using a text-only terminal.  */);
+The value is a symbol:
+ nil for a termcap frame (a character-only terminal),
+ 'x' for an Emacs frame that is really an X window,
+ 'w32' for an Emacs frame that is a window on MS-Windows display,
+ 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
+ 'pc' for a direct-write MS-DOS frame.
+
+Use of this variable as a boolean is deprecated.  Instead,
+use `display-graphic-p' or any of the other `display-*-p'
+predicates which report frame's specific UI-related capabilities.  */);
 
   DEFVAR_KBOARD ("window-system", Vwindow_system,
                 doc: /* Name of window system through which the selected frame is displayed.
-The value is a symbol--for instance, `x' for X windows.
-The value is nil if the selected frame is on a text-only-terminal.  */);
+The value is a symbol:
+ nil for a termcap frame (a character-only terminal),
+ 'x' for an Emacs frame that is really an X window,
+ 'w32' for an Emacs frame that is a window on MS-Windows display,
+ 'ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
+ 'pc' for a direct-write MS-DOS frame.
+
+Use of this variable as a boolean is deprecated.  Instead,
+use `display-graphic-p' or any of the other `display-*-p'
+predicates which report frame's specific UI-related capabilities.  */);
 
   DEFVAR_LISP ("window-system-version", &Vwindow_system_version,
               doc: /* The version number of the window system in use.