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