/* Fringe handling (split from xdisp.c).
- Copyright (C) 1985-1988, 1993-1995, 1997-2011 Free Software Foundation, Inc.
+ Copyright (C) 1985-1988, 1993-1995, 1997-2015 Free Software
+ Foundation, Inc.
This file is part of GNU Emacs.
#include <config.h>
#include <stdio.h>
-#include <setjmp.h>
+
+#include <byteswap.h>
#include "lisp.h"
#include "frame.h"
#include "window.h"
#include "dispextern.h"
+#include "character.h"
#include "buffer.h"
#include "blockinput.h"
#include "termhooks.h"
-#ifdef HAVE_WINDOW_SYSTEM
-
/* Fringe bitmaps are represented in three different ways:
Logical bitmaps are used internally to denote things like
'end-of-buffer', 'left-truncation', 'overlay-arrow', etc.
- Physical bitmaps specify the visual appearence of the bitmap,
+ Physical bitmaps specify the visual appearance of the bitmap,
e.g. 'bottom-left-angle', 'left-arrow', 'left-triangle', etc.
User defined bitmaps are physical bitmaps.
unsigned width : 8;
unsigned period : 8;
unsigned align : 2;
- unsigned dynamic : 1;
+ bool_bf dynamic : 1;
};
\f
static unsigned short question_mark_bits[] = {
0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
+/* An exclamation mark. */
+/*
+ ...XX...
+ ...XX...
+ ...XX...
+ ...XX...
+ ...XX...
+ ...XX...
+ ...XX...
+ ........
+ ...XX...
+ ...XX...
+*/
+static unsigned short exclamation_mark_bits[] = {
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18};
+
/* An arrow like this: `<-'. */
/*
...xx...
{
{ NULL, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */
{ FRBITS (question_mark_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
+ { FRBITS (exclamation_mark_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
{ FRBITS (left_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
{ FRBITS (right_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
{ FRBITS (up_arrow_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
int
lookup_fringe_bitmap (Lisp_Object bitmap)
{
- int bn;
+ EMACS_INT bn;
bitmap = Fget (bitmap, Qfringe);
if (!INTEGERP (bitmap))
{
/* If W has a vertical border to its left, don't draw over it. */
wd -= ((!WINDOW_LEFTMOST_P (w)
- && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
+ /* This could be wrong when we allow window local
+ right dividers - but the window on the left is hard
+ to get. */
+ && !FRAME_RIGHT_DIVIDER_WIDTH (f)
+ && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
+ /* But don't reduce the fringe width if the window
+ has a left margin, because that means we are not
+ in danger of drawing over the vertical border,
+ and OTOH leaving out that one pixel leaves behind
+ traces of the cursor, if it was in column zero
+ before drawing non-empty margin area. */
+ && w->left_margin_cols == 0)
? 1 : 0);
p.bx = x - wd;
p.nx = wd;
}
}
- FRAME_RIF (f)->draw_fringe_bitmap (w, row, &p);
+ if (p.x >= WINDOW_BOX_LEFT_EDGE_X (w)
+ && (p.x + p.wd) <= WINDOW_BOX_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w))
+ FRAME_RIF (f)->draw_fringe_bitmap (w, row, &p);
}
static int
{
Lisp_Object cmap, bm = Qnil;
- if ((cmap = BVAR (XBUFFER (w->buffer), fringe_cursor_alist)), !NILP (cmap))
+ if ((cmap = BVAR (XBUFFER (w->contents), fringe_cursor_alist)), !NILP (cmap))
{
bm = Fassq (cursor, cmap);
if (CONSP (bm))
get_logical_fringe_bitmap (struct window *w, Lisp_Object bitmap, int right_p, int partial_p)
{
Lisp_Object cmap, bm1 = Qnil, bm2 = Qnil, bm;
- int ln1 = 0, ln2 = 0;
+ EMACS_INT ln1 = 0, ln2 = 0;
int ix1 = right_p;
int ix2 = ix1 + (partial_p ? 2 : 0);
If partial, lookup partial bitmap in default value if not found here.
If not partial, or no partial spec is present, use non-partial bitmap. */
- if ((cmap = BVAR (XBUFFER (w->buffer), fringe_indicator_alist)), !NILP (cmap))
+ if ((cmap = BVAR (XBUFFER (w->contents), fringe_indicator_alist)), !NILP (cmap))
{
bm1 = Fassq (bitmap, cmap);
if (CONSP (bm1))
void
draw_row_fringe_bitmaps (struct window *w, struct glyph_row *row)
{
- xassert (interrupt_input_blocked);
+ eassert (input_blocked_p ());
/* If row is completely invisible, because of vscrolling, we
don't have to draw anything. */
/* Draw the fringes of window W. Only fringes for rows marked for
update in redraw_fringe_bitmaps_p are drawn.
- Return >0 if left or right fringe was redrawn in any way.
+ Return nonzero if left or right fringe was redrawn in any way.
- If NO_FRINGE is non-zero, also return >0 if either fringe has zero width.
+ If NO_FRINGE_P is non-zero, also return nonzero if either fringe
+ has zero width.
- A return value >0 indicates that the vertical line between windows
- needs update (as it may be drawn in the fringe).
+ A return nonzero value indicates that the vertical line between
+ windows needs update (as it may be drawn in the fringe).
*/
-int
-draw_window_fringes (struct window *w, int no_fringe)
+bool
+draw_window_fringes (struct window *w, bool no_fringe_p)
{
struct glyph_row *row;
int yb = window_text_bottom_y (w);
int nrows = w->current_matrix->nrows;
int y, rn;
- int updated = 0;
+ bool updated_p = 0;
if (w->pseudo_window_p)
- return 0;
+ return updated_p;
/* Must draw line if no fringe */
- if (no_fringe
+ if (no_fringe_p
&& (WINDOW_LEFT_FRINGE_WIDTH (w) == 0
|| WINDOW_RIGHT_FRINGE_WIDTH (w) == 0))
- updated++;
+ updated_p = 1;
for (y = w->vscroll, rn = 0, row = w->current_matrix->rows;
y < yb && rn < nrows;
continue;
draw_row_fringe_bitmaps (w, row);
row->redraw_fringe_bitmaps_p = 0;
- updated++;
+ updated_p = 1;
}
- return updated;
+ return updated_p;
}
If KEEP_CURRENT_P is 0, update current_matrix too. */
-int
-update_window_fringes (struct window *w, int keep_current_p)
+bool
+update_window_fringes (struct window *w, bool keep_current_p)
{
struct glyph_row *row, *cur = 0;
int yb = window_text_bottom_y (w);
int rn, nrows = w->current_matrix->nrows;
int y;
- int redraw_p = 0;
+ bool redraw_p = 0;
Lisp_Object boundary_top = Qnil, boundary_bot = Qnil;
Lisp_Object arrow_top = Qnil, arrow_bot = Qnil;
Lisp_Object empty_pos;
int top_ind_rn, bot_ind_rn;
int top_ind_min_y, bot_ind_max_y;
- /* top_ind_rn is set to a nonnegative value whenver
+ /* top_ind_rn is set to a nonnegative value whenever
row->indicate_bob_p is set, so it's OK that top_row_ends_at_zv_p
is not initialized here. Similarly for bot_ind_rn,
row->indicate_eob_p and bot_row_ends_at_zv_p. */
return 0;
if (!MINI_WINDOW_P (w)
- && (ind = BVAR (XBUFFER (w->buffer), indicate_buffer_boundaries), !NILP (ind)))
+ && (ind = BVAR (XBUFFER (w->contents), indicate_buffer_boundaries), !NILP (ind)))
{
if (EQ (ind, Qleft) || EQ (ind, Qright))
boundary_top = boundary_bot = arrow_top = arrow_bot = ind;
{
if (top_ind_rn < 0 && row->visible_height > 0)
{
- if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer))
+ if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->contents))
&& !MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
row->indicate_bob_p = !NILP (boundary_top);
else
if (bot_ind_rn < 0)
{
- if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer))
+ if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->contents))
&& !MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row))
row->indicate_eob_p = !NILP (boundary_bot), bot_ind_rn = rn;
else if (y + row->height >= yb)
}
}
- empty_pos = BVAR (XBUFFER (w->buffer), indicate_empty_lines);
+ empty_pos = BVAR (XBUFFER (w->contents), indicate_empty_lines);
if (!NILP (empty_pos) && !EQ (empty_pos, Qright))
empty_pos = WINDOW_LEFT_FRINGE_WIDTH (w) == 0 ? Qright : Qleft;
int left, right;
unsigned left_face_id, right_face_id;
int left_offset, right_offset;
- int periodic_p;
+ bool periodic_p;
row = w->desired_matrix->rows + rn;
cur = w->current_matrix->rows + rn;
|| periodic_p != cur->fringe_bitmap_periodic_p
|| cur->redraw_fringe_bitmaps_p)
{
- redraw_p = row->redraw_fringe_bitmaps_p = 1;
+ redraw_p = 1, row->redraw_fringe_bitmaps_p = 1;
if (!keep_current_p)
{
cur->redraw_fringe_bitmaps_p = 1;
if (row->overlay_arrow_bitmap != cur->overlay_arrow_bitmap)
{
- redraw_p = row->redraw_fringe_bitmaps_p = 1;
+ redraw_p = 1, row->redraw_fringe_bitmaps_p = 1;
if (!keep_current_p)
{
cur->redraw_fringe_bitmaps_p = 1;
*/
void
-compute_fringe_widths (struct frame *f, int redraw)
+compute_fringe_widths (struct frame *f, bool redraw_p)
{
int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
if (left_fringe_width || right_fringe_width)
{
- 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 left_wid = eabs (left_fringe_width);
+ int right_wid = eabs (right_fringe_width);
int conf_wid = left_wid + right_wid;
int font_wid = FRAME_COLUMN_WIDTH (f);
int cols = (left_wid + right_wid + font_wid-1) / font_wid;
FRAME_FRINGE_COLS (f) = 0;
}
- if (redraw && FRAME_VISIBLE_P (f))
+ if (redraw_p && FRAME_VISIBLE_P (f))
if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
o_cols != FRAME_FRINGE_COLS (f))
| (swap_nibble[(b>>12) & 0xf]));
b >>= (16 - fb->width);
#ifdef WORDS_BIGENDIAN
- b = ((b >> 8) | (b << 8));
+ b = bswap_16 (b);
#endif
*bits++ = b;
}
else
{
CHECK_NUMBER (height);
- fb.height = min (XINT (height), 255);
+ fb.height = max (0, min (XINT (height), 255));
if (fb.height > h)
{
fill1 = (fb.height - h) / 2;
else
{
CHECK_NUMBER (width);
- fb.width = min (XINT (width), 255);
+ fb.width = max (0, min (XINT (width), 255));
}
fb.period = 0;
error ("No free fringe bitmap slots");
i = max_fringe_bitmaps;
- fringe_bitmaps
- = ((struct fringe_bitmap **)
- xrealloc (fringe_bitmaps, bitmaps * sizeof *fringe_bitmaps));
- fringe_faces
- = (Lisp_Object *) xrealloc (fringe_faces,
- bitmaps * sizeof *fringe_faces);
+ fringe_bitmaps = xrealloc (fringe_bitmaps,
+ bitmaps * sizeof *fringe_bitmaps);
+ fringe_faces = xrealloc (fringe_faces,
+ bitmaps * sizeof *fringe_faces);
for (i = max_fringe_bitmaps; i < bitmaps; i++)
{
Fput (bitmap, Qfringe, make_number (n));
}
- fb.dynamic = 1;
+ fb.dynamic = true;
- xfb = (struct fringe_bitmap *) xmalloc (sizeof fb
- + fb.height * BYTES_PER_BITMAP_ROW);
+ xfb = xmalloc (sizeof fb + fb.height * BYTES_PER_BITMAP_ROW);
fb.bits = b = (unsigned short *) (xfb + 1);
memset (b, 0, fb.height);
DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face,
1, 2, 0,
doc: /* Set face for fringe bitmap BITMAP to FACE.
+FACE is merged with the `fringe' face, so normally FACE should specify
+only the foreground color.
If FACE is nil, reset face to default fringe face. */)
(Lisp_Object bitmap, Lisp_Object face)
{
int n;
- int face_id;
CHECK_SYMBOL (bitmap);
n = lookup_fringe_bitmap (bitmap);
if (!n)
error ("Undefined fringe bitmap");
+ /* The purpose of the following code is to signal an error if FACE
+ is not a face. This is for the caller's convenience only; the
+ redisplay code should be able to fail gracefully. Skip the check
+ if FRINGE_FACE_ID is unrealized (as in batch mode and during
+ daemon startup). */
if (!NILP (face))
{
- face_id = lookup_derived_face (SELECTED_FRAME (), face,
- FRINGE_FACE_ID, 1);
- if (face_id < 0)
+ struct frame *f = SELECTED_FRAME ();
+
+ if (FACE_FROM_ID (f, FRINGE_FACE_ID)
+ && lookup_derived_face (f, face, FRINGE_FACE_ID, 1) < 0)
error ("No such face");
}
fringe_faces[n] = face;
-
return Qnil;
}
{
struct window *w;
struct glyph_row *row;
- int textpos;
+ ptrdiff_t textpos;
- if (NILP (window))
- window = selected_window;
- CHECK_WINDOW (window);
- w = XWINDOW (window);
+ w = decode_any_window (window);
+ XSETWINDOW (window, w);
if (!NILP (pos))
{
CHECK_NUMBER_COERCE_MARKER (pos);
+ if (! (BEGV <= XINT (pos) && XINT (pos) <= ZV))
+ args_out_of_range (window, pos);
textpos = XINT (pos);
}
else if (w == XWINDOW (selected_window))
textpos = PT;
else
- textpos = XMARKER (w->pointm)->charpos;
+ textpos = marker_position (w->pointm);
row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
row = row_containing_pos (w, textpos, row, NULL, 0);
defsubr (&Sset_fringe_bitmap_face);
DEFVAR_LISP ("overflow-newline-into-fringe", Voverflow_newline_into_fringe,
- doc: /* *Non-nil means that newline may flow into the right fringe.
+ doc: /* Non-nil means that newline may flow into the right fringe.
This means that display lines which are exactly as wide as the window
(not counting the final newline) will only occupy one screen line, by
showing (or hiding) the final newline in the right fringe; when point
max_fringe_bitmaps = MAX_STANDARD_FRINGE_BITMAPS + 20;
- fringe_bitmaps
- = (struct fringe_bitmap **) xmalloc (max_fringe_bitmaps * sizeof (struct fringe_bitmap *));
- fringe_faces
- = (Lisp_Object *) xmalloc (max_fringe_bitmaps * sizeof (Lisp_Object));
+ fringe_bitmaps = xzalloc (max_fringe_bitmaps * sizeof *fringe_bitmaps);
+ fringe_faces = xmalloc (max_fringe_bitmaps * sizeof *fringe_faces);
for (i = 0; i < max_fringe_bitmaps; i++)
- {
- fringe_bitmaps[i] = NULL;
- fringe_faces[i] = Qnil;
- }
+ fringe_faces[i] = Qnil;
}
#ifdef HAVE_NTGUI
}
#endif /* HAVE_NTGUI */
-
-#endif /* HAVE_WINDOW_SYSTEM */