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 unsigned *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
)
550 face_id
= fringe_faces
[which
];
552 fb
= fringe_bitmaps
[which
];
554 fb
= &standard_bitmaps
[which
< MAX_STANDARD_FRINGE_BITMAPS
555 ? which
: UNDEF_FRINGE_BITMAP
];
559 /* Convert row to frame coordinates. */
560 p
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
567 p
.dh
= (period
> 0 ? (p
.y
% period
) : 0);
569 /* Clip bitmap if too high. */
570 if (p
.h
> row
->height
)
573 p
.face
= FACE_FROM_ID (f
, face_id
);
577 /* Why does this happen? ++kfs */
581 PREPARE_FACE_FOR_DISPLAY (f
, p
.face
);
583 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
588 int wd
= WINDOW_LEFT_FRINGE_WIDTH (w
);
589 int x
= window_box_left (w
, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
594 p
.x
= x
- p
.wd
- (wd
- p
.wd
) / 2;
596 if (p
.wd
< wd
|| row
->height
> p
.h
)
598 /* If W has a vertical border to its left, don't draw over it. */
599 wd
-= ((!WINDOW_LEFTMOST_P (w
)
600 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
608 int x
= window_box_right (w
,
609 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
612 int wd
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
615 p
.x
= x
+ (wd
- p
.wd
) / 2;
616 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
618 if (p
.wd
< wd
|| row
->height
> p
.h
)
627 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
629 p
.by
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, row
->y
));
630 p
.ny
= row
->visible_height
;
633 /* Adjust y to the offset in the row to start drawing the bitmap. */
636 case ALIGN_BITMAP_CENTER
:
637 p
.y
+= (row
->height
- p
.h
) / 2;
639 case ALIGN_BITMAP_BOTTOM
:
641 p
.y
+= (row
->visible_height
- p
.h
);
643 case ALIGN_BITMAP_TOP
:
647 rif
->draw_fringe_bitmap (w
, row
, &p
);
651 draw_fringe_bitmap (w
, row
, left_p
)
653 struct glyph_row
*row
;
658 if (!left_p
&& row
->cursor_in_fringe_p
)
660 int cursor
= NO_FRINGE_BITMAP
;
662 switch (w
->phys_cursor_type
)
664 case HOLLOW_BOX_CURSOR
:
665 if (row
->visible_height
>= STANDARD_BITMAP_HEIGHT (hollow_box_cursor_bits
))
666 cursor
= HOLLOW_BOX_CURSOR_BITMAP
;
668 cursor
= HOLLOW_SQUARE_BITMAP
;
670 case FILLED_BOX_CURSOR
:
671 cursor
= FILLED_BOX_CURSOR_BITMAP
;
674 cursor
= BAR_CURSOR_BITMAP
;
677 cursor
= HBAR_CURSOR_BITMAP
;
681 w
->phys_cursor_on_p
= 0;
682 row
->cursor_in_fringe_p
= 0;
685 if (cursor
!= NO_FRINGE_BITMAP
)
687 draw_fringe_bitmap_1 (w
, row
, 0, 2, cursor
);
688 overlay
= cursor
== FILLED_BOX_CURSOR_BITMAP
? 3 : 1;
692 draw_fringe_bitmap_1 (w
, row
, left_p
, overlay
, NO_FRINGE_BITMAP
);
694 if (left_p
&& row
->overlay_arrow_p
)
695 draw_fringe_bitmap_1 (w
, row
, 1, 1,
696 (w
->overlay_arrow_bitmap
697 ? w
->overlay_arrow_bitmap
698 : OVERLAY_ARROW_BITMAP
));
702 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
703 function with input blocked. */
706 draw_row_fringe_bitmaps (w
, row
)
708 struct glyph_row
*row
;
710 xassert (interrupt_input_blocked
);
712 /* If row is completely invisible, because of vscrolling, we
713 don't have to draw anything. */
714 if (row
->visible_height
<= 0)
717 if (WINDOW_LEFT_FRINGE_WIDTH (w
) != 0)
718 draw_fringe_bitmap (w
, row
, 1);
720 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) != 0)
721 draw_fringe_bitmap (w
, row
, 0);
724 /* Draw the fringes of window W. Only fringes for rows marked for
725 update in redraw_fringe_bitmaps_p are drawn. */
728 draw_window_fringes (w
)
731 struct glyph_row
*row
;
732 int yb
= window_text_bottom_y (w
);
733 int nrows
= w
->current_matrix
->nrows
;
736 if (w
->pseudo_window_p
)
739 for (y
= 0, rn
= 0, row
= w
->current_matrix
->rows
;
740 y
< yb
&& rn
< nrows
;
741 y
+= row
->height
, ++row
, ++rn
)
743 if (!row
->redraw_fringe_bitmaps_p
)
745 draw_row_fringe_bitmaps (w
, row
);
746 row
->redraw_fringe_bitmaps_p
= 0;
751 /* Recalculate the bitmaps to show in the fringes of window W.
752 If FORCE_P is 0, only mark rows with modified bitmaps for update in
753 redraw_fringe_bitmaps_p; else mark all rows for update. */
756 update_window_fringes (w
, force_p
)
760 struct glyph_row
*row
, *cur
= 0;
761 int yb
= window_text_bottom_y (w
);
762 int rn
, nrows
= w
->current_matrix
->nrows
;
765 Lisp_Object boundary_top
= Qnil
, boundary_bot
= Qnil
;
766 Lisp_Object arrow_top
= Qnil
, arrow_bot
= Qnil
;
767 Lisp_Object empty_pos
;
768 Lisp_Object ind
= Qnil
;
770 if (w
->pseudo_window_p
)
773 if (!MINI_WINDOW_P (w
)
774 && (ind
= XBUFFER (w
->buffer
)->indicate_buffer_boundaries
, !NILP (ind
)))
776 if (EQ (ind
, Qleft
) || EQ (ind
, Qright
))
777 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= ind
;
778 else if (CONSP (ind
) && CONSP (XCAR (ind
)))
781 if (pos
= Fassq (Qt
, ind
), !NILP (pos
))
782 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= XCDR (pos
);
783 if (pos
= Fassq (Qtop
, ind
), !NILP (pos
))
784 boundary_top
= XCDR (pos
);
785 if (pos
= Fassq (Qbottom
, ind
), !NILP (pos
))
786 boundary_bot
= XCDR (pos
);
787 if (pos
= Fassq (Qup
, ind
), !NILP (pos
))
788 arrow_top
= XCDR (pos
);
789 if (pos
= Fassq (Qdown
, ind
), !NILP (pos
))
790 arrow_bot
= XCDR (pos
);
798 int do_eob
= 1, do_bob
= 1;
801 y
< yb
&& rn
< nrows
;
802 y
+= row
->height
, ++rn
)
804 unsigned indicate_bob_p
, indicate_top_line_p
;
805 unsigned indicate_eob_p
, indicate_bottom_line_p
;
807 row
= w
->desired_matrix
->rows
+ rn
;
809 row
= w
->current_matrix
->rows
+ rn
;
811 indicate_bob_p
= row
->indicate_bob_p
;
812 indicate_top_line_p
= row
->indicate_top_line_p
;
813 indicate_eob_p
= row
->indicate_eob_p
;
814 indicate_bottom_line_p
= row
->indicate_bottom_line_p
;
816 row
->indicate_bob_p
= row
->indicate_top_line_p
= 0;
817 row
->indicate_eob_p
= row
->indicate_bottom_line_p
= 0;
819 if (!NILP (boundary_top
)
820 && MATRIX_ROW_START_CHARPOS (row
) <= BUF_BEGV (XBUFFER (w
->buffer
)))
821 row
->indicate_bob_p
= do_bob
, do_bob
= 0;
822 else if (!NILP (arrow_top
)
823 && (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0) == rn
)
824 row
->indicate_top_line_p
= 1;
826 if (!NILP (boundary_bot
)
827 && MATRIX_ROW_END_CHARPOS (row
) >= BUF_ZV (XBUFFER (w
->buffer
)))
828 row
->indicate_eob_p
= do_eob
, do_eob
= 0;
829 else if (!NILP (arrow_bot
)
830 && y
+ row
->height
>= yb
)
831 row
->indicate_bottom_line_p
= 1;
833 if (indicate_bob_p
!= row
->indicate_bob_p
834 || indicate_top_line_p
!= row
->indicate_top_line_p
835 || indicate_eob_p
!= row
->indicate_eob_p
836 || indicate_bottom_line_p
!= row
->indicate_bottom_line_p
)
837 row
->redraw_fringe_bitmaps_p
= 1;
841 empty_pos
= XBUFFER (w
->buffer
)->indicate_empty_lines
;
842 if (!NILP (empty_pos
) && !EQ (empty_pos
, Qright
))
843 empty_pos
= WINDOW_LEFT_FRINGE_WIDTH (w
) == 0 ? Qright
: Qleft
;
846 y
< yb
&& rn
< nrows
;
847 y
+= row
->height
, rn
++)
849 enum fringe_bitmap_type left
, right
;
850 unsigned left_face_id
, right_face_id
;
852 row
= w
->desired_matrix
->rows
+ rn
;
853 cur
= w
->current_matrix
->rows
+ rn
;
857 left_face_id
= right_face_id
= DEFAULT_FACE_ID
;
859 /* Decide which bitmap to draw in the left fringe. */
860 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
861 left
= NO_FRINGE_BITMAP
;
862 else if (row
->left_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
864 left
= row
->left_user_fringe_bitmap
;
865 left_face_id
= row
->left_user_fringe_face_id
;
867 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qleft
))
868 left
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
869 ? LEFT_BRACKET_BITMAP
: TOP_LEFT_ANGLE_BITMAP
);
870 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
871 left
= BOTTOM_LEFT_ANGLE_BITMAP
;
872 else if (row
->truncated_on_left_p
)
873 left
= LEFT_TRUNCATION_BITMAP
;
874 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
875 left
= CONTINUATION_LINE_BITMAP
;
876 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qleft
))
877 left
= ZV_LINE_BITMAP
;
878 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qleft
))
879 left
= UP_ARROW_BITMAP
;
880 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qleft
))
881 left
= DOWN_ARROW_BITMAP
;
883 left
= NO_FRINGE_BITMAP
;
885 /* Decide which bitmap to draw in the right fringe. */
886 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) == 0)
887 right
= NO_FRINGE_BITMAP
;
888 else if (row
->right_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
890 right
= row
->right_user_fringe_bitmap
;
891 right_face_id
= row
->right_user_fringe_face_id
;
893 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qright
))
894 right
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
895 ? RIGHT_BRACKET_BITMAP
: TOP_RIGHT_ANGLE_BITMAP
);
896 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
897 right
= BOTTOM_RIGHT_ANGLE_BITMAP
;
898 else if (row
->truncated_on_right_p
)
899 right
= RIGHT_TRUNCATION_BITMAP
;
900 else if (row
->continued_p
)
901 right
= CONTINUED_LINE_BITMAP
;
902 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qright
))
903 right
= UP_ARROW_BITMAP
;
904 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qright
))
905 right
= DOWN_ARROW_BITMAP
;
906 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qright
))
907 right
= ZV_LINE_BITMAP
;
909 right
= NO_FRINGE_BITMAP
;
913 || row
->visible_height
!= cur
->visible_height
914 || left
!= cur
->left_fringe_bitmap
915 || right
!= cur
->right_fringe_bitmap
916 || left_face_id
!= cur
->left_fringe_face_id
917 || right_face_id
!= cur
->right_fringe_face_id
918 || cur
->redraw_fringe_bitmaps_p
)
920 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
921 cur
->left_fringe_bitmap
= left
;
922 cur
->right_fringe_bitmap
= right
;
923 cur
->left_fringe_face_id
= left_face_id
;
924 cur
->right_fringe_face_id
= right_face_id
;
927 if (row
->overlay_arrow_p
!= cur
->overlay_arrow_p
)
929 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
930 cur
->overlay_arrow_p
= row
->overlay_arrow_p
;
933 row
->left_fringe_bitmap
= left
;
934 row
->right_fringe_bitmap
= right
;
935 row
->left_fringe_face_id
= left_face_id
;
936 row
->right_fringe_face_id
= right_face_id
;
943 /* Compute actual fringe widths for frame F.
945 If REDRAW is 1, redraw F if the fringe settings was actually
946 modified and F is visible.
948 Since the combined left and right fringe must occupy an integral
949 number of columns, we may need to add some pixels to each fringe.
950 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
951 but a negative width value is taken literally (after negating it).
953 We never make the fringes narrower than specified. It is planned
954 to make fringe bitmaps customizable and expandable, and at that
955 time, the user will typically specify the minimum number of pixels
956 needed for his bitmaps, so we shouldn't select anything less than
961 compute_fringe_widths (f
, redraw
)
965 int o_left
= FRAME_LEFT_FRINGE_WIDTH (f
);
966 int o_right
= FRAME_RIGHT_FRINGE_WIDTH (f
);
967 int o_cols
= FRAME_FRINGE_COLS (f
);
969 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
970 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
971 int left_fringe_width
, right_fringe_width
;
973 if (!NILP (left_fringe
))
974 left_fringe
= Fcdr (left_fringe
);
975 if (!NILP (right_fringe
))
976 right_fringe
= Fcdr (right_fringe
);
978 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
980 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
981 XINT (right_fringe
));
983 if (left_fringe_width
|| right_fringe_width
)
985 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
986 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
987 int conf_wid
= left_wid
+ right_wid
;
988 int font_wid
= FRAME_COLUMN_WIDTH (f
);
989 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
990 int real_wid
= cols
* font_wid
;
991 if (left_wid
&& right_wid
)
993 if (left_fringe_width
< 0)
995 /* Left fringe width is fixed, adjust right fringe if necessary */
996 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
;
997 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
- left_wid
;
999 else if (right_fringe_width
< 0)
1001 /* Right fringe width is fixed, adjust left fringe if necessary */
1002 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
- right_wid
;
1003 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
;
1007 /* Adjust both fringes with an equal amount.
1008 Note that we are doing integer arithmetic here, so don't
1009 lose a pixel if the total width is an odd number. */
1010 int fill
= real_wid
- conf_wid
;
1011 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
+ fill
/2;
1012 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
+ fill
- fill
/2;
1015 else if (left_fringe_width
)
1017 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
;
1018 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1022 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1023 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
;
1025 FRAME_FRINGE_COLS (f
) = cols
;
1029 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1030 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1031 FRAME_FRINGE_COLS (f
) = 0;
1034 if (redraw
&& FRAME_VISIBLE_P (f
))
1035 if (o_left
!= FRAME_LEFT_FRINGE_WIDTH (f
) ||
1036 o_right
!= FRAME_RIGHT_FRINGE_WIDTH (f
) ||
1037 o_cols
!= FRAME_FRINGE_COLS (f
))
1042 /* Free resources used by a user-defined bitmap. */
1045 destroy_fringe_bitmap (n
)
1048 struct fringe_bitmap
**fbp
;
1050 fringe_faces
[n
] = FRINGE_FACE_ID
;
1052 fbp
= &fringe_bitmaps
[n
];
1053 if (*fbp
&& (*fbp
)->dynamic
)
1055 if (rif
&& rif
->destroy_fringe_bitmap
)
1056 rif
->destroy_fringe_bitmap (n
);
1061 while (max_used_fringe_bitmap
> MAX_STANDARD_FRINGE_BITMAPS
1062 && fringe_bitmaps
[max_used_fringe_bitmap
- 1] == NULL
)
1063 max_used_fringe_bitmap
--;
1067 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap
, Sdestroy_fringe_bitmap
,
1069 doc
: /* Destroy fringe bitmap BITMAP.
1070 If BITMAP overrides a standard fringe bitmap, the original bitmap is restored. */)
1076 CHECK_SYMBOL (bitmap
);
1077 n
= lookup_fringe_bitmap (bitmap
);
1081 destroy_fringe_bitmap (n
);
1083 if (n
>= MAX_STANDARD_FRINGE_BITMAPS
)
1085 Vfringe_bitmaps
= Fdelq (bitmap
, Vfringe_bitmaps
);
1086 /* It would be better to remove the fringe property. */
1087 Fput (bitmap
, Qfringe
, Qnil
);
1094 /* Initialize bitmap bit.
1096 On X, we bit-swap the built-in bitmaps and reduce bitmap
1097 from short to char array if width is <= 8 bits.
1099 On MAC with big-endian CPU, we need to byte-swap each short.
1101 On W32 and MAC (little endian), there's no need to do this.
1105 init_fringe_bitmap (which
, fb
, once_p
)
1106 enum fringe_bitmap_type which
;
1107 struct fringe_bitmap
*fb
;
1110 if (once_p
|| fb
->dynamic
)
1112 #if defined (HAVE_X_WINDOWS)
1113 static unsigned char swap_nibble
[16]
1114 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1115 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1116 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1117 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
1118 unsigned short *bits
= fb
->bits
;
1123 unsigned char *cbits
= (unsigned char *)fb
->bits
;
1124 for (j
= 0; j
< fb
->height
; j
++)
1126 unsigned short b
= *bits
++;
1128 c
= (unsigned char)((swap_nibble
[b
& 0xf] << 4)
1129 | (swap_nibble
[(b
>>4) & 0xf]));
1130 *cbits
++ = (c
>> (8 - fb
->width
));
1135 for (j
= 0; j
< fb
->height
; j
++)
1137 unsigned short b
= *bits
;
1138 b
= (unsigned short)((swap_nibble
[b
& 0xf] << 12)
1139 | (swap_nibble
[(b
>>4) & 0xf] << 8)
1140 | (swap_nibble
[(b
>>8) & 0xf] << 4)
1141 | (swap_nibble
[(b
>>12) & 0xf]));
1142 *bits
++ = (b
>> (16 - fb
->width
));
1145 #endif /* HAVE_X_WINDOWS */
1147 #if defined (MAC_OS) && defined (WORDS_BIG_ENDIAN)
1148 unsigned short *bits
= fb
->bits
;
1150 for (j
= 0; j
< fb
->height
; j
++)
1152 unsigned short b
= *bits
;
1153 *bits
++ = ((b
>> 8) & 0xff) | ((b
& 0xff) << 8);
1155 #endif /* MAC_OS && WORDS_BIG_ENDIAN */
1160 destroy_fringe_bitmap (which
);
1162 if (rif
&& rif
->define_fringe_bitmap
)
1163 rif
->define_fringe_bitmap (which
, fb
->bits
, fb
->height
, fb
->width
);
1165 fringe_bitmaps
[which
] = fb
;
1166 if (which
>= max_used_fringe_bitmap
)
1167 max_used_fringe_bitmap
= which
+ 1;
1172 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap
, Sdefine_fringe_bitmap
,
1174 doc
: /* Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH.
1175 BITMAP is a symbol or string naming the new fringe bitmap.
1176 BITS is either a string or a vector of integers.
1177 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1178 WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1179 Optional fifth arg ALIGN may be one of `top', `center', or `bottom',
1180 indicating the positioning of the bitmap relative to the rows where it
1181 is used; the default is to center the bitmap. Fourth arg may also be a
1182 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1184 If BITMAP already exists, the existing definition is replaced. */)
1185 (bitmap
, bits
, height
, width
, align
)
1186 Lisp_Object bitmap
, bits
, height
, width
, align
;
1191 struct fringe_bitmap fb
, *xfb
;
1192 int fill1
= 0, fill2
= 0;
1194 CHECK_SYMBOL (bitmap
);
1196 if (!STRINGP (bits
) && !VECTORP (bits
))
1197 bits
= wrong_type_argument (Qstringp
, bits
);
1199 len
= Flength (bits
);
1202 h
= fb
.height
= XINT (len
);
1205 CHECK_NUMBER (height
);
1206 fb
.height
= min (XINT (height
), 255);
1207 if (fb
.height
> XINT (len
))
1210 fill1
= (fb
.height
- h
) / 2;
1211 fill2
= fb
.height
- h
- fill1
;
1219 CHECK_NUMBER (width
);
1220 fb
.width
= min (XINT (width
), 255);
1224 fb
.align
= ALIGN_BITMAP_CENTER
;
1228 Lisp_Object period
= XCDR (align
);
1231 period
= XCAR (period
);
1234 fb
.period
= fb
.height
;
1238 align
= XCAR (align
);
1240 if (EQ (align
, Qtop
))
1241 fb
.align
= ALIGN_BITMAP_TOP
;
1242 else if (EQ (align
, Qbottom
))
1243 fb
.align
= ALIGN_BITMAP_BOTTOM
;
1244 else if (!NILP (align
) && !EQ (align
, Qcenter
))
1245 error ("Bad align argument");
1247 n
= lookup_fringe_bitmap (bitmap
);
1250 if (max_used_fringe_bitmap
< max_fringe_bitmaps
)
1251 n
= max_used_fringe_bitmap
++;
1254 for (n
= MAX_STANDARD_FRINGE_BITMAPS
;
1255 n
< max_fringe_bitmaps
;
1257 if (fringe_bitmaps
[n
] == NULL
)
1260 if (n
== max_fringe_bitmaps
)
1262 if ((max_fringe_bitmaps
+ 20) > MAX_FRINGE_BITMAPS
)
1263 error ("No free fringe bitmap slots");
1265 i
= max_fringe_bitmaps
;
1266 max_fringe_bitmaps
+= 20;
1268 = ((struct fringe_bitmap
**)
1269 xrealloc (fringe_bitmaps
, max_fringe_bitmaps
* sizeof (struct fringe_bitmap
*)));
1271 = (unsigned *) xrealloc (fringe_faces
, max_fringe_bitmaps
* sizeof (unsigned));
1273 for (; i
< max_fringe_bitmaps
; i
++)
1275 fringe_bitmaps
[i
] = NULL
;
1276 fringe_faces
[i
] = FRINGE_FACE_ID
;
1281 Vfringe_bitmaps
= Fcons (bitmap
, Vfringe_bitmaps
);
1282 Fput (bitmap
, Qfringe
, make_number (n
));
1287 xfb
= (struct fringe_bitmap
*) xmalloc (sizeof fb
1288 + fb
.height
* BYTES_PER_BITMAP_ROW
);
1289 fb
.bits
= b
= (unsigned short *) (xfb
+ 1);
1290 bzero (b
, fb
.height
);
1293 while (j
< fb
.height
)
1295 for (i
= 0; i
< fill1
&& j
< fb
.height
; i
++)
1297 for (i
= 0; i
< h
&& j
< fb
.height
; i
++)
1299 Lisp_Object elt
= Faref (bits
, make_number (i
));
1300 b
[j
++] = NUMBERP (elt
) ? XINT (elt
) : 0;
1302 for (i
= 0; i
< fill2
&& j
< fb
.height
; i
++)
1308 init_fringe_bitmap (n
, xfb
, 0);
1313 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face
, Sset_fringe_bitmap_face
,
1315 doc
: /* Set face for fringe bitmap BITMAP to FACE.
1316 If FACE is nil, reset face to default fringe face. */)
1318 Lisp_Object bitmap
, face
;
1323 CHECK_SYMBOL (bitmap
);
1324 n
= lookup_fringe_bitmap (bitmap
);
1326 error ("Undefined fringe bitmap");
1330 face_id
= lookup_named_face (SELECTED_FRAME (), face
);
1332 error ("No such face");
1335 face_id
= FRINGE_FACE_ID
;
1337 fringe_faces
[n
] = face_id
;
1342 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos
, Sfringe_bitmaps_at_pos
,
1344 doc
: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1345 If WINDOW is nil, use selected window. If POS is nil, use value of point
1346 in that window. Return value is a cons (LEFT . RIGHT) where LEFT and RIGHT
1347 are the fringe bitmap numbers for the bitmaps in the left and right fringe,
1348 resp. If left or right fringe is empty, the corresponding element is nil.
1349 Return nil if POS is not visible in WINDOW. */)
1351 Lisp_Object pos
, window
;
1354 struct buffer
*old_buffer
= NULL
;
1355 struct glyph_row
*row
;
1359 window
= selected_window
;
1360 CHECK_WINDOW (window
);
1361 w
= XWINDOW (window
);
1365 CHECK_NUMBER_COERCE_MARKER (pos
);
1366 textpos
= XINT (pos
);
1368 else if (w
== XWINDOW (selected_window
))
1371 textpos
= XMARKER (w
->pointm
)->charpos
;
1373 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
1374 row
= row_containing_pos (w
, textpos
, row
, NULL
, 0);
1376 return Fcons (get_fringe_bitmap_name (row
->left_fringe_bitmap
),
1377 get_fringe_bitmap_name (row
->right_fringe_bitmap
));
1383 /***********************************************************************
1385 ***********************************************************************/
1390 defsubr (&Sdestroy_fringe_bitmap
);
1391 defsubr (&Sdefine_fringe_bitmap
);
1392 defsubr (&Sfringe_bitmaps_at_pos
);
1393 defsubr (&Sset_fringe_bitmap_face
);
1395 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe
,
1396 doc
: /* *Non-nil means that newline may flow into the right fringe.
1397 This means that display lines which are exactly as wide as the window
1398 (not counting the final newline) will only occupy one screen line, by
1399 showing (or hiding) the final newline in the right fringe; when point
1400 is at the final newline, the cursor is shown in the right fringe.
1401 If nil, also continue lines which are exactly as wide as the window. */);
1402 Voverflow_newline_into_fringe
= Qt
;
1404 DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps
,
1405 doc
: /* List of fringe bitmap symbols.
1406 You must (require 'fringe) to use fringe bitmap symbols in your programs." */);
1407 Vfringe_bitmaps
= Qnil
;
1410 /* Initialize this module when Emacs starts. */
1415 enum fringe_bitmap_type bt
;
1417 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1418 init_fringe_bitmap(bt
, &standard_bitmaps
[bt
], 1);
1426 max_fringe_bitmaps
= MAX_STANDARD_FRINGE_BITMAPS
+ 20;
1429 = (struct fringe_bitmap
**) xmalloc (max_fringe_bitmaps
* sizeof (struct fringe_bitmap
*));
1431 = (unsigned *) xmalloc (max_fringe_bitmaps
* sizeof (unsigned));
1433 for (i
= 0; i
< max_fringe_bitmaps
; i
++)
1435 fringe_bitmaps
[i
] = NULL
;
1436 fringe_faces
[i
] = FRINGE_FACE_ID
;
1445 enum fringe_bitmap_type bt
;
1450 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1452 struct fringe_bitmap
*fb
= &standard_bitmaps
[bt
];
1453 rif
->define_fringe_bitmap (bt
, fb
->bits
, fb
->height
, fb
->width
);
1458 w32_reset_fringes ()
1460 /* Destroy row bitmaps. */
1466 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< max_used_fringe_bitmap
; bt
++)
1467 rif
->destroy_fringe_bitmap (bt
);
1470 #endif /* HAVE_NTGUI */
1472 #endif /* HAVE_WINDOW_SYSTEM */
1474 /* arch-tag: 04596920-43eb-473d-b319-82712338162d
1475 (do not change this comment) */