1 /* Fringe handling (split from xdisp.c).
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997,
3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
28 #include "dispextern.h"
30 #include "blockinput.h"
31 #include "termhooks.h"
33 #ifdef HAVE_WINDOW_SYSTEM
35 extern Lisp_Object Qfringe
;
36 extern Lisp_Object Qtop
, Qbottom
, Qcenter
;
37 extern Lisp_Object Qup
, Qdown
, Qleft
, Qright
;
39 /* Non-nil means that newline may flow into the right fringe. */
41 Lisp_Object Voverflow_newline_into_fringe
;
43 /* List of known fringe bitmap symbols.
45 The fringe bitmap number is stored in the `fringe' property on
46 those symbols. Names for the built-in bitmaps are installed by
50 Lisp_Object Vfringe_bitmaps
;
52 /* Fringe bitmaps are represented in three different ways:
54 Logical bitmaps are used internally to denote things like
55 'end-of-buffer', 'left-truncation', 'overlay-arrow', etc.
57 Physical bitmaps specify the visual appearence of the bitmap,
58 e.g. 'bottom-left-angle', 'left-arrow', 'left-triangle', etc.
59 User defined bitmaps are physical bitmaps.
61 Internally, fringe bitmaps for a specific display row are
62 represented as a simple integer that is used as an index
63 into the table of all defined bitmaps. This index is stored
64 in the `fringe' property of the physical bitmap symbol.
66 Logical bitmaps are mapped to physical bitmaps through the
67 buffer-local `fringe-indicator-alist' variable.
69 Each element of this alist is a cons (LOGICAL . PHYSICAL)
70 mapping a logical bitmap to a physical bitmap.
71 PHYSICAL is either a symbol to use in both left and right fringe,
72 or a cons of two symbols (LEFT . RIGHT) denoting different
73 bitmaps to use in left and right fringe.
75 LOGICAL is first looked up in the window's buffer's buffer-local
76 value of the fringe-indicator-alist variable, and if not present,
77 in the global value of fringe-indicator-alist.
79 If LOGICAL is not present in either alist, or the PHYSICAL value
80 found is nil, no bitmap is shown for the logical bitmap.
82 The `left-fringe' and `right-fringe' display properties
83 must specify physical bitmap symbols.
86 extern Lisp_Object Qunknown
;
87 Lisp_Object Qtruncation
, Qcontinuation
, Qoverlay_arrow
;
88 Lisp_Object Qempty_line
, Qtop_bottom
;
89 extern Lisp_Object Qbar
, Qhbar
, Qbox
, Qhollow
;
90 Lisp_Object Qhollow_small
;
92 enum fringe_bitmap_align
94 ALIGN_BITMAP_CENTER
= 0,
101 unsigned short *bits
;
106 unsigned dynamic
: 1;
110 /***********************************************************************
112 ***********************************************************************/
114 /* Undefined bitmap. A question mark. */
127 static unsigned short question_mark_bits
[] = {
128 0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
130 /* An arrow like this: `<-'. */
141 static unsigned short left_arrow_bits
[] = {
142 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
145 /* Right truncation arrow bitmap `->'. */
156 static unsigned short right_arrow_bits
[] = {
157 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
160 /* Up arrow bitmap. */
171 static unsigned short up_arrow_bits
[] = {
172 0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
175 /* Down arrow bitmap. */
186 static unsigned short down_arrow_bits
[] = {
187 0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
189 /* Marker for continuation lines. */
200 static unsigned short left_curly_arrow_bits
[] = {
201 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
203 /* Marker for continued lines. */
214 static unsigned short right_curly_arrow_bits
[] = {
215 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
217 /* Reverse Overlay arrow bitmap. A triangular arrow. */
228 static unsigned short left_triangle_bits
[] = {
229 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
231 /* Overlay arrow bitmap. A triangular arrow. */
242 static unsigned short right_triangle_bits
[] = {
243 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
245 /* First line bitmap. An top-left angle. */
256 static unsigned short top_left_angle_bits
[] = {
257 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00};
259 /* First line bitmap. An right-up angle. */
270 static unsigned short top_right_angle_bits
[] = {
271 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
273 /* Last line bitmap. An left-down angle. */
284 static unsigned short bottom_left_angle_bits
[] = {
285 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
287 /* Last line bitmap. An right-down angle. */
298 static unsigned short bottom_right_angle_bits
[] = {
299 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
301 /* First/last line bitmap. An left bracket. */
314 static unsigned short left_bracket_bits
[] = {
315 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
317 /* First/last line bitmap. An right bracket. */
330 static unsigned short right_bracket_bits
[] = {
331 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
333 /* Filled box cursor bitmap. A filled box; max 13 pixels high. */
349 static unsigned short filled_rectangle_bits
[] = {
350 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
352 /* Hollow box cursor bitmap. A hollow box; max 13 pixels high. */
368 static unsigned short hollow_rectangle_bits
[] = {
369 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe};
371 /* Hollow square bitmap. */
380 static unsigned short hollow_square_bits
[] = {
381 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
383 /* Filled square bitmap. */
392 static unsigned short filled_square_bits
[] = {
393 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e};
395 /* Bar cursor bitmap. A vertical bar; max 13 pixels high. */
411 static unsigned short vertical_bar_bits
[] = {
412 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
414 /* HBar cursor bitmap. A horizontal bar; 2 pixels high. */
419 static unsigned short horizontal_bar_bits
[] = {
423 /* Bitmap drawn to indicate lines not displaying text if
424 `indicate-empty-lines' is non-nil. */
433 static unsigned short empty_line_bits
[] = {
434 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
435 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
436 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
437 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
438 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
439 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
440 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
441 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
444 #define BYTES_PER_BITMAP_ROW (sizeof (unsigned short))
445 #define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
446 #define FRBITS(bits) bits, STANDARD_BITMAP_HEIGHT (bits)
448 /* NOTE: The order of these bitmaps must match the sequence
449 used in fringe.el to define the corresponding symbols. */
451 struct fringe_bitmap standard_bitmaps
[] =
453 { NULL
, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */
454 { FRBITS (question_mark_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
455 { FRBITS (left_arrow_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
456 { FRBITS (right_arrow_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
457 { FRBITS (up_arrow_bits
), 8, 0, ALIGN_BITMAP_TOP
, 0 },
458 { FRBITS (down_arrow_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
459 { FRBITS (left_curly_arrow_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
460 { FRBITS (right_curly_arrow_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
461 { FRBITS (left_triangle_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
462 { FRBITS (right_triangle_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
463 { FRBITS (top_left_angle_bits
), 8, 0, ALIGN_BITMAP_TOP
, 0 },
464 { FRBITS (top_right_angle_bits
), 8, 0, ALIGN_BITMAP_TOP
, 0 },
465 { FRBITS (bottom_left_angle_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
466 { FRBITS (bottom_right_angle_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
467 { FRBITS (left_bracket_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
468 { FRBITS (right_bracket_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
469 { FRBITS (filled_rectangle_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
470 { FRBITS (hollow_rectangle_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
471 { FRBITS (filled_square_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
472 { FRBITS (hollow_square_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
473 { FRBITS (vertical_bar_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
474 { FRBITS (horizontal_bar_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
475 { FRBITS (empty_line_bits
), 8, 3, ALIGN_BITMAP_TOP
, 0 },
478 #define NO_FRINGE_BITMAP 0
479 #define UNDEF_FRINGE_BITMAP 1
480 #define MAX_STANDARD_FRINGE_BITMAPS (sizeof(standard_bitmaps)/sizeof(standard_bitmaps[0]))
482 static struct fringe_bitmap
**fringe_bitmaps
;
483 static Lisp_Object
*fringe_faces
;
484 static int max_fringe_bitmaps
;
486 int max_used_fringe_bitmap
= MAX_STANDARD_FRINGE_BITMAPS
;
489 /* Lookup bitmap number for symbol BITMAP.
490 Return 0 if not a bitmap. */
493 lookup_fringe_bitmap (Lisp_Object bitmap
)
497 bitmap
= Fget (bitmap
, Qfringe
);
498 if (!INTEGERP (bitmap
))
502 if (bn
> NO_FRINGE_BITMAP
503 && bn
< max_used_fringe_bitmap
504 && (bn
< MAX_STANDARD_FRINGE_BITMAPS
505 || fringe_bitmaps
[bn
] != NULL
))
511 /* Get fringe bitmap name for bitmap number BN.
513 Found by traversing Vfringe_bitmaps comparing BN to the
514 fringe property for each symbol.
516 Return BN if not found in Vfringe_bitmaps. */
519 get_fringe_bitmap_name (int bn
)
524 /* Zero means no bitmap -- return nil. */
528 bitmaps
= Vfringe_bitmaps
;
529 num
= make_number (bn
);
531 while (CONSP (bitmaps
))
533 Lisp_Object bitmap
= XCAR (bitmaps
);
534 if (EQ (num
, Fget (bitmap
, Qfringe
)))
536 bitmaps
= XCDR (bitmaps
);
543 /* Draw the bitmap WHICH in one of the left or right fringes of
544 window W. ROW is the glyph row for which to display the bitmap; it
545 determines the vertical position at which the bitmap has to be
547 LEFT_P is 1 for left fringe, 0 for right fringe.
551 draw_fringe_bitmap_1 (struct window
*w
, struct glyph_row
*row
, int left_p
, int overlay
, int which
)
553 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
554 struct draw_fringe_bitmap_params p
;
555 struct fringe_bitmap
*fb
;
557 int face_id
= DEFAULT_FACE_ID
;
560 p
.overlay_p
= (overlay
& 1) == 1;
561 p
.cursor_p
= (overlay
& 2) == 2;
563 if (which
!= NO_FRINGE_BITMAP
)
568 which
= row
->left_fringe_bitmap
;
569 face_id
= row
->left_fringe_face_id
;
573 which
= row
->right_fringe_bitmap
;
574 face_id
= row
->right_fringe_face_id
;
577 if (face_id
== DEFAULT_FACE_ID
)
579 Lisp_Object face
= fringe_faces
[which
];
580 face_id
= NILP (face
) ? lookup_named_face (f
, Qfringe
, 0)
581 : lookup_derived_face (f
, face
, FRINGE_FACE_ID
, 0);
583 face_id
= FRINGE_FACE_ID
;
586 fb
= fringe_bitmaps
[which
];
588 fb
= &standard_bitmaps
[which
< MAX_STANDARD_FRINGE_BITMAPS
589 ? which
: UNDEF_FRINGE_BITMAP
];
593 /* Convert row to frame coordinates. */
594 p
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
601 p
.dh
= (period
> 0 ? (p
.y
% period
) : 0);
603 /* Clip bitmap if too high. */
604 if (p
.h
> row
->height
)
607 p
.face
= FACE_FROM_ID (f
, face_id
);
611 /* This could happen after clearing face cache.
612 But it shouldn't happen anymore. ++kfs */
616 PREPARE_FACE_FOR_DISPLAY (f
, p
.face
);
618 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
623 int wd
= WINDOW_LEFT_FRINGE_WIDTH (w
);
624 int x
= window_box_left (w
, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
629 p
.x
= x
- p
.wd
- (wd
- p
.wd
) / 2;
631 if (p
.wd
< wd
|| row
->height
> p
.h
)
633 /* If W has a vertical border to its left, don't draw over it. */
634 wd
-= ((!WINDOW_LEFTMOST_P (w
)
635 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
643 int x
= window_box_right (w
,
644 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
647 int wd
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
650 p
.x
= x
+ (wd
- p
.wd
) / 2;
651 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
653 if (p
.wd
< wd
|| row
->height
> p
.h
)
662 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
664 p
.by
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, row
->y
));
665 p
.ny
= row
->visible_height
;
668 /* Adjust y to the offset in the row to start drawing the bitmap. */
671 case ALIGN_BITMAP_CENTER
:
672 p
.y
+= (row
->height
- p
.h
) / 2;
674 case ALIGN_BITMAP_BOTTOM
:
676 p
.y
+= (row
->visible_height
- p
.h
);
678 case ALIGN_BITMAP_TOP
:
682 FRAME_RIF (f
)->draw_fringe_bitmap (w
, row
, &p
);
686 get_logical_cursor_bitmap (struct window
*w
, Lisp_Object cursor
)
688 Lisp_Object cmap
, bm
= Qnil
;
690 if ((cmap
= XBUFFER (w
->buffer
)->fringe_cursor_alist
), !NILP (cmap
))
692 bm
= Fassq (cursor
, cmap
);
695 if ((bm
= XCDR (bm
)), NILP (bm
))
696 return NO_FRINGE_BITMAP
;
697 return lookup_fringe_bitmap (bm
);
700 if (EQ (cmap
, buffer_defaults
.fringe_cursor_alist
))
701 return NO_FRINGE_BITMAP
;
702 bm
= Fassq (cursor
, buffer_defaults
.fringe_cursor_alist
);
703 if (!CONSP (bm
) || ((bm
= XCDR (bm
)), NILP (bm
)))
704 return NO_FRINGE_BITMAP
;
705 return lookup_fringe_bitmap (bm
);
709 get_logical_fringe_bitmap (struct window
*w
, Lisp_Object bitmap
, int right_p
, int partial_p
)
711 Lisp_Object cmap
, bm1
= Qnil
, bm2
= Qnil
, bm
;
712 int ln1
= 0, ln2
= 0;
714 int ix2
= ix1
+ (partial_p
? 2 : 0);
716 /* Lookup in buffer-local fringe-indicator-alist before global alist.
719 BITMAP -- use for all
720 (L R) -- use for left right (whether partial or not)
721 (L R PL PR) -- use for left right partial-left partial-right
722 If any value in local binding is not present or t, use global value.
724 If partial, lookup partial bitmap in default value if not found here.
725 If not partial, or no partial spec is present, use non-partial bitmap. */
727 if ((cmap
= XBUFFER (w
->buffer
)->fringe_indicator_alist
), !NILP (cmap
))
729 bm1
= Fassq (bitmap
, cmap
);
732 if ((bm1
= XCDR (bm1
)), NILP (bm1
))
733 return NO_FRINGE_BITMAP
;
736 ln1
= XINT (Flength (bm1
));
741 bm
= Fnth (make_number (ix2
), bm1
);
750 bm
= Fnth (make_number (ix1
), bm1
);
756 else if ((bm
= bm1
, !EQ (bm
, Qt
)))
761 if (!EQ (cmap
, buffer_defaults
.fringe_indicator_alist
)
762 && !NILP (buffer_defaults
.fringe_indicator_alist
))
764 bm2
= Fassq (bitmap
, buffer_defaults
.fringe_indicator_alist
);
767 if ((bm2
= XCDR (bm2
)), !NILP (bm2
))
771 ln2
= XINT (Flength (bm2
));
776 bm
= Fnth (make_number (ix2
), bm2
);
788 bm
= Fnth (make_number (ix1
), bm1
);
795 bm
= Fnth (make_number (ix1
), bm2
);
798 return NO_FRINGE_BITMAP
;
800 else if ((bm
= bm2
, NILP (bm
)))
801 return NO_FRINGE_BITMAP
;
804 return lookup_fringe_bitmap (bm
);
809 draw_fringe_bitmap (struct window
*w
, struct glyph_row
*row
, int left_p
)
813 if (left_p
== row
->reversed_p
&& row
->cursor_in_fringe_p
)
815 Lisp_Object cursor
= Qnil
;
817 switch (w
->phys_cursor_type
)
819 case HOLLOW_BOX_CURSOR
:
820 if (row
->visible_height
>= STANDARD_BITMAP_HEIGHT (hollow_rectangle_bits
))
823 cursor
= Qhollow_small
;
825 case FILLED_BOX_CURSOR
:
836 w
->phys_cursor_on_p
= 0;
837 row
->cursor_in_fringe_p
= 0;
842 int bm
= get_logical_cursor_bitmap (w
, cursor
);
843 if (bm
!= NO_FRINGE_BITMAP
)
845 draw_fringe_bitmap_1 (w
, row
, left_p
, 2, bm
);
846 overlay
= EQ (cursor
, Qbox
) ? 3 : 1;
851 draw_fringe_bitmap_1 (w
, row
, left_p
, overlay
, NO_FRINGE_BITMAP
);
853 if (left_p
&& row
->overlay_arrow_bitmap
!= NO_FRINGE_BITMAP
)
854 draw_fringe_bitmap_1 (w
, row
, 1, 1, row
->overlay_arrow_bitmap
);
858 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
859 function with input blocked. */
862 draw_row_fringe_bitmaps (struct window
*w
, struct glyph_row
*row
)
864 xassert (interrupt_input_blocked
);
866 /* If row is completely invisible, because of vscrolling, we
867 don't have to draw anything. */
868 if (row
->visible_height
<= 0)
871 if (WINDOW_LEFT_FRINGE_WIDTH (w
) != 0)
872 draw_fringe_bitmap (w
, row
, 1);
874 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) != 0)
875 draw_fringe_bitmap (w
, row
, 0);
878 /* Draw the fringes of window W. Only fringes for rows marked for
879 update in redraw_fringe_bitmaps_p are drawn.
881 Return >0 if left or right fringe was redrawn in any way.
883 If NO_FRINGE is non-zero, also return >0 if either fringe has zero width.
885 A return value >0 indicates that the vertical line between windows
886 needs update (as it may be drawn in the fringe).
890 draw_window_fringes (struct window
*w
, int no_fringe
)
892 struct glyph_row
*row
;
893 int yb
= window_text_bottom_y (w
);
894 int nrows
= w
->current_matrix
->nrows
;
898 if (w
->pseudo_window_p
)
901 /* Must draw line if no fringe */
903 && (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0
904 || WINDOW_RIGHT_FRINGE_WIDTH (w
) == 0))
907 for (y
= 0, rn
= 0, row
= w
->current_matrix
->rows
;
908 y
< yb
&& rn
< nrows
;
909 y
+= row
->height
, ++row
, ++rn
)
911 if (!row
->redraw_fringe_bitmaps_p
)
913 draw_row_fringe_bitmaps (w
, row
);
914 row
->redraw_fringe_bitmaps_p
= 0;
922 /* Recalculate the bitmaps to show in the fringes of window W.
923 Only mark rows with modified bitmaps for update in redraw_fringe_bitmaps_p.
925 If KEEP_CURRENT_P is 0, update current_matrix too. */
928 update_window_fringes (struct window
*w
, int keep_current_p
)
930 struct glyph_row
*row
, *cur
= 0;
931 int yb
= window_text_bottom_y (w
);
932 int rn
, nrows
= w
->current_matrix
->nrows
;
935 Lisp_Object boundary_top
= Qnil
, boundary_bot
= Qnil
;
936 Lisp_Object arrow_top
= Qnil
, arrow_bot
= Qnil
;
937 Lisp_Object empty_pos
;
938 Lisp_Object ind
= Qnil
;
939 #define MAX_BITMAP_CACHE (8*4)
940 int bitmap_cache
[MAX_BITMAP_CACHE
];
942 if (w
->pseudo_window_p
)
945 if (!MINI_WINDOW_P (w
)
946 && (ind
= XBUFFER (w
->buffer
)->indicate_buffer_boundaries
, !NILP (ind
)))
948 if (EQ (ind
, Qleft
) || EQ (ind
, Qright
))
949 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= ind
;
950 else if (CONSP (ind
) && CONSP (XCAR (ind
)))
953 if (pos
= Fassq (Qt
, ind
), !NILP (pos
))
954 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= XCDR (pos
);
955 if (pos
= Fassq (Qtop
, ind
), !NILP (pos
))
956 boundary_top
= XCDR (pos
);
957 if (pos
= Fassq (Qbottom
, ind
), !NILP (pos
))
958 boundary_bot
= XCDR (pos
);
959 if (pos
= Fassq (Qup
, ind
), !NILP (pos
))
960 arrow_top
= XCDR (pos
);
961 if (pos
= Fassq (Qdown
, ind
), !NILP (pos
))
962 arrow_bot
= XCDR (pos
);
965 /* Anything else means boundary on left and no arrows. */
966 boundary_top
= boundary_bot
= Qleft
;
971 int done_top
= 0, done_bot
= 0;
974 y
< yb
&& rn
< nrows
;
975 y
+= row
->height
, ++rn
)
977 unsigned indicate_bob_p
, indicate_top_line_p
;
978 unsigned indicate_eob_p
, indicate_bottom_line_p
;
980 row
= w
->desired_matrix
->rows
+ rn
;
982 row
= w
->current_matrix
->rows
+ rn
;
984 indicate_bob_p
= row
->indicate_bob_p
;
985 indicate_top_line_p
= row
->indicate_top_line_p
;
986 indicate_eob_p
= row
->indicate_eob_p
;
987 indicate_bottom_line_p
= row
->indicate_bottom_line_p
;
989 row
->indicate_bob_p
= row
->indicate_top_line_p
= 0;
990 row
->indicate_eob_p
= row
->indicate_bottom_line_p
= 0;
992 if (!row
->mode_line_p
)
996 if (MATRIX_ROW_START_CHARPOS (row
) <= BUF_BEGV (XBUFFER (w
->buffer
))
997 && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w
, row
))
998 row
->indicate_bob_p
= !NILP (boundary_top
);
1000 row
->indicate_top_line_p
= !NILP (arrow_top
);
1006 if (MATRIX_ROW_END_CHARPOS (row
) >= BUF_ZV (XBUFFER (w
->buffer
))
1007 && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w
, row
))
1008 row
->indicate_eob_p
= !NILP (boundary_bot
), done_bot
= 1;
1009 else if (y
+ row
->height
>= yb
)
1010 row
->indicate_bottom_line_p
= !NILP (arrow_bot
), done_bot
= 1;
1014 if (indicate_bob_p
!= row
->indicate_bob_p
1015 || indicate_top_line_p
!= row
->indicate_top_line_p
1016 || indicate_eob_p
!= row
->indicate_eob_p
1017 || indicate_bottom_line_p
!= row
->indicate_bottom_line_p
)
1018 row
->redraw_fringe_bitmaps_p
= 1;
1022 empty_pos
= XBUFFER (w
->buffer
)->indicate_empty_lines
;
1023 if (!NILP (empty_pos
) && !EQ (empty_pos
, Qright
))
1024 empty_pos
= WINDOW_LEFT_FRINGE_WIDTH (w
) == 0 ? Qright
: Qleft
;
1026 for (y
= 0; y
< MAX_BITMAP_CACHE
; y
++)
1027 bitmap_cache
[y
] = -1;
1029 #define LEFT_FRINGE(cache, which, partial_p) \
1030 (bitmap_cache[cache*4+partial_p] >= 0 \
1031 ? bitmap_cache[cache*4+partial_p] \
1032 : (bitmap_cache[cache*4+partial_p] = \
1033 get_logical_fringe_bitmap (w, which, 0, partial_p)))
1035 #define RIGHT_FRINGE(cache, which, partial_p) \
1036 (bitmap_cache[cache*4+2+partial_p] >= 0 \
1037 ? bitmap_cache[cache*4+2+partial_p] \
1038 : (bitmap_cache[cache*4+2+partial_p] = \
1039 get_logical_fringe_bitmap (w, which, 1, partial_p)))
1043 y
< yb
&& rn
< nrows
;
1044 y
+= row
->height
, rn
++)
1047 unsigned left_face_id
, right_face_id
;
1049 row
= w
->desired_matrix
->rows
+ rn
;
1050 cur
= w
->current_matrix
->rows
+ rn
;
1051 if (!row
->enabled_p
)
1054 left_face_id
= right_face_id
= DEFAULT_FACE_ID
;
1056 /* Decide which bitmap to draw in the left fringe. */
1057 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
1058 left
= NO_FRINGE_BITMAP
;
1059 else if (row
->left_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
1061 left
= row
->left_user_fringe_bitmap
;
1062 left_face_id
= row
->left_user_fringe_face_id
;
1064 else if ((!row
->reversed_p
&& row
->truncated_on_left_p
)
1065 || (row
->reversed_p
&& row
->truncated_on_right_p
))
1066 left
= LEFT_FRINGE(0, Qtruncation
, 0);
1067 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qleft
))
1068 left
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
1069 ? LEFT_FRINGE (1, Qtop_bottom
, row
->ends_at_zv_p
)
1070 : LEFT_FRINGE (2, Qtop
, 0));
1071 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
1072 left
= LEFT_FRINGE (3, Qbottom
, row
->ends_at_zv_p
);
1073 else if ((!row
->reversed_p
&& MATRIX_ROW_CONTINUATION_LINE_P (row
))
1074 || (row
->reversed_p
&& row
->continued_p
))
1075 left
= LEFT_FRINGE (4, Qcontinuation
, 0);
1076 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qleft
))
1077 left
= LEFT_FRINGE (5, Qempty_line
, 0);
1078 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qleft
))
1079 left
= LEFT_FRINGE (6, Qup
, 0);
1080 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qleft
))
1081 left
= LEFT_FRINGE (7, Qdown
, 0);
1083 left
= NO_FRINGE_BITMAP
;
1085 /* Decide which bitmap to draw in the right fringe. */
1086 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) == 0)
1087 right
= NO_FRINGE_BITMAP
;
1088 else if (row
->right_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
1090 right
= row
->right_user_fringe_bitmap
;
1091 right_face_id
= row
->right_user_fringe_face_id
;
1093 else if ((!row
->reversed_p
&& row
->truncated_on_right_p
)
1094 || (row
->reversed_p
&& row
->truncated_on_left_p
))
1095 right
= RIGHT_FRINGE (0, Qtruncation
, 0);
1096 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qright
))
1097 right
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
1098 ? RIGHT_FRINGE (1, Qtop_bottom
, row
->ends_at_zv_p
)
1099 : RIGHT_FRINGE (2, Qtop
, 0));
1100 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
1101 right
= RIGHT_FRINGE (3, Qbottom
, row
->ends_at_zv_p
);
1102 else if ((!row
->reversed_p
&& row
->continued_p
)
1103 || (row
->reversed_p
&& MATRIX_ROW_CONTINUATION_LINE_P (row
)))
1104 right
= RIGHT_FRINGE (4, Qcontinuation
, 0);
1105 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qright
))
1106 right
= RIGHT_FRINGE (6, Qup
, 0);
1107 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qright
))
1108 right
= RIGHT_FRINGE (7, Qdown
, 0);
1109 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qright
))
1110 right
= RIGHT_FRINGE (5, Qempty_line
, 0);
1112 right
= NO_FRINGE_BITMAP
;
1114 if (row
->y
!= cur
->y
1115 || row
->visible_height
!= cur
->visible_height
1116 || row
->ends_at_zv_p
!= cur
->ends_at_zv_p
1117 || left
!= cur
->left_fringe_bitmap
1118 || right
!= cur
->right_fringe_bitmap
1119 || left_face_id
!= cur
->left_fringe_face_id
1120 || right_face_id
!= cur
->right_fringe_face_id
1121 || cur
->redraw_fringe_bitmaps_p
)
1123 redraw_p
= row
->redraw_fringe_bitmaps_p
= 1;
1124 if (!keep_current_p
)
1126 cur
->redraw_fringe_bitmaps_p
= 1;
1127 cur
->left_fringe_bitmap
= left
;
1128 cur
->right_fringe_bitmap
= right
;
1129 cur
->left_fringe_face_id
= left_face_id
;
1130 cur
->right_fringe_face_id
= right_face_id
;
1134 if (row
->overlay_arrow_bitmap
< 0)
1135 row
->overlay_arrow_bitmap
= get_logical_fringe_bitmap (w
, Qoverlay_arrow
, 0, 0);
1137 if (row
->overlay_arrow_bitmap
!= cur
->overlay_arrow_bitmap
)
1139 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
1140 cur
->overlay_arrow_bitmap
= row
->overlay_arrow_bitmap
;
1143 row
->left_fringe_bitmap
= left
;
1144 row
->right_fringe_bitmap
= right
;
1145 row
->left_fringe_face_id
= left_face_id
;
1146 row
->right_fringe_face_id
= right_face_id
;
1148 if (rn
> 0 && row
->redraw_fringe_bitmaps_p
)
1149 row
[-1].redraw_fringe_bitmaps_p
= cur
[-1].redraw_fringe_bitmaps_p
= 1;
1152 return redraw_p
&& !keep_current_p
;
1156 /* Compute actual fringe widths for frame F.
1158 If REDRAW is 1, redraw F if the fringe settings was actually
1159 modified and F is visible.
1161 Since the combined left and right fringe must occupy an integral
1162 number of columns, we may need to add some pixels to each fringe.
1163 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
1164 but a negative width value is taken literally (after negating it).
1166 We never make the fringes narrower than specified.
1170 compute_fringe_widths (struct frame
*f
, int redraw
)
1172 int o_left
= FRAME_LEFT_FRINGE_WIDTH (f
);
1173 int o_right
= FRAME_RIGHT_FRINGE_WIDTH (f
);
1174 int o_cols
= FRAME_FRINGE_COLS (f
);
1176 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
1177 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
1178 int left_fringe_width
, right_fringe_width
;
1180 if (!NILP (left_fringe
))
1181 left_fringe
= Fcdr (left_fringe
);
1182 if (!NILP (right_fringe
))
1183 right_fringe
= Fcdr (right_fringe
);
1185 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
1186 XINT (left_fringe
));
1187 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
1188 XINT (right_fringe
));
1190 if (left_fringe_width
|| right_fringe_width
)
1192 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
1193 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
1194 int conf_wid
= left_wid
+ right_wid
;
1195 int font_wid
= FRAME_COLUMN_WIDTH (f
);
1196 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
1197 int real_wid
= cols
* font_wid
;
1198 if (left_wid
&& right_wid
)
1200 if (left_fringe_width
< 0)
1202 /* Left fringe width is fixed, adjust right fringe if necessary */
1203 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
;
1204 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
- left_wid
;
1206 else if (right_fringe_width
< 0)
1208 /* Right fringe width is fixed, adjust left fringe if necessary */
1209 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
- right_wid
;
1210 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
;
1214 /* Adjust both fringes with an equal amount.
1215 Note that we are doing integer arithmetic here, so don't
1216 lose a pixel if the total width is an odd number. */
1217 int fill
= real_wid
- conf_wid
;
1218 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
+ fill
/2;
1219 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
+ fill
- fill
/2;
1222 else if (left_fringe_width
)
1224 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
;
1225 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1229 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1230 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
;
1232 FRAME_FRINGE_COLS (f
) = cols
;
1236 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1237 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1238 FRAME_FRINGE_COLS (f
) = 0;
1241 if (redraw
&& FRAME_VISIBLE_P (f
))
1242 if (o_left
!= FRAME_LEFT_FRINGE_WIDTH (f
) ||
1243 o_right
!= FRAME_RIGHT_FRINGE_WIDTH (f
) ||
1244 o_cols
!= FRAME_FRINGE_COLS (f
))
1249 /* Free resources used by a user-defined bitmap. */
1252 destroy_fringe_bitmap (int n
)
1254 struct fringe_bitmap
**fbp
;
1256 fringe_faces
[n
] = Qnil
;
1258 fbp
= &fringe_bitmaps
[n
];
1259 if (*fbp
&& (*fbp
)->dynamic
)
1261 /* XXX Is SELECTED_FRAME OK here? */
1262 struct redisplay_interface
*rif
= FRAME_RIF (SELECTED_FRAME ());
1263 if (rif
&& rif
->destroy_fringe_bitmap
)
1264 rif
->destroy_fringe_bitmap (n
);
1269 while (max_used_fringe_bitmap
> MAX_STANDARD_FRINGE_BITMAPS
1270 && fringe_bitmaps
[max_used_fringe_bitmap
- 1] == NULL
)
1271 max_used_fringe_bitmap
--;
1275 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap
, Sdestroy_fringe_bitmap
,
1277 doc
: /* Destroy fringe bitmap BITMAP.
1278 If BITMAP overrides a standard fringe bitmap, the original bitmap is restored. */)
1284 CHECK_SYMBOL (bitmap
);
1285 n
= lookup_fringe_bitmap (bitmap
);
1289 destroy_fringe_bitmap (n
);
1291 if (n
>= MAX_STANDARD_FRINGE_BITMAPS
)
1293 Vfringe_bitmaps
= Fdelq (bitmap
, Vfringe_bitmaps
);
1294 /* It would be better to remove the fringe property. */
1295 Fput (bitmap
, Qfringe
, Qnil
);
1302 /* Initialize bitmap bit.
1304 On X, we bit-swap the built-in bitmaps and reduce bitmap
1305 from short to char array if width is <= 8 bits.
1307 On MAC with big-endian CPU, we need to byte-swap each short.
1309 On W32 and MAC (little endian), there's no need to do this.
1312 #if defined (HAVE_X_WINDOWS)
1313 static const unsigned char swap_nibble
[16] = {
1314 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1315 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1316 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1317 0x3, 0xb, 0x7, 0xf}; /* 0011 1011 0111 1111 */
1318 #endif /* HAVE_X_WINDOWS */
1321 init_fringe_bitmap (int which
, struct fringe_bitmap
*fb
, int once_p
)
1323 if (once_p
|| fb
->dynamic
)
1325 #if defined (HAVE_X_WINDOWS)
1326 unsigned short *bits
= fb
->bits
;
1331 unsigned char *cbits
= (unsigned char *)fb
->bits
;
1332 for (j
= 0; j
< fb
->height
; j
++)
1334 unsigned short b
= *bits
++;
1336 c
= (unsigned char)((swap_nibble
[b
& 0xf] << 4)
1337 | (swap_nibble
[(b
>>4) & 0xf]));
1338 *cbits
++ = (c
>> (8 - fb
->width
));
1343 for (j
= 0; j
< fb
->height
; j
++)
1345 unsigned short b
= *bits
;
1346 b
= (unsigned short)((swap_nibble
[b
& 0xf] << 12)
1347 | (swap_nibble
[(b
>>4) & 0xf] << 8)
1348 | (swap_nibble
[(b
>>8) & 0xf] << 4)
1349 | (swap_nibble
[(b
>>12) & 0xf]));
1350 b
>>= (16 - fb
->width
);
1351 #ifdef WORDS_BIG_ENDIAN
1352 b
= ((b
>> 8) | (b
<< 8));
1357 #endif /* HAVE_X_WINDOWS */
1363 /* XXX Is SELECTED_FRAME OK here? */
1364 struct redisplay_interface
*rif
= FRAME_RIF (SELECTED_FRAME ());
1366 destroy_fringe_bitmap (which
);
1368 if (rif
&& rif
->define_fringe_bitmap
)
1369 rif
->define_fringe_bitmap (which
, fb
->bits
, fb
->height
, fb
->width
);
1371 fringe_bitmaps
[which
] = fb
;
1372 if (which
>= max_used_fringe_bitmap
)
1373 max_used_fringe_bitmap
= which
+ 1;
1378 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap
, Sdefine_fringe_bitmap
,
1380 doc
: /* Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH.
1381 BITMAP is a symbol identifying the new fringe bitmap.
1382 BITS is either a string or a vector of integers.
1383 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1384 WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1385 Optional fifth arg ALIGN may be one of `top', `center', or `bottom',
1386 indicating the positioning of the bitmap relative to the rows where it
1387 is used; the default is to center the bitmap. Fifth arg may also be a
1388 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1390 If BITMAP already exists, the existing definition is replaced. */)
1391 (bitmap
, bits
, height
, width
, align
)
1392 Lisp_Object bitmap
, bits
, height
, width
, align
;
1396 struct fringe_bitmap fb
, *xfb
;
1397 int fill1
= 0, fill2
= 0;
1399 CHECK_SYMBOL (bitmap
);
1403 else if (VECTORP (bits
))
1404 h
= XVECTOR (bits
)->size
;
1406 wrong_type_argument (Qsequencep
, bits
);
1412 CHECK_NUMBER (height
);
1413 fb
.height
= min (XINT (height
), 255);
1416 fill1
= (fb
.height
- h
) / 2;
1417 fill2
= fb
.height
- h
- fill1
;
1425 CHECK_NUMBER (width
);
1426 fb
.width
= min (XINT (width
), 255);
1430 fb
.align
= ALIGN_BITMAP_CENTER
;
1434 Lisp_Object period
= XCDR (align
);
1437 period
= XCAR (period
);
1440 fb
.period
= fb
.height
;
1444 align
= XCAR (align
);
1446 if (EQ (align
, Qtop
))
1447 fb
.align
= ALIGN_BITMAP_TOP
;
1448 else if (EQ (align
, Qbottom
))
1449 fb
.align
= ALIGN_BITMAP_BOTTOM
;
1450 else if (!NILP (align
) && !EQ (align
, Qcenter
))
1451 error ("Bad align argument");
1453 n
= lookup_fringe_bitmap (bitmap
);
1456 if (max_used_fringe_bitmap
< max_fringe_bitmaps
)
1457 n
= max_used_fringe_bitmap
++;
1460 for (n
= MAX_STANDARD_FRINGE_BITMAPS
;
1461 n
< max_fringe_bitmaps
;
1463 if (fringe_bitmaps
[n
] == NULL
)
1466 if (n
== max_fringe_bitmaps
)
1468 if ((max_fringe_bitmaps
+ 20) > MAX_FRINGE_BITMAPS
)
1469 error ("No free fringe bitmap slots");
1471 i
= max_fringe_bitmaps
;
1472 max_fringe_bitmaps
+= 20;
1474 = ((struct fringe_bitmap
**)
1475 xrealloc (fringe_bitmaps
, max_fringe_bitmaps
* sizeof (struct fringe_bitmap
*)));
1477 = (Lisp_Object
*) xrealloc (fringe_faces
, max_fringe_bitmaps
* sizeof (Lisp_Object
));
1479 for (; i
< max_fringe_bitmaps
; i
++)
1481 fringe_bitmaps
[i
] = NULL
;
1482 fringe_faces
[i
] = Qnil
;
1487 Vfringe_bitmaps
= Fcons (bitmap
, Vfringe_bitmaps
);
1488 Fput (bitmap
, Qfringe
, make_number (n
));
1493 xfb
= (struct fringe_bitmap
*) xmalloc (sizeof fb
1494 + fb
.height
* BYTES_PER_BITMAP_ROW
);
1495 fb
.bits
= b
= (unsigned short *) (xfb
+ 1);
1496 bzero (b
, fb
.height
);
1499 while (j
< fb
.height
)
1501 for (i
= 0; i
< fill1
&& j
< fb
.height
; i
++)
1503 for (i
= 0; i
< h
&& j
< fb
.height
; i
++)
1505 Lisp_Object elt
= Faref (bits
, make_number (i
));
1506 b
[j
++] = NUMBERP (elt
) ? XINT (elt
) : 0;
1508 for (i
= 0; i
< fill2
&& j
< fb
.height
; i
++)
1514 init_fringe_bitmap (n
, xfb
, 0);
1519 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face
, Sset_fringe_bitmap_face
,
1521 doc
: /* Set face for fringe bitmap BITMAP to FACE.
1522 If FACE is nil, reset face to default fringe face. */)
1524 Lisp_Object bitmap
, face
;
1529 CHECK_SYMBOL (bitmap
);
1530 n
= lookup_fringe_bitmap (bitmap
);
1532 error ("Undefined fringe bitmap");
1536 face_id
= lookup_derived_face (SELECTED_FRAME (), face
,
1539 error ("No such face");
1542 fringe_faces
[n
] = face
;
1547 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos
, Sfringe_bitmaps_at_pos
,
1549 doc
: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1550 If WINDOW is nil, use selected window. If POS is nil, use value of point
1551 in that window. Return value is a list (LEFT RIGHT OV), where LEFT
1552 is the symbol for the bitmap in the left fringe (or nil if no bitmap),
1553 RIGHT is similar for the right fringe, and OV is non-nil if there is an
1554 overlay arrow in the left fringe.
1555 Return nil if POS is not visible in WINDOW. */)
1557 Lisp_Object pos
, window
;
1560 struct glyph_row
*row
;
1564 window
= selected_window
;
1565 CHECK_WINDOW (window
);
1566 w
= XWINDOW (window
);
1570 CHECK_NUMBER_COERCE_MARKER (pos
);
1571 textpos
= XINT (pos
);
1573 else if (w
== XWINDOW (selected_window
))
1576 textpos
= XMARKER (w
->pointm
)->charpos
;
1578 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
1579 row
= row_containing_pos (w
, textpos
, row
, NULL
, 0);
1581 return list3 (get_fringe_bitmap_name (row
->left_fringe_bitmap
),
1582 get_fringe_bitmap_name (row
->right_fringe_bitmap
),
1583 (row
->overlay_arrow_bitmap
== 0 ? Qnil
1584 : row
->overlay_arrow_bitmap
< 0 ? Qt
1585 : get_fringe_bitmap_name (row
->overlay_arrow_bitmap
)));
1591 /***********************************************************************
1593 ***********************************************************************/
1596 syms_of_fringe (void)
1598 Qtruncation
= intern_c_string ("truncation");
1599 staticpro (&Qtruncation
);
1600 Qcontinuation
= intern_c_string ("continuation");
1601 staticpro (&Qcontinuation
);
1602 Qoverlay_arrow
= intern_c_string ("overlay-arrow");
1603 staticpro (&Qoverlay_arrow
);
1604 Qempty_line
= intern_c_string ("empty-line");
1605 staticpro (&Qempty_line
);
1606 Qtop_bottom
= intern_c_string ("top-bottom");
1607 staticpro (&Qtop_bottom
);
1608 Qhollow_small
= intern_c_string ("hollow-small");
1609 staticpro (&Qhollow_small
);
1611 defsubr (&Sdestroy_fringe_bitmap
);
1612 defsubr (&Sdefine_fringe_bitmap
);
1613 defsubr (&Sfringe_bitmaps_at_pos
);
1614 defsubr (&Sset_fringe_bitmap_face
);
1616 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe
,
1617 doc
: /* *Non-nil means that newline may flow into the right fringe.
1618 This means that display lines which are exactly as wide as the window
1619 (not counting the final newline) will only occupy one screen line, by
1620 showing (or hiding) the final newline in the right fringe; when point
1621 is at the final newline, the cursor is shown in the right fringe.
1622 If nil, also continue lines which are exactly as wide as the window. */);
1623 Voverflow_newline_into_fringe
= Qt
;
1625 DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps
,
1626 doc
: /* List of fringe bitmap symbols. */);
1627 Vfringe_bitmaps
= Qnil
;
1630 /* Garbage collection hook */
1633 mark_fringe_data (void)
1637 for (i
= 0; i
< max_fringe_bitmaps
; i
++)
1638 if (!NILP (fringe_faces
[i
]))
1639 mark_object (fringe_faces
[i
]);
1642 /* Initialize this module when Emacs starts. */
1645 init_fringe_once (void)
1649 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1650 init_fringe_bitmap(bt
, &standard_bitmaps
[bt
], 1);
1658 max_fringe_bitmaps
= MAX_STANDARD_FRINGE_BITMAPS
+ 20;
1661 = (struct fringe_bitmap
**) xmalloc (max_fringe_bitmaps
* sizeof (struct fringe_bitmap
*));
1663 = (Lisp_Object
*) xmalloc (max_fringe_bitmaps
* sizeof (Lisp_Object
));
1665 for (i
= 0; i
< max_fringe_bitmaps
; i
++)
1667 fringe_bitmaps
[i
] = NULL
;
1668 fringe_faces
[i
] = Qnil
;
1675 w32_init_fringe (struct redisplay_interface
*rif
)
1682 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1684 struct fringe_bitmap
*fb
= &standard_bitmaps
[bt
];
1685 rif
->define_fringe_bitmap (bt
, fb
->bits
, fb
->height
, fb
->width
);
1690 w32_reset_fringes ()
1692 /* Destroy row bitmaps. */
1694 struct redisplay_interface
*rif
= FRAME_RIF (SELECTED_FRAME ());
1699 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< max_used_fringe_bitmap
; bt
++)
1700 rif
->destroy_fringe_bitmap (bt
);
1703 #endif /* HAVE_NTGUI */
1705 #endif /* HAVE_WINDOW_SYSTEM */
1707 /* arch-tag: 04596920-43eb-473d-b319-82712338162d
1708 (do not change this comment) */