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