]> code.delx.au - gnu-emacs/blob - src/fringe.c
Merged from miles@gnu.org--gnu-2005 (patch 17-26, 107-116)
[gnu-emacs] / src / fringe.c
1 /* Fringe handling (split from xdisp.c).
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03,04
3 Free Software Foundation, Inc.
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 2, or (at your option)
10 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; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 #include <config.h>
23 #include <stdio.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 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_named_face (f, face, 'A', 1), face_id < 0))
556 face_id = FRINGE_FACE_ID;
557 }
558
559 fb = fringe_bitmaps[which];
560 if (fb == NULL)
561 fb = &standard_bitmaps[which < MAX_STANDARD_FRINGE_BITMAPS
562 ? which : UNDEF_FRINGE_BITMAP];
563
564 period = fb->period;
565
566 /* Convert row to frame coordinates. */
567 p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
568
569 p.which = which;
570 p.bits = fb->bits;
571 p.wd = fb->width;
572
573 p.h = fb->height;
574 p.dh = (period > 0 ? (p.y % period) : 0);
575 p.h -= p.dh;
576 /* Clip bitmap if too high. */
577 if (p.h > row->height)
578 p.h = row->height;
579
580 p.face = FACE_FROM_ID (f, face_id);
581
582 if (p.face == NULL)
583 {
584 /* This could happen after clearing face cache.
585 But it shouldn't happen anymore. ++kfs */
586 return;
587 }
588
589 PREPARE_FACE_FOR_DISPLAY (f, p.face);
590
591 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
592 the fringe. */
593 p.bx = -1;
594 if (left_p)
595 {
596 int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
597 int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
598 ? LEFT_MARGIN_AREA
599 : TEXT_AREA));
600 if (p.wd > wd)
601 p.wd = wd;
602 p.x = x - p.wd - (wd - p.wd) / 2;
603
604 if (p.wd < wd || row->height > p.h)
605 {
606 /* If W has a vertical border to its left, don't draw over it. */
607 wd -= ((!WINDOW_LEFTMOST_P (w)
608 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
609 ? 1 : 0);
610 p.bx = x - wd;
611 p.nx = wd;
612 }
613 }
614 else
615 {
616 int x = window_box_right (w,
617 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
618 ? RIGHT_MARGIN_AREA
619 : TEXT_AREA));
620 int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
621 if (p.wd > wd)
622 p.wd = wd;
623 p.x = x + (wd - p.wd) / 2;
624 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
625 the fringe. */
626 if (p.wd < wd || row->height > p.h)
627 {
628 p.bx = x;
629 p.nx = wd;
630 }
631 }
632
633 if (p.bx >= 0)
634 {
635 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
636
637 p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
638 p.ny = row->visible_height;
639 }
640
641 /* Adjust y to the offset in the row to start drawing the bitmap. */
642 switch (fb->align)
643 {
644 case ALIGN_BITMAP_CENTER:
645 p.y += (row->height - p.h) / 2;
646 break;
647 case ALIGN_BITMAP_BOTTOM:
648 p.h = fb->height;
649 p.y += (row->visible_height - p.h);
650 break;
651 case ALIGN_BITMAP_TOP:
652 break;
653 }
654
655 FRAME_RIF (f)->draw_fringe_bitmap (w, row, &p);
656 }
657
658 void
659 draw_fringe_bitmap (w, row, left_p)
660 struct window *w;
661 struct glyph_row *row;
662 int left_p;
663 {
664 int overlay = 0;
665
666 if (!left_p && row->cursor_in_fringe_p)
667 {
668 int cursor = NO_FRINGE_BITMAP;
669
670 switch (w->phys_cursor_type)
671 {
672 case HOLLOW_BOX_CURSOR:
673 if (row->visible_height >= STANDARD_BITMAP_HEIGHT (hollow_box_cursor_bits))
674 cursor = HOLLOW_BOX_CURSOR_BITMAP;
675 else
676 cursor = HOLLOW_SQUARE_BITMAP;
677 break;
678 case FILLED_BOX_CURSOR:
679 cursor = FILLED_BOX_CURSOR_BITMAP;
680 break;
681 case BAR_CURSOR:
682 cursor = BAR_CURSOR_BITMAP;
683 break;
684 case HBAR_CURSOR:
685 cursor = HBAR_CURSOR_BITMAP;
686 break;
687 case NO_CURSOR:
688 default:
689 w->phys_cursor_on_p = 0;
690 row->cursor_in_fringe_p = 0;
691 break;
692 }
693 if (cursor != NO_FRINGE_BITMAP)
694 {
695 draw_fringe_bitmap_1 (w, row, 0, 2, cursor);
696 overlay = cursor == FILLED_BOX_CURSOR_BITMAP ? 3 : 1;
697 }
698 }
699
700 draw_fringe_bitmap_1 (w, row, left_p, overlay, NO_FRINGE_BITMAP);
701
702 if (left_p && row->overlay_arrow_p)
703 draw_fringe_bitmap_1 (w, row, 1, 1,
704 (w->overlay_arrow_bitmap
705 ? w->overlay_arrow_bitmap
706 : OVERLAY_ARROW_BITMAP));
707 }
708
709
710 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
711 function with input blocked. */
712
713 void
714 draw_row_fringe_bitmaps (w, row)
715 struct window *w;
716 struct glyph_row *row;
717 {
718 xassert (interrupt_input_blocked);
719
720 /* If row is completely invisible, because of vscrolling, we
721 don't have to draw anything. */
722 if (row->visible_height <= 0)
723 return;
724
725 if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
726 draw_fringe_bitmap (w, row, 1);
727
728 if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
729 draw_fringe_bitmap (w, row, 0);
730 }
731
732 /* Draw the fringes of window W. Only fringes for rows marked for
733 update in redraw_fringe_bitmaps_p are drawn.
734
735 Return >0 if left or right fringe was redrawn in any way.
736
737 If NO_FRINGE is non-zero, also return >0 if either fringe has zero width.
738
739 A return value >0 indicates that the vertical line between windows
740 needs update (as it may be drawn in the fringe).
741 */
742
743 int
744 draw_window_fringes (w, no_fringe)
745 struct window *w;
746 int no_fringe;
747 {
748 struct glyph_row *row;
749 int yb = window_text_bottom_y (w);
750 int nrows = w->current_matrix->nrows;
751 int y = 0, rn;
752 int updated = 0;
753
754 if (w->pseudo_window_p)
755 return 0;
756
757 /* Must draw line if no fringe */
758 if (no_fringe
759 && (WINDOW_LEFT_FRINGE_WIDTH (w) == 0
760 || WINDOW_RIGHT_FRINGE_WIDTH (w) == 0))
761 updated++;
762
763 for (y = 0, rn = 0, row = w->current_matrix->rows;
764 y < yb && rn < nrows;
765 y += row->height, ++row, ++rn)
766 {
767 if (!row->redraw_fringe_bitmaps_p)
768 continue;
769 draw_row_fringe_bitmaps (w, row);
770 row->redraw_fringe_bitmaps_p = 0;
771 updated++;
772 }
773
774 return updated;
775 }
776
777
778 /* Recalculate the bitmaps to show in the fringes of window W.
779 If FORCE_P is 0, only mark rows with modified bitmaps for update in
780 redraw_fringe_bitmaps_p; else mark all rows for update. */
781
782 int
783 update_window_fringes (w, force_p)
784 struct window *w;
785 int force_p;
786 {
787 struct glyph_row *row, *cur = 0;
788 int yb = window_text_bottom_y (w);
789 int rn, nrows = w->current_matrix->nrows;
790 int y;
791 int redraw_p = 0;
792 Lisp_Object boundary_top = Qnil, boundary_bot = Qnil;
793 Lisp_Object arrow_top = Qnil, arrow_bot = Qnil;
794 Lisp_Object empty_pos;
795 Lisp_Object ind = Qnil;
796
797 if (w->pseudo_window_p)
798 return 0;
799
800 if (!MINI_WINDOW_P (w)
801 && (ind = XBUFFER (w->buffer)->indicate_buffer_boundaries, !NILP (ind)))
802 {
803 if (EQ (ind, Qleft) || EQ (ind, Qright))
804 boundary_top = boundary_bot = arrow_top = arrow_bot = ind;
805 else if (CONSP (ind) && CONSP (XCAR (ind)))
806 {
807 Lisp_Object pos;
808 if (pos = Fassq (Qt, ind), !NILP (pos))
809 boundary_top = boundary_bot = arrow_top = arrow_bot = XCDR (pos);
810 if (pos = Fassq (Qtop, ind), !NILP (pos))
811 boundary_top = XCDR (pos);
812 if (pos = Fassq (Qbottom, ind), !NILP (pos))
813 boundary_bot = XCDR (pos);
814 if (pos = Fassq (Qup, ind), !NILP (pos))
815 arrow_top = XCDR (pos);
816 if (pos = Fassq (Qdown, ind), !NILP (pos))
817 arrow_bot = XCDR (pos);
818 }
819 else
820 /* Anything else means boundary on left and no arrows. */
821 boundary_top = boundary_bot = Qleft;
822 }
823
824 if (!NILP (ind))
825 {
826 int done_top = 0, done_bot = 0;
827
828 for (y = 0, rn = 0;
829 y < yb && rn < nrows;
830 y += row->height, ++rn)
831 {
832 unsigned indicate_bob_p, indicate_top_line_p;
833 unsigned indicate_eob_p, indicate_bottom_line_p;
834
835 row = w->desired_matrix->rows + rn;
836 if (!row->enabled_p)
837 row = w->current_matrix->rows + rn;
838
839 indicate_bob_p = row->indicate_bob_p;
840 indicate_top_line_p = row->indicate_top_line_p;
841 indicate_eob_p = row->indicate_eob_p;
842 indicate_bottom_line_p = row->indicate_bottom_line_p;
843
844 row->indicate_bob_p = row->indicate_top_line_p = 0;
845 row->indicate_eob_p = row->indicate_bottom_line_p = 0;
846
847 if (!row->mode_line_p)
848 {
849 if (!done_top)
850 {
851 if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer)))
852 row->indicate_bob_p = !NILP (boundary_top);
853 else
854 row->indicate_top_line_p = !NILP (arrow_top);
855 done_top = 1;
856 }
857
858 if (!done_bot)
859 {
860 if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer)))
861 row->indicate_eob_p = !NILP (boundary_bot), done_bot = 1;
862 else if (y + row->height >= yb)
863 row->indicate_bottom_line_p = !NILP (arrow_bot), done_bot = 1;
864 }
865 }
866
867 if (indicate_bob_p != row->indicate_bob_p
868 || indicate_top_line_p != row->indicate_top_line_p
869 || indicate_eob_p != row->indicate_eob_p
870 || indicate_bottom_line_p != row->indicate_bottom_line_p)
871 row->redraw_fringe_bitmaps_p = 1;
872 }
873 }
874
875 empty_pos = XBUFFER (w->buffer)->indicate_empty_lines;
876 if (!NILP (empty_pos) && !EQ (empty_pos, Qright))
877 empty_pos = WINDOW_LEFT_FRINGE_WIDTH (w) == 0 ? Qright : Qleft;
878
879 for (y = 0, rn = 0;
880 y < yb && rn < nrows;
881 y += row->height, rn++)
882 {
883 enum fringe_bitmap_type left, right;
884 unsigned left_face_id, right_face_id;
885
886 row = w->desired_matrix->rows + rn;
887 cur = w->current_matrix->rows + rn;
888 if (!row->enabled_p)
889 row = cur;
890
891 left_face_id = right_face_id = DEFAULT_FACE_ID;
892
893 /* Decide which bitmap to draw in the left fringe. */
894 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
895 left = NO_FRINGE_BITMAP;
896 else if (row->left_user_fringe_bitmap != NO_FRINGE_BITMAP)
897 {
898 left = row->left_user_fringe_bitmap;
899 left_face_id = row->left_user_fringe_face_id;
900 }
901 else if (row->truncated_on_left_p)
902 left = LEFT_TRUNCATION_BITMAP;
903 else if (row->indicate_bob_p && EQ (boundary_top, Qleft))
904 left = ((row->indicate_eob_p && EQ (boundary_bot, Qleft))
905 ? LEFT_BRACKET_BITMAP : TOP_LEFT_ANGLE_BITMAP);
906 else if (row->indicate_eob_p && EQ (boundary_bot, Qleft))
907 left = BOTTOM_LEFT_ANGLE_BITMAP;
908 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
909 left = CONTINUATION_LINE_BITMAP;
910 else if (row->indicate_empty_line_p && EQ (empty_pos, Qleft))
911 left = ZV_LINE_BITMAP;
912 else if (row->indicate_top_line_p && EQ (arrow_top, Qleft))
913 left = UP_ARROW_BITMAP;
914 else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qleft))
915 left = DOWN_ARROW_BITMAP;
916 else
917 left = NO_FRINGE_BITMAP;
918
919 /* Decide which bitmap to draw in the right fringe. */
920 if (WINDOW_RIGHT_FRINGE_WIDTH (w) == 0)
921 right = NO_FRINGE_BITMAP;
922 else if (row->right_user_fringe_bitmap != NO_FRINGE_BITMAP)
923 {
924 right = row->right_user_fringe_bitmap;
925 right_face_id = row->right_user_fringe_face_id;
926 }
927 else if (row->truncated_on_right_p)
928 right = RIGHT_TRUNCATION_BITMAP;
929 else if (row->indicate_bob_p && EQ (boundary_top, Qright))
930 right = ((row->indicate_eob_p && EQ (boundary_bot, Qright))
931 ? RIGHT_BRACKET_BITMAP : TOP_RIGHT_ANGLE_BITMAP);
932 else if (row->indicate_eob_p && EQ (boundary_bot, Qright))
933 right = BOTTOM_RIGHT_ANGLE_BITMAP;
934 else if (row->continued_p)
935 right = CONTINUED_LINE_BITMAP;
936 else if (row->indicate_top_line_p && EQ (arrow_top, Qright))
937 right = UP_ARROW_BITMAP;
938 else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qright))
939 right = DOWN_ARROW_BITMAP;
940 else if (row->indicate_empty_line_p && EQ (empty_pos, Qright))
941 right = ZV_LINE_BITMAP;
942 else
943 right = NO_FRINGE_BITMAP;
944
945 if (force_p
946 || row->y != cur->y
947 || row->visible_height != cur->visible_height
948 || row->ends_at_zv_p != cur->ends_at_zv_p
949 || left != cur->left_fringe_bitmap
950 || right != cur->right_fringe_bitmap
951 || left_face_id != cur->left_fringe_face_id
952 || right_face_id != cur->right_fringe_face_id
953 || cur->redraw_fringe_bitmaps_p)
954 {
955 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
956 cur->left_fringe_bitmap = left;
957 cur->right_fringe_bitmap = right;
958 cur->left_fringe_face_id = left_face_id;
959 cur->right_fringe_face_id = right_face_id;
960 }
961
962 if (row->overlay_arrow_p != cur->overlay_arrow_p)
963 {
964 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
965 cur->overlay_arrow_p = row->overlay_arrow_p;
966 }
967
968 row->left_fringe_bitmap = left;
969 row->right_fringe_bitmap = right;
970 row->left_fringe_face_id = left_face_id;
971 row->right_fringe_face_id = right_face_id;
972
973 if (rn > 0 && row->redraw_fringe_bitmaps_p)
974 row[-1].redraw_fringe_bitmaps_p = cur[-1].redraw_fringe_bitmaps_p = 1;
975 }
976
977 return redraw_p;
978 }
979
980
981 /* Compute actual fringe widths for frame F.
982
983 If REDRAW is 1, redraw F if the fringe settings was actually
984 modified and F is visible.
985
986 Since the combined left and right fringe must occupy an integral
987 number of columns, we may need to add some pixels to each fringe.
988 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
989 but a negative width value is taken literally (after negating it).
990
991 We never make the fringes narrower than specified.
992 */
993
994 void
995 compute_fringe_widths (f, redraw)
996 struct frame *f;
997 int redraw;
998 {
999 int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
1000 int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
1001 int o_cols = FRAME_FRINGE_COLS (f);
1002
1003 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
1004 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
1005 int left_fringe_width, right_fringe_width;
1006
1007 if (!NILP (left_fringe))
1008 left_fringe = Fcdr (left_fringe);
1009 if (!NILP (right_fringe))
1010 right_fringe = Fcdr (right_fringe);
1011
1012 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
1013 XINT (left_fringe));
1014 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
1015 XINT (right_fringe));
1016
1017 if (left_fringe_width || right_fringe_width)
1018 {
1019 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
1020 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
1021 int conf_wid = left_wid + right_wid;
1022 int font_wid = FRAME_COLUMN_WIDTH (f);
1023 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
1024 int real_wid = cols * font_wid;
1025 if (left_wid && right_wid)
1026 {
1027 if (left_fringe_width < 0)
1028 {
1029 /* Left fringe width is fixed, adjust right fringe if necessary */
1030 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
1031 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
1032 }
1033 else if (right_fringe_width < 0)
1034 {
1035 /* Right fringe width is fixed, adjust left fringe if necessary */
1036 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
1037 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
1038 }
1039 else
1040 {
1041 /* Adjust both fringes with an equal amount.
1042 Note that we are doing integer arithmetic here, so don't
1043 lose a pixel if the total width is an odd number. */
1044 int fill = real_wid - conf_wid;
1045 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
1046 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
1047 }
1048 }
1049 else if (left_fringe_width)
1050 {
1051 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
1052 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
1053 }
1054 else
1055 {
1056 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
1057 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
1058 }
1059 FRAME_FRINGE_COLS (f) = cols;
1060 }
1061 else
1062 {
1063 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
1064 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
1065 FRAME_FRINGE_COLS (f) = 0;
1066 }
1067
1068 if (redraw && FRAME_VISIBLE_P (f))
1069 if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
1070 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
1071 o_cols != FRAME_FRINGE_COLS (f))
1072 redraw_frame (f);
1073 }
1074
1075
1076 /* Free resources used by a user-defined bitmap. */
1077
1078 void
1079 destroy_fringe_bitmap (n)
1080 int n;
1081 {
1082 struct fringe_bitmap **fbp;
1083
1084 fringe_faces[n] = Qnil;
1085
1086 fbp = &fringe_bitmaps[n];
1087 if (*fbp && (*fbp)->dynamic)
1088 {
1089 /* XXX Is SELECTED_FRAME OK here? */
1090 struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
1091 if (rif && rif->destroy_fringe_bitmap)
1092 rif->destroy_fringe_bitmap (n);
1093 xfree (*fbp);
1094 *fbp = NULL;
1095 }
1096
1097 while (max_used_fringe_bitmap > MAX_STANDARD_FRINGE_BITMAPS
1098 && fringe_bitmaps[max_used_fringe_bitmap - 1] == NULL)
1099 max_used_fringe_bitmap--;
1100 }
1101
1102
1103 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap, Sdestroy_fringe_bitmap,
1104 1, 1, 0,
1105 doc: /* Destroy fringe bitmap BITMAP.
1106 If BITMAP overrides a standard fringe bitmap, the original bitmap is restored. */)
1107 (bitmap)
1108 Lisp_Object bitmap;
1109 {
1110 int n;
1111
1112 CHECK_SYMBOL (bitmap);
1113 n = lookup_fringe_bitmap (bitmap);
1114 if (!n)
1115 return Qnil;
1116
1117 destroy_fringe_bitmap (n);
1118
1119 if (n >= MAX_STANDARD_FRINGE_BITMAPS)
1120 {
1121 Vfringe_bitmaps = Fdelq (bitmap, Vfringe_bitmaps);
1122 /* It would be better to remove the fringe property. */
1123 Fput (bitmap, Qfringe, Qnil);
1124 }
1125
1126 return Qnil;
1127 }
1128
1129
1130 /* Initialize bitmap bit.
1131
1132 On X, we bit-swap the built-in bitmaps and reduce bitmap
1133 from short to char array if width is <= 8 bits.
1134
1135 On MAC with big-endian CPU, we need to byte-swap each short.
1136
1137 On W32 and MAC (little endian), there's no need to do this.
1138 */
1139
1140 void
1141 init_fringe_bitmap (which, fb, once_p)
1142 enum fringe_bitmap_type which;
1143 struct fringe_bitmap *fb;
1144 int once_p;
1145 {
1146 if (once_p || fb->dynamic)
1147 {
1148 #if defined (HAVE_X_WINDOWS)
1149 static unsigned char swap_nibble[16]
1150 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1151 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1152 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1153 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
1154 unsigned short *bits = fb->bits;
1155 int j;
1156
1157 if (fb->width <= 8)
1158 {
1159 unsigned char *cbits = (unsigned char *)fb->bits;
1160 for (j = 0; j < fb->height; j++)
1161 {
1162 unsigned short b = *bits++;
1163 unsigned char c;
1164 c = (unsigned char)((swap_nibble[b & 0xf] << 4)
1165 | (swap_nibble[(b>>4) & 0xf]));
1166 *cbits++ = (c >> (8 - fb->width));
1167 }
1168 }
1169 else
1170 {
1171 for (j = 0; j < fb->height; j++)
1172 {
1173 unsigned short b = *bits;
1174 b = (unsigned short)((swap_nibble[b & 0xf] << 12)
1175 | (swap_nibble[(b>>4) & 0xf] << 8)
1176 | (swap_nibble[(b>>8) & 0xf] << 4)
1177 | (swap_nibble[(b>>12) & 0xf]));
1178 *bits++ = (b >> (16 - fb->width));
1179 }
1180 }
1181 #endif /* HAVE_X_WINDOWS */
1182
1183 #if defined (MAC_OS) && defined (WORDS_BIG_ENDIAN)
1184 unsigned short *bits = fb->bits;
1185 int j;
1186 for (j = 0; j < fb->height; j++)
1187 {
1188 unsigned short b = *bits;
1189 *bits++ = ((b >> 8) & 0xff) | ((b & 0xff) << 8);
1190 }
1191 #endif /* MAC_OS && WORDS_BIG_ENDIAN */
1192 }
1193
1194 if (!once_p)
1195 {
1196 /* XXX Is SELECTED_FRAME OK here? */
1197 struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
1198
1199 destroy_fringe_bitmap (which);
1200
1201 if (rif && rif->define_fringe_bitmap)
1202 rif->define_fringe_bitmap (which, fb->bits, fb->height, fb->width);
1203
1204 fringe_bitmaps[which] = fb;
1205 if (which >= max_used_fringe_bitmap)
1206 max_used_fringe_bitmap = which + 1;
1207 }
1208 }
1209
1210
1211 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap,
1212 2, 5, 0,
1213 doc: /* Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH.
1214 BITMAP is a symbol or string naming the new fringe bitmap.
1215 BITS is either a string or a vector of integers.
1216 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1217 WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1218 Optional fifth arg ALIGN may be one of `top', `center', or `bottom',
1219 indicating the positioning of the bitmap relative to the rows where it
1220 is used; the default is to center the bitmap. Fourth arg may also be a
1221 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1222 should be repeated.
1223 If BITMAP already exists, the existing definition is replaced. */)
1224 (bitmap, bits, height, width, align)
1225 Lisp_Object bitmap, bits, height, width, align;
1226 {
1227 int n, h, i, j;
1228 unsigned short *b;
1229 struct fringe_bitmap fb, *xfb;
1230 int fill1 = 0, fill2 = 0;
1231
1232 CHECK_SYMBOL (bitmap);
1233
1234 if (STRINGP (bits))
1235 h = SCHARS (bits);
1236 else if (VECTORP (bits))
1237 h = XVECTOR (bits)->size;
1238 else
1239 bits = wrong_type_argument (Qsequencep, bits);
1240
1241 if (NILP (height))
1242 fb.height = h;
1243 else
1244 {
1245 CHECK_NUMBER (height);
1246 fb.height = min (XINT (height), 255);
1247 if (fb.height > h)
1248 {
1249 fill1 = (fb.height - h) / 2;
1250 fill2 = fb.height - h - fill1;
1251 }
1252 }
1253
1254 if (NILP (width))
1255 fb.width = 8;
1256 else
1257 {
1258 CHECK_NUMBER (width);
1259 fb.width = min (XINT (width), 255);
1260 }
1261
1262 fb.period = 0;
1263 fb.align = ALIGN_BITMAP_CENTER;
1264
1265 if (CONSP (align))
1266 {
1267 Lisp_Object period = XCDR (align);
1268 if (CONSP (period))
1269 {
1270 period = XCAR (period);
1271 if (!NILP (period))
1272 {
1273 fb.period = fb.height;
1274 fb.height = 255;
1275 }
1276 }
1277 align = XCAR (align);
1278 }
1279 if (EQ (align, Qtop))
1280 fb.align = ALIGN_BITMAP_TOP;
1281 else if (EQ (align, Qbottom))
1282 fb.align = ALIGN_BITMAP_BOTTOM;
1283 else if (!NILP (align) && !EQ (align, Qcenter))
1284 error ("Bad align argument");
1285
1286 n = lookup_fringe_bitmap (bitmap);
1287 if (!n)
1288 {
1289 if (max_used_fringe_bitmap < max_fringe_bitmaps)
1290 n = max_used_fringe_bitmap++;
1291 else
1292 {
1293 for (n = MAX_STANDARD_FRINGE_BITMAPS;
1294 n < max_fringe_bitmaps;
1295 n++)
1296 if (fringe_bitmaps[n] == NULL)
1297 break;
1298
1299 if (n == max_fringe_bitmaps)
1300 {
1301 if ((max_fringe_bitmaps + 20) > MAX_FRINGE_BITMAPS)
1302 error ("No free fringe bitmap slots");
1303
1304 i = max_fringe_bitmaps;
1305 max_fringe_bitmaps += 20;
1306 fringe_bitmaps
1307 = ((struct fringe_bitmap **)
1308 xrealloc (fringe_bitmaps, max_fringe_bitmaps * sizeof (struct fringe_bitmap *)));
1309 fringe_faces
1310 = (Lisp_Object *) xrealloc (fringe_faces, max_fringe_bitmaps * sizeof (Lisp_Object));
1311
1312 for (; i < max_fringe_bitmaps; i++)
1313 {
1314 fringe_bitmaps[i] = NULL;
1315 fringe_faces[i] = Qnil;
1316 }
1317 }
1318 }
1319
1320 Vfringe_bitmaps = Fcons (bitmap, Vfringe_bitmaps);
1321 Fput (bitmap, Qfringe, make_number (n));
1322 }
1323
1324 fb.dynamic = 1;
1325
1326 xfb = (struct fringe_bitmap *) xmalloc (sizeof fb
1327 + fb.height * BYTES_PER_BITMAP_ROW);
1328 fb.bits = b = (unsigned short *) (xfb + 1);
1329 bzero (b, fb.height);
1330
1331 j = 0;
1332 while (j < fb.height)
1333 {
1334 for (i = 0; i < fill1 && j < fb.height; i++)
1335 b[j++] = 0;
1336 for (i = 0; i < h && j < fb.height; i++)
1337 {
1338 Lisp_Object elt = Faref (bits, make_number (i));
1339 b[j++] = NUMBERP (elt) ? XINT (elt) : 0;
1340 }
1341 for (i = 0; i < fill2 && j < fb.height; i++)
1342 b[j++] = 0;
1343 }
1344
1345 *xfb = fb;
1346
1347 init_fringe_bitmap (n, xfb, 0);
1348
1349 return bitmap;
1350 }
1351
1352 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face,
1353 1, 2, 0,
1354 doc: /* Set face for fringe bitmap BITMAP to FACE.
1355 If FACE is nil, reset face to default fringe face. */)
1356 (bitmap, face)
1357 Lisp_Object bitmap, face;
1358 {
1359 int n;
1360 int face_id;
1361
1362 CHECK_SYMBOL (bitmap);
1363 n = lookup_fringe_bitmap (bitmap);
1364 if (!n)
1365 error ("Undefined fringe bitmap");
1366
1367 if (!NILP (face))
1368 {
1369 face_id = lookup_named_face (SELECTED_FRAME (), face, 'A', 1);
1370 if (face_id < 0)
1371 error ("No such face");
1372 }
1373
1374 fringe_faces[n] = face;
1375
1376 return Qnil;
1377 }
1378
1379 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos, Sfringe_bitmaps_at_pos,
1380 0, 2, 0,
1381 doc: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1382 If WINDOW is nil, use selected window. If POS is nil, use value of point
1383 in that window. Return value is a list (LEFT RIGHT OV), where LEFT
1384 is the symbol for the bitmap in the left fringe (or nil if no bitmap),
1385 RIGHT is similar for the right fringe, and OV is non-nil if there is an
1386 overlay arrow in the left fringe.
1387 Return nil if POS is not visible in WINDOW. */)
1388 (pos, window)
1389 Lisp_Object pos, window;
1390 {
1391 struct window *w;
1392 struct glyph_row *row;
1393 int textpos;
1394
1395 if (NILP (window))
1396 window = selected_window;
1397 CHECK_WINDOW (window);
1398 w = XWINDOW (window);
1399
1400 if (!NILP (pos))
1401 {
1402 CHECK_NUMBER_COERCE_MARKER (pos);
1403 textpos = XINT (pos);
1404 }
1405 else if (w == XWINDOW (selected_window))
1406 textpos = PT;
1407 else
1408 textpos = XMARKER (w->pointm)->charpos;
1409
1410 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1411 row = row_containing_pos (w, textpos, row, NULL, 0);
1412 if (row)
1413 return list3 (get_fringe_bitmap_name (row->left_fringe_bitmap),
1414 get_fringe_bitmap_name (row->right_fringe_bitmap),
1415 (row->overlay_arrow_p ? Qt : Qnil));
1416 else
1417 return Qnil;
1418 }
1419
1420
1421 /***********************************************************************
1422 Initialization
1423 ***********************************************************************/
1424
1425 void
1426 syms_of_fringe ()
1427 {
1428 defsubr (&Sdestroy_fringe_bitmap);
1429 defsubr (&Sdefine_fringe_bitmap);
1430 defsubr (&Sfringe_bitmaps_at_pos);
1431 defsubr (&Sset_fringe_bitmap_face);
1432
1433 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe,
1434 doc: /* *Non-nil means that newline may flow into the right fringe.
1435 This means that display lines which are exactly as wide as the window
1436 (not counting the final newline) will only occupy one screen line, by
1437 showing (or hiding) the final newline in the right fringe; when point
1438 is at the final newline, the cursor is shown in the right fringe.
1439 If nil, also continue lines which are exactly as wide as the window. */);
1440 Voverflow_newline_into_fringe = Qt;
1441
1442 DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps,
1443 doc: /* List of fringe bitmap symbols.
1444 You must (require 'fringe) to use fringe bitmap symbols in your programs." */);
1445 Vfringe_bitmaps = Qnil;
1446 }
1447
1448 /* Garbage collection hook */
1449
1450 void
1451 mark_fringe_data ()
1452 {
1453 int i;
1454
1455 for (i = 0; i < max_fringe_bitmaps; i++)
1456 if (!NILP (fringe_faces[i]))
1457 mark_object (fringe_faces[i]);
1458 }
1459
1460 /* Initialize this module when Emacs starts. */
1461
1462 void
1463 init_fringe_once ()
1464 {
1465 enum fringe_bitmap_type bt;
1466
1467 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1468 init_fringe_bitmap(bt, &standard_bitmaps[bt], 1);
1469 }
1470
1471 void
1472 init_fringe ()
1473 {
1474 int i;
1475
1476 max_fringe_bitmaps = MAX_STANDARD_FRINGE_BITMAPS + 20;
1477
1478 fringe_bitmaps
1479 = (struct fringe_bitmap **) xmalloc (max_fringe_bitmaps * sizeof (struct fringe_bitmap *));
1480 fringe_faces
1481 = (Lisp_Object *) xmalloc (max_fringe_bitmaps * sizeof (Lisp_Object));
1482
1483 for (i = 0; i < max_fringe_bitmaps; i++)
1484 {
1485 fringe_bitmaps[i] = NULL;
1486 fringe_faces[i] = Qnil;
1487 }
1488 }
1489
1490 #ifdef HAVE_NTGUI
1491
1492 void
1493 w32_init_fringe ()
1494 {
1495 enum fringe_bitmap_type bt;
1496
1497 if (!rif)
1498 return;
1499
1500 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1501 {
1502 struct fringe_bitmap *fb = &standard_bitmaps[bt];
1503 rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
1504 }
1505 }
1506
1507 void
1508 w32_reset_fringes ()
1509 {
1510 /* Destroy row bitmaps. */
1511 int bt;
1512
1513 if (!rif)
1514 return;
1515
1516 for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++)
1517 rif->destroy_fringe_bitmap (bt);
1518 }
1519
1520 #endif /* HAVE_NTGUI */
1521
1522 #endif /* HAVE_WINDOW_SYSTEM */
1523
1524 /* arch-tag: 04596920-43eb-473d-b319-82712338162d
1525 (do not change this comment) */