1 /* Fringe handling (split from xdisp.c).
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03,04
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
28 #include "dispextern.h"
30 #include "blockinput.h"
32 #ifdef HAVE_WINDOW_SYSTEM
34 extern Lisp_Object Qfringe
;
35 extern Lisp_Object Qtop
, Qbottom
, Qcenter
;
36 extern Lisp_Object Qup
, Qdown
, Qleft
, Qright
;
38 /* Non-nil means that newline may flow into the right fringe. */
40 Lisp_Object Voverflow_newline_into_fringe
;
42 /* List of known fringe bitmap symbols.
44 The fringe bitmap number is stored in the `fringe' property on
45 those symbols. Names for the built-in bitmaps are installed by
49 Lisp_Object Vfringe_bitmaps
;
51 enum fringe_bitmap_type
55 LEFT_TRUNCATION_BITMAP
,
56 RIGHT_TRUNCATION_BITMAP
,
59 CONTINUED_LINE_BITMAP
,
60 CONTINUATION_LINE_BITMAP
,
62 TOP_LEFT_ANGLE_BITMAP
,
63 TOP_RIGHT_ANGLE_BITMAP
,
64 BOTTOM_LEFT_ANGLE_BITMAP
,
65 BOTTOM_RIGHT_ANGLE_BITMAP
,
68 FILLED_BOX_CURSOR_BITMAP
,
69 HOLLOW_BOX_CURSOR_BITMAP
,
74 MAX_STANDARD_FRINGE_BITMAPS
77 enum fringe_bitmap_align
79 ALIGN_BITMAP_CENTER
= 0,
95 /***********************************************************************
97 ***********************************************************************/
99 /* Undefined bitmap. A question mark. */
112 static unsigned short unknown_bits
[] = {
113 0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
115 /* An arrow like this: `<-'. */
126 static unsigned short left_arrow_bits
[] = {
127 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
130 /* Right truncation arrow bitmap `->'. */
141 static unsigned short right_arrow_bits
[] = {
142 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
145 /* Up arrow bitmap. */
156 static unsigned short up_arrow_bits
[] = {
157 0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
160 /* Down arrow bitmap. */
171 static unsigned short down_arrow_bits
[] = {
172 0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
174 /* Marker for continued lines. */
185 static unsigned short continued_bits
[] = {
186 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
188 /* Marker for continuation lines. */
199 static unsigned short continuation_bits
[] = {
200 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
202 /* Overlay arrow bitmap. A triangular arrow. */
213 static unsigned short ov_bits
[] = {
214 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
217 /* Reverse Overlay arrow bitmap. A triangular arrow. */
228 static unsigned short rev_ov_bits
[] = {
229 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
232 /* First line bitmap. An top-left angle. */
243 static unsigned short top_left_angle_bits
[] = {
244 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00};
246 /* First line bitmap. An right-up angle. */
257 static unsigned short top_right_angle_bits
[] = {
258 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
260 /* Last line bitmap. An left-down angle. */
271 static unsigned short bottom_left_angle_bits
[] = {
272 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
274 /* Last line bitmap. An right-down angle. */
285 static unsigned short bottom_right_angle_bits
[] = {
286 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
288 /* First/last line bitmap. An left bracket. */
301 static unsigned short left_bracket_bits
[] = {
302 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
304 /* First/last line bitmap. An right bracket. */
317 static unsigned short right_bracket_bits
[] = {
318 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
320 /* Filled box cursor bitmap. A filled box; max 13 pixels high. */
336 static unsigned short filled_box_cursor_bits
[] = {
337 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
339 /* Hollow box cursor bitmap. A hollow box; max 13 pixels high. */
355 static unsigned short hollow_box_cursor_bits
[] = {
356 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe};
358 /* Bar cursor bitmap. A vertical bar; max 13 pixels high. */
374 static unsigned short bar_cursor_bits
[] = {
375 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
377 /* HBar cursor bitmap. A horisontal bar; 2 pixels high. */
382 static unsigned short hbar_cursor_bits
[] = {
386 /* Bitmap drawn to indicate lines not displaying text if
387 `indicate-empty-lines' is non-nil. */
396 static unsigned short zv_bits
[] = {
397 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
398 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
399 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
400 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
401 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
402 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
403 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
404 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
406 /* Hollow square bitmap. */
415 static unsigned short hollow_square_bits
[] = {
416 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
419 #define BYTES_PER_BITMAP_ROW (sizeof (unsigned short))
420 #define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
421 #define FRBITS(bits) bits, STANDARD_BITMAP_HEIGHT (bits)
423 struct fringe_bitmap standard_bitmaps
[MAX_STANDARD_FRINGE_BITMAPS
] =
425 { NULL
, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */
426 { FRBITS (unknown_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
427 { FRBITS (left_arrow_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
428 { FRBITS (right_arrow_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
429 { FRBITS (up_arrow_bits
), 8, 0, ALIGN_BITMAP_TOP
, 0 },
430 { FRBITS (down_arrow_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
431 { FRBITS (continued_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
432 { FRBITS (continuation_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
433 { FRBITS (ov_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
434 { FRBITS (top_left_angle_bits
), 8, 0, ALIGN_BITMAP_TOP
, 0 },
435 { FRBITS (top_right_angle_bits
), 8, 0, ALIGN_BITMAP_TOP
, 0 },
436 { FRBITS (bottom_left_angle_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
437 { FRBITS (bottom_right_angle_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
438 { FRBITS (left_bracket_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
439 { FRBITS (right_bracket_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
440 { FRBITS (filled_box_cursor_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
441 { FRBITS (hollow_box_cursor_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
442 { FRBITS (hollow_square_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
443 { FRBITS (bar_cursor_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
444 { FRBITS (hbar_cursor_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
445 { FRBITS (zv_bits
), 8, 3, ALIGN_BITMAP_TOP
, 0 },
448 static struct fringe_bitmap
**fringe_bitmaps
;
449 static unsigned *fringe_faces
;
450 static int max_fringe_bitmaps
;
452 static int max_used_fringe_bitmap
= MAX_STANDARD_FRINGE_BITMAPS
;
455 /* Lookup bitmap number for symbol BITMAP.
456 Return 0 if not a bitmap. */
459 lookup_fringe_bitmap (bitmap
)
464 bitmap
= Fget (bitmap
, Qfringe
);
465 if (!INTEGERP (bitmap
))
469 if (bn
> NO_FRINGE_BITMAP
470 && bn
< max_used_fringe_bitmap
471 && (bn
< MAX_STANDARD_FRINGE_BITMAPS
472 || fringe_bitmaps
[bn
] != NULL
))
478 /* Get fringe bitmap name for bitmap number BN.
480 Found by traversing Vfringe_bitmaps comparing BN to the
481 fringe property for each symbol.
483 Return BN if not found in Vfringe_bitmaps. */
486 get_fringe_bitmap_name (bn
)
492 /* Zero means no bitmap -- return nil. */
496 bitmaps
= Vfringe_bitmaps
;
497 num
= make_number (bn
);
499 while (CONSP (bitmaps
))
501 Lisp_Object bitmap
= XCAR (bitmaps
);
502 if (EQ (num
, Fget (bitmap
, Qfringe
)))
504 bitmaps
= XCDR (bitmaps
);
511 /* Draw the bitmap WHICH in one of the left or right fringes of
512 window W. ROW is the glyph row for which to display the bitmap; it
513 determines the vertical position at which the bitmap has to be
515 LEFT_P is 1 for left fringe, 0 for right fringe.
519 draw_fringe_bitmap_1 (w
, row
, left_p
, overlay
, which
)
521 struct glyph_row
*row
;
523 enum fringe_bitmap_type which
;
525 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
526 struct draw_fringe_bitmap_params p
;
527 struct fringe_bitmap
*fb
;
529 int face_id
= DEFAULT_FACE_ID
;
532 p
.overlay_p
= (overlay
& 1) == 1;
533 p
.cursor_p
= (overlay
& 2) == 2;
535 if (which
!= NO_FRINGE_BITMAP
)
540 which
= row
->left_fringe_bitmap
;
541 face_id
= row
->left_fringe_face_id
;
545 which
= row
->right_fringe_bitmap
;
546 face_id
= row
->right_fringe_face_id
;
549 if (face_id
== DEFAULT_FACE_ID
)
550 face_id
= fringe_faces
[which
];
552 fb
= fringe_bitmaps
[which
];
554 fb
= &standard_bitmaps
[which
< MAX_STANDARD_FRINGE_BITMAPS
555 ? which
: UNDEF_FRINGE_BITMAP
];
559 /* Convert row to frame coordinates. */
560 p
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
567 p
.dh
= (period
> 0 ? (p
.y
% period
) : 0);
569 /* Clip bitmap if too high. */
570 if (p
.h
> row
->height
)
573 p
.face
= FACE_FROM_ID (f
, face_id
);
577 /* Why does this happen? ++kfs */
581 PREPARE_FACE_FOR_DISPLAY (f
, p
.face
);
583 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
588 int wd
= WINDOW_LEFT_FRINGE_WIDTH (w
);
589 int x
= window_box_left (w
, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
594 p
.x
= x
- p
.wd
- (wd
- p
.wd
) / 2;
596 if (p
.wd
< wd
|| row
->height
> p
.h
)
598 /* If W has a vertical border to its left, don't draw over it. */
599 wd
-= ((!WINDOW_LEFTMOST_P (w
)
600 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
608 int x
= window_box_right (w
,
609 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
612 int wd
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
615 p
.x
= x
+ (wd
- p
.wd
) / 2;
616 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
618 if (p
.wd
< wd
|| row
->height
> p
.h
)
627 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
629 p
.by
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, row
->y
));
630 p
.ny
= row
->visible_height
;
633 /* Adjust y to the offset in the row to start drawing the bitmap. */
636 case ALIGN_BITMAP_CENTER
:
637 p
.y
+= (row
->height
- p
.h
) / 2;
639 case ALIGN_BITMAP_BOTTOM
:
641 p
.y
+= (row
->visible_height
- p
.h
);
643 case ALIGN_BITMAP_TOP
:
647 rif
->draw_fringe_bitmap (w
, row
, &p
);
651 draw_fringe_bitmap (w
, row
, left_p
)
653 struct glyph_row
*row
;
658 if (!left_p
&& row
->cursor_in_fringe_p
)
660 int cursor
= NO_FRINGE_BITMAP
;
662 switch (w
->phys_cursor_type
)
664 case HOLLOW_BOX_CURSOR
:
665 if (row
->visible_height
>= STANDARD_BITMAP_HEIGHT (hollow_box_cursor_bits
))
666 cursor
= HOLLOW_BOX_CURSOR_BITMAP
;
668 cursor
= HOLLOW_SQUARE_BITMAP
;
670 case FILLED_BOX_CURSOR
:
671 cursor
= FILLED_BOX_CURSOR_BITMAP
;
674 cursor
= BAR_CURSOR_BITMAP
;
677 cursor
= HBAR_CURSOR_BITMAP
;
681 w
->phys_cursor_on_p
= 0;
682 row
->cursor_in_fringe_p
= 0;
685 if (cursor
!= NO_FRINGE_BITMAP
)
687 draw_fringe_bitmap_1 (w
, row
, 0, 2, cursor
);
688 overlay
= cursor
== FILLED_BOX_CURSOR_BITMAP
? 3 : 1;
692 draw_fringe_bitmap_1 (w
, row
, left_p
, overlay
, NO_FRINGE_BITMAP
);
694 if (left_p
&& row
->overlay_arrow_p
)
695 draw_fringe_bitmap_1 (w
, row
, 1, 1,
696 (w
->overlay_arrow_bitmap
697 ? w
->overlay_arrow_bitmap
698 : OVERLAY_ARROW_BITMAP
));
702 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
703 function with input blocked. */
706 draw_row_fringe_bitmaps (w
, row
)
708 struct glyph_row
*row
;
710 xassert (interrupt_input_blocked
);
712 /* If row is completely invisible, because of vscrolling, we
713 don't have to draw anything. */
714 if (row
->visible_height
<= 0)
717 if (WINDOW_LEFT_FRINGE_WIDTH (w
) != 0)
718 draw_fringe_bitmap (w
, row
, 1);
720 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) != 0)
721 draw_fringe_bitmap (w
, row
, 0);
724 /* Draw the fringes of window W. Only fringes for rows marked for
725 update in redraw_fringe_bitmaps_p are drawn.
727 Return >0 if left or right fringe was redrawn in any way.
729 If NO_FRINGE is non-zero, also return >0 if either fringe has zero width.
731 A return value >0 indicates that the vertical line between windows
732 needs update (as it may be drawn in the fringe).
736 draw_window_fringes (w
, no_fringe
)
740 struct glyph_row
*row
;
741 int yb
= window_text_bottom_y (w
);
742 int nrows
= w
->current_matrix
->nrows
;
746 if (w
->pseudo_window_p
)
749 /* Must draw line if no fringe */
751 && (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0
752 || WINDOW_RIGHT_FRINGE_WIDTH (w
) == 0))
755 for (y
= 0, rn
= 0, row
= w
->current_matrix
->rows
;
756 y
< yb
&& rn
< nrows
;
757 y
+= row
->height
, ++row
, ++rn
)
759 if (!row
->redraw_fringe_bitmaps_p
)
761 draw_row_fringe_bitmaps (w
, row
);
762 row
->redraw_fringe_bitmaps_p
= 0;
770 /* Recalculate the bitmaps to show in the fringes of window W.
771 If FORCE_P is 0, only mark rows with modified bitmaps for update in
772 redraw_fringe_bitmaps_p; else mark all rows for update. */
775 update_window_fringes (w
, force_p
)
779 struct glyph_row
*row
, *cur
= 0;
780 int yb
= window_text_bottom_y (w
);
781 int rn
, nrows
= w
->current_matrix
->nrows
;
784 Lisp_Object boundary_top
= Qnil
, boundary_bot
= Qnil
;
785 Lisp_Object arrow_top
= Qnil
, arrow_bot
= Qnil
;
786 Lisp_Object empty_pos
;
787 Lisp_Object ind
= Qnil
;
789 if (w
->pseudo_window_p
)
792 if (!MINI_WINDOW_P (w
)
793 && (ind
= XBUFFER (w
->buffer
)->indicate_buffer_boundaries
, !NILP (ind
)))
795 if (EQ (ind
, Qleft
) || EQ (ind
, Qright
))
796 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= ind
;
797 else if (CONSP (ind
) && CONSP (XCAR (ind
)))
800 if (pos
= Fassq (Qt
, ind
), !NILP (pos
))
801 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= XCDR (pos
);
802 if (pos
= Fassq (Qtop
, ind
), !NILP (pos
))
803 boundary_top
= XCDR (pos
);
804 if (pos
= Fassq (Qbottom
, ind
), !NILP (pos
))
805 boundary_bot
= XCDR (pos
);
806 if (pos
= Fassq (Qup
, ind
), !NILP (pos
))
807 arrow_top
= XCDR (pos
);
808 if (pos
= Fassq (Qdown
, ind
), !NILP (pos
))
809 arrow_bot
= XCDR (pos
);
812 /* Anything else means boundary on left and no arrows. */
813 boundary_top
= boundary_bot
= Qleft
;
818 int done_top
= 0, done_bot
= 0;
821 y
< yb
&& rn
< nrows
;
822 y
+= row
->height
, ++rn
)
824 unsigned indicate_bob_p
, indicate_top_line_p
;
825 unsigned indicate_eob_p
, indicate_bottom_line_p
;
827 row
= w
->desired_matrix
->rows
+ rn
;
829 row
= w
->current_matrix
->rows
+ rn
;
831 indicate_bob_p
= row
->indicate_bob_p
;
832 indicate_top_line_p
= row
->indicate_top_line_p
;
833 indicate_eob_p
= row
->indicate_eob_p
;
834 indicate_bottom_line_p
= row
->indicate_bottom_line_p
;
836 row
->indicate_bob_p
= row
->indicate_top_line_p
= 0;
837 row
->indicate_eob_p
= row
->indicate_bottom_line_p
= 0;
839 if (!row
->mode_line_p
)
843 if (MATRIX_ROW_START_CHARPOS (row
) <= BUF_BEGV (XBUFFER (w
->buffer
)))
844 row
->indicate_bob_p
= !NILP (boundary_top
);
846 row
->indicate_top_line_p
= !NILP (arrow_top
);
852 if (MATRIX_ROW_END_CHARPOS (row
) >= BUF_ZV (XBUFFER (w
->buffer
)))
853 row
->indicate_eob_p
= !NILP (boundary_bot
), done_bot
= 1;
854 else if (y
+ row
->height
>= yb
)
855 row
->indicate_bottom_line_p
= !NILP (arrow_bot
), done_bot
= 1;
859 if (indicate_bob_p
!= row
->indicate_bob_p
860 || indicate_top_line_p
!= row
->indicate_top_line_p
861 || indicate_eob_p
!= row
->indicate_eob_p
862 || indicate_bottom_line_p
!= row
->indicate_bottom_line_p
)
863 row
->redraw_fringe_bitmaps_p
= 1;
867 empty_pos
= XBUFFER (w
->buffer
)->indicate_empty_lines
;
868 if (!NILP (empty_pos
) && !EQ (empty_pos
, Qright
))
869 empty_pos
= WINDOW_LEFT_FRINGE_WIDTH (w
) == 0 ? Qright
: Qleft
;
872 y
< yb
&& rn
< nrows
;
873 y
+= row
->height
, rn
++)
875 enum fringe_bitmap_type left
, right
;
876 unsigned left_face_id
, right_face_id
;
878 row
= w
->desired_matrix
->rows
+ rn
;
879 cur
= w
->current_matrix
->rows
+ rn
;
883 left_face_id
= right_face_id
= DEFAULT_FACE_ID
;
885 /* Decide which bitmap to draw in the left fringe. */
886 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
887 left
= NO_FRINGE_BITMAP
;
888 else if (row
->left_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
890 left
= row
->left_user_fringe_bitmap
;
891 left_face_id
= row
->left_user_fringe_face_id
;
893 else if (row
->truncated_on_left_p
)
894 left
= LEFT_TRUNCATION_BITMAP
;
895 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qleft
))
896 left
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
897 ? LEFT_BRACKET_BITMAP
: TOP_LEFT_ANGLE_BITMAP
);
898 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
899 left
= BOTTOM_LEFT_ANGLE_BITMAP
;
900 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
901 left
= CONTINUATION_LINE_BITMAP
;
902 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qleft
))
903 left
= ZV_LINE_BITMAP
;
904 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qleft
))
905 left
= UP_ARROW_BITMAP
;
906 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qleft
))
907 left
= DOWN_ARROW_BITMAP
;
909 left
= NO_FRINGE_BITMAP
;
911 /* Decide which bitmap to draw in the right fringe. */
912 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) == 0)
913 right
= NO_FRINGE_BITMAP
;
914 else if (row
->right_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
916 right
= row
->right_user_fringe_bitmap
;
917 right_face_id
= row
->right_user_fringe_face_id
;
919 else if (row
->truncated_on_right_p
)
920 right
= RIGHT_TRUNCATION_BITMAP
;
921 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qright
))
922 right
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
923 ? RIGHT_BRACKET_BITMAP
: TOP_RIGHT_ANGLE_BITMAP
);
924 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
925 right
= BOTTOM_RIGHT_ANGLE_BITMAP
;
926 else if (row
->continued_p
)
927 right
= CONTINUED_LINE_BITMAP
;
928 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qright
))
929 right
= UP_ARROW_BITMAP
;
930 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qright
))
931 right
= DOWN_ARROW_BITMAP
;
932 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qright
))
933 right
= ZV_LINE_BITMAP
;
935 right
= NO_FRINGE_BITMAP
;
939 || row
->visible_height
!= cur
->visible_height
940 || row
->ends_at_zv_p
!= cur
->ends_at_zv_p
941 || left
!= cur
->left_fringe_bitmap
942 || right
!= cur
->right_fringe_bitmap
943 || left_face_id
!= cur
->left_fringe_face_id
944 || right_face_id
!= cur
->right_fringe_face_id
945 || cur
->redraw_fringe_bitmaps_p
)
947 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
948 cur
->left_fringe_bitmap
= left
;
949 cur
->right_fringe_bitmap
= right
;
950 cur
->left_fringe_face_id
= left_face_id
;
951 cur
->right_fringe_face_id
= right_face_id
;
954 if (row
->overlay_arrow_p
!= cur
->overlay_arrow_p
)
956 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
957 cur
->overlay_arrow_p
= row
->overlay_arrow_p
;
960 row
->left_fringe_bitmap
= left
;
961 row
->right_fringe_bitmap
= right
;
962 row
->left_fringe_face_id
= left_face_id
;
963 row
->right_fringe_face_id
= right_face_id
;
965 if (rn
> 0 && row
->redraw_fringe_bitmaps_p
)
966 row
[-1].redraw_fringe_bitmaps_p
= cur
[-1].redraw_fringe_bitmaps_p
= 1;
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.
987 compute_fringe_widths (f
, redraw
)
991 int o_left
= FRAME_LEFT_FRINGE_WIDTH (f
);
992 int o_right
= FRAME_RIGHT_FRINGE_WIDTH (f
);
993 int o_cols
= FRAME_FRINGE_COLS (f
);
995 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
996 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
997 int left_fringe_width
, right_fringe_width
;
999 if (!NILP (left_fringe
))
1000 left_fringe
= Fcdr (left_fringe
);
1001 if (!NILP (right_fringe
))
1002 right_fringe
= Fcdr (right_fringe
);
1004 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
1005 XINT (left_fringe
));
1006 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
1007 XINT (right_fringe
));
1009 if (left_fringe_width
|| right_fringe_width
)
1011 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
1012 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
1013 int conf_wid
= left_wid
+ right_wid
;
1014 int font_wid
= FRAME_COLUMN_WIDTH (f
);
1015 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
1016 int real_wid
= cols
* font_wid
;
1017 if (left_wid
&& right_wid
)
1019 if (left_fringe_width
< 0)
1021 /* Left fringe width is fixed, adjust right fringe if necessary */
1022 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
;
1023 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
- left_wid
;
1025 else if (right_fringe_width
< 0)
1027 /* Right fringe width is fixed, adjust left fringe if necessary */
1028 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
- right_wid
;
1029 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
;
1033 /* Adjust both fringes with an equal amount.
1034 Note that we are doing integer arithmetic here, so don't
1035 lose a pixel if the total width is an odd number. */
1036 int fill
= real_wid
- conf_wid
;
1037 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
+ fill
/2;
1038 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
+ fill
- fill
/2;
1041 else if (left_fringe_width
)
1043 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
;
1044 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1048 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1049 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
;
1051 FRAME_FRINGE_COLS (f
) = cols
;
1055 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1056 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1057 FRAME_FRINGE_COLS (f
) = 0;
1060 if (redraw
&& FRAME_VISIBLE_P (f
))
1061 if (o_left
!= FRAME_LEFT_FRINGE_WIDTH (f
) ||
1062 o_right
!= FRAME_RIGHT_FRINGE_WIDTH (f
) ||
1063 o_cols
!= FRAME_FRINGE_COLS (f
))
1068 /* Free resources used by a user-defined bitmap. */
1071 destroy_fringe_bitmap (n
)
1074 struct fringe_bitmap
**fbp
;
1076 fringe_faces
[n
] = FRINGE_FACE_ID
;
1078 fbp
= &fringe_bitmaps
[n
];
1079 if (*fbp
&& (*fbp
)->dynamic
)
1081 if (rif
&& rif
->destroy_fringe_bitmap
)
1082 rif
->destroy_fringe_bitmap (n
);
1087 while (max_used_fringe_bitmap
> MAX_STANDARD_FRINGE_BITMAPS
1088 && fringe_bitmaps
[max_used_fringe_bitmap
- 1] == NULL
)
1089 max_used_fringe_bitmap
--;
1093 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap
, Sdestroy_fringe_bitmap
,
1095 doc
: /* Destroy fringe bitmap BITMAP.
1096 If BITMAP overrides a standard fringe bitmap, the original bitmap is restored. */)
1102 CHECK_SYMBOL (bitmap
);
1103 n
= lookup_fringe_bitmap (bitmap
);
1107 destroy_fringe_bitmap (n
);
1109 if (n
>= MAX_STANDARD_FRINGE_BITMAPS
)
1111 Vfringe_bitmaps
= Fdelq (bitmap
, Vfringe_bitmaps
);
1112 /* It would be better to remove the fringe property. */
1113 Fput (bitmap
, 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
;
1216 struct fringe_bitmap fb
, *xfb
;
1217 int fill1
= 0, fill2
= 0;
1219 CHECK_SYMBOL (bitmap
);
1223 else if (VECTORP (bits
))
1224 h
= XVECTOR (bits
)->size
;
1226 bits
= wrong_type_argument (Qsequencep
, bits
);
1232 CHECK_NUMBER (height
);
1233 fb
.height
= min (XINT (height
), 255);
1236 fill1
= (fb
.height
- h
) / 2;
1237 fill2
= fb
.height
- h
- fill1
;
1245 CHECK_NUMBER (width
);
1246 fb
.width
= min (XINT (width
), 255);
1250 fb
.align
= ALIGN_BITMAP_CENTER
;
1254 Lisp_Object period
= XCDR (align
);
1257 period
= XCAR (period
);
1260 fb
.period
= fb
.height
;
1264 align
= XCAR (align
);
1266 if (EQ (align
, Qtop
))
1267 fb
.align
= ALIGN_BITMAP_TOP
;
1268 else if (EQ (align
, Qbottom
))
1269 fb
.align
= ALIGN_BITMAP_BOTTOM
;
1270 else if (!NILP (align
) && !EQ (align
, Qcenter
))
1271 error ("Bad align argument");
1273 n
= lookup_fringe_bitmap (bitmap
);
1276 if (max_used_fringe_bitmap
< max_fringe_bitmaps
)
1277 n
= max_used_fringe_bitmap
++;
1280 for (n
= MAX_STANDARD_FRINGE_BITMAPS
;
1281 n
< max_fringe_bitmaps
;
1283 if (fringe_bitmaps
[n
] == NULL
)
1286 if (n
== max_fringe_bitmaps
)
1288 if ((max_fringe_bitmaps
+ 20) > MAX_FRINGE_BITMAPS
)
1289 error ("No free fringe bitmap slots");
1291 i
= max_fringe_bitmaps
;
1292 max_fringe_bitmaps
+= 20;
1294 = ((struct fringe_bitmap
**)
1295 xrealloc (fringe_bitmaps
, max_fringe_bitmaps
* sizeof (struct fringe_bitmap
*)));
1297 = (unsigned *) xrealloc (fringe_faces
, max_fringe_bitmaps
* sizeof (unsigned));
1299 for (; i
< max_fringe_bitmaps
; i
++)
1301 fringe_bitmaps
[i
] = NULL
;
1302 fringe_faces
[i
] = FRINGE_FACE_ID
;
1307 Vfringe_bitmaps
= Fcons (bitmap
, Vfringe_bitmaps
);
1308 Fput (bitmap
, Qfringe
, make_number (n
));
1313 xfb
= (struct fringe_bitmap
*) xmalloc (sizeof fb
1314 + fb
.height
* BYTES_PER_BITMAP_ROW
);
1315 fb
.bits
= b
= (unsigned short *) (xfb
+ 1);
1316 bzero (b
, fb
.height
);
1319 while (j
< fb
.height
)
1321 for (i
= 0; i
< fill1
&& j
< fb
.height
; i
++)
1323 for (i
= 0; i
< h
&& j
< fb
.height
; i
++)
1325 Lisp_Object elt
= Faref (bits
, make_number (i
));
1326 b
[j
++] = NUMBERP (elt
) ? XINT (elt
) : 0;
1328 for (i
= 0; i
< fill2
&& j
< fb
.height
; i
++)
1334 init_fringe_bitmap (n
, xfb
, 0);
1339 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face
, Sset_fringe_bitmap_face
,
1341 doc
: /* Set face for fringe bitmap BITMAP to FACE.
1342 If FACE is nil, reset face to default fringe face. */)
1344 Lisp_Object bitmap
, face
;
1349 CHECK_SYMBOL (bitmap
);
1350 n
= lookup_fringe_bitmap (bitmap
);
1352 error ("Undefined fringe bitmap");
1356 face_id
= lookup_named_face (SELECTED_FRAME (), face
, 'A', 1);
1358 error ("No such face");
1361 face_id
= FRINGE_FACE_ID
;
1363 fringe_faces
[n
] = face_id
;
1368 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos
, Sfringe_bitmaps_at_pos
,
1370 doc
: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1371 If WINDOW is nil, use selected window. If POS is nil, use value of point
1372 in that window. Return value is a list (LEFT RIGHT OV), where LEFT
1373 is the symbol for the bitmap in the left fringe (or nil if no bitmap),
1374 RIGHT is similar for the right fringe, and OV is non-nil if there is an
1375 overlay arrow in the left fringe.
1376 Return nil if POS is not visible in WINDOW. */)
1378 Lisp_Object pos
, window
;
1381 struct glyph_row
*row
;
1385 window
= selected_window
;
1386 CHECK_WINDOW (window
);
1387 w
= XWINDOW (window
);
1391 CHECK_NUMBER_COERCE_MARKER (pos
);
1392 textpos
= XINT (pos
);
1394 else if (w
== XWINDOW (selected_window
))
1397 textpos
= XMARKER (w
->pointm
)->charpos
;
1399 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
1400 row
= row_containing_pos (w
, textpos
, row
, NULL
, 0);
1402 return list3 (get_fringe_bitmap_name (row
->left_fringe_bitmap
),
1403 get_fringe_bitmap_name (row
->right_fringe_bitmap
),
1404 (row
->overlay_arrow_p
? Qt
: Qnil
));
1410 /***********************************************************************
1412 ***********************************************************************/
1417 defsubr (&Sdestroy_fringe_bitmap
);
1418 defsubr (&Sdefine_fringe_bitmap
);
1419 defsubr (&Sfringe_bitmaps_at_pos
);
1420 defsubr (&Sset_fringe_bitmap_face
);
1422 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe
,
1423 doc
: /* *Non-nil means that newline may flow into the right fringe.
1424 This means that display lines which are exactly as wide as the window
1425 (not counting the final newline) will only occupy one screen line, by
1426 showing (or hiding) the final newline in the right fringe; when point
1427 is at the final newline, the cursor is shown in the right fringe.
1428 If nil, also continue lines which are exactly as wide as the window. */);
1429 Voverflow_newline_into_fringe
= Qt
;
1431 DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps
,
1432 doc
: /* List of fringe bitmap symbols.
1433 You must (require 'fringe) to use fringe bitmap symbols in your programs." */);
1434 Vfringe_bitmaps
= Qnil
;
1437 /* Initialize this module when Emacs starts. */
1442 enum fringe_bitmap_type bt
;
1444 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1445 init_fringe_bitmap(bt
, &standard_bitmaps
[bt
], 1);
1453 max_fringe_bitmaps
= MAX_STANDARD_FRINGE_BITMAPS
+ 20;
1456 = (struct fringe_bitmap
**) xmalloc (max_fringe_bitmaps
* sizeof (struct fringe_bitmap
*));
1458 = (unsigned *) xmalloc (max_fringe_bitmaps
* sizeof (unsigned));
1460 for (i
= 0; i
< max_fringe_bitmaps
; i
++)
1462 fringe_bitmaps
[i
] = NULL
;
1463 fringe_faces
[i
] = FRINGE_FACE_ID
;
1472 enum fringe_bitmap_type bt
;
1477 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1479 struct fringe_bitmap
*fb
= &standard_bitmaps
[bt
];
1480 rif
->define_fringe_bitmap (bt
, fb
->bits
, fb
->height
, fb
->width
);
1485 w32_reset_fringes ()
1487 /* Destroy row bitmaps. */
1493 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< max_used_fringe_bitmap
; bt
++)
1494 rif
->destroy_fringe_bitmap (bt
);
1497 #endif /* HAVE_NTGUI */
1499 #endif /* HAVE_WINDOW_SYSTEM */
1501 /* arch-tag: 04596920-43eb-473d-b319-82712338162d
1502 (do not change this comment) */