Replace last-command-char with last-command-event.
[emacs.git] / src / fringe.c
blob9b5924145322868ca3a5375edb9c4aa25a72be1d
1 /* Fringe handling (split from xdisp.c).
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997,
3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 #include <config.h>
22 #include <stdio.h>
24 #include "lisp.h"
25 #include "frame.h"
26 #include "window.h"
27 #include "dispextern.h"
28 #include "buffer.h"
29 #include "blockinput.h"
30 #include "termhooks.h"
32 #ifdef HAVE_WINDOW_SYSTEM
34 extern Lisp_Object Qfringe;
35 extern Lisp_Object Qtop, Qbottom, Qcenter;
36 extern Lisp_Object Qup, Qdown, Qleft, Qright;
38 /* Non-nil means that newline may flow into the right fringe. */
40 Lisp_Object Voverflow_newline_into_fringe;
42 /* List of known fringe bitmap symbols.
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.
49 Lisp_Object Vfringe_bitmaps;
51 /* Fringe bitmaps are represented in three different ways:
53 Logical bitmaps are used internally to denote things like
54 'end-of-buffer', 'left-truncation', 'overlay-arrow', etc.
56 Physical bitmaps specify the visual appearence of the bitmap,
57 e.g. 'bottom-left-angle', 'left-arrow', 'left-triangle', etc.
58 User defined bitmaps are physical bitmaps.
60 Internally, fringe bitmaps for a specific display row are
61 represented as a simple integer that is used as an index
62 into the table of all defined bitmaps. This index is stored
63 in the `fringe' property of the physical bitmap symbol.
65 Logical bitmaps are mapped to physical bitmaps through the
66 buffer-local `fringe-indicator-alist' variable.
68 Each element of this alist is a cons (LOGICAL . PHYSICAL)
69 mapping a logical bitmap to a physical bitmap.
70 PHYSICAL is either a symbol to use in both left and right fringe,
71 or a cons of two symbols (LEFT . RIGHT) denoting different
72 bitmaps to use in left and right fringe.
74 LOGICAL is first looked up in the window's buffer's buffer-local
75 value of the fringe-indicator-alist variable, and if not present,
76 in the global value of fringe-indicator-alist.
78 If LOGICAL is not present in either alist, or the PHYSICAL value
79 found is nil, no bitmap is shown for the logical bitmap.
81 The `left-fringe' and `right-fringe' display properties
82 must specify physical bitmap symbols.
85 extern Lisp_Object Qunknown;
86 Lisp_Object Qtruncation, Qcontinuation, Qoverlay_arrow;
87 Lisp_Object Qempty_line, Qtop_bottom;
88 extern Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
89 Lisp_Object Qhollow_small;
91 enum fringe_bitmap_align
93 ALIGN_BITMAP_CENTER = 0,
94 ALIGN_BITMAP_TOP,
95 ALIGN_BITMAP_BOTTOM
98 struct fringe_bitmap
100 unsigned short *bits;
101 unsigned height : 8;
102 unsigned width : 8;
103 unsigned period : 8;
104 unsigned align : 2;
105 unsigned dynamic : 1;
109 /***********************************************************************
110 Fringe bitmaps
111 ***********************************************************************/
113 /* Undefined bitmap. A question mark. */
115 ..xxxx..
116 .xxxxxx.
117 xx....xx
118 xx....xx
119 ....xx..
120 ...xx...
121 ...xx...
122 ........
123 ...xx...
124 ...xx...
126 static unsigned short question_mark_bits[] = {
127 0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
129 /* An arrow like this: `<-'. */
131 ...xx...
132 ..xx....
133 .xx.....
134 xxxxxx..
135 xxxxxx..
136 .xx.....
137 ..xx....
138 ...xx...
140 static unsigned short left_arrow_bits[] = {
141 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
144 /* Right truncation arrow bitmap `->'. */
146 ...xx...
147 ....xx..
148 .....xx.
149 ..xxxxxx
150 ..xxxxxx
151 .....xx.
152 ....xx..
153 ...xx...
155 static unsigned short right_arrow_bits[] = {
156 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
159 /* Up arrow bitmap. */
161 ...xx...
162 ..xxxx..
163 .xxxxxx.
164 xxxxxxxx
165 ...xx...
166 ...xx...
167 ...xx...
168 ...xx...
170 static unsigned short up_arrow_bits[] = {
171 0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
174 /* Down arrow bitmap. */
176 ...xx...
177 ...xx...
178 ...xx...
179 ...xx...
180 xxxxxxxx
181 .xxxxxx.
182 ..xxxx..
183 ...xx...
185 static unsigned short down_arrow_bits[] = {
186 0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
188 /* Marker for continuation lines. */
190 ..xxxx..
191 .xxxxx..
192 xx......
193 xxx..x..
194 xxxxxx..
195 .xxxxx..
196 ..xxxx..
197 .xxxxx..
199 static unsigned short left_curly_arrow_bits[] = {
200 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
202 /* Marker for continued lines. */
204 ..xxxx..
205 ..xxxxx.
206 ......xx
207 ..x..xxx
208 ..xxxxxx
209 ..xxxxx.
210 ..xxxx..
211 ..xxxxx.
213 static unsigned short right_curly_arrow_bits[] = {
214 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
216 /* Reverse Overlay arrow bitmap. A triangular arrow. */
218 ......xx
219 ....xxxx
220 ...xxxxx
221 ..xxxxxx
222 ..xxxxxx
223 ...xxxxx
224 ....xxxx
225 ......xx
227 static unsigned short left_triangle_bits[] = {
228 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
230 /* Overlay arrow bitmap. A triangular arrow. */
232 xx......
233 xxxx....
234 xxxxx...
235 xxxxxx..
236 xxxxxx..
237 xxxxx...
238 xxxx....
239 xx......
241 static unsigned short right_triangle_bits[] = {
242 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
244 /* First line bitmap. An top-left angle. */
246 xxxxxx..
247 xxxxxx..
248 xx......
249 xx......
250 xx......
251 xx......
252 xx......
253 ........
255 static unsigned short top_left_angle_bits[] = {
256 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00};
258 /* First line bitmap. An right-up angle. */
260 ..xxxxxx
261 ..xxxxxx
262 ......xx
263 ......xx
264 ......xx
265 ......xx
266 ......xx
267 ........
269 static unsigned short top_right_angle_bits[] = {
270 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
272 /* Last line bitmap. An left-down angle. */
274 ........
275 xx......
276 xx......
277 xx......
278 xx......
279 xx......
280 xxxxxx..
281 xxxxxx..
283 static unsigned short bottom_left_angle_bits[] = {
284 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
286 /* Last line bitmap. An right-down angle. */
288 ........
289 ......xx
290 ......xx
291 ......xx
292 ......xx
293 ......xx
294 ..xxxxxx
295 ..xxxxxx
297 static unsigned short bottom_right_angle_bits[] = {
298 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
300 /* First/last line bitmap. An left bracket. */
302 xxxxxx..
303 xxxxxx..
304 xx......
305 xx......
306 xx......
307 xx......
308 xx......
309 xx......
310 xxxxxx..
311 xxxxxx..
313 static unsigned short left_bracket_bits[] = {
314 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
316 /* First/last line bitmap. An right bracket. */
318 ..xxxxxx
319 ..xxxxxx
320 ......xx
321 ......xx
322 ......xx
323 ......xx
324 ......xx
325 ......xx
326 ..xxxxxx
327 ..xxxxxx
329 static unsigned short right_bracket_bits[] = {
330 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
332 /* Filled box cursor bitmap. A filled box; max 13 pixels high. */
334 xxxxxxx.
335 xxxxxxx.
336 xxxxxxx.
337 xxxxxxx.
338 xxxxxxx.
339 xxxxxxx.
340 xxxxxxx.
341 xxxxxxx.
342 xxxxxxx.
343 xxxxxxx.
344 xxxxxxx.
345 xxxxxxx.
346 xxxxxxx.
348 static unsigned short filled_rectangle_bits[] = {
349 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
351 /* Hollow box cursor bitmap. A hollow box; max 13 pixels high. */
353 xxxxxxx.
354 x.....x.
355 x.....x.
356 x.....x.
357 x.....x.
358 x.....x.
359 x.....x.
360 x.....x.
361 x.....x.
362 x.....x.
363 x.....x.
364 x.....x.
365 xxxxxxx.
367 static unsigned short hollow_rectangle_bits[] = {
368 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe};
370 /* Hollow square bitmap. */
372 .xxxxxx.
373 .x....x.
374 .x....x.
375 .x....x.
376 .x....x.
377 .xxxxxx.
379 static unsigned short hollow_square_bits[] = {
380 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
382 /* Filled square bitmap. */
384 .xxxxxx.
385 .xxxxxx.
386 .xxxxxx.
387 .xxxxxx.
388 .xxxxxx.
389 .xxxxxx.
391 static unsigned short filled_square_bits[] = {
392 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e};
394 /* Bar cursor bitmap. A vertical bar; max 13 pixels high. */
396 xx......
397 xx......
398 xx......
399 xx......
400 xx......
401 xx......
402 xx......
403 xx......
404 xx......
405 xx......
406 xx......
407 xx......
408 xx......
410 static unsigned short vertical_bar_bits[] = {
411 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
413 /* HBar cursor bitmap. A horizontal bar; 2 pixels high. */
415 xxxxxxx.
416 xxxxxxx.
418 static unsigned short horizontal_bar_bits[] = {
419 0xfe, 0xfe};
422 /* Bitmap drawn to indicate lines not displaying text if
423 `indicate-empty-lines' is non-nil. */
425 ........
426 ..xxxx..
427 ........
428 ........
429 ..xxxx..
430 ........
432 static unsigned short empty_line_bits[] = {
433 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
434 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
435 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
436 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
437 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
438 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
439 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
440 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
443 #define BYTES_PER_BITMAP_ROW (sizeof (unsigned short))
444 #define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
445 #define FRBITS(bits) bits, STANDARD_BITMAP_HEIGHT (bits)
447 /* NOTE: The order of these bitmaps must match the sequence
448 used in fringe.el to define the corresponding symbols. */
450 struct fringe_bitmap standard_bitmaps[] =
452 { NULL, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */
453 { FRBITS (question_mark_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
454 { FRBITS (left_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
455 { FRBITS (right_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
456 { FRBITS (up_arrow_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
457 { FRBITS (down_arrow_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
458 { FRBITS (left_curly_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
459 { FRBITS (right_curly_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
460 { FRBITS (left_triangle_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
461 { FRBITS (right_triangle_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
462 { FRBITS (top_left_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
463 { FRBITS (top_right_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
464 { FRBITS (bottom_left_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
465 { FRBITS (bottom_right_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
466 { FRBITS (left_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
467 { FRBITS (right_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
468 { FRBITS (filled_rectangle_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
469 { FRBITS (hollow_rectangle_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
470 { FRBITS (filled_square_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
471 { FRBITS (hollow_square_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
472 { FRBITS (vertical_bar_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
473 { FRBITS (horizontal_bar_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
474 { FRBITS (empty_line_bits), 8, 3, ALIGN_BITMAP_TOP, 0 },
477 #define NO_FRINGE_BITMAP 0
478 #define UNDEF_FRINGE_BITMAP 1
479 #define MAX_STANDARD_FRINGE_BITMAPS (sizeof(standard_bitmaps)/sizeof(standard_bitmaps[0]))
481 static struct fringe_bitmap **fringe_bitmaps;
482 static Lisp_Object *fringe_faces;
483 static int max_fringe_bitmaps;
485 int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS;
488 /* Lookup bitmap number for symbol BITMAP.
489 Return 0 if not a bitmap. */
492 lookup_fringe_bitmap (bitmap)
493 Lisp_Object bitmap;
495 int bn;
497 bitmap = Fget (bitmap, Qfringe);
498 if (!INTEGERP (bitmap))
499 return 0;
501 bn = XINT (bitmap);
502 if (bn > NO_FRINGE_BITMAP
503 && bn < max_used_fringe_bitmap
504 && (bn < MAX_STANDARD_FRINGE_BITMAPS
505 || fringe_bitmaps[bn] != NULL))
506 return bn;
508 return 0;
511 /* Get fringe bitmap name for bitmap number BN.
513 Found by traversing Vfringe_bitmaps comparing BN to the
514 fringe property for each symbol.
516 Return BN if not found in Vfringe_bitmaps. */
518 static Lisp_Object
519 get_fringe_bitmap_name (bn)
520 int bn;
522 Lisp_Object bitmaps;
523 Lisp_Object num;
525 /* Zero means no bitmap -- return nil. */
526 if (bn <= 0)
527 return Qnil;
529 bitmaps = Vfringe_bitmaps;
530 num = make_number (bn);
532 while (CONSP (bitmaps))
534 Lisp_Object bitmap = XCAR (bitmaps);
535 if (EQ (num, Fget (bitmap, Qfringe)))
536 return bitmap;
537 bitmaps = XCDR (bitmaps);
540 return num;
544 /* Draw the bitmap WHICH in one of the left or right fringes of
545 window W. ROW is the glyph row for which to display the bitmap; it
546 determines the vertical position at which the bitmap has to be
547 drawn.
548 LEFT_P is 1 for left fringe, 0 for right fringe.
551 static void
552 draw_fringe_bitmap_1 (w, row, left_p, overlay, which)
553 struct window *w;
554 struct glyph_row *row;
555 int left_p, overlay;
556 int which;
558 struct frame *f = XFRAME (WINDOW_FRAME (w));
559 struct draw_fringe_bitmap_params p;
560 struct fringe_bitmap *fb;
561 int period;
562 int face_id = DEFAULT_FACE_ID;
564 p.cursor_p = 0;
565 p.overlay_p = (overlay & 1) == 1;
566 p.cursor_p = (overlay & 2) == 2;
568 if (which != NO_FRINGE_BITMAP)
571 else if (left_p)
573 which = row->left_fringe_bitmap;
574 face_id = row->left_fringe_face_id;
576 else
578 which = row->right_fringe_bitmap;
579 face_id = row->right_fringe_face_id;
582 if (face_id == DEFAULT_FACE_ID)
584 Lisp_Object face;
586 if ((face = fringe_faces[which], NILP (face))
587 || (face_id = lookup_derived_face (f, face, FRINGE_FACE_ID, 0),
588 face_id < 0))
589 face_id = FRINGE_FACE_ID;
592 fb = fringe_bitmaps[which];
593 if (fb == NULL)
594 fb = &standard_bitmaps[which < MAX_STANDARD_FRINGE_BITMAPS
595 ? which : UNDEF_FRINGE_BITMAP];
597 period = fb->period;
599 /* Convert row to frame coordinates. */
600 p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
602 p.which = which;
603 p.bits = fb->bits;
604 p.wd = fb->width;
606 p.h = fb->height;
607 p.dh = (period > 0 ? (p.y % period) : 0);
608 p.h -= p.dh;
609 /* Clip bitmap if too high. */
610 if (p.h > row->height)
611 p.h = row->height;
613 p.face = FACE_FROM_ID (f, face_id);
615 if (p.face == NULL)
617 /* This could happen after clearing face cache.
618 But it shouldn't happen anymore. ++kfs */
619 return;
622 PREPARE_FACE_FOR_DISPLAY (f, p.face);
624 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
625 the fringe. */
626 p.bx = -1;
627 if (left_p)
629 int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
630 int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
631 ? LEFT_MARGIN_AREA
632 : TEXT_AREA));
633 if (p.wd > wd)
634 p.wd = wd;
635 p.x = x - p.wd - (wd - p.wd) / 2;
637 if (p.wd < wd || row->height > p.h)
639 /* If W has a vertical border to its left, don't draw over it. */
640 wd -= ((!WINDOW_LEFTMOST_P (w)
641 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
642 ? 1 : 0);
643 p.bx = x - wd;
644 p.nx = wd;
647 else
649 int x = window_box_right (w,
650 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
651 ? RIGHT_MARGIN_AREA
652 : TEXT_AREA));
653 int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
654 if (p.wd > wd)
655 p.wd = wd;
656 p.x = x + (wd - p.wd) / 2;
657 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
658 the fringe. */
659 if (p.wd < wd || row->height > p.h)
661 p.bx = x;
662 p.nx = wd;
666 if (p.bx >= 0)
668 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
670 p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
671 p.ny = row->visible_height;
674 /* Adjust y to the offset in the row to start drawing the bitmap. */
675 switch (fb->align)
677 case ALIGN_BITMAP_CENTER:
678 p.y += (row->height - p.h) / 2;
679 break;
680 case ALIGN_BITMAP_BOTTOM:
681 p.h = fb->height;
682 p.y += (row->visible_height - p.h);
683 break;
684 case ALIGN_BITMAP_TOP:
685 break;
688 FRAME_RIF (f)->draw_fringe_bitmap (w, row, &p);
691 static int
692 get_logical_cursor_bitmap (w, cursor)
693 struct window *w;
694 Lisp_Object cursor;
696 Lisp_Object cmap, bm = Qnil;
698 if ((cmap = XBUFFER (w->buffer)->fringe_cursor_alist), !NILP (cmap))
700 bm = Fassq (cursor, cmap);
701 if (CONSP (bm))
703 if ((bm = XCDR (bm)), NILP (bm))
704 return NO_FRINGE_BITMAP;
705 return lookup_fringe_bitmap (bm);
708 if (EQ (cmap, buffer_defaults.fringe_cursor_alist))
709 return NO_FRINGE_BITMAP;
710 bm = Fassq (cursor, buffer_defaults.fringe_cursor_alist);
711 if (!CONSP (bm) || ((bm = XCDR (bm)), NILP (bm)))
712 return NO_FRINGE_BITMAP;
713 return lookup_fringe_bitmap (bm);
716 static int
717 get_logical_fringe_bitmap (w, bitmap, right_p, partial_p)
718 struct window *w;
719 Lisp_Object bitmap;
720 int right_p, partial_p;
722 Lisp_Object cmap, bm1 = Qnil, bm2 = Qnil, bm;
723 int ln1 = 0, ln2 = 0;
724 int ix1 = right_p;
725 int ix2 = ix1 + (partial_p ? 2 : 0);
727 /* Lookup in buffer-local fringe-indicator-alist before global alist.
729 Elements are:
730 BITMAP -- use for all
731 (L R) -- use for left right (whether partial or not)
732 (L R PL PR) -- use for left rigth partial-left partial-right
733 If any value in local binding is not present or t, use global value.
735 If partial, lookup partial bitmap in default value if not found here.
736 If not partial, or no partial spec is present, use non-partial bitmap. */
738 if ((cmap = XBUFFER (w->buffer)->fringe_indicator_alist), !NILP (cmap))
740 bm1 = Fassq (bitmap, cmap);
741 if (CONSP (bm1))
743 if ((bm1 = XCDR (bm1)), NILP (bm1))
744 return NO_FRINGE_BITMAP;
745 if (CONSP (bm1))
747 ln1 = XINT (Flength (bm1));
748 if (partial_p)
750 if (ln1 > ix2)
752 bm = Fnth (make_number (ix2), bm1);
753 if (!EQ (bm, Qt))
754 goto found;
757 else
759 if (ln1 > ix1)
761 bm = Fnth (make_number (ix1), bm1);
762 if (!EQ (bm, Qt))
763 goto found;
767 else if ((bm = bm1, !EQ (bm, Qt)))
768 goto found;
772 if (!EQ (cmap, buffer_defaults.fringe_indicator_alist)
773 && !NILP (buffer_defaults.fringe_indicator_alist))
775 bm2 = Fassq (bitmap, buffer_defaults.fringe_indicator_alist);
776 if (CONSP (bm2))
778 if ((bm2 = XCDR (bm2)), !NILP (bm2))
780 if (CONSP (bm2))
782 ln2 = XINT (Flength (bm2));
783 if (partial_p)
785 if (ln2 > ix2)
787 bm = Fnth (make_number (ix2), bm2);
788 if (!EQ (bm, Qt))
789 goto found;
797 if (ln1 > ix1)
799 bm = Fnth (make_number (ix1), bm1);
800 if (!EQ (bm, Qt))
801 goto found;
804 if (ln2 > ix1)
806 bm = Fnth (make_number (ix1), bm2);
807 if (!EQ (bm, Qt))
808 goto found;
809 return NO_FRINGE_BITMAP;
811 else if ((bm = bm2, NILP (bm)))
812 return NO_FRINGE_BITMAP;
814 found:
815 return lookup_fringe_bitmap (bm);
819 void
820 draw_fringe_bitmap (w, row, left_p)
821 struct window *w;
822 struct glyph_row *row;
823 int left_p;
825 int overlay = 0;
827 if (!left_p && row->cursor_in_fringe_p)
829 Lisp_Object cursor = Qnil;
831 switch (w->phys_cursor_type)
833 case HOLLOW_BOX_CURSOR:
834 if (row->visible_height >= STANDARD_BITMAP_HEIGHT (hollow_rectangle_bits))
835 cursor = Qhollow;
836 else
837 cursor = Qhollow_small;
838 break;
839 case FILLED_BOX_CURSOR:
840 cursor = Qbox;
841 break;
842 case BAR_CURSOR:
843 cursor = Qbar;
844 break;
845 case HBAR_CURSOR:
846 cursor = Qhbar;
847 break;
848 case NO_CURSOR:
849 default:
850 w->phys_cursor_on_p = 0;
851 row->cursor_in_fringe_p = 0;
852 break;
854 if (!NILP (cursor))
856 int bm = get_logical_cursor_bitmap (w, cursor);
857 if (bm != NO_FRINGE_BITMAP)
859 draw_fringe_bitmap_1 (w, row, 0, 2, bm);
860 overlay = EQ (cursor, Qbox) ? 3 : 1;
865 draw_fringe_bitmap_1 (w, row, left_p, overlay, NO_FRINGE_BITMAP);
867 if (left_p && row->overlay_arrow_bitmap != NO_FRINGE_BITMAP)
868 draw_fringe_bitmap_1 (w, row, 1, 1, row->overlay_arrow_bitmap);
872 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
873 function with input blocked. */
875 void
876 draw_row_fringe_bitmaps (w, row)
877 struct window *w;
878 struct glyph_row *row;
880 xassert (interrupt_input_blocked);
882 /* If row is completely invisible, because of vscrolling, we
883 don't have to draw anything. */
884 if (row->visible_height <= 0)
885 return;
887 if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
888 draw_fringe_bitmap (w, row, 1);
890 if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
891 draw_fringe_bitmap (w, row, 0);
894 /* Draw the fringes of window W. Only fringes for rows marked for
895 update in redraw_fringe_bitmaps_p are drawn.
897 Return >0 if left or right fringe was redrawn in any way.
899 If NO_FRINGE is non-zero, also return >0 if either fringe has zero width.
901 A return value >0 indicates that the vertical line between windows
902 needs update (as it may be drawn in the fringe).
906 draw_window_fringes (w, no_fringe)
907 struct window *w;
908 int no_fringe;
910 struct glyph_row *row;
911 int yb = window_text_bottom_y (w);
912 int nrows = w->current_matrix->nrows;
913 int y = 0, rn;
914 int updated = 0;
916 if (w->pseudo_window_p)
917 return 0;
919 /* Must draw line if no fringe */
920 if (no_fringe
921 && (WINDOW_LEFT_FRINGE_WIDTH (w) == 0
922 || WINDOW_RIGHT_FRINGE_WIDTH (w) == 0))
923 updated++;
925 for (y = 0, rn = 0, row = w->current_matrix->rows;
926 y < yb && rn < nrows;
927 y += row->height, ++row, ++rn)
929 if (!row->redraw_fringe_bitmaps_p)
930 continue;
931 draw_row_fringe_bitmaps (w, row);
932 row->redraw_fringe_bitmaps_p = 0;
933 updated++;
936 return updated;
940 /* Recalculate the bitmaps to show in the fringes of window W.
941 Only mark rows with modified bitmaps for update in redraw_fringe_bitmaps_p.
943 If KEEP_CURRENT_P is 0, update current_matrix too. */
946 update_window_fringes (w, keep_current_p)
947 struct window *w;
948 int keep_current_p;
950 struct glyph_row *row, *cur = 0;
951 int yb = window_text_bottom_y (w);
952 int rn, nrows = w->current_matrix->nrows;
953 int y;
954 int redraw_p = 0;
955 Lisp_Object boundary_top = Qnil, boundary_bot = Qnil;
956 Lisp_Object arrow_top = Qnil, arrow_bot = Qnil;
957 Lisp_Object empty_pos;
958 Lisp_Object ind = Qnil;
959 #define MAX_BITMAP_CACHE (8*4)
960 int bitmap_cache[MAX_BITMAP_CACHE];
962 if (w->pseudo_window_p)
963 return 0;
965 if (!MINI_WINDOW_P (w)
966 && (ind = XBUFFER (w->buffer)->indicate_buffer_boundaries, !NILP (ind)))
968 if (EQ (ind, Qleft) || EQ (ind, Qright))
969 boundary_top = boundary_bot = arrow_top = arrow_bot = ind;
970 else if (CONSP (ind) && CONSP (XCAR (ind)))
972 Lisp_Object pos;
973 if (pos = Fassq (Qt, ind), !NILP (pos))
974 boundary_top = boundary_bot = arrow_top = arrow_bot = XCDR (pos);
975 if (pos = Fassq (Qtop, ind), !NILP (pos))
976 boundary_top = XCDR (pos);
977 if (pos = Fassq (Qbottom, ind), !NILP (pos))
978 boundary_bot = XCDR (pos);
979 if (pos = Fassq (Qup, ind), !NILP (pos))
980 arrow_top = XCDR (pos);
981 if (pos = Fassq (Qdown, ind), !NILP (pos))
982 arrow_bot = XCDR (pos);
984 else
985 /* Anything else means boundary on left and no arrows. */
986 boundary_top = boundary_bot = Qleft;
989 if (!NILP (ind))
991 int done_top = 0, done_bot = 0;
993 for (y = 0, rn = 0;
994 y < yb && rn < nrows;
995 y += row->height, ++rn)
997 unsigned indicate_bob_p, indicate_top_line_p;
998 unsigned indicate_eob_p, indicate_bottom_line_p;
1000 row = w->desired_matrix->rows + rn;
1001 if (!row->enabled_p)
1002 row = w->current_matrix->rows + rn;
1004 indicate_bob_p = row->indicate_bob_p;
1005 indicate_top_line_p = row->indicate_top_line_p;
1006 indicate_eob_p = row->indicate_eob_p;
1007 indicate_bottom_line_p = row->indicate_bottom_line_p;
1009 row->indicate_bob_p = row->indicate_top_line_p = 0;
1010 row->indicate_eob_p = row->indicate_bottom_line_p = 0;
1012 if (!row->mode_line_p)
1014 if (!done_top)
1016 if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer))
1017 && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
1018 row->indicate_bob_p = !NILP (boundary_top);
1019 else
1020 row->indicate_top_line_p = !NILP (arrow_top);
1021 done_top = 1;
1024 if (!done_bot)
1026 if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer))
1027 && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row))
1028 row->indicate_eob_p = !NILP (boundary_bot), done_bot = 1;
1029 else if (y + row->height >= yb)
1030 row->indicate_bottom_line_p = !NILP (arrow_bot), done_bot = 1;
1034 if (indicate_bob_p != row->indicate_bob_p
1035 || indicate_top_line_p != row->indicate_top_line_p
1036 || indicate_eob_p != row->indicate_eob_p
1037 || indicate_bottom_line_p != row->indicate_bottom_line_p)
1038 row->redraw_fringe_bitmaps_p = 1;
1042 empty_pos = XBUFFER (w->buffer)->indicate_empty_lines;
1043 if (!NILP (empty_pos) && !EQ (empty_pos, Qright))
1044 empty_pos = WINDOW_LEFT_FRINGE_WIDTH (w) == 0 ? Qright : Qleft;
1046 for (y = 0; y < MAX_BITMAP_CACHE; y++)
1047 bitmap_cache[y] = -1;
1049 #define LEFT_FRINGE(cache, which, partial_p) \
1050 (bitmap_cache[cache*4+partial_p] >= 0 \
1051 ? bitmap_cache[cache*4+partial_p] \
1052 : (bitmap_cache[cache*4+partial_p] = \
1053 get_logical_fringe_bitmap (w, which, 0, partial_p)))
1055 #define RIGHT_FRINGE(cache, which, partial_p) \
1056 (bitmap_cache[cache*4+2+partial_p] >= 0 \
1057 ? bitmap_cache[cache*4+2+partial_p] \
1058 : (bitmap_cache[cache*4+2+partial_p] = \
1059 get_logical_fringe_bitmap (w, which, 1, partial_p)))
1062 for (y = 0, rn = 0;
1063 y < yb && rn < nrows;
1064 y += row->height, rn++)
1066 int left, right;
1067 unsigned left_face_id, right_face_id;
1069 row = w->desired_matrix->rows + rn;
1070 cur = w->current_matrix->rows + rn;
1071 if (!row->enabled_p)
1072 row = cur;
1074 left_face_id = right_face_id = DEFAULT_FACE_ID;
1076 /* Decide which bitmap to draw in the left fringe. */
1077 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
1078 left = NO_FRINGE_BITMAP;
1079 else if (row->left_user_fringe_bitmap != NO_FRINGE_BITMAP)
1081 left = row->left_user_fringe_bitmap;
1082 left_face_id = row->left_user_fringe_face_id;
1084 else if (row->truncated_on_left_p)
1085 left = LEFT_FRINGE(0, Qtruncation, 0);
1086 else if (row->indicate_bob_p && EQ (boundary_top, Qleft))
1087 left = ((row->indicate_eob_p && EQ (boundary_bot, Qleft))
1088 ? LEFT_FRINGE (1, Qtop_bottom, row->ends_at_zv_p)
1089 : LEFT_FRINGE (2, Qtop, 0));
1090 else if (row->indicate_eob_p && EQ (boundary_bot, Qleft))
1091 left = LEFT_FRINGE (3, Qbottom, row->ends_at_zv_p);
1092 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
1093 left = LEFT_FRINGE (4, Qcontinuation, 0);
1094 else if (row->indicate_empty_line_p && EQ (empty_pos, Qleft))
1095 left = LEFT_FRINGE (5, Qempty_line, 0);
1096 else if (row->indicate_top_line_p && EQ (arrow_top, Qleft))
1097 left = LEFT_FRINGE (6, Qup, 0);
1098 else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qleft))
1099 left = LEFT_FRINGE (7, Qdown, 0);
1100 else
1101 left = NO_FRINGE_BITMAP;
1103 /* Decide which bitmap to draw in the right fringe. */
1104 if (WINDOW_RIGHT_FRINGE_WIDTH (w) == 0)
1105 right = NO_FRINGE_BITMAP;
1106 else if (row->right_user_fringe_bitmap != NO_FRINGE_BITMAP)
1108 right = row->right_user_fringe_bitmap;
1109 right_face_id = row->right_user_fringe_face_id;
1111 else if (row->truncated_on_right_p)
1112 right = RIGHT_FRINGE (0, Qtruncation, 0);
1113 else if (row->indicate_bob_p && EQ (boundary_top, Qright))
1114 right = ((row->indicate_eob_p && EQ (boundary_bot, Qright))
1115 ? RIGHT_FRINGE (1, Qtop_bottom, row->ends_at_zv_p)
1116 : RIGHT_FRINGE (2, Qtop, 0));
1117 else if (row->indicate_eob_p && EQ (boundary_bot, Qright))
1118 right = RIGHT_FRINGE (3, Qbottom, row->ends_at_zv_p);
1119 else if (row->continued_p)
1120 right = RIGHT_FRINGE (4, Qcontinuation, 0);
1121 else if (row->indicate_top_line_p && EQ (arrow_top, Qright))
1122 right = RIGHT_FRINGE (6, Qup, 0);
1123 else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qright))
1124 right = RIGHT_FRINGE (7, Qdown, 0);
1125 else if (row->indicate_empty_line_p && EQ (empty_pos, Qright))
1126 right = RIGHT_FRINGE (5, Qempty_line, 0);
1127 else
1128 right = NO_FRINGE_BITMAP;
1130 if (row->y != cur->y
1131 || row->visible_height != cur->visible_height
1132 || row->ends_at_zv_p != cur->ends_at_zv_p
1133 || left != cur->left_fringe_bitmap
1134 || right != cur->right_fringe_bitmap
1135 || left_face_id != cur->left_fringe_face_id
1136 || right_face_id != cur->right_fringe_face_id
1137 || cur->redraw_fringe_bitmaps_p)
1139 redraw_p = row->redraw_fringe_bitmaps_p = 1;
1140 if (!keep_current_p)
1142 cur->redraw_fringe_bitmaps_p = 1;
1143 cur->left_fringe_bitmap = left;
1144 cur->right_fringe_bitmap = right;
1145 cur->left_fringe_face_id = left_face_id;
1146 cur->right_fringe_face_id = right_face_id;
1150 if (row->overlay_arrow_bitmap < 0)
1151 row->overlay_arrow_bitmap = get_logical_fringe_bitmap (w, Qoverlay_arrow, 0, 0);
1153 if (row->overlay_arrow_bitmap != cur->overlay_arrow_bitmap)
1155 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
1156 cur->overlay_arrow_bitmap = row->overlay_arrow_bitmap;
1159 row->left_fringe_bitmap = left;
1160 row->right_fringe_bitmap = right;
1161 row->left_fringe_face_id = left_face_id;
1162 row->right_fringe_face_id = right_face_id;
1164 if (rn > 0 && row->redraw_fringe_bitmaps_p)
1165 row[-1].redraw_fringe_bitmaps_p = cur[-1].redraw_fringe_bitmaps_p = 1;
1168 return redraw_p && !keep_current_p;
1172 /* Compute actual fringe widths for frame F.
1174 If REDRAW is 1, redraw F if the fringe settings was actually
1175 modified and F is visible.
1177 Since the combined left and right fringe must occupy an integral
1178 number of columns, we may need to add some pixels to each fringe.
1179 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
1180 but a negative width value is taken literally (after negating it).
1182 We never make the fringes narrower than specified.
1185 void
1186 compute_fringe_widths (f, redraw)
1187 struct frame *f;
1188 int redraw;
1190 int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
1191 int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
1192 int o_cols = FRAME_FRINGE_COLS (f);
1194 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
1195 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
1196 int left_fringe_width, right_fringe_width;
1198 if (!NILP (left_fringe))
1199 left_fringe = Fcdr (left_fringe);
1200 if (!NILP (right_fringe))
1201 right_fringe = Fcdr (right_fringe);
1203 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
1204 XINT (left_fringe));
1205 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
1206 XINT (right_fringe));
1208 if (left_fringe_width || right_fringe_width)
1210 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
1211 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
1212 int conf_wid = left_wid + right_wid;
1213 int font_wid = FRAME_COLUMN_WIDTH (f);
1214 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
1215 int real_wid = cols * font_wid;
1216 if (left_wid && right_wid)
1218 if (left_fringe_width < 0)
1220 /* Left fringe width is fixed, adjust right fringe if necessary */
1221 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
1222 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
1224 else if (right_fringe_width < 0)
1226 /* Right fringe width is fixed, adjust left fringe if necessary */
1227 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
1228 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
1230 else
1232 /* Adjust both fringes with an equal amount.
1233 Note that we are doing integer arithmetic here, so don't
1234 lose a pixel if the total width is an odd number. */
1235 int fill = real_wid - conf_wid;
1236 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
1237 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
1240 else if (left_fringe_width)
1242 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
1243 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
1245 else
1247 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
1248 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
1250 FRAME_FRINGE_COLS (f) = cols;
1252 else
1254 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
1255 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
1256 FRAME_FRINGE_COLS (f) = 0;
1259 if (redraw && FRAME_VISIBLE_P (f))
1260 if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
1261 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
1262 o_cols != FRAME_FRINGE_COLS (f))
1263 redraw_frame (f);
1267 /* Free resources used by a user-defined bitmap. */
1269 void
1270 destroy_fringe_bitmap (n)
1271 int n;
1273 struct fringe_bitmap **fbp;
1275 fringe_faces[n] = Qnil;
1277 fbp = &fringe_bitmaps[n];
1278 if (*fbp && (*fbp)->dynamic)
1280 /* XXX Is SELECTED_FRAME OK here? */
1281 struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
1282 if (rif && rif->destroy_fringe_bitmap)
1283 rif->destroy_fringe_bitmap (n);
1284 xfree (*fbp);
1285 *fbp = NULL;
1288 while (max_used_fringe_bitmap > MAX_STANDARD_FRINGE_BITMAPS
1289 && fringe_bitmaps[max_used_fringe_bitmap - 1] == NULL)
1290 max_used_fringe_bitmap--;
1294 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap, Sdestroy_fringe_bitmap,
1295 1, 1, 0,
1296 doc: /* Destroy fringe bitmap BITMAP.
1297 If BITMAP overrides a standard fringe bitmap, the original bitmap is restored. */)
1298 (bitmap)
1299 Lisp_Object bitmap;
1301 int n;
1303 CHECK_SYMBOL (bitmap);
1304 n = lookup_fringe_bitmap (bitmap);
1305 if (!n)
1306 return Qnil;
1308 destroy_fringe_bitmap (n);
1310 if (n >= MAX_STANDARD_FRINGE_BITMAPS)
1312 Vfringe_bitmaps = Fdelq (bitmap, Vfringe_bitmaps);
1313 /* It would be better to remove the fringe property. */
1314 Fput (bitmap, Qfringe, Qnil);
1317 return Qnil;
1321 /* Initialize bitmap bit.
1323 On X, we bit-swap the built-in bitmaps and reduce bitmap
1324 from short to char array if width is <= 8 bits.
1326 On MAC with big-endian CPU, we need to byte-swap each short.
1328 On W32 and MAC (little endian), there's no need to do this.
1331 #if defined (HAVE_X_WINDOWS)
1332 static unsigned char swap_nibble[16] = {
1333 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1334 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1335 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1336 0x3, 0xb, 0x7, 0xf}; /* 0011 1011 0111 1111 */
1337 #endif /* HAVE_X_WINDOWS */
1339 void
1340 init_fringe_bitmap (which, fb, once_p)
1341 int which;
1342 struct fringe_bitmap *fb;
1343 int once_p;
1345 if (once_p || fb->dynamic)
1347 #if defined (HAVE_X_WINDOWS)
1348 unsigned short *bits = fb->bits;
1349 int j;
1351 if (fb->width <= 8)
1353 unsigned char *cbits = (unsigned char *)fb->bits;
1354 for (j = 0; j < fb->height; j++)
1356 unsigned short b = *bits++;
1357 unsigned char c;
1358 c = (unsigned char)((swap_nibble[b & 0xf] << 4)
1359 | (swap_nibble[(b>>4) & 0xf]));
1360 *cbits++ = (c >> (8 - fb->width));
1363 else
1365 for (j = 0; j < fb->height; j++)
1367 unsigned short b = *bits;
1368 b = (unsigned short)((swap_nibble[b & 0xf] << 12)
1369 | (swap_nibble[(b>>4) & 0xf] << 8)
1370 | (swap_nibble[(b>>8) & 0xf] << 4)
1371 | (swap_nibble[(b>>12) & 0xf]));
1372 *bits++ = (b >> (16 - fb->width));
1375 #endif /* HAVE_X_WINDOWS */
1379 if (!once_p)
1381 /* XXX Is SELECTED_FRAME OK here? */
1382 struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
1384 destroy_fringe_bitmap (which);
1386 if (rif && rif->define_fringe_bitmap)
1387 rif->define_fringe_bitmap (which, fb->bits, fb->height, fb->width);
1389 fringe_bitmaps[which] = fb;
1390 if (which >= max_used_fringe_bitmap)
1391 max_used_fringe_bitmap = which + 1;
1396 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap,
1397 2, 5, 0,
1398 doc: /* Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH.
1399 BITMAP is a symbol identifying the new fringe bitmap.
1400 BITS is either a string or a vector of integers.
1401 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1402 WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1403 Optional fifth arg ALIGN may be one of `top', `center', or `bottom',
1404 indicating the positioning of the bitmap relative to the rows where it
1405 is used; the default is to center the bitmap. Fifth arg may also be a
1406 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1407 should be repeated.
1408 If BITMAP already exists, the existing definition is replaced. */)
1409 (bitmap, bits, height, width, align)
1410 Lisp_Object bitmap, bits, height, width, align;
1412 int n, h, i, j;
1413 unsigned short *b;
1414 struct fringe_bitmap fb, *xfb;
1415 int fill1 = 0, fill2 = 0;
1417 CHECK_SYMBOL (bitmap);
1419 if (STRINGP (bits))
1420 h = SCHARS (bits);
1421 else if (VECTORP (bits))
1422 h = XVECTOR (bits)->size;
1423 else
1424 wrong_type_argument (Qsequencep, bits);
1426 if (NILP (height))
1427 fb.height = h;
1428 else
1430 CHECK_NUMBER (height);
1431 fb.height = min (XINT (height), 255);
1432 if (fb.height > h)
1434 fill1 = (fb.height - h) / 2;
1435 fill2 = fb.height - h - fill1;
1439 if (NILP (width))
1440 fb.width = 8;
1441 else
1443 CHECK_NUMBER (width);
1444 fb.width = min (XINT (width), 255);
1447 fb.period = 0;
1448 fb.align = ALIGN_BITMAP_CENTER;
1450 if (CONSP (align))
1452 Lisp_Object period = XCDR (align);
1453 if (CONSP (period))
1455 period = XCAR (period);
1456 if (!NILP (period))
1458 fb.period = fb.height;
1459 fb.height = 255;
1462 align = XCAR (align);
1464 if (EQ (align, Qtop))
1465 fb.align = ALIGN_BITMAP_TOP;
1466 else if (EQ (align, Qbottom))
1467 fb.align = ALIGN_BITMAP_BOTTOM;
1468 else if (!NILP (align) && !EQ (align, Qcenter))
1469 error ("Bad align argument");
1471 n = lookup_fringe_bitmap (bitmap);
1472 if (!n)
1474 if (max_used_fringe_bitmap < max_fringe_bitmaps)
1475 n = max_used_fringe_bitmap++;
1476 else
1478 for (n = MAX_STANDARD_FRINGE_BITMAPS;
1479 n < max_fringe_bitmaps;
1480 n++)
1481 if (fringe_bitmaps[n] == NULL)
1482 break;
1484 if (n == max_fringe_bitmaps)
1486 if ((max_fringe_bitmaps + 20) > MAX_FRINGE_BITMAPS)
1487 error ("No free fringe bitmap slots");
1489 i = max_fringe_bitmaps;
1490 max_fringe_bitmaps += 20;
1491 fringe_bitmaps
1492 = ((struct fringe_bitmap **)
1493 xrealloc (fringe_bitmaps, max_fringe_bitmaps * sizeof (struct fringe_bitmap *)));
1494 fringe_faces
1495 = (Lisp_Object *) xrealloc (fringe_faces, max_fringe_bitmaps * sizeof (Lisp_Object));
1497 for (; i < max_fringe_bitmaps; i++)
1499 fringe_bitmaps[i] = NULL;
1500 fringe_faces[i] = Qnil;
1505 Vfringe_bitmaps = Fcons (bitmap, Vfringe_bitmaps);
1506 Fput (bitmap, Qfringe, make_number (n));
1509 fb.dynamic = 1;
1511 xfb = (struct fringe_bitmap *) xmalloc (sizeof fb
1512 + fb.height * BYTES_PER_BITMAP_ROW);
1513 fb.bits = b = (unsigned short *) (xfb + 1);
1514 bzero (b, fb.height);
1516 j = 0;
1517 while (j < fb.height)
1519 for (i = 0; i < fill1 && j < fb.height; i++)
1520 b[j++] = 0;
1521 for (i = 0; i < h && j < fb.height; i++)
1523 Lisp_Object elt = Faref (bits, make_number (i));
1524 b[j++] = NUMBERP (elt) ? XINT (elt) : 0;
1526 for (i = 0; i < fill2 && j < fb.height; i++)
1527 b[j++] = 0;
1530 *xfb = fb;
1532 init_fringe_bitmap (n, xfb, 0);
1534 return bitmap;
1537 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face,
1538 1, 2, 0,
1539 doc: /* Set face for fringe bitmap BITMAP to FACE.
1540 If FACE is nil, reset face to default fringe face. */)
1541 (bitmap, face)
1542 Lisp_Object bitmap, face;
1544 int n;
1545 int face_id;
1547 CHECK_SYMBOL (bitmap);
1548 n = lookup_fringe_bitmap (bitmap);
1549 if (!n)
1550 error ("Undefined fringe bitmap");
1552 if (!NILP (face))
1554 face_id = lookup_derived_face (SELECTED_FRAME (), face,
1555 FRINGE_FACE_ID, 1);
1556 if (face_id < 0)
1557 error ("No such face");
1560 fringe_faces[n] = face;
1562 return Qnil;
1565 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos, Sfringe_bitmaps_at_pos,
1566 0, 2, 0,
1567 doc: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1568 If WINDOW is nil, use selected window. If POS is nil, use value of point
1569 in that window. Return value is a list (LEFT RIGHT OV), where LEFT
1570 is the symbol for the bitmap in the left fringe (or nil if no bitmap),
1571 RIGHT is similar for the right fringe, and OV is non-nil if there is an
1572 overlay arrow in the left fringe.
1573 Return nil if POS is not visible in WINDOW. */)
1574 (pos, window)
1575 Lisp_Object pos, window;
1577 struct window *w;
1578 struct glyph_row *row;
1579 int textpos;
1581 if (NILP (window))
1582 window = selected_window;
1583 CHECK_WINDOW (window);
1584 w = XWINDOW (window);
1586 if (!NILP (pos))
1588 CHECK_NUMBER_COERCE_MARKER (pos);
1589 textpos = XINT (pos);
1591 else if (w == XWINDOW (selected_window))
1592 textpos = PT;
1593 else
1594 textpos = XMARKER (w->pointm)->charpos;
1596 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1597 row = row_containing_pos (w, textpos, row, NULL, 0);
1598 if (row)
1599 return list3 (get_fringe_bitmap_name (row->left_fringe_bitmap),
1600 get_fringe_bitmap_name (row->right_fringe_bitmap),
1601 (row->overlay_arrow_bitmap == 0 ? Qnil
1602 : row->overlay_arrow_bitmap < 0 ? Qt
1603 : get_fringe_bitmap_name (row->overlay_arrow_bitmap)));
1604 else
1605 return Qnil;
1609 /***********************************************************************
1610 Initialization
1611 ***********************************************************************/
1613 void
1614 syms_of_fringe ()
1616 Qtruncation = intern ("truncation");
1617 staticpro (&Qtruncation);
1618 Qcontinuation = intern ("continuation");
1619 staticpro (&Qcontinuation);
1620 Qoverlay_arrow = intern ("overlay-arrow");
1621 staticpro (&Qoverlay_arrow);
1622 Qempty_line = intern ("empty-line");
1623 staticpro (&Qempty_line);
1624 Qtop_bottom = intern ("top-bottom");
1625 staticpro (&Qtop_bottom);
1626 Qhollow_small = intern ("hollow-small");
1627 staticpro (&Qhollow_small);
1629 defsubr (&Sdestroy_fringe_bitmap);
1630 defsubr (&Sdefine_fringe_bitmap);
1631 defsubr (&Sfringe_bitmaps_at_pos);
1632 defsubr (&Sset_fringe_bitmap_face);
1634 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe,
1635 doc: /* *Non-nil means that newline may flow into the right fringe.
1636 This means that display lines which are exactly as wide as the window
1637 (not counting the final newline) will only occupy one screen line, by
1638 showing (or hiding) the final newline in the right fringe; when point
1639 is at the final newline, the cursor is shown in the right fringe.
1640 If nil, also continue lines which are exactly as wide as the window. */);
1641 Voverflow_newline_into_fringe = Qt;
1643 DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps,
1644 doc: /* List of fringe bitmap symbols. */);
1645 Vfringe_bitmaps = Qnil;
1648 /* Garbage collection hook */
1650 void
1651 mark_fringe_data ()
1653 int i;
1655 for (i = 0; i < max_fringe_bitmaps; i++)
1656 if (!NILP (fringe_faces[i]))
1657 mark_object (fringe_faces[i]);
1660 /* Initialize this module when Emacs starts. */
1662 void
1663 init_fringe_once ()
1665 int bt;
1667 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1668 init_fringe_bitmap(bt, &standard_bitmaps[bt], 1);
1671 void
1672 init_fringe ()
1674 int i;
1676 max_fringe_bitmaps = MAX_STANDARD_FRINGE_BITMAPS + 20;
1678 fringe_bitmaps
1679 = (struct fringe_bitmap **) xmalloc (max_fringe_bitmaps * sizeof (struct fringe_bitmap *));
1680 fringe_faces
1681 = (Lisp_Object *) xmalloc (max_fringe_bitmaps * sizeof (Lisp_Object));
1683 for (i = 0; i < max_fringe_bitmaps; i++)
1685 fringe_bitmaps[i] = NULL;
1686 fringe_faces[i] = Qnil;
1690 #ifdef HAVE_NTGUI
1692 void
1693 w32_init_fringe (struct redisplay_interface *rif)
1695 int bt;
1697 if (!rif)
1698 return;
1700 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1702 struct fringe_bitmap *fb = &standard_bitmaps[bt];
1703 rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
1707 void
1708 w32_reset_fringes ()
1710 /* Destroy row bitmaps. */
1711 int bt;
1712 struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
1714 if (!rif)
1715 return;
1717 for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++)
1718 rif->destroy_fringe_bitmap (bt);
1721 #endif /* HAVE_NTGUI */
1723 #endif /* HAVE_WINDOW_SYSTEM */
1725 /* arch-tag: 04596920-43eb-473d-b319-82712338162d
1726 (do not change this comment) */