X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/ac887bc2843e28a189afa7a1f83ca48157a5e750..40fb2103c2986cbb91add4afed635886c4f87ae5:/src/fringe.c diff --git a/src/fringe.c b/src/fringe.c index 3f04069900..771e7d4787 100644 --- a/src/fringe.c +++ b/src/fringe.c @@ -31,12 +31,22 @@ Boston, MA 02111-1307, USA. */ #ifdef HAVE_WINDOW_SYSTEM +extern Lisp_Object Qfringe; extern Lisp_Object Qtop, Qbottom, Qcenter; +extern Lisp_Object Qup, Qdown, Qleft, Qright; /* Non-nil means that newline may flow into the right fringe. */ Lisp_Object Voverflow_newline_into_fringe; +/* List of known fringe bitmap symbols. + + The fringe bitmap number is stored in the `fringe' property on + those symbols. Names for the built-in bitmaps are installed by + loading fringe.el. + */ + +Lisp_Object Vfringe_bitmaps; enum fringe_bitmap_type { @@ -435,23 +445,69 @@ struct fringe_bitmap standard_bitmaps[MAX_STANDARD_FRINGE_BITMAPS] = { FRBITS (zv_bits), 8, 3, ALIGN_BITMAP_TOP, 0 }, }; -static struct fringe_bitmap *fringe_bitmaps[MAX_FRINGE_BITMAPS]; -static unsigned fringe_faces[MAX_FRINGE_BITMAPS]; +static struct fringe_bitmap **fringe_bitmaps; +static Lisp_Object *fringe_faces; +static int max_fringe_bitmaps; static int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS; -/* Return 1 if FRINGE_ID is a valid fringe bitmap id. */ + +/* Lookup bitmap number for symbol BITMAP. + Return 0 if not a bitmap. */ int -valid_fringe_bitmap_id_p (fringe_id) - int fringe_id; +lookup_fringe_bitmap (bitmap) + Lisp_Object bitmap; { - return (fringe_id >= NO_FRINGE_BITMAP - && fringe_id < max_used_fringe_bitmap - && (fringe_id < MAX_STANDARD_FRINGE_BITMAPS - || fringe_bitmaps[fringe_id] != NULL)); + int bn; + + bitmap = Fget (bitmap, Qfringe); + if (!INTEGERP (bitmap)) + return 0; + + bn = XINT (bitmap); + if (bn > NO_FRINGE_BITMAP + && bn < max_used_fringe_bitmap + && (bn < MAX_STANDARD_FRINGE_BITMAPS + || fringe_bitmaps[bn] != NULL)) + return bn; + + return 0; } +/* Get fringe bitmap name for bitmap number BN. + + Found by traversing Vfringe_bitmaps comparing BN to the + fringe property for each symbol. + + Return BN if not found in Vfringe_bitmaps. */ + +static Lisp_Object +get_fringe_bitmap_name (bn) + int bn; +{ + Lisp_Object bitmaps; + Lisp_Object num; + + /* Zero means no bitmap -- return nil. */ + if (bn <= 0) + return Qnil; + + bitmaps = Vfringe_bitmaps; + num = make_number (bn); + + while (CONSP (bitmaps)) + { + Lisp_Object bitmap = XCAR (bitmaps); + if (EQ (num, Fget (bitmap, Qfringe))) + return bitmap; + bitmaps = XCDR (bitmaps); + } + + return num; +} + + /* Draw the bitmap WHICH in one of the left or right fringes of window W. ROW is the glyph row for which to display the bitmap; it determines the vertical position at which the bitmap has to be @@ -491,7 +547,13 @@ draw_fringe_bitmap_1 (w, row, left_p, overlay, which) } if (face_id == DEFAULT_FACE_ID) - face_id = fringe_faces[which]; + { + Lisp_Object face; + + if ((face = fringe_faces[which], NILP (face)) + || (face_id = lookup_named_face (f, face, 1), face_id < 0)) + face_id = FRINGE_FACE_ID; + } fb = fringe_bitmaps[which]; if (fb == NULL) @@ -518,7 +580,8 @@ draw_fringe_bitmap_1 (w, row, left_p, overlay, which) if (p.face == NULL) { - /* Why does this happen? ++kfs */ + /* This could happen after clearing face cache. + But it shouldn't happen anymore. ++kfs */ return; } @@ -666,19 +729,35 @@ draw_row_fringe_bitmaps (w, row) } /* Draw the fringes of window W. Only fringes for rows marked for - update in redraw_fringe_bitmaps_p are drawn. */ + update in redraw_fringe_bitmaps_p are drawn. -void -draw_window_fringes (w) + Return >0 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. + + A return value >0 indicates that the vertical line between windows + needs update (as it may be drawn in the fringe). +*/ + +int +draw_window_fringes (w, no_fringe) struct window *w; + int no_fringe; { struct glyph_row *row; int yb = window_text_bottom_y (w); int nrows = w->current_matrix->nrows; int y = 0, rn; + int updated = 0; if (w->pseudo_window_p) - return; + return 0; + + /* Must draw line if no fringe */ + if (no_fringe + && (WINDOW_LEFT_FRINGE_WIDTH (w) == 0 + || WINDOW_RIGHT_FRINGE_WIDTH (w) == 0)) + updated++; for (y = 0, rn = 0, row = w->current_matrix->rows; y < yb && rn < nrows; @@ -688,7 +767,10 @@ draw_window_fringes (w) continue; draw_row_fringe_bitmaps (w, row); row->redraw_fringe_bitmaps_p = 0; + updated++; } + + return updated; } @@ -706,9 +788,10 @@ update_window_fringes (w, force_p) int rn, nrows = w->current_matrix->nrows; int y; int redraw_p = 0; - Lisp_Object ind; - int boundary_pos = 0, arrow_pos = 0; - int empty_pos = 0; + Lisp_Object boundary_top = Qnil, boundary_bot = Qnil; + Lisp_Object arrow_top = Qnil, arrow_bot = Qnil; + Lisp_Object empty_pos; + Lisp_Object ind = Qnil; if (w->pseudo_window_p) return 0; @@ -716,23 +799,30 @@ update_window_fringes (w, force_p) if (!MINI_WINDOW_P (w) && (ind = XBUFFER (w->buffer)->indicate_buffer_boundaries, !NILP (ind))) { - int do_eob = 1, do_bob = 1; - Lisp_Object arrows; - - if (CONSP (ind)) - arrows = XCDR (ind), ind = XCAR (ind); + if (EQ (ind, Qleft) || EQ (ind, Qright)) + boundary_top = boundary_bot = arrow_top = arrow_bot = ind; + else if (CONSP (ind) && CONSP (XCAR (ind))) + { + Lisp_Object pos; + if (pos = Fassq (Qt, ind), !NILP (pos)) + boundary_top = boundary_bot = arrow_top = arrow_bot = XCDR (pos); + if (pos = Fassq (Qtop, ind), !NILP (pos)) + boundary_top = XCDR (pos); + if (pos = Fassq (Qbottom, ind), !NILP (pos)) + boundary_bot = XCDR (pos); + if (pos = Fassq (Qup, ind), !NILP (pos)) + arrow_top = XCDR (pos); + if (pos = Fassq (Qdown, ind), !NILP (pos)) + arrow_bot = XCDR (pos); + } else - arrows = ind; - - if (EQ (ind, Qleft)) - boundary_pos = -1; - else if (EQ (ind, Qright)) - boundary_pos = 1; + /* Anything else means boundary on left and no arrows. */ + boundary_top = boundary_bot = Qleft; + } - if (EQ (arrows, Qleft)) - arrow_pos = -1; - else if (EQ (arrows, Qright)) - arrow_pos = 1; + if (!NILP (ind)) + { + int done_top = 0, done_bot = 0; for (y = 0, rn = 0; y < yb && rn < nrows; @@ -753,19 +843,25 @@ update_window_fringes (w, force_p) row->indicate_bob_p = row->indicate_top_line_p = 0; row->indicate_eob_p = row->indicate_bottom_line_p = 0; - if (!NILP (ind) - && MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer))) - row->indicate_bob_p = do_bob, do_bob = 0; - else if (!NILP (arrows) - && (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0) == rn) - row->indicate_top_line_p = 1; - - if (!NILP (ind) - && MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer))) - row->indicate_eob_p = do_eob, do_eob = 0; - else if (!NILP (arrows) - && y + row->height >= yb) - row->indicate_bottom_line_p = 1; + if (!row->mode_line_p) + { + if (!done_top) + { + if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer))) + row->indicate_bob_p = !NILP (boundary_top); + else + row->indicate_top_line_p = !NILP (arrow_top); + done_top = 1; + } + + if (!done_bot) + { + if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer))) + 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 @@ -775,10 +871,9 @@ update_window_fringes (w, force_p) } } - if (EQ (XBUFFER (w->buffer)->indicate_empty_lines, Qright)) - empty_pos = 1; - else if (EQ (XBUFFER (w->buffer)->indicate_empty_lines, Qleft)) - empty_pos = -1; + empty_pos = XBUFFER (w->buffer)->indicate_empty_lines; + if (!NILP (empty_pos) && !EQ (empty_pos, Qright)) + empty_pos = WINDOW_LEFT_FRINGE_WIDTH (w) == 0 ? Qright : Qleft; for (y = 0, rn = 0; y < yb && rn < nrows; @@ -802,20 +897,20 @@ update_window_fringes (w, force_p) left = row->left_user_fringe_bitmap; left_face_id = row->left_user_fringe_face_id; } - else if (row->indicate_bob_p && boundary_pos <= 0) - left = ((row->indicate_eob_p && boundary_pos < 0) - ? LEFT_BRACKET_BITMAP : TOP_LEFT_ANGLE_BITMAP); - else if (row->indicate_eob_p && boundary_pos < 0) - left = BOTTOM_LEFT_ANGLE_BITMAP; 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 (MATRIX_ROW_CONTINUATION_LINE_P (row)) left = CONTINUATION_LINE_BITMAP; - else if (row->indicate_empty_line_p && empty_pos <= 0) + else if (row->indicate_empty_line_p && EQ (empty_pos, Qleft)) left = ZV_LINE_BITMAP; - else if (row->indicate_top_line_p && arrow_pos <= 0) + else if (row->indicate_top_line_p && EQ (arrow_top, Qleft)) left = UP_ARROW_BITMAP; - else if (row->indicate_bottom_line_p && arrow_pos < 0) + else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qleft)) left = DOWN_ARROW_BITMAP; else left = NO_FRINGE_BITMAP; @@ -828,22 +923,20 @@ update_window_fringes (w, force_p) right = row->right_user_fringe_bitmap; right_face_id = row->right_user_fringe_face_id; } - else if (row->indicate_bob_p && boundary_pos > 0) - right = ((row->indicate_eob_p && boundary_pos >= 0) - ? RIGHT_BRACKET_BITMAP : TOP_RIGHT_ANGLE_BITMAP); - else if (row->indicate_eob_p && boundary_pos >= 0) - right = BOTTOM_RIGHT_ANGLE_BITMAP; 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->continued_p) right = CONTINUED_LINE_BITMAP; - else if (row->indicate_top_line_p && arrow_pos > 0) + else if (row->indicate_top_line_p && EQ (arrow_top, Qright)) right = UP_ARROW_BITMAP; - else if (row->indicate_bottom_line_p && arrow_pos >= 0) + else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qright)) right = DOWN_ARROW_BITMAP; - else if (row->indicate_empty_line_p - && (empty_pos > 0 - || (WINDOW_LEFT_FRINGE_WIDTH (w) == 0 && empty_pos == 0))) + else if (row->indicate_empty_line_p && EQ (empty_pos, Qright)) right = ZV_LINE_BITMAP; else right = NO_FRINGE_BITMAP; @@ -851,6 +944,7 @@ update_window_fringes (w, force_p) if (force_p || 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 != cur->right_fringe_bitmap || left_face_id != cur->left_fringe_face_id @@ -874,6 +968,9 @@ update_window_fringes (w, force_p) row->right_fringe_bitmap = right; row->left_fringe_face_id = left_face_id; row->right_fringe_face_id = right_face_id; + + if (rn > 0 && row->redraw_fringe_bitmaps_p) + row[-1].redraw_fringe_bitmaps_p = cur[-1].redraw_fringe_bitmaps_p = 1; } return redraw_p; @@ -890,11 +987,7 @@ update_window_fringes (w, force_p) Typically, we add an equal amount (+/- 1 pixel) to each fringe, but a negative width value is taken literally (after negating it). - We never make the fringes narrower than specified. It is planned - to make fringe bitmaps customizable and expandable, and at that - time, the user will typically specify the minimum number of pixels - needed for his bitmaps, so we shouldn't select anything less than - what is specified. + We never make the fringes narrower than specified. */ void @@ -978,26 +1071,21 @@ compute_fringe_widths (f, redraw) redraw_frame (f); } -DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap, Sdestroy_fringe_bitmap, - 1, 1, 0, - doc: /* Destroy fringe bitmap WHICH. -If WHICH overrides a standard fringe bitmap, the original bitmap is restored. */) - (which) - Lisp_Object which; + +/* Free resources used by a user-defined bitmap. */ + +void +destroy_fringe_bitmap (n) + int n; { - int n; struct fringe_bitmap **fbp; - CHECK_NUMBER (which); - if (n = XINT (which), n >= max_used_fringe_bitmap) - return Qnil; - - fringe_faces[n] = FRINGE_FACE_ID; + fringe_faces[n] = Qnil; fbp = &fringe_bitmaps[n]; if (*fbp && (*fbp)->dynamic) { - if (rif->destroy_fringe_bitmap) + if (rif && rif->destroy_fringe_bitmap) rif->destroy_fringe_bitmap (n); xfree (*fbp); *fbp = NULL; @@ -1006,6 +1094,31 @@ If WHICH overrides a standard fringe bitmap, the original bitmap is restored. * while (max_used_fringe_bitmap > MAX_STANDARD_FRINGE_BITMAPS && fringe_bitmaps[max_used_fringe_bitmap - 1] == NULL) max_used_fringe_bitmap--; +} + + +DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap, Sdestroy_fringe_bitmap, + 1, 1, 0, + doc: /* Destroy fringe bitmap BITMAP. +If BITMAP overrides a standard fringe bitmap, the original bitmap is restored. */) + (bitmap) + Lisp_Object bitmap; +{ + int n; + + CHECK_SYMBOL (bitmap); + n = lookup_fringe_bitmap (bitmap); + if (!n) + return Qnil; + + destroy_fringe_bitmap (n); + + if (n >= MAX_STANDARD_FRINGE_BITMAPS) + { + Vfringe_bitmaps = Fdelq (bitmap, Vfringe_bitmaps); + /* It would be better to remove the fringe property. */ + Fput (bitmap, Qfringe, Qnil); + } return Qnil; } @@ -1077,9 +1190,9 @@ init_fringe_bitmap (which, fb, once_p) if (!once_p) { - Fdestroy_fringe_bitmap (make_number (which)); + destroy_fringe_bitmap (which); - if (rif->define_fringe_bitmap) + if (rif && rif->define_fringe_bitmap) rif->define_fringe_bitmap (which, fb->bits, fb->height, fb->width); fringe_bitmaps[which] = fb; @@ -1090,41 +1203,43 @@ init_fringe_bitmap (which, fb, once_p) DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap, - 1, 5, 0, - doc: /* Define a fringe bitmap from BITS of height HEIGHT and width WIDTH. + 2, 5, 0, + doc: /* Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH. +BITMAP is a symbol or string naming the new fringe bitmap. BITS is either a string or a vector of integers. HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS. WIDTH must be an integer between 1 and 16, or nil which defaults to 8. -Optional fourth arg ALIGN may be one of `top', `center', or `bottom', +Optional fifth arg ALIGN may be one of `top', `center', or `bottom', indicating the positioning of the bitmap relative to the rows where it is used; the default is to center the bitmap. Fourth arg may also be a list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap should be repeated. -Optional fifth argument WHICH is bitmap number to redefine. -Return new bitmap number, or nil of no more free bitmap slots. */) - (bits, height, width, align, which) - Lisp_Object bits, height, width, align, which; +If BITMAP already exists, the existing definition is replaced. */) + (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; int fill1 = 0, fill2 = 0; - if (!STRINGP (bits) && !VECTORP (bits)) - bits = wrong_type_argument (Qstringp, bits); + CHECK_SYMBOL (bitmap); - 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; } @@ -1162,28 +1277,42 @@ Return new bitmap number, or nil of no more free bitmap slots. */) else if (!NILP (align) && !EQ (align, Qcenter)) error ("Bad align argument"); - if (NILP (which)) + n = lookup_fringe_bitmap (bitmap); + if (!n) { - if (max_used_fringe_bitmap < MAX_FRINGE_BITMAPS) + if (max_used_fringe_bitmap < max_fringe_bitmaps) n = max_used_fringe_bitmap++; else { for (n = MAX_STANDARD_FRINGE_BITMAPS; - n < MAX_FRINGE_BITMAPS; + n < max_fringe_bitmaps; n++) if (fringe_bitmaps[n] == NULL) break; - if (n == MAX_FRINGE_BITMAPS) - return Qnil; + + if (n == max_fringe_bitmaps) + { + if ((max_fringe_bitmaps + 20) > MAX_FRINGE_BITMAPS) + error ("No free fringe bitmap slots"); + + i = max_fringe_bitmaps; + max_fringe_bitmaps += 20; + fringe_bitmaps + = ((struct fringe_bitmap **) + xrealloc (fringe_bitmaps, max_fringe_bitmaps * sizeof (struct fringe_bitmap *))); + fringe_faces + = (Lisp_Object *) xrealloc (fringe_faces, max_fringe_bitmaps * sizeof (Lisp_Object)); + + for (; i < max_fringe_bitmaps; i++) + { + fringe_bitmaps[i] = NULL; + fringe_faces[i] = Qnil; + } + } } - which = make_number (n); - } - else - { - CHECK_NUMBER (which); - n = XINT (which); - if (n <= NO_FRINGE_BITMAP || n >= MAX_FRINGE_BITMAPS) - error ("Invalid fringe bitmap number"); + + Vfringe_bitmaps = Fcons (bitmap, Vfringe_bitmaps); + Fput (bitmap, Qfringe, make_number (n)); } fb.dynamic = 1; @@ -1211,32 +1340,32 @@ Return new bitmap number, or nil of no more free bitmap slots. */) init_fringe_bitmap (n, xfb, 0); - return which; + return bitmap; } DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face, 1, 2, 0, - doc: /* Set face for fringe bitmap FRINGE-ID to FACE. + doc: /* Set face for fringe bitmap BITMAP to FACE. If FACE is nil, reset face to default fringe face. */) - (fringe_id, face) - Lisp_Object fringe_id, face; + (bitmap, face) + Lisp_Object bitmap, face; { + int n; int face_id; - CHECK_NUMBER (fringe_id); - if (!valid_fringe_bitmap_id_p (XINT (fringe_id))) - error ("Invalid fringe id"); + CHECK_SYMBOL (bitmap); + n = lookup_fringe_bitmap (bitmap); + if (!n) + error ("Undefined fringe bitmap"); if (!NILP (face)) { - face_id = lookup_named_face (SELECTED_FRAME (), face); + face_id = lookup_named_face (SELECTED_FRAME (), face, 1); if (face_id < 0) error ("No such face"); } - else - face_id = FRINGE_FACE_ID; - fringe_faces [XINT (fringe_id)] = face_id; + fringe_faces[n] = face; return Qnil; } @@ -1245,14 +1374,15 @@ DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos, Sfringe_bitmaps_at_pos, 0, 2, 0, doc: /* Return fringe bitmaps of row containing position POS in window WINDOW. If WINDOW is nil, use selected window. If POS is nil, use value of point -in that window. Return value is a cons (LEFT . RIGHT) where LEFT and RIGHT -are the fringe bitmap numbers for the bitmaps in the left and right fringe, -resp. Return nil if POS is not visible in WINDOW. */) +in that window. Return value is a list (LEFT RIGHT OV), where LEFT +is the symbol for the bitmap in the left fringe (or nil if no bitmap), +RIGHT is similar for the right fringe, and OV is non-nil if there is an +overlay arrow in the left fringe. +Return nil if POS is not visible in WINDOW. */) (pos, window) Lisp_Object pos, window; { struct window *w; - struct buffer *old_buffer = NULL; struct glyph_row *row; int textpos; @@ -1274,8 +1404,9 @@ resp. Return nil if POS is not visible in WINDOW. */) row = MATRIX_FIRST_TEXT_ROW (w->current_matrix); row = row_containing_pos (w, textpos, row, NULL, 0); if (row) - return Fcons (make_number (row->left_fringe_bitmap), - make_number (row->right_fringe_bitmap)); + return list3 (get_fringe_bitmap_name (row->left_fringe_bitmap), + get_fringe_bitmap_name (row->right_fringe_bitmap), + (row->overlay_arrow_p ? Qt : Qnil)); else return Qnil; } @@ -1288,7 +1419,6 @@ resp. Return nil if POS is not visible in WINDOW. */) void syms_of_fringe () { - defsubr (&Sdestroy_fringe_bitmap); defsubr (&Sdefine_fringe_bitmap); defsubr (&Sfringe_bitmaps_at_pos); @@ -1303,6 +1433,22 @@ is at the final newline, the cursor is shown in the right fringe. If nil, also continue lines which are exactly as wide as the window. */); Voverflow_newline_into_fringe = Qt; + DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps, + doc: /* List of fringe bitmap symbols. +You must (require 'fringe) to use fringe bitmap symbols in your programs." */); + 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. */ @@ -1321,9 +1467,18 @@ init_fringe () { int i; - bzero (fringe_bitmaps, sizeof fringe_bitmaps); - for (i = 0; i < MAX_FRINGE_BITMAPS; i++) - fringe_faces[i] = FRINGE_FACE_ID; + 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)); + + for (i = 0; i < max_fringe_bitmaps; i++) + { + fringe_bitmaps[i] = NULL; + fringe_faces[i] = Qnil; + } } #ifdef HAVE_NTGUI @@ -1333,6 +1488,9 @@ w32_init_fringe () { enum fringe_bitmap_type bt; + if (!rif) + return; + for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++) { struct fringe_bitmap *fb = &standard_bitmaps[bt]; @@ -1346,6 +1504,9 @@ w32_reset_fringes () /* Destroy row bitmaps. */ int bt; + if (!rif) + return; + for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++) rif->destroy_fringe_bitmap (bt); }