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