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