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