(update_window_fringes): Handle new formats of
[emacs.git] / src / fringe.c
blob03cd5fe93afdf9b60f5fc508d49c898276076d6f
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.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 #include <config.h>
23 #include <stdio.h>
25 #include "lisp.h"
26 #include "frame.h"
27 #include "window.h"
28 #include "dispextern.h"
29 #include "buffer.h"
30 #include "blockinput.h"
32 #ifdef HAVE_WINDOW_SYSTEM
34 extern Lisp_Object Qtop, Qbottom, Qcenter;
35 extern Lisp_Object Qup, Qdown, Qleft, Qright;
37 /* Non-nil means that newline may flow into the right fringe. */
39 Lisp_Object Voverflow_newline_into_fringe;
42 enum fringe_bitmap_type
44 NO_FRINGE_BITMAP = 0,
45 UNDEF_FRINGE_BITMAP,
46 LEFT_TRUNCATION_BITMAP,
47 RIGHT_TRUNCATION_BITMAP,
48 UP_ARROW_BITMAP,
49 DOWN_ARROW_BITMAP,
50 CONTINUED_LINE_BITMAP,
51 CONTINUATION_LINE_BITMAP,
52 OVERLAY_ARROW_BITMAP,
53 TOP_LEFT_ANGLE_BITMAP,
54 TOP_RIGHT_ANGLE_BITMAP,
55 BOTTOM_LEFT_ANGLE_BITMAP,
56 BOTTOM_RIGHT_ANGLE_BITMAP,
57 LEFT_BRACKET_BITMAP,
58 RIGHT_BRACKET_BITMAP,
59 FILLED_BOX_CURSOR_BITMAP,
60 HOLLOW_BOX_CURSOR_BITMAP,
61 HOLLOW_SQUARE_BITMAP,
62 BAR_CURSOR_BITMAP,
63 HBAR_CURSOR_BITMAP,
64 ZV_LINE_BITMAP,
65 MAX_STANDARD_FRINGE_BITMAPS
68 enum fringe_bitmap_align
70 ALIGN_BITMAP_CENTER = 0,
71 ALIGN_BITMAP_TOP,
72 ALIGN_BITMAP_BOTTOM
75 struct fringe_bitmap
77 unsigned short *bits;
78 unsigned height : 8;
79 unsigned width : 8;
80 unsigned period : 8;
81 unsigned align : 2;
82 unsigned dynamic : 1;
86 /***********************************************************************
87 Fringe bitmaps
88 ***********************************************************************/
90 /* Undefined bitmap. A question mark. */
92 ..xxxx..
93 .xxxxxx.
94 xx....xx
95 xx....xx
96 ....xx..
97 ...xx...
98 ...xx...
99 ........
100 ...xx...
101 ...xx...
103 static unsigned short unknown_bits[] = {
104 0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
106 /* An arrow like this: `<-'. */
108 ...xx...
109 ..xx....
110 .xx.....
111 xxxxxx..
112 xxxxxx..
113 .xx.....
114 ..xx....
115 ...xx...
117 static unsigned short left_arrow_bits[] = {
118 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
121 /* Right truncation arrow bitmap `->'. */
123 ...xx...
124 ....xx..
125 .....xx.
126 ..xxxxxx
127 ..xxxxxx
128 .....xx.
129 ....xx..
130 ...xx...
132 static unsigned short right_arrow_bits[] = {
133 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
136 /* Up arrow bitmap. */
138 ...xx...
139 ..xxxx..
140 .xxxxxx.
141 xxxxxxxx
142 ...xx...
143 ...xx...
144 ...xx...
145 ...xx...
147 static unsigned short up_arrow_bits[] = {
148 0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
151 /* Down arrow bitmap. */
153 ...xx...
154 ...xx...
155 ...xx...
156 ...xx...
157 xxxxxxxx
158 .xxxxxx.
159 ..xxxx..
160 ...xx...
162 static unsigned short down_arrow_bits[] = {
163 0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
165 /* Marker for continued lines. */
167 ..xxxx..
168 ..xxxxx.
169 ......xx
170 ..x..xxx
171 ..xxxxxx
172 ..xxxxx.
173 ..xxxx..
174 ..xxxxx.
176 static unsigned short continued_bits[] = {
177 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
179 /* Marker for continuation lines. */
181 ..xxxx..
182 .xxxxx..
183 xx......
184 xxx..x..
185 xxxxxx..
186 .xxxxx..
187 ..xxxx..
188 .xxxxx..
190 static unsigned short continuation_bits[] = {
191 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
193 /* Overlay arrow bitmap. A triangular arrow. */
195 xx......
196 xxxx....
197 xxxxx...
198 xxxxxx..
199 xxxxxx..
200 xxxxx...
201 xxxx....
202 xx......
204 static unsigned short ov_bits[] = {
205 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
207 #if 0
208 /* Reverse Overlay arrow bitmap. A triangular arrow. */
210 ......xx
211 ....xxxx
212 ...xxxxx
213 ..xxxxxx
214 ..xxxxxx
215 ...xxxxx
216 ....xxxx
217 ......xx
219 static unsigned short rev_ov_bits[] = {
220 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
221 #endif
223 /* First line bitmap. An top-left angle. */
225 xxxxxx..
226 xxxxxx..
227 xx......
228 xx......
229 xx......
230 xx......
231 xx......
232 ........
234 static unsigned short top_left_angle_bits[] = {
235 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00};
237 /* First line bitmap. An right-up angle. */
239 ..xxxxxx
240 ..xxxxxx
241 ......xx
242 ......xx
243 ......xx
244 ......xx
245 ......xx
246 ........
248 static unsigned short top_right_angle_bits[] = {
249 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
251 /* Last line bitmap. An left-down angle. */
253 ........
254 xx......
255 xx......
256 xx......
257 xx......
258 xx......
259 xxxxxx..
260 xxxxxx..
262 static unsigned short bottom_left_angle_bits[] = {
263 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
265 /* Last line bitmap. An right-down angle. */
267 ........
268 ......xx
269 ......xx
270 ......xx
271 ......xx
272 ......xx
273 ..xxxxxx
274 ..xxxxxx
276 static unsigned short bottom_right_angle_bits[] = {
277 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
279 /* First/last line bitmap. An left bracket. */
281 xxxxxx..
282 xxxxxx..
283 xx......
284 xx......
285 xx......
286 xx......
287 xx......
288 xx......
289 xxxxxx..
290 xxxxxx..
292 static unsigned short left_bracket_bits[] = {
293 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
295 /* First/last line bitmap. An right bracket. */
297 ..xxxxxx
298 ..xxxxxx
299 ......xx
300 ......xx
301 ......xx
302 ......xx
303 ......xx
304 ......xx
305 ..xxxxxx
306 ..xxxxxx
308 static unsigned short right_bracket_bits[] = {
309 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
311 /* Filled box cursor bitmap. A filled box; max 13 pixels high. */
313 xxxxxxx.
314 xxxxxxx.
315 xxxxxxx.
316 xxxxxxx.
317 xxxxxxx.
318 xxxxxxx.
319 xxxxxxx.
320 xxxxxxx.
321 xxxxxxx.
322 xxxxxxx.
323 xxxxxxx.
324 xxxxxxx.
325 xxxxxxx.
327 static unsigned short filled_box_cursor_bits[] = {
328 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
330 /* Hollow box cursor bitmap. A hollow box; max 13 pixels high. */
332 xxxxxxx.
333 x.....x.
334 x.....x.
335 x.....x.
336 x.....x.
337 x.....x.
338 x.....x.
339 x.....x.
340 x.....x.
341 x.....x.
342 x.....x.
343 x.....x.
344 xxxxxxx.
346 static unsigned short hollow_box_cursor_bits[] = {
347 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe};
349 /* Bar cursor bitmap. A vertical bar; max 13 pixels high. */
351 xx......
352 xx......
353 xx......
354 xx......
355 xx......
356 xx......
357 xx......
358 xx......
359 xx......
360 xx......
361 xx......
362 xx......
363 xx......
365 static unsigned short bar_cursor_bits[] = {
366 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
368 /* HBar cursor bitmap. A horisontal bar; 2 pixels high. */
370 xxxxxxx.
371 xxxxxxx.
373 static unsigned short hbar_cursor_bits[] = {
374 0xfe, 0xfe};
377 /* Bitmap drawn to indicate lines not displaying text if
378 `indicate-empty-lines' is non-nil. */
380 ........
381 ..xxxx..
382 ........
383 ........
384 ..xxxx..
385 ........
387 static unsigned short zv_bits[] = {
388 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
389 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
390 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
391 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
392 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
393 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
394 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
395 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
397 /* Hollow square bitmap. */
399 .xxxxxx.
400 .x....x.
401 .x....x.
402 .x....x.
403 .x....x.
404 .xxxxxx.
406 static unsigned short hollow_square_bits[] = {
407 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
410 #define BYTES_PER_BITMAP_ROW (sizeof (unsigned short))
411 #define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
412 #define FRBITS(bits) bits, STANDARD_BITMAP_HEIGHT (bits)
414 struct fringe_bitmap standard_bitmaps[MAX_STANDARD_FRINGE_BITMAPS] =
416 { NULL, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */
417 { FRBITS (unknown_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
418 { FRBITS (left_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
419 { FRBITS (right_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
420 { FRBITS (up_arrow_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
421 { FRBITS (down_arrow_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
422 { FRBITS (continued_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
423 { FRBITS (continuation_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
424 { FRBITS (ov_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
425 { FRBITS (top_left_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
426 { FRBITS (top_right_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
427 { FRBITS (bottom_left_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
428 { FRBITS (bottom_right_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
429 { FRBITS (left_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
430 { FRBITS (right_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
431 { FRBITS (filled_box_cursor_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
432 { FRBITS (hollow_box_cursor_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
433 { FRBITS (hollow_square_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
434 { FRBITS (bar_cursor_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
435 { FRBITS (hbar_cursor_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
436 { FRBITS (zv_bits), 8, 3, ALIGN_BITMAP_TOP, 0 },
439 static struct fringe_bitmap *fringe_bitmaps[MAX_FRINGE_BITMAPS];
440 static unsigned fringe_faces[MAX_FRINGE_BITMAPS];
442 static int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS;
444 /* Return 1 if FRINGE_ID is a valid fringe bitmap id. */
447 valid_fringe_bitmap_id_p (fringe_id)
448 int fringe_id;
450 return (fringe_id >= NO_FRINGE_BITMAP
451 && fringe_id < max_used_fringe_bitmap
452 && (fringe_id < MAX_STANDARD_FRINGE_BITMAPS
453 || fringe_bitmaps[fringe_id] != NULL));
456 /* Draw the bitmap WHICH in one of the left or right fringes of
457 window W. ROW is the glyph row for which to display the bitmap; it
458 determines the vertical position at which the bitmap has to be
459 drawn.
460 LEFT_P is 1 for left fringe, 0 for right fringe.
463 void
464 draw_fringe_bitmap_1 (w, row, left_p, overlay, which)
465 struct window *w;
466 struct glyph_row *row;
467 int left_p, overlay;
468 enum fringe_bitmap_type which;
470 struct frame *f = XFRAME (WINDOW_FRAME (w));
471 struct draw_fringe_bitmap_params p;
472 struct fringe_bitmap *fb;
473 int period;
474 int face_id = DEFAULT_FACE_ID;
476 p.cursor_p = 0;
477 p.overlay_p = (overlay & 1) == 1;
478 p.cursor_p = (overlay & 2) == 2;
480 if (which != NO_FRINGE_BITMAP)
483 else if (left_p)
485 which = row->left_fringe_bitmap;
486 face_id = row->left_fringe_face_id;
488 else
490 which = row->right_fringe_bitmap;
491 face_id = row->right_fringe_face_id;
494 if (face_id == DEFAULT_FACE_ID)
495 face_id = fringe_faces[which];
497 fb = fringe_bitmaps[which];
498 if (fb == NULL)
499 fb = &standard_bitmaps[which < MAX_STANDARD_FRINGE_BITMAPS
500 ? which : UNDEF_FRINGE_BITMAP];
502 period = fb->period;
504 /* Convert row to frame coordinates. */
505 p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
507 p.which = which;
508 p.bits = fb->bits;
509 p.wd = fb->width;
511 p.h = fb->height;
512 p.dh = (period > 0 ? (p.y % period) : 0);
513 p.h -= p.dh;
514 /* Clip bitmap if too high. */
515 if (p.h > row->height)
516 p.h = row->height;
518 p.face = FACE_FROM_ID (f, face_id);
520 if (p.face == NULL)
522 /* Why does this happen? ++kfs */
523 return;
526 PREPARE_FACE_FOR_DISPLAY (f, p.face);
528 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
529 the fringe. */
530 p.bx = -1;
531 if (left_p)
533 int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
534 int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
535 ? LEFT_MARGIN_AREA
536 : TEXT_AREA));
537 if (p.wd > wd)
538 p.wd = wd;
539 p.x = x - p.wd - (wd - p.wd) / 2;
541 if (p.wd < wd || row->height > p.h)
543 /* If W has a vertical border to its left, don't draw over it. */
544 wd -= ((!WINDOW_LEFTMOST_P (w)
545 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
546 ? 1 : 0);
547 p.bx = x - wd;
548 p.nx = wd;
551 else
553 int x = window_box_right (w,
554 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
555 ? RIGHT_MARGIN_AREA
556 : TEXT_AREA));
557 int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
558 if (p.wd > wd)
559 p.wd = wd;
560 p.x = x + (wd - p.wd) / 2;
561 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
562 the fringe. */
563 if (p.wd < wd || row->height > p.h)
565 p.bx = x;
566 p.nx = wd;
570 if (p.bx >= 0)
572 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
574 p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
575 p.ny = row->visible_height;
578 /* Adjust y to the offset in the row to start drawing the bitmap. */
579 switch (fb->align)
581 case ALIGN_BITMAP_CENTER:
582 p.y += (row->height - p.h) / 2;
583 break;
584 case ALIGN_BITMAP_BOTTOM:
585 p.h = fb->height;
586 p.y += (row->visible_height - p.h);
587 break;
588 case ALIGN_BITMAP_TOP:
589 break;
592 rif->draw_fringe_bitmap (w, row, &p);
595 void
596 draw_fringe_bitmap (w, row, left_p)
597 struct window *w;
598 struct glyph_row *row;
599 int left_p;
601 int overlay = 0;
603 if (!left_p && row->cursor_in_fringe_p)
605 int cursor = NO_FRINGE_BITMAP;
607 switch (w->phys_cursor_type)
609 case HOLLOW_BOX_CURSOR:
610 if (row->visible_height >= STANDARD_BITMAP_HEIGHT (hollow_box_cursor_bits))
611 cursor = HOLLOW_BOX_CURSOR_BITMAP;
612 else
613 cursor = HOLLOW_SQUARE_BITMAP;
614 break;
615 case FILLED_BOX_CURSOR:
616 cursor = FILLED_BOX_CURSOR_BITMAP;
617 break;
618 case BAR_CURSOR:
619 cursor = BAR_CURSOR_BITMAP;
620 break;
621 case HBAR_CURSOR:
622 cursor = HBAR_CURSOR_BITMAP;
623 break;
624 case NO_CURSOR:
625 default:
626 w->phys_cursor_on_p = 0;
627 row->cursor_in_fringe_p = 0;
628 break;
630 if (cursor != NO_FRINGE_BITMAP)
632 draw_fringe_bitmap_1 (w, row, 0, 2, cursor);
633 overlay = cursor == FILLED_BOX_CURSOR_BITMAP ? 3 : 1;
637 draw_fringe_bitmap_1 (w, row, left_p, overlay, NO_FRINGE_BITMAP);
639 if (left_p && row->overlay_arrow_p)
640 draw_fringe_bitmap_1 (w, row, 1, 1,
641 (w->overlay_arrow_bitmap
642 ? w->overlay_arrow_bitmap
643 : OVERLAY_ARROW_BITMAP));
647 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
648 function with input blocked. */
650 void
651 draw_row_fringe_bitmaps (w, row)
652 struct window *w;
653 struct glyph_row *row;
655 xassert (interrupt_input_blocked);
657 /* If row is completely invisible, because of vscrolling, we
658 don't have to draw anything. */
659 if (row->visible_height <= 0)
660 return;
662 if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
663 draw_fringe_bitmap (w, row, 1);
665 if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
666 draw_fringe_bitmap (w, row, 0);
669 /* Draw the fringes of window W. Only fringes for rows marked for
670 update in redraw_fringe_bitmaps_p are drawn. */
672 void
673 draw_window_fringes (w)
674 struct window *w;
676 struct glyph_row *row;
677 int yb = window_text_bottom_y (w);
678 int nrows = w->current_matrix->nrows;
679 int y = 0, rn;
681 if (w->pseudo_window_p)
682 return;
684 for (y = 0, rn = 0, row = w->current_matrix->rows;
685 y < yb && rn < nrows;
686 y += row->height, ++row, ++rn)
688 if (!row->redraw_fringe_bitmaps_p)
689 continue;
690 draw_row_fringe_bitmaps (w, row);
691 row->redraw_fringe_bitmaps_p = 0;
696 /* Recalculate the bitmaps to show in the fringes of window W.
697 If FORCE_P is 0, only mark rows with modified bitmaps for update in
698 redraw_fringe_bitmaps_p; else mark all rows for update. */
701 update_window_fringes (w, force_p)
702 struct window *w;
703 int force_p;
705 struct glyph_row *row, *cur = 0;
706 int yb = window_text_bottom_y (w);
707 int rn, nrows = w->current_matrix->nrows;
708 int y;
709 int redraw_p = 0;
710 Lisp_Object boundary_top = Qnil, boundary_bot = Qnil;
711 Lisp_Object arrow_top = Qnil, arrow_bot = Qnil;
712 Lisp_Object empty_pos;
713 Lisp_Object ind = Qnil;
715 if (w->pseudo_window_p)
716 return 0;
718 if (!MINI_WINDOW_P (w)
719 && (ind = XBUFFER (w->buffer)->indicate_buffer_boundaries, !NILP (ind)))
721 if (EQ (ind, Qleft) || EQ (ind, Qright))
722 boundary_top = boundary_bot = arrow_top = arrow_bot = ind;
723 else if (CONSP (ind) && CONSP (XCAR (ind)))
725 Lisp_Object pos;
726 if (pos = Fassq (Qt, ind), !NILP (pos))
727 boundary_top = boundary_bot = arrow_top = arrow_bot = XCDR (pos);
728 if (pos = Fassq (Qtop, ind), !NILP (pos))
729 boundary_top = XCDR (pos);
730 if (pos = Fassq (Qbottom, ind), !NILP (pos))
731 boundary_bot = XCDR (pos);
732 if (pos = Fassq (Qup, ind), !NILP (pos))
733 arrow_top = XCDR (pos);
734 if (pos = Fassq (Qdown, ind), !NILP (pos))
735 arrow_bot = XCDR (pos);
737 else
738 ind = Qnil;
741 if (!NILP (ind))
743 int do_eob = 1, do_bob = 1;
745 for (y = 0, rn = 0;
746 y < yb && rn < nrows;
747 y += row->height, ++rn)
749 unsigned indicate_bob_p, indicate_top_line_p;
750 unsigned indicate_eob_p, indicate_bottom_line_p;
752 row = w->desired_matrix->rows + rn;
753 if (!row->enabled_p)
754 row = w->current_matrix->rows + rn;
756 indicate_bob_p = row->indicate_bob_p;
757 indicate_top_line_p = row->indicate_top_line_p;
758 indicate_eob_p = row->indicate_eob_p;
759 indicate_bottom_line_p = row->indicate_bottom_line_p;
761 row->indicate_bob_p = row->indicate_top_line_p = 0;
762 row->indicate_eob_p = row->indicate_bottom_line_p = 0;
764 if (!NILP (boundary_top)
765 && MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer)))
766 row->indicate_bob_p = do_bob, do_bob = 0;
767 else if (!NILP (arrow_top)
768 && (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0) == rn)
769 row->indicate_top_line_p = 1;
771 if (!NILP (boundary_bot)
772 && MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer)))
773 row->indicate_eob_p = do_eob, do_eob = 0;
774 else if (!NILP (arrow_bot)
775 && y + row->height >= yb)
776 row->indicate_bottom_line_p = 1;
778 if (indicate_bob_p != row->indicate_bob_p
779 || indicate_top_line_p != row->indicate_top_line_p
780 || indicate_eob_p != row->indicate_eob_p
781 || indicate_bottom_line_p != row->indicate_bottom_line_p)
782 row->redraw_fringe_bitmaps_p = 1;
786 empty_pos = XBUFFER (w->buffer)->indicate_empty_lines;
787 if (!NILP (empty_pos) && !EQ (empty_pos, Qright))
788 empty_pos = WINDOW_LEFT_FRINGE_WIDTH (w) == 0 ? Qright : Qleft;
790 for (y = 0, rn = 0;
791 y < yb && rn < nrows;
792 y += row->height, rn++)
794 enum fringe_bitmap_type left, right;
795 unsigned left_face_id, right_face_id;
797 row = w->desired_matrix->rows + rn;
798 cur = w->current_matrix->rows + rn;
799 if (!row->enabled_p)
800 row = cur;
802 left_face_id = right_face_id = DEFAULT_FACE_ID;
804 /* Decide which bitmap to draw in the left fringe. */
805 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
806 left = NO_FRINGE_BITMAP;
807 else if (row->left_user_fringe_bitmap != NO_FRINGE_BITMAP)
809 left = row->left_user_fringe_bitmap;
810 left_face_id = row->left_user_fringe_face_id;
812 else if (row->indicate_bob_p && EQ (boundary_top, Qleft))
813 left = ((row->indicate_eob_p && EQ (boundary_bot, Qleft))
814 ? LEFT_BRACKET_BITMAP : TOP_LEFT_ANGLE_BITMAP);
815 else if (row->indicate_eob_p && EQ (boundary_bot, Qleft))
816 left = BOTTOM_LEFT_ANGLE_BITMAP;
817 else if (row->truncated_on_left_p)
818 left = LEFT_TRUNCATION_BITMAP;
819 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
820 left = CONTINUATION_LINE_BITMAP;
821 else if (row->indicate_empty_line_p && EQ (empty_pos, Qleft))
822 left = ZV_LINE_BITMAP;
823 else if (row->indicate_top_line_p && EQ (arrow_top, Qleft))
824 left = UP_ARROW_BITMAP;
825 else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qleft))
826 left = DOWN_ARROW_BITMAP;
827 else
828 left = NO_FRINGE_BITMAP;
830 /* Decide which bitmap to draw in the right fringe. */
831 if (WINDOW_RIGHT_FRINGE_WIDTH (w) == 0)
832 right = NO_FRINGE_BITMAP;
833 else if (row->right_user_fringe_bitmap != NO_FRINGE_BITMAP)
835 right = row->right_user_fringe_bitmap;
836 right_face_id = row->right_user_fringe_face_id;
838 else if (row->indicate_bob_p && EQ (boundary_top, Qright))
839 right = ((row->indicate_eob_p && EQ (boundary_bot, Qright))
840 ? RIGHT_BRACKET_BITMAP : TOP_RIGHT_ANGLE_BITMAP);
841 else if (row->indicate_eob_p && EQ (boundary_bot, Qright))
842 right = BOTTOM_RIGHT_ANGLE_BITMAP;
843 else if (row->truncated_on_right_p)
844 right = RIGHT_TRUNCATION_BITMAP;
845 else if (row->continued_p)
846 right = CONTINUED_LINE_BITMAP;
847 else if (row->indicate_top_line_p && EQ (arrow_top, Qright))
848 right = UP_ARROW_BITMAP;
849 else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qright))
850 right = DOWN_ARROW_BITMAP;
851 else if (row->indicate_empty_line_p && EQ (empty_pos, Qright))
852 right = ZV_LINE_BITMAP;
853 else
854 right = NO_FRINGE_BITMAP;
856 if (force_p
857 || row->y != cur->y
858 || row->visible_height != cur->visible_height
859 || left != cur->left_fringe_bitmap
860 || right != cur->right_fringe_bitmap
861 || left_face_id != cur->left_fringe_face_id
862 || right_face_id != cur->right_fringe_face_id
863 || cur->redraw_fringe_bitmaps_p)
865 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
866 cur->left_fringe_bitmap = left;
867 cur->right_fringe_bitmap = right;
868 cur->left_fringe_face_id = left_face_id;
869 cur->right_fringe_face_id = right_face_id;
872 if (row->overlay_arrow_p != cur->overlay_arrow_p)
874 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
875 cur->overlay_arrow_p = row->overlay_arrow_p;
878 row->left_fringe_bitmap = left;
879 row->right_fringe_bitmap = right;
880 row->left_fringe_face_id = left_face_id;
881 row->right_fringe_face_id = right_face_id;
884 return redraw_p;
888 /* Compute actual fringe widths for frame F.
890 If REDRAW is 1, redraw F if the fringe settings was actually
891 modified and F is visible.
893 Since the combined left and right fringe must occupy an integral
894 number of columns, we may need to add some pixels to each fringe.
895 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
896 but a negative width value is taken literally (after negating it).
898 We never make the fringes narrower than specified. It is planned
899 to make fringe bitmaps customizable and expandable, and at that
900 time, the user will typically specify the minimum number of pixels
901 needed for his bitmaps, so we shouldn't select anything less than
902 what is specified.
905 void
906 compute_fringe_widths (f, redraw)
907 struct frame *f;
908 int redraw;
910 int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
911 int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
912 int o_cols = FRAME_FRINGE_COLS (f);
914 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
915 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
916 int left_fringe_width, right_fringe_width;
918 if (!NILP (left_fringe))
919 left_fringe = Fcdr (left_fringe);
920 if (!NILP (right_fringe))
921 right_fringe = Fcdr (right_fringe);
923 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
924 XINT (left_fringe));
925 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
926 XINT (right_fringe));
928 if (left_fringe_width || right_fringe_width)
930 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
931 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
932 int conf_wid = left_wid + right_wid;
933 int font_wid = FRAME_COLUMN_WIDTH (f);
934 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
935 int real_wid = cols * font_wid;
936 if (left_wid && right_wid)
938 if (left_fringe_width < 0)
940 /* Left fringe width is fixed, adjust right fringe if necessary */
941 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
942 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
944 else if (right_fringe_width < 0)
946 /* Right fringe width is fixed, adjust left fringe if necessary */
947 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
948 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
950 else
952 /* Adjust both fringes with an equal amount.
953 Note that we are doing integer arithmetic here, so don't
954 lose a pixel if the total width is an odd number. */
955 int fill = real_wid - conf_wid;
956 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
957 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
960 else if (left_fringe_width)
962 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
963 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
965 else
967 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
968 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
970 FRAME_FRINGE_COLS (f) = cols;
972 else
974 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
975 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
976 FRAME_FRINGE_COLS (f) = 0;
979 if (redraw && FRAME_VISIBLE_P (f))
980 if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
981 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
982 o_cols != FRAME_FRINGE_COLS (f))
983 redraw_frame (f);
986 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap, Sdestroy_fringe_bitmap,
987 1, 1, 0,
988 doc: /* Destroy fringe bitmap WHICH.
989 If WHICH overrides a standard fringe bitmap, the original bitmap is restored. */)
990 (which)
991 Lisp_Object which;
993 int n;
994 struct fringe_bitmap **fbp;
996 CHECK_NUMBER (which);
997 if (n = XINT (which), n >= max_used_fringe_bitmap)
998 return Qnil;
1000 fringe_faces[n] = FRINGE_FACE_ID;
1002 fbp = &fringe_bitmaps[n];
1003 if (*fbp && (*fbp)->dynamic)
1005 if (rif->destroy_fringe_bitmap)
1006 rif->destroy_fringe_bitmap (n);
1007 xfree (*fbp);
1008 *fbp = NULL;
1011 while (max_used_fringe_bitmap > MAX_STANDARD_FRINGE_BITMAPS
1012 && fringe_bitmaps[max_used_fringe_bitmap - 1] == NULL)
1013 max_used_fringe_bitmap--;
1015 return Qnil;
1019 /* Initialize bitmap bit.
1021 On X, we bit-swap the built-in bitmaps and reduce bitmap
1022 from short to char array if width is <= 8 bits.
1024 On MAC with big-endian CPU, we need to byte-swap each short.
1026 On W32 and MAC (little endian), there's no need to do this.
1029 void
1030 init_fringe_bitmap (which, fb, once_p)
1031 enum fringe_bitmap_type which;
1032 struct fringe_bitmap *fb;
1033 int once_p;
1035 if (once_p || fb->dynamic)
1037 #if defined (HAVE_X_WINDOWS)
1038 static unsigned char swap_nibble[16]
1039 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1040 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1041 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
1042 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
1043 unsigned short *bits = fb->bits;
1044 int j;
1046 if (fb->width <= 8)
1048 unsigned char *cbits = (unsigned char *)fb->bits;
1049 for (j = 0; j < fb->height; j++)
1051 unsigned short b = *bits++;
1052 unsigned char c;
1053 c = (unsigned char)((swap_nibble[b & 0xf] << 4)
1054 | (swap_nibble[(b>>4) & 0xf]));
1055 *cbits++ = (c >> (8 - fb->width));
1058 else
1060 for (j = 0; j < fb->height; j++)
1062 unsigned short b = *bits;
1063 b = (unsigned short)((swap_nibble[b & 0xf] << 12)
1064 | (swap_nibble[(b>>4) & 0xf] << 8)
1065 | (swap_nibble[(b>>8) & 0xf] << 4)
1066 | (swap_nibble[(b>>12) & 0xf]));
1067 *bits++ = (b >> (16 - fb->width));
1070 #endif /* HAVE_X_WINDOWS */
1072 #if defined (MAC_OS) && defined (WORDS_BIG_ENDIAN)
1073 unsigned short *bits = fb->bits;
1074 int j;
1075 for (j = 0; j < fb->height; j++)
1077 unsigned short b = *bits;
1078 *bits++ = ((b >> 8) & 0xff) | ((b & 0xff) << 8);
1080 #endif /* MAC_OS && WORDS_BIG_ENDIAN */
1083 if (!once_p)
1085 Fdestroy_fringe_bitmap (make_number (which));
1087 if (rif->define_fringe_bitmap)
1088 rif->define_fringe_bitmap (which, fb->bits, fb->height, fb->width);
1090 fringe_bitmaps[which] = fb;
1091 if (which >= max_used_fringe_bitmap)
1092 max_used_fringe_bitmap = which + 1;
1097 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap,
1098 1, 5, 0,
1099 doc: /* Define a fringe bitmap from BITS of height HEIGHT and width WIDTH.
1100 BITS is either a string or a vector of integers.
1101 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1102 WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1103 Optional fourth arg ALIGN may be one of `top', `center', or `bottom',
1104 indicating the positioning of the bitmap relative to the rows where it
1105 is used; the default is to center the bitmap. Fourth arg may also be a
1106 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1107 should be repeated.
1108 Optional fifth argument WHICH is bitmap number to redefine.
1109 Return new bitmap number, or nil of no more free bitmap slots. */)
1110 (bits, height, width, align, which)
1111 Lisp_Object bits, height, width, align, which;
1113 Lisp_Object len;
1114 int n, h, i, j;
1115 unsigned short *b;
1116 struct fringe_bitmap fb, *xfb;
1117 int fill1 = 0, fill2 = 0;
1119 if (!STRINGP (bits) && !VECTORP (bits))
1120 bits = wrong_type_argument (Qstringp, bits);
1122 len = Flength (bits);
1124 if (NILP (height))
1125 h = fb.height = XINT (len);
1126 else
1128 CHECK_NUMBER (height);
1129 fb.height = min (XINT (height), 255);
1130 if (fb.height > XINT (len))
1132 h = XINT (len);
1133 fill1 = (fb.height - h) / 2;
1134 fill2 = fb.height - h - fill1;
1138 if (NILP (width))
1139 fb.width = 8;
1140 else
1142 CHECK_NUMBER (width);
1143 fb.width = min (XINT (width), 255);
1146 fb.period = 0;
1147 fb.align = ALIGN_BITMAP_CENTER;
1149 if (CONSP (align))
1151 Lisp_Object period = XCDR (align);
1152 if (CONSP (period))
1154 period = XCAR (period);
1155 if (!NILP (period))
1157 fb.period = fb.height;
1158 fb.height = 255;
1161 align = XCAR (align);
1163 if (EQ (align, Qtop))
1164 fb.align = ALIGN_BITMAP_TOP;
1165 else if (EQ (align, Qbottom))
1166 fb.align = ALIGN_BITMAP_BOTTOM;
1167 else if (!NILP (align) && !EQ (align, Qcenter))
1168 error ("Bad align argument");
1170 if (NILP (which))
1172 if (max_used_fringe_bitmap < MAX_FRINGE_BITMAPS)
1173 n = max_used_fringe_bitmap++;
1174 else
1176 for (n = MAX_STANDARD_FRINGE_BITMAPS;
1177 n < MAX_FRINGE_BITMAPS;
1178 n++)
1179 if (fringe_bitmaps[n] == NULL)
1180 break;
1181 if (n == MAX_FRINGE_BITMAPS)
1182 return Qnil;
1184 which = make_number (n);
1186 else
1188 CHECK_NUMBER (which);
1189 n = XINT (which);
1190 if (n <= NO_FRINGE_BITMAP || n >= MAX_FRINGE_BITMAPS)
1191 error ("Invalid fringe bitmap number");
1194 fb.dynamic = 1;
1196 xfb = (struct fringe_bitmap *) xmalloc (sizeof fb
1197 + fb.height * BYTES_PER_BITMAP_ROW);
1198 fb.bits = b = (unsigned short *) (xfb + 1);
1199 bzero (b, fb.height);
1201 j = 0;
1202 while (j < fb.height)
1204 for (i = 0; i < fill1 && j < fb.height; i++)
1205 b[j++] = 0;
1206 for (i = 0; i < h && j < fb.height; i++)
1208 Lisp_Object elt = Faref (bits, make_number (i));
1209 b[j++] = NUMBERP (elt) ? XINT (elt) : 0;
1211 for (i = 0; i < fill2 && j < fb.height; i++)
1212 b[j++] = 0;
1215 *xfb = fb;
1217 init_fringe_bitmap (n, xfb, 0);
1219 return which;
1222 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face,
1223 1, 2, 0,
1224 doc: /* Set face for fringe bitmap FRINGE-ID to FACE.
1225 If FACE is nil, reset face to default fringe face. */)
1226 (fringe_id, face)
1227 Lisp_Object fringe_id, face;
1229 int face_id;
1231 CHECK_NUMBER (fringe_id);
1232 if (!valid_fringe_bitmap_id_p (XINT (fringe_id)))
1233 error ("Invalid fringe id");
1235 if (!NILP (face))
1237 face_id = lookup_named_face (SELECTED_FRAME (), face, 'A');
1238 if (face_id < 0)
1239 error ("No such face");
1241 else
1242 face_id = FRINGE_FACE_ID;
1244 fringe_faces [XINT (fringe_id)] = face_id;
1246 return Qnil;
1249 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos, Sfringe_bitmaps_at_pos,
1250 0, 2, 0,
1251 doc: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1252 If WINDOW is nil, use selected window. If POS is nil, use value of point
1253 in that window. Return value is a cons (LEFT . RIGHT) where LEFT and RIGHT
1254 are the fringe bitmap numbers for the bitmaps in the left and right fringe,
1255 resp. If left or right fringe is empty, the corresponding element is nil.
1256 Return nil if POS is not visible in WINDOW. */)
1257 (pos, window)
1258 Lisp_Object pos, window;
1260 struct window *w;
1261 struct buffer *old_buffer = NULL;
1262 struct glyph_row *row;
1263 int textpos;
1265 if (NILP (window))
1266 window = selected_window;
1267 CHECK_WINDOW (window);
1268 w = XWINDOW (window);
1270 if (!NILP (pos))
1272 CHECK_NUMBER_COERCE_MARKER (pos);
1273 textpos = XINT (pos);
1275 else if (w == XWINDOW (selected_window))
1276 textpos = PT;
1277 else
1278 textpos = XMARKER (w->pointm)->charpos;
1280 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1281 row = row_containing_pos (w, textpos, row, NULL, 0);
1282 if (row)
1283 return Fcons ((row->left_fringe_bitmap == NO_FRINGE_BITMAP
1284 ? Qnil : make_number (row->left_fringe_bitmap)),
1285 (row->right_fringe_bitmap == NO_FRINGE_BITMAP
1286 ? Qnil : make_number (row->right_fringe_bitmap)));
1287 else
1288 return Qnil;
1292 /***********************************************************************
1293 Initialization
1294 ***********************************************************************/
1296 void
1297 syms_of_fringe ()
1300 defsubr (&Sdestroy_fringe_bitmap);
1301 defsubr (&Sdefine_fringe_bitmap);
1302 defsubr (&Sfringe_bitmaps_at_pos);
1303 defsubr (&Sset_fringe_bitmap_face);
1305 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe,
1306 doc: /* *Non-nil means that newline may flow into the right fringe.
1307 This means that display lines which are exactly as wide as the window
1308 (not counting the final newline) will only occupy one screen line, by
1309 showing (or hiding) the final newline in the right fringe; when point
1310 is at the final newline, the cursor is shown in the right fringe.
1311 If nil, also continue lines which are exactly as wide as the window. */);
1312 Voverflow_newline_into_fringe = Qt;
1316 /* Initialize this module when Emacs starts. */
1318 void
1319 init_fringe_once ()
1321 enum fringe_bitmap_type bt;
1323 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1324 init_fringe_bitmap(bt, &standard_bitmaps[bt], 1);
1327 void
1328 init_fringe ()
1330 int i;
1332 bzero (fringe_bitmaps, sizeof fringe_bitmaps);
1333 for (i = 0; i < MAX_FRINGE_BITMAPS; i++)
1334 fringe_faces[i] = FRINGE_FACE_ID;
1337 #ifdef HAVE_NTGUI
1339 void
1340 w32_init_fringe ()
1342 enum fringe_bitmap_type bt;
1344 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1346 struct fringe_bitmap *fb = &standard_bitmaps[bt];
1347 rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
1351 void
1352 w32_reset_fringes ()
1354 /* Destroy row bitmaps. */
1355 int bt;
1357 for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++)
1358 rif->destroy_fringe_bitmap (bt);
1361 #endif /* HAVE_NTGUI */
1363 #endif /* HAVE_WINDOW_SYSTEM */
1365 /* arch-tag: 04596920-43eb-473d-b319-82712338162d
1366 (do not change this comment) */