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., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
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 enum fringe_bitmap_type
56 LEFT_TRUNCATION_BITMAP
,
57 RIGHT_TRUNCATION_BITMAP
,
60 CONTINUED_LINE_BITMAP
,
61 CONTINUATION_LINE_BITMAP
,
63 TOP_LEFT_ANGLE_BITMAP
,
64 TOP_RIGHT_ANGLE_BITMAP
,
65 BOTTOM_LEFT_ANGLE_BITMAP
,
66 BOTTOM_RIGHT_ANGLE_BITMAP
,
69 FILLED_BOX_CURSOR_BITMAP
,
70 HOLLOW_BOX_CURSOR_BITMAP
,
75 MAX_STANDARD_FRINGE_BITMAPS
78 enum fringe_bitmap_align
80 ALIGN_BITMAP_CENTER
= 0,
96 /***********************************************************************
98 ***********************************************************************/
100 /* Undefined bitmap. A question mark. */
113 static unsigned short unknown_bits
[] = {
114 0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
116 /* An arrow like this: `<-'. */
127 static unsigned short left_arrow_bits
[] = {
128 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
131 /* Right truncation arrow bitmap `->'. */
142 static unsigned short right_arrow_bits
[] = {
143 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
146 /* Up arrow bitmap. */
157 static unsigned short up_arrow_bits
[] = {
158 0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
161 /* Down arrow bitmap. */
172 static unsigned short down_arrow_bits
[] = {
173 0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
175 /* Marker for continued lines. */
186 static unsigned short continued_bits
[] = {
187 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
189 /* Marker for continuation lines. */
200 static unsigned short continuation_bits
[] = {
201 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
203 /* Overlay arrow bitmap. A triangular arrow. */
214 static unsigned short ov_bits
[] = {
215 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
218 /* Reverse Overlay arrow bitmap. A triangular arrow. */
229 static unsigned short rev_ov_bits
[] = {
230 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
233 /* First line bitmap. An top-left angle. */
244 static unsigned short top_left_angle_bits
[] = {
245 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00};
247 /* First line bitmap. An right-up angle. */
258 static unsigned short top_right_angle_bits
[] = {
259 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
261 /* Last line bitmap. An left-down angle. */
272 static unsigned short bottom_left_angle_bits
[] = {
273 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
275 /* Last line bitmap. An right-down angle. */
286 static unsigned short bottom_right_angle_bits
[] = {
287 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
289 /* First/last line bitmap. An left bracket. */
302 static unsigned short left_bracket_bits
[] = {
303 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
305 /* First/last line bitmap. An right bracket. */
318 static unsigned short right_bracket_bits
[] = {
319 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
321 /* Filled box cursor bitmap. A filled box; max 13 pixels high. */
337 static unsigned short filled_box_cursor_bits
[] = {
338 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
340 /* Hollow box cursor bitmap. A hollow box; max 13 pixels high. */
356 static unsigned short hollow_box_cursor_bits
[] = {
357 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe};
359 /* Bar cursor bitmap. A vertical bar; max 13 pixels high. */
375 static unsigned short bar_cursor_bits
[] = {
376 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
378 /* HBar cursor bitmap. A horisontal bar; 2 pixels high. */
383 static unsigned short hbar_cursor_bits
[] = {
387 /* Bitmap drawn to indicate lines not displaying text if
388 `indicate-empty-lines' is non-nil. */
397 static unsigned short zv_bits
[] = {
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,
405 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
407 /* Hollow square bitmap. */
416 static unsigned short hollow_square_bits
[] = {
417 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
420 #define BYTES_PER_BITMAP_ROW (sizeof (unsigned short))
421 #define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
422 #define FRBITS(bits) bits, STANDARD_BITMAP_HEIGHT (bits)
424 struct fringe_bitmap standard_bitmaps
[MAX_STANDARD_FRINGE_BITMAPS
] =
426 { NULL
, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */
427 { FRBITS (unknown_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
428 { FRBITS (left_arrow_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
429 { FRBITS (right_arrow_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
430 { FRBITS (up_arrow_bits
), 8, 0, ALIGN_BITMAP_TOP
, 0 },
431 { FRBITS (down_arrow_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
432 { FRBITS (continued_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
433 { FRBITS (continuation_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
434 { FRBITS (ov_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
435 { FRBITS (top_left_angle_bits
), 8, 0, ALIGN_BITMAP_TOP
, 0 },
436 { FRBITS (top_right_angle_bits
), 8, 0, ALIGN_BITMAP_TOP
, 0 },
437 { FRBITS (bottom_left_angle_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
438 { FRBITS (bottom_right_angle_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
439 { FRBITS (left_bracket_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
440 { FRBITS (right_bracket_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
441 { FRBITS (filled_box_cursor_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
442 { FRBITS (hollow_box_cursor_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
443 { FRBITS (hollow_square_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
444 { FRBITS (bar_cursor_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
445 { FRBITS (hbar_cursor_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
446 { FRBITS (zv_bits
), 8, 3, ALIGN_BITMAP_TOP
, 0 },
449 static struct fringe_bitmap
**fringe_bitmaps
;
450 static Lisp_Object
*fringe_faces
;
451 static int max_fringe_bitmaps
;
453 static int max_used_fringe_bitmap
= MAX_STANDARD_FRINGE_BITMAPS
;
456 /* Lookup bitmap number for symbol BITMAP.
457 Return 0 if not a bitmap. */
460 lookup_fringe_bitmap (bitmap
)
465 bitmap
= Fget (bitmap
, Qfringe
);
466 if (!INTEGERP (bitmap
))
470 if (bn
> NO_FRINGE_BITMAP
471 && bn
< max_used_fringe_bitmap
472 && (bn
< MAX_STANDARD_FRINGE_BITMAPS
473 || fringe_bitmaps
[bn
] != NULL
))
479 /* Get fringe bitmap name for bitmap number BN.
481 Found by traversing Vfringe_bitmaps comparing BN to the
482 fringe property for each symbol.
484 Return BN if not found in Vfringe_bitmaps. */
487 get_fringe_bitmap_name (bn
)
493 /* Zero means no bitmap -- return nil. */
497 bitmaps
= Vfringe_bitmaps
;
498 num
= make_number (bn
);
500 while (CONSP (bitmaps
))
502 Lisp_Object bitmap
= XCAR (bitmaps
);
503 if (EQ (num
, Fget (bitmap
, Qfringe
)))
505 bitmaps
= XCDR (bitmaps
);
512 /* Draw the bitmap WHICH in one of the left or right fringes of
513 window W. ROW is the glyph row for which to display the bitmap; it
514 determines the vertical position at which the bitmap has to be
516 LEFT_P is 1 for left fringe, 0 for right fringe.
520 draw_fringe_bitmap_1 (w
, row
, left_p
, overlay
, which
)
522 struct glyph_row
*row
;
524 enum fringe_bitmap_type which
;
526 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
527 struct draw_fringe_bitmap_params p
;
528 struct fringe_bitmap
*fb
;
530 int face_id
= DEFAULT_FACE_ID
;
533 p
.overlay_p
= (overlay
& 1) == 1;
534 p
.cursor_p
= (overlay
& 2) == 2;
536 if (which
!= NO_FRINGE_BITMAP
)
541 which
= row
->left_fringe_bitmap
;
542 face_id
= row
->left_fringe_face_id
;
546 which
= row
->right_fringe_bitmap
;
547 face_id
= row
->right_fringe_face_id
;
550 if (face_id
== DEFAULT_FACE_ID
)
554 if ((face
= fringe_faces
[which
], NILP (face
))
555 || (face_id
= lookup_derived_face (f
, face
, 'A', FRINGE_FACE_ID
, 0),
557 face_id
= FRINGE_FACE_ID
;
560 fb
= fringe_bitmaps
[which
];
562 fb
= &standard_bitmaps
[which
< MAX_STANDARD_FRINGE_BITMAPS
563 ? which
: UNDEF_FRINGE_BITMAP
];
567 /* Convert row to frame coordinates. */
568 p
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
575 p
.dh
= (period
> 0 ? (p
.y
% period
) : 0);
577 /* Clip bitmap if too high. */
578 if (p
.h
> row
->height
)
581 p
.face
= FACE_FROM_ID (f
, face_id
);
585 /* This could happen after clearing face cache.
586 But it shouldn't happen anymore. ++kfs */
590 PREPARE_FACE_FOR_DISPLAY (f
, p
.face
);
592 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
597 int wd
= WINDOW_LEFT_FRINGE_WIDTH (w
);
598 int x
= window_box_left (w
, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
603 p
.x
= x
- p
.wd
- (wd
- p
.wd
) / 2;
605 if (p
.wd
< wd
|| row
->height
> p
.h
)
607 /* If W has a vertical border to its left, don't draw over it. */
608 wd
-= ((!WINDOW_LEFTMOST_P (w
)
609 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
617 int x
= window_box_right (w
,
618 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
621 int wd
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
624 p
.x
= x
+ (wd
- p
.wd
) / 2;
625 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
627 if (p
.wd
< wd
|| row
->height
> p
.h
)
636 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
638 p
.by
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, row
->y
));
639 p
.ny
= row
->visible_height
;
642 /* Adjust y to the offset in the row to start drawing the bitmap. */
645 case ALIGN_BITMAP_CENTER
:
646 p
.y
+= (row
->height
- p
.h
) / 2;
648 case ALIGN_BITMAP_BOTTOM
:
650 p
.y
+= (row
->visible_height
- p
.h
);
652 case ALIGN_BITMAP_TOP
:
656 FRAME_RIF (f
)->draw_fringe_bitmap (w
, row
, &p
);
660 draw_fringe_bitmap (w
, row
, left_p
)
662 struct glyph_row
*row
;
667 if (!left_p
&& row
->cursor_in_fringe_p
)
669 int cursor
= NO_FRINGE_BITMAP
;
671 switch (w
->phys_cursor_type
)
673 case HOLLOW_BOX_CURSOR
:
674 if (row
->visible_height
>= STANDARD_BITMAP_HEIGHT (hollow_box_cursor_bits
))
675 cursor
= HOLLOW_BOX_CURSOR_BITMAP
;
677 cursor
= HOLLOW_SQUARE_BITMAP
;
679 case FILLED_BOX_CURSOR
:
680 cursor
= FILLED_BOX_CURSOR_BITMAP
;
683 cursor
= BAR_CURSOR_BITMAP
;
686 cursor
= HBAR_CURSOR_BITMAP
;
690 w
->phys_cursor_on_p
= 0;
691 row
->cursor_in_fringe_p
= 0;
694 if (cursor
!= NO_FRINGE_BITMAP
)
696 draw_fringe_bitmap_1 (w
, row
, 0, 2, cursor
);
697 overlay
= cursor
== FILLED_BOX_CURSOR_BITMAP
? 3 : 1;
701 draw_fringe_bitmap_1 (w
, row
, left_p
, overlay
, NO_FRINGE_BITMAP
);
703 if (left_p
&& row
->overlay_arrow_bitmap
!= NO_FRINGE_BITMAP
)
704 draw_fringe_bitmap_1 (w
, row
, 1, 1,
705 (row
->overlay_arrow_bitmap
< 0
706 ? OVERLAY_ARROW_BITMAP
707 : row
->overlay_arrow_bitmap
));
711 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
712 function with input blocked. */
715 draw_row_fringe_bitmaps (w
, row
)
717 struct glyph_row
*row
;
719 xassert (interrupt_input_blocked
);
721 /* If row is completely invisible, because of vscrolling, we
722 don't have to draw anything. */
723 if (row
->visible_height
<= 0)
726 if (WINDOW_LEFT_FRINGE_WIDTH (w
) != 0)
727 draw_fringe_bitmap (w
, row
, 1);
729 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) != 0)
730 draw_fringe_bitmap (w
, row
, 0);
733 /* Draw the fringes of window W. Only fringes for rows marked for
734 update in redraw_fringe_bitmaps_p are drawn.
736 Return >0 if left or right fringe was redrawn in any way.
738 If NO_FRINGE is non-zero, also return >0 if either fringe has zero width.
740 A return value >0 indicates that the vertical line between windows
741 needs update (as it may be drawn in the fringe).
745 draw_window_fringes (w
, no_fringe
)
749 struct glyph_row
*row
;
750 int yb
= window_text_bottom_y (w
);
751 int nrows
= w
->current_matrix
->nrows
;
755 if (w
->pseudo_window_p
)
758 /* Must draw line if no fringe */
760 && (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0
761 || WINDOW_RIGHT_FRINGE_WIDTH (w
) == 0))
764 for (y
= 0, rn
= 0, row
= w
->current_matrix
->rows
;
765 y
< yb
&& rn
< nrows
;
766 y
+= row
->height
, ++row
, ++rn
)
768 if (!row
->redraw_fringe_bitmaps_p
)
770 draw_row_fringe_bitmaps (w
, row
);
771 row
->redraw_fringe_bitmaps_p
= 0;
779 /* Recalculate the bitmaps to show in the fringes of window W.
780 If FORCE_P is 0, only mark rows with modified bitmaps for update in
781 redraw_fringe_bitmaps_p; else mark all rows for update. */
784 update_window_fringes (w
, force_p
)
788 struct glyph_row
*row
, *cur
= 0;
789 int yb
= window_text_bottom_y (w
);
790 int rn
, nrows
= w
->current_matrix
->nrows
;
793 Lisp_Object boundary_top
= Qnil
, boundary_bot
= Qnil
;
794 Lisp_Object arrow_top
= Qnil
, arrow_bot
= Qnil
;
795 Lisp_Object empty_pos
;
796 Lisp_Object ind
= Qnil
;
798 if (w
->pseudo_window_p
)
801 if (!MINI_WINDOW_P (w
)
802 && (ind
= XBUFFER (w
->buffer
)->indicate_buffer_boundaries
, !NILP (ind
)))
804 if (EQ (ind
, Qleft
) || EQ (ind
, Qright
))
805 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= ind
;
806 else if (CONSP (ind
) && CONSP (XCAR (ind
)))
809 if (pos
= Fassq (Qt
, ind
), !NILP (pos
))
810 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= XCDR (pos
);
811 if (pos
= Fassq (Qtop
, ind
), !NILP (pos
))
812 boundary_top
= XCDR (pos
);
813 if (pos
= Fassq (Qbottom
, ind
), !NILP (pos
))
814 boundary_bot
= XCDR (pos
);
815 if (pos
= Fassq (Qup
, ind
), !NILP (pos
))
816 arrow_top
= XCDR (pos
);
817 if (pos
= Fassq (Qdown
, ind
), !NILP (pos
))
818 arrow_bot
= XCDR (pos
);
821 /* Anything else means boundary on left and no arrows. */
822 boundary_top
= boundary_bot
= Qleft
;
827 int done_top
= 0, done_bot
= 0;
830 y
< yb
&& rn
< nrows
;
831 y
+= row
->height
, ++rn
)
833 unsigned indicate_bob_p
, indicate_top_line_p
;
834 unsigned indicate_eob_p
, indicate_bottom_line_p
;
836 row
= w
->desired_matrix
->rows
+ rn
;
838 row
= w
->current_matrix
->rows
+ rn
;
840 indicate_bob_p
= row
->indicate_bob_p
;
841 indicate_top_line_p
= row
->indicate_top_line_p
;
842 indicate_eob_p
= row
->indicate_eob_p
;
843 indicate_bottom_line_p
= row
->indicate_bottom_line_p
;
845 row
->indicate_bob_p
= row
->indicate_top_line_p
= 0;
846 row
->indicate_eob_p
= row
->indicate_bottom_line_p
= 0;
848 if (!row
->mode_line_p
)
852 if (MATRIX_ROW_START_CHARPOS (row
) <= BUF_BEGV (XBUFFER (w
->buffer
)))
853 row
->indicate_bob_p
= !NILP (boundary_top
);
855 row
->indicate_top_line_p
= !NILP (arrow_top
);
861 if (MATRIX_ROW_END_CHARPOS (row
) >= BUF_ZV (XBUFFER (w
->buffer
)))
862 row
->indicate_eob_p
= !NILP (boundary_bot
), done_bot
= 1;
863 else if (y
+ row
->height
>= yb
)
864 row
->indicate_bottom_line_p
= !NILP (arrow_bot
), done_bot
= 1;
868 if (indicate_bob_p
!= row
->indicate_bob_p
869 || indicate_top_line_p
!= row
->indicate_top_line_p
870 || indicate_eob_p
!= row
->indicate_eob_p
871 || indicate_bottom_line_p
!= row
->indicate_bottom_line_p
)
872 row
->redraw_fringe_bitmaps_p
= 1;
876 empty_pos
= XBUFFER (w
->buffer
)->indicate_empty_lines
;
877 if (!NILP (empty_pos
) && !EQ (empty_pos
, Qright
))
878 empty_pos
= WINDOW_LEFT_FRINGE_WIDTH (w
) == 0 ? Qright
: Qleft
;
881 y
< yb
&& rn
< nrows
;
882 y
+= row
->height
, rn
++)
884 enum fringe_bitmap_type left
, right
;
885 unsigned left_face_id
, right_face_id
;
887 row
= w
->desired_matrix
->rows
+ rn
;
888 cur
= w
->current_matrix
->rows
+ rn
;
892 left_face_id
= right_face_id
= DEFAULT_FACE_ID
;
894 /* Decide which bitmap to draw in the left fringe. */
895 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
896 left
= NO_FRINGE_BITMAP
;
897 else if (row
->left_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
899 left
= row
->left_user_fringe_bitmap
;
900 left_face_id
= row
->left_user_fringe_face_id
;
902 else if (row
->truncated_on_left_p
)
903 left
= LEFT_TRUNCATION_BITMAP
;
904 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qleft
))
905 left
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
906 ? LEFT_BRACKET_BITMAP
: TOP_LEFT_ANGLE_BITMAP
);
907 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
908 left
= BOTTOM_LEFT_ANGLE_BITMAP
;
909 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
910 left
= CONTINUATION_LINE_BITMAP
;
911 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qleft
))
912 left
= ZV_LINE_BITMAP
;
913 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qleft
))
914 left
= UP_ARROW_BITMAP
;
915 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qleft
))
916 left
= DOWN_ARROW_BITMAP
;
918 left
= NO_FRINGE_BITMAP
;
920 /* Decide which bitmap to draw in the right fringe. */
921 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) == 0)
922 right
= NO_FRINGE_BITMAP
;
923 else if (row
->right_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
925 right
= row
->right_user_fringe_bitmap
;
926 right_face_id
= row
->right_user_fringe_face_id
;
928 else if (row
->truncated_on_right_p
)
929 right
= RIGHT_TRUNCATION_BITMAP
;
930 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qright
))
931 right
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
932 ? RIGHT_BRACKET_BITMAP
: TOP_RIGHT_ANGLE_BITMAP
);
933 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
934 right
= BOTTOM_RIGHT_ANGLE_BITMAP
;
935 else if (row
->continued_p
)
936 right
= CONTINUED_LINE_BITMAP
;
937 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qright
))
938 right
= UP_ARROW_BITMAP
;
939 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qright
))
940 right
= DOWN_ARROW_BITMAP
;
941 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qright
))
942 right
= ZV_LINE_BITMAP
;
944 right
= NO_FRINGE_BITMAP
;
948 || row
->visible_height
!= cur
->visible_height
949 || row
->ends_at_zv_p
!= cur
->ends_at_zv_p
950 || left
!= cur
->left_fringe_bitmap
951 || right
!= cur
->right_fringe_bitmap
952 || left_face_id
!= cur
->left_fringe_face_id
953 || right_face_id
!= cur
->right_fringe_face_id
954 || cur
->redraw_fringe_bitmaps_p
)
956 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
957 cur
->left_fringe_bitmap
= left
;
958 cur
->right_fringe_bitmap
= right
;
959 cur
->left_fringe_face_id
= left_face_id
;
960 cur
->right_fringe_face_id
= right_face_id
;
963 if (row
->overlay_arrow_bitmap
!= cur
->overlay_arrow_bitmap
)
965 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
966 cur
->overlay_arrow_bitmap
= row
->overlay_arrow_bitmap
;
969 row
->left_fringe_bitmap
= left
;
970 row
->right_fringe_bitmap
= right
;
971 row
->left_fringe_face_id
= left_face_id
;
972 row
->right_fringe_face_id
= right_face_id
;
974 if (rn
> 0 && row
->redraw_fringe_bitmaps_p
)
975 row
[-1].redraw_fringe_bitmaps_p
= cur
[-1].redraw_fringe_bitmaps_p
= 1;
982 /* Compute actual fringe widths for frame F.
984 If REDRAW is 1, redraw F if the fringe settings was actually
985 modified and F is visible.
987 Since the combined left and right fringe must occupy an integral
988 number of columns, we may need to add some pixels to each fringe.
989 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
990 but a negative width value is taken literally (after negating it).
992 We never make the fringes narrower than specified.
996 compute_fringe_widths (f
, redraw
)
1000 int o_left
= FRAME_LEFT_FRINGE_WIDTH (f
);
1001 int o_right
= FRAME_RIGHT_FRINGE_WIDTH (f
);
1002 int o_cols
= FRAME_FRINGE_COLS (f
);
1004 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
1005 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
1006 int left_fringe_width
, right_fringe_width
;
1008 if (!NILP (left_fringe
))
1009 left_fringe
= Fcdr (left_fringe
);
1010 if (!NILP (right_fringe
))
1011 right_fringe
= Fcdr (right_fringe
);
1013 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
1014 XINT (left_fringe
));
1015 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
1016 XINT (right_fringe
));
1018 if (left_fringe_width
|| right_fringe_width
)
1020 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
1021 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
1022 int conf_wid
= left_wid
+ right_wid
;
1023 int font_wid
= FRAME_COLUMN_WIDTH (f
);
1024 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
1025 int real_wid
= cols
* font_wid
;
1026 if (left_wid
&& right_wid
)
1028 if (left_fringe_width
< 0)
1030 /* Left fringe width is fixed, adjust right fringe if necessary */
1031 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
;
1032 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
- left_wid
;
1034 else if (right_fringe_width
< 0)
1036 /* Right fringe width is fixed, adjust left fringe if necessary */
1037 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
- right_wid
;
1038 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
;
1042 /* Adjust both fringes with an equal amount.
1043 Note that we are doing integer arithmetic here, so don't
1044 lose a pixel if the total width is an odd number. */
1045 int fill
= real_wid
- conf_wid
;
1046 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
+ fill
/2;
1047 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
+ fill
- fill
/2;
1050 else if (left_fringe_width
)
1052 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
;
1053 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1057 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1058 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
;
1060 FRAME_FRINGE_COLS (f
) = cols
;
1064 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1065 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1066 FRAME_FRINGE_COLS (f
) = 0;
1069 if (redraw
&& FRAME_VISIBLE_P (f
))
1070 if (o_left
!= FRAME_LEFT_FRINGE_WIDTH (f
) ||
1071 o_right
!= FRAME_RIGHT_FRINGE_WIDTH (f
) ||
1072 o_cols
!= FRAME_FRINGE_COLS (f
))
1077 /* Free resources used by a user-defined bitmap. */
1080 destroy_fringe_bitmap (n
)
1083 struct fringe_bitmap
**fbp
;
1085 fringe_faces
[n
] = Qnil
;
1087 fbp
= &fringe_bitmaps
[n
];
1088 if (*fbp
&& (*fbp
)->dynamic
)
1090 /* XXX Is SELECTED_FRAME OK here? */
1091 struct redisplay_interface
*rif
= FRAME_RIF (SELECTED_FRAME ());
1092 if (rif
&& rif
->destroy_fringe_bitmap
)
1093 rif
->destroy_fringe_bitmap (n
);
1098 while (max_used_fringe_bitmap
> MAX_STANDARD_FRINGE_BITMAPS
1099 && fringe_bitmaps
[max_used_fringe_bitmap
- 1] == NULL
)
1100 max_used_fringe_bitmap
--;
1104 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap
, Sdestroy_fringe_bitmap
,
1106 doc
: /* Destroy fringe bitmap BITMAP.
1107 If BITMAP overrides a standard fringe bitmap, the original bitmap is restored. */)
1113 CHECK_SYMBOL (bitmap
);
1114 n
= lookup_fringe_bitmap (bitmap
);
1118 destroy_fringe_bitmap (n
);
1120 if (n
>= MAX_STANDARD_FRINGE_BITMAPS
)
1122 Vfringe_bitmaps
= Fdelq (bitmap
, Vfringe_bitmaps
);
1123 /* It would be better to remove the fringe property. */
1124 Fput (bitmap
, Qfringe
, Qnil
);
1131 /* Initialize bitmap bit.
1133 On X, we bit-swap the built-in bitmaps and reduce bitmap
1134 from short to char array if width is <= 8 bits.
1136 On MAC with big-endian CPU, we need to byte-swap each short.
1138 On W32 and MAC (little endian), there's no need to do this.
1142 init_fringe_bitmap (which
, fb
, once_p
)
1143 enum fringe_bitmap_type which
;
1144 struct fringe_bitmap
*fb
;
1147 if (once_p
|| fb
->dynamic
)
1149 #if defined (HAVE_X_WINDOWS)
1150 static unsigned char swap_nibble
[16]
1151 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1152 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1153 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1154 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
1155 unsigned short *bits
= fb
->bits
;
1160 unsigned char *cbits
= (unsigned char *)fb
->bits
;
1161 for (j
= 0; j
< fb
->height
; j
++)
1163 unsigned short b
= *bits
++;
1165 c
= (unsigned char)((swap_nibble
[b
& 0xf] << 4)
1166 | (swap_nibble
[(b
>>4) & 0xf]));
1167 *cbits
++ = (c
>> (8 - fb
->width
));
1172 for (j
= 0; j
< fb
->height
; j
++)
1174 unsigned short b
= *bits
;
1175 b
= (unsigned short)((swap_nibble
[b
& 0xf] << 12)
1176 | (swap_nibble
[(b
>>4) & 0xf] << 8)
1177 | (swap_nibble
[(b
>>8) & 0xf] << 4)
1178 | (swap_nibble
[(b
>>12) & 0xf]));
1179 *bits
++ = (b
>> (16 - fb
->width
));
1182 #endif /* HAVE_X_WINDOWS */
1184 #if defined (MAC_OS) && defined (WORDS_BIG_ENDIAN)
1185 unsigned short *bits
= fb
->bits
;
1187 for (j
= 0; j
< fb
->height
; j
++)
1189 unsigned short b
= *bits
;
1190 *bits
++ = ((b
>> 8) & 0xff) | ((b
& 0xff) << 8);
1192 #endif /* MAC_OS && WORDS_BIG_ENDIAN */
1197 /* XXX Is SELECTED_FRAME OK here? */
1198 struct redisplay_interface
*rif
= FRAME_RIF (SELECTED_FRAME ());
1200 destroy_fringe_bitmap (which
);
1202 if (rif
&& rif
->define_fringe_bitmap
)
1203 rif
->define_fringe_bitmap (which
, fb
->bits
, fb
->height
, fb
->width
);
1205 fringe_bitmaps
[which
] = fb
;
1206 if (which
>= max_used_fringe_bitmap
)
1207 max_used_fringe_bitmap
= which
+ 1;
1212 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap
, Sdefine_fringe_bitmap
,
1214 doc
: /* Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH.
1215 BITMAP is a symbol or string naming the new fringe bitmap.
1216 BITS is either a string or a vector of integers.
1217 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1218 WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1219 Optional fifth arg ALIGN may be one of `top', `center', or `bottom',
1220 indicating the positioning of the bitmap relative to the rows where it
1221 is used; the default is to center the bitmap. Fourth arg may also be a
1222 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1224 If BITMAP already exists, the existing definition is replaced. */)
1225 (bitmap
, bits
, height
, width
, align
)
1226 Lisp_Object bitmap
, bits
, height
, width
, align
;
1230 struct fringe_bitmap fb
, *xfb
;
1231 int fill1
= 0, fill2
= 0;
1233 CHECK_SYMBOL (bitmap
);
1237 else if (VECTORP (bits
))
1238 h
= XVECTOR (bits
)->size
;
1240 bits
= wrong_type_argument (Qsequencep
, bits
);
1246 CHECK_NUMBER (height
);
1247 fb
.height
= min (XINT (height
), 255);
1250 fill1
= (fb
.height
- h
) / 2;
1251 fill2
= fb
.height
- h
- fill1
;
1259 CHECK_NUMBER (width
);
1260 fb
.width
= min (XINT (width
), 255);
1264 fb
.align
= ALIGN_BITMAP_CENTER
;
1268 Lisp_Object period
= XCDR (align
);
1271 period
= XCAR (period
);
1274 fb
.period
= fb
.height
;
1278 align
= XCAR (align
);
1280 if (EQ (align
, Qtop
))
1281 fb
.align
= ALIGN_BITMAP_TOP
;
1282 else if (EQ (align
, Qbottom
))
1283 fb
.align
= ALIGN_BITMAP_BOTTOM
;
1284 else if (!NILP (align
) && !EQ (align
, Qcenter
))
1285 error ("Bad align argument");
1287 n
= lookup_fringe_bitmap (bitmap
);
1290 if (max_used_fringe_bitmap
< max_fringe_bitmaps
)
1291 n
= max_used_fringe_bitmap
++;
1294 for (n
= MAX_STANDARD_FRINGE_BITMAPS
;
1295 n
< max_fringe_bitmaps
;
1297 if (fringe_bitmaps
[n
] == NULL
)
1300 if (n
== max_fringe_bitmaps
)
1302 if ((max_fringe_bitmaps
+ 20) > MAX_FRINGE_BITMAPS
)
1303 error ("No free fringe bitmap slots");
1305 i
= max_fringe_bitmaps
;
1306 max_fringe_bitmaps
+= 20;
1308 = ((struct fringe_bitmap
**)
1309 xrealloc (fringe_bitmaps
, max_fringe_bitmaps
* sizeof (struct fringe_bitmap
*)));
1311 = (Lisp_Object
*) xrealloc (fringe_faces
, max_fringe_bitmaps
* sizeof (Lisp_Object
));
1313 for (; i
< max_fringe_bitmaps
; i
++)
1315 fringe_bitmaps
[i
] = NULL
;
1316 fringe_faces
[i
] = Qnil
;
1321 Vfringe_bitmaps
= Fcons (bitmap
, Vfringe_bitmaps
);
1322 Fput (bitmap
, Qfringe
, make_number (n
));
1327 xfb
= (struct fringe_bitmap
*) xmalloc (sizeof fb
1328 + fb
.height
* BYTES_PER_BITMAP_ROW
);
1329 fb
.bits
= b
= (unsigned short *) (xfb
+ 1);
1330 bzero (b
, fb
.height
);
1333 while (j
< fb
.height
)
1335 for (i
= 0; i
< fill1
&& j
< fb
.height
; i
++)
1337 for (i
= 0; i
< h
&& j
< fb
.height
; i
++)
1339 Lisp_Object elt
= Faref (bits
, make_number (i
));
1340 b
[j
++] = NUMBERP (elt
) ? XINT (elt
) : 0;
1342 for (i
= 0; i
< fill2
&& j
< fb
.height
; i
++)
1348 init_fringe_bitmap (n
, xfb
, 0);
1353 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face
, Sset_fringe_bitmap_face
,
1355 doc
: /* Set face for fringe bitmap BITMAP to FACE.
1356 If FACE is nil, reset face to default fringe face. */)
1358 Lisp_Object bitmap
, face
;
1363 CHECK_SYMBOL (bitmap
);
1364 n
= lookup_fringe_bitmap (bitmap
);
1366 error ("Undefined fringe bitmap");
1370 face_id
= lookup_derived_face (SELECTED_FRAME (), face
,
1371 'A', FRINGE_FACE_ID
, 1);
1373 error ("No such face");
1376 fringe_faces
[n
] = face
;
1381 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos
, Sfringe_bitmaps_at_pos
,
1383 doc
: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1384 If WINDOW is nil, use selected window. If POS is nil, use value of point
1385 in that window. Return value is a list (LEFT RIGHT OV), where LEFT
1386 is the symbol for the bitmap in the left fringe (or nil if no bitmap),
1387 RIGHT is similar for the right fringe, and OV is non-nil if there is an
1388 overlay arrow in the left fringe.
1389 Return nil if POS is not visible in WINDOW. */)
1391 Lisp_Object pos
, window
;
1394 struct glyph_row
*row
;
1398 window
= selected_window
;
1399 CHECK_WINDOW (window
);
1400 w
= XWINDOW (window
);
1404 CHECK_NUMBER_COERCE_MARKER (pos
);
1405 textpos
= XINT (pos
);
1407 else if (w
== XWINDOW (selected_window
))
1410 textpos
= XMARKER (w
->pointm
)->charpos
;
1412 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
1413 row
= row_containing_pos (w
, textpos
, row
, NULL
, 0);
1415 return list3 (get_fringe_bitmap_name (row
->left_fringe_bitmap
),
1416 get_fringe_bitmap_name (row
->right_fringe_bitmap
),
1417 (row
->overlay_arrow_bitmap
== 0 ? Qnil
1418 : row
->overlay_arrow_bitmap
< 0 ? Qt
1419 : get_fringe_bitmap_name (row
->overlay_arrow_bitmap
)));
1425 /***********************************************************************
1427 ***********************************************************************/
1432 defsubr (&Sdestroy_fringe_bitmap
);
1433 defsubr (&Sdefine_fringe_bitmap
);
1434 defsubr (&Sfringe_bitmaps_at_pos
);
1435 defsubr (&Sset_fringe_bitmap_face
);
1437 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe
,
1438 doc
: /* *Non-nil means that newline may flow into the right fringe.
1439 This means that display lines which are exactly as wide as the window
1440 (not counting the final newline) will only occupy one screen line, by
1441 showing (or hiding) the final newline in the right fringe; when point
1442 is at the final newline, the cursor is shown in the right fringe.
1443 If nil, also continue lines which are exactly as wide as the window. */);
1444 Voverflow_newline_into_fringe
= Qt
;
1446 DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps
,
1447 doc
: /* List of fringe bitmap symbols.
1448 You must (require 'fringe) to use fringe bitmap symbols in your programs." */);
1449 Vfringe_bitmaps
= Qnil
;
1452 /* Garbage collection hook */
1459 for (i
= 0; i
< max_fringe_bitmaps
; i
++)
1460 if (!NILP (fringe_faces
[i
]))
1461 mark_object (fringe_faces
[i
]);
1464 /* Initialize this module when Emacs starts. */
1469 enum fringe_bitmap_type bt
;
1471 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1472 init_fringe_bitmap(bt
, &standard_bitmaps
[bt
], 1);
1480 max_fringe_bitmaps
= MAX_STANDARD_FRINGE_BITMAPS
+ 20;
1483 = (struct fringe_bitmap
**) xmalloc (max_fringe_bitmaps
* sizeof (struct fringe_bitmap
*));
1485 = (Lisp_Object
*) xmalloc (max_fringe_bitmaps
* sizeof (Lisp_Object
));
1487 for (i
= 0; i
< max_fringe_bitmaps
; i
++)
1489 fringe_bitmaps
[i
] = NULL
;
1490 fringe_faces
[i
] = Qnil
;
1499 enum fringe_bitmap_type bt
;
1504 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1506 struct fringe_bitmap
*fb
= &standard_bitmaps
[bt
];
1507 rif
->define_fringe_bitmap (bt
, fb
->bits
, fb
->height
, fb
->width
);
1512 w32_reset_fringes ()
1514 /* Destroy row bitmaps. */
1520 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< max_used_fringe_bitmap
; bt
++)
1521 rif
->destroy_fringe_bitmap (bt
);
1524 #endif /* HAVE_NTGUI */
1526 #endif /* HAVE_WINDOW_SYSTEM */
1528 /* arch-tag: 04596920-43eb-473d-b319-82712338162d
1529 (do not change this comment) */