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