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
[MAX_FRINGE_BITMAPS
];
449 static unsigned fringe_faces
[MAX_FRINGE_BITMAPS
];
451 static int max_used_fringe_bitmap
= MAX_STANDARD_FRINGE_BITMAPS
;
453 /* Return 1 if FRINGE_ID is a valid fringe bitmap id. */
456 valid_fringe_bitmap_p (bitmap
)
461 if (!INTEGERP (bitmap
))
465 return (bn
>= NO_FRINGE_BITMAP
466 && bn
< max_used_fringe_bitmap
467 && (bn
< MAX_STANDARD_FRINGE_BITMAPS
468 || fringe_bitmaps
[bn
] != NULL
));
471 /* Get fringe bitmap name for bitmap number BN.
473 Found by traversing Vfringe_bitmaps comparing BN to the
474 fringe property for each symbol.
476 Return BN if not found in Vfringe_bitmaps. */
479 get_fringe_bitmap_name (bn
)
485 /* Zero means no bitmap -- return nil. */
489 bitmaps
= Vfringe_bitmaps
;
490 num
= make_number (bn
);
492 while (CONSP (bitmaps
))
494 Lisp_Object bitmap
= XCAR (bitmaps
);
495 if (EQ (num
, Fget (bitmap
, Qfringe
)))
497 bitmaps
= XCDR (bitmaps
);
504 /* Resolve a BITMAP parameter.
506 An INTEGER, corresponding to a bitmap number.
507 A STRING which is interned to a symbol.
508 A SYMBOL which has a fringe property which is a bitmap number.
512 resolve_fringe_bitmap (bitmap
, namep
)
519 if (STRINGP (bitmap
))
520 bitmap
= intern (SDATA (bitmap
));
522 if (SYMBOLP (bitmap
))
526 bitmap
= Fget (bitmap
, Qfringe
);
529 if (valid_fringe_bitmap_p (bitmap
))
531 if (namep
&& NILP (*namep
))
532 *namep
= get_fringe_bitmap_name (XINT (bitmap
));
533 return XINT (bitmap
);
540 /* Draw the bitmap WHICH in one of the left or right fringes of
541 window W. ROW is the glyph row for which to display the bitmap; it
542 determines the vertical position at which the bitmap has to be
544 LEFT_P is 1 for left fringe, 0 for right fringe.
548 draw_fringe_bitmap_1 (w
, row
, left_p
, overlay
, which
)
550 struct glyph_row
*row
;
552 enum fringe_bitmap_type which
;
554 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
555 struct draw_fringe_bitmap_params p
;
556 struct fringe_bitmap
*fb
;
558 int face_id
= DEFAULT_FACE_ID
;
561 p
.overlay_p
= (overlay
& 1) == 1;
562 p
.cursor_p
= (overlay
& 2) == 2;
564 if (which
!= NO_FRINGE_BITMAP
)
569 which
= row
->left_fringe_bitmap
;
570 face_id
= row
->left_fringe_face_id
;
574 which
= row
->right_fringe_bitmap
;
575 face_id
= row
->right_fringe_face_id
;
578 if (face_id
== DEFAULT_FACE_ID
)
579 face_id
= fringe_faces
[which
];
581 fb
= fringe_bitmaps
[which
];
583 fb
= &standard_bitmaps
[which
< MAX_STANDARD_FRINGE_BITMAPS
584 ? which
: UNDEF_FRINGE_BITMAP
];
588 /* Convert row to frame coordinates. */
589 p
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
596 p
.dh
= (period
> 0 ? (p
.y
% period
) : 0);
598 /* Clip bitmap if too high. */
599 if (p
.h
> row
->height
)
602 p
.face
= FACE_FROM_ID (f
, face_id
);
606 /* Why does this happen? ++kfs */
610 PREPARE_FACE_FOR_DISPLAY (f
, p
.face
);
612 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
617 int wd
= WINDOW_LEFT_FRINGE_WIDTH (w
);
618 int x
= window_box_left (w
, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
623 p
.x
= x
- p
.wd
- (wd
- p
.wd
) / 2;
625 if (p
.wd
< wd
|| row
->height
> p
.h
)
627 /* If W has a vertical border to its left, don't draw over it. */
628 wd
-= ((!WINDOW_LEFTMOST_P (w
)
629 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
637 int x
= window_box_right (w
,
638 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
641 int wd
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
644 p
.x
= x
+ (wd
- p
.wd
) / 2;
645 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
647 if (p
.wd
< wd
|| row
->height
> p
.h
)
656 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
658 p
.by
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, row
->y
));
659 p
.ny
= row
->visible_height
;
662 /* Adjust y to the offset in the row to start drawing the bitmap. */
665 case ALIGN_BITMAP_CENTER
:
666 p
.y
+= (row
->height
- p
.h
) / 2;
668 case ALIGN_BITMAP_BOTTOM
:
670 p
.y
+= (row
->visible_height
- p
.h
);
672 case ALIGN_BITMAP_TOP
:
676 rif
->draw_fringe_bitmap (w
, row
, &p
);
680 draw_fringe_bitmap (w
, row
, left_p
)
682 struct glyph_row
*row
;
687 if (!left_p
&& row
->cursor_in_fringe_p
)
689 int cursor
= NO_FRINGE_BITMAP
;
691 switch (w
->phys_cursor_type
)
693 case HOLLOW_BOX_CURSOR
:
694 if (row
->visible_height
>= STANDARD_BITMAP_HEIGHT (hollow_box_cursor_bits
))
695 cursor
= HOLLOW_BOX_CURSOR_BITMAP
;
697 cursor
= HOLLOW_SQUARE_BITMAP
;
699 case FILLED_BOX_CURSOR
:
700 cursor
= FILLED_BOX_CURSOR_BITMAP
;
703 cursor
= BAR_CURSOR_BITMAP
;
706 cursor
= HBAR_CURSOR_BITMAP
;
710 w
->phys_cursor_on_p
= 0;
711 row
->cursor_in_fringe_p
= 0;
714 if (cursor
!= NO_FRINGE_BITMAP
)
716 draw_fringe_bitmap_1 (w
, row
, 0, 2, cursor
);
717 overlay
= cursor
== FILLED_BOX_CURSOR_BITMAP
? 3 : 1;
721 draw_fringe_bitmap_1 (w
, row
, left_p
, overlay
, NO_FRINGE_BITMAP
);
723 if (left_p
&& row
->overlay_arrow_p
)
724 draw_fringe_bitmap_1 (w
, row
, 1, 1,
725 (w
->overlay_arrow_bitmap
726 ? w
->overlay_arrow_bitmap
727 : OVERLAY_ARROW_BITMAP
));
731 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
732 function with input blocked. */
735 draw_row_fringe_bitmaps (w
, row
)
737 struct glyph_row
*row
;
739 xassert (interrupt_input_blocked
);
741 /* If row is completely invisible, because of vscrolling, we
742 don't have to draw anything. */
743 if (row
->visible_height
<= 0)
746 if (WINDOW_LEFT_FRINGE_WIDTH (w
) != 0)
747 draw_fringe_bitmap (w
, row
, 1);
749 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) != 0)
750 draw_fringe_bitmap (w
, row
, 0);
753 /* Draw the fringes of window W. Only fringes for rows marked for
754 update in redraw_fringe_bitmaps_p are drawn. */
757 draw_window_fringes (w
)
760 struct glyph_row
*row
;
761 int yb
= window_text_bottom_y (w
);
762 int nrows
= w
->current_matrix
->nrows
;
765 if (w
->pseudo_window_p
)
768 for (y
= 0, rn
= 0, row
= w
->current_matrix
->rows
;
769 y
< yb
&& rn
< nrows
;
770 y
+= row
->height
, ++row
, ++rn
)
772 if (!row
->redraw_fringe_bitmaps_p
)
774 draw_row_fringe_bitmaps (w
, row
);
775 row
->redraw_fringe_bitmaps_p
= 0;
780 /* Recalculate the bitmaps to show in the fringes of window W.
781 If FORCE_P is 0, only mark rows with modified bitmaps for update in
782 redraw_fringe_bitmaps_p; else mark all rows for update. */
785 update_window_fringes (w
, force_p
)
789 struct glyph_row
*row
, *cur
= 0;
790 int yb
= window_text_bottom_y (w
);
791 int rn
, nrows
= w
->current_matrix
->nrows
;
794 Lisp_Object boundary_top
= Qnil
, boundary_bot
= Qnil
;
795 Lisp_Object arrow_top
= Qnil
, arrow_bot
= Qnil
;
796 Lisp_Object empty_pos
;
797 Lisp_Object ind
= Qnil
;
799 if (w
->pseudo_window_p
)
802 if (!MINI_WINDOW_P (w
)
803 && (ind
= XBUFFER (w
->buffer
)->indicate_buffer_boundaries
, !NILP (ind
)))
805 if (EQ (ind
, Qleft
) || EQ (ind
, Qright
))
806 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= ind
;
807 else if (CONSP (ind
) && CONSP (XCAR (ind
)))
810 if (pos
= Fassq (Qt
, ind
), !NILP (pos
))
811 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= XCDR (pos
);
812 if (pos
= Fassq (Qtop
, ind
), !NILP (pos
))
813 boundary_top
= XCDR (pos
);
814 if (pos
= Fassq (Qbottom
, ind
), !NILP (pos
))
815 boundary_bot
= XCDR (pos
);
816 if (pos
= Fassq (Qup
, ind
), !NILP (pos
))
817 arrow_top
= XCDR (pos
);
818 if (pos
= Fassq (Qdown
, ind
), !NILP (pos
))
819 arrow_bot
= XCDR (pos
);
827 int do_eob
= 1, do_bob
= 1;
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 (!NILP (boundary_top
)
849 && MATRIX_ROW_START_CHARPOS (row
) <= BUF_BEGV (XBUFFER (w
->buffer
)))
850 row
->indicate_bob_p
= do_bob
, do_bob
= 0;
851 else if (!NILP (arrow_top
)
852 && (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0) == rn
)
853 row
->indicate_top_line_p
= 1;
855 if (!NILP (boundary_bot
)
856 && MATRIX_ROW_END_CHARPOS (row
) >= BUF_ZV (XBUFFER (w
->buffer
)))
857 row
->indicate_eob_p
= do_eob
, do_eob
= 0;
858 else if (!NILP (arrow_bot
)
859 && y
+ row
->height
>= yb
)
860 row
->indicate_bottom_line_p
= 1;
862 if (indicate_bob_p
!= row
->indicate_bob_p
863 || indicate_top_line_p
!= row
->indicate_top_line_p
864 || indicate_eob_p
!= row
->indicate_eob_p
865 || indicate_bottom_line_p
!= row
->indicate_bottom_line_p
)
866 row
->redraw_fringe_bitmaps_p
= 1;
870 empty_pos
= XBUFFER (w
->buffer
)->indicate_empty_lines
;
871 if (!NILP (empty_pos
) && !EQ (empty_pos
, Qright
))
872 empty_pos
= WINDOW_LEFT_FRINGE_WIDTH (w
) == 0 ? Qright
: Qleft
;
875 y
< yb
&& rn
< nrows
;
876 y
+= row
->height
, rn
++)
878 enum fringe_bitmap_type left
, right
;
879 unsigned left_face_id
, right_face_id
;
881 row
= w
->desired_matrix
->rows
+ rn
;
882 cur
= w
->current_matrix
->rows
+ rn
;
886 left_face_id
= right_face_id
= DEFAULT_FACE_ID
;
888 /* Decide which bitmap to draw in the left fringe. */
889 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
890 left
= NO_FRINGE_BITMAP
;
891 else if (row
->left_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
893 left
= row
->left_user_fringe_bitmap
;
894 left_face_id
= row
->left_user_fringe_face_id
;
896 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qleft
))
897 left
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
898 ? LEFT_BRACKET_BITMAP
: TOP_LEFT_ANGLE_BITMAP
);
899 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
900 left
= BOTTOM_LEFT_ANGLE_BITMAP
;
901 else if (row
->truncated_on_left_p
)
902 left
= LEFT_TRUNCATION_BITMAP
;
903 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
904 left
= CONTINUATION_LINE_BITMAP
;
905 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qleft
))
906 left
= ZV_LINE_BITMAP
;
907 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qleft
))
908 left
= UP_ARROW_BITMAP
;
909 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qleft
))
910 left
= DOWN_ARROW_BITMAP
;
912 left
= NO_FRINGE_BITMAP
;
914 /* Decide which bitmap to draw in the right fringe. */
915 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) == 0)
916 right
= NO_FRINGE_BITMAP
;
917 else if (row
->right_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
919 right
= row
->right_user_fringe_bitmap
;
920 right_face_id
= row
->right_user_fringe_face_id
;
922 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qright
))
923 right
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
924 ? RIGHT_BRACKET_BITMAP
: TOP_RIGHT_ANGLE_BITMAP
);
925 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
926 right
= BOTTOM_RIGHT_ANGLE_BITMAP
;
927 else if (row
->truncated_on_right_p
)
928 right
= RIGHT_TRUNCATION_BITMAP
;
929 else if (row
->continued_p
)
930 right
= CONTINUED_LINE_BITMAP
;
931 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qright
))
932 right
= UP_ARROW_BITMAP
;
933 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qright
))
934 right
= DOWN_ARROW_BITMAP
;
935 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qright
))
936 right
= ZV_LINE_BITMAP
;
938 right
= NO_FRINGE_BITMAP
;
942 || row
->visible_height
!= cur
->visible_height
943 || left
!= cur
->left_fringe_bitmap
944 || right
!= cur
->right_fringe_bitmap
945 || left_face_id
!= cur
->left_fringe_face_id
946 || right_face_id
!= cur
->right_fringe_face_id
947 || cur
->redraw_fringe_bitmaps_p
)
949 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
950 cur
->left_fringe_bitmap
= left
;
951 cur
->right_fringe_bitmap
= right
;
952 cur
->left_fringe_face_id
= left_face_id
;
953 cur
->right_fringe_face_id
= right_face_id
;
956 if (row
->overlay_arrow_p
!= cur
->overlay_arrow_p
)
958 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
959 cur
->overlay_arrow_p
= row
->overlay_arrow_p
;
962 row
->left_fringe_bitmap
= left
;
963 row
->right_fringe_bitmap
= right
;
964 row
->left_fringe_face_id
= left_face_id
;
965 row
->right_fringe_face_id
= right_face_id
;
972 /* Compute actual fringe widths for frame F.
974 If REDRAW is 1, redraw F if the fringe settings was actually
975 modified and F is visible.
977 Since the combined left and right fringe must occupy an integral
978 number of columns, we may need to add some pixels to each fringe.
979 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
980 but a negative width value is taken literally (after negating it).
982 We never make the fringes narrower than specified. It is planned
983 to make fringe bitmaps customizable and expandable, and at that
984 time, the user will typically specify the minimum number of pixels
985 needed for his bitmaps, so we shouldn't select anything less than
990 compute_fringe_widths (f
, redraw
)
994 int o_left
= FRAME_LEFT_FRINGE_WIDTH (f
);
995 int o_right
= FRAME_RIGHT_FRINGE_WIDTH (f
);
996 int o_cols
= FRAME_FRINGE_COLS (f
);
998 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
999 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
1000 int left_fringe_width
, right_fringe_width
;
1002 if (!NILP (left_fringe
))
1003 left_fringe
= Fcdr (left_fringe
);
1004 if (!NILP (right_fringe
))
1005 right_fringe
= Fcdr (right_fringe
);
1007 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
1008 XINT (left_fringe
));
1009 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
1010 XINT (right_fringe
));
1012 if (left_fringe_width
|| right_fringe_width
)
1014 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
1015 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
1016 int conf_wid
= left_wid
+ right_wid
;
1017 int font_wid
= FRAME_COLUMN_WIDTH (f
);
1018 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
1019 int real_wid
= cols
* font_wid
;
1020 if (left_wid
&& right_wid
)
1022 if (left_fringe_width
< 0)
1024 /* Left fringe width is fixed, adjust right fringe if necessary */
1025 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
;
1026 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
- left_wid
;
1028 else if (right_fringe_width
< 0)
1030 /* Right fringe width is fixed, adjust left fringe if necessary */
1031 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
- right_wid
;
1032 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
;
1036 /* Adjust both fringes with an equal amount.
1037 Note that we are doing integer arithmetic here, so don't
1038 lose a pixel if the total width is an odd number. */
1039 int fill
= real_wid
- conf_wid
;
1040 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
+ fill
/2;
1041 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
+ fill
- fill
/2;
1044 else if (left_fringe_width
)
1046 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
;
1047 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1051 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1052 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
;
1054 FRAME_FRINGE_COLS (f
) = cols
;
1058 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1059 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1060 FRAME_FRINGE_COLS (f
) = 0;
1063 if (redraw
&& FRAME_VISIBLE_P (f
))
1064 if (o_left
!= FRAME_LEFT_FRINGE_WIDTH (f
) ||
1065 o_right
!= FRAME_RIGHT_FRINGE_WIDTH (f
) ||
1066 o_cols
!= FRAME_FRINGE_COLS (f
))
1072 destroy_fringe_bitmap (n
)
1075 struct fringe_bitmap
**fbp
;
1077 fringe_faces
[n
] = FRINGE_FACE_ID
;
1079 fbp
= &fringe_bitmaps
[n
];
1080 if (*fbp
&& (*fbp
)->dynamic
)
1082 if (rif
&& rif
->destroy_fringe_bitmap
)
1083 rif
->destroy_fringe_bitmap (n
);
1088 while (max_used_fringe_bitmap
> MAX_STANDARD_FRINGE_BITMAPS
1089 && fringe_bitmaps
[max_used_fringe_bitmap
- 1] == NULL
)
1090 max_used_fringe_bitmap
--;
1094 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap
, Sdestroy_fringe_bitmap
,
1096 doc
: /* Destroy fringe bitmap BITMAP.
1097 If BITMAP overrides a standard fringe bitmap, the original bitmap is restored. */)
1104 n
= resolve_fringe_bitmap (bitmap
, &sym
);
1108 destroy_fringe_bitmap (n
);
1112 Vfringe_bitmaps
= Fdelq (sym
, Vfringe_bitmaps
);
1113 /* It would be better to remove the fringe property. */
1114 Fput (sym
, Qfringe
, Qnil
);
1120 /* Initialize bitmap bit.
1122 On X, we bit-swap the built-in bitmaps and reduce bitmap
1123 from short to char array if width is <= 8 bits.
1125 On MAC with big-endian CPU, we need to byte-swap each short.
1127 On W32 and MAC (little endian), there's no need to do this.
1131 init_fringe_bitmap (which
, fb
, once_p
)
1132 enum fringe_bitmap_type which
;
1133 struct fringe_bitmap
*fb
;
1136 if (once_p
|| fb
->dynamic
)
1138 #if defined (HAVE_X_WINDOWS)
1139 static unsigned char swap_nibble
[16]
1140 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1141 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1142 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1143 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
1144 unsigned short *bits
= fb
->bits
;
1149 unsigned char *cbits
= (unsigned char *)fb
->bits
;
1150 for (j
= 0; j
< fb
->height
; j
++)
1152 unsigned short b
= *bits
++;
1154 c
= (unsigned char)((swap_nibble
[b
& 0xf] << 4)
1155 | (swap_nibble
[(b
>>4) & 0xf]));
1156 *cbits
++ = (c
>> (8 - fb
->width
));
1161 for (j
= 0; j
< fb
->height
; j
++)
1163 unsigned short b
= *bits
;
1164 b
= (unsigned short)((swap_nibble
[b
& 0xf] << 12)
1165 | (swap_nibble
[(b
>>4) & 0xf] << 8)
1166 | (swap_nibble
[(b
>>8) & 0xf] << 4)
1167 | (swap_nibble
[(b
>>12) & 0xf]));
1168 *bits
++ = (b
>> (16 - fb
->width
));
1171 #endif /* HAVE_X_WINDOWS */
1173 #if defined (MAC_OS) && defined (WORDS_BIG_ENDIAN)
1174 unsigned short *bits
= fb
->bits
;
1176 for (j
= 0; j
< fb
->height
; j
++)
1178 unsigned short b
= *bits
;
1179 *bits
++ = ((b
>> 8) & 0xff) | ((b
& 0xff) << 8);
1181 #endif /* MAC_OS && WORDS_BIG_ENDIAN */
1186 destroy_fringe_bitmap (which
);
1188 if (rif
&& rif
->define_fringe_bitmap
)
1189 rif
->define_fringe_bitmap (which
, fb
->bits
, fb
->height
, fb
->width
);
1191 fringe_bitmaps
[which
] = fb
;
1192 if (which
>= max_used_fringe_bitmap
)
1193 max_used_fringe_bitmap
= which
+ 1;
1198 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap
, Sdefine_fringe_bitmap
,
1200 doc
: /* Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH.
1201 BITMAP is a symbol or string naming the new fringe bitmap.
1202 BITS is either a string or a vector of integers.
1203 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1204 WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1205 Optional fifth arg ALIGN may be one of `top', `center', or `bottom',
1206 indicating the positioning of the bitmap relative to the rows where it
1207 is used; the default is to center the bitmap. Fourth arg may also be a
1208 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1210 If BITMAP already exists, the existing definition is replaced. */)
1211 (bitmap
, bits
, height
, width
, align
)
1212 Lisp_Object bitmap
, bits
, height
, width
, align
;
1217 struct fringe_bitmap fb
, *xfb
;
1218 int fill1
= 0, fill2
= 0;
1221 n
= resolve_fringe_bitmap (bitmap
, &sym
);
1223 if (NILP (sym
) || INTEGERP (sym
))
1224 sym
= wrong_type_argument (Qsymbolp
, bitmap
);
1226 if (!STRINGP (bits
) && !VECTORP (bits
))
1227 bits
= wrong_type_argument (Qstringp
, bits
);
1229 len
= Flength (bits
);
1232 h
= fb
.height
= XINT (len
);
1235 CHECK_NUMBER (height
);
1236 fb
.height
= min (XINT (height
), 255);
1237 if (fb
.height
> XINT (len
))
1240 fill1
= (fb
.height
- h
) / 2;
1241 fill2
= fb
.height
- h
- fill1
;
1249 CHECK_NUMBER (width
);
1250 fb
.width
= min (XINT (width
), 255);
1254 fb
.align
= ALIGN_BITMAP_CENTER
;
1258 Lisp_Object period
= XCDR (align
);
1261 period
= XCAR (period
);
1264 fb
.period
= fb
.height
;
1268 align
= XCAR (align
);
1270 if (EQ (align
, Qtop
))
1271 fb
.align
= ALIGN_BITMAP_TOP
;
1272 else if (EQ (align
, Qbottom
))
1273 fb
.align
= ALIGN_BITMAP_BOTTOM
;
1274 else if (!NILP (align
) && !EQ (align
, Qcenter
))
1275 error ("Bad align argument");
1279 if (max_used_fringe_bitmap
< MAX_FRINGE_BITMAPS
)
1280 n
= max_used_fringe_bitmap
++;
1283 for (n
= MAX_STANDARD_FRINGE_BITMAPS
;
1284 n
< MAX_FRINGE_BITMAPS
;
1286 if (fringe_bitmaps
[n
] == NULL
)
1288 if (n
== MAX_FRINGE_BITMAPS
)
1289 error ("Cannot define more fringe bitmaps");
1292 Vfringe_bitmaps
= Fcons (sym
, Vfringe_bitmaps
);
1293 Fput (sym
, Qfringe
, make_number (n
));
1298 xfb
= (struct fringe_bitmap
*) xmalloc (sizeof fb
1299 + fb
.height
* BYTES_PER_BITMAP_ROW
);
1300 fb
.bits
= b
= (unsigned short *) (xfb
+ 1);
1301 bzero (b
, fb
.height
);
1304 while (j
< fb
.height
)
1306 for (i
= 0; i
< fill1
&& j
< fb
.height
; i
++)
1308 for (i
= 0; i
< h
&& j
< fb
.height
; i
++)
1310 Lisp_Object elt
= Faref (bits
, make_number (i
));
1311 b
[j
++] = NUMBERP (elt
) ? XINT (elt
) : 0;
1313 for (i
= 0; i
< fill2
&& j
< fb
.height
; i
++)
1319 init_fringe_bitmap (n
, xfb
, 0);
1324 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face
, Sset_fringe_bitmap_face
,
1326 doc
: /* Set face for fringe bitmap BITMAP to FACE.
1327 If FACE is nil, reset face to default fringe face. */)
1329 Lisp_Object bitmap
, face
;
1334 bn
= resolve_fringe_bitmap (bitmap
, 0);
1336 error ("Undefined fringe bitmap");
1340 face_id
= lookup_named_face (SELECTED_FRAME (), face
, 'A');
1342 error ("No such face");
1345 face_id
= FRINGE_FACE_ID
;
1347 fringe_faces
[bn
] = face_id
;
1352 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos
, Sfringe_bitmaps_at_pos
,
1354 doc
: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1355 If WINDOW is nil, use selected window. If POS is nil, use value of point
1356 in that window. Return value is a cons (LEFT . RIGHT) where LEFT and RIGHT
1357 are the fringe bitmap numbers for the bitmaps in the left and right fringe,
1358 resp. If left or right fringe is empty, the corresponding element is nil.
1359 Return nil if POS is not visible in WINDOW. */)
1361 Lisp_Object pos
, window
;
1364 struct buffer
*old_buffer
= NULL
;
1365 struct glyph_row
*row
;
1369 window
= selected_window
;
1370 CHECK_WINDOW (window
);
1371 w
= XWINDOW (window
);
1375 CHECK_NUMBER_COERCE_MARKER (pos
);
1376 textpos
= XINT (pos
);
1378 else if (w
== XWINDOW (selected_window
))
1381 textpos
= XMARKER (w
->pointm
)->charpos
;
1383 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
1384 row
= row_containing_pos (w
, textpos
, row
, NULL
, 0);
1386 return Fcons (get_fringe_bitmap_name (row
->left_fringe_bitmap
),
1387 get_fringe_bitmap_name (row
->right_fringe_bitmap
));
1393 /***********************************************************************
1395 ***********************************************************************/
1400 defsubr (&Sdestroy_fringe_bitmap
);
1401 defsubr (&Sdefine_fringe_bitmap
);
1402 defsubr (&Sfringe_bitmaps_at_pos
);
1403 defsubr (&Sset_fringe_bitmap_face
);
1405 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe
,
1406 doc
: /* *Non-nil means that newline may flow into the right fringe.
1407 This means that display lines which are exactly as wide as the window
1408 (not counting the final newline) will only occupy one screen line, by
1409 showing (or hiding) the final newline in the right fringe; when point
1410 is at the final newline, the cursor is shown in the right fringe.
1411 If nil, also continue lines which are exactly as wide as the window. */);
1412 Voverflow_newline_into_fringe
= Qt
;
1414 DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps
,
1415 doc
: /* List of fringe bitmap symbols.
1416 You must (require 'fringe) to use fringe bitmap symbols in your programs." */);
1417 Vfringe_bitmaps
= Qnil
;
1420 /* Initialize this module when Emacs starts. */
1425 enum fringe_bitmap_type bt
;
1427 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1428 init_fringe_bitmap(bt
, &standard_bitmaps
[bt
], 1);
1436 bzero (fringe_bitmaps
, sizeof fringe_bitmaps
);
1437 for (i
= 0; i
< MAX_FRINGE_BITMAPS
; i
++)
1438 fringe_faces
[i
] = FRINGE_FACE_ID
;
1446 enum fringe_bitmap_type bt
;
1451 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1453 struct fringe_bitmap
*fb
= &standard_bitmaps
[bt
];
1454 rif
->define_fringe_bitmap (bt
, fb
->bits
, fb
->height
, fb
->width
);
1459 w32_reset_fringes ()
1461 /* Destroy row bitmaps. */
1467 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< max_used_fringe_bitmap
; bt
++)
1468 rif
->destroy_fringe_bitmap (bt
);
1471 #endif /* HAVE_NTGUI */
1473 #endif /* HAVE_WINDOW_SYSTEM */
1475 /* arch-tag: 04596920-43eb-473d-b319-82712338162d
1476 (do not change this comment) */