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