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