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 Qtop
, Qbottom
, Qcenter
;
36 /* Non-nil means that newline may flow into the right fringe. */
38 Lisp_Object Voverflow_newline_into_fringe
;
41 enum fringe_bitmap_type
45 LEFT_TRUNCATION_BITMAP
,
46 RIGHT_TRUNCATION_BITMAP
,
49 CONTINUED_LINE_BITMAP
,
50 CONTINUATION_LINE_BITMAP
,
52 TOP_LEFT_ANGLE_BITMAP
,
53 TOP_RIGHT_ANGLE_BITMAP
,
54 BOTTOM_LEFT_ANGLE_BITMAP
,
55 BOTTOM_RIGHT_ANGLE_BITMAP
,
58 FILLED_BOX_CURSOR_BITMAP
,
59 HOLLOW_BOX_CURSOR_BITMAP
,
64 MAX_STANDARD_FRINGE_BITMAPS
67 enum fringe_bitmap_align
69 ALIGN_BITMAP_CENTER
= 0,
85 /***********************************************************************
87 ***********************************************************************/
89 /* Undefined bitmap. A question mark. */
102 static unsigned short unknown_bits
[] = {
103 0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
105 /* An arrow like this: `<-'. */
116 static unsigned short left_arrow_bits
[] = {
117 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
120 /* Right truncation arrow bitmap `->'. */
131 static unsigned short right_arrow_bits
[] = {
132 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
135 /* Up arrow bitmap. */
146 static unsigned short up_arrow_bits
[] = {
147 0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
150 /* Down arrow bitmap. */
161 static unsigned short down_arrow_bits
[] = {
162 0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
164 /* Marker for continued lines. */
175 static unsigned short continued_bits
[] = {
176 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
178 /* Marker for continuation lines. */
189 static unsigned short continuation_bits
[] = {
190 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
192 /* Overlay arrow bitmap. A triangular arrow. */
203 static unsigned short ov_bits
[] = {
204 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
207 /* Reverse Overlay arrow bitmap. A triangular arrow. */
218 static unsigned short rev_ov_bits
[] = {
219 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
222 /* First line bitmap. An top-left angle. */
233 static unsigned short top_left_angle_bits
[] = {
234 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00};
236 /* First line bitmap. An right-up angle. */
247 static unsigned short top_right_angle_bits
[] = {
248 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
250 /* Last line bitmap. An left-down angle. */
261 static unsigned short bottom_left_angle_bits
[] = {
262 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
264 /* Last line bitmap. An right-down angle. */
275 static unsigned short bottom_right_angle_bits
[] = {
276 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
278 /* First/last line bitmap. An left bracket. */
291 static unsigned short left_bracket_bits
[] = {
292 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
294 /* First/last line bitmap. An right bracket. */
307 static unsigned short right_bracket_bits
[] = {
308 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
310 /* Filled box cursor bitmap. A filled box; max 13 pixels high. */
326 static unsigned short filled_box_cursor_bits
[] = {
327 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
329 /* Hollow box cursor bitmap. A hollow box; max 13 pixels high. */
345 static unsigned short hollow_box_cursor_bits
[] = {
346 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe};
348 /* Bar cursor bitmap. A vertical bar; max 13 pixels high. */
364 static unsigned short bar_cursor_bits
[] = {
365 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
367 /* HBar cursor bitmap. A horisontal bar; 2 pixels high. */
372 static unsigned short hbar_cursor_bits
[] = {
376 /* Bitmap drawn to indicate lines not displaying text if
377 `indicate-empty-lines' is non-nil. */
386 static unsigned short zv_bits
[] = {
387 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
388 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
389 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
390 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
391 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
392 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
393 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
394 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
396 /* Hollow square bitmap. */
405 static unsigned short hollow_square_bits
[] = {
406 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
409 #define BYTES_PER_BITMAP_ROW (sizeof (unsigned short))
410 #define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
411 #define FRBITS(bits) bits, STANDARD_BITMAP_HEIGHT (bits)
413 struct fringe_bitmap standard_bitmaps
[MAX_STANDARD_FRINGE_BITMAPS
] =
415 { NULL
, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */
416 { FRBITS (unknown_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
417 { FRBITS (left_arrow_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
418 { FRBITS (right_arrow_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
419 { FRBITS (up_arrow_bits
), 8, 0, ALIGN_BITMAP_TOP
, 0 },
420 { FRBITS (down_arrow_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
421 { FRBITS (continued_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
422 { FRBITS (continuation_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
423 { FRBITS (ov_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
424 { FRBITS (top_left_angle_bits
), 8, 0, ALIGN_BITMAP_TOP
, 0 },
425 { FRBITS (top_right_angle_bits
), 8, 0, ALIGN_BITMAP_TOP
, 0 },
426 { FRBITS (bottom_left_angle_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
427 { FRBITS (bottom_right_angle_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
428 { FRBITS (left_bracket_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
429 { FRBITS (right_bracket_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
430 { FRBITS (filled_box_cursor_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
431 { FRBITS (hollow_box_cursor_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
432 { FRBITS (hollow_square_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
433 { FRBITS (bar_cursor_bits
), 8, 0, ALIGN_BITMAP_CENTER
, 0 },
434 { FRBITS (hbar_cursor_bits
), 8, 0, ALIGN_BITMAP_BOTTOM
, 0 },
435 { FRBITS (zv_bits
), 8, 3, ALIGN_BITMAP_TOP
, 0 },
438 static struct fringe_bitmap
*fringe_bitmaps
[MAX_FRINGE_BITMAPS
];
439 static unsigned fringe_faces
[MAX_FRINGE_BITMAPS
];
441 static int max_used_fringe_bitmap
= MAX_STANDARD_FRINGE_BITMAPS
;
443 /* Return 1 if FRINGE_ID is a valid fringe bitmap id. */
446 valid_fringe_bitmap_id_p (fringe_id
)
449 return (fringe_id
>= NO_FRINGE_BITMAP
450 && fringe_id
< max_used_fringe_bitmap
451 && (fringe_id
< MAX_STANDARD_FRINGE_BITMAPS
452 || fringe_bitmaps
[fringe_id
] != NULL
));
455 /* Draw the bitmap WHICH in one of the left or right fringes of
456 window W. ROW is the glyph row for which to display the bitmap; it
457 determines the vertical position at which the bitmap has to be
459 LEFT_P is 1 for left fringe, 0 for right fringe.
463 draw_fringe_bitmap_1 (w
, row
, left_p
, overlay
, which
)
465 struct glyph_row
*row
;
467 enum fringe_bitmap_type which
;
469 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
470 struct draw_fringe_bitmap_params p
;
471 struct fringe_bitmap
*fb
;
473 int face_id
= DEFAULT_FACE_ID
;
476 p
.overlay_p
= (overlay
& 1) == 1;
477 p
.cursor_p
= (overlay
& 2) == 2;
479 if (which
!= NO_FRINGE_BITMAP
)
484 which
= row
->left_fringe_bitmap
;
485 face_id
= row
->left_fringe_face_id
;
489 which
= row
->right_fringe_bitmap
;
490 face_id
= row
->right_fringe_face_id
;
493 if (face_id
== DEFAULT_FACE_ID
)
494 face_id
= fringe_faces
[which
];
496 fb
= fringe_bitmaps
[which
];
498 fb
= &standard_bitmaps
[which
< MAX_STANDARD_FRINGE_BITMAPS
499 ? which
: UNDEF_FRINGE_BITMAP
];
503 /* Convert row to frame coordinates. */
504 p
.y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
511 p
.dh
= (period
> 0 ? (p
.y
% period
) : 0);
513 /* Clip bitmap if too high. */
514 if (p
.h
> row
->height
)
517 p
.face
= FACE_FROM_ID (f
, face_id
);
521 /* Why does this happen? ++kfs */
525 PREPARE_FACE_FOR_DISPLAY (f
, p
.face
);
527 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
532 int wd
= WINDOW_LEFT_FRINGE_WIDTH (w
);
533 int x
= window_box_left (w
, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
538 p
.x
= x
- p
.wd
- (wd
- p
.wd
) / 2;
540 if (p
.wd
< wd
|| row
->height
> p
.h
)
542 /* If W has a vertical border to its left, don't draw over it. */
543 wd
-= ((!WINDOW_LEFTMOST_P (w
)
544 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
552 int x
= window_box_right (w
,
553 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
556 int wd
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
559 p
.x
= x
+ (wd
- p
.wd
) / 2;
560 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
562 if (p
.wd
< wd
|| row
->height
> p
.h
)
571 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
573 p
.by
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, row
->y
));
574 p
.ny
= row
->visible_height
;
577 /* Adjust y to the offset in the row to start drawing the bitmap. */
580 case ALIGN_BITMAP_CENTER
:
581 p
.y
+= (row
->height
- p
.h
) / 2;
583 case ALIGN_BITMAP_BOTTOM
:
585 p
.y
+= (row
->visible_height
- p
.h
);
587 case ALIGN_BITMAP_TOP
:
591 rif
->draw_fringe_bitmap (w
, row
, &p
);
595 draw_fringe_bitmap (w
, row
, left_p
)
597 struct glyph_row
*row
;
602 if (!left_p
&& row
->cursor_in_fringe_p
)
604 int cursor
= NO_FRINGE_BITMAP
;
606 switch (w
->phys_cursor_type
)
608 case HOLLOW_BOX_CURSOR
:
609 if (row
->visible_height
>= STANDARD_BITMAP_HEIGHT (hollow_box_cursor_bits
))
610 cursor
= HOLLOW_BOX_CURSOR_BITMAP
;
612 cursor
= HOLLOW_SQUARE_BITMAP
;
614 case FILLED_BOX_CURSOR
:
615 cursor
= FILLED_BOX_CURSOR_BITMAP
;
618 cursor
= BAR_CURSOR_BITMAP
;
621 cursor
= HBAR_CURSOR_BITMAP
;
625 w
->phys_cursor_on_p
= 0;
626 row
->cursor_in_fringe_p
= 0;
629 if (cursor
!= NO_FRINGE_BITMAP
)
631 draw_fringe_bitmap_1 (w
, row
, 0, 2, cursor
);
632 overlay
= cursor
== FILLED_BOX_CURSOR_BITMAP
? 3 : 1;
636 draw_fringe_bitmap_1 (w
, row
, left_p
, overlay
, NO_FRINGE_BITMAP
);
638 if (left_p
&& row
->overlay_arrow_p
)
639 draw_fringe_bitmap_1 (w
, row
, 1, 1, OVERLAY_ARROW_BITMAP
);
643 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
644 function with input blocked. */
647 draw_row_fringe_bitmaps (w
, row
)
649 struct glyph_row
*row
;
651 xassert (interrupt_input_blocked
);
653 /* If row is completely invisible, because of vscrolling, we
654 don't have to draw anything. */
655 if (row
->visible_height
<= 0)
658 if (WINDOW_LEFT_FRINGE_WIDTH (w
) != 0)
659 draw_fringe_bitmap (w
, row
, 1);
661 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) != 0)
662 draw_fringe_bitmap (w
, row
, 0);
665 /* Draw the fringes of window W. Only fringes for rows marked for
666 update in redraw_fringe_bitmaps_p are drawn. */
669 draw_window_fringes (w
)
672 struct glyph_row
*row
;
673 int yb
= window_text_bottom_y (w
);
674 int nrows
= w
->current_matrix
->nrows
;
677 if (w
->pseudo_window_p
)
680 for (y
= 0, rn
= 0, row
= w
->current_matrix
->rows
;
681 y
< yb
&& rn
< nrows
;
682 y
+= row
->height
, ++row
, ++rn
)
684 if (!row
->redraw_fringe_bitmaps_p
)
686 draw_row_fringe_bitmaps (w
, row
);
687 row
->redraw_fringe_bitmaps_p
= 0;
692 /* Recalculate the bitmaps to show in the fringes of window W.
693 If FORCE_P is 0, only mark rows with modified bitmaps for update in
694 redraw_fringe_bitmaps_p; else mark all rows for update. */
697 update_window_fringes (w
, force_p
)
701 struct glyph_row
*row
, *cur
= 0;
702 int yb
= window_text_bottom_y (w
);
703 int rn
, nrows
= w
->current_matrix
->nrows
;
707 int boundary_pos
= 0, arrow_pos
= 0;
710 if (w
->pseudo_window_p
)
713 if (!MINI_WINDOW_P (w
)
714 && (ind
= XBUFFER (w
->buffer
)->indicate_buffer_boundaries
, !NILP (ind
)))
716 int do_eob
= 1, do_bob
= 1;
720 arrows
= XCDR (ind
), ind
= XCAR (ind
);
726 else if (EQ (ind
, Qright
))
729 if (EQ (arrows
, Qleft
))
731 else if (EQ (arrows
, Qright
))
735 y
< yb
&& rn
< nrows
;
736 y
+= row
->height
, ++rn
)
738 unsigned indicate_bob_p
, indicate_top_line_p
;
739 unsigned indicate_eob_p
, indicate_bottom_line_p
;
741 row
= w
->desired_matrix
->rows
+ rn
;
743 row
= w
->current_matrix
->rows
+ rn
;
745 indicate_bob_p
= row
->indicate_bob_p
;
746 indicate_top_line_p
= row
->indicate_top_line_p
;
747 indicate_eob_p
= row
->indicate_eob_p
;
748 indicate_bottom_line_p
= row
->indicate_bottom_line_p
;
750 row
->indicate_bob_p
= row
->indicate_top_line_p
= 0;
751 row
->indicate_eob_p
= row
->indicate_bottom_line_p
= 0;
754 && MATRIX_ROW_START_CHARPOS (row
) <= BUF_BEGV (XBUFFER (w
->buffer
)))
755 row
->indicate_bob_p
= do_bob
, do_bob
= 0;
756 else if (!NILP (arrows
)
757 && (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0) == rn
)
758 row
->indicate_top_line_p
= 1;
761 && MATRIX_ROW_END_CHARPOS (row
) >= BUF_ZV (XBUFFER (w
->buffer
)))
762 row
->indicate_eob_p
= do_eob
, do_eob
= 0;
763 else if (!NILP (arrows
)
764 && y
+ row
->height
>= yb
)
765 row
->indicate_bottom_line_p
= 1;
767 if (indicate_bob_p
!= row
->indicate_bob_p
768 || indicate_top_line_p
!= row
->indicate_top_line_p
769 || indicate_eob_p
!= row
->indicate_eob_p
770 || indicate_bottom_line_p
!= row
->indicate_bottom_line_p
)
771 row
->redraw_fringe_bitmaps_p
= 1;
775 if (EQ (XBUFFER (w
->buffer
)->indicate_empty_lines
, Qright
))
777 else if (EQ (XBUFFER (w
->buffer
)->indicate_empty_lines
, Qleft
))
781 y
< yb
&& rn
< nrows
;
782 y
+= row
->height
, rn
++)
784 enum fringe_bitmap_type left
, right
;
785 unsigned left_face_id
, right_face_id
;
787 row
= w
->desired_matrix
->rows
+ rn
;
788 cur
= w
->current_matrix
->rows
+ rn
;
792 left_face_id
= right_face_id
= DEFAULT_FACE_ID
;
794 /* Decide which bitmap to draw in the left fringe. */
795 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
796 left
= NO_FRINGE_BITMAP
;
797 else if (row
->left_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
799 left
= row
->left_user_fringe_bitmap
;
800 left_face_id
= row
->left_user_fringe_face_id
;
802 #if 0 /* this is now done via an overlay */
803 else if (row
->overlay_arrow_p
)
804 left
= OVERLAY_ARROW_BITMAP
;
806 else if (row
->indicate_bob_p
&& boundary_pos
<= 0)
807 left
= ((row
->indicate_eob_p
&& boundary_pos
< 0)
808 ? LEFT_BRACKET_BITMAP
: TOP_LEFT_ANGLE_BITMAP
);
809 else if (row
->indicate_eob_p
&& boundary_pos
< 0)
810 left
= BOTTOM_LEFT_ANGLE_BITMAP
;
811 else if (row
->truncated_on_left_p
)
812 left
= LEFT_TRUNCATION_BITMAP
;
813 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
814 left
= CONTINUATION_LINE_BITMAP
;
815 else if (row
->indicate_empty_line_p
&& empty_pos
<= 0)
816 left
= ZV_LINE_BITMAP
;
817 else if (row
->indicate_top_line_p
&& arrow_pos
<= 0)
818 left
= UP_ARROW_BITMAP
;
819 else if (row
->indicate_bottom_line_p
&& arrow_pos
< 0)
820 left
= DOWN_ARROW_BITMAP
;
822 left
= NO_FRINGE_BITMAP
;
824 /* Decide which bitmap to draw in the right fringe. */
825 if (WINDOW_RIGHT_FRINGE_WIDTH (w
) == 0)
826 right
= NO_FRINGE_BITMAP
;
827 else if (row
->right_user_fringe_bitmap
!= NO_FRINGE_BITMAP
)
829 right
= row
->right_user_fringe_bitmap
;
830 right_face_id
= row
->right_user_fringe_face_id
;
832 else if (row
->indicate_bob_p
&& boundary_pos
> 0)
833 right
= ((row
->indicate_eob_p
&& boundary_pos
>= 0)
834 ? RIGHT_BRACKET_BITMAP
: TOP_RIGHT_ANGLE_BITMAP
);
835 else if (row
->indicate_eob_p
&& boundary_pos
>= 0)
836 right
= BOTTOM_RIGHT_ANGLE_BITMAP
;
837 else if (row
->truncated_on_right_p
)
838 right
= RIGHT_TRUNCATION_BITMAP
;
839 else if (row
->continued_p
)
840 right
= CONTINUED_LINE_BITMAP
;
841 else if (row
->indicate_top_line_p
&& arrow_pos
> 0)
842 right
= UP_ARROW_BITMAP
;
843 else if (row
->indicate_bottom_line_p
&& arrow_pos
>= 0)
844 right
= DOWN_ARROW_BITMAP
;
845 else if (row
->indicate_empty_line_p
847 || (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0 && empty_pos
== 0)))
848 right
= ZV_LINE_BITMAP
;
850 right
= NO_FRINGE_BITMAP
;
854 || row
->visible_height
!= cur
->visible_height
855 || left
!= cur
->left_fringe_bitmap
856 || right
!= cur
->right_fringe_bitmap
857 || left_face_id
!= cur
->left_fringe_face_id
858 || right_face_id
!= cur
->right_fringe_face_id
859 || cur
->redraw_fringe_bitmaps_p
)
861 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
862 cur
->left_fringe_bitmap
= left
;
863 cur
->right_fringe_bitmap
= right
;
864 cur
->left_fringe_face_id
= left_face_id
;
865 cur
->right_fringe_face_id
= right_face_id
;
868 if (row
->overlay_arrow_p
!= cur
->overlay_arrow_p
)
870 redraw_p
= row
->redraw_fringe_bitmaps_p
= cur
->redraw_fringe_bitmaps_p
= 1;
871 cur
->overlay_arrow_p
= row
->overlay_arrow_p
;
874 row
->left_fringe_bitmap
= left
;
875 row
->right_fringe_bitmap
= right
;
876 row
->left_fringe_face_id
= left_face_id
;
877 row
->right_fringe_face_id
= right_face_id
;
884 /* Compute actual fringe widths for frame F.
886 If REDRAW is 1, redraw F if the fringe settings was actually
887 modified and F is visible.
889 Since the combined left and right fringe must occupy an integral
890 number of columns, we may need to add some pixels to each fringe.
891 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
892 but a negative width value is taken literally (after negating it).
894 We never make the fringes narrower than specified. It is planned
895 to make fringe bitmaps customizable and expandable, and at that
896 time, the user will typically specify the minimum number of pixels
897 needed for his bitmaps, so we shouldn't select anything less than
902 compute_fringe_widths (f
, redraw
)
906 int o_left
= FRAME_LEFT_FRINGE_WIDTH (f
);
907 int o_right
= FRAME_RIGHT_FRINGE_WIDTH (f
);
908 int o_cols
= FRAME_FRINGE_COLS (f
);
910 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
911 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
912 int left_fringe_width
, right_fringe_width
;
914 if (!NILP (left_fringe
))
915 left_fringe
= Fcdr (left_fringe
);
916 if (!NILP (right_fringe
))
917 right_fringe
= Fcdr (right_fringe
);
919 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
921 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
922 XINT (right_fringe
));
924 if (left_fringe_width
|| right_fringe_width
)
926 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
927 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
928 int conf_wid
= left_wid
+ right_wid
;
929 int font_wid
= FRAME_COLUMN_WIDTH (f
);
930 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
931 int real_wid
= cols
* font_wid
;
932 if (left_wid
&& right_wid
)
934 if (left_fringe_width
< 0)
936 /* Left fringe width is fixed, adjust right fringe if necessary */
937 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
;
938 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
- left_wid
;
940 else if (right_fringe_width
< 0)
942 /* Right fringe width is fixed, adjust left fringe if necessary */
943 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
- right_wid
;
944 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
;
948 /* Adjust both fringes with an equal amount.
949 Note that we are doing integer arithmetic here, so don't
950 lose a pixel if the total width is an odd number. */
951 int fill
= real_wid
- conf_wid
;
952 FRAME_LEFT_FRINGE_WIDTH (f
) = left_wid
+ fill
/2;
953 FRAME_RIGHT_FRINGE_WIDTH (f
) = right_wid
+ fill
- fill
/2;
956 else if (left_fringe_width
)
958 FRAME_LEFT_FRINGE_WIDTH (f
) = real_wid
;
959 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
963 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
964 FRAME_RIGHT_FRINGE_WIDTH (f
) = real_wid
;
966 FRAME_FRINGE_COLS (f
) = cols
;
970 FRAME_LEFT_FRINGE_WIDTH (f
) = 0;
971 FRAME_RIGHT_FRINGE_WIDTH (f
) = 0;
972 FRAME_FRINGE_COLS (f
) = 0;
975 if (redraw
&& FRAME_VISIBLE_P (f
))
976 if (o_left
!= FRAME_LEFT_FRINGE_WIDTH (f
) ||
977 o_right
!= FRAME_RIGHT_FRINGE_WIDTH (f
) ||
978 o_cols
!= FRAME_FRINGE_COLS (f
))
982 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap
, Sdestroy_fringe_bitmap
,
984 doc
: /* Destroy fringe bitmap WHICH.
985 If WHICH overrides a standard fringe bitmap, the original bitmap is restored. */)
990 struct fringe_bitmap
**fbp
;
992 CHECK_NUMBER (which
);
993 if (n
= XINT (which
), n
>= max_used_fringe_bitmap
)
996 fringe_faces
[n
] = FRINGE_FACE_ID
;
998 fbp
= &fringe_bitmaps
[n
];
999 if (*fbp
&& (*fbp
)->dynamic
)
1001 if (rif
->destroy_fringe_bitmap
)
1002 rif
->destroy_fringe_bitmap (n
);
1007 while (max_used_fringe_bitmap
> MAX_STANDARD_FRINGE_BITMAPS
1008 && fringe_bitmaps
[max_used_fringe_bitmap
- 1] == NULL
)
1009 max_used_fringe_bitmap
--;
1015 /* Initialize bitmap bit.
1017 On X, we bit-swap the built-in bitmaps and reduce bitmap
1018 from short to char array if width is <= 8 bits.
1020 On MAC with big-endian CPU, we need to byte-swap each short.
1022 On W32 and MAC (little endian), there's no need to do this.
1026 init_fringe_bitmap (which
, fb
, once_p
)
1027 enum fringe_bitmap_type which
;
1028 struct fringe_bitmap
*fb
;
1031 if (once_p
|| fb
->dynamic
)
1033 #if defined (HAVE_X_WINDOWS)
1034 static unsigned char swap_nibble
[16]
1035 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1036 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1037 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1038 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
1039 unsigned short *bits
= fb
->bits
;
1044 unsigned char *cbits
= (unsigned char *)fb
->bits
;
1045 for (j
= 0; j
< fb
->height
; j
++)
1047 unsigned short b
= *bits
++;
1049 c
= (unsigned char)((swap_nibble
[b
& 0xf] << 4)
1050 | (swap_nibble
[(b
>>4) & 0xf]));
1051 *cbits
++ = (c
>> (8 - fb
->width
));
1056 for (j
= 0; j
< fb
->height
; j
++)
1058 unsigned short b
= *bits
;
1059 b
= (unsigned short)((swap_nibble
[b
& 0xf] << 12)
1060 | (swap_nibble
[(b
>>4) & 0xf] << 8)
1061 | (swap_nibble
[(b
>>8) & 0xf] << 4)
1062 | (swap_nibble
[(b
>>12) & 0xf]));
1063 *bits
++ = (b
>> (16 - fb
->width
));
1066 #endif /* HAVE_X_WINDOWS */
1068 #if defined (MAC_OS) && defined (WORDS_BIG_ENDIAN)
1069 unsigned short *bits
= fb
->bits
;
1071 for (j
= 0; j
< fb
->height
; j
++)
1073 unsigned short b
= *bits
;
1074 *bits
++ = ((b
>> 8) & 0xff) | ((b
& 0xff) << 8);
1076 #endif /* MAC_OS && WORDS_BIG_ENDIAN */
1081 Fdestroy_fringe_bitmap (make_number (which
));
1083 if (rif
->define_fringe_bitmap
)
1084 rif
->define_fringe_bitmap (which
, fb
->bits
, fb
->height
, fb
->width
);
1086 fringe_bitmaps
[which
] = fb
;
1087 if (which
>= max_used_fringe_bitmap
)
1088 max_used_fringe_bitmap
= which
+ 1;
1093 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap
, Sdefine_fringe_bitmap
,
1095 doc
: /* Define a fringe bitmap from BITS of height HEIGHT and width WIDTH.
1096 BITS is either a string or a vector of integers.
1097 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1098 WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1099 Optional forth arg ALIGN may be one of `top', `center', or `bottom',
1100 indicating the positioning of the bitmap relative to the rows where it
1101 is used; the default is to center the bitmap. Fourth arg may also be a
1102 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1104 Optional fifth argument WHICH is bitmap number to redefine.
1105 Return new bitmap number, or nil of no more free bitmap slots. */)
1106 (bits
, height
, width
, align
, which
)
1107 Lisp_Object bits
, height
, width
, align
, which
;
1112 struct fringe_bitmap fb
, *xfb
;
1113 int fill1
= 0, fill2
= 0;
1115 if (!STRINGP (bits
) && !VECTORP (bits
))
1116 bits
= wrong_type_argument (Qstringp
, bits
);
1118 len
= Flength (bits
);
1121 h
= fb
.height
= XINT (len
);
1124 CHECK_NUMBER (height
);
1125 fb
.height
= min (XINT (height
), 255);
1126 if (fb
.height
> XINT (len
))
1129 fill1
= (fb
.height
- h
) / 2;
1130 fill2
= fb
.height
- h
- fill1
;
1138 CHECK_NUMBER (width
);
1139 fb
.width
= min (XINT (width
), 255);
1143 fb
.align
= ALIGN_BITMAP_CENTER
;
1147 Lisp_Object period
= XCDR (align
);
1150 period
= XCAR (period
);
1153 fb
.period
= fb
.height
;
1157 align
= XCAR (align
);
1159 if (EQ (align
, Qtop
))
1160 fb
.align
= ALIGN_BITMAP_TOP
;
1161 else if (EQ (align
, Qbottom
))
1162 fb
.align
= ALIGN_BITMAP_BOTTOM
;
1163 else if (!NILP (align
) && !EQ (align
, Qcenter
))
1164 error ("Bad align argument");
1168 if (max_used_fringe_bitmap
< MAX_FRINGE_BITMAPS
)
1169 n
= max_used_fringe_bitmap
++;
1172 for (n
= MAX_STANDARD_FRINGE_BITMAPS
;
1173 n
< MAX_FRINGE_BITMAPS
;
1175 if (fringe_bitmaps
[n
] == NULL
)
1177 if (n
== MAX_FRINGE_BITMAPS
)
1180 which
= make_number (n
);
1184 CHECK_NUMBER (which
);
1186 if (n
<= NO_FRINGE_BITMAP
|| n
>= MAX_FRINGE_BITMAPS
)
1187 error ("Invalid fringe bitmap number");
1192 xfb
= (struct fringe_bitmap
*) xmalloc (sizeof fb
1193 + fb
.height
* BYTES_PER_BITMAP_ROW
);
1194 fb
.bits
= b
= (unsigned short *) (xfb
+ 1);
1195 bzero (b
, fb
.height
);
1198 while (j
< fb
.height
)
1200 for (i
= 0; i
< fill1
&& j
< fb
.height
; i
++)
1202 for (i
= 0; i
< h
&& j
< fb
.height
; i
++)
1204 Lisp_Object elt
= Faref (bits
, make_number (i
));
1205 b
[j
++] = NUMBERP (elt
) ? XINT (elt
) : 0;
1207 for (i
= 0; i
< fill2
&& j
< fb
.height
; i
++)
1213 init_fringe_bitmap (n
, xfb
, 0);
1218 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face
, Sset_fringe_bitmap_face
,
1220 doc
: /* Set face for fringe bitmap FRINGE-ID to FACE.
1221 If FACE is nil, reset face to default fringe face. */)
1223 Lisp_Object fringe_id
, face
;
1227 CHECK_NUMBER (fringe_id
);
1228 if (!valid_fringe_bitmap_id_p (XINT (fringe_id
)))
1229 error ("Invalid fringe id");
1233 face_id
= lookup_named_face (SELECTED_FRAME (), face
, 'A');
1235 error ("No such face");
1238 face_id
= FRINGE_FACE_ID
;
1240 fringe_faces
[XINT (fringe_id
)] = face_id
;
1245 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos
, Sfringe_bitmaps_at_pos
,
1247 doc
: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1248 If WINDOW is nil, use selected window. If POS is nil, use value of point
1249 in that window. Return value is a cons (LEFT . RIGHT) where LEFT and RIGHT
1250 are the fringe bitmap numbers for the bitmaps in the left and right fringe,
1251 resp. Return nil if POS is not visible in WINDOW. */)
1253 Lisp_Object pos
, window
;
1256 struct buffer
*old_buffer
= NULL
;
1257 struct glyph_row
*row
;
1261 window
= selected_window
;
1262 CHECK_WINDOW (window
);
1263 w
= XWINDOW (window
);
1267 CHECK_NUMBER_COERCE_MARKER (pos
);
1268 textpos
= XINT (pos
);
1270 else if (w
== XWINDOW (selected_window
))
1273 textpos
= XMARKER (w
->pointm
)->charpos
;
1275 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
1276 row
= row_containing_pos (w
, textpos
, row
, NULL
, 0);
1278 return Fcons (make_number (row
->left_fringe_bitmap
),
1279 make_number (row
->right_fringe_bitmap
));
1285 /***********************************************************************
1287 ***********************************************************************/
1293 defsubr (&Sdestroy_fringe_bitmap
);
1294 defsubr (&Sdefine_fringe_bitmap
);
1295 defsubr (&Sfringe_bitmaps_at_pos
);
1296 defsubr (&Sset_fringe_bitmap_face
);
1298 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe
,
1299 doc
: /* *Non-nil means that newline may flow into the right fringe.
1300 This means that display lines which are exactly as wide as the window
1301 (not counting the final newline) will only occupy one screen line, by
1302 showing (or hiding) the final newline in the right fringe; when point
1303 is at the final newline, the cursor is shown in the right fringe.
1304 If nil, also continue lines which are exactly as wide as the window. */);
1305 Voverflow_newline_into_fringe
= Qt
;
1309 /* Initialize this module when Emacs starts. */
1314 enum fringe_bitmap_type bt
;
1316 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1317 init_fringe_bitmap(bt
, &standard_bitmaps
[bt
], 1);
1325 bzero (fringe_bitmaps
, sizeof fringe_bitmaps
);
1326 for (i
= 0; i
< MAX_FRINGE_BITMAPS
; i
++)
1327 fringe_faces
[i
] = FRINGE_FACE_ID
;
1335 enum fringe_bitmap_type bt
;
1337 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< MAX_STANDARD_FRINGE_BITMAPS
; bt
++)
1339 struct fringe_bitmap
*fb
= &standard_bitmaps
[bt
];
1340 rif
->define_fringe_bitmap (bt
, fb
->bits
, fb
->height
, fb
->width
);
1345 w32_reset_fringes ()
1347 /* Destroy row bitmaps. */
1350 for (bt
= NO_FRINGE_BITMAP
+ 1; bt
< max_used_fringe_bitmap
; bt
++)
1351 rif
->destroy_fringe_bitmap (bt
);
1354 #endif /* HAVE_NTGUI */
1356 #endif /* HAVE_WINDOW_SYSTEM */
1358 /* arch-tag: 04596920-43eb-473d-b319-82712338162d
1359 (do not change this comment) */