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"
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
[MAX_FRINGE_BITMAPS
];
450 static unsigned fringe_faces
[MAX_FRINGE_BITMAPS
];
452 static int max_used_fringe_bitmap
= MAX_STANDARD_FRINGE_BITMAPS
;
454 /* Return 1 if FRINGE_ID is a valid fringe bitmap id. */
457 valid_fringe_bitmap_p (bitmap
)
462 if (!INTEGERP (bitmap
))
466 return (bn
>= NO_FRINGE_BITMAP
467 && bn
< max_used_fringe_bitmap
468 && (bn
< MAX_STANDARD_FRINGE_BITMAPS
469 || fringe_bitmaps
[bn
] != NULL
));
472 /* Get fringe bitmap name for bitmap number BN.
474 Found by traversing Vfringe_bitmaps comparing BN to the
475 fringe property for each symbol.
477 Return BN if not found in Vfringe_bitmaps. */
480 get_fringe_bitmap_name (bn
)
486 /* Zero means no bitmap -- return nil. */
490 bitmaps
= Vfringe_bitmaps
;
491 num
= make_number (bn
);
493 while (CONSP (bitmaps
))
495 Lisp_Object bitmap
= XCAR (bitmaps
);
496 if (EQ (num
, Fget (bitmap
, Qfringe
)))
498 bitmaps
= XCDR (bitmaps
);
505 /* Resolve a BITMAP parameter.
507 An INTEGER, corresponding to a bitmap number.
508 A STRING which is interned to a symbol.
509 A SYMBOL which has a fringe property which is a bitmap number.
513 resolve_fringe_bitmap (bitmap
, namep
)
520 if (STRINGP (bitmap
))
521 bitmap
= intern (SDATA (bitmap
));
523 if (SYMBOLP (bitmap
))
527 bitmap
= Fget (bitmap
, Qfringe
);
530 if (valid_fringe_bitmap_p (bitmap
))
532 if (namep
&& NILP (*namep
))
533 *namep
= get_fringe_bitmap_name (XINT (bitmap
));
534 return XINT (bitmap
);
541 /* Draw the bitmap WHICH in one of the left or right fringes of
542 window W. ROW is the glyph row for which to display the bitmap; it
543 determines the vertical position at which the bitmap has to be
545 LEFT_P is 1 for left fringe, 0 for right fringe.
549 draw_fringe_bitmap_1 (w
, row
, left_p
, overlay
, which
)
551 struct glyph_row
*row
;
553 enum fringe_bitmap_type which
;
555 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
556 struct draw_fringe_bitmap_params p
;
557 struct fringe_bitmap
*fb
;
559 int face_id
= DEFAULT_FACE_ID
;
562 p
.overlay_p
= (overlay
& 1) == 1;
563 p
.cursor_p
= (overlay
& 2) == 2;
565 if (which
!= NO_FRINGE_BITMAP
)
570 which
= row
->left_fringe_bitmap
;
571 face_id
= row
->left_fringe_face_id
;
575 which
= row
->right_fringe_bitmap
;
576 face_id
= row
->right_fringe_face_id
;
579 if (face_id
== DEFAULT_FACE_ID
)
580 face_id
= fringe_faces
[which
];
582 fb
= fringe_bitmaps
[which
];
584 fb
= &standard_bitmaps
[which
< MAX_STANDARD_FRINGE_BITMAPS
585 ? which
: UNDEF_FRINGE_BITMAP
];
589 /* Convert row to frame coordinates. */
590 p
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
597 p
.dh
= (period
> 0 ? (p
.y
% period
) : 0);
599 /* Clip bitmap if too high. */
600 if (p
.h
> row
->height
)
603 p
.face
= FACE_FROM_ID (f
, face_id
);
607 /* Why does this happen? ++kfs */
611 PREPARE_FACE_FOR_DISPLAY (f
, p
.face
);
613 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
618 int wd
= WINDOW_LEFT_FRINGE_WIDTH (w
);
619 int x
= window_box_left (w
, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
624 p
.x
= x
- p
.wd
- (wd
- p
.wd
) / 2;
626 if (p
.wd
< wd
|| row
->height
> p
.h
)
628 /* If W has a vertical border to its left, don't draw over it. */
629 wd
-= ((!WINDOW_LEFTMOST_P (w
)
630 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
638 int x
= window_box_right (w
,
639 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
642 int wd
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
645 p
.x
= x
+ (wd
- p
.wd
) / 2;
646 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
648 if (p
.wd
< wd
|| row
->height
> p
.h
)
657 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
659 p
.by
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, row
->y
));
660 p
.ny
= row
->visible_height
;
663 /* Adjust y to the offset in the row to start drawing the bitmap. */
666 case ALIGN_BITMAP_CENTER
:
667 p
.y
+= (row
->height
- p
.h
) / 2;
669 case ALIGN_BITMAP_BOTTOM
:
671 p
.y
+= (row
->visible_height
- p
.h
);
673 case ALIGN_BITMAP_TOP
:
677 FRAME_RIF (f
)->draw_fringe_bitmap (w
, row
, &p
);
681 draw_fringe_bitmap (w
, row
, left_p
)
683 struct glyph_row
*row
;
688 if (!left_p
&& row
->cursor_in_fringe_p
)
690 int cursor
= NO_FRINGE_BITMAP
;
692 switch (w
->phys_cursor_type
)
694 case HOLLOW_BOX_CURSOR
:
695 if (row
->visible_height
>= STANDARD_BITMAP_HEIGHT (hollow_box_cursor_bits
))
696 cursor
= HOLLOW_BOX_CURSOR_BITMAP
;
698 cursor
= HOLLOW_SQUARE_BITMAP
;
700 case FILLED_BOX_CURSOR
:
701 cursor
= FILLED_BOX_CURSOR_BITMAP
;
704 cursor
= BAR_CURSOR_BITMAP
;
707 cursor
= HBAR_CURSOR_BITMAP
;
711 w
->phys_cursor_on_p
= 0;
712 row
->cursor_in_fringe_p
= 0;
715 if (cursor
!= NO_FRINGE_BITMAP
)
717 draw_fringe_bitmap_1 (w
, row
, 0, 2, cursor
);
718 overlay
= cursor
== FILLED_BOX_CURSOR_BITMAP
? 3 : 1;
722 draw_fringe_bitmap_1 (w
, row
, left_p
, overlay
, NO_FRINGE_BITMAP
);
724 if (left_p
&& row
->overlay_arrow_p
)
725 draw_fringe_bitmap_1 (w
, row
, 1, 1,
726 (w
->overlay_arrow_bitmap
727 ? w
->overlay_arrow_bitmap
728 : OVERLAY_ARROW_BITMAP
));
732 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
733 function with input blocked. */
736 draw_row_fringe_bitmaps (w
, row
)
738 struct glyph_row
*row
;
740 xassert (interrupt_input_blocked
);
742 /* If row is completely invisible, because of vscrolling, we
743 don't have to draw anything. */
744 if (row
->visible_height
<= 0)
747 if (WINDOW_LEFT_FRINGE_WIDTH (w
) != 0)
748 draw_fringe_bitmap (w
, row
, 1);
750 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) != 0)
751 draw_fringe_bitmap (w
, row
, 0);
754 /* Draw the fringes of window W. Only fringes for rows marked for
755 update in redraw_fringe_bitmaps_p are drawn. */
758 draw_window_fringes (w
)
761 struct glyph_row
*row
;
762 int yb
= window_text_bottom_y (w
);
763 int nrows
= w
->current_matrix
->nrows
;
766 if (w
->pseudo_window_p
)
769 for (y
= 0, rn
= 0, row
= w
->current_matrix
->rows
;
770 y
< yb
&& rn
< nrows
;
771 y
+= row
->height
, ++row
, ++rn
)
773 if (!row
->redraw_fringe_bitmaps_p
)
775 draw_row_fringe_bitmaps (w
, row
);
776 row
->redraw_fringe_bitmaps_p
= 0;
781 /* Recalculate the bitmaps to show in the fringes of window W.
782 If FORCE_P is 0, only mark rows with modified bitmaps for update in
783 redraw_fringe_bitmaps_p; else mark all rows for update. */
786 update_window_fringes (w
, force_p
)
790 struct glyph_row
*row
, *cur
= 0;
791 int yb
= window_text_bottom_y (w
);
792 int rn
, nrows
= w
->current_matrix
->nrows
;
795 Lisp_Object boundary_top
= Qnil
, boundary_bot
= Qnil
;
796 Lisp_Object arrow_top
= Qnil
, arrow_bot
= Qnil
;
797 Lisp_Object empty_pos
;
798 Lisp_Object ind
= Qnil
;
800 if (w
->pseudo_window_p
)
803 if (!MINI_WINDOW_P (w
)
804 && (ind
= XBUFFER (w
->buffer
)->indicate_buffer_boundaries
, !NILP (ind
)))
806 if (EQ (ind
, Qleft
) || EQ (ind
, Qright
))
807 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= ind
;
808 else if (CONSP (ind
) && CONSP (XCAR (ind
)))
811 if (pos
= Fassq (Qt
, ind
), !NILP (pos
))
812 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= XCDR (pos
);
813 if (pos
= Fassq (Qtop
, ind
), !NILP (pos
))
814 boundary_top
= XCDR (pos
);
815 if (pos
= Fassq (Qbottom
, ind
), !NILP (pos
))
816 boundary_bot
= XCDR (pos
);
817 if (pos
= Fassq (Qup
, ind
), !NILP (pos
))
818 arrow_top
= XCDR (pos
);
819 if (pos
= Fassq (Qdown
, ind
), !NILP (pos
))
820 arrow_bot
= XCDR (pos
);
828 int do_eob
= 1, do_bob
= 1;
831 y
< yb
&& rn
< nrows
;
832 y
+= row
->height
, ++rn
)
834 unsigned indicate_bob_p
, indicate_top_line_p
;
835 unsigned indicate_eob_p
, indicate_bottom_line_p
;
837 row
= w
->desired_matrix
->rows
+ rn
;
839 row
= w
->current_matrix
->rows
+ rn
;
841 indicate_bob_p
= row
->indicate_bob_p
;
842 indicate_top_line_p
= row
->indicate_top_line_p
;
843 indicate_eob_p
= row
->indicate_eob_p
;
844 indicate_bottom_line_p
= row
->indicate_bottom_line_p
;
846 row
->indicate_bob_p
= row
->indicate_top_line_p
= 0;
847 row
->indicate_eob_p
= row
->indicate_bottom_line_p
= 0;
849 if (!NILP (boundary_top
)
850 && MATRIX_ROW_START_CHARPOS (row
) <= BUF_BEGV (XBUFFER (w
->buffer
)))
851 row
->indicate_bob_p
= do_bob
, do_bob
= 0;
852 else if (!NILP (arrow_top
)
853 && (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0) == rn
)
854 row
->indicate_top_line_p
= 1;
856 if (!NILP (boundary_bot
)
857 && MATRIX_ROW_END_CHARPOS (row
) >= BUF_ZV (XBUFFER (w
->buffer
)))
858 row
->indicate_eob_p
= do_eob
, do_eob
= 0;
859 else if (!NILP (arrow_bot
)
860 && y
+ row
->height
>= yb
)
861 row
->indicate_bottom_line_p
= 1;
863 if (indicate_bob_p
!= row
->indicate_bob_p
864 || indicate_top_line_p
!= row
->indicate_top_line_p
865 || indicate_eob_p
!= row
->indicate_eob_p
866 || indicate_bottom_line_p
!= row
->indicate_bottom_line_p
)
867 row
->redraw_fringe_bitmaps_p
= 1;
871 empty_pos
= XBUFFER (w
->buffer
)->indicate_empty_lines
;
872 if (!NILP (empty_pos
) && !EQ (empty_pos
, Qright
))
873 empty_pos
= WINDOW_LEFT_FRINGE_WIDTH (w
) == 0 ? Qright
: Qleft
;
876 y
< yb
&& rn
< nrows
;
877 y
+= row
->height
, rn
++)
879 enum fringe_bitmap_type left
, right
;
880 unsigned left_face_id
, right_face_id
;
882 row
= w
->desired_matrix
->rows
+ rn
;
883 cur
= w
->current_matrix
->rows
+ rn
;
887 left_face_id
= right_face_id
= DEFAULT_FACE_ID
;
889 /* Decide which bitmap to draw in the left fringe. */
890 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
891 left
= NO_FRINGE_BITMAP
;
892 else if (row
->left_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
894 left
= row
->left_user_fringe_bitmap
;
895 left_face_id
= row
->left_user_fringe_face_id
;
897 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qleft
))
898 left
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
899 ? LEFT_BRACKET_BITMAP
: TOP_LEFT_ANGLE_BITMAP
);
900 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
901 left
= BOTTOM_LEFT_ANGLE_BITMAP
;
902 else if (row
->truncated_on_left_p
)
903 left
= LEFT_TRUNCATION_BITMAP
;
904 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
905 left
= CONTINUATION_LINE_BITMAP
;
906 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qleft
))
907 left
= ZV_LINE_BITMAP
;
908 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qleft
))
909 left
= UP_ARROW_BITMAP
;
910 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qleft
))
911 left
= DOWN_ARROW_BITMAP
;
913 left
= NO_FRINGE_BITMAP
;
915 /* Decide which bitmap to draw in the right fringe. */
916 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) == 0)
917 right
= NO_FRINGE_BITMAP
;
918 else if (row
->right_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
920 right
= row
->right_user_fringe_bitmap
;
921 right_face_id
= row
->right_user_fringe_face_id
;
923 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qright
))
924 right
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
925 ? RIGHT_BRACKET_BITMAP
: TOP_RIGHT_ANGLE_BITMAP
);
926 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
927 right
= BOTTOM_RIGHT_ANGLE_BITMAP
;
928 else if (row
->truncated_on_right_p
)
929 right
= RIGHT_TRUNCATION_BITMAP
;
930 else if (row
->continued_p
)
931 right
= CONTINUED_LINE_BITMAP
;
932 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qright
))
933 right
= UP_ARROW_BITMAP
;
934 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qright
))
935 right
= DOWN_ARROW_BITMAP
;
936 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qright
))
937 right
= ZV_LINE_BITMAP
;
939 right
= NO_FRINGE_BITMAP
;
943 || row
->visible_height
!= cur
->visible_height
944 || left
!= cur
->left_fringe_bitmap
945 || right
!= cur
->right_fringe_bitmap
946 || left_face_id
!= cur
->left_fringe_face_id
947 || right_face_id
!= cur
->right_fringe_face_id
948 || cur
->redraw_fringe_bitmaps_p
)
950 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
951 cur
->left_fringe_bitmap
= left
;
952 cur
->right_fringe_bitmap
= right
;
953 cur
->left_fringe_face_id
= left_face_id
;
954 cur
->right_fringe_face_id
= right_face_id
;
957 if (row
->overlay_arrow_p
!= cur
->overlay_arrow_p
)
959 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
960 cur
->overlay_arrow_p
= row
->overlay_arrow_p
;
963 row
->left_fringe_bitmap
= left
;
964 row
->right_fringe_bitmap
= right
;
965 row
->left_fringe_face_id
= left_face_id
;
966 row
->right_fringe_face_id
= right_face_id
;
973 /* Compute actual fringe widths for frame F.
975 If REDRAW is 1, redraw F if the fringe settings was actually
976 modified and F is visible.
978 Since the combined left and right fringe must occupy an integral
979 number of columns, we may need to add some pixels to each fringe.
980 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
981 but a negative width value is taken literally (after negating it).
983 We never make the fringes narrower than specified. It is planned
984 to make fringe bitmaps customizable and expandable, and at that
985 time, the user will typically specify the minimum number of pixels
986 needed for his bitmaps, so we shouldn't select anything less than
991 compute_fringe_widths (f
, redraw
)
995 int o_left
= FRAME_LEFT_FRINGE_WIDTH (f
);
996 int o_right
= FRAME_RIGHT_FRINGE_WIDTH (f
);
997 int o_cols
= FRAME_FRINGE_COLS (f
);
999 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
1000 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
1001 int left_fringe_width
, right_fringe_width
;
1003 if (!NILP (left_fringe
))
1004 left_fringe
= Fcdr (left_fringe
);
1005 if (!NILP (right_fringe
))
1006 right_fringe
= Fcdr (right_fringe
);
1008 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
1009 XINT (left_fringe
));
1010 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
1011 XINT (right_fringe
));
1013 if (left_fringe_width
|| right_fringe_width
)
1015 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
1016 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
1017 int conf_wid
= left_wid
+ right_wid
;
1018 int font_wid
= FRAME_COLUMN_WIDTH (f
);
1019 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
1020 int real_wid
= cols
* font_wid
;
1021 if (left_wid
&& right_wid
)
1023 if (left_fringe_width
< 0)
1025 /* Left fringe width is fixed, adjust right fringe if necessary */
1026 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
;
1027 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
- left_wid
;
1029 else if (right_fringe_width
< 0)
1031 /* Right fringe width is fixed, adjust left fringe if necessary */
1032 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
- right_wid
;
1033 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
;
1037 /* Adjust both fringes with an equal amount.
1038 Note that we are doing integer arithmetic here, so don't
1039 lose a pixel if the total width is an odd number. */
1040 int fill
= real_wid
- conf_wid
;
1041 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
+ fill
/2;
1042 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
+ fill
- fill
/2;
1045 else if (left_fringe_width
)
1047 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
;
1048 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1052 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1053 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
;
1055 FRAME_FRINGE_COLS (f
) = cols
;
1059 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1060 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1061 FRAME_FRINGE_COLS (f
) = 0;
1064 if (redraw
&& FRAME_VISIBLE_P (f
))
1065 if (o_left
!= FRAME_LEFT_FRINGE_WIDTH (f
) ||
1066 o_right
!= FRAME_RIGHT_FRINGE_WIDTH (f
) ||
1067 o_cols
!= FRAME_FRINGE_COLS (f
))
1073 destroy_fringe_bitmap (n
)
1076 struct fringe_bitmap
**fbp
;
1078 fringe_faces
[n
] = FRINGE_FACE_ID
;
1080 fbp
= &fringe_bitmaps
[n
];
1081 if (*fbp
&& (*fbp
)->dynamic
)
1083 /* XXX Is SELECTED_FRAME OK here? */
1084 if (FRAME_RIF (SELECTED_FRAME ())->destroy_fringe_bitmap
)
1085 FRAME_RIF (SELECTED_FRAME ())->destroy_fringe_bitmap (n
);
1090 while (max_used_fringe_bitmap
> MAX_STANDARD_FRINGE_BITMAPS
1091 && fringe_bitmaps
[max_used_fringe_bitmap
- 1] == NULL
)
1092 max_used_fringe_bitmap
--;
1096 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap
, Sdestroy_fringe_bitmap
,
1098 doc
: /* Destroy fringe bitmap BITMAP.
1099 If BITMAP overrides a standard fringe bitmap, the original bitmap is restored. */)
1106 n
= resolve_fringe_bitmap (bitmap
, &sym
);
1110 destroy_fringe_bitmap (n
);
1114 Vfringe_bitmaps
= Fdelq (sym
, Vfringe_bitmaps
);
1115 /* It would be better to remove the fringe property. */
1116 Fput (sym
, Qfringe
, Qnil
);
1122 /* Initialize bitmap bit.
1124 On X, we bit-swap the built-in bitmaps and reduce bitmap
1125 from short to char array if width is <= 8 bits.
1127 On MAC with big-endian CPU, we need to byte-swap each short.
1129 On W32 and MAC (little endian), there's no need to do this.
1133 init_fringe_bitmap (which
, fb
, once_p
)
1134 enum fringe_bitmap_type which
;
1135 struct fringe_bitmap
*fb
;
1138 if (once_p
|| fb
->dynamic
)
1140 #if defined (HAVE_X_WINDOWS)
1141 static unsigned char swap_nibble
[16]
1142 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1143 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1144 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1145 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
1146 unsigned short *bits
= fb
->bits
;
1151 unsigned char *cbits
= (unsigned char *)fb
->bits
;
1152 for (j
= 0; j
< fb
->height
; j
++)
1154 unsigned short b
= *bits
++;
1156 c
= (unsigned char)((swap_nibble
[b
& 0xf] << 4)
1157 | (swap_nibble
[(b
>>4) & 0xf]));
1158 *cbits
++ = (c
>> (8 - fb
->width
));
1163 for (j
= 0; j
< fb
->height
; j
++)
1165 unsigned short b
= *bits
;
1166 b
= (unsigned short)((swap_nibble
[b
& 0xf] << 12)
1167 | (swap_nibble
[(b
>>4) & 0xf] << 8)
1168 | (swap_nibble
[(b
>>8) & 0xf] << 4)
1169 | (swap_nibble
[(b
>>12) & 0xf]));
1170 *bits
++ = (b
>> (16 - fb
->width
));
1173 #endif /* HAVE_X_WINDOWS */
1175 #if defined (MAC_OS) && defined (WORDS_BIG_ENDIAN)
1176 unsigned short *bits
= fb
->bits
;
1178 for (j
= 0; j
< fb
->height
; j
++)
1180 unsigned short b
= *bits
;
1181 *bits
++ = ((b
>> 8) & 0xff) | ((b
& 0xff) << 8);
1183 #endif /* MAC_OS && WORDS_BIG_ENDIAN */
1188 destroy_fringe_bitmap (which
);
1190 /* XXX Is SELECTED_FRAME OK here? */
1191 if (FRAME_RIF (SELECTED_FRAME ())->define_fringe_bitmap
)
1192 FRAME_RIF (SELECTED_FRAME ())->define_fringe_bitmap (which
, fb
->bits
, fb
->height
, fb
->width
);
1194 fringe_bitmaps
[which
] = fb
;
1195 if (which
>= max_used_fringe_bitmap
)
1196 max_used_fringe_bitmap
= which
+ 1;
1201 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap
, Sdefine_fringe_bitmap
,
1203 doc
: /* Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH.
1204 BITMAP is a symbol or string naming the new fringe bitmap.
1205 BITS is either a string or a vector of integers.
1206 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1207 WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1208 Optional fifth arg ALIGN may be one of `top', `center', or `bottom',
1209 indicating the positioning of the bitmap relative to the rows where it
1210 is used; the default is to center the bitmap. Fourth arg may also be a
1211 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1213 If BITMAP already exists, the existing definition is replaced. */)
1214 (bitmap
, bits
, height
, width
, align
)
1215 Lisp_Object bitmap
, bits
, height
, width
, align
;
1220 struct fringe_bitmap fb
, *xfb
;
1221 int fill1
= 0, fill2
= 0;
1224 n
= resolve_fringe_bitmap (bitmap
, &sym
);
1226 if (NILP (sym
) || INTEGERP (sym
))
1227 sym
= wrong_type_argument (Qsymbolp
, bitmap
);
1229 if (!STRINGP (bits
) && !VECTORP (bits
))
1230 bits
= wrong_type_argument (Qstringp
, bits
);
1232 len
= Flength (bits
);
1235 h
= fb
.height
= XINT (len
);
1238 CHECK_NUMBER (height
);
1239 fb
.height
= min (XINT (height
), 255);
1240 if (fb
.height
> XINT (len
))
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");
1282 if (max_used_fringe_bitmap
< MAX_FRINGE_BITMAPS
)
1283 n
= max_used_fringe_bitmap
++;
1286 for (n
= MAX_STANDARD_FRINGE_BITMAPS
;
1287 n
< MAX_FRINGE_BITMAPS
;
1289 if (fringe_bitmaps
[n
] == NULL
)
1291 if (n
== MAX_FRINGE_BITMAPS
)
1292 error ("Cannot define more fringe bitmaps");
1295 Vfringe_bitmaps
= Fcons (sym
, Vfringe_bitmaps
);
1296 Fput (sym
, Qfringe
, make_number (n
));
1301 xfb
= (struct fringe_bitmap
*) xmalloc (sizeof fb
1302 + fb
.height
* BYTES_PER_BITMAP_ROW
);
1303 fb
.bits
= b
= (unsigned short *) (xfb
+ 1);
1304 bzero (b
, fb
.height
);
1307 while (j
< fb
.height
)
1309 for (i
= 0; i
< fill1
&& j
< fb
.height
; i
++)
1311 for (i
= 0; i
< h
&& j
< fb
.height
; i
++)
1313 Lisp_Object elt
= Faref (bits
, make_number (i
));
1314 b
[j
++] = NUMBERP (elt
) ? XINT (elt
) : 0;
1316 for (i
= 0; i
< fill2
&& j
< fb
.height
; i
++)
1322 init_fringe_bitmap (n
, xfb
, 0);
1327 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face
, Sset_fringe_bitmap_face
,
1329 doc
: /* Set face for fringe bitmap BITMAP to FACE.
1330 If FACE is nil, reset face to default fringe face. */)
1332 Lisp_Object bitmap
, face
;
1337 bn
= resolve_fringe_bitmap (bitmap
, 0);
1339 error ("Undefined fringe bitmap");
1343 face_id
= lookup_named_face (SELECTED_FRAME (), face
, 'A');
1345 error ("No such face");
1348 face_id
= FRINGE_FACE_ID
;
1350 fringe_faces
[bn
] = face_id
;
1355 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos
, Sfringe_bitmaps_at_pos
,
1357 doc
: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1358 If WINDOW is nil, use selected window. If POS is nil, use value of point
1359 in that window. Return value is a cons (LEFT . RIGHT) where LEFT and RIGHT
1360 are the fringe bitmap numbers for the bitmaps in the left and right fringe,
1361 resp. If left or right fringe is empty, the corresponding element is nil.
1362 Return nil if POS is not visible in WINDOW. */)
1364 Lisp_Object pos
, window
;
1367 struct glyph_row
*row
;
1371 window
= selected_window
;
1372 CHECK_WINDOW (window
);
1373 w
= XWINDOW (window
);
1377 CHECK_NUMBER_COERCE_MARKER (pos
);
1378 textpos
= XINT (pos
);
1380 else if (w
== XWINDOW (selected_window
))
1383 textpos
= XMARKER (w
->pointm
)->charpos
;
1385 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
1386 row
= row_containing_pos (w
, textpos
, row
, NULL
, 0);
1388 return Fcons (get_fringe_bitmap_name (row
->left_fringe_bitmap
),
1389 get_fringe_bitmap_name (row
->right_fringe_bitmap
));
1395 /***********************************************************************
1397 ***********************************************************************/
1402 defsubr (&Sdestroy_fringe_bitmap
);
1403 defsubr (&Sdefine_fringe_bitmap
);
1404 defsubr (&Sfringe_bitmaps_at_pos
);
1405 defsubr (&Sset_fringe_bitmap_face
);
1407 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe
,
1408 doc
: /* *Non-nil means that newline may flow into the right fringe.
1409 This means that display lines which are exactly as wide as the window
1410 (not counting the final newline) will only occupy one screen line, by
1411 showing (or hiding) the final newline in the right fringe; when point
1412 is at the final newline, the cursor is shown in the right fringe.
1413 If nil, also continue lines which are exactly as wide as the window. */);
1414 Voverflow_newline_into_fringe
= Qt
;
1416 DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps
,
1417 doc
: /* List of fringe bitmap symbols.
1418 You must (require 'fringe) to use fringe bitmap symbols in your programs." */);
1419 Vfringe_bitmaps
= Qnil
;
1422 /* Initialize this module when Emacs starts. */
1427 enum fringe_bitmap_type bt
;
1429 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1430 init_fringe_bitmap(bt
, &standard_bitmaps
[bt
], 1);
1438 bzero (fringe_bitmaps
, sizeof fringe_bitmaps
);
1439 for (i
= 0; i
< MAX_FRINGE_BITMAPS
; i
++)
1440 fringe_faces
[i
] = FRINGE_FACE_ID
;
1448 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. */
1463 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< max_used_fringe_bitmap
; bt
++)
1464 rif
->destroy_fringe_bitmap (bt
);
1467 #endif /* HAVE_NTGUI */
1469 #endif /* HAVE_WINDOW_SYSTEM */
1471 /* arch-tag: 04596920-43eb-473d-b319-82712338162d
1472 (do not change this comment) */