(define-ibuffer-filter filename): If `dired-directory' is a list then
[emacs.git] / src / fringe.c
blob334cc4515fdd640513cca5ece98508f9ae5097fd
1 /* Fringe handling (split from xdisp.c).
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997,
3 1998, 1999, 2000, 2000, 2001, 2002, 2003, 2004,
4 2005 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 #include <config.h>
24 #include <stdio.h>
26 #include "lisp.h"
27 #include "frame.h"
28 #include "window.h"
29 #include "dispextern.h"
30 #include "buffer.h"
31 #include "blockinput.h"
33 #ifdef HAVE_WINDOW_SYSTEM
35 extern Lisp_Object Qfringe;
36 extern Lisp_Object Qtop, Qbottom, Qcenter;
37 extern Lisp_Object Qup, Qdown, Qleft, Qright;
39 /* Non-nil means that newline may flow into the right fringe. */
41 Lisp_Object Voverflow_newline_into_fringe;
43 /* List of known fringe bitmap symbols.
45 The fringe bitmap number is stored in the `fringe' property on
46 those symbols. Names for the built-in bitmaps are installed by
47 loading fringe.el.
50 Lisp_Object Vfringe_bitmaps;
52 enum fringe_bitmap_type
54 NO_FRINGE_BITMAP = 0,
55 UNDEF_FRINGE_BITMAP,
56 LEFT_TRUNCATION_BITMAP,
57 RIGHT_TRUNCATION_BITMAP,
58 UP_ARROW_BITMAP,
59 DOWN_ARROW_BITMAP,
60 CONTINUED_LINE_BITMAP,
61 CONTINUATION_LINE_BITMAP,
62 OVERLAY_ARROW_BITMAP,
63 TOP_LEFT_ANGLE_BITMAP,
64 TOP_RIGHT_ANGLE_BITMAP,
65 BOTTOM_LEFT_ANGLE_BITMAP,
66 BOTTOM_RIGHT_ANGLE_BITMAP,
67 LEFT_BRACKET_BITMAP,
68 RIGHT_BRACKET_BITMAP,
69 FILLED_BOX_CURSOR_BITMAP,
70 HOLLOW_BOX_CURSOR_BITMAP,
71 HOLLOW_SQUARE_BITMAP,
72 BAR_CURSOR_BITMAP,
73 HBAR_CURSOR_BITMAP,
74 ZV_LINE_BITMAP,
75 MAX_STANDARD_FRINGE_BITMAPS
78 enum fringe_bitmap_align
80 ALIGN_BITMAP_CENTER = 0,
81 ALIGN_BITMAP_TOP,
82 ALIGN_BITMAP_BOTTOM
85 struct fringe_bitmap
87 unsigned short *bits;
88 unsigned height : 8;
89 unsigned width : 8;
90 unsigned period : 8;
91 unsigned align : 2;
92 unsigned dynamic : 1;
96 /***********************************************************************
97 Fringe bitmaps
98 ***********************************************************************/
100 /* Undefined bitmap. A question mark. */
102 ..xxxx..
103 .xxxxxx.
104 xx....xx
105 xx....xx
106 ....xx..
107 ...xx...
108 ...xx...
109 ........
110 ...xx...
111 ...xx...
113 static unsigned short unknown_bits[] = {
114 0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
116 /* An arrow like this: `<-'. */
118 ...xx...
119 ..xx....
120 .xx.....
121 xxxxxx..
122 xxxxxx..
123 .xx.....
124 ..xx....
125 ...xx...
127 static unsigned short left_arrow_bits[] = {
128 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
131 /* Right truncation arrow bitmap `->'. */
133 ...xx...
134 ....xx..
135 .....xx.
136 ..xxxxxx
137 ..xxxxxx
138 .....xx.
139 ....xx..
140 ...xx...
142 static unsigned short right_arrow_bits[] = {
143 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
146 /* Up arrow bitmap. */
148 ...xx...
149 ..xxxx..
150 .xxxxxx.
151 xxxxxxxx
152 ...xx...
153 ...xx...
154 ...xx...
155 ...xx...
157 static unsigned short up_arrow_bits[] = {
158 0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
161 /* Down arrow bitmap. */
163 ...xx...
164 ...xx...
165 ...xx...
166 ...xx...
167 xxxxxxxx
168 .xxxxxx.
169 ..xxxx..
170 ...xx...
172 static unsigned short down_arrow_bits[] = {
173 0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
175 /* Marker for continued lines. */
177 ..xxxx..
178 ..xxxxx.
179 ......xx
180 ..x..xxx
181 ..xxxxxx
182 ..xxxxx.
183 ..xxxx..
184 ..xxxxx.
186 static unsigned short continued_bits[] = {
187 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
189 /* Marker for continuation lines. */
191 ..xxxx..
192 .xxxxx..
193 xx......
194 xxx..x..
195 xxxxxx..
196 .xxxxx..
197 ..xxxx..
198 .xxxxx..
200 static unsigned short continuation_bits[] = {
201 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
203 /* Overlay arrow bitmap. A triangular arrow. */
205 xx......
206 xxxx....
207 xxxxx...
208 xxxxxx..
209 xxxxxx..
210 xxxxx...
211 xxxx....
212 xx......
214 static unsigned short ov_bits[] = {
215 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
217 #if 0
218 /* Reverse Overlay arrow bitmap. A triangular arrow. */
220 ......xx
221 ....xxxx
222 ...xxxxx
223 ..xxxxxx
224 ..xxxxxx
225 ...xxxxx
226 ....xxxx
227 ......xx
229 static unsigned short rev_ov_bits[] = {
230 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
231 #endif
233 /* First line bitmap. An top-left angle. */
235 xxxxxx..
236 xxxxxx..
237 xx......
238 xx......
239 xx......
240 xx......
241 xx......
242 ........
244 static unsigned short top_left_angle_bits[] = {
245 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00};
247 /* First line bitmap. An right-up angle. */
249 ..xxxxxx
250 ..xxxxxx
251 ......xx
252 ......xx
253 ......xx
254 ......xx
255 ......xx
256 ........
258 static unsigned short top_right_angle_bits[] = {
259 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
261 /* Last line bitmap. An left-down angle. */
263 ........
264 xx......
265 xx......
266 xx......
267 xx......
268 xx......
269 xxxxxx..
270 xxxxxx..
272 static unsigned short bottom_left_angle_bits[] = {
273 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
275 /* Last line bitmap. An right-down angle. */
277 ........
278 ......xx
279 ......xx
280 ......xx
281 ......xx
282 ......xx
283 ..xxxxxx
284 ..xxxxxx
286 static unsigned short bottom_right_angle_bits[] = {
287 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
289 /* First/last line bitmap. An left bracket. */
291 xxxxxx..
292 xxxxxx..
293 xx......
294 xx......
295 xx......
296 xx......
297 xx......
298 xx......
299 xxxxxx..
300 xxxxxx..
302 static unsigned short left_bracket_bits[] = {
303 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
305 /* First/last line bitmap. An right bracket. */
307 ..xxxxxx
308 ..xxxxxx
309 ......xx
310 ......xx
311 ......xx
312 ......xx
313 ......xx
314 ......xx
315 ..xxxxxx
316 ..xxxxxx
318 static unsigned short right_bracket_bits[] = {
319 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
321 /* Filled box cursor bitmap. A filled box; max 13 pixels high. */
323 xxxxxxx.
324 xxxxxxx.
325 xxxxxxx.
326 xxxxxxx.
327 xxxxxxx.
328 xxxxxxx.
329 xxxxxxx.
330 xxxxxxx.
331 xxxxxxx.
332 xxxxxxx.
333 xxxxxxx.
334 xxxxxxx.
335 xxxxxxx.
337 static unsigned short filled_box_cursor_bits[] = {
338 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
340 /* Hollow box cursor bitmap. A hollow box; max 13 pixels high. */
342 xxxxxxx.
343 x.....x.
344 x.....x.
345 x.....x.
346 x.....x.
347 x.....x.
348 x.....x.
349 x.....x.
350 x.....x.
351 x.....x.
352 x.....x.
353 x.....x.
354 xxxxxxx.
356 static unsigned short hollow_box_cursor_bits[] = {
357 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe};
359 /* Bar cursor bitmap. A vertical bar; max 13 pixels high. */
361 xx......
362 xx......
363 xx......
364 xx......
365 xx......
366 xx......
367 xx......
368 xx......
369 xx......
370 xx......
371 xx......
372 xx......
373 xx......
375 static unsigned short bar_cursor_bits[] = {
376 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
378 /* HBar cursor bitmap. A horisontal bar; 2 pixels high. */
380 xxxxxxx.
381 xxxxxxx.
383 static unsigned short hbar_cursor_bits[] = {
384 0xfe, 0xfe};
387 /* Bitmap drawn to indicate lines not displaying text if
388 `indicate-empty-lines' is non-nil. */
390 ........
391 ..xxxx..
392 ........
393 ........
394 ..xxxx..
395 ........
397 static unsigned short zv_bits[] = {
398 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
399 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
400 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
401 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
402 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
403 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
404 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
405 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
407 /* Hollow square bitmap. */
409 .xxxxxx.
410 .x....x.
411 .x....x.
412 .x....x.
413 .x....x.
414 .xxxxxx.
416 static unsigned short hollow_square_bits[] = {
417 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
420 #define BYTES_PER_BITMAP_ROW (sizeof (unsigned short))
421 #define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
422 #define FRBITS(bits) bits, STANDARD_BITMAP_HEIGHT (bits)
424 struct fringe_bitmap standard_bitmaps[MAX_STANDARD_FRINGE_BITMAPS] =
426 { NULL, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */
427 { FRBITS (unknown_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
428 { FRBITS (left_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
429 { FRBITS (right_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
430 { FRBITS (up_arrow_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
431 { FRBITS (down_arrow_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
432 { FRBITS (continued_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
433 { FRBITS (continuation_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
434 { FRBITS (ov_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
435 { FRBITS (top_left_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
436 { FRBITS (top_right_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
437 { FRBITS (bottom_left_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
438 { FRBITS (bottom_right_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
439 { FRBITS (left_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
440 { FRBITS (right_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
441 { FRBITS (filled_box_cursor_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
442 { FRBITS (hollow_box_cursor_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
443 { FRBITS (hollow_square_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
444 { FRBITS (bar_cursor_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
445 { FRBITS (hbar_cursor_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
446 { FRBITS (zv_bits), 8, 3, ALIGN_BITMAP_TOP, 0 },
449 static struct fringe_bitmap **fringe_bitmaps;
450 static Lisp_Object *fringe_faces;
451 static int max_fringe_bitmaps;
453 static int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS;
456 /* Lookup bitmap number for symbol BITMAP.
457 Return 0 if not a bitmap. */
460 lookup_fringe_bitmap (bitmap)
461 Lisp_Object bitmap;
463 int bn;
465 bitmap = Fget (bitmap, Qfringe);
466 if (!INTEGERP (bitmap))
467 return 0;
469 bn = XINT (bitmap);
470 if (bn > NO_FRINGE_BITMAP
471 && bn < max_used_fringe_bitmap
472 && (bn < MAX_STANDARD_FRINGE_BITMAPS
473 || fringe_bitmaps[bn] != NULL))
474 return bn;
476 return 0;
479 /* Get fringe bitmap name for bitmap number BN.
481 Found by traversing Vfringe_bitmaps comparing BN to the
482 fringe property for each symbol.
484 Return BN if not found in Vfringe_bitmaps. */
486 static Lisp_Object
487 get_fringe_bitmap_name (bn)
488 int bn;
490 Lisp_Object bitmaps;
491 Lisp_Object num;
493 /* Zero means no bitmap -- return nil. */
494 if (bn <= 0)
495 return Qnil;
497 bitmaps = Vfringe_bitmaps;
498 num = make_number (bn);
500 while (CONSP (bitmaps))
502 Lisp_Object bitmap = XCAR (bitmaps);
503 if (EQ (num, Fget (bitmap, Qfringe)))
504 return bitmap;
505 bitmaps = XCDR (bitmaps);
508 return num;
512 /* Draw the bitmap WHICH in one of the left or right fringes of
513 window W. ROW is the glyph row for which to display the bitmap; it
514 determines the vertical position at which the bitmap has to be
515 drawn.
516 LEFT_P is 1 for left fringe, 0 for right fringe.
519 void
520 draw_fringe_bitmap_1 (w, row, left_p, overlay, which)
521 struct window *w;
522 struct glyph_row *row;
523 int left_p, overlay;
524 enum fringe_bitmap_type which;
526 struct frame *f = XFRAME (WINDOW_FRAME (w));
527 struct draw_fringe_bitmap_params p;
528 struct fringe_bitmap *fb;
529 int period;
530 int face_id = DEFAULT_FACE_ID;
532 p.cursor_p = 0;
533 p.overlay_p = (overlay & 1) == 1;
534 p.cursor_p = (overlay & 2) == 2;
536 if (which != NO_FRINGE_BITMAP)
539 else if (left_p)
541 which = row->left_fringe_bitmap;
542 face_id = row->left_fringe_face_id;
544 else
546 which = row->right_fringe_bitmap;
547 face_id = row->right_fringe_face_id;
550 if (face_id == DEFAULT_FACE_ID)
552 Lisp_Object face;
554 if ((face = fringe_faces[which], NILP (face))
555 || (face_id = lookup_derived_face (f, face, 'A', FRINGE_FACE_ID, 0),
556 face_id < 0))
557 face_id = FRINGE_FACE_ID;
560 fb = fringe_bitmaps[which];
561 if (fb == NULL)
562 fb = &standard_bitmaps[which < MAX_STANDARD_FRINGE_BITMAPS
563 ? which : UNDEF_FRINGE_BITMAP];
565 period = fb->period;
567 /* Convert row to frame coordinates. */
568 p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
570 p.which = which;
571 p.bits = fb->bits;
572 p.wd = fb->width;
574 p.h = fb->height;
575 p.dh = (period > 0 ? (p.y % period) : 0);
576 p.h -= p.dh;
577 /* Clip bitmap if too high. */
578 if (p.h > row->height)
579 p.h = row->height;
581 p.face = FACE_FROM_ID (f, face_id);
583 if (p.face == NULL)
585 /* This could happen after clearing face cache.
586 But it shouldn't happen anymore. ++kfs */
587 return;
590 PREPARE_FACE_FOR_DISPLAY (f, p.face);
592 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
593 the fringe. */
594 p.bx = -1;
595 if (left_p)
597 int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
598 int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
599 ? LEFT_MARGIN_AREA
600 : TEXT_AREA));
601 if (p.wd > wd)
602 p.wd = wd;
603 p.x = x - p.wd - (wd - p.wd) / 2;
605 if (p.wd < wd || row->height > p.h)
607 /* If W has a vertical border to its left, don't draw over it. */
608 wd -= ((!WINDOW_LEFTMOST_P (w)
609 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
610 ? 1 : 0);
611 p.bx = x - wd;
612 p.nx = wd;
615 else
617 int x = window_box_right (w,
618 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
619 ? RIGHT_MARGIN_AREA
620 : TEXT_AREA));
621 int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
622 if (p.wd > wd)
623 p.wd = wd;
624 p.x = x + (wd - p.wd) / 2;
625 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
626 the fringe. */
627 if (p.wd < wd || row->height > p.h)
629 p.bx = x;
630 p.nx = wd;
634 if (p.bx >= 0)
636 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
638 p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
639 p.ny = row->visible_height;
642 /* Adjust y to the offset in the row to start drawing the bitmap. */
643 switch (fb->align)
645 case ALIGN_BITMAP_CENTER:
646 p.y += (row->height - p.h) / 2;
647 break;
648 case ALIGN_BITMAP_BOTTOM:
649 p.h = fb->height;
650 p.y += (row->visible_height - p.h);
651 break;
652 case ALIGN_BITMAP_TOP:
653 break;
656 rif->draw_fringe_bitmap (w, row, &p);
659 void
660 draw_fringe_bitmap (w, row, left_p)
661 struct window *w;
662 struct glyph_row *row;
663 int left_p;
665 int overlay = 0;
667 if (!left_p && row->cursor_in_fringe_p)
669 int cursor = NO_FRINGE_BITMAP;
671 switch (w->phys_cursor_type)
673 case HOLLOW_BOX_CURSOR:
674 if (row->visible_height >= STANDARD_BITMAP_HEIGHT (hollow_box_cursor_bits))
675 cursor = HOLLOW_BOX_CURSOR_BITMAP;
676 else
677 cursor = HOLLOW_SQUARE_BITMAP;
678 break;
679 case FILLED_BOX_CURSOR:
680 cursor = FILLED_BOX_CURSOR_BITMAP;
681 break;
682 case BAR_CURSOR:
683 cursor = BAR_CURSOR_BITMAP;
684 break;
685 case HBAR_CURSOR:
686 cursor = HBAR_CURSOR_BITMAP;
687 break;
688 case NO_CURSOR:
689 default:
690 w->phys_cursor_on_p = 0;
691 row->cursor_in_fringe_p = 0;
692 break;
694 if (cursor != NO_FRINGE_BITMAP)
696 draw_fringe_bitmap_1 (w, row, 0, 2, cursor);
697 overlay = cursor == FILLED_BOX_CURSOR_BITMAP ? 3 : 1;
701 draw_fringe_bitmap_1 (w, row, left_p, overlay, NO_FRINGE_BITMAP);
703 if (left_p && row->overlay_arrow_bitmap != NO_FRINGE_BITMAP)
704 draw_fringe_bitmap_1 (w, row, 1, 1,
705 (row->overlay_arrow_bitmap < 0
706 ? OVERLAY_ARROW_BITMAP
707 : row->overlay_arrow_bitmap));
711 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
712 function with input blocked. */
714 void
715 draw_row_fringe_bitmaps (w, row)
716 struct window *w;
717 struct glyph_row *row;
719 xassert (interrupt_input_blocked);
721 /* If row is completely invisible, because of vscrolling, we
722 don't have to draw anything. */
723 if (row->visible_height <= 0)
724 return;
726 if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
727 draw_fringe_bitmap (w, row, 1);
729 if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
730 draw_fringe_bitmap (w, row, 0);
733 /* Draw the fringes of window W. Only fringes for rows marked for
734 update in redraw_fringe_bitmaps_p are drawn.
736 Return >0 if left or right fringe was redrawn in any way.
738 If NO_FRINGE is non-zero, also return >0 if either fringe has zero width.
740 A return value >0 indicates that the vertical line between windows
741 needs update (as it may be drawn in the fringe).
745 draw_window_fringes (w, no_fringe)
746 struct window *w;
747 int no_fringe;
749 struct glyph_row *row;
750 int yb = window_text_bottom_y (w);
751 int nrows = w->current_matrix->nrows;
752 int y = 0, rn;
753 int updated = 0;
755 if (w->pseudo_window_p)
756 return 0;
758 /* Must draw line if no fringe */
759 if (no_fringe
760 && (WINDOW_LEFT_FRINGE_WIDTH (w) == 0
761 || WINDOW_RIGHT_FRINGE_WIDTH (w) == 0))
762 updated++;
764 for (y = 0, rn = 0, row = w->current_matrix->rows;
765 y < yb && rn < nrows;
766 y += row->height, ++row, ++rn)
768 if (!row->redraw_fringe_bitmaps_p)
769 continue;
770 draw_row_fringe_bitmaps (w, row);
771 row->redraw_fringe_bitmaps_p = 0;
772 updated++;
775 return updated;
779 /* Recalculate the bitmaps to show in the fringes of window W.
780 Only mark rows with modified bitmaps for update in redraw_fringe_bitmaps_p.
782 If KEEP_CURRENT_P is 0, update current_matrix too. */
785 update_window_fringes (w, keep_current_p)
786 struct window *w;
787 int keep_current_p;
789 struct glyph_row *row, *cur = 0;
790 int yb = window_text_bottom_y (w);
791 int rn, nrows = w->current_matrix->nrows;
792 int y;
793 int redraw_p = 0;
794 Lisp_Object boundary_top = Qnil, boundary_bot = Qnil;
795 Lisp_Object arrow_top = Qnil, arrow_bot = Qnil;
796 Lisp_Object empty_pos;
797 Lisp_Object ind = Qnil;
799 if (w->pseudo_window_p)
800 return 0;
802 if (!MINI_WINDOW_P (w)
803 && (ind = XBUFFER (w->buffer)->indicate_buffer_boundaries, !NILP (ind)))
805 if (EQ (ind, Qleft) || EQ (ind, Qright))
806 boundary_top = boundary_bot = arrow_top = arrow_bot = ind;
807 else if (CONSP (ind) && CONSP (XCAR (ind)))
809 Lisp_Object pos;
810 if (pos = Fassq (Qt, ind), !NILP (pos))
811 boundary_top = boundary_bot = arrow_top = arrow_bot = XCDR (pos);
812 if (pos = Fassq (Qtop, ind), !NILP (pos))
813 boundary_top = XCDR (pos);
814 if (pos = Fassq (Qbottom, ind), !NILP (pos))
815 boundary_bot = XCDR (pos);
816 if (pos = Fassq (Qup, ind), !NILP (pos))
817 arrow_top = XCDR (pos);
818 if (pos = Fassq (Qdown, ind), !NILP (pos))
819 arrow_bot = XCDR (pos);
821 else
822 /* Anything else means boundary on left and no arrows. */
823 boundary_top = boundary_bot = Qleft;
826 if (!NILP (ind))
828 int done_top = 0, done_bot = 0;
830 for (y = 0, rn = 0;
831 y < yb && rn < nrows;
832 y += row->height, ++rn)
834 unsigned indicate_bob_p, indicate_top_line_p;
835 unsigned indicate_eob_p, indicate_bottom_line_p;
837 row = w->desired_matrix->rows + rn;
838 if (!row->enabled_p)
839 row = w->current_matrix->rows + rn;
841 indicate_bob_p = row->indicate_bob_p;
842 indicate_top_line_p = row->indicate_top_line_p;
843 indicate_eob_p = row->indicate_eob_p;
844 indicate_bottom_line_p = row->indicate_bottom_line_p;
846 row->indicate_bob_p = row->indicate_top_line_p = 0;
847 row->indicate_eob_p = row->indicate_bottom_line_p = 0;
849 if (!row->mode_line_p)
851 if (!done_top)
853 if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer))
854 && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
855 row->indicate_bob_p = !NILP (boundary_top);
856 else
857 row->indicate_top_line_p = !NILP (arrow_top);
858 done_top = 1;
861 if (!done_bot)
863 if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer))
864 && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row))
865 row->indicate_eob_p = !NILP (boundary_bot), done_bot = 1;
866 else if (y + row->height >= yb)
867 row->indicate_bottom_line_p = !NILP (arrow_bot), done_bot = 1;
871 if (indicate_bob_p != row->indicate_bob_p
872 || indicate_top_line_p != row->indicate_top_line_p
873 || indicate_eob_p != row->indicate_eob_p
874 || indicate_bottom_line_p != row->indicate_bottom_line_p)
875 row->redraw_fringe_bitmaps_p = 1;
879 empty_pos = XBUFFER (w->buffer)->indicate_empty_lines;
880 if (!NILP (empty_pos) && !EQ (empty_pos, Qright))
881 empty_pos = WINDOW_LEFT_FRINGE_WIDTH (w) == 0 ? Qright : Qleft;
883 for (y = 0, rn = 0;
884 y < yb && rn < nrows;
885 y += row->height, rn++)
887 enum fringe_bitmap_type left, right;
888 unsigned left_face_id, right_face_id;
890 row = w->desired_matrix->rows + rn;
891 cur = w->current_matrix->rows + rn;
892 if (!row->enabled_p)
893 row = cur;
895 left_face_id = right_face_id = DEFAULT_FACE_ID;
897 /* Decide which bitmap to draw in the left fringe. */
898 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
899 left = NO_FRINGE_BITMAP;
900 else if (row->left_user_fringe_bitmap != NO_FRINGE_BITMAP)
902 left = row->left_user_fringe_bitmap;
903 left_face_id = row->left_user_fringe_face_id;
905 else if (row->truncated_on_left_p)
906 left = LEFT_TRUNCATION_BITMAP;
907 else if (row->indicate_bob_p && EQ (boundary_top, Qleft))
908 left = ((row->indicate_eob_p && EQ (boundary_bot, Qleft))
909 ? (row->ends_at_zv_p
910 ? TOP_RIGHT_ANGLE_BITMAP : LEFT_BRACKET_BITMAP)
911 : TOP_LEFT_ANGLE_BITMAP);
912 else if (row->indicate_eob_p && EQ (boundary_bot, Qleft))
913 left = (row->ends_at_zv_p
914 ? TOP_RIGHT_ANGLE_BITMAP : BOTTOM_LEFT_ANGLE_BITMAP);
915 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
916 left = CONTINUATION_LINE_BITMAP;
917 else if (row->indicate_empty_line_p && EQ (empty_pos, Qleft))
918 left = ZV_LINE_BITMAP;
919 else if (row->indicate_top_line_p && EQ (arrow_top, Qleft))
920 left = UP_ARROW_BITMAP;
921 else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qleft))
922 left = DOWN_ARROW_BITMAP;
923 else
924 left = NO_FRINGE_BITMAP;
926 /* Decide which bitmap to draw in the right fringe. */
927 if (WINDOW_RIGHT_FRINGE_WIDTH (w) == 0)
928 right = NO_FRINGE_BITMAP;
929 else if (row->right_user_fringe_bitmap != NO_FRINGE_BITMAP)
931 right = row->right_user_fringe_bitmap;
932 right_face_id = row->right_user_fringe_face_id;
934 else if (row->truncated_on_right_p)
935 right = RIGHT_TRUNCATION_BITMAP;
936 else if (row->indicate_bob_p && EQ (boundary_top, Qright))
937 right = ((row->indicate_eob_p && EQ (boundary_bot, Qright))
938 ? (row->ends_at_zv_p
939 ? TOP_LEFT_ANGLE_BITMAP : RIGHT_BRACKET_BITMAP)
940 : TOP_RIGHT_ANGLE_BITMAP);
941 else if (row->indicate_eob_p && EQ (boundary_bot, Qright))
942 right = (row->ends_at_zv_p
943 ? TOP_LEFT_ANGLE_BITMAP : BOTTOM_RIGHT_ANGLE_BITMAP);
944 else if (row->continued_p)
945 right = CONTINUED_LINE_BITMAP;
946 else if (row->indicate_top_line_p && EQ (arrow_top, Qright))
947 right = UP_ARROW_BITMAP;
948 else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qright))
949 right = DOWN_ARROW_BITMAP;
950 else if (row->indicate_empty_line_p && EQ (empty_pos, Qright))
951 right = ZV_LINE_BITMAP;
952 else
953 right = NO_FRINGE_BITMAP;
955 if (row->y != cur->y
956 || row->visible_height != cur->visible_height
957 || row->ends_at_zv_p != cur->ends_at_zv_p
958 || left != cur->left_fringe_bitmap
959 || right != cur->right_fringe_bitmap
960 || left_face_id != cur->left_fringe_face_id
961 || right_face_id != cur->right_fringe_face_id
962 || cur->redraw_fringe_bitmaps_p)
964 redraw_p = row->redraw_fringe_bitmaps_p = 1;
965 if (!keep_current_p)
967 cur->redraw_fringe_bitmaps_p = 1;
968 cur->left_fringe_bitmap = left;
969 cur->right_fringe_bitmap = right;
970 cur->left_fringe_face_id = left_face_id;
971 cur->right_fringe_face_id = right_face_id;
975 if (row->overlay_arrow_bitmap != cur->overlay_arrow_bitmap)
977 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
978 cur->overlay_arrow_bitmap = row->overlay_arrow_bitmap;
981 row->left_fringe_bitmap = left;
982 row->right_fringe_bitmap = right;
983 row->left_fringe_face_id = left_face_id;
984 row->right_fringe_face_id = right_face_id;
986 if (rn > 0 && row->redraw_fringe_bitmaps_p)
987 row[-1].redraw_fringe_bitmaps_p = cur[-1].redraw_fringe_bitmaps_p = 1;
990 return redraw_p && !keep_current_p;
994 /* Compute actual fringe widths for frame F.
996 If REDRAW is 1, redraw F if the fringe settings was actually
997 modified and F is visible.
999 Since the combined left and right fringe must occupy an integral
1000 number of columns, we may need to add some pixels to each fringe.
1001 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
1002 but a negative width value is taken literally (after negating it).
1004 We never make the fringes narrower than specified.
1007 void
1008 compute_fringe_widths (f, redraw)
1009 struct frame *f;
1010 int redraw;
1012 int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
1013 int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
1014 int o_cols = FRAME_FRINGE_COLS (f);
1016 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
1017 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
1018 int left_fringe_width, right_fringe_width;
1020 if (!NILP (left_fringe))
1021 left_fringe = Fcdr (left_fringe);
1022 if (!NILP (right_fringe))
1023 right_fringe = Fcdr (right_fringe);
1025 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
1026 XINT (left_fringe));
1027 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
1028 XINT (right_fringe));
1030 if (left_fringe_width || right_fringe_width)
1032 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
1033 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
1034 int conf_wid = left_wid + right_wid;
1035 int font_wid = FRAME_COLUMN_WIDTH (f);
1036 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
1037 int real_wid = cols * font_wid;
1038 if (left_wid && right_wid)
1040 if (left_fringe_width < 0)
1042 /* Left fringe width is fixed, adjust right fringe if necessary */
1043 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
1044 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
1046 else if (right_fringe_width < 0)
1048 /* Right fringe width is fixed, adjust left fringe if necessary */
1049 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
1050 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
1052 else
1054 /* Adjust both fringes with an equal amount.
1055 Note that we are doing integer arithmetic here, so don't
1056 lose a pixel if the total width is an odd number. */
1057 int fill = real_wid - conf_wid;
1058 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
1059 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
1062 else if (left_fringe_width)
1064 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
1065 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
1067 else
1069 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
1070 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
1072 FRAME_FRINGE_COLS (f) = cols;
1074 else
1076 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
1077 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
1078 FRAME_FRINGE_COLS (f) = 0;
1081 if (redraw && FRAME_VISIBLE_P (f))
1082 if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
1083 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
1084 o_cols != FRAME_FRINGE_COLS (f))
1085 redraw_frame (f);
1089 /* Free resources used by a user-defined bitmap. */
1091 void
1092 destroy_fringe_bitmap (n)
1093 int n;
1095 struct fringe_bitmap **fbp;
1097 fringe_faces[n] = Qnil;
1099 fbp = &fringe_bitmaps[n];
1100 if (*fbp && (*fbp)->dynamic)
1102 if (rif && rif->destroy_fringe_bitmap)
1103 rif->destroy_fringe_bitmap (n);
1104 xfree (*fbp);
1105 *fbp = NULL;
1108 while (max_used_fringe_bitmap > MAX_STANDARD_FRINGE_BITMAPS
1109 && fringe_bitmaps[max_used_fringe_bitmap - 1] == NULL)
1110 max_used_fringe_bitmap--;
1114 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap, Sdestroy_fringe_bitmap,
1115 1, 1, 0,
1116 doc: /* Destroy fringe bitmap BITMAP.
1117 If BITMAP overrides a standard fringe bitmap, the original bitmap is restored. */)
1118 (bitmap)
1119 Lisp_Object bitmap;
1121 int n;
1123 CHECK_SYMBOL (bitmap);
1124 n = lookup_fringe_bitmap (bitmap);
1125 if (!n)
1126 return Qnil;
1128 destroy_fringe_bitmap (n);
1130 if (n >= MAX_STANDARD_FRINGE_BITMAPS)
1132 Vfringe_bitmaps = Fdelq (bitmap, Vfringe_bitmaps);
1133 /* It would be better to remove the fringe property. */
1134 Fput (bitmap, Qfringe, Qnil);
1137 return Qnil;
1141 /* Initialize bitmap bit.
1143 On X, we bit-swap the built-in bitmaps and reduce bitmap
1144 from short to char array if width is <= 8 bits.
1146 On MAC with big-endian CPU, we need to byte-swap each short.
1148 On W32 and MAC (little endian), there's no need to do this.
1151 void
1152 init_fringe_bitmap (which, fb, once_p)
1153 enum fringe_bitmap_type which;
1154 struct fringe_bitmap *fb;
1155 int once_p;
1157 if (once_p || fb->dynamic)
1159 #if defined (HAVE_X_WINDOWS)
1160 static unsigned char swap_nibble[16]
1161 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1162 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1163 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1164 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
1165 unsigned short *bits = fb->bits;
1166 int j;
1168 if (fb->width <= 8)
1170 unsigned char *cbits = (unsigned char *)fb->bits;
1171 for (j = 0; j < fb->height; j++)
1173 unsigned short b = *bits++;
1174 unsigned char c;
1175 c = (unsigned char)((swap_nibble[b & 0xf] << 4)
1176 | (swap_nibble[(b>>4) & 0xf]));
1177 *cbits++ = (c >> (8 - fb->width));
1180 else
1182 for (j = 0; j < fb->height; j++)
1184 unsigned short b = *bits;
1185 b = (unsigned short)((swap_nibble[b & 0xf] << 12)
1186 | (swap_nibble[(b>>4) & 0xf] << 8)
1187 | (swap_nibble[(b>>8) & 0xf] << 4)
1188 | (swap_nibble[(b>>12) & 0xf]));
1189 *bits++ = (b >> (16 - fb->width));
1192 #endif /* HAVE_X_WINDOWS */
1194 #if defined (MAC_OS) && defined (WORDS_BIG_ENDIAN)
1195 unsigned short *bits = fb->bits;
1196 int j;
1197 for (j = 0; j < fb->height; j++)
1199 unsigned short b = *bits;
1200 *bits++ = ((b >> 8) & 0xff) | ((b & 0xff) << 8);
1202 #endif /* MAC_OS && WORDS_BIG_ENDIAN */
1205 if (!once_p)
1207 destroy_fringe_bitmap (which);
1209 if (rif && rif->define_fringe_bitmap)
1210 rif->define_fringe_bitmap (which, fb->bits, fb->height, fb->width);
1212 fringe_bitmaps[which] = fb;
1213 if (which >= max_used_fringe_bitmap)
1214 max_used_fringe_bitmap = which + 1;
1219 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap,
1220 2, 5, 0,
1221 doc: /* Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH.
1222 BITMAP is a symbol or string naming the new fringe bitmap.
1223 BITS is either a string or a vector of integers.
1224 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1225 WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1226 Optional fifth arg ALIGN may be one of `top', `center', or `bottom',
1227 indicating the positioning of the bitmap relative to the rows where it
1228 is used; the default is to center the bitmap. Fourth arg may also be a
1229 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1230 should be repeated.
1231 If BITMAP already exists, the existing definition is replaced. */)
1232 (bitmap, bits, height, width, align)
1233 Lisp_Object bitmap, bits, height, width, align;
1235 int n, h, i, j;
1236 unsigned short *b;
1237 struct fringe_bitmap fb, *xfb;
1238 int fill1 = 0, fill2 = 0;
1240 CHECK_SYMBOL (bitmap);
1242 if (STRINGP (bits))
1243 h = SCHARS (bits);
1244 else if (VECTORP (bits))
1245 h = XVECTOR (bits)->size;
1246 else
1247 bits = wrong_type_argument (Qsequencep, bits);
1249 if (NILP (height))
1250 fb.height = h;
1251 else
1253 CHECK_NUMBER (height);
1254 fb.height = min (XINT (height), 255);
1255 if (fb.height > h)
1257 fill1 = (fb.height - h) / 2;
1258 fill2 = fb.height - h - fill1;
1262 if (NILP (width))
1263 fb.width = 8;
1264 else
1266 CHECK_NUMBER (width);
1267 fb.width = min (XINT (width), 255);
1270 fb.period = 0;
1271 fb.align = ALIGN_BITMAP_CENTER;
1273 if (CONSP (align))
1275 Lisp_Object period = XCDR (align);
1276 if (CONSP (period))
1278 period = XCAR (period);
1279 if (!NILP (period))
1281 fb.period = fb.height;
1282 fb.height = 255;
1285 align = XCAR (align);
1287 if (EQ (align, Qtop))
1288 fb.align = ALIGN_BITMAP_TOP;
1289 else if (EQ (align, Qbottom))
1290 fb.align = ALIGN_BITMAP_BOTTOM;
1291 else if (!NILP (align) && !EQ (align, Qcenter))
1292 error ("Bad align argument");
1294 n = lookup_fringe_bitmap (bitmap);
1295 if (!n)
1297 if (max_used_fringe_bitmap < max_fringe_bitmaps)
1298 n = max_used_fringe_bitmap++;
1299 else
1301 for (n = MAX_STANDARD_FRINGE_BITMAPS;
1302 n < max_fringe_bitmaps;
1303 n++)
1304 if (fringe_bitmaps[n] == NULL)
1305 break;
1307 if (n == max_fringe_bitmaps)
1309 if ((max_fringe_bitmaps + 20) > MAX_FRINGE_BITMAPS)
1310 error ("No free fringe bitmap slots");
1312 i = max_fringe_bitmaps;
1313 max_fringe_bitmaps += 20;
1314 fringe_bitmaps
1315 = ((struct fringe_bitmap **)
1316 xrealloc (fringe_bitmaps, max_fringe_bitmaps * sizeof (struct fringe_bitmap *)));
1317 fringe_faces
1318 = (Lisp_Object *) xrealloc (fringe_faces, max_fringe_bitmaps * sizeof (Lisp_Object));
1320 for (; i < max_fringe_bitmaps; i++)
1322 fringe_bitmaps[i] = NULL;
1323 fringe_faces[i] = Qnil;
1328 Vfringe_bitmaps = Fcons (bitmap, Vfringe_bitmaps);
1329 Fput (bitmap, Qfringe, make_number (n));
1332 fb.dynamic = 1;
1334 xfb = (struct fringe_bitmap *) xmalloc (sizeof fb
1335 + fb.height * BYTES_PER_BITMAP_ROW);
1336 fb.bits = b = (unsigned short *) (xfb + 1);
1337 bzero (b, fb.height);
1339 j = 0;
1340 while (j < fb.height)
1342 for (i = 0; i < fill1 && j < fb.height; i++)
1343 b[j++] = 0;
1344 for (i = 0; i < h && j < fb.height; i++)
1346 Lisp_Object elt = Faref (bits, make_number (i));
1347 b[j++] = NUMBERP (elt) ? XINT (elt) : 0;
1349 for (i = 0; i < fill2 && j < fb.height; i++)
1350 b[j++] = 0;
1353 *xfb = fb;
1355 init_fringe_bitmap (n, xfb, 0);
1357 return bitmap;
1360 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face,
1361 1, 2, 0,
1362 doc: /* Set face for fringe bitmap BITMAP to FACE.
1363 If FACE is nil, reset face to default fringe face. */)
1364 (bitmap, face)
1365 Lisp_Object bitmap, face;
1367 int n;
1368 int face_id;
1370 CHECK_SYMBOL (bitmap);
1371 n = lookup_fringe_bitmap (bitmap);
1372 if (!n)
1373 error ("Undefined fringe bitmap");
1375 if (!NILP (face))
1377 face_id = lookup_derived_face (SELECTED_FRAME (), face,
1378 'A', FRINGE_FACE_ID, 1);
1379 if (face_id < 0)
1380 error ("No such face");
1383 fringe_faces[n] = face;
1385 return Qnil;
1388 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos, Sfringe_bitmaps_at_pos,
1389 0, 2, 0,
1390 doc: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1391 If WINDOW is nil, use selected window. If POS is nil, use value of point
1392 in that window. Return value is a list (LEFT RIGHT OV), where LEFT
1393 is the symbol for the bitmap in the left fringe (or nil if no bitmap),
1394 RIGHT is similar for the right fringe, and OV is non-nil if there is an
1395 overlay arrow in the left fringe.
1396 Return nil if POS is not visible in WINDOW. */)
1397 (pos, window)
1398 Lisp_Object pos, window;
1400 struct window *w;
1401 struct glyph_row *row;
1402 int textpos;
1404 if (NILP (window))
1405 window = selected_window;
1406 CHECK_WINDOW (window);
1407 w = XWINDOW (window);
1409 if (!NILP (pos))
1411 CHECK_NUMBER_COERCE_MARKER (pos);
1412 textpos = XINT (pos);
1414 else if (w == XWINDOW (selected_window))
1415 textpos = PT;
1416 else
1417 textpos = XMARKER (w->pointm)->charpos;
1419 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1420 row = row_containing_pos (w, textpos, row, NULL, 0);
1421 if (row)
1422 return list3 (get_fringe_bitmap_name (row->left_fringe_bitmap),
1423 get_fringe_bitmap_name (row->right_fringe_bitmap),
1424 (row->overlay_arrow_bitmap == 0 ? Qnil
1425 : row->overlay_arrow_bitmap < 0 ? Qt
1426 : get_fringe_bitmap_name (row->overlay_arrow_bitmap)));
1427 else
1428 return Qnil;
1432 /***********************************************************************
1433 Initialization
1434 ***********************************************************************/
1436 void
1437 syms_of_fringe ()
1439 defsubr (&Sdestroy_fringe_bitmap);
1440 defsubr (&Sdefine_fringe_bitmap);
1441 defsubr (&Sfringe_bitmaps_at_pos);
1442 defsubr (&Sset_fringe_bitmap_face);
1444 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe,
1445 doc: /* *Non-nil means that newline may flow into the right fringe.
1446 This means that display lines which are exactly as wide as the window
1447 (not counting the final newline) will only occupy one screen line, by
1448 showing (or hiding) the final newline in the right fringe; when point
1449 is at the final newline, the cursor is shown in the right fringe.
1450 If nil, also continue lines which are exactly as wide as the window. */);
1451 Voverflow_newline_into_fringe = Qt;
1453 DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps,
1454 doc: /* List of fringe bitmap symbols.
1455 You must (require 'fringe) to use fringe bitmap symbols in your programs." */);
1456 Vfringe_bitmaps = Qnil;
1459 /* Garbage collection hook */
1461 void
1462 mark_fringe_data ()
1464 int i;
1466 for (i = 0; i < max_fringe_bitmaps; i++)
1467 if (!NILP (fringe_faces[i]))
1468 mark_object (fringe_faces[i]);
1471 /* Initialize this module when Emacs starts. */
1473 void
1474 init_fringe_once ()
1476 enum fringe_bitmap_type bt;
1478 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1479 init_fringe_bitmap(bt, &standard_bitmaps[bt], 1);
1482 void
1483 init_fringe ()
1485 int i;
1487 max_fringe_bitmaps = MAX_STANDARD_FRINGE_BITMAPS + 20;
1489 fringe_bitmaps
1490 = (struct fringe_bitmap **) xmalloc (max_fringe_bitmaps * sizeof (struct fringe_bitmap *));
1491 fringe_faces
1492 = (Lisp_Object *) xmalloc (max_fringe_bitmaps * sizeof (Lisp_Object));
1494 for (i = 0; i < max_fringe_bitmaps; i++)
1496 fringe_bitmaps[i] = NULL;
1497 fringe_faces[i] = Qnil;
1501 #ifdef HAVE_NTGUI
1503 void
1504 w32_init_fringe ()
1506 enum fringe_bitmap_type bt;
1508 if (!rif)
1509 return;
1511 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1513 struct fringe_bitmap *fb = &standard_bitmaps[bt];
1514 rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
1518 void
1519 w32_reset_fringes ()
1521 /* Destroy row bitmaps. */
1522 int bt;
1524 if (!rif)
1525 return;
1527 for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++)
1528 rif->destroy_fringe_bitmap (bt);
1531 #endif /* HAVE_NTGUI */
1533 #endif /* HAVE_WINDOW_SYSTEM */
1535 /* arch-tag: 04596920-43eb-473d-b319-82712338162d
1536 (do not change this comment) */