/* Display generation from window structure and buffer text.
- Copyright (C) 1985,86,87,88,93,94,95,97,98,99, 2000, 2001, 2002, 2003
+ Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "termchar.h"
#include "dispextern.h"
#include "buffer.h"
+#include "character.h"
#include "charset.h"
#include "indent.h"
#include "commands.h"
#endif
#ifdef MAC_OS
#include "macterm.h"
+
+Cursor No_Cursor;
+#endif
+
+#ifndef FRAME_X_OUTPUT
+#define FRAME_X_OUTPUT(f) ((f)->output_data.x)
#endif
#define INFINITY 10000000
/* Recenter the window whenever point gets within this many lines of
the top or bottom of the window. This value is translated into a
- pixel value by multiplying it with CANON_Y_UNIT, which means that
- there is really a fixed pixel height scroll margin. */
+ pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
+ that there is really a fixed pixel height scroll margin. */
EMACS_INT scroll_margin;
static enum prop_handled handle_composition_prop P_ ((struct it *));
static enum prop_handled handle_overlay_change P_ ((struct it *));
static enum prop_handled handle_fontified_prop P_ ((struct it *));
+static enum prop_handled handle_auto_composed_prop P_ ((struct it *));
/* Properties handled by iterators. */
static struct props it_props[] =
{
+ {&Qauto_composed, AUTO_COMPOSED_PROP_IDX, handle_auto_composed_prop},
{&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
/* Handle `face' before `display' because some sub-properties of
`display' need to know the face. */
window_text_bottom_y (w)
struct window *w;
{
- struct frame *f = XFRAME (w->frame);
- int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
+ int height = WINDOW_TOTAL_HEIGHT (w);
if (WINDOW_WANTS_MODELINE_P (w))
height -= CURRENT_MODE_LINE_HEIGHT (w);
return height;
}
-
/* Return the pixel width of display area AREA of window W. AREA < 0
means return the total width of W, not including fringes to
the left and right of the window. */
struct window *w;
int area;
{
- struct frame *f = XFRAME (w->frame);
- int width = XFASTINT (w->width);
+ int cols = XFASTINT (w->total_cols);
+ int pixels = 0;
if (!w->pseudo_window_p)
{
- width -= FRAME_SCROLL_BAR_WIDTH (f) + FRAME_FRINGE_COLS (f);
+ cols -= WINDOW_SCROLL_BAR_COLS (w);
if (area == TEXT_AREA)
{
- if (INTEGERP (w->left_margin_width))
- width -= XFASTINT (w->left_margin_width);
- if (INTEGERP (w->right_margin_width))
- width -= XFASTINT (w->right_margin_width);
+ if (INTEGERP (w->left_margin_cols))
+ cols -= XFASTINT (w->left_margin_cols);
+ if (INTEGERP (w->right_margin_cols))
+ cols -= XFASTINT (w->right_margin_cols);
+ pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
}
else if (area == LEFT_MARGIN_AREA)
- width = (INTEGERP (w->left_margin_width)
- ? XFASTINT (w->left_margin_width) : 0);
+ {
+ cols = (INTEGERP (w->left_margin_cols)
+ ? XFASTINT (w->left_margin_cols) : 0);
+ pixels = 0;
+ }
else if (area == RIGHT_MARGIN_AREA)
- width = (INTEGERP (w->right_margin_width)
- ? XFASTINT (w->right_margin_width) : 0);
+ {
+ cols = (INTEGERP (w->right_margin_cols)
+ ? XFASTINT (w->right_margin_cols) : 0);
+ pixels = 0;
+ }
}
- return width * CANON_X_UNIT (f);
+ return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
}
struct window *w;
{
struct frame *f = XFRAME (w->frame);
- int height = XFASTINT (w->height) * CANON_Y_UNIT (f);
+ int height = WINDOW_TOTAL_HEIGHT (w);
xassert (height >= 0);
return max (0, height);
}
+/* Return the window-relative coordinate of the left edge of display
+ area AREA of window W. AREA < 0 means return the left edge of the
+ whole window, to the right of the left fringe of W. */
+
+INLINE int
+window_box_left_offset (w, area)
+ struct window *w;
+ int area;
+{
+ int x;
+
+ if (w->pseudo_window_p)
+ return 0;
+
+ x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
+
+ if (area == TEXT_AREA)
+ x += (WINDOW_LEFT_FRINGE_WIDTH (w)
+ + window_box_width (w, LEFT_MARGIN_AREA));
+ else if (area == RIGHT_MARGIN_AREA)
+ x += (WINDOW_LEFT_FRINGE_WIDTH (w)
+ + window_box_width (w, LEFT_MARGIN_AREA)
+ + window_box_width (w, TEXT_AREA)
+ + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ ? 0
+ : WINDOW_RIGHT_FRINGE_WIDTH (w)));
+ else if (area == LEFT_MARGIN_AREA
+ && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
+ x += WINDOW_LEFT_FRINGE_WIDTH (w);
+
+ return x;
+}
+
+
+/* Return the window-relative coordinate of the right edge of display
+ area AREA of window W. AREA < 0 means return the left edge of the
+ whole window, to the left of the right fringe of W. */
+
+INLINE int
+window_box_right_offset (w, area)
+ struct window *w;
+ int area;
+{
+ return window_box_left_offset (w, area) + window_box_width (w, area);
+}
/* Return the frame-relative coordinate of the left edge of display
area AREA of window W. AREA < 0 means return the left edge of the
int area;
{
struct frame *f = XFRAME (w->frame);
- int x = FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
+ int x;
- if (!w->pseudo_window_p)
- {
- x += (WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f)
- + FRAME_LEFT_FRINGE_WIDTH (f));
+ if (w->pseudo_window_p)
+ return FRAME_INTERNAL_BORDER_WIDTH (f);
- if (area == TEXT_AREA)
- x += window_box_width (w, LEFT_MARGIN_AREA);
- else if (area == RIGHT_MARGIN_AREA)
- x += (window_box_width (w, LEFT_MARGIN_AREA)
- + window_box_width (w, TEXT_AREA));
- }
+ x = (WINDOW_LEFT_EDGE_X (w)
+ + window_box_left_offset (w, area));
return x;
}
return window_box_left (w, area) + window_box_width (w, area);
}
-
/* Get the bounding box of the display area AREA of window W, without
mode lines, in frame-relative coordinates. AREA < 0 means the
whole window, not including the left and right fringes of
int area;
int *box_x, *box_y, *box_width, *box_height;
{
- struct frame *f = XFRAME (w->frame);
-
- *box_width = window_box_width (w, area);
- *box_height = window_box_height (w);
- *box_x = window_box_left (w, area);
- *box_y = (FRAME_INTERNAL_BORDER_WIDTH_SAFE (f)
- + XFASTINT (w->top) * CANON_Y_UNIT (f));
- if (WINDOW_WANTS_HEADER_LINE_P (w))
- *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
+ if (box_width)
+ *box_width = window_box_width (w, area);
+ if (box_height)
+ *box_height = window_box_height (w);
+ if (box_x)
+ *box_x = window_box_left (w, area);
+ if (box_y)
+ {
+ *box_y = WINDOW_TOP_EDGE_Y (w);
+ if (WINDOW_WANTS_HEADER_LINE_P (w))
+ *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
+ }
}
{
int top_y = it.current_y;
int bottom_y = line_bottom_y (&it);
- int window_top_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
+ int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
if (top_y < window_top_y)
visible_p = bottom_y > window_top_y;
return 1;
}
+/* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
+ co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
+ glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
+ not force the value into range. */
+
+void
+pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
+ FRAME_PTR f;
+ register int pix_x, pix_y;
+ int *x, *y;
+ NativeRectangle *bounds;
+ int noclip;
+{
+
+#ifdef HAVE_WINDOW_SYSTEM
+ if (FRAME_WINDOW_P (f))
+ {
+ /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
+ even for negative values. */
+ if (pix_x < 0)
+ pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
+ if (pix_y < 0)
+ pix_y -= FRAME_LINE_HEIGHT (f) - 1;
+
+ pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
+ pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
+
+ if (bounds)
+ STORE_NATIVE_RECT (*bounds,
+ FRAME_COL_TO_PIXEL_X (f, pix_x),
+ FRAME_LINE_TO_PIXEL_Y (f, pix_y),
+ FRAME_COLUMN_WIDTH (f) - 1,
+ FRAME_LINE_HEIGHT (f) - 1);
+
+ if (!noclip)
+ {
+ if (pix_x < 0)
+ pix_x = 0;
+ else if (pix_x > FRAME_TOTAL_COLS (f))
+ pix_x = FRAME_TOTAL_COLS (f);
+
+ if (pix_y < 0)
+ pix_y = 0;
+ else if (pix_y > FRAME_LINES (f))
+ pix_y = FRAME_LINES (f);
+ }
+ }
+#endif
+
+ *x = pix_x;
+ *y = pix_y;
+}
+
+
+/* Given HPOS/VPOS in the current matrix of W, return corresponding
+ frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
+ can't tell the positions because W's display is not up to date,
+ return 0. */
+
+int
+glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
+ struct window *w;
+ int hpos, vpos;
+ int *frame_x, *frame_y;
+{
+#ifdef HAVE_WINDOW_SYSTEM
+ if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
+ {
+ int success_p;
+
+ xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
+ xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
+
+ if (display_completed)
+ {
+ struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
+ struct glyph *glyph = row->glyphs[TEXT_AREA];
+ struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
+
+ hpos = row->x;
+ vpos = row->y;
+ while (glyph < end)
+ {
+ hpos += glyph->pixel_width;
+ ++glyph;
+ }
+
+ success_p = 1;
+ }
+ else
+ {
+ hpos = vpos = 0;
+ success_p = 0;
+ }
+
+ *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
+ *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
+ return success_p;
+ }
+#endif
+
+ *frame_x = hpos;
+ *frame_y = vpos;
+ return 1;
+}
+
+
#ifdef HAVE_WINDOW_SYSTEM
/* Find the glyph under window-relative coordinates X/Y in window W.
{
struct glyph *glyph, *end;
struct glyph_row *row = NULL;
- int x0, i, left_area_width;
+ int x0, i;
/* Find row containing Y. Give up if some row is not enabled. */
for (i = 0; i < w->current_matrix->nrows; ++i)
}
else
{
- left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
- if (x < left_area_width)
+ if (x < window_box_left_offset (w, TEXT_AREA))
{
*area = LEFT_MARGIN_AREA;
- x0 = 0;
+ x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
}
- else if (x < left_area_width + window_box_width (w, TEXT_AREA))
+ else if (x < window_box_right_offset (w, TEXT_AREA))
{
*area = TEXT_AREA;
- x0 = row->x + left_area_width;
+ x0 = window_box_left_offset (w, TEXT_AREA);
}
else
{
*area = RIGHT_MARGIN_AREA;
- x0 = left_area_width + window_box_width (w, TEXT_AREA);
+ x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
}
}
/* A pseudo-window is always full-width, and starts at the
left edge of the frame, plus a frame border. */
struct frame *f = XFRAME (w->frame);
- *x -= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
+ *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
*y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
}
else
{
- *x = FRAME_TO_WINDOW_PIXEL_X (w, *x);
+ *x -= WINDOW_LEFT_EDGE_X (w);
*y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
}
}
if (s->row->full_width_p)
{
- /* Draw full-width. X coordinates are relative to S->w->left. */
- int canon_x = CANON_X_UNIT (s->f);
-
- r.x = WINDOW_LEFT_MARGIN (s->w) * canon_x;
- r.width = XFASTINT (s->w->width) * canon_x;
-
- if (FRAME_HAS_VERTICAL_SCROLL_BARS (s->f))
- {
- int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x;
- if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s->f))
- r.x -= width;
- }
-
- r.x += FRAME_INTERNAL_BORDER_WIDTH (s->f);
+ /* Draw full-width. X coordinates are relative to S->w->left_col. */
+ r.x = WINDOW_LEFT_EDGE_X (s->w);
+ r.width = WINDOW_TOTAL_WIDTH (s->w);
/* Unless displaying a mode or menu bar line, which are always
fully visible, clip to the visible part of the row. */
else
{
/* This is a text line that may be partially visible. */
- r.x = WINDOW_AREA_TO_FRAME_PIXEL_X (s->w, s->area, 0);
+ r.x = window_box_left (s->w, s->area);
r.width = window_box_width (s->w, s->area);
r.height = s->row->visible_height;
}
intentionally draws over other lines. */
if (s->for_overlaps_p)
{
- r.y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
+ r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
r.height = window_text_bottom_y (s->w) - r.y;
}
else
partially visible lines at the top of a window. */
if (!s->row->full_width_p
&& MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
- r.y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
+ r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
else
r.y = max (0, s->row->y);
/* If drawing a tool-bar window, draw it over the internal border
at the top of the window. */
if (s->w == XWINDOW (s->f->tool_bar_window))
- r.y -= s->f->output_data.x->internal_border_width;
+ r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
}
r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
CONVERT_FROM_XRECT (r, *nr);
#else
*nr = r;
-#endif;
+#endif
}
#endif /* HAVE_WINDOW_SYSTEM */
{
/* Mode lines, menu bar in terminal frames. */
it->first_visible_x = 0;
- it->last_visible_x = XFASTINT (w->width) * CANON_X_UNIT (it->f);
+ it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
}
else
{
it->first_visible_x
- = XFASTINT (it->w->hscroll) * CANON_X_UNIT (it->f);
+ = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
it->last_visible_x = (it->first_visible_x
+ window_box_width (w, TEXT_AREA));
}
it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
- it->current_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w) + w->vscroll;
+ it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
}
/* Leave room for a border glyph. */
struct face *face = FACE_FROM_ID (it->f, face_id);
c = string_char_and_length (p, rest, &len);
- face_id = FACE_FOR_CHAR (it->f, face, c);
+ face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
}
}
else
{
int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
struct face *face = FACE_FROM_ID (it->f, face_id);
- face_id = FACE_FOR_CHAR (it->f, face, c);
+ face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
}
}
return 0;
}
- return CONSP (prop) && EQ (XCAR (prop), Qimage);
+ return (CONSP (prop)
+ && (EQ (XCAR (prop), Qimage)
+ || EQ (XCAR (prop), Qspace)));
}
`composition' property
***********************************************************************/
+static enum prop_handled
+handle_auto_composed_prop (it)
+ struct it *it;
+{
+ enum prop_handled handled = HANDLED_NORMALLY;
+
+ if (FUNCTIONP (Vauto_composition_function))
+ {
+ Lisp_Object val;
+ EMACS_INT pos, this_pos;
+
+ if (STRINGP (it->string))
+ pos = IT_STRING_CHARPOS (*it);
+ else
+ pos = IT_CHARPOS (*it);
+ this_pos = pos;
+
+ val =Fget_char_property (make_number (pos), Qauto_composed, it->string);
+ if (! NILP (val))
+ {
+ Lisp_Object limit = Qnil, next;
+
+ /* As Fnext_single_char_property_change is very slow, we
+ limit the search to the current line. */
+ if (STRINGP (it->string))
+ limit = make_number (SCHARS (it->string));
+ else
+ limit = make_number (find_next_newline_no_quit (pos, 1));
+
+ next = (Fnext_single_property_change
+ (make_number (pos), Qauto_composed, it->string, limit));
+ if (XINT (next) < XINT (limit))
+ {
+ /* The current point is auto-composed, but there exist
+ characters not yet composed beyond the auto-composed
+ region. There's a possiblity that the last
+ characters in the region may be newly composed. */
+ int charpos = XINT (next) - 1, bytepos, c;
+
+ if (STRINGP (it->string))
+ {
+ bytepos = string_char_to_byte (it->string, charpos);
+ c = SDATA (it->string)[bytepos];
+ }
+ else
+ {
+ bytepos = CHAR_TO_BYTE (charpos);
+ c = FETCH_BYTE (bytepos);
+ }
+ if (c != '\n')
+ /* If the last character is not newline, it may be
+ composed with the following characters. */
+ val = Qnil, pos = charpos + 1;
+ }
+ }
+ if (NILP (val))
+ {
+ int count = SPECPDL_INDEX ();
+ Lisp_Object args[3];
+
+ args[0] = Vauto_composition_function;
+ specbind (Qauto_composition_function, Qnil);
+ args[1] = make_number (pos);
+ args[2] = it->string;
+ safe_call (3, args);
+ unbind_to (count, Qnil);
+
+ if (this_pos == pos)
+ {
+ val = Fget_char_property (args[1], Qauto_composed, it->string);
+ /* Return HANDLED_RECOMPUTE_PROPS only if function composed
+ something. This avoids an endless loop if they failed to
+ fontify the text for which reason ever. */
+ if (! NILP (val))
+ handled = HANDLED_RECOMPUTE_PROPS;
+ }
+ else
+ handled = HANDLED_RECOMPUTE_PROPS;
+ }
+ }
+
+ return handled;
+}
+
/* Set up iterator IT from `composition' property at its current
position. Called from handle_stop. */
struct it *it;
{
Lisp_Object prop, string;
- int pos, pos_byte, end;
+ EMACS_INT pos, pos_byte, start, end;
enum prop_handled handled = HANDLED_NORMALLY;
if (STRINGP (it->string))
/* If there's a valid composition and point is not inside of the
composition (in the case that the composition is from the current
buffer), draw a glyph composed from the composition components. */
- if (find_composition (pos, -1, &pos, &end, &prop, string)
- && COMPOSITION_VALID_P (pos, end, prop)
- && (STRINGP (it->string) || (PT <= pos || PT >= end)))
+ if (find_composition (pos, -1, &start, &end, &prop, string)
+ && COMPOSITION_VALID_P (start, end, prop)
+ && (STRINGP (it->string) || (PT <= start || PT >= end)))
{
- int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
+ int id;
+
+ if (start != pos)
+ {
+ if (STRINGP (it->string))
+ pos_byte = string_char_to_byte (it->string, start);
+ else
+ pos_byte = CHAR_TO_BYTE (start);
+ }
+ id = get_composition_id (start, pos_byte, end - start, prop, string);
if (id >= 0)
{
int charpos;
{
extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
- Lisp_Object ov, overlay, window, str, invisible;
+ Lisp_Object overlay, window, str, invisible;
+ struct Lisp_Overlay *ov;
int start, end;
int size = 20;
int n = 0, i, j, invis_p;
while (0)
/* Process overlay before the overlay center. */
- for (ov = current_buffer->overlays_before; CONSP (ov); ov = XCDR (ov))
+ for (ov = current_buffer->overlays_before; ov; ov = ov->next)
{
- overlay = XCAR (ov);
+ XSETMISC (overlay, ov);
xassert (OVERLAYP (overlay));
start = OVERLAY_POSITION (OVERLAY_START (overlay));
end = OVERLAY_POSITION (OVERLAY_END (overlay));
}
/* Process overlays after the overlay center. */
- for (ov = current_buffer->overlays_after; CONSP (ov); ov = XCDR (ov))
+ for (ov = current_buffer->overlays_after; ov; ov = ov->next)
{
- overlay = XCAR (ov);
+ XSETMISC (overlay, ov);
xassert (OVERLAYP (overlay));
start = OVERLAY_POSITION (OVERLAY_START (overlay));
end = OVERLAY_POSITION (OVERLAY_END (overlay));
IT_STRING_BYTEPOS (*it) = -1;
it->string = Qnil;
it->method = next_element_from_buffer;
+ /* RMS: I added this to fix a bug in move_it_vertically_backward
+ where it->area continued to relate to the starting point
+ for the backward motion. Bug report from
+ Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
+ However, I am not sure whether reseat still does the right thing
+ in general after this change. */
+ it->area = TEXT_AREA;
it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
it->sp = 0;
it->face_before_selective_p = 0;
else if ((it->c < ' '
&& (it->area != TEXT_AREA
|| (it->c != '\n' && it->c != '\t')))
- || (it->multibyte_p
- ? ((it->c >= 127
- && it->len == 1)
- || !CHAR_PRINTABLE_P (it->c))
- : (it->c >= 127
- && it->c == unibyte_char_to_multibyte (it->c))))
+ || (it->c != '\n' && it->c != '\t'
+ && (it->multibyte_p ? !CHAR_PRINTABLE_P (it->c)
+ : it->c == 127)))
{
/* IT->c is a control character which must be displayed
either as '\003' or as `^C' where the '\\' and '^'
else
escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
- if (SINGLE_BYTE_CHAR_P (it->c))
- str[0] = it->c, len = 1;
+ if (CHAR_BYTE8_P (it->c))
+ {
+ str[0] = CHAR_TO_BYTE8 (it->c);
+ len = 1;
+ }
+ else if (it->c < 256)
+ {
+ str[0] = it->c;
+ len = 1;
+ }
else
{
- len = CHAR_STRING_NO_SIGNAL (it->c, str);
- if (len < 0)
- {
- /* It's an invalid character, which
- shouldn't happen actually, but due to
- bugs it may happen. Let's print the char
- as is, there's not much meaningful we can
- do with it. */
- str[0] = it->c;
- str[1] = it->c >> 8;
- str[2] = it->c >> 16;
- str[3] = it->c >> 24;
- len = 4;
- }
+ /* It's an invalid character, which
+ shouldn't happen actually, but due to
+ bugs it may happen. Let's print the char
+ as is, there's not much meaningful we can
+ do with it. */
+ str[0] = it->c;
+ str[1] = it->c >> 8;
+ str[2] = it->c >> 16;
+ str[3] = it->c >> 24;
+ len = 4;
}
for (i = 0; i < len; i++)
&& FRAME_WINDOW_P (it->f))
{
struct face *face = FACE_FROM_ID (it->f, it->face_id);
- it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
+ int pos = (it->s ? -1
+ : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
+ : IT_CHARPOS (*it));
+
+ it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
}
}
the line. */
if (skip == MOVE_X_REACHED)
{
+ /* Wait! We can conclude that TO_Y is in the line if
+ the already scanned glyphs make the line tall enough
+ because further scanning doesn't make it shorter. */
+ line_height = it->max_ascent + it->max_descent;
+ if (to_y >= it->current_y
+ && to_y < it->current_y + line_height)
+ {
+ reached = 6;
+ break;
+ }
it_backup = *it;
TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
skip2 = move_it_in_display_line_to (it, to_charpos, -1,
xassert (dy >= 0);
/* Estimate how many newlines we must move back. */
- nlines = max (1, dy / CANON_Y_UNIT (it->f));
+ nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
/* Set the iterator's position that many lines back. */
while (nlines-- && IT_CHARPOS (*it) > BEGV)
move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
xassert (IT_CHARPOS (*it) >= BEGV);
+ /* H is the actual vertical distance from the position in *IT
+ and the starting position. */
h = it2.current_y - it->current_y;
+ /* NLINES is the distance in number of lines. */
nlines = it2.vpos - it->vpos;
- /* Correct IT's y and vpos position. */
+ /* Correct IT's y and vpos position
+ so that they are relative to the starting point. */
it->vpos -= nlines;
it->current_y -= h;
move_it_by_lines (it, nlines, 1);
xassert (IT_CHARPOS (*it) <= start_pos);
}
- else if (nlines)
+ else
{
- /* The y-position we try to reach. Note that h has been
- subtracted in front of the if-statement. */
+ /* The y-position we try to reach, relative to *IT.
+ Note that H has been subtracted in front of the if-statement. */
int target_y = it->current_y + h - dy;
int y0 = it3.current_y;
int y1 = line_bottom_y (&it3);
for (i = 0; i < nbytes; i += char_bytes)
{
c = string_char_and_length (m + i, nbytes - i, &char_bytes);
- work[0] = (SINGLE_BYTE_CHAR_P (c)
+ work[0] = (ASCII_CHAR_P (c)
? c
: multibyte_char_to_unibyte (c, Qnil));
insert_1_both (work, 1, 1, 1, 0, 0);
XMARKER (oldpoint)->bytepos);
UNGCPRO;
- unchain_marker (oldpoint);
- unchain_marker (oldbegv);
- unchain_marker (oldzv);
+ unchain_marker (XMARKER (oldpoint));
+ unchain_marker (XMARKER (oldbegv));
+ unchain_marker (XMARKER (oldzv));
tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
set_buffer_internal (oldbuf);
{
struct it it;
struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
- int total_height = XFASTINT (root->height) + XFASTINT (w->height);
+ int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
int height, max_height;
- int unit = CANON_Y_UNIT (f);
+ int unit = FRAME_LINE_HEIGHT (f);
struct text_pos start;
struct buffer *old_current_buffer = NULL;
/* Compute the max. number of lines specified by the user. */
if (FLOATP (Vmax_mini_window_height))
- max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_HEIGHT (f);
+ max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
else if (INTEGERP (Vmax_mini_window_height))
max_height = XINT (Vmax_mini_window_height);
else
{
/* Let it grow only, until we display an empty message, in which
case the window shrinks again. */
- if (height > XFASTINT (w->height))
+ if (height > WINDOW_TOTAL_LINES (w))
{
- int old_height = XFASTINT (w->height);
+ int old_height = WINDOW_TOTAL_LINES (w);
freeze_window_starts (f, 1);
- grow_mini_window (w, height - XFASTINT (w->height));
- window_height_changed_p = XFASTINT (w->height) != old_height;
+ grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
+ window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
}
- else if (height < XFASTINT (w->height)
+ else if (height < WINDOW_TOTAL_LINES (w)
&& (exact_p || BEGV == ZV))
{
- int old_height = XFASTINT (w->height);
+ int old_height = WINDOW_TOTAL_LINES (w);
freeze_window_starts (f, 0);
shrink_mini_window (w);
- window_height_changed_p = XFASTINT (w->height) != old_height;
+ window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
}
}
else
{
/* Always resize to exact size needed. */
- if (height > XFASTINT (w->height))
+ if (height > WINDOW_TOTAL_LINES (w))
{
- int old_height = XFASTINT (w->height);
+ int old_height = WINDOW_TOTAL_LINES (w);
freeze_window_starts (f, 1);
- grow_mini_window (w, height - XFASTINT (w->height));
- window_height_changed_p = XFASTINT (w->height) != old_height;
+ grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
+ window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
}
- else if (height < XFASTINT (w->height))
+ else if (height < WINDOW_TOTAL_LINES (w))
{
- int old_height = XFASTINT (w->height);
+ int old_height = WINDOW_TOTAL_LINES (w);
freeze_window_starts (f, 0);
shrink_mini_window (w);
if (height)
{
freeze_window_starts (f, 1);
- grow_mini_window (w, height - XFASTINT (w->height));
+ grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
}
- window_height_changed_p = XFASTINT (w->height) != old_height;
+ window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
}
}
for (i = 0; i < nbytes; i += n)
{
c = string_char_and_length (s + i, nbytes - i, &n);
- work[0] = (SINGLE_BYTE_CHAR_P (c)
+ work[0] = (ASCII_CHAR_P (c)
? c
: multibyte_char_to_unibyte (c, Qnil));
insert_1_both (work, 1, 1, 1, 0, 0);
Output Cursor
***********************************************************************/
+#ifdef HAVE_WINDOW_SYSTEM
+
/* EXPORT:
Nominal cursor position -- where to draw output.
HPOS and VPOS are window relative glyph matrix coordinates.
}
}
+#endif /* HAVE_WINDOW_SYSTEM */
\f
/***********************************************************************
int do_update = FRAME_EXTERNAL_TOOL_BAR(f);
#else
int do_update = WINDOWP (f->tool_bar_window)
- && XFASTINT (XWINDOW (f->tool_bar_window)->height) > 0;
+ && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
#endif
if (do_update)
windows_or_buffers_changed anyway. */
if (windows_or_buffers_changed
|| !NILP (w->update_mode_line)
+ || update_mode_lines
|| ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
< BUF_MODIFF (XBUFFER (w->buffer)))
!= !NILP (w->last_had_star))
{
struct buffer *prev = current_buffer;
int count = SPECPDL_INDEX ();
+ Lisp_Object old_tool_bar;
+ struct gcpro gcpro1;
/* Set current_buffer to the buffer of the selected
window of the frame, so that we get the right local
specbind (Qoverriding_local_map, Qnil);
}
+ old_tool_bar = f->tool_bar_items;
+ GCPRO1 (old_tool_bar);
+
/* Build desired tool-bar items from keymaps. */
+ BLOCK_INPUT;
f->tool_bar_items
= tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
+ UNBLOCK_INPUT;
- /* Redisplay the tool-bar in case we changed it. */
- w->update_mode_line = Qt;
+ /* Redisplay the tool-bar if we changed it. */
+ if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
+ w->update_mode_line = Qt;
+
+ UNGCPRO;
unbind_to (count, Qnil);
set_buffer_internal_1 (prev);
F->desired_tool_bar_string in the tool-bar window of frame F. */
init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
it.first_visible_x = 0;
- it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
+ it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
while (!ITERATOR_AT_END_P (&it))
display_tool_bar_line (&it);
}
- return (it.current_y + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
+ return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
}
if (WINDOWP (f->tool_bar_window)
|| (w = XWINDOW (f->tool_bar_window),
- XFASTINT (w->height) > 0))
+ WINDOW_TOTAL_LINES (w) > 0))
{
update_tool_bar (f, 1);
if (f->n_tool_bar_items)
can turn off tool-bars by specifying tool-bar-lines zero. */
if (!WINDOWP (f->tool_bar_window)
|| (w = XWINDOW (f->tool_bar_window),
- XFASTINT (w->height) == 0))
+ WINDOW_TOTAL_LINES (w) == 0))
return 0;
/* Set up an iterator for the tool-bar window. */
init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
it.first_visible_x = 0;
- it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
+ it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
row = it.glyph_row;
/* Build a string that represents the contents of the tool-bar. */
/* If there are blank lines at the end, except for a partially
visible blank line at the end that is smaller than
- CANON_Y_UNIT, change the tool-bar's height. */
+ FRAME_LINE_HEIGHT, change the tool-bar's height. */
row = it.glyph_row - 1;
if (!row->displays_text_p
- && row->height >= CANON_Y_UNIT (f))
+ && row->height >= FRAME_LINE_HEIGHT (f))
change_height_p = 1;
/* If row displays tool-bar items, but is partially visible,
frame parameter. */
if (change_height_p
&& (nlines = tool_bar_lines_needed (f),
- nlines != XFASTINT (w->height)))
+ nlines != WINDOW_TOTAL_LINES (w)))
{
extern Lisp_Object Qtool_bar_lines;
Lisp_Object frame;
- int old_height = XFASTINT (w->height);
+ int old_height = WINDOW_TOTAL_LINES (w);
XSETFRAME (frame, f);
clear_glyph_matrix (w->desired_matrix);
Fcons (Fcons (Qtool_bar_lines,
make_number (nlines)),
Qnil));
- if (XFASTINT (w->height) != old_height)
+ if (WINDOW_TOTAL_LINES (w) != old_height)
fonts_changed_p = 1;
}
}
{
Lisp_Object key, frame;
struct input_event event;
+ EVENT_INIT (event);
/* Show item in released state. */
show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
if (!NILP (enabled_p))
{
/* Compute the x-position of the glyph. In front and past the
- image is a space. We include this is the highlighted area. */
+ image is a space. We include this in the highlighted area. */
row = MATRIX_ROW (w->current_matrix, vpos);
for (i = x = 0; i < hpos; ++i)
x += row->glyphs[TEXT_AREA][i].pixel_width;
p.bx = -1;
if (left_p)
{
- if (p.wd > FRAME_X_LEFT_FRINGE_WIDTH (f))
- p.wd = FRAME_X_LEFT_FRINGE_WIDTH (f);
- p.x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
- - p.wd
- - (FRAME_X_LEFT_FRINGE_WIDTH (f) - p.wd) / 2);
- if (p.wd < FRAME_X_LEFT_FRINGE_WIDTH (f) || row->height > p.h)
+ int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
+ int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ ? LEFT_MARGIN_AREA
+ : TEXT_AREA));
+ if (p.wd > wd)
+ p.wd = wd;
+ p.x = x - p.wd - (wd - p.wd) / 2;
+
+ if (p.wd < wd || row->height > p.h)
{
/* If W has a vertical border to its left, don't draw over it. */
- int border = ((XFASTINT (w->left) > 0
- && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
- ? 1 : 0);
- p.bx = (window_box_left (w, -1)
- - FRAME_X_LEFT_FRINGE_WIDTH (f)
- + border);
- p.nx = (FRAME_X_LEFT_FRINGE_WIDTH (f) - border);
+ wd -= ((!WINDOW_LEFTMOST_P (w)
+ && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
+ ? 1 : 0);
+ p.bx = x - wd;
+ p.nx = wd;
}
}
else
{
- if (p.wd > FRAME_X_RIGHT_FRINGE_WIDTH (f))
- p.wd = FRAME_X_RIGHT_FRINGE_WIDTH (f);
- p.x = (window_box_right (w, -1)
- + (FRAME_X_RIGHT_FRINGE_WIDTH (f) - p.wd) / 2);
+ int x = window_box_right (w,
+ (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ ? RIGHT_MARGIN_AREA
+ : TEXT_AREA));
+ int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
+ if (p.wd > wd)
+ p.wd = wd;
+ p.x = x + (wd - p.wd) / 2;
/* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
the fringe. */
- if (p.wd < FRAME_X_RIGHT_FRINGE_WIDTH (f) || row->height > p.h)
+ if (p.wd < wd || row->height > p.h)
{
- p.bx = window_box_right (w, -1);
- p.nx = FRAME_X_RIGHT_FRINGE_WIDTH (f);
+ p.bx = x;
+ p.nx = wd;
}
}
if (p.bx >= 0)
{
- int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
+ int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
p.ny = row->visible_height;
struct window *w;
struct glyph_row *row;
{
- struct frame *f = XFRAME (w->frame);
enum fringe_bitmap_type bitmap;
xassert (interrupt_input_blocked);
if (row->visible_height <= 0)
return;
- if (FRAME_X_LEFT_FRINGE_WIDTH (f) != 0)
+ if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
{
/* Decide which bitmap to draw in the left fringe. */
if (row->overlay_arrow_p)
draw_fringe_bitmap (w, row, bitmap, 1);
}
- if (FRAME_X_RIGHT_FRINGE_WIDTH (f) != 0)
+ if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
{
/* Decide which bitmap to draw in the right fringe. */
if (row->truncated_on_right_p)
bitmap = RIGHT_TRUNCATION_BITMAP;
else if (row->continued_p)
bitmap = CONTINUED_LINE_BITMAP;
- else if (row->indicate_empty_line_p && FRAME_X_LEFT_FRINGE_WIDTH (f) == 0)
+ else if (row->indicate_empty_line_p && WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
bitmap = ZV_LINE_BITMAP;
else
bitmap = NO_FRINGE_BITMAP;
struct frame *f;
int redraw;
{
- int o_left = FRAME_X_LEFT_FRINGE_WIDTH (f);
- int o_right = FRAME_X_RIGHT_FRINGE_WIDTH (f);
- int o_cols = FRAME_X_FRINGE_COLS (f);
+ int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
+ int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
+ int o_cols = FRAME_FRINGE_COLS (f);
Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
int conf_wid = left_wid + right_wid;
- int font_wid = FONT_WIDTH (FRAME_FONT (f));
+ int font_wid = FRAME_COLUMN_WIDTH (f);
int cols = (left_wid + right_wid + font_wid-1) / font_wid;
int real_wid = cols * font_wid;
if (left_wid && right_wid)
if (left_fringe_width < 0)
{
/* Left fringe width is fixed, adjust right fringe if necessary */
- FRAME_X_LEFT_FRINGE_WIDTH (f) = left_wid;
- FRAME_X_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
+ FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
+ FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
}
else if (right_fringe_width < 0)
{
/* Right fringe width is fixed, adjust left fringe if necessary */
- FRAME_X_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
- FRAME_X_RIGHT_FRINGE_WIDTH (f) = right_wid;
+ FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
+ FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
}
else
{
Note that we are doing integer arithmetic here, so don't
lose a pixel if the total width is an odd number. */
int fill = real_wid - conf_wid;
- FRAME_X_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
- FRAME_X_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
+ FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
+ FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
}
}
else if (left_fringe_width)
{
- FRAME_X_LEFT_FRINGE_WIDTH (f) = real_wid;
- FRAME_X_RIGHT_FRINGE_WIDTH (f) = 0;
+ FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
+ FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
}
else
{
- FRAME_X_LEFT_FRINGE_WIDTH (f) = 0;
- FRAME_X_RIGHT_FRINGE_WIDTH (f) = real_wid;
+ FRAME_LEFT_FRINGE_WIDTH (f) = 0;
+ FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
}
- FRAME_X_FRINGE_COLS (f) = cols;
- FRAME_X_FRINGE_WIDTH (f) = real_wid;
+ FRAME_FRINGE_COLS (f) = cols;
}
else
{
- FRAME_X_LEFT_FRINGE_WIDTH (f) = 0;
- FRAME_X_RIGHT_FRINGE_WIDTH (f) = 0;
- FRAME_X_FRINGE_COLS (f) = 0;
- FRAME_X_FRINGE_WIDTH (f) = 0;
+ FRAME_LEFT_FRINGE_WIDTH (f) = 0;
+ FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
+ FRAME_FRINGE_COLS (f) = 0;
}
if (redraw && FRAME_VISIBLE_P (f))
- if (o_left != FRAME_X_LEFT_FRINGE_WIDTH (f) ||
- o_right != FRAME_X_RIGHT_FRINGE_WIDTH (f) ||
- o_cols != FRAME_X_FRINGE_COLS (f))
+ if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
+ o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
+ o_cols != FRAME_FRINGE_COLS (f))
redraw_frame (f);
}
hscrolled_p |= hscroll_window_tree (w->vchild);
else if (w->cursor.vpos >= 0)
{
- int h_margin, text_area_x, text_area_y;
- int text_area_width, text_area_height;
+ int h_margin;
+ int text_area_width;
struct glyph_row *current_cursor_row
= MATRIX_ROW (w->current_matrix, w->cursor.vpos);
struct glyph_row *desired_cursor_row
? desired_cursor_row
: current_cursor_row);
- window_box (w, TEXT_AREA, &text_area_x, &text_area_y,
- &text_area_width, &text_area_height);
+ text_area_width = window_box_width (w, TEXT_AREA);
/* Scroll when cursor is inside this scroll margin. */
- h_margin = hscroll_margin * CANON_X_UNIT (XFRAME (w->frame));
+ h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
if ((XFASTINT (w->hscroll)
&& w->cursor.x <= h_margin)
/* Position cursor in window. */
if (!hscroll_relative_p && hscroll_step_abs == 0)
hscroll = max (0, it.current_x - text_area_width / 2)
- / CANON_X_UNIT (it.f);
+ / FRAME_COLUMN_WIDTH (it.f);
else if (w->cursor.x >= text_area_width - h_margin)
{
if (hscroll_relative_p)
- h_margin;
else
wanted_x = text_area_width
- - hscroll_step_abs * CANON_X_UNIT (it.f)
+ - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
- h_margin;
hscroll
- = max (0, it.current_x - wanted_x) / CANON_X_UNIT (it.f);
+ = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
}
else
{
wanted_x = text_area_width * hscroll_step_rel
+ h_margin;
else
- wanted_x = hscroll_step_abs * CANON_X_UNIT (it.f)
+ wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
+ h_margin;
hscroll
- = max (0, it.current_x - wanted_x) / CANON_X_UNIT (it.f);
+ = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
}
hscroll = max (hscroll, XFASTINT (w->min_hscroll));
struct buffer *prev_buf, *buf;
int prev_pt, pt;
{
- int start, end;
+ EMACS_INT start, end;
Lisp_Object prop;
Lisp_Object buffer;
/* Make sure the cursor was last displayed
in this window. Otherwise we have to reposition it. */
&& 0 <= w->cursor.vpos
- && XINT (w->height) > w->cursor.vpos)
+ && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
{
if (!must_finish)
{
/* Update the display. */
set_window_update_flags (XWINDOW (f->root_window), 1);
pause |= update_frame (f, 0, 0);
+#if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
if (pause)
break;
+#endif
if (n == size)
{
w->window_end_valid = w->buffer;
#if 0 /* This is incorrect with variable-height lines. */
xassert (XINT (w->window_end_vpos)
- < (XINT (w->height)
+ < (WINDOW_TOTAL_LINES (w)
- (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
#endif
w->update_mode_line = Qnil;
struct Lisp_Char_Table *dp;
int c;
{
- int code[4], i;
Lisp_Object val;
- if (SINGLE_BYTE_CHAR_P (c))
- return (dp->contents[c]);
-
- SPLIT_CHAR (c, code[0], code[1], code[2]);
- if (code[1] < 32)
- code[1] = -1;
- else if (code[2] < 32)
- code[2] = -1;
-
- /* Here, the possible range of code[0] (== charset ID) is
- 128..max_charset. Since the top level char table contains data
- for multibyte characters after 256th element, we must increment
- code[0] by 128 to get a correct index. */
- code[0] += 128;
- code[3] = -1; /* anchor */
-
- for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
+ if (ASCII_CHAR_P (c))
{
- val = dp->contents[code[i]];
- if (!SUB_CHAR_TABLE_P (val))
- return (NILP (val) ? dp->defalt : val);
+ val = dp->ascii;
+ if (SUB_CHAR_TABLE_P (val))
+ val = XSUB_CHAR_TABLE (val)->contents[c];
}
+ else
+ {
+ Lisp_Object table;
- /* Here, val is a sub char table. We return the default value of
- it. */
- return (dp->defalt);
+ XSETCHAR_TABLE (table, dp);
+ val = char_table_ref (table, c);
+ }
+ if (NILP (val))
+ val = dp->defalt;
+ return val;
}
within this distance from the top or bottom of the window. */
if (scroll_margin > 0)
{
- this_scroll_margin = min (scroll_margin, XINT (w->height) / 4);
- this_scroll_margin *= CANON_Y_UNIT (f);
+ this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
+ this_scroll_margin *= FRAME_LINE_HEIGHT (f);
}
else
this_scroll_margin = 0;
scroll_max = 10;
else
scroll_max = 0;
- scroll_max *= CANON_Y_UNIT (f);
+ scroll_max *= FRAME_LINE_HEIGHT (f);
/* Decide whether we have to scroll down. Start at the window end
and move this_scroll_margin up to find the position of the scroll
/* Set AMOUNT_TO_SCROLL to at least one line,
and at most scroll_conservatively lines. */
amount_to_scroll
- = min (max (dy, CANON_Y_UNIT (f)),
- CANON_Y_UNIT (f) * scroll_conservatively);
+ = min (max (dy, FRAME_LINE_HEIGHT (f)),
+ FRAME_LINE_HEIGHT (f) * scroll_conservatively);
else if (scroll_step || temp_scroll_step)
amount_to_scroll = scroll_max;
else
{
aggressive = current_buffer->scroll_up_aggressively;
- height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
- - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
+ height = WINDOW_BOX_TEXT_HEIGHT (w);
if (NUMBERP (aggressive))
amount_to_scroll = XFLOATINT (aggressive) * height;
}
if (scroll_conservatively)
amount_to_scroll =
- max (dy, CANON_Y_UNIT (f) * max (scroll_step, temp_scroll_step));
+ max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
else if (scroll_step || temp_scroll_step)
amount_to_scroll = scroll_max;
else
{
aggressive = current_buffer->scroll_down_aggressively;
- height = (WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w)
- - WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
+ height = WINDOW_BOX_TEXT_HEIGHT (w);
if (NUMBERP (aggressive))
amount_to_scroll = XFLOATINT (aggressive) * height;
}
/* If the line start is "too far" away from the window start,
say it takes too much time to compute a new window start. */
if (CHARPOS (start_pos) - IT_CHARPOS (it)
- < XFASTINT (w->height) * XFASTINT (w->width))
+ < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
{
int min_distance, distance;
/* Scroll if point within this distance from the top or bottom
of the window. This is a pixel value. */
this_scroll_margin = max (0, scroll_margin);
- this_scroll_margin = min (this_scroll_margin, XFASTINT (w->height) / 4);
- this_scroll_margin *= CANON_Y_UNIT (f);
+ this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
+ this_scroll_margin *= FRAME_LINE_HEIGHT (f);
/* Start with the row the cursor was displayed during the last
not paused redisplay. Give up if that row is not valid. */
return rc;
}
+void
+set_vertical_scroll_bar (w)
+ struct window *w;
+{
+ int start, end, whole;
+
+ /* Calculate the start and end positions for the current window.
+ At some point, it would be nice to choose between scrollbars
+ which reflect the whole buffer size, with special markers
+ indicating narrowing, and scrollbars which reflect only the
+ visible region.
+
+ Note that mini-buffers sometimes aren't displaying any text. */
+ if (!MINI_WINDOW_P (w)
+ || (w == XWINDOW (minibuf_window)
+ && NILP (echo_area_buffer[0])))
+ {
+ struct buffer *buf = XBUFFER (w->buffer);
+ whole = BUF_ZV (buf) - BUF_BEGV (buf);
+ start = marker_position (w->start) - BUF_BEGV (buf);
+ /* I don't think this is guaranteed to be right. For the
+ moment, we'll pretend it is. */
+ end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
+
+ if (end < start)
+ end = start;
+ if (whole < (end - start))
+ whole = end - start;
+ }
+ else
+ start = end = whole = 0;
+
+ /* Indicate what this scroll bar ought to be displaying now. */
+ set_vertical_scroll_bar_hook (w, end - start, whole, start);
+}
/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
selected_window is redisplayed.
}
else if ((w != XWINDOW (minibuf_window)
|| minibuf_level == 0)
+ /* When buffer is nonempty, redisplay window normally. */
+ && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
/* Quail displays non-mini buffers in minibuffer window.
In that case, redisplay the window normally. */
&& !NILP (Fmemq (w->buffer, Vminibuffer_list)))
;
finish_scroll_bars:
- if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
+ if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
{
- int start, end, whole;
-
- /* Calculate the start and end positions for the current window.
- At some point, it would be nice to choose between scrollbars
- which reflect the whole buffer size, with special markers
- indicating narrowing, and scrollbars which reflect only the
- visible region.
-
- Note that mini-buffers sometimes aren't displaying any text. */
- if (!MINI_WINDOW_P (w)
- || (w == XWINDOW (minibuf_window)
- && NILP (echo_area_buffer[0])))
- {
- whole = ZV - BEGV;
- start = marker_position (w->start) - BEGV;
- /* I don't think this is guaranteed to be right. For the
- moment, we'll pretend it is. */
- end = (Z - XFASTINT (w->window_end_pos)) - BEGV;
-
- if (end < start)
- end = start;
- if (whole < (end - start))
- whole = end - start;
- }
- else
- start = end = whole = 0;
-
- /* Indicate what this scroll bar ought to be displaying now. */
- set_vertical_scroll_bar_hook (w, end - start, whole, start);
+ /* Set the thumb's position and size. */
+ set_vertical_scroll_bar (w);
/* Note that we actually used the scroll bar attached to this
window, so it shouldn't be deleted at the end of redisplay. */
}
else
{
- w->window_end_bytepos = 0;
- w->window_end_pos = w->window_end_vpos = make_number (0);
+ w->window_end_bytepos = Z_BYTE - ZV_BYTE;
+ w->window_end_pos = make_number (Z - ZV);
+ w->window_end_vpos = make_number (0);
}
/* But that is not valid info until redisplay finishes. */
(start_row + i)->enabled_p = 0;
/* Re-compute Y positions. */
- min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
+ min_y = WINDOW_HEADER_LINE_HEIGHT (w);
max_y = it.last_visible_y;
for (row = start_row + nrows_scrolled;
row < bottom_row;
else
{
/* This window must be completely empty. */
- w->window_end_bytepos = 0;
- w->window_end_pos = w->window_end_vpos = make_number (0);
+ w->window_end_bytepos = Z_BYTE - ZV_BYTE;
+ w->window_end_pos = make_number (Z - ZV);
+ w->window_end_vpos = make_number (0);
}
w->window_end_valid = Qnil;
it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
- nrows_scrolled);
it.current_y = (first_row_to_display->y - first_reusable_row->y
- + WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w));
+ + WINDOW_HEADER_LINE_HEIGHT (w));
/* Display lines beginning with first_row_to_display in the
desired matrix. Set last_text_row to the last row displayed
/* Scroll the display. */
run.current_y = first_reusable_row->y;
- run.desired_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
+ run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
run.height = it.last_visible_y - run.current_y;
dy = run.current_y - run.desired_y;
/* Adjust Y positions of reused rows. */
bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
- min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
+ min_y = WINDOW_HEADER_LINE_HEIGHT (w);
max_y = it.last_visible_y;
for (row = first_reusable_row; row < first_row_to_display; ++row)
{
marginal areas (see build_frame_matrix). */
window_row = w->current_matrix->rows;
window_row_end = window_row + w->current_matrix->nrows;
- frame_row = f->current_matrix->rows + XFASTINT (w->top);
+ frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
while (window_row < window_row_end)
{
struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
the window end again, since its offset from Z hasn't changed. */
r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
- && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes)
+ && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
+ /* PT must not be in a partially visible line. */
+ && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
+ && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
{
/* Adjust positions in the glyph matrix. */
if (delta || delta_bytes)
as is, without changing glyph positions since no text has
been added/removed in front of the window end. */
r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
- if (TEXT_POS_EQUAL_P (start, r0->start.pos))
+ if (TEXT_POS_EQUAL_P (start, r0->start.pos)
+ /* PT must not be in a partially visible line. */
+ && !(PT >= MATRIX_ROW_START_CHARPOS (row)
+ && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
{
/* We have to compute the window end anew since text
can have been added/removed after it. */
int this_scroll_margin, cursor_height;
this_scroll_margin = max (0, scroll_margin);
- this_scroll_margin = min (this_scroll_margin,
- XFASTINT (w->height) / 4);
- this_scroll_margin *= CANON_Y_UNIT (it.f);
+ this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
+ this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
if ((w->cursor.y < this_scroll_margin
lines to scroll by; dvpos < 0 means scroll up. */
int first_unchanged_at_end_vpos
= MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
- int from = XFASTINT (w->top) + first_unchanged_at_end_vpos;
- int end = (XFASTINT (w->top)
+ int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
+ int end = (WINDOW_TOP_EDGE_LINE (w)
+ (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
+ window_internal_height (w));
if (row->height == 0)
{
if (it->max_ascent + it->max_descent == 0)
- it->max_descent = it->max_phys_descent = CANON_Y_UNIT (it->f);
+ it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
row->ascent = it->max_ascent;
row->height = it->max_ascent + it->max_descent;
row->phys_ascent = it->max_phys_ascent;
/* Compute how much of the line is visible. */
row->visible_height = row->height;
- min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (it->w);
- max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (it->w);
+ min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
+ max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
if (row->y < min_y)
row->visible_height -= min_y - row->y;
else if (it->face_before_selective_p)
it->face_id = it->saved_face_id;
face = FACE_FROM_ID (it->f, it->face_id);
- it->face_id = FACE_FOR_CHAR (it->f, face, 0);
+ it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
PRODUCE_GLYPHS (it);
ASCII face. This will be automatically undone the next time
get_next_display_element returns a multibyte character. Note
that the character will always be single byte in unibyte text. */
- if (!SINGLE_BYTE_CHAR_P (it->c))
+ if (!ASCII_CHAR_P (it->c))
{
- it->face_id = FACE_FOR_CHAR (f, face, 0);
+ it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
}
if (FRAME_WINDOW_P (f))
&& glyph->u.ch == ' '))
&& trailing_whitespace_p (glyph->charpos))
{
- int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
+ int face_id = lookup_named_face (f, Qtrailing_whitespace);
while (glyph >= start
&& BUFFERP (glyph->object)
xassert (!FRAME_WINDOW_P (f));
init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
it.first_visible_x = 0;
- it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
+ it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
#else /* not USE_X_TOOLKIT */
if (FRAME_WINDOW_P (f))
{
init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
MENU_FACE_ID);
it.first_visible_x = 0;
- it.last_visible_x = FRAME_WINDOW_WIDTH (f) * CANON_X_UNIT (f);
+ it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
}
else
{
init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
MENU_FACE_ID);
it.first_visible_x = 0;
- it.last_visible_x = FRAME_WIDTH (f);
+ it.last_visible_x = FRAME_COLS (f);
}
#endif /* not USE_X_TOOLKIT */
int literal = 0;
tail_recurse:
- if (depth > 10)
- goto invalid;
+ if (depth > 100)
+ elt = build_string ("*too-deep*");
depth++;
default:
invalid:
- if (frame_title_ptr)
- n += store_frame_title ("*invalid*", 0, precision - n);
- else if (!NILP (mode_line_string_list))
- n += store_mode_line_string ("*invalid*", Qnil, 0, 0, precision - n, Qnil);
- else
- n += display_string ("*invalid*", Qnil, Qnil, 0, 0, it, 0,
- precision - n, 0, 0);
- return n;
+ elt = build_string ("*invalid*");
+ goto tail_recurse;
}
/* Pad to FIELD_WIDTH. */
/* The EOL conversion we are using. */
Lisp_Object eoltype;
- val = Fget (coding_system, Qcoding_system);
+ val = CODING_SYSTEM_SPEC (coding_system);
eoltype = Qnil;
if (!VECTORP (val)) /* Not yet decided. */
}
else
{
+ Lisp_Object attrs;
Lisp_Object eolvalue;
- eolvalue = Fget (coding_system, Qeol_type);
+ attrs = AREF (val, 0);
+ eolvalue = AREF (val, 2);
if (multibyte)
- *buf++ = XFASTINT (AREF (val, 1));
+ *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
if (eol_flag)
{
eoltype = eol_mnemonic_undecided;
else if (VECTORP (eolvalue)) /* Not yet decided. */
eoltype = eol_mnemonic_undecided;
- else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
- eoltype = (XFASTINT (eolvalue) == 0
+ else /* eolvalue is Qunix, Qdos, or Qmac. */
+ eoltype = (EQ (eolvalue, Qunix)
? eol_mnemonic_unix
- : (XFASTINT (eolvalue) == 1
+ : (EQ (eolvalue, Qdos) == 1
? eol_mnemonic_dos : eol_mnemonic_mac));
}
}
eol_str = SDATA (eoltype);
eol_str_len = SBYTES (eoltype);
}
- else if (INTEGERP (eoltype)
- && CHAR_VALID_P (XINT (eoltype), 0))
+ else if (CHARACTERP (eoltype))
{
unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
int startpos_byte = marker_byte_position (w->start);
int line, linepos, linepos_byte, topline;
int nlines, junk;
- int height = XFASTINT (w->height);
+ int height = WINDOW_TOTAL_LINES (w);
/* If we decided that this buffer isn't suitable for line numbers,
don't forget that too fast. */
{
/* No need to mention EOL here--the terminal never needs
to do EOL conversion. */
- p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
- p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
+ p = decode_mode_spec_coding (CODING_ID_NAME (keyboard_coding.id),
+ p, 0);
+ p = decode_mode_spec_coding (CODING_ID_NAME (terminal_coding.id),
+ p, 0);
}
p = decode_mode_spec_coding (b->buffer_file_coding_system,
p, eol_flag);
}
break;
}
- else if (x + glyph->pixel_width > it->first_visible_x)
+ else if (x + glyph->pixel_width >= it->first_visible_x)
{
/* Glyph is at least partially visible. */
++it->hpos;
}
else
{
- int c1, c2, charset;
+ struct font_info *font_info
+ = FONT_INFO_FROM_ID (f, face->font_info_id);
+ if (font_info)
+ {
+ struct charset *charset = CHARSET_FROM_ID (font_info->charset);
+ unsigned code = ENCODE_CHAR (charset, glyph->u.ch);
- /* Split characters into bytes. If c2 is -1 afterwards, C is
- really a one-byte character so that byte1 is zero. */
- SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
- if (c2 > 0)
- STORE_XCHAR2B (char2b, c1, c2);
- else
- STORE_XCHAR2B (char2b, 0, c1);
+ if (CHARSET_DIMENSION (charset) == 1)
+ STORE_XCHAR2B (char2b, 0, code);
+ else
+ STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
- /* Maybe encode the character in *CHAR2B. */
- if (charset != CHARSET_ASCII)
- {
- struct font_info *font_info
- = FONT_INFO_FROM_ID (f, face->font_info_id);
- if (font_info)
- glyph->font_type
- = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
+ /* Maybe encode the character in *CHAR2B. */
+ if (CHARSET_ID (charset) != charset_ascii)
+ {
+ glyph->font_type
+ = rif->encode_char (glyph->u.ch, char2b, font_info, charset,
+ two_byte_p);
+ }
}
}
*left = -pcm->lbearing;
}
}
+ else if (glyph->type == COMPOSITE_GLYPH)
+ {
+ struct composition *cmp = composition_table[glyph->u.cmp_id];
+
+ *right = cmp->rbearing - cmp->pixel_width;
+ *left = - cmp->lbearing;
+ }
}
/* Unibyte case. We don't have to encode, but we have to make
sure to use a face suitable for unibyte. */
STORE_XCHAR2B (char2b, 0, c);
- face_id = FACE_FOR_CHAR (f, face, c);
+ face_id = FACE_FOR_CHAR (f, face, c, -1, Qnil);
face = FACE_FROM_ID (f, face_id);
}
else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
/* Case of ASCII in a face known to fit ASCII. */
STORE_XCHAR2B (char2b, 0, c);
}
- else
+ else if (face->font != NULL)
{
- int c1, c2, charset;
+ struct font_info *font_info
+ = FONT_INFO_FROM_ID (f, face->font_info_id);
+ struct charset *charset = CHARSET_FROM_ID (font_info->charset);
+ unsigned code = ENCODE_CHAR (charset, c);
- /* Split characters into bytes. If c2 is -1 afterwards, C is
- really a one-byte character so that byte1 is zero. */
- SPLIT_CHAR (c, charset, c1, c2);
- if (c2 > 0)
- STORE_XCHAR2B (char2b, c1, c2);
+ if (CHARSET_DIMENSION (charset) == 1)
+ STORE_XCHAR2B (char2b, 0, code);
else
- STORE_XCHAR2B (char2b, 0, c1);
-
- /* Maybe encode the character in *CHAR2B. */
- if (face->font != NULL)
- {
- struct font_info *font_info
- = FONT_INFO_FROM_ID (f, face->font_info_id);
- if (font_info)
- rif->encode_char (c, char2b, font_info, 0);
- }
+ STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+ /* Maybe encode the character in *CHAR2B. */
+ rif->encode_char (c, char2b, font_info, charset, NULL);
}
/* Make sure X resources of the face are allocated. */
#define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
do \
{ \
- int c, face_id; \
+ int face_id; \
XChar2b *char2b; \
\
- c = (row)->glyphs[area][START].u.ch; \
face_id = (row)->glyphs[area][START].face_id; \
\
s = (struct glyph_string *) alloca (sizeof *s); \
for (n = 0; n < glyph_len; n++) \
{ \
int c = COMPOSITION_GLYPH (cmp, n); \
- int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
+ int this_face_id = FACE_FOR_CHAR (f, base_face, c, -1, Qnil); \
faces[n] = FACE_FROM_ID (f, this_face_id); \
get_char_face_and_encoding (f, c, this_face_id, \
char2b + n, 1, 1); \
int x;
struct glyph_row *row;
enum glyph_row_area area;
- int start, end;
+ EMACS_INT start, end;
enum draw_glyphs_face hl;
int overlaps_p;
{
{
/* X is relative to the left edge of W, without scroll bars
or fringes. */
- int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f);
-
- x += window_left_x;
- area_width = XFASTINT (w->width) * CANON_X_UNIT (f);
- last_x = window_left_x + area_width;
-
- if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
- {
- int width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
- if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
- last_x += width;
- else
- x -= width;
- }
-
- x += FRAME_INTERNAL_BORDER_WIDTH (f);
- /* ++KFS: W32 and MAC versions had -= in next line (bug??) */
- last_x += FRAME_INTERNAL_BORDER_WIDTH (f);
+ x += WINDOW_LEFT_EDGE_X (w);
+ last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
}
else
{
- x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, x);
+ int area_left = window_box_left (w, area);
+ x += area_left;
area_width = window_box_width (w, area);
- last_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, area_width);
+ last_x = area_left + area_width;
}
/* Build a doubly-linked list of glyph_string structures between
int x0 = head ? head->x : x;
int x1 = tail ? tail->x + tail->background_width : x;
- x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0);
- x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1);
-
- /* ++KFS: W32 and MAC versions had following test here:
- if (!row->full_width_p && XFASTINT (w->left_margin_width) != 0)
- */
+ int text_left = window_box_left (w, TEXT_AREA);
+ x0 -= text_left;
+ x1 -= text_left;
- if (XFASTINT (w->left_margin_width) != 0)
- {
- int left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
- x0 -= left_area_width;
- x1 -= left_area_width;
- }
-
- notice_overwritten_cursor (w, area, x0, x1,
+ notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
row->y, MATRIX_ROW_BOTTOM_Y (row));
}
/* Value is the x-position up to which drawn, relative to AREA of W.
This doesn't include parts drawn because of overhangs. */
- x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
- if (!row->full_width_p)
- {
- /* ++KFS: W32 and MAC versions only had this test here:
- if (area > LEFT_MARGIN_AREA)
- */
-
- if (area > LEFT_MARGIN_AREA && XFASTINT (w->left_margin_width) != 0)
- x_reached -= window_box_width (w, LEFT_MARGIN_AREA);
- if (area > TEXT_AREA)
- x_reached -= window_box_width (w, TEXT_AREA);
- }
+ if (row->full_width_p)
+ x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
+ else
+ x_reached -= window_box_left (w, area);
RELEASE_HDC (hdc, f);
if (prop = Fplist_get (plist, QCwidth),
NUMVAL (prop) > 0)
/* Absolute width `:width WIDTH' specified and valid. */
- width = NUMVAL (prop) * CANON_X_UNIT (it->f);
+ width = NUMVAL (prop) * FRAME_COLUMN_WIDTH (it->f);
else if (prop = Fplist_get (plist, QCrelative_width),
NUMVAL (prop) > 0)
{
}
else if (prop = Fplist_get (plist, QCalign_to),
NUMVAL (prop) > 0)
- width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x;
+ width = NUMVAL (prop) * FRAME_COLUMN_WIDTH (it->f) - it->current_x;
else
/* Nothing specified -> width defaults to canonical char width. */
- width = CANON_X_UNIT (it->f);
+ width = FRAME_COLUMN_WIDTH (it->f);
/* Compute height. */
if (prop = Fplist_get (plist, QCheight),
NUMVAL (prop) > 0)
- height = NUMVAL (prop) * CANON_Y_UNIT (it->f);
+ height = NUMVAL (prop) * FRAME_LINE_HEIGHT (it->f);
else if (prop = Fplist_get (plist, QCrelative_height),
NUMVAL (prop) > 0)
height = FONT_HEIGHT (font) * NUMVAL (prop);
/* Maybe translate single-byte characters to multibyte, or the
other way. */
it->char_to_display = it->c;
- if (!ASCII_BYTE_P (it->c))
+ if (!ASCII_BYTE_P (it->c)
+ && ! it->multibyte_p)
{
- if (unibyte_display_via_language_environment
- && SINGLE_BYTE_CHAR_P (it->c)
- && (it->c >= 0240
- || !NILP (Vnonascii_translation_table)))
+ if (SINGLE_BYTE_CHAR_P (it->c)
+ && unibyte_display_via_language_environment)
+ it->char_to_display = unibyte_char_to_multibyte (it->c);
+ if (! SINGLE_BYTE_CHAR_P (it->c))
{
- it->char_to_display = unibyte_char_to_multibyte (it->c);
it->multibyte_p = 1;
- it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
- face = FACE_FROM_ID (it->f, it->face_id);
- }
- else if (!SINGLE_BYTE_CHAR_P (it->c)
- && !it->multibyte_p)
- {
- it->multibyte_p = 1;
- it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
+ it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
+ -1, Qnil);
face = FACE_FROM_ID (it->f, it->face_id);
}
}
}
else if (it->char_to_display == '\t')
{
- int tab_width = it->tab_width * CANON_X_UNIT (it->f);
+ int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
int x = it->current_x + it->continuation_lines_width;
int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
/* If the distance from the current position to the next tab
stop is less than a canonical character width, use the
tab stop after that. */
- if (next_tab_x - x < CANON_X_UNIT (it->f))
+ if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
next_tab_x += tab_width;
it->pixel_width = next_tab_x - x;
/* If we found a font, this font should give us the right
metrics. If we didn't find a font, use the frame's
- default font and calculate the width of the character
- from the charset width; this is what old redisplay code
- did. */
+ default font and calculate the width of the character by
+ multiplying the width of font by the width of the
+ character. */
pcm = rif->per_char_metric (font, &char2b,
FONT_TYPE_FOR_MULTIBYTE (font, it->c));
if (font_not_found_p || !pcm)
{
- int charset = CHAR_CHARSET (it->char_to_display);
-
it->glyph_not_available_p = 1;
- it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f))
- * CHARSET_WIDTH (charset));
+ it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
+ * CHAR_WIDTH (it->char_to_display));
it->phys_ascent = FONT_BASE (font) + boff;
it->phys_descent = FONT_DESCENT (font) - boff;
}
struct font_info *font_info;
int boff; /* baseline offset */
struct composition *cmp = composition_table[it->cmp_id];
+ int pos;
/* Maybe translate single-byte characters to multibyte. */
it->char_to_display = it->c;
if (unibyte_display_via_language_environment
- && SINGLE_BYTE_CHAR_P (it->c)
- && (it->c >= 0240
- || (it->c >= 0200
- && !NILP (Vnonascii_translation_table))))
+ && it->c >= 0200)
{
it->char_to_display = unibyte_char_to_multibyte (it->c);
}
/* Get face and font to use. Encode IT->char_to_display. */
- it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
+ pos = STRINGP (it->string) ? IT_STRING_CHARPOS (*it) : IT_CHARPOS (*it);
+ it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
+ pos, it->string);
face = FACE_FROM_ID (it->f, it->face_id);
get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
&char2b, it->multibyte_p, 0);
now. Theoretically, we have to check all fonts for the
glyphs, but that requires much time and memory space. So,
here we check only the font of the first glyph. This leads
- to incorrect display very rarely, and C-l (recenter) can
- correct the display anyway. */
+ to incorrect display, but it's very rare, and C-l (recenter)
+ can correct the display anyway. */
if (cmp->font != (void *) font)
{
/* Ascent and descent of the font of the first character of
them respectively. */
int font_ascent = FONT_BASE (font) + boff;
int font_descent = FONT_DESCENT (font) - boff;
+ int font_height = FONT_HEIGHT (font);
/* Bounding box of the overall glyphs. */
int leftmost, rightmost, lowest, highest;
+ int lbearing, rbearing;
int i, width, ascent, descent;
cmp->font = (void *) font;
width = pcm->width;
ascent = pcm->ascent;
descent = pcm->descent;
+ lbearing = pcm->lbearing;
+ if (lbearing > 0)
+ lbearing = 0;
+ rbearing = pcm->rbearing;
+ if (rbearing < width)
+ rbearing = width;
}
else
{
width = FONT_WIDTH (font);
ascent = FONT_BASE (font);
descent = FONT_DESCENT (font);
+ lbearing = 0;
+ rbearing = width;
}
rightmost = width;
the left. */
cmp->offsets[0] = 0;
cmp->offsets[1] = boff;
+ cmp->lbearing = lbearing;
+ cmp->rbearing = rbearing;
/* Set cmp->offsets for the remaining glyphs. */
for (i = 1; i < cmp->glyph_len; i++)
{
int left, right, btm, top;
int ch = COMPOSITION_GLYPH (cmp, i);
- int face_id = FACE_FOR_CHAR (it->f, face, ch);
+ int face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
face = FACE_FROM_ID (it->f, face_id);
get_char_face_and_encoding (it->f, ch, face->id,
width = pcm->width;
ascent = pcm->ascent;
descent = pcm->descent;
+ lbearing = pcm->lbearing;
+ if (lbearing > 0)
+ lbearing = 0;
+ rbearing = pcm->rbearing;
+ if (rbearing < width)
+ rbearing = width;
}
else
{
width = FONT_WIDTH (font);
ascent = 1;
descent = 0;
+ lbearing = 0;
+ rbearing = width;
}
if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
6---7---8 -- descent
*/
int rule = COMPOSITION_RULE (cmp, i);
- int gref, nref, grefx, grefy, nrefx, nrefy;
+ int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
- COMPOSITION_DECODE_RULE (rule, gref, nref);
+ COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
grefx = gref % 3, nrefx = nref % 3;
grefy = gref / 3, nrefy = nref / 3;
+ if (xoff)
+ xoff = font_height * (xoff - 128) / 256;
+ if (yoff)
+ yoff = font_height * (yoff - 128) / 256;
left = (leftmost
+ grefx * (rightmost - leftmost) / 2
- - nrefx * width / 2);
+ - nrefx * width / 2
+ + xoff);
+
btm = ((grefy == 0 ? highest
: grefy == 1 ? 0
: grefy == 2 ? lowest
- (nrefy == 0 ? ascent + descent
: nrefy == 1 ? descent - boff
: nrefy == 2 ? 0
- : (ascent + descent) / 2));
+ : (ascent + descent) / 2)
+ + yoff);
}
cmp->offsets[i * 2] = left;
cmp->offsets[i * 2 + 1] = btm + descent;
/* Update the bounding box of the overall glyphs. */
- right = left + width;
+ if (width > 0)
+ {
+ right = left + width;
+ if (left < leftmost)
+ leftmost = left;
+ if (right > rightmost)
+ rightmost = right;
+ }
top = btm + descent + ascent;
- if (left < leftmost)
- leftmost = left;
- if (right > rightmost)
- rightmost = right;
if (top > highest)
highest = top;
if (btm < lowest)
lowest = btm;
+
+ if (cmp->lbearing > left + lbearing)
+ cmp->lbearing = left + lbearing;
+ if (cmp->rbearing < left + rbearing)
+ cmp->rbearing = left + rbearing;
}
/* If there are glyphs whose x-offsets are negative,
for (i = 0; i < cmp->glyph_len; i++)
cmp->offsets[i * 2] -= leftmost;
rightmost -= leftmost;
+ cmp->lbearing -= leftmost;
+ cmp->rbearing -= leftmost;
}
cmp->pixel_width = rightmost;
cmp->descent = font_descent;
}
+ if (it->glyph_row
+ && (cmp->lbearing < 0
+ || cmp->rbearing > cmp->pixel_width))
+ it->glyph_row->contains_overlapping_glyphs_p = 1;
+
it->pixel_width = cmp->pixel_width;
it->ascent = it->phys_ascent = cmp->ascent;
it->descent = it->phys_descent = cmp->descent;
hpos, hpos + len,
DRAW_NORMAL_TEXT, 0);
-#ifndef HAVE_CARBON
- /* ++KFS: Why not on MAC ? */
-
/* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
if (updated_area == TEXT_AREA
&& updated_window->phys_cursor_on_p
&& updated_window->phys_cursor.hpos >= hpos
&& updated_window->phys_cursor.hpos < hpos + len)
updated_window->phys_cursor_on_p = 0;
-#endif
UNBLOCK_INPUT;
int line_height, shift_by_width, shifted_region_width;
struct glyph_row *row;
struct glyph *glyph;
- int frame_x, frame_y, hpos;
+ int frame_x, frame_y;
+ EMACS_INT hpos;
xassert (updated_window && updated_row);
BLOCK_INPUT;
frame_x = window_box_left (w, updated_area) + output_cursor.x;
frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
- rif->shift_glyphs_for_insert (f, frame_x, frame_y, line_height,
- shifted_region_width, shift_by_width);
+ rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
+ line_height, shift_by_width);
/* Write the glyphs. */
hpos = start - row->glyphs[updated_area];
f = XFRAME (w->frame);
if (updated_row->full_width_p)
- {
- max_x = XFASTINT (w->width) * CANON_X_UNIT (f);
- if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
- && !w->pseudo_window_p)
- max_x += FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
- }
+ max_x = WINDOW_TOTAL_WIDTH (w);
else
max_x = window_box_width (w, updated_area);
max_y = window_text_bottom_y (w);
}
else
{
- from_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, from_x);
- to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x);
+ int area_left = window_box_left (w, updated_area);
+ from_x += area_left;
+ to_x += area_left;
}
- min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
+ min_y = WINDOW_HEADER_LINE_HEIGHT (w);
from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
enum glyph_row_area area;
int x0, y0, x1, y1;
{
-#ifdef HAVE_CARBON
- /* ++KFS: Why is there a special version of this for the mac ? */
- if (area == TEXT_AREA
- && w->phys_cursor_on_p
- && y0 <= w->phys_cursor.y
- && y1 >= w->phys_cursor.y + w->phys_cursor_height
- && x0 <= w->phys_cursor.x
- && (x1 < 0 || x1 > w->phys_cursor.x))
- w->phys_cursor_on_p = 0;
-#else
if (area == TEXT_AREA && w->phys_cursor_on_p)
{
int cx0 = w->phys_cursor.x;
w->phys_cursor_on_p = 0;
}
}
-#endif
}
#endif /* HAVE_WINDOW_SYSTEM */
BLOCK_INPUT;
- if (area == LEFT_MARGIN_AREA)
- x = 0;
- else if (area == TEXT_AREA)
- x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
- else
- x = (window_box_width (w, LEFT_MARGIN_AREA)
- + window_box_width (w, TEXT_AREA));
-
+ x = 0;
for (i = 0; i < row->used[area];)
{
if (row->glyphs[area][i].overlaps_vertically_p)
hl, 0);
w->phys_cursor_on_p = on_p;
-#ifndef HAVE_CARBON
- /* ++KFS: MAC version did not adjust phys_cursor_width (bug?) */
if (hl == DRAW_CURSOR)
w->phys_cursor_width = x1 - w->phys_cursor.x;
- else
-#endif
/* When we erase the cursor, and ROW is overlapped by other
rows, make sure that these overlapping parts of other rows
are redrawn. */
- if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
+ else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
{
if (row > w->current_matrix->rows
&& MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
{
int x, y;
- int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
+ int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
cursor_glyph = get_phys_cursor_glyph (w);
if (cursor_glyph == NULL)
int active_cursor;
struct glyph_matrix *current_glyphs;
struct glyph_row *glyph_row;
- struct glyph *glyph;
/* This is pointless on invisible frames, and dangerous on garbaged
windows and frames; in the latter case, the frame or window may
current_glyphs = w->current_matrix;
glyph_row = MATRIX_ROW (current_glyphs, vpos);
- glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
/* If cursor row is not enabled, we don't really know where to
display the cursor. */
w->phys_cursor.vpos = vpos;
}
- rif->draw_window_cursor (w, glyph_row, on, x, y,
- new_cursor_type, new_cursor_width);
+ rif->draw_window_cursor (w, glyph_row, x, y,
+ new_cursor_type, new_cursor_width,
+ on, active_cursor);
}
of last line in W. In the row containing CHARPOS, stop before glyphs
having STOP as object. */
-#if 0 /* This is a version of fast_find_position that's more correct
+#if 1 /* This is a version of fast_find_position that's more correct
in the presence of hscrolling, for example. I didn't install
it right away because the problem fixed is minor, it failed
in 20.x as well, and I think it's too risky to install
static int
fast_find_position (w, charpos, hpos, vpos, x, y, stop)
struct window *w;
- int charpos;
+ EMACS_INT charpos;
int *hpos, *vpos, *x, *y;
Lisp_Object stop;
{
struct glyph_row *row, *first;
struct glyph *glyph, *end;
- int i, past_end = 0;
+ int past_end = 0;
first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
row = row_containing_pos (w, charpos, first, NULL, 0);
return past_end;
}
-#else /* not 0 */
+#else /* not 1 */
static int
fast_find_position (w, pos, hpos, vpos, x, y, stop)
struct window *w;
- int pos;
+ EMACS_INT pos;
int *hpos, *vpos, *x, *y;
Lisp_Object stop;
{
return 0;
}
-#endif /* not 0 */
+#endif /* not 1 */
/* Find the position of the glyph for position POS in OBJECT in
static int
fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
struct window *w;
- int pos;
+ EMACS_INT pos;
Lisp_Object object;
int *hpos, *vpos, *x, *y;
int right_p;
}
-#ifdef HAVE_CARBON
-
-/* ++KFS: Why does MAC have its own version here? Looks like OLD CODE!! */
-
-/* Take proper action when mouse has moved to the mode or header line of
- window W, x-position X. MODE_LINE_P non-zero means mouse is on the
- mode line. X is relative to the start of the text display area of
- W, so the width of fringes and scroll bars must be subtracted
- to get a position relative to the start of the mode line. */
-
-static void
-note_mode_line_highlight (w, x, mode_line_p)
- struct window *w;
- int x, mode_line_p;
-{
- struct frame *f = XFRAME (w->frame);
- struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
- Cursor *cursor = dpyinfo->vertical_scroll_bar_cursor;
- struct glyph_row *row;
-
- if (mode_line_p)
- row = MATRIX_MODE_LINE_ROW (w->current_matrix);
- else
- row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
-
- if (row->enabled_p)
- {
- struct glyph *glyph, *end;
- Lisp_Object help, map;
- int x0;
-
- /* Find the glyph under X. */
- glyph = row->glyphs[TEXT_AREA];
- end = glyph + row->used[TEXT_AREA];
- x0 = - (FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f)
- + FRAME_X_LEFT_FRINGE_WIDTH (f));
-
- while (glyph < end
- && x >= x0 + glyph->pixel_width)
- {
- x0 += glyph->pixel_width;
- ++glyph;
- }
-
- if (glyph < end
- && STRINGP (glyph->object)
- && STRING_INTERVALS (glyph->object)
- && glyph->charpos >= 0
- && glyph->charpos < SCHARS (glyph->object))
- {
- /* If we're on a string with `help-echo' text property,
- arrange for the help to be displayed. This is done by
- setting the global variable help_echo_string to the help
- string. */
- help = Fget_text_property (make_number (glyph->charpos),
- Qhelp_echo, glyph->object);
- if (!NILP (help))
- {
- help_echo_string = help;
- XSETWINDOW (help_echo_window, w);
- help_echo_object = glyph->object;
- help_echo_pos = glyph->charpos;
- }
-
- /* Change the mouse pointer according to what is under X/Y. */
- map = Fget_text_property (make_number (glyph->charpos),
- Qlocal_map, glyph->object);
- if (KEYMAPP (map))
- cursor = f->output_data.mac->nontext_cursor;
- else
- {
- map = Fget_text_property (make_number (glyph->charpos),
- Qkeymap, glyph->object);
- if (KEYMAPP (map))
- cursor = f->output_data.mac->nontext_cursor;
- }
- }
- }
-
- rif->define_frame_cursor (f, cursor);
-}
-
-#else
-
/* Take proper action when mouse has moved to the mode or header line
or marginal area AREA of window W, x-position X and y-position Y.
X is relative to the start of the text display area of W, so the
rif->define_frame_cursor (f, cursor);
}
-#endif /* !HAVE_CARBON */
-
/* EXPORT:
Take proper action when the mouse has moved to position X, Y on
}
/* Which window is that in? */
- window = window_from_coordinates (f, x, y, &part, 1);
+ window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
/* If we were displaying active text in another window, clear that. */
if (! EQ (window, dpyinfo->mouse_face_window))
return;
}
-#ifdef HAVE_CARBON
- /* ++KFS: Why does MAC have its own version here? Looks like OLD CODE!! */
-
- /* Mouse is on the mode or header line? */
- if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
- {
- note_mode_line_highlight (w, x, part == ON_MODE_LINE);
- return;
- }
-#else
/* Mouse is on the mode, header line or margin? */
if (part == ON_MODE_LINE || part == ON_HEADER_LINE
|| part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
note_mode_line_or_margin_highlight (w, x, y, part);
return;
}
-#endif
if (part == ON_VERTICAL_BORDER)
cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
set_cursor:
+#ifndef HAVE_CARBON
if (cursor != No_Cursor)
+#else
+ if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
+#endif
rif->define_frame_cursor (f, cursor);
}
/* Set START_X to the window-relative start position for drawing glyphs of
AREA. The first glyph of the text area can be partially visible.
The first glyphs of other areas cannot. */
- if (area == LEFT_MARGIN_AREA)
- start_x = 0;
- else if (area == TEXT_AREA)
- start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
- else
- start_x = (window_box_width (w, LEFT_MARGIN_AREA)
- + window_box_width (w, TEXT_AREA));
+ start_x = window_box_left_offset (w, area);
+ if (area == TEXT_AREA)
+ start_x += row->x;
x = start_x;
/* Find the first glyph that must be redrawn. */
cursor_glyph = get_phys_cursor_glyph (w);
if (cursor_glyph)
{
- cr.x = w->phys_cursor.x;
+ /* r is relative to W's box, but w->phys_cursor.x is relative
+ to left edge of W's TEXT area. Adjust it. */
+ cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
cr.y = w->phys_cursor.y;
cr.width = cursor_glyph->pixel_width;
cr.height = w->phys_cursor_height;
x_draw_vertical_border (w)
struct window *w;
{
- struct frame *f = XFRAME (WINDOW_FRAME (w));
+ /* We could do better, if we knew what type of scroll-bar the adjacent
+ windows (on either side) have... But we don't :-(
+ However, I think this works ok. ++KFS 2003-04-25 */
/* Redraw borders between horizontally adjacent windows. Don't
do it for frames with vertical scroll bars because either the
right scroll bar of a window, or the left scroll bar of its
neighbor will suffice as a border. */
if (!WINDOW_RIGHTMOST_P (w)
- && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
+ && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
{
int x0, x1, y0, y1;
window_box_edges (w, -1, &x0, &y0, &x1, &y1);
- x1 += FRAME_X_RIGHT_FRINGE_WIDTH (f);
y1 -= 1;
rif->draw_vertical_window_border (w, x1, y0, y1);
}
+ else if (!WINDOW_LEFTMOST_P (w)
+ && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+ {
+ int x0, x1, y0, y1;
+
+ window_box_edges (w, -1, &x0, &y0, &x1, &y1);
+ y1 -= 1;
+
+ rif->draw_vertical_window_border (w, x0, y0, y1);
+ }
}
}
/* Frame-relative pixel rectangle of W. */
- wr.x = XFASTINT (w->left) * CANON_X_UNIT (f);
- wr.y = XFASTINT (w->top) * CANON_Y_UNIT (f);
- wr.width = XFASTINT (w->width) * CANON_X_UNIT (f);
- wr.height = XFASTINT (w->height) * CANON_Y_UNIT (f);
+ wr.x = WINDOW_LEFT_EDGE_X (w);
+ wr.y = WINDOW_TOP_EDGE_Y (w);
+ wr.width = WINDOW_TOTAL_WIDTH (w);
+ wr.height = WINDOW_TOTAL_HEIGHT (w);
if (x_intersect_rectangles (fr, &wr, &r))
{
r.x, r.y, r.width, r.height));
/* Convert to window coordinates. */
- r.x = FRAME_TO_WINDOW_PIXEL_X (w, r.x);
- r.y = FRAME_TO_WINDOW_PIXEL_Y (w, r.y);
+ r.x -= WINDOW_LEFT_EDGE_X (w);
+ r.y -= WINDOW_TOP_EDGE_Y (w);
/* Turn off the cursor. */
if (!w->pseudo_window_p
if (w == 0 || h == 0)
{
r.x = r.y = 0;
- r.width = CANON_X_UNIT (f) * f->width;
- r.height = CANON_Y_UNIT (f) * f->height;
+ r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
+ r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
}
else
{
struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
int i;
- XWINDOW (root_window)->top = make_number (FRAME_TOP_MARGIN (f));
+ XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
set_window_height (root_window,
- FRAME_HEIGHT (f) - 1 - FRAME_TOP_MARGIN (f),
+ FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
0);
- mini_w->top = make_number (FRAME_HEIGHT (f) - 1);
+ mini_w->top_line = make_number (FRAME_LINES (f) - 1);
set_window_height (minibuf_window, 1, 0);
- XWINDOW (root_window)->width = make_number (FRAME_WIDTH (f));
- mini_w->width = make_number (FRAME_WIDTH (f));
+ XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
+ mini_w->total_cols = make_number (FRAME_COLS (f));
scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
scratch_glyph_row.glyphs[TEXT_AREA + 1]