]> code.delx.au - gnu-emacs/blob - src/fringe.c
Update years in copyright notice; nfc.
[gnu-emacs] / 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, 2000, 2001, 2002, 2003, 2004,
4 2005 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 2, or (at your option)
11 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; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
22
23 #include <config.h>
24 #include <stdio.h>
25
26 #include "lisp.h"
27 #include "frame.h"
28 #include "window.h"
29 #include "dispextern.h"
30 #include "buffer.h"
31 #include "blockinput.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 enum fringe_bitmap_type
53 {
54 NO_FRINGE_BITMAP = 0,
55 UNDEF_FRINGE_BITMAP,
56 LEFT_TRUNCATION_BITMAP,
57 RIGHT_TRUNCATION_BITMAP,
58 UP_ARROW_BITMAP,
59 DOWN_ARROW_BITMAP,
60 CONTINUED_LINE_BITMAP,
61 CONTINUATION_LINE_BITMAP,
62 OVERLAY_ARROW_BITMAP,
63 TOP_LEFT_ANGLE_BITMAP,
64 TOP_RIGHT_ANGLE_BITMAP,
65 BOTTOM_LEFT_ANGLE_BITMAP,
66 BOTTOM_RIGHT_ANGLE_BITMAP,
67 LEFT_BRACKET_BITMAP,
68 RIGHT_BRACKET_BITMAP,
69 FILLED_BOX_CURSOR_BITMAP,
70 HOLLOW_BOX_CURSOR_BITMAP,
71 HOLLOW_SQUARE_BITMAP,
72 BAR_CURSOR_BITMAP,
73 HBAR_CURSOR_BITMAP,
74 ZV_LINE_BITMAP,
75 MAX_STANDARD_FRINGE_BITMAPS
76 };
77
78 enum fringe_bitmap_align
79 {
80 ALIGN_BITMAP_CENTER = 0,
81 ALIGN_BITMAP_TOP,
82 ALIGN_BITMAP_BOTTOM
83 };
84
85 struct fringe_bitmap
86 {
87 unsigned short *bits;
88 unsigned height : 8;
89 unsigned width : 8;
90 unsigned period : 8;
91 unsigned align : 2;
92 unsigned dynamic : 1;
93 };
94
95 \f
96 /***********************************************************************
97 Fringe bitmaps
98 ***********************************************************************/
99
100 /* Undefined bitmap. A question mark. */
101 /*
102 ..xxxx..
103 .xxxxxx.
104 xx....xx
105 xx....xx
106 ....xx..
107 ...xx...
108 ...xx...
109 ........
110 ...xx...
111 ...xx...
112 */
113 static unsigned short unknown_bits[] = {
114 0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
115
116 /* An arrow like this: `<-'. */
117 /*
118 ...xx...
119 ..xx....
120 .xx.....
121 xxxxxx..
122 xxxxxx..
123 .xx.....
124 ..xx....
125 ...xx...
126 */
127 static unsigned short left_arrow_bits[] = {
128 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
129
130
131 /* Right truncation arrow bitmap `->'. */
132 /*
133 ...xx...
134 ....xx..
135 .....xx.
136 ..xxxxxx
137 ..xxxxxx
138 .....xx.
139 ....xx..
140 ...xx...
141 */
142 static unsigned short right_arrow_bits[] = {
143 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
144
145
146 /* Up arrow bitmap. */
147 /*
148 ...xx...
149 ..xxxx..
150 .xxxxxx.
151 xxxxxxxx
152 ...xx...
153 ...xx...
154 ...xx...
155 ...xx...
156 */
157 static unsigned short up_arrow_bits[] = {
158 0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
159
160
161 /* Down arrow bitmap. */
162 /*
163 ...xx...
164 ...xx...
165 ...xx...
166 ...xx...
167 xxxxxxxx
168 .xxxxxx.
169 ..xxxx..
170 ...xx...
171 */
172 static unsigned short down_arrow_bits[] = {
173 0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
174
175 /* Marker for continued lines. */
176 /*
177 ..xxxx..
178 ..xxxxx.
179 ......xx
180 ..x..xxx
181 ..xxxxxx
182 ..xxxxx.
183 ..xxxx..
184 ..xxxxx.
185 */
186 static unsigned short continued_bits[] = {
187 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
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 continuation_bits[] = {
201 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
202
203 /* Overlay arrow bitmap. A triangular arrow. */
204 /*
205 xx......
206 xxxx....
207 xxxxx...
208 xxxxxx..
209 xxxxxx..
210 xxxxx...
211 xxxx....
212 xx......
213 */
214 static unsigned short ov_bits[] = {
215 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
216
217 #if 0
218 /* Reverse Overlay arrow bitmap. A triangular arrow. */
219 /*
220 ......xx
221 ....xxxx
222 ...xxxxx
223 ..xxxxxx
224 ..xxxxxx
225 ...xxxxx
226 ....xxxx
227 ......xx
228 */
229 static unsigned short rev_ov_bits[] = {
230 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
231 #endif
232
233 /* First line bitmap. An top-left angle. */
234 /*
235 xxxxxx..
236 xxxxxx..
237 xx......
238 xx......
239 xx......
240 xx......
241 xx......
242 ........
243 */
244 static unsigned short top_left_angle_bits[] = {
245 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00};
246
247 /* First line bitmap. An right-up angle. */
248 /*
249 ..xxxxxx
250 ..xxxxxx
251 ......xx
252 ......xx
253 ......xx
254 ......xx
255 ......xx
256 ........
257 */
258 static unsigned short top_right_angle_bits[] = {
259 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
260
261 /* Last line bitmap. An left-down angle. */
262 /*
263 ........
264 xx......
265 xx......
266 xx......
267 xx......
268 xx......
269 xxxxxx..
270 xxxxxx..
271 */
272 static unsigned short bottom_left_angle_bits[] = {
273 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
274
275 /* Last line bitmap. An right-down angle. */
276 /*
277 ........
278 ......xx
279 ......xx
280 ......xx
281 ......xx
282 ......xx
283 ..xxxxxx
284 ..xxxxxx
285 */
286 static unsigned short bottom_right_angle_bits[] = {
287 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
288
289 /* First/last line bitmap. An left bracket. */
290 /*
291 xxxxxx..
292 xxxxxx..
293 xx......
294 xx......
295 xx......
296 xx......
297 xx......
298 xx......
299 xxxxxx..
300 xxxxxx..
301 */
302 static unsigned short left_bracket_bits[] = {
303 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
304
305 /* First/last line bitmap. An right bracket. */
306 /*
307 ..xxxxxx
308 ..xxxxxx
309 ......xx
310 ......xx
311 ......xx
312 ......xx
313 ......xx
314 ......xx
315 ..xxxxxx
316 ..xxxxxx
317 */
318 static unsigned short right_bracket_bits[] = {
319 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
320
321 /* Filled box cursor bitmap. A filled box; max 13 pixels high. */
322 /*
323 xxxxxxx.
324 xxxxxxx.
325 xxxxxxx.
326 xxxxxxx.
327 xxxxxxx.
328 xxxxxxx.
329 xxxxxxx.
330 xxxxxxx.
331 xxxxxxx.
332 xxxxxxx.
333 xxxxxxx.
334 xxxxxxx.
335 xxxxxxx.
336 */
337 static unsigned short filled_box_cursor_bits[] = {
338 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
339
340 /* Hollow box cursor bitmap. A hollow box; max 13 pixels high. */
341 /*
342 xxxxxxx.
343 x.....x.
344 x.....x.
345 x.....x.
346 x.....x.
347 x.....x.
348 x.....x.
349 x.....x.
350 x.....x.
351 x.....x.
352 x.....x.
353 x.....x.
354 xxxxxxx.
355 */
356 static unsigned short hollow_box_cursor_bits[] = {
357 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe};
358
359 /* Bar cursor bitmap. A vertical bar; max 13 pixels high. */
360 /*
361 xx......
362 xx......
363 xx......
364 xx......
365 xx......
366 xx......
367 xx......
368 xx......
369 xx......
370 xx......
371 xx......
372 xx......
373 xx......
374 */
375 static unsigned short bar_cursor_bits[] = {
376 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
377
378 /* HBar cursor bitmap. A horisontal bar; 2 pixels high. */
379 /*
380 xxxxxxx.
381 xxxxxxx.
382 */
383 static unsigned short hbar_cursor_bits[] = {
384 0xfe, 0xfe};
385
386
387 /* Bitmap drawn to indicate lines not displaying text if
388 `indicate-empty-lines' is non-nil. */
389 /*
390 ........
391 ..xxxx..
392 ........
393 ........
394 ..xxxx..
395 ........
396 */
397 static unsigned short zv_bits[] = {
398 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
399 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
400 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
401 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
402 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
403 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
404 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
405 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
406
407 /* Hollow square bitmap. */
408 /*
409 .xxxxxx.
410 .x....x.
411 .x....x.
412 .x....x.
413 .x....x.
414 .xxxxxx.
415 */
416 static unsigned short hollow_square_bits[] = {
417 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
418
419
420 #define BYTES_PER_BITMAP_ROW (sizeof (unsigned short))
421 #define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
422 #define FRBITS(bits) bits, STANDARD_BITMAP_HEIGHT (bits)
423
424 struct fringe_bitmap standard_bitmaps[MAX_STANDARD_FRINGE_BITMAPS] =
425 {
426 { NULL, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */
427 { FRBITS (unknown_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
428 { FRBITS (left_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
429 { FRBITS (right_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
430 { FRBITS (up_arrow_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
431 { FRBITS (down_arrow_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
432 { FRBITS (continued_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
433 { FRBITS (continuation_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
434 { FRBITS (ov_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
435 { FRBITS (top_left_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
436 { FRBITS (top_right_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
437 { FRBITS (bottom_left_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
438 { FRBITS (bottom_right_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
439 { FRBITS (left_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
440 { FRBITS (right_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
441 { FRBITS (filled_box_cursor_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
442 { FRBITS (hollow_box_cursor_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
443 { FRBITS (hollow_square_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
444 { FRBITS (bar_cursor_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
445 { FRBITS (hbar_cursor_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
446 { FRBITS (zv_bits), 8, 3, ALIGN_BITMAP_TOP, 0 },
447 };
448
449 static struct fringe_bitmap **fringe_bitmaps;
450 static Lisp_Object *fringe_faces;
451 static int max_fringe_bitmaps;
452
453 static int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS;
454
455
456 /* Lookup bitmap number for symbol BITMAP.
457 Return 0 if not a bitmap. */
458
459 int
460 lookup_fringe_bitmap (bitmap)
461 Lisp_Object bitmap;
462 {
463 int bn;
464
465 bitmap = Fget (bitmap, Qfringe);
466 if (!INTEGERP (bitmap))
467 return 0;
468
469 bn = XINT (bitmap);
470 if (bn > NO_FRINGE_BITMAP
471 && bn < max_used_fringe_bitmap
472 && (bn < MAX_STANDARD_FRINGE_BITMAPS
473 || fringe_bitmaps[bn] != NULL))
474 return bn;
475
476 return 0;
477 }
478
479 /* Get fringe bitmap name for bitmap number BN.
480
481 Found by traversing Vfringe_bitmaps comparing BN to the
482 fringe property for each symbol.
483
484 Return BN if not found in Vfringe_bitmaps. */
485
486 static Lisp_Object
487 get_fringe_bitmap_name (bn)
488 int bn;
489 {
490 Lisp_Object bitmaps;
491 Lisp_Object num;
492
493 /* Zero means no bitmap -- return nil. */
494 if (bn <= 0)
495 return Qnil;
496
497 bitmaps = Vfringe_bitmaps;
498 num = make_number (bn);
499
500 while (CONSP (bitmaps))
501 {
502 Lisp_Object bitmap = XCAR (bitmaps);
503 if (EQ (num, Fget (bitmap, Qfringe)))
504 return bitmap;
505 bitmaps = XCDR (bitmaps);
506 }
507
508 return num;
509 }
510
511
512 /* Draw the bitmap WHICH in one of the left or right fringes of
513 window W. ROW is the glyph row for which to display the bitmap; it
514 determines the vertical position at which the bitmap has to be
515 drawn.
516 LEFT_P is 1 for left fringe, 0 for right fringe.
517 */
518
519 void
520 draw_fringe_bitmap_1 (w, row, left_p, overlay, which)
521 struct window *w;
522 struct glyph_row *row;
523 int left_p, overlay;
524 enum fringe_bitmap_type which;
525 {
526 struct frame *f = XFRAME (WINDOW_FRAME (w));
527 struct draw_fringe_bitmap_params p;
528 struct fringe_bitmap *fb;
529 int period;
530 int face_id = DEFAULT_FACE_ID;
531
532 p.cursor_p = 0;
533 p.overlay_p = (overlay & 1) == 1;
534 p.cursor_p = (overlay & 2) == 2;
535
536 if (which != NO_FRINGE_BITMAP)
537 {
538 }
539 else if (left_p)
540 {
541 which = row->left_fringe_bitmap;
542 face_id = row->left_fringe_face_id;
543 }
544 else
545 {
546 which = row->right_fringe_bitmap;
547 face_id = row->right_fringe_face_id;
548 }
549
550 if (face_id == DEFAULT_FACE_ID)
551 {
552 Lisp_Object face;
553
554 if ((face = fringe_faces[which], NILP (face))
555 || (face_id = lookup_derived_face (f, face, 'A', FRINGE_FACE_ID, 0),
556 face_id < 0))
557 face_id = FRINGE_FACE_ID;
558 }
559
560 fb = fringe_bitmaps[which];
561 if (fb == NULL)
562 fb = &standard_bitmaps[which < MAX_STANDARD_FRINGE_BITMAPS
563 ? which : UNDEF_FRINGE_BITMAP];
564
565 period = fb->period;
566
567 /* Convert row to frame coordinates. */
568 p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
569
570 p.which = which;
571 p.bits = fb->bits;
572 p.wd = fb->width;
573
574 p.h = fb->height;
575 p.dh = (period > 0 ? (p.y % period) : 0);
576 p.h -= p.dh;
577 /* Clip bitmap if too high. */
578 if (p.h > row->height)
579 p.h = row->height;
580
581 p.face = FACE_FROM_ID (f, face_id);
582
583 if (p.face == NULL)
584 {
585 /* This could happen after clearing face cache.
586 But it shouldn't happen anymore. ++kfs */
587 return;
588 }
589
590 PREPARE_FACE_FOR_DISPLAY (f, p.face);
591
592 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
593 the fringe. */
594 p.bx = -1;
595 if (left_p)
596 {
597 int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
598 int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
599 ? LEFT_MARGIN_AREA
600 : TEXT_AREA));
601 if (p.wd > wd)
602 p.wd = wd;
603 p.x = x - p.wd - (wd - p.wd) / 2;
604
605 if (p.wd < wd || row->height > p.h)
606 {
607 /* If W has a vertical border to its left, don't draw over it. */
608 wd -= ((!WINDOW_LEFTMOST_P (w)
609 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
610 ? 1 : 0);
611 p.bx = x - wd;
612 p.nx = wd;
613 }
614 }
615 else
616 {
617 int x = window_box_right (w,
618 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
619 ? RIGHT_MARGIN_AREA
620 : TEXT_AREA));
621 int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
622 if (p.wd > wd)
623 p.wd = wd;
624 p.x = x + (wd - p.wd) / 2;
625 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
626 the fringe. */
627 if (p.wd < wd || row->height > p.h)
628 {
629 p.bx = x;
630 p.nx = wd;
631 }
632 }
633
634 if (p.bx >= 0)
635 {
636 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
637
638 p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
639 p.ny = row->visible_height;
640 }
641
642 /* Adjust y to the offset in the row to start drawing the bitmap. */
643 switch (fb->align)
644 {
645 case ALIGN_BITMAP_CENTER:
646 p.y += (row->height - p.h) / 2;
647 break;
648 case ALIGN_BITMAP_BOTTOM:
649 p.h = fb->height;
650 p.y += (row->visible_height - p.h);
651 break;
652 case ALIGN_BITMAP_TOP:
653 break;
654 }
655
656 rif->draw_fringe_bitmap (w, row, &p);
657 }
658
659 void
660 draw_fringe_bitmap (w, row, left_p)
661 struct window *w;
662 struct glyph_row *row;
663 int left_p;
664 {
665 int overlay = 0;
666
667 if (!left_p && row->cursor_in_fringe_p)
668 {
669 int cursor = NO_FRINGE_BITMAP;
670
671 switch (w->phys_cursor_type)
672 {
673 case HOLLOW_BOX_CURSOR:
674 if (row->visible_height >= STANDARD_BITMAP_HEIGHT (hollow_box_cursor_bits))
675 cursor = HOLLOW_BOX_CURSOR_BITMAP;
676 else
677 cursor = HOLLOW_SQUARE_BITMAP;
678 break;
679 case FILLED_BOX_CURSOR:
680 cursor = FILLED_BOX_CURSOR_BITMAP;
681 break;
682 case BAR_CURSOR:
683 cursor = BAR_CURSOR_BITMAP;
684 break;
685 case HBAR_CURSOR:
686 cursor = HBAR_CURSOR_BITMAP;
687 break;
688 case NO_CURSOR:
689 default:
690 w->phys_cursor_on_p = 0;
691 row->cursor_in_fringe_p = 0;
692 break;
693 }
694 if (cursor != NO_FRINGE_BITMAP)
695 {
696 draw_fringe_bitmap_1 (w, row, 0, 2, cursor);
697 overlay = cursor == FILLED_BOX_CURSOR_BITMAP ? 3 : 1;
698 }
699 }
700
701 draw_fringe_bitmap_1 (w, row, left_p, overlay, NO_FRINGE_BITMAP);
702
703 if (left_p && row->overlay_arrow_bitmap != NO_FRINGE_BITMAP)
704 draw_fringe_bitmap_1 (w, row, 1, 1,
705 (row->overlay_arrow_bitmap < 0
706 ? OVERLAY_ARROW_BITMAP
707 : row->overlay_arrow_bitmap));
708 }
709
710
711 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
712 function with input blocked. */
713
714 void
715 draw_row_fringe_bitmaps (w, row)
716 struct window *w;
717 struct glyph_row *row;
718 {
719 xassert (interrupt_input_blocked);
720
721 /* If row is completely invisible, because of vscrolling, we
722 don't have to draw anything. */
723 if (row->visible_height <= 0)
724 return;
725
726 if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
727 draw_fringe_bitmap (w, row, 1);
728
729 if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
730 draw_fringe_bitmap (w, row, 0);
731 }
732
733 /* Draw the fringes of window W. Only fringes for rows marked for
734 update in redraw_fringe_bitmaps_p are drawn.
735
736 Return >0 if left or right fringe was redrawn in any way.
737
738 If NO_FRINGE is non-zero, also return >0 if either fringe has zero width.
739
740 A return value >0 indicates that the vertical line between windows
741 needs update (as it may be drawn in the fringe).
742 */
743
744 int
745 draw_window_fringes (w, no_fringe)
746 struct window *w;
747 int no_fringe;
748 {
749 struct glyph_row *row;
750 int yb = window_text_bottom_y (w);
751 int nrows = w->current_matrix->nrows;
752 int y = 0, rn;
753 int updated = 0;
754
755 if (w->pseudo_window_p)
756 return 0;
757
758 /* Must draw line if no fringe */
759 if (no_fringe
760 && (WINDOW_LEFT_FRINGE_WIDTH (w) == 0
761 || WINDOW_RIGHT_FRINGE_WIDTH (w) == 0))
762 updated++;
763
764 for (y = 0, rn = 0, row = w->current_matrix->rows;
765 y < yb && rn < nrows;
766 y += row->height, ++row, ++rn)
767 {
768 if (!row->redraw_fringe_bitmaps_p)
769 continue;
770 draw_row_fringe_bitmaps (w, row);
771 row->redraw_fringe_bitmaps_p = 0;
772 updated++;
773 }
774
775 return updated;
776 }
777
778
779 /* Recalculate the bitmaps to show in the fringes of window W.
780 If FORCE_P is 0, only mark rows with modified bitmaps for update in
781 redraw_fringe_bitmaps_p; else mark all rows for update. */
782
783 int
784 update_window_fringes (w, force_p)
785 struct window *w;
786 int force_p;
787 {
788 struct glyph_row *row, *cur = 0;
789 int yb = window_text_bottom_y (w);
790 int rn, nrows = w->current_matrix->nrows;
791 int y;
792 int redraw_p = 0;
793 Lisp_Object boundary_top = Qnil, boundary_bot = Qnil;
794 Lisp_Object arrow_top = Qnil, arrow_bot = Qnil;
795 Lisp_Object empty_pos;
796 Lisp_Object ind = Qnil;
797
798 if (w->pseudo_window_p)
799 return 0;
800
801 if (!MINI_WINDOW_P (w)
802 && (ind = XBUFFER (w->buffer)->indicate_buffer_boundaries, !NILP (ind)))
803 {
804 if (EQ (ind, Qleft) || EQ (ind, Qright))
805 boundary_top = boundary_bot = arrow_top = arrow_bot = ind;
806 else if (CONSP (ind) && CONSP (XCAR (ind)))
807 {
808 Lisp_Object pos;
809 if (pos = Fassq (Qt, ind), !NILP (pos))
810 boundary_top = boundary_bot = arrow_top = arrow_bot = XCDR (pos);
811 if (pos = Fassq (Qtop, ind), !NILP (pos))
812 boundary_top = XCDR (pos);
813 if (pos = Fassq (Qbottom, ind), !NILP (pos))
814 boundary_bot = XCDR (pos);
815 if (pos = Fassq (Qup, ind), !NILP (pos))
816 arrow_top = XCDR (pos);
817 if (pos = Fassq (Qdown, ind), !NILP (pos))
818 arrow_bot = XCDR (pos);
819 }
820 else
821 /* Anything else means boundary on left and no arrows. */
822 boundary_top = boundary_bot = Qleft;
823 }
824
825 if (!NILP (ind))
826 {
827 int done_top = 0, done_bot = 0;
828
829 for (y = 0, rn = 0;
830 y < yb && rn < nrows;
831 y += row->height, ++rn)
832 {
833 unsigned indicate_bob_p, indicate_top_line_p;
834 unsigned indicate_eob_p, indicate_bottom_line_p;
835
836 row = w->desired_matrix->rows + rn;
837 if (!row->enabled_p)
838 row = w->current_matrix->rows + rn;
839
840 indicate_bob_p = row->indicate_bob_p;
841 indicate_top_line_p = row->indicate_top_line_p;
842 indicate_eob_p = row->indicate_eob_p;
843 indicate_bottom_line_p = row->indicate_bottom_line_p;
844
845 row->indicate_bob_p = row->indicate_top_line_p = 0;
846 row->indicate_eob_p = row->indicate_bottom_line_p = 0;
847
848 if (!row->mode_line_p)
849 {
850 if (!done_top)
851 {
852 if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer)))
853 row->indicate_bob_p = !NILP (boundary_top);
854 else
855 row->indicate_top_line_p = !NILP (arrow_top);
856 done_top = 1;
857 }
858
859 if (!done_bot)
860 {
861 if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer)))
862 row->indicate_eob_p = !NILP (boundary_bot), done_bot = 1;
863 else if (y + row->height >= yb)
864 row->indicate_bottom_line_p = !NILP (arrow_bot), done_bot = 1;
865 }
866 }
867
868 if (indicate_bob_p != row->indicate_bob_p
869 || indicate_top_line_p != row->indicate_top_line_p
870 || indicate_eob_p != row->indicate_eob_p
871 || indicate_bottom_line_p != row->indicate_bottom_line_p)
872 row->redraw_fringe_bitmaps_p = 1;
873 }
874 }
875
876 empty_pos = XBUFFER (w->buffer)->indicate_empty_lines;
877 if (!NILP (empty_pos) && !EQ (empty_pos, Qright))
878 empty_pos = WINDOW_LEFT_FRINGE_WIDTH (w) == 0 ? Qright : Qleft;
879
880 for (y = 0, rn = 0;
881 y < yb && rn < nrows;
882 y += row->height, rn++)
883 {
884 enum fringe_bitmap_type left, right;
885 unsigned left_face_id, right_face_id;
886
887 row = w->desired_matrix->rows + rn;
888 cur = w->current_matrix->rows + rn;
889 if (!row->enabled_p)
890 row = cur;
891
892 left_face_id = right_face_id = DEFAULT_FACE_ID;
893
894 /* Decide which bitmap to draw in the left fringe. */
895 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
896 left = NO_FRINGE_BITMAP;
897 else if (row->left_user_fringe_bitmap != NO_FRINGE_BITMAP)
898 {
899 left = row->left_user_fringe_bitmap;
900 left_face_id = row->left_user_fringe_face_id;
901 }
902 else if (row->truncated_on_left_p)
903 left = LEFT_TRUNCATION_BITMAP;
904 else if (row->indicate_bob_p && EQ (boundary_top, Qleft))
905 left = ((row->indicate_eob_p && EQ (boundary_bot, Qleft))
906 ? LEFT_BRACKET_BITMAP : TOP_LEFT_ANGLE_BITMAP);
907 else if (row->indicate_eob_p && EQ (boundary_bot, Qleft))
908 left = BOTTOM_LEFT_ANGLE_BITMAP;
909 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
910 left = CONTINUATION_LINE_BITMAP;
911 else if (row->indicate_empty_line_p && EQ (empty_pos, Qleft))
912 left = ZV_LINE_BITMAP;
913 else if (row->indicate_top_line_p && EQ (arrow_top, Qleft))
914 left = UP_ARROW_BITMAP;
915 else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qleft))
916 left = DOWN_ARROW_BITMAP;
917 else
918 left = NO_FRINGE_BITMAP;
919
920 /* Decide which bitmap to draw in the right fringe. */
921 if (WINDOW_RIGHT_FRINGE_WIDTH (w) == 0)
922 right = NO_FRINGE_BITMAP;
923 else if (row->right_user_fringe_bitmap != NO_FRINGE_BITMAP)
924 {
925 right = row->right_user_fringe_bitmap;
926 right_face_id = row->right_user_fringe_face_id;
927 }
928 else if (row->truncated_on_right_p)
929 right = RIGHT_TRUNCATION_BITMAP;
930 else if (row->indicate_bob_p && EQ (boundary_top, Qright))
931 right = ((row->indicate_eob_p && EQ (boundary_bot, Qright))
932 ? RIGHT_BRACKET_BITMAP : TOP_RIGHT_ANGLE_BITMAP);
933 else if (row->indicate_eob_p && EQ (boundary_bot, Qright))
934 right = BOTTOM_RIGHT_ANGLE_BITMAP;
935 else if (row->continued_p)
936 right = CONTINUED_LINE_BITMAP;
937 else if (row->indicate_top_line_p && EQ (arrow_top, Qright))
938 right = UP_ARROW_BITMAP;
939 else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qright))
940 right = DOWN_ARROW_BITMAP;
941 else if (row->indicate_empty_line_p && EQ (empty_pos, Qright))
942 right = ZV_LINE_BITMAP;
943 else
944 right = NO_FRINGE_BITMAP;
945
946 if (force_p
947 || row->y != cur->y
948 || row->visible_height != cur->visible_height
949 || row->ends_at_zv_p != cur->ends_at_zv_p
950 || left != cur->left_fringe_bitmap
951 || right != cur->right_fringe_bitmap
952 || left_face_id != cur->left_fringe_face_id
953 || right_face_id != cur->right_fringe_face_id
954 || cur->redraw_fringe_bitmaps_p)
955 {
956 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
957 cur->left_fringe_bitmap = left;
958 cur->right_fringe_bitmap = right;
959 cur->left_fringe_face_id = left_face_id;
960 cur->right_fringe_face_id = right_face_id;
961 }
962
963 if (row->overlay_arrow_bitmap != cur->overlay_arrow_bitmap)
964 {
965 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
966 cur->overlay_arrow_bitmap = row->overlay_arrow_bitmap;
967 }
968
969 row->left_fringe_bitmap = left;
970 row->right_fringe_bitmap = right;
971 row->left_fringe_face_id = left_face_id;
972 row->right_fringe_face_id = right_face_id;
973
974 if (rn > 0 && row->redraw_fringe_bitmaps_p)
975 row[-1].redraw_fringe_bitmaps_p = cur[-1].redraw_fringe_bitmaps_p = 1;
976 }
977
978 return redraw_p;
979 }
980
981
982 /* Compute actual fringe widths for frame F.
983
984 If REDRAW is 1, redraw F if the fringe settings was actually
985 modified and F is visible.
986
987 Since the combined left and right fringe must occupy an integral
988 number of columns, we may need to add some pixels to each fringe.
989 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
990 but a negative width value is taken literally (after negating it).
991
992 We never make the fringes narrower than specified.
993 */
994
995 void
996 compute_fringe_widths (f, redraw)
997 struct frame *f;
998 int redraw;
999 {
1000 int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
1001 int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
1002 int o_cols = FRAME_FRINGE_COLS (f);
1003
1004 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
1005 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
1006 int left_fringe_width, right_fringe_width;
1007
1008 if (!NILP (left_fringe))
1009 left_fringe = Fcdr (left_fringe);
1010 if (!NILP (right_fringe))
1011 right_fringe = Fcdr (right_fringe);
1012
1013 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
1014 XINT (left_fringe));
1015 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
1016 XINT (right_fringe));
1017
1018 if (left_fringe_width || right_fringe_width)
1019 {
1020 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
1021 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
1022 int conf_wid = left_wid + right_wid;
1023 int font_wid = FRAME_COLUMN_WIDTH (f);
1024 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
1025 int real_wid = cols * font_wid;
1026 if (left_wid && right_wid)
1027 {
1028 if (left_fringe_width < 0)
1029 {
1030 /* Left fringe width is fixed, adjust right fringe if necessary */
1031 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
1032 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
1033 }
1034 else if (right_fringe_width < 0)
1035 {
1036 /* Right fringe width is fixed, adjust left fringe if necessary */
1037 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
1038 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
1039 }
1040 else
1041 {
1042 /* Adjust both fringes with an equal amount.
1043 Note that we are doing integer arithmetic here, so don't
1044 lose a pixel if the total width is an odd number. */
1045 int fill = real_wid - conf_wid;
1046 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
1047 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
1048 }
1049 }
1050 else if (left_fringe_width)
1051 {
1052 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
1053 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
1054 }
1055 else
1056 {
1057 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
1058 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
1059 }
1060 FRAME_FRINGE_COLS (f) = cols;
1061 }
1062 else
1063 {
1064 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
1065 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
1066 FRAME_FRINGE_COLS (f) = 0;
1067 }
1068
1069 if (redraw && FRAME_VISIBLE_P (f))
1070 if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
1071 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
1072 o_cols != FRAME_FRINGE_COLS (f))
1073 redraw_frame (f);
1074 }
1075
1076
1077 /* Free resources used by a user-defined bitmap. */
1078
1079 void
1080 destroy_fringe_bitmap (n)
1081 int n;
1082 {
1083 struct fringe_bitmap **fbp;
1084
1085 fringe_faces[n] = Qnil;
1086
1087 fbp = &fringe_bitmaps[n];
1088 if (*fbp && (*fbp)->dynamic)
1089 {
1090 if (rif && rif->destroy_fringe_bitmap)
1091 rif->destroy_fringe_bitmap (n);
1092 xfree (*fbp);
1093 *fbp = NULL;
1094 }
1095
1096 while (max_used_fringe_bitmap > MAX_STANDARD_FRINGE_BITMAPS
1097 && fringe_bitmaps[max_used_fringe_bitmap - 1] == NULL)
1098 max_used_fringe_bitmap--;
1099 }
1100
1101
1102 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap, Sdestroy_fringe_bitmap,
1103 1, 1, 0,
1104 doc: /* Destroy fringe bitmap BITMAP.
1105 If BITMAP overrides a standard fringe bitmap, the original bitmap is restored. */)
1106 (bitmap)
1107 Lisp_Object bitmap;
1108 {
1109 int n;
1110
1111 CHECK_SYMBOL (bitmap);
1112 n = lookup_fringe_bitmap (bitmap);
1113 if (!n)
1114 return Qnil;
1115
1116 destroy_fringe_bitmap (n);
1117
1118 if (n >= MAX_STANDARD_FRINGE_BITMAPS)
1119 {
1120 Vfringe_bitmaps = Fdelq (bitmap, Vfringe_bitmaps);
1121 /* It would be better to remove the fringe property. */
1122 Fput (bitmap, Qfringe, Qnil);
1123 }
1124
1125 return Qnil;
1126 }
1127
1128
1129 /* Initialize bitmap bit.
1130
1131 On X, we bit-swap the built-in bitmaps and reduce bitmap
1132 from short to char array if width is <= 8 bits.
1133
1134 On MAC with big-endian CPU, we need to byte-swap each short.
1135
1136 On W32 and MAC (little endian), there's no need to do this.
1137 */
1138
1139 void
1140 init_fringe_bitmap (which, fb, once_p)
1141 enum fringe_bitmap_type which;
1142 struct fringe_bitmap *fb;
1143 int once_p;
1144 {
1145 if (once_p || fb->dynamic)
1146 {
1147 #if defined (HAVE_X_WINDOWS)
1148 static unsigned char swap_nibble[16]
1149 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1150 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1151 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1152 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
1153 unsigned short *bits = fb->bits;
1154 int j;
1155
1156 if (fb->width <= 8)
1157 {
1158 unsigned char *cbits = (unsigned char *)fb->bits;
1159 for (j = 0; j < fb->height; j++)
1160 {
1161 unsigned short b = *bits++;
1162 unsigned char c;
1163 c = (unsigned char)((swap_nibble[b & 0xf] << 4)
1164 | (swap_nibble[(b>>4) & 0xf]));
1165 *cbits++ = (c >> (8 - fb->width));
1166 }
1167 }
1168 else
1169 {
1170 for (j = 0; j < fb->height; j++)
1171 {
1172 unsigned short b = *bits;
1173 b = (unsigned short)((swap_nibble[b & 0xf] << 12)
1174 | (swap_nibble[(b>>4) & 0xf] << 8)
1175 | (swap_nibble[(b>>8) & 0xf] << 4)
1176 | (swap_nibble[(b>>12) & 0xf]));
1177 *bits++ = (b >> (16 - fb->width));
1178 }
1179 }
1180 #endif /* HAVE_X_WINDOWS */
1181
1182 #if defined (MAC_OS) && defined (WORDS_BIG_ENDIAN)
1183 unsigned short *bits = fb->bits;
1184 int j;
1185 for (j = 0; j < fb->height; j++)
1186 {
1187 unsigned short b = *bits;
1188 *bits++ = ((b >> 8) & 0xff) | ((b & 0xff) << 8);
1189 }
1190 #endif /* MAC_OS && WORDS_BIG_ENDIAN */
1191 }
1192
1193 if (!once_p)
1194 {
1195 destroy_fringe_bitmap (which);
1196
1197 if (rif && rif->define_fringe_bitmap)
1198 rif->define_fringe_bitmap (which, fb->bits, fb->height, fb->width);
1199
1200 fringe_bitmaps[which] = fb;
1201 if (which >= max_used_fringe_bitmap)
1202 max_used_fringe_bitmap = which + 1;
1203 }
1204 }
1205
1206
1207 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap,
1208 2, 5, 0,
1209 doc: /* Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH.
1210 BITMAP is a symbol or string naming the new fringe bitmap.
1211 BITS is either a string or a vector of integers.
1212 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1213 WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1214 Optional fifth arg ALIGN may be one of `top', `center', or `bottom',
1215 indicating the positioning of the bitmap relative to the rows where it
1216 is used; the default is to center the bitmap. Fourth arg may also be a
1217 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1218 should be repeated.
1219 If BITMAP already exists, the existing definition is replaced. */)
1220 (bitmap, bits, height, width, align)
1221 Lisp_Object bitmap, bits, height, width, align;
1222 {
1223 int n, h, i, j;
1224 unsigned short *b;
1225 struct fringe_bitmap fb, *xfb;
1226 int fill1 = 0, fill2 = 0;
1227
1228 CHECK_SYMBOL (bitmap);
1229
1230 if (STRINGP (bits))
1231 h = SCHARS (bits);
1232 else if (VECTORP (bits))
1233 h = XVECTOR (bits)->size;
1234 else
1235 bits = wrong_type_argument (Qsequencep, bits);
1236
1237 if (NILP (height))
1238 fb.height = h;
1239 else
1240 {
1241 CHECK_NUMBER (height);
1242 fb.height = min (XINT (height), 255);
1243 if (fb.height > h)
1244 {
1245 fill1 = (fb.height - h) / 2;
1246 fill2 = fb.height - h - fill1;
1247 }
1248 }
1249
1250 if (NILP (width))
1251 fb.width = 8;
1252 else
1253 {
1254 CHECK_NUMBER (width);
1255 fb.width = min (XINT (width), 255);
1256 }
1257
1258 fb.period = 0;
1259 fb.align = ALIGN_BITMAP_CENTER;
1260
1261 if (CONSP (align))
1262 {
1263 Lisp_Object period = XCDR (align);
1264 if (CONSP (period))
1265 {
1266 period = XCAR (period);
1267 if (!NILP (period))
1268 {
1269 fb.period = fb.height;
1270 fb.height = 255;
1271 }
1272 }
1273 align = XCAR (align);
1274 }
1275 if (EQ (align, Qtop))
1276 fb.align = ALIGN_BITMAP_TOP;
1277 else if (EQ (align, Qbottom))
1278 fb.align = ALIGN_BITMAP_BOTTOM;
1279 else if (!NILP (align) && !EQ (align, Qcenter))
1280 error ("Bad align argument");
1281
1282 n = lookup_fringe_bitmap (bitmap);
1283 if (!n)
1284 {
1285 if (max_used_fringe_bitmap < max_fringe_bitmaps)
1286 n = max_used_fringe_bitmap++;
1287 else
1288 {
1289 for (n = MAX_STANDARD_FRINGE_BITMAPS;
1290 n < max_fringe_bitmaps;
1291 n++)
1292 if (fringe_bitmaps[n] == NULL)
1293 break;
1294
1295 if (n == max_fringe_bitmaps)
1296 {
1297 if ((max_fringe_bitmaps + 20) > MAX_FRINGE_BITMAPS)
1298 error ("No free fringe bitmap slots");
1299
1300 i = max_fringe_bitmaps;
1301 max_fringe_bitmaps += 20;
1302 fringe_bitmaps
1303 = ((struct fringe_bitmap **)
1304 xrealloc (fringe_bitmaps, max_fringe_bitmaps * sizeof (struct fringe_bitmap *)));
1305 fringe_faces
1306 = (Lisp_Object *) xrealloc (fringe_faces, max_fringe_bitmaps * sizeof (Lisp_Object));
1307
1308 for (; i < max_fringe_bitmaps; i++)
1309 {
1310 fringe_bitmaps[i] = NULL;
1311 fringe_faces[i] = Qnil;
1312 }
1313 }
1314 }
1315
1316 Vfringe_bitmaps = Fcons (bitmap, Vfringe_bitmaps);
1317 Fput (bitmap, Qfringe, make_number (n));
1318 }
1319
1320 fb.dynamic = 1;
1321
1322 xfb = (struct fringe_bitmap *) xmalloc (sizeof fb
1323 + fb.height * BYTES_PER_BITMAP_ROW);
1324 fb.bits = b = (unsigned short *) (xfb + 1);
1325 bzero (b, fb.height);
1326
1327 j = 0;
1328 while (j < fb.height)
1329 {
1330 for (i = 0; i < fill1 && j < fb.height; i++)
1331 b[j++] = 0;
1332 for (i = 0; i < h && j < fb.height; i++)
1333 {
1334 Lisp_Object elt = Faref (bits, make_number (i));
1335 b[j++] = NUMBERP (elt) ? XINT (elt) : 0;
1336 }
1337 for (i = 0; i < fill2 && j < fb.height; i++)
1338 b[j++] = 0;
1339 }
1340
1341 *xfb = fb;
1342
1343 init_fringe_bitmap (n, xfb, 0);
1344
1345 return bitmap;
1346 }
1347
1348 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face,
1349 1, 2, 0,
1350 doc: /* Set face for fringe bitmap BITMAP to FACE.
1351 If FACE is nil, reset face to default fringe face. */)
1352 (bitmap, face)
1353 Lisp_Object bitmap, face;
1354 {
1355 int n;
1356 int face_id;
1357
1358 CHECK_SYMBOL (bitmap);
1359 n = lookup_fringe_bitmap (bitmap);
1360 if (!n)
1361 error ("Undefined fringe bitmap");
1362
1363 if (!NILP (face))
1364 {
1365 face_id = lookup_derived_face (SELECTED_FRAME (), face,
1366 'A', FRINGE_FACE_ID, 1);
1367 if (face_id < 0)
1368 error ("No such face");
1369 }
1370
1371 fringe_faces[n] = face;
1372
1373 return Qnil;
1374 }
1375
1376 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos, Sfringe_bitmaps_at_pos,
1377 0, 2, 0,
1378 doc: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1379 If WINDOW is nil, use selected window. If POS is nil, use value of point
1380 in that window. Return value is a list (LEFT RIGHT OV), where LEFT
1381 is the symbol for the bitmap in the left fringe (or nil if no bitmap),
1382 RIGHT is similar for the right fringe, and OV is non-nil if there is an
1383 overlay arrow in the left fringe.
1384 Return nil if POS is not visible in WINDOW. */)
1385 (pos, window)
1386 Lisp_Object pos, window;
1387 {
1388 struct window *w;
1389 struct glyph_row *row;
1390 int textpos;
1391
1392 if (NILP (window))
1393 window = selected_window;
1394 CHECK_WINDOW (window);
1395 w = XWINDOW (window);
1396
1397 if (!NILP (pos))
1398 {
1399 CHECK_NUMBER_COERCE_MARKER (pos);
1400 textpos = XINT (pos);
1401 }
1402 else if (w == XWINDOW (selected_window))
1403 textpos = PT;
1404 else
1405 textpos = XMARKER (w->pointm)->charpos;
1406
1407 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1408 row = row_containing_pos (w, textpos, row, NULL, 0);
1409 if (row)
1410 return list3 (get_fringe_bitmap_name (row->left_fringe_bitmap),
1411 get_fringe_bitmap_name (row->right_fringe_bitmap),
1412 (row->overlay_arrow_bitmap == 0 ? Qnil
1413 : row->overlay_arrow_bitmap < 0 ? Qt
1414 : get_fringe_bitmap_name (row->overlay_arrow_bitmap)));
1415 else
1416 return Qnil;
1417 }
1418
1419
1420 /***********************************************************************
1421 Initialization
1422 ***********************************************************************/
1423
1424 void
1425 syms_of_fringe ()
1426 {
1427 defsubr (&Sdestroy_fringe_bitmap);
1428 defsubr (&Sdefine_fringe_bitmap);
1429 defsubr (&Sfringe_bitmaps_at_pos);
1430 defsubr (&Sset_fringe_bitmap_face);
1431
1432 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe,
1433 doc: /* *Non-nil means that newline may flow into the right fringe.
1434 This means that display lines which are exactly as wide as the window
1435 (not counting the final newline) will only occupy one screen line, by
1436 showing (or hiding) the final newline in the right fringe; when point
1437 is at the final newline, the cursor is shown in the right fringe.
1438 If nil, also continue lines which are exactly as wide as the window. */);
1439 Voverflow_newline_into_fringe = Qt;
1440
1441 DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps,
1442 doc: /* List of fringe bitmap symbols.
1443 You must (require 'fringe) to use fringe bitmap symbols in your programs." */);
1444 Vfringe_bitmaps = Qnil;
1445 }
1446
1447 /* Garbage collection hook */
1448
1449 void
1450 mark_fringe_data ()
1451 {
1452 int i;
1453
1454 for (i = 0; i < max_fringe_bitmaps; i++)
1455 if (!NILP (fringe_faces[i]))
1456 mark_object (fringe_faces[i]);
1457 }
1458
1459 /* Initialize this module when Emacs starts. */
1460
1461 void
1462 init_fringe_once ()
1463 {
1464 enum fringe_bitmap_type bt;
1465
1466 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1467 init_fringe_bitmap(bt, &standard_bitmaps[bt], 1);
1468 }
1469
1470 void
1471 init_fringe ()
1472 {
1473 int i;
1474
1475 max_fringe_bitmaps = MAX_STANDARD_FRINGE_BITMAPS + 20;
1476
1477 fringe_bitmaps
1478 = (struct fringe_bitmap **) xmalloc (max_fringe_bitmaps * sizeof (struct fringe_bitmap *));
1479 fringe_faces
1480 = (Lisp_Object *) xmalloc (max_fringe_bitmaps * sizeof (Lisp_Object));
1481
1482 for (i = 0; i < max_fringe_bitmaps; i++)
1483 {
1484 fringe_bitmaps[i] = NULL;
1485 fringe_faces[i] = Qnil;
1486 }
1487 }
1488
1489 #ifdef HAVE_NTGUI
1490
1491 void
1492 w32_init_fringe ()
1493 {
1494 enum fringe_bitmap_type bt;
1495
1496 if (!rif)
1497 return;
1498
1499 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1500 {
1501 struct fringe_bitmap *fb = &standard_bitmaps[bt];
1502 rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
1503 }
1504 }
1505
1506 void
1507 w32_reset_fringes ()
1508 {
1509 /* Destroy row bitmaps. */
1510 int bt;
1511
1512 if (!rif)
1513 return;
1514
1515 for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++)
1516 rif->destroy_fringe_bitmap (bt);
1517 }
1518
1519 #endif /* HAVE_NTGUI */
1520
1521 #endif /* HAVE_WINDOW_SYSTEM */
1522
1523 /* arch-tag: 04596920-43eb-473d-b319-82712338162d
1524 (do not change this comment) */