1 /* Fringe handling (split from xdisp.c).
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03,04
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
28 #include "dispextern.h"
30 #include "blockinput.h"
32 #ifdef HAVE_WINDOW_SYSTEM
34 extern Lisp_Object Qfringe
;
35 extern Lisp_Object Qtop
, Qbottom
, Qcenter
;
36 extern Lisp_Object Qup
, Qdown
, Qleft
, Qright
;
38 /* Non-nil means that newline may flow into the right fringe. */
40 Lisp_Object Voverflow_newline_into_fringe
;
42 /* List of known fringe bitmap symbols.
44 The fringe bitmap number is stored in the `fringe' property on
45 those symbols. Names for the built-in bitmaps are installed by
49 Lisp_Object Vfringe_bitmaps
;
51 enum fringe_bitmap_type
55 LEFT_TRUNCATION_BITMAP
,
56 RIGHT_TRUNCATION_BITMAP
,
59 CONTINUED_LINE_BITMAP
,
60 CONTINUATION_LINE_BITMAP
,
62 TOP_LEFT_ANGLE_BITMAP
,
63 TOP_RIGHT_ANGLE_BITMAP
,
64 BOTTOM_LEFT_ANGLE_BITMAP
,
65 BOTTOM_RIGHT_ANGLE_BITMAP
,
68 FILLED_BOX_CURSOR_BITMAP
,
69 HOLLOW_BOX_CURSOR_BITMAP
,
74 MAX_STANDARD_FRINGE_BITMAPS
77 enum fringe_bitmap_align
79 ALIGN_BITMAP_CENTER
= 0,
95 /***********************************************************************
97 ***********************************************************************/
99 /* Undefined bitmap. A question mark. */
112 static unsigned short unknown_bits
[] = {
113 0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
115 /* An arrow like this: `<-'. */
126 static unsigned short left_arrow_bits
[] = {
127 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
130 /* Right truncation arrow bitmap `->'. */
141 static unsigned short right_arrow_bits
[] = {
142 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
145 /* Up arrow bitmap. */
156 static unsigned short up_arrow_bits
[] = {
157 0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
160 /* Down arrow bitmap. */
171 static unsigned short down_arrow_bits
[] = {
172 0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
174 /* Marker for continued lines. */
185 static unsigned short continued_bits
[] = {
186 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
188 /* Marker for continuation lines. */
199 static unsigned short continuation_bits
[] = {
200 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
202 /* Overlay arrow bitmap. A triangular arrow. */
213 static unsigned short ov_bits
[] = {
214 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
217 /* Reverse Overlay arrow bitmap. A triangular arrow. */
228 static unsigned short rev_ov_bits
[] = {
229 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
232 /* First line bitmap. An top-left angle. */
243 static unsigned short top_left_angle_bits
[] = {
244 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00};
246 /* First line bitmap. An right-up angle. */
257 static unsigned short top_right_angle_bits
[] = {
258 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
260 /* Last line bitmap. An left-down angle. */
271 static unsigned short bottom_left_angle_bits
[] = {
272 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
274 /* Last line bitmap. An right-down angle. */
285 static unsigned short bottom_right_angle_bits
[] = {
286 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
288 /* First/last line bitmap. An left bracket. */
301 static unsigned short left_bracket_bits
[] = {
302 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
304 /* First/last line bitmap. An right bracket. */
317 static unsigned short right_bracket_bits
[] = {
318 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
320 /* Filled box cursor bitmap. A filled box; max 13 pixels high. */
336 static unsigned short filled_box_cursor_bits
[] = {
337 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
339 /* Hollow box cursor bitmap. A hollow box; max 13 pixels high. */
355 static unsigned short hollow_box_cursor_bits
[] = {
356 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe};
358 /* Bar cursor bitmap. A vertical bar; max 13 pixels high. */
374 static unsigned short bar_cursor_bits
[] = {
375 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
377 /* HBar cursor bitmap. A horisontal bar; 2 pixels high. */
382 static unsigned short hbar_cursor_bits
[] = {
386 /* Bitmap drawn to indicate lines not displaying text if
387 `indicate-empty-lines' is non-nil. */
396 static unsigned short zv_bits
[] = {
397 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
398 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
399 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
400 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
401 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
402 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
403 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
404 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
406 /* Hollow square bitmap. */
415 static unsigned short hollow_square_bits
[] = {
416 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
419 #define BYTES_PER_BITMAP_ROW (sizeof (unsigned short))
420 #define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
421 #define FRBITS(bits) bits, STANDARD_BITMAP_HEIGHT (bits)
423 struct fringe_bitmap standard_bitmaps
[MAX_STANDARD_FRINGE_BITMAPS
] =
425 { NULL
, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */
426 { FRBITS (unknown_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
427 { FRBITS (left_arrow_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
428 { FRBITS (right_arrow_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
429 { FRBITS (up_arrow_bits
), 8, 0, ALIGN_BITMAP_TOP
, 0 },
430 { FRBITS (down_arrow_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
431 { FRBITS (continued_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
432 { FRBITS (continuation_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
433 { FRBITS (ov_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
434 { FRBITS (top_left_angle_bits
), 8, 0, ALIGN_BITMAP_TOP
, 0 },
435 { FRBITS (top_right_angle_bits
), 8, 0, ALIGN_BITMAP_TOP
, 0 },
436 { FRBITS (bottom_left_angle_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
437 { FRBITS (bottom_right_angle_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
438 { FRBITS (left_bracket_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
439 { FRBITS (right_bracket_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
440 { FRBITS (filled_box_cursor_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
441 { FRBITS (hollow_box_cursor_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
442 { FRBITS (hollow_square_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
443 { FRBITS (bar_cursor_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
444 { FRBITS (hbar_cursor_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
445 { FRBITS (zv_bits
), 8, 3, ALIGN_BITMAP_TOP
, 0 },
448 static struct fringe_bitmap
**fringe_bitmaps
;
449 static Lisp_Object
*fringe_faces
;
450 static int max_fringe_bitmaps
;
452 static int max_used_fringe_bitmap
= MAX_STANDARD_FRINGE_BITMAPS
;
455 /* Lookup bitmap number for symbol BITMAP.
456 Return 0 if not a bitmap. */
459 lookup_fringe_bitmap (bitmap
)
464 bitmap
= Fget (bitmap
, Qfringe
);
465 if (!INTEGERP (bitmap
))
469 if (bn
> NO_FRINGE_BITMAP
470 && bn
< max_used_fringe_bitmap
471 && (bn
< MAX_STANDARD_FRINGE_BITMAPS
472 || fringe_bitmaps
[bn
] != NULL
))
478 /* Get fringe bitmap name for bitmap number BN.
480 Found by traversing Vfringe_bitmaps comparing BN to the
481 fringe property for each symbol.
483 Return BN if not found in Vfringe_bitmaps. */
486 get_fringe_bitmap_name (bn
)
492 /* Zero means no bitmap -- return nil. */
496 bitmaps
= Vfringe_bitmaps
;
497 num
= make_number (bn
);
499 while (CONSP (bitmaps
))
501 Lisp_Object bitmap
= XCAR (bitmaps
);
502 if (EQ (num
, Fget (bitmap
, Qfringe
)))
504 bitmaps
= XCDR (bitmaps
);
511 /* Draw the bitmap WHICH in one of the left or right fringes of
512 window W. ROW is the glyph row for which to display the bitmap; it
513 determines the vertical position at which the bitmap has to be
515 LEFT_P is 1 for left fringe, 0 for right fringe.
519 draw_fringe_bitmap_1 (w
, row
, left_p
, overlay
, which
)
521 struct glyph_row
*row
;
523 enum fringe_bitmap_type which
;
525 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
526 struct draw_fringe_bitmap_params p
;
527 struct fringe_bitmap
*fb
;
529 int face_id
= DEFAULT_FACE_ID
;
532 p
.overlay_p
= (overlay
& 1) == 1;
533 p
.cursor_p
= (overlay
& 2) == 2;
535 if (which
!= NO_FRINGE_BITMAP
)
540 which
= row
->left_fringe_bitmap
;
541 face_id
= row
->left_fringe_face_id
;
545 which
= row
->right_fringe_bitmap
;
546 face_id
= row
->right_fringe_face_id
;
549 if (face_id
== DEFAULT_FACE_ID
)
553 if ((face
= fringe_faces
[which
], NILP (face
))
554 || (face_id
= lookup_named_face (f
, face
, 'A', 1), face_id
< 0))
555 face_id
= FRINGE_FACE_ID
;
558 fb
= fringe_bitmaps
[which
];
560 fb
= &standard_bitmaps
[which
< MAX_STANDARD_FRINGE_BITMAPS
561 ? which
: UNDEF_FRINGE_BITMAP
];
565 /* Convert row to frame coordinates. */
566 p
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
573 p
.dh
= (period
> 0 ? (p
.y
% period
) : 0);
575 /* Clip bitmap if too high. */
576 if (p
.h
> row
->height
)
579 p
.face
= FACE_FROM_ID (f
, face_id
);
583 /* This could happen after clearing face cache.
584 But it shouldn't happen anymore. ++kfs */
588 PREPARE_FACE_FOR_DISPLAY (f
, p
.face
);
590 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
595 int wd
= WINDOW_LEFT_FRINGE_WIDTH (w
);
596 int x
= window_box_left (w
, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
601 p
.x
= x
- p
.wd
- (wd
- p
.wd
) / 2;
603 if (p
.wd
< wd
|| row
->height
> p
.h
)
605 /* If W has a vertical border to its left, don't draw over it. */
606 wd
-= ((!WINDOW_LEFTMOST_P (w
)
607 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
615 int x
= window_box_right (w
,
616 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
619 int wd
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
622 p
.x
= x
+ (wd
- p
.wd
) / 2;
623 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
625 if (p
.wd
< wd
|| row
->height
> p
.h
)
634 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
636 p
.by
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, row
->y
));
637 p
.ny
= row
->visible_height
;
640 /* Adjust y to the offset in the row to start drawing the bitmap. */
643 case ALIGN_BITMAP_CENTER
:
644 p
.y
+= (row
->height
- p
.h
) / 2;
646 case ALIGN_BITMAP_BOTTOM
:
648 p
.y
+= (row
->visible_height
- p
.h
);
650 case ALIGN_BITMAP_TOP
:
654 rif
->draw_fringe_bitmap (w
, row
, &p
);
658 draw_fringe_bitmap (w
, row
, left_p
)
660 struct glyph_row
*row
;
665 if (!left_p
&& row
->cursor_in_fringe_p
)
667 int cursor
= NO_FRINGE_BITMAP
;
669 switch (w
->phys_cursor_type
)
671 case HOLLOW_BOX_CURSOR
:
672 if (row
->visible_height
>= STANDARD_BITMAP_HEIGHT (hollow_box_cursor_bits
))
673 cursor
= HOLLOW_BOX_CURSOR_BITMAP
;
675 cursor
= HOLLOW_SQUARE_BITMAP
;
677 case FILLED_BOX_CURSOR
:
678 cursor
= FILLED_BOX_CURSOR_BITMAP
;
681 cursor
= BAR_CURSOR_BITMAP
;
684 cursor
= HBAR_CURSOR_BITMAP
;
688 w
->phys_cursor_on_p
= 0;
689 row
->cursor_in_fringe_p
= 0;
692 if (cursor
!= NO_FRINGE_BITMAP
)
694 draw_fringe_bitmap_1 (w
, row
, 0, 2, cursor
);
695 overlay
= cursor
== FILLED_BOX_CURSOR_BITMAP
? 3 : 1;
699 draw_fringe_bitmap_1 (w
, row
, left_p
, overlay
, NO_FRINGE_BITMAP
);
701 if (left_p
&& row
->overlay_arrow_p
)
702 draw_fringe_bitmap_1 (w
, row
, 1, 1,
703 (w
->overlay_arrow_bitmap
704 ? w
->overlay_arrow_bitmap
705 : OVERLAY_ARROW_BITMAP
));
709 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
710 function with input blocked. */
713 draw_row_fringe_bitmaps (w
, row
)
715 struct glyph_row
*row
;
717 xassert (interrupt_input_blocked
);
719 /* If row is completely invisible, because of vscrolling, we
720 don't have to draw anything. */
721 if (row
->visible_height
<= 0)
724 if (WINDOW_LEFT_FRINGE_WIDTH (w
) != 0)
725 draw_fringe_bitmap (w
, row
, 1);
727 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) != 0)
728 draw_fringe_bitmap (w
, row
, 0);
731 /* Draw the fringes of window W. Only fringes for rows marked for
732 update in redraw_fringe_bitmaps_p are drawn.
734 Return >0 if left or right fringe was redrawn in any way.
736 If NO_FRINGE is non-zero, also return >0 if either fringe has zero width.
738 A return value >0 indicates that the vertical line between windows
739 needs update (as it may be drawn in the fringe).
743 draw_window_fringes (w
, no_fringe
)
747 struct glyph_row
*row
;
748 int yb
= window_text_bottom_y (w
);
749 int nrows
= w
->current_matrix
->nrows
;
753 if (w
->pseudo_window_p
)
756 /* Must draw line if no fringe */
758 && (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0
759 || WINDOW_RIGHT_FRINGE_WIDTH (w
) == 0))
762 for (y
= 0, rn
= 0, row
= w
->current_matrix
->rows
;
763 y
< yb
&& rn
< nrows
;
764 y
+= row
->height
, ++row
, ++rn
)
766 if (!row
->redraw_fringe_bitmaps_p
)
768 draw_row_fringe_bitmaps (w
, row
);
769 row
->redraw_fringe_bitmaps_p
= 0;
777 /* Recalculate the bitmaps to show in the fringes of window W.
778 If FORCE_P is 0, only mark rows with modified bitmaps for update in
779 redraw_fringe_bitmaps_p; else mark all rows for update. */
782 update_window_fringes (w
, force_p
)
786 struct glyph_row
*row
, *cur
= 0;
787 int yb
= window_text_bottom_y (w
);
788 int rn
, nrows
= w
->current_matrix
->nrows
;
791 Lisp_Object boundary_top
= Qnil
, boundary_bot
= Qnil
;
792 Lisp_Object arrow_top
= Qnil
, arrow_bot
= Qnil
;
793 Lisp_Object empty_pos
;
794 Lisp_Object ind
= Qnil
;
796 if (w
->pseudo_window_p
)
799 if (!MINI_WINDOW_P (w
)
800 && (ind
= XBUFFER (w
->buffer
)->indicate_buffer_boundaries
, !NILP (ind
)))
802 if (EQ (ind
, Qleft
) || EQ (ind
, Qright
))
803 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= ind
;
804 else if (CONSP (ind
) && CONSP (XCAR (ind
)))
807 if (pos
= Fassq (Qt
, ind
), !NILP (pos
))
808 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= XCDR (pos
);
809 if (pos
= Fassq (Qtop
, ind
), !NILP (pos
))
810 boundary_top
= XCDR (pos
);
811 if (pos
= Fassq (Qbottom
, ind
), !NILP (pos
))
812 boundary_bot
= XCDR (pos
);
813 if (pos
= Fassq (Qup
, ind
), !NILP (pos
))
814 arrow_top
= XCDR (pos
);
815 if (pos
= Fassq (Qdown
, ind
), !NILP (pos
))
816 arrow_bot
= XCDR (pos
);
819 /* Anything else means boundary on left and no arrows. */
820 boundary_top
= boundary_bot
= Qleft
;
825 int done_top
= 0, done_bot
= 0;
828 y
< yb
&& rn
< nrows
;
829 y
+= row
->height
, ++rn
)
831 unsigned indicate_bob_p
, indicate_top_line_p
;
832 unsigned indicate_eob_p
, indicate_bottom_line_p
;
834 row
= w
->desired_matrix
->rows
+ rn
;
836 row
= w
->current_matrix
->rows
+ rn
;
838 indicate_bob_p
= row
->indicate_bob_p
;
839 indicate_top_line_p
= row
->indicate_top_line_p
;
840 indicate_eob_p
= row
->indicate_eob_p
;
841 indicate_bottom_line_p
= row
->indicate_bottom_line_p
;
843 row
->indicate_bob_p
= row
->indicate_top_line_p
= 0;
844 row
->indicate_eob_p
= row
->indicate_bottom_line_p
= 0;
846 if (!row
->mode_line_p
)
850 if (MATRIX_ROW_START_CHARPOS (row
) <= BUF_BEGV (XBUFFER (w
->buffer
)))
851 row
->indicate_bob_p
= !NILP (boundary_top
);
853 row
->indicate_top_line_p
= !NILP (arrow_top
);
859 if (MATRIX_ROW_END_CHARPOS (row
) >= BUF_ZV (XBUFFER (w
->buffer
)))
860 row
->indicate_eob_p
= !NILP (boundary_bot
), done_bot
= 1;
861 else if (y
+ row
->height
>= yb
)
862 row
->indicate_bottom_line_p
= !NILP (arrow_bot
), done_bot
= 1;
866 if (indicate_bob_p
!= row
->indicate_bob_p
867 || indicate_top_line_p
!= row
->indicate_top_line_p
868 || indicate_eob_p
!= row
->indicate_eob_p
869 || indicate_bottom_line_p
!= row
->indicate_bottom_line_p
)
870 row
->redraw_fringe_bitmaps_p
= 1;
874 empty_pos
= XBUFFER (w
->buffer
)->indicate_empty_lines
;
875 if (!NILP (empty_pos
) && !EQ (empty_pos
, Qright
))
876 empty_pos
= WINDOW_LEFT_FRINGE_WIDTH (w
) == 0 ? Qright
: Qleft
;
879 y
< yb
&& rn
< nrows
;
880 y
+= row
->height
, rn
++)
882 enum fringe_bitmap_type left
, right
;
883 unsigned left_face_id
, right_face_id
;
885 row
= w
->desired_matrix
->rows
+ rn
;
886 cur
= w
->current_matrix
->rows
+ rn
;
890 left_face_id
= right_face_id
= DEFAULT_FACE_ID
;
892 /* Decide which bitmap to draw in the left fringe. */
893 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
894 left
= NO_FRINGE_BITMAP
;
895 else if (row
->left_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
897 left
= row
->left_user_fringe_bitmap
;
898 left_face_id
= row
->left_user_fringe_face_id
;
900 else if (row
->truncated_on_left_p
)
901 left
= LEFT_TRUNCATION_BITMAP
;
902 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qleft
))
903 left
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
904 ? LEFT_BRACKET_BITMAP
: TOP_LEFT_ANGLE_BITMAP
);
905 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
906 left
= BOTTOM_LEFT_ANGLE_BITMAP
;
907 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
908 left
= CONTINUATION_LINE_BITMAP
;
909 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qleft
))
910 left
= ZV_LINE_BITMAP
;
911 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qleft
))
912 left
= UP_ARROW_BITMAP
;
913 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qleft
))
914 left
= DOWN_ARROW_BITMAP
;
916 left
= NO_FRINGE_BITMAP
;
918 /* Decide which bitmap to draw in the right fringe. */
919 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) == 0)
920 right
= NO_FRINGE_BITMAP
;
921 else if (row
->right_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
923 right
= row
->right_user_fringe_bitmap
;
924 right_face_id
= row
->right_user_fringe_face_id
;
926 else if (row
->truncated_on_right_p
)
927 right
= RIGHT_TRUNCATION_BITMAP
;
928 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qright
))
929 right
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
930 ? RIGHT_BRACKET_BITMAP
: TOP_RIGHT_ANGLE_BITMAP
);
931 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
932 right
= BOTTOM_RIGHT_ANGLE_BITMAP
;
933 else if (row
->continued_p
)
934 right
= CONTINUED_LINE_BITMAP
;
935 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qright
))
936 right
= UP_ARROW_BITMAP
;
937 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qright
))
938 right
= DOWN_ARROW_BITMAP
;
939 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qright
))
940 right
= ZV_LINE_BITMAP
;
942 right
= NO_FRINGE_BITMAP
;
946 || row
->visible_height
!= cur
->visible_height
947 || row
->ends_at_zv_p
!= cur
->ends_at_zv_p
948 || left
!= cur
->left_fringe_bitmap
949 || right
!= cur
->right_fringe_bitmap
950 || left_face_id
!= cur
->left_fringe_face_id
951 || right_face_id
!= cur
->right_fringe_face_id
952 || cur
->redraw_fringe_bitmaps_p
)
954 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
955 cur
->left_fringe_bitmap
= left
;
956 cur
->right_fringe_bitmap
= right
;
957 cur
->left_fringe_face_id
= left_face_id
;
958 cur
->right_fringe_face_id
= right_face_id
;
961 if (row
->overlay_arrow_p
!= cur
->overlay_arrow_p
)
963 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
964 cur
->overlay_arrow_p
= row
->overlay_arrow_p
;
967 row
->left_fringe_bitmap
= left
;
968 row
->right_fringe_bitmap
= right
;
969 row
->left_fringe_face_id
= left_face_id
;
970 row
->right_fringe_face_id
= right_face_id
;
972 if (rn
> 0 && row
->redraw_fringe_bitmaps_p
)
973 row
[-1].redraw_fringe_bitmaps_p
= cur
[-1].redraw_fringe_bitmaps_p
= 1;
980 /* Compute actual fringe widths for frame F.
982 If REDRAW is 1, redraw F if the fringe settings was actually
983 modified and F is visible.
985 Since the combined left and right fringe must occupy an integral
986 number of columns, we may need to add some pixels to each fringe.
987 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
988 but a negative width value is taken literally (after negating it).
990 We never make the fringes narrower than specified.
994 compute_fringe_widths (f
, redraw
)
998 int o_left
= FRAME_LEFT_FRINGE_WIDTH (f
);
999 int o_right
= FRAME_RIGHT_FRINGE_WIDTH (f
);
1000 int o_cols
= FRAME_FRINGE_COLS (f
);
1002 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
1003 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
1004 int left_fringe_width
, right_fringe_width
;
1006 if (!NILP (left_fringe
))
1007 left_fringe
= Fcdr (left_fringe
);
1008 if (!NILP (right_fringe
))
1009 right_fringe
= Fcdr (right_fringe
);
1011 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
1012 XINT (left_fringe
));
1013 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
1014 XINT (right_fringe
));
1016 if (left_fringe_width
|| right_fringe_width
)
1018 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
1019 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
1020 int conf_wid
= left_wid
+ right_wid
;
1021 int font_wid
= FRAME_COLUMN_WIDTH (f
);
1022 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
1023 int real_wid
= cols
* font_wid
;
1024 if (left_wid
&& right_wid
)
1026 if (left_fringe_width
< 0)
1028 /* Left fringe width is fixed, adjust right fringe if necessary */
1029 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
;
1030 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
- left_wid
;
1032 else if (right_fringe_width
< 0)
1034 /* Right fringe width is fixed, adjust left fringe if necessary */
1035 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
- right_wid
;
1036 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
;
1040 /* Adjust both fringes with an equal amount.
1041 Note that we are doing integer arithmetic here, so don't
1042 lose a pixel if the total width is an odd number. */
1043 int fill
= real_wid
- conf_wid
;
1044 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
+ fill
/2;
1045 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
+ fill
- fill
/2;
1048 else if (left_fringe_width
)
1050 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
;
1051 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1055 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1056 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
;
1058 FRAME_FRINGE_COLS (f
) = cols
;
1062 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1063 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1064 FRAME_FRINGE_COLS (f
) = 0;
1067 if (redraw
&& FRAME_VISIBLE_P (f
))
1068 if (o_left
!= FRAME_LEFT_FRINGE_WIDTH (f
) ||
1069 o_right
!= FRAME_RIGHT_FRINGE_WIDTH (f
) ||
1070 o_cols
!= FRAME_FRINGE_COLS (f
))
1075 /* Free resources used by a user-defined bitmap. */
1078 destroy_fringe_bitmap (n
)
1081 struct fringe_bitmap
**fbp
;
1083 fringe_faces
[n
] = Qnil
;
1085 fbp
= &fringe_bitmaps
[n
];
1086 if (*fbp
&& (*fbp
)->dynamic
)
1088 if (rif
&& rif
->destroy_fringe_bitmap
)
1089 rif
->destroy_fringe_bitmap (n
);
1094 while (max_used_fringe_bitmap
> MAX_STANDARD_FRINGE_BITMAPS
1095 && fringe_bitmaps
[max_used_fringe_bitmap
- 1] == NULL
)
1096 max_used_fringe_bitmap
--;
1100 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap
, Sdestroy_fringe_bitmap
,
1102 doc
: /* Destroy fringe bitmap BITMAP.
1103 If BITMAP overrides a standard fringe bitmap, the original bitmap is restored. */)
1109 CHECK_SYMBOL (bitmap
);
1110 n
= lookup_fringe_bitmap (bitmap
);
1114 destroy_fringe_bitmap (n
);
1116 if (n
>= MAX_STANDARD_FRINGE_BITMAPS
)
1118 Vfringe_bitmaps
= Fdelq (bitmap
, Vfringe_bitmaps
);
1119 /* It would be better to remove the fringe property. */
1120 Fput (bitmap
, Qfringe
, Qnil
);
1127 /* Initialize bitmap bit.
1129 On X, we bit-swap the built-in bitmaps and reduce bitmap
1130 from short to char array if width is <= 8 bits.
1132 On MAC with big-endian CPU, we need to byte-swap each short.
1134 On W32 and MAC (little endian), there's no need to do this.
1138 init_fringe_bitmap (which
, fb
, once_p
)
1139 enum fringe_bitmap_type which
;
1140 struct fringe_bitmap
*fb
;
1143 if (once_p
|| fb
->dynamic
)
1145 #if defined (HAVE_X_WINDOWS)
1146 static unsigned char swap_nibble
[16]
1147 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1148 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1149 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1150 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
1151 unsigned short *bits
= fb
->bits
;
1156 unsigned char *cbits
= (unsigned char *)fb
->bits
;
1157 for (j
= 0; j
< fb
->height
; j
++)
1159 unsigned short b
= *bits
++;
1161 c
= (unsigned char)((swap_nibble
[b
& 0xf] << 4)
1162 | (swap_nibble
[(b
>>4) & 0xf]));
1163 *cbits
++ = (c
>> (8 - fb
->width
));
1168 for (j
= 0; j
< fb
->height
; j
++)
1170 unsigned short b
= *bits
;
1171 b
= (unsigned short)((swap_nibble
[b
& 0xf] << 12)
1172 | (swap_nibble
[(b
>>4) & 0xf] << 8)
1173 | (swap_nibble
[(b
>>8) & 0xf] << 4)
1174 | (swap_nibble
[(b
>>12) & 0xf]));
1175 *bits
++ = (b
>> (16 - fb
->width
));
1178 #endif /* HAVE_X_WINDOWS */
1180 #if defined (MAC_OS) && defined (WORDS_BIG_ENDIAN)
1181 unsigned short *bits
= fb
->bits
;
1183 for (j
= 0; j
< fb
->height
; j
++)
1185 unsigned short b
= *bits
;
1186 *bits
++ = ((b
>> 8) & 0xff) | ((b
& 0xff) << 8);
1188 #endif /* MAC_OS && WORDS_BIG_ENDIAN */
1193 destroy_fringe_bitmap (which
);
1195 if (rif
&& rif
->define_fringe_bitmap
)
1196 rif
->define_fringe_bitmap (which
, fb
->bits
, fb
->height
, fb
->width
);
1198 fringe_bitmaps
[which
] = fb
;
1199 if (which
>= max_used_fringe_bitmap
)
1200 max_used_fringe_bitmap
= which
+ 1;
1205 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap
, Sdefine_fringe_bitmap
,
1207 doc
: /* Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH.
1208 BITMAP is a symbol or string naming the new fringe bitmap.
1209 BITS is either a string or a vector of integers.
1210 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1211 WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1212 Optional fifth arg ALIGN may be one of `top', `center', or `bottom',
1213 indicating the positioning of the bitmap relative to the rows where it
1214 is used; the default is to center the bitmap. Fourth arg may also be a
1215 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1217 If BITMAP already exists, the existing definition is replaced. */)
1218 (bitmap
, bits
, height
, width
, align
)
1219 Lisp_Object bitmap
, bits
, height
, width
, align
;
1223 struct fringe_bitmap fb
, *xfb
;
1224 int fill1
= 0, fill2
= 0;
1226 CHECK_SYMBOL (bitmap
);
1230 else if (VECTORP (bits
))
1231 h
= XVECTOR (bits
)->size
;
1233 bits
= wrong_type_argument (Qsequencep
, bits
);
1239 CHECK_NUMBER (height
);
1240 fb
.height
= min (XINT (height
), 255);
1243 fill1
= (fb
.height
- h
) / 2;
1244 fill2
= fb
.height
- h
- fill1
;
1252 CHECK_NUMBER (width
);
1253 fb
.width
= min (XINT (width
), 255);
1257 fb
.align
= ALIGN_BITMAP_CENTER
;
1261 Lisp_Object period
= XCDR (align
);
1264 period
= XCAR (period
);
1267 fb
.period
= fb
.height
;
1271 align
= XCAR (align
);
1273 if (EQ (align
, Qtop
))
1274 fb
.align
= ALIGN_BITMAP_TOP
;
1275 else if (EQ (align
, Qbottom
))
1276 fb
.align
= ALIGN_BITMAP_BOTTOM
;
1277 else if (!NILP (align
) && !EQ (align
, Qcenter
))
1278 error ("Bad align argument");
1280 n
= lookup_fringe_bitmap (bitmap
);
1283 if (max_used_fringe_bitmap
< max_fringe_bitmaps
)
1284 n
= max_used_fringe_bitmap
++;
1287 for (n
= MAX_STANDARD_FRINGE_BITMAPS
;
1288 n
< max_fringe_bitmaps
;
1290 if (fringe_bitmaps
[n
] == NULL
)
1293 if (n
== max_fringe_bitmaps
)
1295 if ((max_fringe_bitmaps
+ 20) > MAX_FRINGE_BITMAPS
)
1296 error ("No free fringe bitmap slots");
1298 i
= max_fringe_bitmaps
;
1299 max_fringe_bitmaps
+= 20;
1301 = ((struct fringe_bitmap
**)
1302 xrealloc (fringe_bitmaps
, max_fringe_bitmaps
* sizeof (struct fringe_bitmap
*)));
1304 = (Lisp_Object
*) xrealloc (fringe_faces
, max_fringe_bitmaps
* sizeof (Lisp_Object
));
1306 for (; i
< max_fringe_bitmaps
; i
++)
1308 fringe_bitmaps
[i
] = NULL
;
1309 fringe_faces
[i
] = Qnil
;
1314 Vfringe_bitmaps
= Fcons (bitmap
, Vfringe_bitmaps
);
1315 Fput (bitmap
, Qfringe
, make_number (n
));
1320 xfb
= (struct fringe_bitmap
*) xmalloc (sizeof fb
1321 + fb
.height
* BYTES_PER_BITMAP_ROW
);
1322 fb
.bits
= b
= (unsigned short *) (xfb
+ 1);
1323 bzero (b
, fb
.height
);
1326 while (j
< fb
.height
)
1328 for (i
= 0; i
< fill1
&& j
< fb
.height
; i
++)
1330 for (i
= 0; i
< h
&& j
< fb
.height
; i
++)
1332 Lisp_Object elt
= Faref (bits
, make_number (i
));
1333 b
[j
++] = NUMBERP (elt
) ? XINT (elt
) : 0;
1335 for (i
= 0; i
< fill2
&& j
< fb
.height
; i
++)
1341 init_fringe_bitmap (n
, xfb
, 0);
1346 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face
, Sset_fringe_bitmap_face
,
1348 doc
: /* Set face for fringe bitmap BITMAP to FACE.
1349 If FACE is nil, reset face to default fringe face. */)
1351 Lisp_Object bitmap
, face
;
1356 CHECK_SYMBOL (bitmap
);
1357 n
= lookup_fringe_bitmap (bitmap
);
1359 error ("Undefined fringe bitmap");
1363 face_id
= lookup_named_face (SELECTED_FRAME (), face
, 'A', 1);
1365 error ("No such face");
1368 fringe_faces
[n
] = face
;
1373 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos
, Sfringe_bitmaps_at_pos
,
1375 doc
: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1376 If WINDOW is nil, use selected window. If POS is nil, use value of point
1377 in that window. Return value is a list (LEFT RIGHT OV), where LEFT
1378 is the symbol for the bitmap in the left fringe (or nil if no bitmap),
1379 RIGHT is similar for the right fringe, and OV is non-nil if there is an
1380 overlay arrow in the left fringe.
1381 Return nil if POS is not visible in WINDOW. */)
1383 Lisp_Object pos
, window
;
1386 struct glyph_row
*row
;
1390 window
= selected_window
;
1391 CHECK_WINDOW (window
);
1392 w
= XWINDOW (window
);
1396 CHECK_NUMBER_COERCE_MARKER (pos
);
1397 textpos
= XINT (pos
);
1399 else if (w
== XWINDOW (selected_window
))
1402 textpos
= XMARKER (w
->pointm
)->charpos
;
1404 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
1405 row
= row_containing_pos (w
, textpos
, row
, NULL
, 0);
1407 return list3 (get_fringe_bitmap_name (row
->left_fringe_bitmap
),
1408 get_fringe_bitmap_name (row
->right_fringe_bitmap
),
1409 (row
->overlay_arrow_p
? Qt
: Qnil
));
1415 /***********************************************************************
1417 ***********************************************************************/
1422 defsubr (&Sdestroy_fringe_bitmap
);
1423 defsubr (&Sdefine_fringe_bitmap
);
1424 defsubr (&Sfringe_bitmaps_at_pos
);
1425 defsubr (&Sset_fringe_bitmap_face
);
1427 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe
,
1428 doc
: /* *Non-nil means that newline may flow into the right fringe.
1429 This means that display lines which are exactly as wide as the window
1430 (not counting the final newline) will only occupy one screen line, by
1431 showing (or hiding) the final newline in the right fringe; when point
1432 is at the final newline, the cursor is shown in the right fringe.
1433 If nil, also continue lines which are exactly as wide as the window. */);
1434 Voverflow_newline_into_fringe
= Qt
;
1436 DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps
,
1437 doc
: /* List of fringe bitmap symbols.
1438 You must (require 'fringe) to use fringe bitmap symbols in your programs." */);
1439 Vfringe_bitmaps
= Qnil
;
1442 /* Garbage collection hook */
1449 for (i
= 0; i
< max_fringe_bitmaps
; i
++)
1450 if (!NILP (fringe_faces
[i
]))
1451 mark_object (fringe_faces
[i
]);
1454 /* Initialize this module when Emacs starts. */
1459 enum fringe_bitmap_type bt
;
1461 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1462 init_fringe_bitmap(bt
, &standard_bitmaps
[bt
], 1);
1470 max_fringe_bitmaps
= MAX_STANDARD_FRINGE_BITMAPS
+ 20;
1473 = (struct fringe_bitmap
**) xmalloc (max_fringe_bitmaps
* sizeof (struct fringe_bitmap
*));
1475 = (Lisp_Object
*) xmalloc (max_fringe_bitmaps
* sizeof (Lisp_Object
));
1477 for (i
= 0; i
< max_fringe_bitmaps
; i
++)
1479 fringe_bitmaps
[i
] = NULL
;
1480 fringe_faces
[i
] = Qnil
;
1489 enum fringe_bitmap_type bt
;
1494 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1496 struct fringe_bitmap
*fb
= &standard_bitmaps
[bt
];
1497 rif
->define_fringe_bitmap (bt
, fb
->bits
, fb
->height
, fb
->width
);
1502 w32_reset_fringes ()
1504 /* Destroy row bitmaps. */
1510 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< max_used_fringe_bitmap
; bt
++)
1511 rif
->destroy_fringe_bitmap (bt
);
1514 #endif /* HAVE_NTGUI */
1516 #endif /* HAVE_WINDOW_SYSTEM */
1518 /* arch-tag: 04596920-43eb-473d-b319-82712338162d
1519 (do not change this comment) */