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