Add 2011 to FSF/AIST copyright years.
[bpt/emacs.git] / src / fringe.c
1 /* Fringe handling (split from xdisp.c).
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997,
3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
5
6 This file is part of GNU Emacs.
7
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 3 of the License, or
11 (at your option) any later version.
12
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.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <setjmp.h>
24
25 #include "lisp.h"
26 #include "frame.h"
27 #include "window.h"
28 #include "dispextern.h"
29 #include "buffer.h"
30 #include "blockinput.h"
31 #include "termhooks.h"
32
33 #ifdef HAVE_WINDOW_SYSTEM
34
35 extern Lisp_Object Qfringe;
36 extern Lisp_Object Qtop, Qbottom, Qcenter;
37 extern Lisp_Object Qup, Qdown, Qleft, Qright;
38
39 /* Non-nil means that newline may flow into the right fringe. */
40
41 Lisp_Object Voverflow_newline_into_fringe;
42
43 /* List of known fringe bitmap symbols.
44
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.
48 */
49
50 Lisp_Object Vfringe_bitmaps;
51
52 /* Fringe bitmaps are represented in three different ways:
53
54 Logical bitmaps are used internally to denote things like
55 'end-of-buffer', 'left-truncation', 'overlay-arrow', etc.
56
57 Physical bitmaps specify the visual appearence of the bitmap,
58 e.g. 'bottom-left-angle', 'left-arrow', 'left-triangle', etc.
59 User defined bitmaps are physical bitmaps.
60
61 Internally, fringe bitmaps for a specific display row are
62 represented as a simple integer that is used as an index
63 into the table of all defined bitmaps. This index is stored
64 in the `fringe' property of the physical bitmap symbol.
65
66 Logical bitmaps are mapped to physical bitmaps through the
67 buffer-local `fringe-indicator-alist' variable.
68
69 Each element of this alist is a cons (LOGICAL . PHYSICAL)
70 mapping a logical bitmap to a physical bitmap.
71 PHYSICAL is either a symbol to use in both left and right fringe,
72 or a cons of two symbols (LEFT . RIGHT) denoting different
73 bitmaps to use in left and right fringe.
74
75 LOGICAL is first looked up in the window's buffer's buffer-local
76 value of the fringe-indicator-alist variable, and if not present,
77 in the global value of fringe-indicator-alist.
78
79 If LOGICAL is not present in either alist, or the PHYSICAL value
80 found is nil, no bitmap is shown for the logical bitmap.
81
82 The `left-fringe' and `right-fringe' display properties
83 must specify physical bitmap symbols.
84 */
85
86 extern Lisp_Object Qunknown;
87 Lisp_Object Qtruncation, Qcontinuation, Qoverlay_arrow;
88 Lisp_Object Qempty_line, Qtop_bottom;
89 extern Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
90 Lisp_Object Qhollow_small;
91
92 enum fringe_bitmap_align
93 {
94 ALIGN_BITMAP_CENTER = 0,
95 ALIGN_BITMAP_TOP,
96 ALIGN_BITMAP_BOTTOM
97 };
98
99 struct fringe_bitmap
100 {
101 unsigned short *bits;
102 unsigned height : 8;
103 unsigned width : 8;
104 unsigned period : 8;
105 unsigned align : 2;
106 unsigned dynamic : 1;
107 };
108
109 \f
110 /***********************************************************************
111 Fringe bitmaps
112 ***********************************************************************/
113
114 /* Undefined bitmap. A question mark. */
115 /*
116 ..xxxx..
117 .xxxxxx.
118 xx....xx
119 xx....xx
120 ....xx..
121 ...xx...
122 ...xx...
123 ........
124 ...xx...
125 ...xx...
126 */
127 static unsigned short question_mark_bits[] = {
128 0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
129
130 /* An arrow like this: `<-'. */
131 /*
132 ...xx...
133 ..xx....
134 .xx.....
135 xxxxxx..
136 xxxxxx..
137 .xx.....
138 ..xx....
139 ...xx...
140 */
141 static unsigned short left_arrow_bits[] = {
142 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
143
144
145 /* Right truncation arrow bitmap `->'. */
146 /*
147 ...xx...
148 ....xx..
149 .....xx.
150 ..xxxxxx
151 ..xxxxxx
152 .....xx.
153 ....xx..
154 ...xx...
155 */
156 static unsigned short right_arrow_bits[] = {
157 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
158
159
160 /* Up arrow bitmap. */
161 /*
162 ...xx...
163 ..xxxx..
164 .xxxxxx.
165 xxxxxxxx
166 ...xx...
167 ...xx...
168 ...xx...
169 ...xx...
170 */
171 static unsigned short up_arrow_bits[] = {
172 0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
173
174
175 /* Down arrow bitmap. */
176 /*
177 ...xx...
178 ...xx...
179 ...xx...
180 ...xx...
181 xxxxxxxx
182 .xxxxxx.
183 ..xxxx..
184 ...xx...
185 */
186 static unsigned short down_arrow_bits[] = {
187 0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
188
189 /* Marker for continuation lines. */
190 /*
191 ..xxxx..
192 .xxxxx..
193 xx......
194 xxx..x..
195 xxxxxx..
196 .xxxxx..
197 ..xxxx..
198 .xxxxx..
199 */
200 static unsigned short left_curly_arrow_bits[] = {
201 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
202
203 /* Marker for continued lines. */
204 /*
205 ..xxxx..
206 ..xxxxx.
207 ......xx
208 ..x..xxx
209 ..xxxxxx
210 ..xxxxx.
211 ..xxxx..
212 ..xxxxx.
213 */
214 static unsigned short right_curly_arrow_bits[] = {
215 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
216
217 /* Reverse Overlay arrow bitmap. A triangular arrow. */
218 /*
219 ......xx
220 ....xxxx
221 ...xxxxx
222 ..xxxxxx
223 ..xxxxxx
224 ...xxxxx
225 ....xxxx
226 ......xx
227 */
228 static unsigned short left_triangle_bits[] = {
229 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
230
231 /* Overlay arrow bitmap. A triangular arrow. */
232 /*
233 xx......
234 xxxx....
235 xxxxx...
236 xxxxxx..
237 xxxxxx..
238 xxxxx...
239 xxxx....
240 xx......
241 */
242 static unsigned short right_triangle_bits[] = {
243 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
244
245 /* First line bitmap. An top-left angle. */
246 /*
247 xxxxxx..
248 xxxxxx..
249 xx......
250 xx......
251 xx......
252 xx......
253 xx......
254 ........
255 */
256 static unsigned short top_left_angle_bits[] = {
257 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00};
258
259 /* First line bitmap. An right-up angle. */
260 /*
261 ..xxxxxx
262 ..xxxxxx
263 ......xx
264 ......xx
265 ......xx
266 ......xx
267 ......xx
268 ........
269 */
270 static unsigned short top_right_angle_bits[] = {
271 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
272
273 /* Last line bitmap. An left-down angle. */
274 /*
275 ........
276 xx......
277 xx......
278 xx......
279 xx......
280 xx......
281 xxxxxx..
282 xxxxxx..
283 */
284 static unsigned short bottom_left_angle_bits[] = {
285 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
286
287 /* Last line bitmap. An right-down angle. */
288 /*
289 ........
290 ......xx
291 ......xx
292 ......xx
293 ......xx
294 ......xx
295 ..xxxxxx
296 ..xxxxxx
297 */
298 static unsigned short bottom_right_angle_bits[] = {
299 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
300
301 /* First/last line bitmap. An left bracket. */
302 /*
303 xxxxxx..
304 xxxxxx..
305 xx......
306 xx......
307 xx......
308 xx......
309 xx......
310 xx......
311 xxxxxx..
312 xxxxxx..
313 */
314 static unsigned short left_bracket_bits[] = {
315 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
316
317 /* First/last line bitmap. An right bracket. */
318 /*
319 ..xxxxxx
320 ..xxxxxx
321 ......xx
322 ......xx
323 ......xx
324 ......xx
325 ......xx
326 ......xx
327 ..xxxxxx
328 ..xxxxxx
329 */
330 static unsigned short right_bracket_bits[] = {
331 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
332
333 /* Filled box cursor bitmap. A filled box; max 13 pixels high. */
334 /*
335 xxxxxxx.
336 xxxxxxx.
337 xxxxxxx.
338 xxxxxxx.
339 xxxxxxx.
340 xxxxxxx.
341 xxxxxxx.
342 xxxxxxx.
343 xxxxxxx.
344 xxxxxxx.
345 xxxxxxx.
346 xxxxxxx.
347 xxxxxxx.
348 */
349 static unsigned short filled_rectangle_bits[] = {
350 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
351
352 /* Hollow box cursor bitmap. A hollow box; max 13 pixels high. */
353 /*
354 xxxxxxx.
355 x.....x.
356 x.....x.
357 x.....x.
358 x.....x.
359 x.....x.
360 x.....x.
361 x.....x.
362 x.....x.
363 x.....x.
364 x.....x.
365 x.....x.
366 xxxxxxx.
367 */
368 static unsigned short hollow_rectangle_bits[] = {
369 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe};
370
371 /* Hollow square bitmap. */
372 /*
373 .xxxxxx.
374 .x....x.
375 .x....x.
376 .x....x.
377 .x....x.
378 .xxxxxx.
379 */
380 static unsigned short hollow_square_bits[] = {
381 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
382
383 /* Filled square bitmap. */
384 /*
385 .xxxxxx.
386 .xxxxxx.
387 .xxxxxx.
388 .xxxxxx.
389 .xxxxxx.
390 .xxxxxx.
391 */
392 static unsigned short filled_square_bits[] = {
393 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e};
394
395 /* Bar cursor bitmap. A vertical bar; max 13 pixels high. */
396 /*
397 xx......
398 xx......
399 xx......
400 xx......
401 xx......
402 xx......
403 xx......
404 xx......
405 xx......
406 xx......
407 xx......
408 xx......
409 xx......
410 */
411 static unsigned short vertical_bar_bits[] = {
412 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
413
414 /* HBar cursor bitmap. A horizontal bar; 2 pixels high. */
415 /*
416 xxxxxxx.
417 xxxxxxx.
418 */
419 static unsigned short horizontal_bar_bits[] = {
420 0xfe, 0xfe};
421
422
423 /* Bitmap drawn to indicate lines not displaying text if
424 `indicate-empty-lines' is non-nil. */
425 /*
426 ........
427 ..xxxx..
428 ........
429 ........
430 ..xxxx..
431 ........
432 */
433 static unsigned short empty_line_bits[] = {
434 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
435 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
436 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
437 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
438 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
439 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
440 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
441 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
442
443
444 #define BYTES_PER_BITMAP_ROW (sizeof (unsigned short))
445 #define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
446 #define FRBITS(bits) bits, STANDARD_BITMAP_HEIGHT (bits)
447
448 /* NOTE: The order of these bitmaps must match the sequence
449 used in fringe.el to define the corresponding symbols. */
450
451 struct fringe_bitmap standard_bitmaps[] =
452 {
453 { NULL, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */
454 { FRBITS (question_mark_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
455 { FRBITS (left_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
456 { FRBITS (right_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
457 { FRBITS (up_arrow_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
458 { FRBITS (down_arrow_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
459 { FRBITS (left_curly_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
460 { FRBITS (right_curly_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
461 { FRBITS (left_triangle_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
462 { FRBITS (right_triangle_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
463 { FRBITS (top_left_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
464 { FRBITS (top_right_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
465 { FRBITS (bottom_left_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
466 { FRBITS (bottom_right_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
467 { FRBITS (left_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
468 { FRBITS (right_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
469 { FRBITS (filled_rectangle_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
470 { FRBITS (hollow_rectangle_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
471 { FRBITS (filled_square_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
472 { FRBITS (hollow_square_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
473 { FRBITS (vertical_bar_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
474 { FRBITS (horizontal_bar_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
475 { FRBITS (empty_line_bits), 8, 3, ALIGN_BITMAP_TOP, 0 },
476 };
477
478 #define NO_FRINGE_BITMAP 0
479 #define UNDEF_FRINGE_BITMAP 1
480 #define MAX_STANDARD_FRINGE_BITMAPS (sizeof(standard_bitmaps)/sizeof(standard_bitmaps[0]))
481
482 static struct fringe_bitmap **fringe_bitmaps;
483 static Lisp_Object *fringe_faces;
484 static int max_fringe_bitmaps;
485
486 int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS;
487
488
489 /* Lookup bitmap number for symbol BITMAP.
490 Return 0 if not a bitmap. */
491
492 int
493 lookup_fringe_bitmap (bitmap)
494 Lisp_Object bitmap;
495 {
496 int bn;
497
498 bitmap = Fget (bitmap, Qfringe);
499 if (!INTEGERP (bitmap))
500 return 0;
501
502 bn = XINT (bitmap);
503 if (bn > NO_FRINGE_BITMAP
504 && bn < max_used_fringe_bitmap
505 && (bn < MAX_STANDARD_FRINGE_BITMAPS
506 || fringe_bitmaps[bn] != NULL))
507 return bn;
508
509 return 0;
510 }
511
512 /* Get fringe bitmap name for bitmap number BN.
513
514 Found by traversing Vfringe_bitmaps comparing BN to the
515 fringe property for each symbol.
516
517 Return BN if not found in Vfringe_bitmaps. */
518
519 static Lisp_Object
520 get_fringe_bitmap_name (bn)
521 int bn;
522 {
523 Lisp_Object bitmaps;
524 Lisp_Object num;
525
526 /* Zero means no bitmap -- return nil. */
527 if (bn <= 0)
528 return Qnil;
529
530 bitmaps = Vfringe_bitmaps;
531 num = make_number (bn);
532
533 while (CONSP (bitmaps))
534 {
535 Lisp_Object bitmap = XCAR (bitmaps);
536 if (EQ (num, Fget (bitmap, Qfringe)))
537 return bitmap;
538 bitmaps = XCDR (bitmaps);
539 }
540
541 return num;
542 }
543
544
545 /* Draw the bitmap WHICH in one of the left or right fringes of
546 window W. ROW is the glyph row for which to display the bitmap; it
547 determines the vertical position at which the bitmap has to be
548 drawn.
549 LEFT_P is 1 for left fringe, 0 for right fringe.
550 */
551
552 static void
553 draw_fringe_bitmap_1 (w, row, left_p, overlay, which)
554 struct window *w;
555 struct glyph_row *row;
556 int left_p, overlay;
557 int which;
558 {
559 struct frame *f = XFRAME (WINDOW_FRAME (w));
560 struct draw_fringe_bitmap_params p;
561 struct fringe_bitmap *fb;
562 int period;
563 int face_id = DEFAULT_FACE_ID;
564 int offset, header_line_height;
565
566 p.overlay_p = (overlay & 1) == 1;
567 p.cursor_p = (overlay & 2) == 2;
568
569 if (which != NO_FRINGE_BITMAP)
570 {
571 offset = 0;
572 }
573 else if (left_p)
574 {
575 which = row->left_fringe_bitmap;
576 face_id = row->left_fringe_face_id;
577 offset = row->left_fringe_offset;
578 }
579 else
580 {
581 which = row->right_fringe_bitmap;
582 face_id = row->right_fringe_face_id;
583 offset = row->right_fringe_offset;
584 }
585
586 if (face_id == DEFAULT_FACE_ID)
587 {
588 Lisp_Object face;
589
590 if ((face = fringe_faces[which], NILP (face))
591 || (face_id = lookup_derived_face (f, face, FRINGE_FACE_ID, 0),
592 face_id < 0))
593 face_id = FRINGE_FACE_ID;
594 }
595
596 fb = fringe_bitmaps[which];
597 if (fb == NULL)
598 fb = &standard_bitmaps[which < MAX_STANDARD_FRINGE_BITMAPS
599 ? which : UNDEF_FRINGE_BITMAP];
600
601 period = fb->period;
602
603 /* Convert row to frame coordinates. */
604 p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y) + offset;
605
606 p.which = which;
607 p.bits = fb->bits;
608 p.wd = fb->width;
609
610 p.h = fb->height;
611 p.dh = (period > 0 ? (p.y % period) : 0);
612 p.h -= p.dh;
613
614 /* Adjust y to the offset in the row to start drawing the bitmap. */
615 switch (fb->align)
616 {
617 case ALIGN_BITMAP_CENTER:
618 p.y += (row->height - p.h) / 2;
619 break;
620 case ALIGN_BITMAP_BOTTOM:
621 p.y += (row->visible_height - p.h);
622 break;
623 case ALIGN_BITMAP_TOP:
624 break;
625 }
626
627 p.face = FACE_FROM_ID (f, face_id);
628
629 if (p.face == NULL)
630 {
631 /* This could happen after clearing face cache.
632 But it shouldn't happen anymore. ++kfs */
633 return;
634 }
635
636 PREPARE_FACE_FOR_DISPLAY (f, p.face);
637
638 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
639 the fringe. */
640 p.bx = -1;
641 header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
642 p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
643 p.ny = row->visible_height;
644 if (left_p)
645 {
646 int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
647 int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
648 ? LEFT_MARGIN_AREA
649 : TEXT_AREA));
650 if (p.wd > wd)
651 p.wd = wd;
652 p.x = x - p.wd - (wd - p.wd) / 2;
653
654 if (p.wd < wd || p.y > p.by || p.y + p.h < p.by + p.ny)
655 {
656 /* If W has a vertical border to its left, don't draw over it. */
657 wd -= ((!WINDOW_LEFTMOST_P (w)
658 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
659 ? 1 : 0);
660 p.bx = x - wd;
661 p.nx = wd;
662 }
663 }
664 else
665 {
666 int x = window_box_right (w,
667 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
668 ? RIGHT_MARGIN_AREA
669 : TEXT_AREA));
670 int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
671 if (p.wd > wd)
672 p.wd = wd;
673 p.x = x + (wd - p.wd) / 2;
674 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
675 the fringe. */
676 if (p.wd < wd || p.y > p.by || p.y + p.h < p.by + p.ny)
677 {
678 p.bx = x;
679 p.nx = wd;
680 }
681 }
682
683 FRAME_RIF (f)->draw_fringe_bitmap (w, row, &p);
684 }
685
686 static int
687 get_logical_cursor_bitmap (w, cursor)
688 struct window *w;
689 Lisp_Object cursor;
690 {
691 Lisp_Object cmap, bm = Qnil;
692
693 if ((cmap = XBUFFER (w->buffer)->fringe_cursor_alist), !NILP (cmap))
694 {
695 bm = Fassq (cursor, cmap);
696 if (CONSP (bm))
697 {
698 if ((bm = XCDR (bm)), NILP (bm))
699 return NO_FRINGE_BITMAP;
700 return lookup_fringe_bitmap (bm);
701 }
702 }
703 if (EQ (cmap, buffer_defaults.fringe_cursor_alist))
704 return NO_FRINGE_BITMAP;
705 bm = Fassq (cursor, buffer_defaults.fringe_cursor_alist);
706 if (!CONSP (bm) || ((bm = XCDR (bm)), NILP (bm)))
707 return NO_FRINGE_BITMAP;
708 return lookup_fringe_bitmap (bm);
709 }
710
711 static int
712 get_logical_fringe_bitmap (w, bitmap, right_p, partial_p)
713 struct window *w;
714 Lisp_Object bitmap;
715 int right_p, partial_p;
716 {
717 Lisp_Object cmap, bm1 = Qnil, bm2 = Qnil, bm;
718 int ln1 = 0, ln2 = 0;
719 int ix1 = right_p;
720 int ix2 = ix1 + (partial_p ? 2 : 0);
721
722 /* Lookup in buffer-local fringe-indicator-alist before global alist.
723
724 Elements are:
725 BITMAP -- use for all
726 (L R) -- use for left right (whether partial or not)
727 (L R PL PR) -- use for left right partial-left partial-right
728 If any value in local binding is not present or t, use global value.
729
730 If partial, lookup partial bitmap in default value if not found here.
731 If not partial, or no partial spec is present, use non-partial bitmap. */
732
733 if ((cmap = XBUFFER (w->buffer)->fringe_indicator_alist), !NILP (cmap))
734 {
735 bm1 = Fassq (bitmap, cmap);
736 if (CONSP (bm1))
737 {
738 if ((bm1 = XCDR (bm1)), NILP (bm1))
739 return NO_FRINGE_BITMAP;
740 if (CONSP (bm1))
741 {
742 ln1 = XINT (Flength (bm1));
743 if (partial_p)
744 {
745 if (ln1 > ix2)
746 {
747 bm = Fnth (make_number (ix2), bm1);
748 if (!EQ (bm, Qt))
749 goto found;
750 }
751 }
752 else
753 {
754 if (ln1 > ix1)
755 {
756 bm = Fnth (make_number (ix1), bm1);
757 if (!EQ (bm, Qt))
758 goto found;
759 }
760 }
761 }
762 else if ((bm = bm1, !EQ (bm, Qt)))
763 goto found;
764 }
765 }
766
767 if (!EQ (cmap, buffer_defaults.fringe_indicator_alist)
768 && !NILP (buffer_defaults.fringe_indicator_alist))
769 {
770 bm2 = Fassq (bitmap, buffer_defaults.fringe_indicator_alist);
771 if (CONSP (bm2))
772 {
773 if ((bm2 = XCDR (bm2)), !NILP (bm2))
774 {
775 if (CONSP (bm2))
776 {
777 ln2 = XINT (Flength (bm2));
778 if (partial_p)
779 {
780 if (ln2 > ix2)
781 {
782 bm = Fnth (make_number (ix2), bm2);
783 if (!EQ (bm, Qt))
784 goto found;
785 }
786 }
787 }
788 }
789 }
790 }
791
792 if (ln1 > ix1)
793 {
794 bm = Fnth (make_number (ix1), bm1);
795 if (!EQ (bm, Qt))
796 goto found;
797 }
798
799 if (ln2 > ix1)
800 {
801 bm = Fnth (make_number (ix1), bm2);
802 if (!EQ (bm, Qt))
803 goto found;
804 return NO_FRINGE_BITMAP;
805 }
806 else if ((bm = bm2, NILP (bm)))
807 return NO_FRINGE_BITMAP;
808
809 found:
810 return lookup_fringe_bitmap (bm);
811 }
812
813
814 void
815 draw_fringe_bitmap (w, row, left_p)
816 struct window *w;
817 struct glyph_row *row;
818 int left_p;
819 {
820 int overlay = 0;
821
822 if (!left_p && row->cursor_in_fringe_p)
823 {
824 Lisp_Object cursor = Qnil;
825
826 switch (w->phys_cursor_type)
827 {
828 case HOLLOW_BOX_CURSOR:
829 if (row->visible_height >= STANDARD_BITMAP_HEIGHT (hollow_rectangle_bits))
830 cursor = Qhollow;
831 else
832 cursor = Qhollow_small;
833 break;
834 case FILLED_BOX_CURSOR:
835 cursor = Qbox;
836 break;
837 case BAR_CURSOR:
838 cursor = Qbar;
839 break;
840 case HBAR_CURSOR:
841 cursor = Qhbar;
842 break;
843 case NO_CURSOR:
844 default:
845 w->phys_cursor_on_p = 0;
846 row->cursor_in_fringe_p = 0;
847 break;
848 }
849 if (!NILP (cursor))
850 {
851 int bm = get_logical_cursor_bitmap (w, cursor);
852 if (bm != NO_FRINGE_BITMAP)
853 {
854 draw_fringe_bitmap_1 (w, row, 0, 2, bm);
855 overlay = EQ (cursor, Qbox) ? 3 : 1;
856 }
857 }
858 }
859
860 draw_fringe_bitmap_1 (w, row, left_p, overlay, NO_FRINGE_BITMAP);
861
862 if (left_p && row->overlay_arrow_bitmap != NO_FRINGE_BITMAP)
863 draw_fringe_bitmap_1 (w, row, 1, 1, row->overlay_arrow_bitmap);
864 }
865
866
867 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
868 function with input blocked. */
869
870 void
871 draw_row_fringe_bitmaps (w, row)
872 struct window *w;
873 struct glyph_row *row;
874 {
875 xassert (interrupt_input_blocked);
876
877 /* If row is completely invisible, because of vscrolling, we
878 don't have to draw anything. */
879 if (row->visible_height <= 0)
880 return;
881
882 if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
883 draw_fringe_bitmap (w, row, 1);
884
885 if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
886 draw_fringe_bitmap (w, row, 0);
887 }
888
889 /* Draw the fringes of window W. Only fringes for rows marked for
890 update in redraw_fringe_bitmaps_p are drawn.
891
892 Return >0 if left or right fringe was redrawn in any way.
893
894 If NO_FRINGE is non-zero, also return >0 if either fringe has zero width.
895
896 A return value >0 indicates that the vertical line between windows
897 needs update (as it may be drawn in the fringe).
898 */
899
900 int
901 draw_window_fringes (w, no_fringe)
902 struct window *w;
903 int no_fringe;
904 {
905 struct glyph_row *row;
906 int yb = window_text_bottom_y (w);
907 int nrows = w->current_matrix->nrows;
908 int y, rn;
909 int updated = 0;
910
911 if (w->pseudo_window_p)
912 return 0;
913
914 /* Must draw line if no fringe */
915 if (no_fringe
916 && (WINDOW_LEFT_FRINGE_WIDTH (w) == 0
917 || WINDOW_RIGHT_FRINGE_WIDTH (w) == 0))
918 updated++;
919
920 for (y = w->vscroll, rn = 0, row = w->current_matrix->rows;
921 y < yb && rn < nrows;
922 y += row->height, ++row, ++rn)
923 {
924 if (!row->redraw_fringe_bitmaps_p)
925 continue;
926 draw_row_fringe_bitmaps (w, row);
927 row->redraw_fringe_bitmaps_p = 0;
928 updated++;
929 }
930
931 return updated;
932 }
933
934
935 /* Recalculate the bitmaps to show in the fringes of window W.
936 Only mark rows with modified bitmaps for update in redraw_fringe_bitmaps_p.
937
938 If KEEP_CURRENT_P is 0, update current_matrix too. */
939
940 int
941 update_window_fringes (w, keep_current_p)
942 struct window *w;
943 int keep_current_p;
944 {
945 struct glyph_row *row, *cur = 0;
946 int yb = window_text_bottom_y (w);
947 int rn, nrows = w->current_matrix->nrows;
948 int y;
949 int redraw_p = 0;
950 Lisp_Object boundary_top = Qnil, boundary_bot = Qnil;
951 Lisp_Object arrow_top = Qnil, arrow_bot = Qnil;
952 Lisp_Object empty_pos;
953 Lisp_Object ind = Qnil;
954 #define MAX_BITMAP_CACHE (8*4)
955 int bitmap_cache[MAX_BITMAP_CACHE];
956 int top_ind_rn, bot_ind_rn;
957 int top_ind_min_y, bot_ind_max_y;
958 int top_row_ends_at_zv_p, bot_row_ends_at_zv_p;
959
960 if (w->pseudo_window_p)
961 return 0;
962
963 if (!MINI_WINDOW_P (w)
964 && (ind = XBUFFER (w->buffer)->indicate_buffer_boundaries, !NILP (ind)))
965 {
966 if (EQ (ind, Qleft) || EQ (ind, Qright))
967 boundary_top = boundary_bot = arrow_top = arrow_bot = ind;
968 else if (CONSP (ind) && CONSP (XCAR (ind)))
969 {
970 Lisp_Object pos;
971 if (pos = Fassq (Qt, ind), !NILP (pos))
972 boundary_top = boundary_bot = arrow_top = arrow_bot = XCDR (pos);
973 if (pos = Fassq (Qtop, ind), !NILP (pos))
974 boundary_top = XCDR (pos);
975 if (pos = Fassq (Qbottom, ind), !NILP (pos))
976 boundary_bot = XCDR (pos);
977 if (pos = Fassq (Qup, ind), !NILP (pos))
978 arrow_top = XCDR (pos);
979 if (pos = Fassq (Qdown, ind), !NILP (pos))
980 arrow_bot = XCDR (pos);
981 }
982 else
983 /* Anything else means boundary on left and no arrows. */
984 boundary_top = boundary_bot = Qleft;
985 }
986
987 top_ind_rn = bot_ind_rn = -1;
988 if (!NILP (ind))
989 {
990 for (y = w->vscroll, rn = 0;
991 y < yb && rn < nrows;
992 y += row->height, ++rn)
993 {
994 unsigned indicate_bob_p, indicate_top_line_p;
995 unsigned indicate_eob_p, indicate_bottom_line_p;
996
997 row = w->desired_matrix->rows + rn;
998 if (!row->enabled_p)
999 row = w->current_matrix->rows + rn;
1000
1001 indicate_bob_p = row->indicate_bob_p;
1002 indicate_top_line_p = row->indicate_top_line_p;
1003 indicate_eob_p = row->indicate_eob_p;
1004 indicate_bottom_line_p = row->indicate_bottom_line_p;
1005
1006 row->indicate_bob_p = row->indicate_top_line_p = 0;
1007 row->indicate_eob_p = row->indicate_bottom_line_p = 0;
1008
1009 if (!row->mode_line_p)
1010 {
1011 if (top_ind_rn < 0 && row->visible_height > 0)
1012 {
1013 if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer))
1014 && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
1015 row->indicate_bob_p = !NILP (boundary_top);
1016 else
1017 row->indicate_top_line_p = !NILP (arrow_top);
1018 top_ind_rn = rn;
1019 }
1020
1021 if (bot_ind_rn < 0)
1022 {
1023 if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer))
1024 && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row))
1025 row->indicate_eob_p = !NILP (boundary_bot), bot_ind_rn = rn;
1026 else if (y + row->height >= yb)
1027 row->indicate_bottom_line_p = !NILP (arrow_bot), bot_ind_rn = rn;
1028 }
1029 }
1030 }
1031 }
1032
1033 empty_pos = XBUFFER (w->buffer)->indicate_empty_lines;
1034 if (!NILP (empty_pos) && !EQ (empty_pos, Qright))
1035 empty_pos = WINDOW_LEFT_FRINGE_WIDTH (w) == 0 ? Qright : Qleft;
1036
1037 for (y = 0; y < MAX_BITMAP_CACHE; y++)
1038 bitmap_cache[y] = -1;
1039
1040 #define LEFT_FRINGE(cache, which, partial_p) \
1041 (bitmap_cache[cache*4+partial_p] >= 0 \
1042 ? bitmap_cache[cache*4+partial_p] \
1043 : (bitmap_cache[cache*4+partial_p] = \
1044 get_logical_fringe_bitmap (w, which, 0, partial_p)))
1045
1046 #define RIGHT_FRINGE(cache, which, partial_p) \
1047 (bitmap_cache[cache*4+2+partial_p] >= 0 \
1048 ? bitmap_cache[cache*4+2+partial_p] \
1049 : (bitmap_cache[cache*4+2+partial_p] = \
1050 get_logical_fringe_bitmap (w, which, 1, partial_p)))
1051
1052
1053 /* Extend top-aligned top indicator (or bottom-aligned bottom
1054 indicator) to adjacent rows if it doesn't fit in one row. */
1055 top_ind_min_y = bot_ind_max_y = -1;
1056 if (top_ind_rn >= 0)
1057 {
1058 int bn = NO_FRINGE_BITMAP;
1059
1060 row = w->desired_matrix->rows + top_ind_rn;
1061 if (!row->enabled_p)
1062 row = w->current_matrix->rows + top_ind_rn;
1063
1064 top_row_ends_at_zv_p = row->ends_at_zv_p;
1065 if (row->indicate_bob_p)
1066 {
1067 if (EQ (boundary_top, Qleft))
1068 bn = ((row->indicate_eob_p && EQ (boundary_bot, Qleft))
1069 ? LEFT_FRINGE (1, Qtop_bottom, row->ends_at_zv_p)
1070 : LEFT_FRINGE (2, Qtop, 0));
1071 else
1072 bn = ((row->indicate_eob_p && EQ (boundary_bot, Qright))
1073 ? RIGHT_FRINGE (1, Qtop_bottom, row->ends_at_zv_p)
1074 : RIGHT_FRINGE (2, Qtop, 0));
1075 }
1076 else if (row->indicate_top_line_p)
1077 {
1078 if (EQ (arrow_top, Qleft))
1079 bn = LEFT_FRINGE (6, Qup, 0);
1080 else
1081 bn = RIGHT_FRINGE (6, Qup, 0);
1082 }
1083
1084 if (bn != NO_FRINGE_BITMAP)
1085 {
1086 struct fringe_bitmap *fb;
1087
1088 fb = fringe_bitmaps[bn];
1089 if (fb == NULL)
1090 fb = &standard_bitmaps[bn < MAX_STANDARD_FRINGE_BITMAPS
1091 ? bn : UNDEF_FRINGE_BITMAP];
1092 if (fb->align == ALIGN_BITMAP_TOP && fb->period == 0)
1093 {
1094 struct glyph_row *row1;
1095 int top_ind_max_y;
1096
1097 top_ind_min_y = WINDOW_HEADER_LINE_HEIGHT (w);
1098 top_ind_max_y = top_ind_min_y + fb->height;
1099 if (top_ind_max_y > yb)
1100 top_ind_max_y = yb;
1101
1102 for (y = row->y + row->height, rn = top_ind_rn + 1;
1103 y < top_ind_max_y && rn < nrows;
1104 y += row1->height, rn++)
1105 {
1106 if (bot_ind_rn >= 0 && rn >= bot_ind_rn)
1107 break;
1108
1109 row1 = w->desired_matrix->rows + rn;
1110 if (!row1->enabled_p)
1111 row1 = w->current_matrix->rows + rn;
1112
1113 row1->indicate_bob_p = row->indicate_bob_p;
1114 row1->indicate_top_line_p = row->indicate_top_line_p;
1115 }
1116 }
1117 }
1118 }
1119 if (bot_ind_rn >= 0)
1120 {
1121 int bn = NO_FRINGE_BITMAP;
1122
1123 row = w->desired_matrix->rows + bot_ind_rn;
1124 if (!row->enabled_p)
1125 row = w->current_matrix->rows + bot_ind_rn;
1126
1127 bot_row_ends_at_zv_p = row->ends_at_zv_p;
1128 if (row->indicate_eob_p)
1129 {
1130 if (EQ (boundary_bot, Qleft))
1131 bn = LEFT_FRINGE (3, Qbottom, row->ends_at_zv_p);
1132 else
1133 bn = RIGHT_FRINGE (3, Qbottom, row->ends_at_zv_p);
1134 }
1135 else if (row->indicate_bottom_line_p)
1136 {
1137 if (EQ (arrow_bot, Qleft))
1138 bn = LEFT_FRINGE (7, Qdown, 0);
1139 else
1140 bn = RIGHT_FRINGE (7, Qdown, 0);
1141 }
1142
1143 if (bn != NO_FRINGE_BITMAP)
1144 {
1145 struct fringe_bitmap *fb;
1146
1147 fb = fringe_bitmaps[bn];
1148 if (fb == NULL)
1149 fb = &standard_bitmaps[bn < MAX_STANDARD_FRINGE_BITMAPS
1150 ? bn : UNDEF_FRINGE_BITMAP];
1151 if (fb->align == ALIGN_BITMAP_BOTTOM && fb->period == 0)
1152 {
1153 struct glyph_row *row1;
1154 int bot_ind_min_y;
1155
1156 bot_ind_max_y = row->y + row->visible_height;
1157 bot_ind_min_y = bot_ind_max_y - fb->height;
1158 if (bot_ind_min_y < WINDOW_HEADER_LINE_HEIGHT (w))
1159 bot_ind_min_y = WINDOW_HEADER_LINE_HEIGHT (w);
1160
1161 for (y = row->y, rn = bot_ind_rn - 1;
1162 y >= bot_ind_min_y && rn >= 0;
1163 y -= row1->height, rn--)
1164 {
1165 if (top_ind_rn >= 0 && rn <= top_ind_rn)
1166 break;
1167
1168 row1 = w->desired_matrix->rows + rn;
1169 if (!row1->enabled_p)
1170 row1 = w->current_matrix->rows + rn;
1171
1172 row1->indicate_eob_p = row->indicate_eob_p;
1173 row1->indicate_bottom_line_p = row->indicate_bottom_line_p;
1174 }
1175 }
1176 }
1177 }
1178
1179 for (y = w->vscroll, rn = 0;
1180 y < yb && rn < nrows;
1181 y += row->height, rn++)
1182 {
1183 int left, right;
1184 unsigned left_face_id, right_face_id;
1185 int left_offset, right_offset;
1186
1187 row = w->desired_matrix->rows + rn;
1188 cur = w->current_matrix->rows + rn;
1189 if (!row->enabled_p)
1190 row = cur;
1191
1192 left_face_id = right_face_id = DEFAULT_FACE_ID;
1193 left_offset = right_offset = 0;
1194
1195 /* Decide which bitmap to draw in the left fringe. */
1196 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
1197 left = NO_FRINGE_BITMAP;
1198 else if (row->left_user_fringe_bitmap != NO_FRINGE_BITMAP)
1199 {
1200 left = row->left_user_fringe_bitmap;
1201 left_face_id = row->left_user_fringe_face_id;
1202 }
1203 else if (row->truncated_on_left_p)
1204 left = LEFT_FRINGE(0, Qtruncation, 0);
1205 else if (row->indicate_bob_p && EQ (boundary_top, Qleft))
1206 {
1207 left = ((row->indicate_eob_p && EQ (boundary_bot, Qleft))
1208 ? LEFT_FRINGE (1, Qtop_bottom, top_row_ends_at_zv_p)
1209 : LEFT_FRINGE (2, Qtop, 0));
1210 if (top_ind_min_y >= 0)
1211 left_offset = top_ind_min_y - row->y;
1212 }
1213 else if (row->indicate_eob_p && EQ (boundary_bot, Qleft))
1214 {
1215 left = LEFT_FRINGE (3, Qbottom, bot_row_ends_at_zv_p);
1216 if (bot_ind_max_y >= 0)
1217 left_offset = bot_ind_max_y - (row->y + row->visible_height);
1218 }
1219 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
1220 left = LEFT_FRINGE (4, Qcontinuation, 0);
1221 else if (row->indicate_empty_line_p && EQ (empty_pos, Qleft))
1222 left = LEFT_FRINGE (5, Qempty_line, 0);
1223 else if (row->indicate_top_line_p && EQ (arrow_top, Qleft))
1224 {
1225 left = LEFT_FRINGE (6, Qup, 0);
1226 if (top_ind_min_y >= 0)
1227 left_offset = top_ind_min_y - row->y;
1228 }
1229 else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qleft))
1230 {
1231 left = LEFT_FRINGE (7, Qdown, 0);
1232 if (bot_ind_max_y >= 0)
1233 left_offset = bot_ind_max_y - (row->y + row->visible_height);
1234 }
1235 else
1236 left = NO_FRINGE_BITMAP;
1237
1238 /* Decide which bitmap to draw in the right fringe. */
1239 if (WINDOW_RIGHT_FRINGE_WIDTH (w) == 0)
1240 right = NO_FRINGE_BITMAP;
1241 else if (row->right_user_fringe_bitmap != NO_FRINGE_BITMAP)
1242 {
1243 right = row->right_user_fringe_bitmap;
1244 right_face_id = row->right_user_fringe_face_id;
1245 }
1246 else if (row->truncated_on_right_p)
1247 right = RIGHT_FRINGE (0, Qtruncation, 0);
1248 else if (row->indicate_bob_p && EQ (boundary_top, Qright))
1249 {
1250 right = ((row->indicate_eob_p && EQ (boundary_bot, Qright))
1251 ? RIGHT_FRINGE (1, Qtop_bottom, top_row_ends_at_zv_p)
1252 : RIGHT_FRINGE (2, Qtop, 0));
1253 if (top_ind_min_y >= 0)
1254 right_offset = top_ind_min_y - row->y;
1255 }
1256 else if (row->indicate_eob_p && EQ (boundary_bot, Qright))
1257 {
1258 right = RIGHT_FRINGE (3, Qbottom, bot_row_ends_at_zv_p);
1259 if (bot_ind_max_y >= 0)
1260 right_offset = bot_ind_max_y - (row->y + row->visible_height);
1261 }
1262 else if (row->continued_p)
1263 right = RIGHT_FRINGE (4, Qcontinuation, 0);
1264 else if (row->indicate_top_line_p && EQ (arrow_top, Qright))
1265 {
1266 right = RIGHT_FRINGE (6, Qup, 0);
1267 if (top_ind_min_y >= 0)
1268 right_offset = top_ind_min_y - row->y;
1269 }
1270 else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qright))
1271 {
1272 right = RIGHT_FRINGE (7, Qdown, 0);
1273 if (bot_ind_max_y >= 0)
1274 right_offset = bot_ind_max_y - (row->y + row->visible_height);
1275 }
1276 else if (row->indicate_empty_line_p && EQ (empty_pos, Qright))
1277 right = RIGHT_FRINGE (5, Qempty_line, 0);
1278 else
1279 right = NO_FRINGE_BITMAP;
1280
1281 if (row->y != cur->y
1282 || row->visible_height != cur->visible_height
1283 || row->ends_at_zv_p != cur->ends_at_zv_p
1284 || left != cur->left_fringe_bitmap
1285 || right != cur->right_fringe_bitmap
1286 || left_face_id != cur->left_fringe_face_id
1287 || right_face_id != cur->right_fringe_face_id
1288 || left_offset != cur->left_fringe_offset
1289 || right_offset != cur->right_fringe_offset
1290 || cur->redraw_fringe_bitmaps_p)
1291 {
1292 redraw_p = row->redraw_fringe_bitmaps_p = 1;
1293 if (!keep_current_p)
1294 {
1295 cur->redraw_fringe_bitmaps_p = 1;
1296 cur->left_fringe_bitmap = left;
1297 cur->right_fringe_bitmap = right;
1298 cur->left_fringe_face_id = left_face_id;
1299 cur->right_fringe_face_id = right_face_id;
1300 cur->left_fringe_offset = left_offset;
1301 cur->right_fringe_offset = right_offset;
1302 }
1303 }
1304
1305 if (row->overlay_arrow_bitmap < 0)
1306 row->overlay_arrow_bitmap = get_logical_fringe_bitmap (w, Qoverlay_arrow, 0, 0);
1307
1308 if (row->overlay_arrow_bitmap != cur->overlay_arrow_bitmap)
1309 {
1310 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
1311 cur->overlay_arrow_bitmap = row->overlay_arrow_bitmap;
1312 }
1313
1314 row->left_fringe_bitmap = left;
1315 row->right_fringe_bitmap = right;
1316 row->left_fringe_face_id = left_face_id;
1317 row->right_fringe_face_id = right_face_id;
1318 row->left_fringe_offset = left_offset;
1319 row->right_fringe_offset = right_offset;
1320 }
1321
1322 return redraw_p && !keep_current_p;
1323 }
1324
1325
1326 /* Compute actual fringe widths for frame F.
1327
1328 If REDRAW is 1, redraw F if the fringe settings was actually
1329 modified and F is visible.
1330
1331 Since the combined left and right fringe must occupy an integral
1332 number of columns, we may need to add some pixels to each fringe.
1333 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
1334 but a negative width value is taken literally (after negating it).
1335
1336 We never make the fringes narrower than specified.
1337 */
1338
1339 void
1340 compute_fringe_widths (f, redraw)
1341 struct frame *f;
1342 int redraw;
1343 {
1344 int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
1345 int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
1346 int o_cols = FRAME_FRINGE_COLS (f);
1347
1348 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
1349 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
1350 int left_fringe_width, right_fringe_width;
1351
1352 if (!NILP (left_fringe))
1353 left_fringe = Fcdr (left_fringe);
1354 if (!NILP (right_fringe))
1355 right_fringe = Fcdr (right_fringe);
1356
1357 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
1358 XINT (left_fringe));
1359 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
1360 XINT (right_fringe));
1361
1362 if (left_fringe_width || right_fringe_width)
1363 {
1364 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
1365 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
1366 int conf_wid = left_wid + right_wid;
1367 int font_wid = FRAME_COLUMN_WIDTH (f);
1368 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
1369 int real_wid = cols * font_wid;
1370 if (left_wid && right_wid)
1371 {
1372 if (left_fringe_width < 0)
1373 {
1374 /* Left fringe width is fixed, adjust right fringe if necessary */
1375 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
1376 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
1377 }
1378 else if (right_fringe_width < 0)
1379 {
1380 /* Right fringe width is fixed, adjust left fringe if necessary */
1381 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
1382 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
1383 }
1384 else
1385 {
1386 /* Adjust both fringes with an equal amount.
1387 Note that we are doing integer arithmetic here, so don't
1388 lose a pixel if the total width is an odd number. */
1389 int fill = real_wid - conf_wid;
1390 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
1391 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
1392 }
1393 }
1394 else if (left_fringe_width)
1395 {
1396 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
1397 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
1398 }
1399 else
1400 {
1401 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
1402 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
1403 }
1404 FRAME_FRINGE_COLS (f) = cols;
1405 }
1406 else
1407 {
1408 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
1409 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
1410 FRAME_FRINGE_COLS (f) = 0;
1411 }
1412
1413 if (redraw && FRAME_VISIBLE_P (f))
1414 if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
1415 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
1416 o_cols != FRAME_FRINGE_COLS (f))
1417 redraw_frame (f);
1418 }
1419
1420
1421 /* Free resources used by a user-defined bitmap. */
1422
1423 void
1424 destroy_fringe_bitmap (n)
1425 int n;
1426 {
1427 struct fringe_bitmap **fbp;
1428
1429 fringe_faces[n] = Qnil;
1430
1431 fbp = &fringe_bitmaps[n];
1432 if (*fbp && (*fbp)->dynamic)
1433 {
1434 /* XXX Is SELECTED_FRAME OK here? */
1435 struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
1436 if (rif && rif->destroy_fringe_bitmap)
1437 rif->destroy_fringe_bitmap (n);
1438 xfree (*fbp);
1439 *fbp = NULL;
1440 }
1441
1442 while (max_used_fringe_bitmap > MAX_STANDARD_FRINGE_BITMAPS
1443 && fringe_bitmaps[max_used_fringe_bitmap - 1] == NULL)
1444 max_used_fringe_bitmap--;
1445 }
1446
1447
1448 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap, Sdestroy_fringe_bitmap,
1449 1, 1, 0,
1450 doc: /* Destroy fringe bitmap BITMAP.
1451 If BITMAP overrides a standard fringe bitmap, the original bitmap is restored. */)
1452 (bitmap)
1453 Lisp_Object bitmap;
1454 {
1455 int n;
1456
1457 CHECK_SYMBOL (bitmap);
1458 n = lookup_fringe_bitmap (bitmap);
1459 if (!n)
1460 return Qnil;
1461
1462 destroy_fringe_bitmap (n);
1463
1464 if (n >= MAX_STANDARD_FRINGE_BITMAPS)
1465 {
1466 Vfringe_bitmaps = Fdelq (bitmap, Vfringe_bitmaps);
1467 /* It would be better to remove the fringe property. */
1468 Fput (bitmap, Qfringe, Qnil);
1469 }
1470
1471 return Qnil;
1472 }
1473
1474
1475 /* Initialize bitmap bit.
1476
1477 On X, we bit-swap the built-in bitmaps and reduce bitmap
1478 from short to char array if width is <= 8 bits.
1479
1480 On MAC with big-endian CPU, we need to byte-swap each short.
1481
1482 On W32 and MAC (little endian), there's no need to do this.
1483 */
1484
1485 #if defined (HAVE_X_WINDOWS)
1486 static const unsigned char swap_nibble[16] = {
1487 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1488 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1489 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1490 0x3, 0xb, 0x7, 0xf}; /* 0011 1011 0111 1111 */
1491 #endif /* HAVE_X_WINDOWS */
1492
1493 void
1494 init_fringe_bitmap (which, fb, once_p)
1495 int which;
1496 struct fringe_bitmap *fb;
1497 int once_p;
1498 {
1499 if (once_p || fb->dynamic)
1500 {
1501 #if defined (HAVE_X_WINDOWS)
1502 unsigned short *bits = fb->bits;
1503 int j;
1504
1505 if (fb->width <= 8)
1506 {
1507 unsigned char *cbits = (unsigned char *)fb->bits;
1508 for (j = 0; j < fb->height; j++)
1509 {
1510 unsigned short b = *bits++;
1511 unsigned char c;
1512 c = (unsigned char)((swap_nibble[b & 0xf] << 4)
1513 | (swap_nibble[(b>>4) & 0xf]));
1514 *cbits++ = (c >> (8 - fb->width));
1515 }
1516 }
1517 else
1518 {
1519 for (j = 0; j < fb->height; j++)
1520 {
1521 unsigned short b = *bits;
1522 b = (unsigned short)((swap_nibble[b & 0xf] << 12)
1523 | (swap_nibble[(b>>4) & 0xf] << 8)
1524 | (swap_nibble[(b>>8) & 0xf] << 4)
1525 | (swap_nibble[(b>>12) & 0xf]));
1526 b >>= (16 - fb->width);
1527 #ifdef WORDS_BIG_ENDIAN
1528 b = ((b >> 8) | (b << 8));
1529 #endif
1530 *bits++ = b;
1531 }
1532 }
1533 #endif /* HAVE_X_WINDOWS */
1534
1535 }
1536
1537 if (!once_p)
1538 {
1539 /* XXX Is SELECTED_FRAME OK here? */
1540 struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
1541
1542 destroy_fringe_bitmap (which);
1543
1544 if (rif && rif->define_fringe_bitmap)
1545 rif->define_fringe_bitmap (which, fb->bits, fb->height, fb->width);
1546
1547 fringe_bitmaps[which] = fb;
1548 if (which >= max_used_fringe_bitmap)
1549 max_used_fringe_bitmap = which + 1;
1550 }
1551 }
1552
1553
1554 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap,
1555 2, 5, 0,
1556 doc: /* Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH.
1557 BITMAP is a symbol identifying the new fringe bitmap.
1558 BITS is either a string or a vector of integers.
1559 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1560 WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1561 Optional fifth arg ALIGN may be one of `top', `center', or `bottom',
1562 indicating the positioning of the bitmap relative to the rows where it
1563 is used; the default is to center the bitmap. Fifth arg may also be a
1564 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1565 should be repeated.
1566 If BITMAP already exists, the existing definition is replaced. */)
1567 (bitmap, bits, height, width, align)
1568 Lisp_Object bitmap, bits, height, width, align;
1569 {
1570 int n, h, i, j;
1571 unsigned short *b;
1572 struct fringe_bitmap fb, *xfb;
1573 int fill1 = 0, fill2 = 0;
1574
1575 CHECK_SYMBOL (bitmap);
1576
1577 if (STRINGP (bits))
1578 h = SCHARS (bits);
1579 else if (VECTORP (bits))
1580 h = XVECTOR (bits)->size;
1581 else
1582 wrong_type_argument (Qsequencep, bits);
1583
1584 if (NILP (height))
1585 fb.height = h;
1586 else
1587 {
1588 CHECK_NUMBER (height);
1589 fb.height = min (XINT (height), 255);
1590 if (fb.height > h)
1591 {
1592 fill1 = (fb.height - h) / 2;
1593 fill2 = fb.height - h - fill1;
1594 }
1595 }
1596
1597 if (NILP (width))
1598 fb.width = 8;
1599 else
1600 {
1601 CHECK_NUMBER (width);
1602 fb.width = min (XINT (width), 255);
1603 }
1604
1605 fb.period = 0;
1606 fb.align = ALIGN_BITMAP_CENTER;
1607
1608 if (CONSP (align))
1609 {
1610 Lisp_Object period = XCDR (align);
1611 if (CONSP (period))
1612 {
1613 period = XCAR (period);
1614 if (!NILP (period))
1615 {
1616 fb.period = fb.height;
1617 fb.height = 255;
1618 }
1619 }
1620 align = XCAR (align);
1621 }
1622 if (EQ (align, Qtop))
1623 fb.align = ALIGN_BITMAP_TOP;
1624 else if (EQ (align, Qbottom))
1625 fb.align = ALIGN_BITMAP_BOTTOM;
1626 else if (!NILP (align) && !EQ (align, Qcenter))
1627 error ("Bad align argument");
1628
1629 n = lookup_fringe_bitmap (bitmap);
1630 if (!n)
1631 {
1632 if (max_used_fringe_bitmap < max_fringe_bitmaps)
1633 n = max_used_fringe_bitmap++;
1634 else
1635 {
1636 for (n = MAX_STANDARD_FRINGE_BITMAPS;
1637 n < max_fringe_bitmaps;
1638 n++)
1639 if (fringe_bitmaps[n] == NULL)
1640 break;
1641
1642 if (n == max_fringe_bitmaps)
1643 {
1644 if ((max_fringe_bitmaps + 20) > MAX_FRINGE_BITMAPS)
1645 error ("No free fringe bitmap slots");
1646
1647 i = max_fringe_bitmaps;
1648 max_fringe_bitmaps += 20;
1649 fringe_bitmaps
1650 = ((struct fringe_bitmap **)
1651 xrealloc (fringe_bitmaps, max_fringe_bitmaps * sizeof (struct fringe_bitmap *)));
1652 fringe_faces
1653 = (Lisp_Object *) xrealloc (fringe_faces, max_fringe_bitmaps * sizeof (Lisp_Object));
1654
1655 for (; i < max_fringe_bitmaps; i++)
1656 {
1657 fringe_bitmaps[i] = NULL;
1658 fringe_faces[i] = Qnil;
1659 }
1660 }
1661 }
1662
1663 Vfringe_bitmaps = Fcons (bitmap, Vfringe_bitmaps);
1664 Fput (bitmap, Qfringe, make_number (n));
1665 }
1666
1667 fb.dynamic = 1;
1668
1669 xfb = (struct fringe_bitmap *) xmalloc (sizeof fb
1670 + fb.height * BYTES_PER_BITMAP_ROW);
1671 fb.bits = b = (unsigned short *) (xfb + 1);
1672 bzero (b, fb.height);
1673
1674 j = 0;
1675 while (j < fb.height)
1676 {
1677 for (i = 0; i < fill1 && j < fb.height; i++)
1678 b[j++] = 0;
1679 for (i = 0; i < h && j < fb.height; i++)
1680 {
1681 Lisp_Object elt = Faref (bits, make_number (i));
1682 b[j++] = NUMBERP (elt) ? XINT (elt) : 0;
1683 }
1684 for (i = 0; i < fill2 && j < fb.height; i++)
1685 b[j++] = 0;
1686 }
1687
1688 *xfb = fb;
1689
1690 init_fringe_bitmap (n, xfb, 0);
1691
1692 return bitmap;
1693 }
1694
1695 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face,
1696 1, 2, 0,
1697 doc: /* Set face for fringe bitmap BITMAP to FACE.
1698 If FACE is nil, reset face to default fringe face. */)
1699 (bitmap, face)
1700 Lisp_Object bitmap, face;
1701 {
1702 int n;
1703 int face_id;
1704
1705 CHECK_SYMBOL (bitmap);
1706 n = lookup_fringe_bitmap (bitmap);
1707 if (!n)
1708 error ("Undefined fringe bitmap");
1709
1710 if (!NILP (face))
1711 {
1712 face_id = lookup_derived_face (SELECTED_FRAME (), face,
1713 FRINGE_FACE_ID, 1);
1714 if (face_id < 0)
1715 error ("No such face");
1716 }
1717
1718 fringe_faces[n] = face;
1719
1720 return Qnil;
1721 }
1722
1723 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos, Sfringe_bitmaps_at_pos,
1724 0, 2, 0,
1725 doc: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1726 If WINDOW is nil, use selected window. If POS is nil, use value of point
1727 in that window. Return value is a list (LEFT RIGHT OV), where LEFT
1728 is the symbol for the bitmap in the left fringe (or nil if no bitmap),
1729 RIGHT is similar for the right fringe, and OV is non-nil if there is an
1730 overlay arrow in the left fringe.
1731 Return nil if POS is not visible in WINDOW. */)
1732 (pos, window)
1733 Lisp_Object pos, window;
1734 {
1735 struct window *w;
1736 struct glyph_row *row;
1737 int textpos;
1738
1739 if (NILP (window))
1740 window = selected_window;
1741 CHECK_WINDOW (window);
1742 w = XWINDOW (window);
1743
1744 if (!NILP (pos))
1745 {
1746 CHECK_NUMBER_COERCE_MARKER (pos);
1747 textpos = XINT (pos);
1748 }
1749 else if (w == XWINDOW (selected_window))
1750 textpos = PT;
1751 else
1752 textpos = XMARKER (w->pointm)->charpos;
1753
1754 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1755 row = row_containing_pos (w, textpos, row, NULL, 0);
1756 if (row)
1757 return list3 (get_fringe_bitmap_name (row->left_fringe_bitmap),
1758 get_fringe_bitmap_name (row->right_fringe_bitmap),
1759 (row->overlay_arrow_bitmap == 0 ? Qnil
1760 : row->overlay_arrow_bitmap < 0 ? Qt
1761 : get_fringe_bitmap_name (row->overlay_arrow_bitmap)));
1762 else
1763 return Qnil;
1764 }
1765
1766
1767 /***********************************************************************
1768 Initialization
1769 ***********************************************************************/
1770
1771 void
1772 syms_of_fringe ()
1773 {
1774 Qtruncation = intern_c_string ("truncation");
1775 staticpro (&Qtruncation);
1776 Qcontinuation = intern_c_string ("continuation");
1777 staticpro (&Qcontinuation);
1778 Qoverlay_arrow = intern_c_string ("overlay-arrow");
1779 staticpro (&Qoverlay_arrow);
1780 Qempty_line = intern_c_string ("empty-line");
1781 staticpro (&Qempty_line);
1782 Qtop_bottom = intern_c_string ("top-bottom");
1783 staticpro (&Qtop_bottom);
1784 Qhollow_small = intern_c_string ("hollow-small");
1785 staticpro (&Qhollow_small);
1786
1787 defsubr (&Sdestroy_fringe_bitmap);
1788 defsubr (&Sdefine_fringe_bitmap);
1789 defsubr (&Sfringe_bitmaps_at_pos);
1790 defsubr (&Sset_fringe_bitmap_face);
1791
1792 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe,
1793 doc: /* *Non-nil means that newline may flow into the right fringe.
1794 This means that display lines which are exactly as wide as the window
1795 (not counting the final newline) will only occupy one screen line, by
1796 showing (or hiding) the final newline in the right fringe; when point
1797 is at the final newline, the cursor is shown in the right fringe.
1798 If nil, also continue lines which are exactly as wide as the window. */);
1799 Voverflow_newline_into_fringe = Qt;
1800
1801 DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps,
1802 doc: /* List of fringe bitmap symbols. */);
1803 Vfringe_bitmaps = Qnil;
1804 }
1805
1806 /* Garbage collection hook */
1807
1808 void
1809 mark_fringe_data ()
1810 {
1811 int i;
1812
1813 for (i = 0; i < max_fringe_bitmaps; i++)
1814 if (!NILP (fringe_faces[i]))
1815 mark_object (fringe_faces[i]);
1816 }
1817
1818 /* Initialize this module when Emacs starts. */
1819
1820 void
1821 init_fringe_once ()
1822 {
1823 int bt;
1824
1825 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1826 init_fringe_bitmap(bt, &standard_bitmaps[bt], 1);
1827 }
1828
1829 void
1830 init_fringe ()
1831 {
1832 int i;
1833
1834 max_fringe_bitmaps = MAX_STANDARD_FRINGE_BITMAPS + 20;
1835
1836 fringe_bitmaps
1837 = (struct fringe_bitmap **) xmalloc (max_fringe_bitmaps * sizeof (struct fringe_bitmap *));
1838 fringe_faces
1839 = (Lisp_Object *) xmalloc (max_fringe_bitmaps * sizeof (Lisp_Object));
1840
1841 for (i = 0; i < max_fringe_bitmaps; i++)
1842 {
1843 fringe_bitmaps[i] = NULL;
1844 fringe_faces[i] = Qnil;
1845 }
1846 }
1847
1848 #ifdef HAVE_NTGUI
1849
1850 void
1851 w32_init_fringe (struct redisplay_interface *rif)
1852 {
1853 int bt;
1854
1855 if (!rif)
1856 return;
1857
1858 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1859 {
1860 struct fringe_bitmap *fb = &standard_bitmaps[bt];
1861 rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
1862 }
1863 }
1864
1865 void
1866 w32_reset_fringes ()
1867 {
1868 /* Destroy row bitmaps. */
1869 int bt;
1870 struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
1871
1872 if (!rif)
1873 return;
1874
1875 for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++)
1876 rif->destroy_fringe_bitmap (bt);
1877 }
1878
1879 #endif /* HAVE_NTGUI */
1880
1881 #endif /* HAVE_WINDOW_SYSTEM */
1882
1883 /* arch-tag: 04596920-43eb-473d-b319-82712338162d
1884 (do not change this comment) */