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 Lisp_Object
*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
)
553 if ((face
= fringe_faces
[which
], NILP (face
))
554 || (face_id
= lookup_derived_face (f
, face
, 'A', FRINGE_FACE_ID
, 0),
556 face_id
= FRINGE_FACE_ID
;
559 fb
= fringe_bitmaps
[which
];
561 fb
= &standard_bitmaps
[which
< MAX_STANDARD_FRINGE_BITMAPS
562 ? which
: UNDEF_FRINGE_BITMAP
];
566 /* Convert row to frame coordinates. */
567 p
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
574 p
.dh
= (period
> 0 ? (p
.y
% period
) : 0);
576 /* Clip bitmap if too high. */
577 if (p
.h
> row
->height
)
580 p
.face
= FACE_FROM_ID (f
, face_id
);
584 /* This could happen after clearing face cache.
585 But it shouldn't happen anymore. ++kfs */
589 PREPARE_FACE_FOR_DISPLAY (f
, p
.face
);
591 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
596 int wd
= WINDOW_LEFT_FRINGE_WIDTH (w
);
597 int x
= window_box_left (w
, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
602 p
.x
= x
- p
.wd
- (wd
- p
.wd
) / 2;
604 if (p
.wd
< wd
|| row
->height
> p
.h
)
606 /* If W has a vertical border to its left, don't draw over it. */
607 wd
-= ((!WINDOW_LEFTMOST_P (w
)
608 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
616 int x
= window_box_right (w
,
617 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
620 int wd
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
623 p
.x
= x
+ (wd
- p
.wd
) / 2;
624 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
626 if (p
.wd
< wd
|| row
->height
> p
.h
)
635 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
637 p
.by
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, row
->y
));
638 p
.ny
= row
->visible_height
;
641 /* Adjust y to the offset in the row to start drawing the bitmap. */
644 case ALIGN_BITMAP_CENTER
:
645 p
.y
+= (row
->height
- p
.h
) / 2;
647 case ALIGN_BITMAP_BOTTOM
:
649 p
.y
+= (row
->visible_height
- p
.h
);
651 case ALIGN_BITMAP_TOP
:
655 rif
->draw_fringe_bitmap (w
, row
, &p
);
659 draw_fringe_bitmap (w
, row
, left_p
)
661 struct glyph_row
*row
;
666 if (!left_p
&& row
->cursor_in_fringe_p
)
668 int cursor
= NO_FRINGE_BITMAP
;
670 switch (w
->phys_cursor_type
)
672 case HOLLOW_BOX_CURSOR
:
673 if (row
->visible_height
>= STANDARD_BITMAP_HEIGHT (hollow_box_cursor_bits
))
674 cursor
= HOLLOW_BOX_CURSOR_BITMAP
;
676 cursor
= HOLLOW_SQUARE_BITMAP
;
678 case FILLED_BOX_CURSOR
:
679 cursor
= FILLED_BOX_CURSOR_BITMAP
;
682 cursor
= BAR_CURSOR_BITMAP
;
685 cursor
= HBAR_CURSOR_BITMAP
;
689 w
->phys_cursor_on_p
= 0;
690 row
->cursor_in_fringe_p
= 0;
693 if (cursor
!= NO_FRINGE_BITMAP
)
695 draw_fringe_bitmap_1 (w
, row
, 0, 2, cursor
);
696 overlay
= cursor
== FILLED_BOX_CURSOR_BITMAP
? 3 : 1;
700 draw_fringe_bitmap_1 (w
, row
, left_p
, overlay
, NO_FRINGE_BITMAP
);
702 if (left_p
&& row
->overlay_arrow_bitmap
!= NO_FRINGE_BITMAP
)
703 draw_fringe_bitmap_1 (w
, row
, 1, 1,
704 (row
->overlay_arrow_bitmap
< 0
705 ? OVERLAY_ARROW_BITMAP
706 : row
->overlay_arrow_bitmap
));
710 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
711 function with input blocked. */
714 draw_row_fringe_bitmaps (w
, row
)
716 struct glyph_row
*row
;
718 xassert (interrupt_input_blocked
);
720 /* If row is completely invisible, because of vscrolling, we
721 don't have to draw anything. */
722 if (row
->visible_height
<= 0)
725 if (WINDOW_LEFT_FRINGE_WIDTH (w
) != 0)
726 draw_fringe_bitmap (w
, row
, 1);
728 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) != 0)
729 draw_fringe_bitmap (w
, row
, 0);
732 /* Draw the fringes of window W. Only fringes for rows marked for
733 update in redraw_fringe_bitmaps_p are drawn.
735 Return >0 if left or right fringe was redrawn in any way.
737 If NO_FRINGE is non-zero, also return >0 if either fringe has zero width.
739 A return value >0 indicates that the vertical line between windows
740 needs update (as it may be drawn in the fringe).
744 draw_window_fringes (w
, no_fringe
)
748 struct glyph_row
*row
;
749 int yb
= window_text_bottom_y (w
);
750 int nrows
= w
->current_matrix
->nrows
;
754 if (w
->pseudo_window_p
)
757 /* Must draw line if no fringe */
759 && (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0
760 || WINDOW_RIGHT_FRINGE_WIDTH (w
) == 0))
763 for (y
= 0, rn
= 0, row
= w
->current_matrix
->rows
;
764 y
< yb
&& rn
< nrows
;
765 y
+= row
->height
, ++row
, ++rn
)
767 if (!row
->redraw_fringe_bitmaps_p
)
769 draw_row_fringe_bitmaps (w
, row
);
770 row
->redraw_fringe_bitmaps_p
= 0;
778 /* Recalculate the bitmaps to show in the fringes of window W.
779 If FORCE_P is 0, only mark rows with modified bitmaps for update in
780 redraw_fringe_bitmaps_p; else mark all rows for update. */
783 update_window_fringes (w
, force_p
)
787 struct glyph_row
*row
, *cur
= 0;
788 int yb
= window_text_bottom_y (w
);
789 int rn
, nrows
= w
->current_matrix
->nrows
;
792 Lisp_Object boundary_top
= Qnil
, boundary_bot
= Qnil
;
793 Lisp_Object arrow_top
= Qnil
, arrow_bot
= Qnil
;
794 Lisp_Object empty_pos
;
795 Lisp_Object ind
= Qnil
;
797 if (w
->pseudo_window_p
)
800 if (!MINI_WINDOW_P (w
)
801 && (ind
= XBUFFER (w
->buffer
)->indicate_buffer_boundaries
, !NILP (ind
)))
803 if (EQ (ind
, Qleft
) || EQ (ind
, Qright
))
804 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= ind
;
805 else if (CONSP (ind
) && CONSP (XCAR (ind
)))
808 if (pos
= Fassq (Qt
, ind
), !NILP (pos
))
809 boundary_top
= boundary_bot
= arrow_top
= arrow_bot
= XCDR (pos
);
810 if (pos
= Fassq (Qtop
, ind
), !NILP (pos
))
811 boundary_top
= XCDR (pos
);
812 if (pos
= Fassq (Qbottom
, ind
), !NILP (pos
))
813 boundary_bot
= XCDR (pos
);
814 if (pos
= Fassq (Qup
, ind
), !NILP (pos
))
815 arrow_top
= XCDR (pos
);
816 if (pos
= Fassq (Qdown
, ind
), !NILP (pos
))
817 arrow_bot
= XCDR (pos
);
820 /* Anything else means boundary on left and no arrows. */
821 boundary_top
= boundary_bot
= Qleft
;
826 int done_top
= 0, done_bot
= 0;
829 y
< yb
&& rn
< nrows
;
830 y
+= row
->height
, ++rn
)
832 unsigned indicate_bob_p
, indicate_top_line_p
;
833 unsigned indicate_eob_p
, indicate_bottom_line_p
;
835 row
= w
->desired_matrix
->rows
+ rn
;
837 row
= w
->current_matrix
->rows
+ rn
;
839 indicate_bob_p
= row
->indicate_bob_p
;
840 indicate_top_line_p
= row
->indicate_top_line_p
;
841 indicate_eob_p
= row
->indicate_eob_p
;
842 indicate_bottom_line_p
= row
->indicate_bottom_line_p
;
844 row
->indicate_bob_p
= row
->indicate_top_line_p
= 0;
845 row
->indicate_eob_p
= row
->indicate_bottom_line_p
= 0;
847 if (!row
->mode_line_p
)
851 if (MATRIX_ROW_START_CHARPOS (row
) <= BUF_BEGV (XBUFFER (w
->buffer
)))
852 row
->indicate_bob_p
= !NILP (boundary_top
);
854 row
->indicate_top_line_p
= !NILP (arrow_top
);
860 if (MATRIX_ROW_END_CHARPOS (row
) >= BUF_ZV (XBUFFER (w
->buffer
)))
861 row
->indicate_eob_p
= !NILP (boundary_bot
), done_bot
= 1;
862 else if (y
+ row
->height
>= yb
)
863 row
->indicate_bottom_line_p
= !NILP (arrow_bot
), done_bot
= 1;
867 if (indicate_bob_p
!= row
->indicate_bob_p
868 || indicate_top_line_p
!= row
->indicate_top_line_p
869 || indicate_eob_p
!= row
->indicate_eob_p
870 || indicate_bottom_line_p
!= row
->indicate_bottom_line_p
)
871 row
->redraw_fringe_bitmaps_p
= 1;
875 empty_pos
= XBUFFER (w
->buffer
)->indicate_empty_lines
;
876 if (!NILP (empty_pos
) && !EQ (empty_pos
, Qright
))
877 empty_pos
= WINDOW_LEFT_FRINGE_WIDTH (w
) == 0 ? Qright
: Qleft
;
880 y
< yb
&& rn
< nrows
;
881 y
+= row
->height
, rn
++)
883 enum fringe_bitmap_type left
, right
;
884 unsigned left_face_id
, right_face_id
;
886 row
= w
->desired_matrix
->rows
+ rn
;
887 cur
= w
->current_matrix
->rows
+ rn
;
891 left_face_id
= right_face_id
= DEFAULT_FACE_ID
;
893 /* Decide which bitmap to draw in the left fringe. */
894 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
895 left
= NO_FRINGE_BITMAP
;
896 else if (row
->left_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
898 left
= row
->left_user_fringe_bitmap
;
899 left_face_id
= row
->left_user_fringe_face_id
;
901 else if (row
->truncated_on_left_p
)
902 left
= LEFT_TRUNCATION_BITMAP
;
903 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qleft
))
904 left
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
905 ? LEFT_BRACKET_BITMAP
: TOP_LEFT_ANGLE_BITMAP
);
906 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qleft
))
907 left
= BOTTOM_LEFT_ANGLE_BITMAP
;
908 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
909 left
= CONTINUATION_LINE_BITMAP
;
910 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qleft
))
911 left
= ZV_LINE_BITMAP
;
912 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qleft
))
913 left
= UP_ARROW_BITMAP
;
914 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qleft
))
915 left
= DOWN_ARROW_BITMAP
;
917 left
= NO_FRINGE_BITMAP
;
919 /* Decide which bitmap to draw in the right fringe. */
920 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) == 0)
921 right
= NO_FRINGE_BITMAP
;
922 else if (row
->right_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
924 right
= row
->right_user_fringe_bitmap
;
925 right_face_id
= row
->right_user_fringe_face_id
;
927 else if (row
->truncated_on_right_p
)
928 right
= RIGHT_TRUNCATION_BITMAP
;
929 else if (row
->indicate_bob_p
&& EQ (boundary_top
, Qright
))
930 right
= ((row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
931 ? RIGHT_BRACKET_BITMAP
: TOP_RIGHT_ANGLE_BITMAP
);
932 else if (row
->indicate_eob_p
&& EQ (boundary_bot
, Qright
))
933 right
= BOTTOM_RIGHT_ANGLE_BITMAP
;
934 else if (row
->continued_p
)
935 right
= CONTINUED_LINE_BITMAP
;
936 else if (row
->indicate_top_line_p
&& EQ (arrow_top
, Qright
))
937 right
= UP_ARROW_BITMAP
;
938 else if (row
->indicate_bottom_line_p
&& EQ (arrow_bot
, Qright
))
939 right
= DOWN_ARROW_BITMAP
;
940 else if (row
->indicate_empty_line_p
&& EQ (empty_pos
, Qright
))
941 right
= ZV_LINE_BITMAP
;
943 right
= NO_FRINGE_BITMAP
;
947 || row
->visible_height
!= cur
->visible_height
948 || row
->ends_at_zv_p
!= cur
->ends_at_zv_p
949 || left
!= cur
->left_fringe_bitmap
950 || right
!= cur
->right_fringe_bitmap
951 || left_face_id
!= cur
->left_fringe_face_id
952 || right_face_id
!= cur
->right_fringe_face_id
953 || cur
->redraw_fringe_bitmaps_p
)
955 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
956 cur
->left_fringe_bitmap
= left
;
957 cur
->right_fringe_bitmap
= right
;
958 cur
->left_fringe_face_id
= left_face_id
;
959 cur
->right_fringe_face_id
= right_face_id
;
962 if (row
->overlay_arrow_bitmap
!= cur
->overlay_arrow_bitmap
)
964 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
965 cur
->overlay_arrow_bitmap
= row
->overlay_arrow_bitmap
;
968 row
->left_fringe_bitmap
= left
;
969 row
->right_fringe_bitmap
= right
;
970 row
->left_fringe_face_id
= left_face_id
;
971 row
->right_fringe_face_id
= right_face_id
;
973 if (rn
> 0 && row
->redraw_fringe_bitmaps_p
)
974 row
[-1].redraw_fringe_bitmaps_p
= cur
[-1].redraw_fringe_bitmaps_p
= 1;
981 /* Compute actual fringe widths for frame F.
983 If REDRAW is 1, redraw F if the fringe settings was actually
984 modified and F is visible.
986 Since the combined left and right fringe must occupy an integral
987 number of columns, we may need to add some pixels to each fringe.
988 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
989 but a negative width value is taken literally (after negating it).
991 We never make the fringes narrower than specified.
995 compute_fringe_widths (f
, redraw
)
999 int o_left
= FRAME_LEFT_FRINGE_WIDTH (f
);
1000 int o_right
= FRAME_RIGHT_FRINGE_WIDTH (f
);
1001 int o_cols
= FRAME_FRINGE_COLS (f
);
1003 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
1004 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
1005 int left_fringe_width
, right_fringe_width
;
1007 if (!NILP (left_fringe
))
1008 left_fringe
= Fcdr (left_fringe
);
1009 if (!NILP (right_fringe
))
1010 right_fringe
= Fcdr (right_fringe
);
1012 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
1013 XINT (left_fringe
));
1014 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
1015 XINT (right_fringe
));
1017 if (left_fringe_width
|| right_fringe_width
)
1019 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
1020 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
1021 int conf_wid
= left_wid
+ right_wid
;
1022 int font_wid
= FRAME_COLUMN_WIDTH (f
);
1023 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
1024 int real_wid
= cols
* font_wid
;
1025 if (left_wid
&& right_wid
)
1027 if (left_fringe_width
< 0)
1029 /* Left fringe width is fixed, adjust right fringe if necessary */
1030 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
;
1031 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
- left_wid
;
1033 else if (right_fringe_width
< 0)
1035 /* Right fringe width is fixed, adjust left fringe if necessary */
1036 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
- right_wid
;
1037 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
;
1041 /* Adjust both fringes with an equal amount.
1042 Note that we are doing integer arithmetic here, so don't
1043 lose a pixel if the total width is an odd number. */
1044 int fill
= real_wid
- conf_wid
;
1045 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
+ fill
/2;
1046 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
+ fill
- fill
/2;
1049 else if (left_fringe_width
)
1051 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
;
1052 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1056 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1057 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
;
1059 FRAME_FRINGE_COLS (f
) = cols
;
1063 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
1064 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
1065 FRAME_FRINGE_COLS (f
) = 0;
1068 if (redraw
&& FRAME_VISIBLE_P (f
))
1069 if (o_left
!= FRAME_LEFT_FRINGE_WIDTH (f
) ||
1070 o_right
!= FRAME_RIGHT_FRINGE_WIDTH (f
) ||
1071 o_cols
!= FRAME_FRINGE_COLS (f
))
1076 /* Free resources used by a user-defined bitmap. */
1079 destroy_fringe_bitmap (n
)
1082 struct fringe_bitmap
**fbp
;
1084 fringe_faces
[n
] = Qnil
;
1086 fbp
= &fringe_bitmaps
[n
];
1087 if (*fbp
&& (*fbp
)->dynamic
)
1089 if (rif
&& rif
->destroy_fringe_bitmap
)
1090 rif
->destroy_fringe_bitmap (n
);
1095 while (max_used_fringe_bitmap
> MAX_STANDARD_FRINGE_BITMAPS
1096 && fringe_bitmaps
[max_used_fringe_bitmap
- 1] == NULL
)
1097 max_used_fringe_bitmap
--;
1101 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap
, Sdestroy_fringe_bitmap
,
1103 doc
: /* Destroy fringe bitmap BITMAP.
1104 If BITMAP overrides a standard fringe bitmap, the original bitmap is restored. */)
1110 CHECK_SYMBOL (bitmap
);
1111 n
= lookup_fringe_bitmap (bitmap
);
1115 destroy_fringe_bitmap (n
);
1117 if (n
>= MAX_STANDARD_FRINGE_BITMAPS
)
1119 Vfringe_bitmaps
= Fdelq (bitmap
, Vfringe_bitmaps
);
1120 /* It would be better to remove the fringe property. */
1121 Fput (bitmap
, Qfringe
, Qnil
);
1128 /* Initialize bitmap bit.
1130 On X, we bit-swap the built-in bitmaps and reduce bitmap
1131 from short to char array if width is <= 8 bits.
1133 On MAC with big-endian CPU, we need to byte-swap each short.
1135 On W32 and MAC (little endian), there's no need to do this.
1139 init_fringe_bitmap (which
, fb
, once_p
)
1140 enum fringe_bitmap_type which
;
1141 struct fringe_bitmap
*fb
;
1144 if (once_p
|| fb
->dynamic
)
1146 #if defined (HAVE_X_WINDOWS)
1147 static unsigned char swap_nibble
[16]
1148 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1149 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1150 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1151 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
1152 unsigned short *bits
= fb
->bits
;
1157 unsigned char *cbits
= (unsigned char *)fb
->bits
;
1158 for (j
= 0; j
< fb
->height
; j
++)
1160 unsigned short b
= *bits
++;
1162 c
= (unsigned char)((swap_nibble
[b
& 0xf] << 4)
1163 | (swap_nibble
[(b
>>4) & 0xf]));
1164 *cbits
++ = (c
>> (8 - fb
->width
));
1169 for (j
= 0; j
< fb
->height
; j
++)
1171 unsigned short b
= *bits
;
1172 b
= (unsigned short)((swap_nibble
[b
& 0xf] << 12)
1173 | (swap_nibble
[(b
>>4) & 0xf] << 8)
1174 | (swap_nibble
[(b
>>8) & 0xf] << 4)
1175 | (swap_nibble
[(b
>>12) & 0xf]));
1176 *bits
++ = (b
>> (16 - fb
->width
));
1179 #endif /* HAVE_X_WINDOWS */
1181 #if defined (MAC_OS) && defined (WORDS_BIG_ENDIAN)
1182 unsigned short *bits
= fb
->bits
;
1184 for (j
= 0; j
< fb
->height
; j
++)
1186 unsigned short b
= *bits
;
1187 *bits
++ = ((b
>> 8) & 0xff) | ((b
& 0xff) << 8);
1189 #endif /* MAC_OS && WORDS_BIG_ENDIAN */
1194 destroy_fringe_bitmap (which
);
1196 if (rif
&& rif
->define_fringe_bitmap
)
1197 rif
->define_fringe_bitmap (which
, fb
->bits
, fb
->height
, fb
->width
);
1199 fringe_bitmaps
[which
] = fb
;
1200 if (which
>= max_used_fringe_bitmap
)
1201 max_used_fringe_bitmap
= which
+ 1;
1206 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap
, Sdefine_fringe_bitmap
,
1208 doc
: /* Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH.
1209 BITMAP is a symbol or string naming the new fringe bitmap.
1210 BITS is either a string or a vector of integers.
1211 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1212 WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1213 Optional fifth arg ALIGN may be one of `top', `center', or `bottom',
1214 indicating the positioning of the bitmap relative to the rows where it
1215 is used; the default is to center the bitmap. Fourth arg may also be a
1216 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1218 If BITMAP already exists, the existing definition is replaced. */)
1219 (bitmap
, bits
, height
, width
, align
)
1220 Lisp_Object bitmap
, bits
, height
, width
, align
;
1224 struct fringe_bitmap fb
, *xfb
;
1225 int fill1
= 0, fill2
= 0;
1227 CHECK_SYMBOL (bitmap
);
1231 else if (VECTORP (bits
))
1232 h
= XVECTOR (bits
)->size
;
1234 bits
= wrong_type_argument (Qsequencep
, bits
);
1240 CHECK_NUMBER (height
);
1241 fb
.height
= min (XINT (height
), 255);
1244 fill1
= (fb
.height
- h
) / 2;
1245 fill2
= fb
.height
- h
- fill1
;
1253 CHECK_NUMBER (width
);
1254 fb
.width
= min (XINT (width
), 255);
1258 fb
.align
= ALIGN_BITMAP_CENTER
;
1262 Lisp_Object period
= XCDR (align
);
1265 period
= XCAR (period
);
1268 fb
.period
= fb
.height
;
1272 align
= XCAR (align
);
1274 if (EQ (align
, Qtop
))
1275 fb
.align
= ALIGN_BITMAP_TOP
;
1276 else if (EQ (align
, Qbottom
))
1277 fb
.align
= ALIGN_BITMAP_BOTTOM
;
1278 else if (!NILP (align
) && !EQ (align
, Qcenter
))
1279 error ("Bad align argument");
1281 n
= lookup_fringe_bitmap (bitmap
);
1284 if (max_used_fringe_bitmap
< max_fringe_bitmaps
)
1285 n
= max_used_fringe_bitmap
++;
1288 for (n
= MAX_STANDARD_FRINGE_BITMAPS
;
1289 n
< max_fringe_bitmaps
;
1291 if (fringe_bitmaps
[n
] == NULL
)
1294 if (n
== max_fringe_bitmaps
)
1296 if ((max_fringe_bitmaps
+ 20) > MAX_FRINGE_BITMAPS
)
1297 error ("No free fringe bitmap slots");
1299 i
= max_fringe_bitmaps
;
1300 max_fringe_bitmaps
+= 20;
1302 = ((struct fringe_bitmap
**)
1303 xrealloc (fringe_bitmaps
, max_fringe_bitmaps
* sizeof (struct fringe_bitmap
*)));
1305 = (Lisp_Object
*) xrealloc (fringe_faces
, max_fringe_bitmaps
* sizeof (Lisp_Object
));
1307 for (; i
< max_fringe_bitmaps
; i
++)
1309 fringe_bitmaps
[i
] = NULL
;
1310 fringe_faces
[i
] = Qnil
;
1315 Vfringe_bitmaps
= Fcons (bitmap
, Vfringe_bitmaps
);
1316 Fput (bitmap
, Qfringe
, make_number (n
));
1321 xfb
= (struct fringe_bitmap
*) xmalloc (sizeof fb
1322 + fb
.height
* BYTES_PER_BITMAP_ROW
);
1323 fb
.bits
= b
= (unsigned short *) (xfb
+ 1);
1324 bzero (b
, fb
.height
);
1327 while (j
< fb
.height
)
1329 for (i
= 0; i
< fill1
&& j
< fb
.height
; i
++)
1331 for (i
= 0; i
< h
&& j
< fb
.height
; i
++)
1333 Lisp_Object elt
= Faref (bits
, make_number (i
));
1334 b
[j
++] = NUMBERP (elt
) ? XINT (elt
) : 0;
1336 for (i
= 0; i
< fill2
&& j
< fb
.height
; i
++)
1342 init_fringe_bitmap (n
, xfb
, 0);
1347 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face
, Sset_fringe_bitmap_face
,
1349 doc
: /* Set face for fringe bitmap BITMAP to FACE.
1350 If FACE is nil, reset face to default fringe face. */)
1352 Lisp_Object bitmap
, face
;
1357 CHECK_SYMBOL (bitmap
);
1358 n
= lookup_fringe_bitmap (bitmap
);
1360 error ("Undefined fringe bitmap");
1364 face_id
= lookup_derived_face (SELECTED_FRAME (), face
,
1365 'A', FRINGE_FACE_ID
, 1);
1367 error ("No such face");
1370 fringe_faces
[n
] = face
;
1375 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos
, Sfringe_bitmaps_at_pos
,
1377 doc
: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1378 If WINDOW is nil, use selected window. If POS is nil, use value of point
1379 in that window. Return value is a list (LEFT RIGHT OV), where LEFT
1380 is the symbol for the bitmap in the left fringe (or nil if no bitmap),
1381 RIGHT is similar for the right fringe, and OV is non-nil if there is an
1382 overlay arrow in the left fringe.
1383 Return nil if POS is not visible in WINDOW. */)
1385 Lisp_Object pos
, window
;
1388 struct glyph_row
*row
;
1392 window
= selected_window
;
1393 CHECK_WINDOW (window
);
1394 w
= XWINDOW (window
);
1398 CHECK_NUMBER_COERCE_MARKER (pos
);
1399 textpos
= XINT (pos
);
1401 else if (w
== XWINDOW (selected_window
))
1404 textpos
= XMARKER (w
->pointm
)->charpos
;
1406 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
1407 row
= row_containing_pos (w
, textpos
, row
, NULL
, 0);
1409 return list3 (get_fringe_bitmap_name (row
->left_fringe_bitmap
),
1410 get_fringe_bitmap_name (row
->right_fringe_bitmap
),
1411 (row
->overlay_arrow_bitmap
== 0 ? Qnil
1412 : row
->overlay_arrow_bitmap
< 0 ? Qt
1413 : get_fringe_bitmap_name (row
->overlay_arrow_bitmap
)));
1419 /***********************************************************************
1421 ***********************************************************************/
1426 defsubr (&Sdestroy_fringe_bitmap
);
1427 defsubr (&Sdefine_fringe_bitmap
);
1428 defsubr (&Sfringe_bitmaps_at_pos
);
1429 defsubr (&Sset_fringe_bitmap_face
);
1431 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe
,
1432 doc
: /* *Non-nil means that newline may flow into the right fringe.
1433 This means that display lines which are exactly as wide as the window
1434 (not counting the final newline) will only occupy one screen line, by
1435 showing (or hiding) the final newline in the right fringe; when point
1436 is at the final newline, the cursor is shown in the right fringe.
1437 If nil, also continue lines which are exactly as wide as the window. */);
1438 Voverflow_newline_into_fringe
= Qt
;
1440 DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps
,
1441 doc
: /* List of fringe bitmap symbols.
1442 You must (require 'fringe) to use fringe bitmap symbols in your programs." */);
1443 Vfringe_bitmaps
= Qnil
;
1446 /* Garbage collection hook */
1453 for (i
= 0; i
< max_fringe_bitmaps
; i
++)
1454 if (!NILP (fringe_faces
[i
]))
1455 mark_object (fringe_faces
[i
]);
1458 /* Initialize this module when Emacs starts. */
1463 enum fringe_bitmap_type bt
;
1465 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1466 init_fringe_bitmap(bt
, &standard_bitmaps
[bt
], 1);
1474 max_fringe_bitmaps
= MAX_STANDARD_FRINGE_BITMAPS
+ 20;
1477 = (struct fringe_bitmap
**) xmalloc (max_fringe_bitmaps
* sizeof (struct fringe_bitmap
*));
1479 = (Lisp_Object
*) xmalloc (max_fringe_bitmaps
* sizeof (Lisp_Object
));
1481 for (i
= 0; i
< max_fringe_bitmaps
; i
++)
1483 fringe_bitmaps
[i
] = NULL
;
1484 fringe_faces
[i
] = Qnil
;
1493 enum fringe_bitmap_type bt
;
1498 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1500 struct fringe_bitmap
*fb
= &standard_bitmaps
[bt
];
1501 rif
->define_fringe_bitmap (bt
, fb
->bits
, fb
->height
, fb
->width
);
1506 w32_reset_fringes ()
1508 /* Destroy row bitmaps. */
1514 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< max_used_fringe_bitmap
; bt
++)
1515 rif
->destroy_fringe_bitmap (bt
);
1518 #endif /* HAVE_NTGUI */
1520 #endif /* HAVE_WINDOW_SYSTEM */
1522 /* arch-tag: 04596920-43eb-473d-b319-82712338162d
1523 (do not change this comment) */