#include <stdio.h>
#include <ctype.h>
#include <setjmp.h>
-
-#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#endif
#include "lisp.h"
#include "termchar.h"
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 *);
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
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;
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;
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);
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;
/* 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];
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;
#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];
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;
/* Return a hash code for glyph row ROW. */
-int
+static int
line_hash_code (struct glyph_row *row)
{
int hash = 0;
*/
void
-flush_stdout ()
+flush_stdout (void)
{
fflush (stdout);
}
MATRIX. */
void
-check_matrix_pointer_lossage (matrix)
- struct glyph_matrix *matrix;
+check_matrix_pointer_lossage (struct glyph_matrix *matrix)
{
int i, j;
/* 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);
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);
/* Return the required height of glyph matrices for window W. */
-int
+static int
required_matrix_height (struct window *w)
{
#ifdef HAVE_WINDOW_SYSTEM
/* Return the required width of glyph matrices for window W. */
-int
+static int
required_matrix_width (struct window *w)
{
#ifdef HAVE_WINDOW_SYSTEM
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;
}
}
glyph pointers. */
void
-check_window_matrix_pointers (w)
- struct window *w;
+check_window_matrix_pointers (struct window *w)
{
while (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;
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);
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);
#endif
}
+#if PERIODIC_PREEMPTION_CHECKING
do_pause:
+#endif
/* Reset flags indicating that a window should be updated. */
set_window_update_flags (root_window, 0);
}
}
+#if !PERIODIC_PREEMPTION_CHECKING
do_pause:
+#endif
clear_desired_matrices (f);
return pause;
***********************************************************************/
/* 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)
#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). */
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);
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)
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;
*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;
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;
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
}
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),
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.