(make_window): Initialize overlay_arrow_bitmap.
[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)
639 draw_fringe_bitmap_1 (w, row, 1, 1, OVERLAY_ARROW_BITMAP);
640}
641
642
643/* Draw fringe bitmaps for glyph row ROW on window W. Call this
644 function with input blocked. */
645
646void
647draw_row_fringe_bitmaps (w, row)
648 struct window *w;
649 struct glyph_row *row;
650{
651 xassert (interrupt_input_blocked);
652
653 /* If row is completely invisible, because of vscrolling, we
654 don't have to draw anything. */
655 if (row->visible_height <= 0)
656 return;
657
658 if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
659 draw_fringe_bitmap (w, row, 1);
660
661 if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
662 draw_fringe_bitmap (w, row, 0);
663}
664
665/* Draw the fringes of window W. Only fringes for rows marked for
666 update in redraw_fringe_bitmaps_p are drawn. */
667
668void
669draw_window_fringes (w)
670 struct window *w;
671{
672 struct glyph_row *row;
673 int yb = window_text_bottom_y (w);
674 int nrows = w->current_matrix->nrows;
675 int y = 0, rn;
676
677 if (w->pseudo_window_p)
678 return;
679
680 for (y = 0, rn = 0, row = w->current_matrix->rows;
681 y < yb && rn < nrows;
682 y += row->height, ++row, ++rn)
683 {
684 if (!row->redraw_fringe_bitmaps_p)
685 continue;
686 draw_row_fringe_bitmaps (w, row);
687 row->redraw_fringe_bitmaps_p = 0;
688 }
689}
690
691
692/* Recalculate the bitmaps to show in the fringes of window W.
693 If FORCE_P is 0, only mark rows with modified bitmaps for update in
694 redraw_fringe_bitmaps_p; else mark all rows for update. */
695
696int
697update_window_fringes (w, force_p)
698 struct window *w;
699 int force_p;
700{
701 struct glyph_row *row, *cur = 0;
702 int yb = window_text_bottom_y (w);
703 int rn, nrows = w->current_matrix->nrows;
704 int y;
705 int redraw_p = 0;
706 Lisp_Object ind;
707 int boundary_pos = 0, arrow_pos = 0;
708 int empty_pos = 0;
709
710 if (w->pseudo_window_p)
711 return 0;
712
713 if (!MINI_WINDOW_P (w)
714 && (ind = XBUFFER (w->buffer)->indicate_buffer_boundaries, !NILP (ind)))
715 {
716 int do_eob = 1, do_bob = 1;
717 Lisp_Object arrows;
718
719 if (CONSP (ind))
720 arrows = XCDR (ind), ind = XCAR (ind);
721 else
722 arrows = ind;
723
724 if (EQ (ind, Qleft))
725 boundary_pos = -1;
726 else if (EQ (ind, Qright))
727 boundary_pos = 1;
728
729 if (EQ (arrows, Qleft))
730 arrow_pos = -1;
731 else if (EQ (arrows, Qright))
732 arrow_pos = 1;
733
734 for (y = 0, rn = 0;
735 y < yb && rn < nrows;
736 y += row->height, ++rn)
737 {
738 unsigned indicate_bob_p, indicate_top_line_p;
739 unsigned indicate_eob_p, indicate_bottom_line_p;
bffe8c26 740
2d05deef
KS
741 row = w->desired_matrix->rows + rn;
742 if (!row->enabled_p)
743 row = w->current_matrix->rows + rn;
744
745 indicate_bob_p = row->indicate_bob_p;
746 indicate_top_line_p = row->indicate_top_line_p;
747 indicate_eob_p = row->indicate_eob_p;
748 indicate_bottom_line_p = row->indicate_bottom_line_p;
bffe8c26 749
2d05deef
KS
750 row->indicate_bob_p = row->indicate_top_line_p = 0;
751 row->indicate_eob_p = row->indicate_bottom_line_p = 0;
752
753 if (!NILP (ind)
754 && MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer)))
755 row->indicate_bob_p = do_bob, do_bob = 0;
756 else if (!NILP (arrows)
757 && (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0) == rn)
758 row->indicate_top_line_p = 1;
759
760 if (!NILP (ind)
761 && MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer)))
762 row->indicate_eob_p = do_eob, do_eob = 0;
763 else if (!NILP (arrows)
764 && y + row->height >= yb)
765 row->indicate_bottom_line_p = 1;
766
767 if (indicate_bob_p != row->indicate_bob_p
768 || indicate_top_line_p != row->indicate_top_line_p
769 || indicate_eob_p != row->indicate_eob_p
770 || indicate_bottom_line_p != row->indicate_bottom_line_p)
771 row->redraw_fringe_bitmaps_p = 1;
772 }
773 }
774
775 if (EQ (XBUFFER (w->buffer)->indicate_empty_lines, Qright))
776 empty_pos = 1;
777 else if (EQ (XBUFFER (w->buffer)->indicate_empty_lines, Qleft))
778 empty_pos = -1;
779
780 for (y = 0, rn = 0;
781 y < yb && rn < nrows;
782 y += row->height, rn++)
783 {
784 enum fringe_bitmap_type left, right;
785 unsigned left_face_id, right_face_id;
786
787 row = w->desired_matrix->rows + rn;
788 cur = w->current_matrix->rows + rn;
789 if (!row->enabled_p)
790 row = cur;
791
792 left_face_id = right_face_id = DEFAULT_FACE_ID;
793
794 /* Decide which bitmap to draw in the left fringe. */
795 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
796 left = NO_FRINGE_BITMAP;
797 else if (row->left_user_fringe_bitmap != NO_FRINGE_BITMAP)
798 {
799 left = row->left_user_fringe_bitmap;
800 left_face_id = row->left_user_fringe_face_id;
801 }
802#if 0 /* this is now done via an overlay */
803 else if (row->overlay_arrow_p)
804 left = OVERLAY_ARROW_BITMAP;
805#endif
806 else if (row->indicate_bob_p && boundary_pos <= 0)
807 left = ((row->indicate_eob_p && boundary_pos < 0)
808 ? LEFT_BRACKET_BITMAP : TOP_LEFT_ANGLE_BITMAP);
809 else if (row->indicate_eob_p && boundary_pos < 0)
810 left = BOTTOM_LEFT_ANGLE_BITMAP;
811 else if (row->truncated_on_left_p)
812 left = LEFT_TRUNCATION_BITMAP;
813 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
814 left = CONTINUATION_LINE_BITMAP;
815 else if (row->indicate_empty_line_p && empty_pos <= 0)
816 left = ZV_LINE_BITMAP;
817 else if (row->indicate_top_line_p && arrow_pos <= 0)
818 left = UP_ARROW_BITMAP;
819 else if (row->indicate_bottom_line_p && arrow_pos < 0)
820 left = DOWN_ARROW_BITMAP;
821 else
822 left = NO_FRINGE_BITMAP;
823
824 /* Decide which bitmap to draw in the right fringe. */
825 if (WINDOW_RIGHT_FRINGE_WIDTH (w) == 0)
826 right = NO_FRINGE_BITMAP;
827 else if (row->right_user_fringe_bitmap != NO_FRINGE_BITMAP)
828 {
829 right = row->right_user_fringe_bitmap;
830 right_face_id = row->right_user_fringe_face_id;
831 }
832 else if (row->indicate_bob_p && boundary_pos > 0)
833 right = ((row->indicate_eob_p && boundary_pos >= 0)
834 ? RIGHT_BRACKET_BITMAP : TOP_RIGHT_ANGLE_BITMAP);
835 else if (row->indicate_eob_p && boundary_pos >= 0)
836 right = BOTTOM_RIGHT_ANGLE_BITMAP;
837 else if (row->truncated_on_right_p)
838 right = RIGHT_TRUNCATION_BITMAP;
839 else if (row->continued_p)
840 right = CONTINUED_LINE_BITMAP;
841 else if (row->indicate_top_line_p && arrow_pos > 0)
842 right = UP_ARROW_BITMAP;
843 else if (row->indicate_bottom_line_p && arrow_pos >= 0)
844 right = DOWN_ARROW_BITMAP;
845 else if (row->indicate_empty_line_p
846 && (empty_pos > 0
847 || (WINDOW_LEFT_FRINGE_WIDTH (w) == 0 && empty_pos == 0)))
848 right = ZV_LINE_BITMAP;
849 else
850 right = NO_FRINGE_BITMAP;
851
852 if (force_p
853 || row->y != cur->y
854 || row->visible_height != cur->visible_height
855 || left != cur->left_fringe_bitmap
856 || right != cur->right_fringe_bitmap
857 || left_face_id != cur->left_fringe_face_id
858 || right_face_id != cur->right_fringe_face_id
859 || cur->redraw_fringe_bitmaps_p)
860 {
861 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
862 cur->left_fringe_bitmap = left;
863 cur->right_fringe_bitmap = right;
864 cur->left_fringe_face_id = left_face_id;
865 cur->right_fringe_face_id = right_face_id;
866 }
867
868 if (row->overlay_arrow_p != cur->overlay_arrow_p)
869 {
870 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
871 cur->overlay_arrow_p = row->overlay_arrow_p;
872 }
873
874 row->left_fringe_bitmap = left;
875 row->right_fringe_bitmap = right;
876 row->left_fringe_face_id = left_face_id;
877 row->right_fringe_face_id = right_face_id;
878 }
879
880 return redraw_p;
881}
882
883
bffe8c26 884/* Compute actual fringe widths for frame F.
2d05deef
KS
885
886 If REDRAW is 1, redraw F if the fringe settings was actually
887 modified and F is visible.
888
889 Since the combined left and right fringe must occupy an integral
890 number of columns, we may need to add some pixels to each fringe.
891 Typically, we add an equal amount (+/- 1 pixel) to each fringe,
892 but a negative width value is taken literally (after negating it).
893
894 We never make the fringes narrower than specified. It is planned
895 to make fringe bitmaps customizable and expandable, and at that
896 time, the user will typically specify the minimum number of pixels
897 needed for his bitmaps, so we shouldn't select anything less than
898 what is specified.
899*/
900
901void
902compute_fringe_widths (f, redraw)
903 struct frame *f;
904 int redraw;
905{
906 int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
907 int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
908 int o_cols = FRAME_FRINGE_COLS (f);
909
910 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
911 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
912 int left_fringe_width, right_fringe_width;
913
914 if (!NILP (left_fringe))
915 left_fringe = Fcdr (left_fringe);
916 if (!NILP (right_fringe))
917 right_fringe = Fcdr (right_fringe);
918
919 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
920 XINT (left_fringe));
921 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
922 XINT (right_fringe));
923
924 if (left_fringe_width || right_fringe_width)
925 {
926 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
927 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
928 int conf_wid = left_wid + right_wid;
929 int font_wid = FRAME_COLUMN_WIDTH (f);
930 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
931 int real_wid = cols * font_wid;
932 if (left_wid && right_wid)
933 {
934 if (left_fringe_width < 0)
935 {
936 /* Left fringe width is fixed, adjust right fringe if necessary */
937 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
938 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
939 }
940 else if (right_fringe_width < 0)
941 {
942 /* Right fringe width is fixed, adjust left fringe if necessary */
943 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
944 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
945 }
946 else
947 {
948 /* Adjust both fringes with an equal amount.
949 Note that we are doing integer arithmetic here, so don't
950 lose a pixel if the total width is an odd number. */
951 int fill = real_wid - conf_wid;
952 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
953 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
954 }
955 }
956 else if (left_fringe_width)
957 {
958 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
959 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
960 }
961 else
962 {
963 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
964 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
965 }
966 FRAME_FRINGE_COLS (f) = cols;
967 }
968 else
969 {
970 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
971 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
972 FRAME_FRINGE_COLS (f) = 0;
973 }
974
975 if (redraw && FRAME_VISIBLE_P (f))
976 if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
977 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
978 o_cols != FRAME_FRINGE_COLS (f))
979 redraw_frame (f);
980}
981
982DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap, Sdestroy_fringe_bitmap,
983 1, 1, 0,
984 doc: /* Destroy fringe bitmap WHICH.
985If WHICH overrides a standard fringe bitmap, the original bitmap is restored. */)
986 (which)
987 Lisp_Object which;
988{
989 int n;
990 struct fringe_bitmap **fbp;
991
992 CHECK_NUMBER (which);
993 if (n = XINT (which), n >= max_used_fringe_bitmap)
994 return Qnil;
995
996 fringe_faces[n] = FRINGE_FACE_ID;
997
998 fbp = &fringe_bitmaps[n];
999 if (*fbp && (*fbp)->dynamic)
1000 {
1001 if (rif->destroy_fringe_bitmap)
1002 rif->destroy_fringe_bitmap (n);
1003 xfree (*fbp);
1004 *fbp = NULL;
1005 }
1006
1007 while (max_used_fringe_bitmap > MAX_STANDARD_FRINGE_BITMAPS
1008 && fringe_bitmaps[max_used_fringe_bitmap - 1] == NULL)
1009 max_used_fringe_bitmap--;
1010
1011 return Qnil;
1012}
1013
1014
1015/* Initialize bitmap bit.
0881a0fd
KS
1016
1017 On X, we bit-swap the built-in bitmaps and reduce bitmap
1018 from short to char array if width is <= 8 bits.
1019
bd231131
KS
1020 On MAC with big-endian CPU, we need to byte-swap each short.
1021
1022 On W32 and MAC (little endian), there's no need to do this.
2d05deef
KS
1023*/
1024
1025void
1026init_fringe_bitmap (which, fb, once_p)
1027 enum fringe_bitmap_type which;
1028 struct fringe_bitmap *fb;
1029 int once_p;
1030{
1031 if (once_p || fb->dynamic)
1032 {
0881a0fd
KS
1033#if defined (HAVE_X_WINDOWS)
1034 static unsigned char swap_nibble[16]
1035 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
1036 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
1037 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
bd231131 1038 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
0881a0fd 1039 unsigned short *bits = fb->bits;
2d05deef 1040 int j;
0881a0fd
KS
1041
1042 if (fb->width <= 8)
1043 {
1044 unsigned char *cbits = (unsigned char *)fb->bits;
1045 for (j = 0; j < fb->height; j++)
1046 {
1047 unsigned short b = *bits++;
1048 unsigned char c;
1049 c = (unsigned char)((swap_nibble[b & 0xf] << 4)
1050 | (swap_nibble[(b>>4) & 0xf]));
1051 *cbits++ = (c >> (8 - fb->width));
1052 }
1053 }
1054 else
2d05deef 1055 {
0881a0fd
KS
1056 for (j = 0; j < fb->height; j++)
1057 {
1058 unsigned short b = *bits;
1059 b = (unsigned short)((swap_nibble[b & 0xf] << 12)
1060 | (swap_nibble[(b>>4) & 0xf] << 8)
1061 | (swap_nibble[(b>>8) & 0xf] << 4)
1062 | (swap_nibble[(b>>12) & 0xf]));
1063 *bits++ = (b >> (16 - fb->width));
1064 }
2d05deef 1065 }
bd231131
KS
1066#endif /* HAVE_X_WINDOWS */
1067
1068#if defined (MAC_OS) && defined (WORDS_BIG_ENDIAN)
1069 unsigned short *bits = fb->bits;
159c348e 1070 int j;
bd231131
KS
1071 for (j = 0; j < fb->height; j++)
1072 {
1073 unsigned short b = *bits;
1074 *bits++ = ((b >> 8) & 0xff) | ((b & 0xff) << 8);
1075 }
1076#endif /* MAC_OS && WORDS_BIG_ENDIAN */
2d05deef
KS
1077 }
1078
1079 if (!once_p)
1080 {
1081 Fdestroy_fringe_bitmap (make_number (which));
1082
1083 if (rif->define_fringe_bitmap)
1084 rif->define_fringe_bitmap (which, fb->bits, fb->height, fb->width);
1085
1086 fringe_bitmaps[which] = fb;
1087 if (which >= max_used_fringe_bitmap)
1088 max_used_fringe_bitmap = which + 1;
1089 }
1090}
1091
1092
1093DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap,
1094 1, 5, 0,
1095 doc: /* Define a fringe bitmap from BITS of height HEIGHT and width WIDTH.
0881a0fd
KS
1096BITS is either a string or a vector of integers.
1097HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
1098WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
bffe8c26 1099Optional fourth arg ALIGN may be one of `top', `center', or `bottom',
0881a0fd
KS
1100indicating the positioning of the bitmap relative to the rows where it
1101is used; the default is to center the bitmap. Fourth arg may also be a
1102list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1103should be repeated.
2d05deef
KS
1104Optional fifth argument WHICH is bitmap number to redefine.
1105Return new bitmap number, or nil of no more free bitmap slots. */)
1106 (bits, height, width, align, which)
1107 Lisp_Object bits, height, width, align, which;
1108{
1109 Lisp_Object len;
1110 int n, h, i, j;
0881a0fd 1111 unsigned short *b;
2d05deef
KS
1112 struct fringe_bitmap fb, *xfb;
1113 int fill1 = 0, fill2 = 0;
1114
1115 if (!STRINGP (bits) && !VECTORP (bits))
1116 bits = wrong_type_argument (Qstringp, bits);
1117
1118 len = Flength (bits);
1119
1120 if (NILP (height))
1121 h = fb.height = XINT (len);
1122 else
1123 {
1124 CHECK_NUMBER (height);
1125 fb.height = min (XINT (height), 255);
1126 if (fb.height > XINT (len))
1127 {
1128 h = XINT (len);
1129 fill1 = (fb.height - h) / 2;
1130 fill2 = fb.height - h - fill1;
1131 }
1132 }
bffe8c26 1133
2d05deef
KS
1134 if (NILP (width))
1135 fb.width = 8;
1136 else
1137 {
1138 CHECK_NUMBER (width);
1139 fb.width = min (XINT (width), 255);
1140 }
1141
1142 fb.period = 0;
1143 fb.align = ALIGN_BITMAP_CENTER;
1144
1145 if (CONSP (align))
1146 {
1147 Lisp_Object period = XCDR (align);
1148 if (CONSP (period))
1149 {
1150 period = XCAR (period);
1151 if (!NILP (period))
1152 {
1153 fb.period = fb.height;
1154 fb.height = 255;
1155 }
1156 }
1157 align = XCAR (align);
1158 }
1159 if (EQ (align, Qtop))
1160 fb.align = ALIGN_BITMAP_TOP;
1161 else if (EQ (align, Qbottom))
1162 fb.align = ALIGN_BITMAP_BOTTOM;
1163 else if (!NILP (align) && !EQ (align, Qcenter))
1164 error ("Bad align argument");
1165
1166 if (NILP (which))
1167 {
1168 if (max_used_fringe_bitmap < MAX_FRINGE_BITMAPS)
d2f14999 1169 n = max_used_fringe_bitmap++;
2d05deef
KS
1170 else
1171 {
1172 for (n = MAX_STANDARD_FRINGE_BITMAPS;
1173 n < MAX_FRINGE_BITMAPS;
1174 n++)
1175 if (fringe_bitmaps[n] == NULL)
1176 break;
1177 if (n == MAX_FRINGE_BITMAPS)
1178 return Qnil;
1179 }
1180 which = make_number (n);
1181 }
1182 else
1183 {
1184 CHECK_NUMBER (which);
1185 n = XINT (which);
1186 if (n <= NO_FRINGE_BITMAP || n >= MAX_FRINGE_BITMAPS)
1187 error ("Invalid fringe bitmap number");
1188 }
1189
1190 fb.dynamic = 1;
1191
beaedd56
AS
1192 xfb = (struct fringe_bitmap *) xmalloc (sizeof fb
1193 + fb.height * BYTES_PER_BITMAP_ROW);
1194 fb.bits = b = (unsigned short *) (xfb + 1);
2d05deef
KS
1195 bzero (b, fb.height);
1196
1197 j = 0;
1198 while (j < fb.height)
1199 {
1200 for (i = 0; i < fill1 && j < fb.height; i++)
1201 b[j++] = 0;
beaedd56 1202 for (i = 0; i < h && j < fb.height; i++)
2d05deef
KS
1203 {
1204 Lisp_Object elt = Faref (bits, make_number (i));
1205 b[j++] = NUMBERP (elt) ? XINT (elt) : 0;
1206 }
1207 for (i = 0; i < fill2 && j < fb.height; i++)
1208 b[j++] = 0;
1209 }
1210
1211 *xfb = fb;
1212
1213 init_fringe_bitmap (n, xfb, 0);
1214
1215 return which;
1216}
1217
1218DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face,
1219 1, 2, 0,
bffe8c26 1220 doc: /* Set face for fringe bitmap FRINGE-ID to FACE.
2d05deef
KS
1221If FACE is nil, reset face to default fringe face. */)
1222 (fringe_id, face)
1223 Lisp_Object fringe_id, face;
1224{
1225 int face_id;
1226
1227 CHECK_NUMBER (fringe_id);
1228 if (!valid_fringe_bitmap_id_p (XINT (fringe_id)))
1229 error ("Invalid fringe id");
1230
1231 if (!NILP (face))
1232 {
1233 face_id = lookup_named_face (SELECTED_FRAME (), face, 'A');
1234 if (face_id < 0)
1235 error ("No such face");
1236 }
1237 else
1238 face_id = FRINGE_FACE_ID;
1239
1240 fringe_faces [XINT (fringe_id)] = face_id;
1241
1242 return Qnil;
1243}
1244
1245DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos, Sfringe_bitmaps_at_pos,
1246 0, 2, 0,
bffe8c26 1247 doc: /* Return fringe bitmaps of row containing position POS in window WINDOW.
2d05deef
KS
1248If WINDOW is nil, use selected window. If POS is nil, use value of point
1249in that window. Return value is a cons (LEFT . RIGHT) where LEFT and RIGHT
1250are the fringe bitmap numbers for the bitmaps in the left and right fringe,
1251resp. Return nil if POS is not visible in WINDOW. */)
1252 (pos, window)
d30b6b33 1253 Lisp_Object pos, window;
2d05deef
KS
1254{
1255 struct window *w;
1256 struct buffer *old_buffer = NULL;
1257 struct glyph_row *row;
1258 int textpos;
1259
1260 if (NILP (window))
1261 window = selected_window;
1262 CHECK_WINDOW (window);
1263 w = XWINDOW (window);
1264
1265 if (!NILP (pos))
1266 {
1267 CHECK_NUMBER_COERCE_MARKER (pos);
1268 textpos = XINT (pos);
1269 }
1270 else if (w == XWINDOW (selected_window))
1271 textpos = PT;
1272 else
1273 textpos = XMARKER (w->pointm)->charpos;
1274
1275 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1276 row = row_containing_pos (w, textpos, row, NULL, 0);
1277 if (row)
1278 return Fcons (make_number (row->left_fringe_bitmap),
1279 make_number (row->right_fringe_bitmap));
1280 else
1281 return Qnil;
1282}
1283
1284
1285/***********************************************************************
1286 Initialization
1287 ***********************************************************************/
1288
1289void
1290syms_of_fringe ()
1291{
1292
1293 defsubr (&Sdestroy_fringe_bitmap);
1294 defsubr (&Sdefine_fringe_bitmap);
1295 defsubr (&Sfringe_bitmaps_at_pos);
1296 defsubr (&Sset_fringe_bitmap_face);
1297
1298 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe,
1299 doc: /* *Non-nil means that newline may flow into the right fringe.
1300This means that display lines which are exactly as wide as the window
1301(not counting the final newline) will only occupy one screen line, by
1302showing (or hiding) the final newline in the right fringe; when point
1303is at the final newline, the cursor is shown in the right fringe.
1304If nil, also continue lines which are exactly as wide as the window. */);
1305 Voverflow_newline_into_fringe = Qt;
1306
1307}
1308
1309/* Initialize this module when Emacs starts. */
1310
1311void
1312init_fringe_once ()
1313{
1314 enum fringe_bitmap_type bt;
1315
1316 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1317 init_fringe_bitmap(bt, &standard_bitmaps[bt], 1);
1318}
1319
1320void
1321init_fringe ()
1322{
1323 int i;
1324
1325 bzero (fringe_bitmaps, sizeof fringe_bitmaps);
1326 for (i = 0; i < MAX_FRINGE_BITMAPS; i++)
1327 fringe_faces[i] = FRINGE_FACE_ID;
1328}
1329
1330#ifdef HAVE_NTGUI
1331
1332void
1333w32_init_fringe ()
1334{
1335 enum fringe_bitmap_type bt;
1336
1337 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1338 {
1339 struct fringe_bitmap *fb = &standard_bitmaps[bt];
1340 rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
1341 }
1342}
1343
1344void
1345w32_reset_fringes ()
1346{
1347 /* Destroy row bitmaps. */
1348 int bt;
bffe8c26 1349
2d05deef
KS
1350 for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++)
1351 rif->destroy_fringe_bitmap (bt);
1352}
1353
bd231131 1354#endif /* HAVE_NTGUI */
2d05deef
KS
1355
1356#endif /* HAVE_WINDOW_SYSTEM */
1357
429e7e2d
MB
1358/* arch-tag: 04596920-43eb-473d-b319-82712338162d
1359 (do not change this comment) */