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