/* Fringe handling (split from xdisp.c).
- Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03,04
- Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997,
+ 1998, 1999, 2000, 2000, 2001, 2002, 2003, 2004,
+ 2005 Free Software Foundation, Inc.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
#include <config.h>
#include <stdio.h>
};
static struct fringe_bitmap **fringe_bitmaps;
-static unsigned *fringe_faces;
+static Lisp_Object *fringe_faces;
static int max_fringe_bitmaps;
static int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS;
}
if (face_id == DEFAULT_FACE_ID)
- face_id = fringe_faces[which];
+ {
+ Lisp_Object face;
+
+ if ((face = fringe_faces[which], NILP (face))
+ || (face_id = lookup_derived_face (f, face, 'A', FRINGE_FACE_ID, 0),
+ face_id < 0))
+ face_id = FRINGE_FACE_ID;
+ }
fb = fringe_bitmaps[which];
if (fb == NULL)
if (p.face == NULL)
{
- /* Why does this happen? ++kfs */
+ /* This could happen after clearing face cache.
+ But it shouldn't happen anymore. ++kfs */
return;
}
draw_fringe_bitmap_1 (w, row, left_p, overlay, NO_FRINGE_BITMAP);
- if (left_p && row->overlay_arrow_p)
+ if (left_p && row->overlay_arrow_bitmap != NO_FRINGE_BITMAP)
draw_fringe_bitmap_1 (w, row, 1, 1,
- (w->overlay_arrow_bitmap
- ? w->overlay_arrow_bitmap
- : OVERLAY_ARROW_BITMAP));
+ (row->overlay_arrow_bitmap < 0
+ ? OVERLAY_ARROW_BITMAP
+ : row->overlay_arrow_bitmap));
}
/* Recalculate the bitmaps to show in the fringes of window W.
- If FORCE_P is 0, only mark rows with modified bitmaps for update in
- redraw_fringe_bitmaps_p; else mark all rows for update. */
+ Only mark rows with modified bitmaps for update in redraw_fringe_bitmaps_p.
+
+ If KEEP_CURRENT_P is 0, update current_matrix too. */
int
-update_window_fringes (w, force_p)
+update_window_fringes (w, keep_current_p)
struct window *w;
- int force_p;
+ int keep_current_p;
{
struct glyph_row *row, *cur = 0;
int yb = window_text_bottom_y (w);
arrow_bot = XCDR (pos);
}
else
- ind = Qnil;
+ /* Anything else means boundary on left and no arrows. */
+ boundary_top = boundary_bot = Qleft;
}
if (!NILP (ind))
{
- int do_eob = 1, do_bob = 1;
+ int done_top = 0, done_bot = 0;
for (y = 0, rn = 0;
y < yb && rn < nrows;
row->indicate_bob_p = row->indicate_top_line_p = 0;
row->indicate_eob_p = row->indicate_bottom_line_p = 0;
- if (!NILP (boundary_top)
- && MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer)))
- row->indicate_bob_p = do_bob, do_bob = 0;
- else if (!NILP (arrow_top)
- && (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0) == rn)
- row->indicate_top_line_p = 1;
+ if (!row->mode_line_p)
+ {
+ if (!done_top)
+ {
+ if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer))
+ && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
+ row->indicate_bob_p = !NILP (boundary_top);
+ else
+ row->indicate_top_line_p = !NILP (arrow_top);
+ done_top = 1;
+ }
- if (!NILP (boundary_bot)
- && MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer)))
- row->indicate_eob_p = do_eob, do_eob = 0;
- else if (!NILP (arrow_bot)
- && y + row->height >= yb)
- row->indicate_bottom_line_p = 1;
+ if (!done_bot)
+ {
+ if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer))
+ && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row))
+ row->indicate_eob_p = !NILP (boundary_bot), done_bot = 1;
+ else if (y + row->height >= yb)
+ row->indicate_bottom_line_p = !NILP (arrow_bot), done_bot = 1;
+ }
+ }
if (indicate_bob_p != row->indicate_bob_p
|| indicate_top_line_p != row->indicate_top_line_p
left = row->left_user_fringe_bitmap;
left_face_id = row->left_user_fringe_face_id;
}
+ else if (row->truncated_on_left_p)
+ left = LEFT_TRUNCATION_BITMAP;
else if (row->indicate_bob_p && EQ (boundary_top, Qleft))
left = ((row->indicate_eob_p && EQ (boundary_bot, Qleft))
? LEFT_BRACKET_BITMAP : TOP_LEFT_ANGLE_BITMAP);
else if (row->indicate_eob_p && EQ (boundary_bot, Qleft))
left = BOTTOM_LEFT_ANGLE_BITMAP;
- else if (row->truncated_on_left_p)
- left = LEFT_TRUNCATION_BITMAP;
else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
left = CONTINUATION_LINE_BITMAP;
else if (row->indicate_empty_line_p && EQ (empty_pos, Qleft))
right = row->right_user_fringe_bitmap;
right_face_id = row->right_user_fringe_face_id;
}
+ else if (row->truncated_on_right_p)
+ right = RIGHT_TRUNCATION_BITMAP;
else if (row->indicate_bob_p && EQ (boundary_top, Qright))
right = ((row->indicate_eob_p && EQ (boundary_bot, Qright))
? RIGHT_BRACKET_BITMAP : TOP_RIGHT_ANGLE_BITMAP);
else if (row->indicate_eob_p && EQ (boundary_bot, Qright))
right = BOTTOM_RIGHT_ANGLE_BITMAP;
- else if (row->truncated_on_right_p)
- right = RIGHT_TRUNCATION_BITMAP;
else if (row->continued_p)
right = CONTINUED_LINE_BITMAP;
else if (row->indicate_top_line_p && EQ (arrow_top, Qright))
else
right = NO_FRINGE_BITMAP;
- if (force_p
- || row->y != cur->y
+ if (row->y != cur->y
|| row->visible_height != cur->visible_height
|| row->ends_at_zv_p != cur->ends_at_zv_p
|| left != cur->left_fringe_bitmap
|| right_face_id != cur->right_fringe_face_id
|| cur->redraw_fringe_bitmaps_p)
{
- redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
- cur->left_fringe_bitmap = left;
- cur->right_fringe_bitmap = right;
- cur->left_fringe_face_id = left_face_id;
- cur->right_fringe_face_id = right_face_id;
+ redraw_p = row->redraw_fringe_bitmaps_p = 1;
+ if (!keep_current_p)
+ {
+ cur->redraw_fringe_bitmaps_p = 1;
+ cur->left_fringe_bitmap = left;
+ cur->right_fringe_bitmap = right;
+ cur->left_fringe_face_id = left_face_id;
+ cur->right_fringe_face_id = right_face_id;
+ }
}
- if (row->overlay_arrow_p != cur->overlay_arrow_p)
+ if (row->overlay_arrow_bitmap != cur->overlay_arrow_bitmap)
{
redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
- cur->overlay_arrow_p = row->overlay_arrow_p;
+ cur->overlay_arrow_bitmap = row->overlay_arrow_bitmap;
}
row->left_fringe_bitmap = left;
row[-1].redraw_fringe_bitmaps_p = cur[-1].redraw_fringe_bitmaps_p = 1;
}
- return redraw_p;
+ return redraw_p && !keep_current_p;
}
/* Free resources used by a user-defined bitmap. */
-int
+void
destroy_fringe_bitmap (n)
int n;
{
struct fringe_bitmap **fbp;
- fringe_faces[n] = FRINGE_FACE_ID;
+ fringe_faces[n] = Qnil;
fbp = &fringe_bitmaps[n];
if (*fbp && (*fbp)->dynamic)
(bitmap, bits, height, width, align)
Lisp_Object bitmap, bits, height, width, align;
{
- Lisp_Object len;
int n, h, i, j;
unsigned short *b;
struct fringe_bitmap fb, *xfb;
CHECK_SYMBOL (bitmap);
- if (!STRINGP (bits) && !VECTORP (bits))
- bits = wrong_type_argument (Qstringp, bits);
-
- len = Flength (bits);
+ if (STRINGP (bits))
+ h = SCHARS (bits);
+ else if (VECTORP (bits))
+ h = XVECTOR (bits)->size;
+ else
+ bits = wrong_type_argument (Qsequencep, bits);
if (NILP (height))
- h = fb.height = XINT (len);
+ fb.height = h;
else
{
CHECK_NUMBER (height);
fb.height = min (XINT (height), 255);
- if (fb.height > XINT (len))
+ if (fb.height > h)
{
- h = XINT (len);
fill1 = (fb.height - h) / 2;
fill2 = fb.height - h - fill1;
}
= ((struct fringe_bitmap **)
xrealloc (fringe_bitmaps, max_fringe_bitmaps * sizeof (struct fringe_bitmap *)));
fringe_faces
- = (unsigned *) xrealloc (fringe_faces, max_fringe_bitmaps * sizeof (unsigned));
+ = (Lisp_Object *) xrealloc (fringe_faces, max_fringe_bitmaps * sizeof (Lisp_Object));
for (; i < max_fringe_bitmaps; i++)
{
fringe_bitmaps[i] = NULL;
- fringe_faces[i] = FRINGE_FACE_ID;
+ fringe_faces[i] = Qnil;
}
}
}
if (!NILP (face))
{
- face_id = lookup_named_face (SELECTED_FRAME (), face, 'A');
+ face_id = lookup_derived_face (SELECTED_FRAME (), face,
+ 'A', FRINGE_FACE_ID, 1);
if (face_id < 0)
error ("No such face");
}
- else
- face_id = FRINGE_FACE_ID;
- fringe_faces[n] = face_id;
+ fringe_faces[n] = face;
return Qnil;
}
Lisp_Object pos, window;
{
struct window *w;
- struct buffer *old_buffer = NULL;
struct glyph_row *row;
int textpos;
if (row)
return list3 (get_fringe_bitmap_name (row->left_fringe_bitmap),
get_fringe_bitmap_name (row->right_fringe_bitmap),
- (row->overlay_arrow_p ? Qt : Qnil));
+ (row->overlay_arrow_bitmap == 0 ? Qnil
+ : row->overlay_arrow_bitmap < 0 ? Qt
+ : get_fringe_bitmap_name (row->overlay_arrow_bitmap)));
else
return Qnil;
}
Vfringe_bitmaps = Qnil;
}
+/* Garbage collection hook */
+
+void
+mark_fringe_data ()
+{
+ int i;
+
+ for (i = 0; i < max_fringe_bitmaps; i++)
+ if (!NILP (fringe_faces[i]))
+ mark_object (fringe_faces[i]);
+}
+
/* Initialize this module when Emacs starts. */
void
fringe_bitmaps
= (struct fringe_bitmap **) xmalloc (max_fringe_bitmaps * sizeof (struct fringe_bitmap *));
fringe_faces
- = (unsigned *) xmalloc (max_fringe_bitmaps * sizeof (unsigned));
+ = (Lisp_Object *) xmalloc (max_fringe_bitmaps * sizeof (Lisp_Object));
for (i = 0; i < max_fringe_bitmaps; i++)
{
fringe_bitmaps[i] = NULL;
- fringe_faces[i] = FRINGE_FACE_ID;
+ fringe_faces[i] = Qnil;
}
}