1/* Fringe handling (split from xdisp.c).
2   Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997,
3                 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4                 2006, 2007  Free Software Foundation, Inc.
5
6This file is part of GNU Emacs.
7
8GNU Emacs is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU Emacs is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU Emacs; see the file COPYING.  If not, write to
20the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21Boston, MA 02110-1301, USA.  */
22
23#include <config.h>
24#include <stdio.h>
25
26#include "lisp.h"
27#include "frame.h"
28#include "window.h"
29#include "dispextern.h"
30#include "buffer.h"
31#include "blockinput.h"
32
33#ifdef HAVE_WINDOW_SYSTEM
34
35extern Lisp_Object Qfringe;
36extern Lisp_Object Qtop, Qbottom, Qcenter;
37extern Lisp_Object Qup, Qdown, Qleft, Qright;
38
39/* Non-nil means that newline may flow into the right fringe.  */
40
41Lisp_Object Voverflow_newline_into_fringe;
42
43/* List of known fringe bitmap symbols.
44
45   The fringe bitmap number is stored in the `fringe' property on
46   those symbols.  Names for the built-in bitmaps are installed by
47   loading fringe.el.
48 */
49
50Lisp_Object Vfringe_bitmaps;
51
52/* Fringe bitmaps are represented in three different ways:
53
54   Logical bitmaps are used internally to denote things like
55   'end-of-buffer', 'left-truncation', 'overlay-arrow', etc.
56
57   Physical bitmaps specify the visual appearence of the bitmap,
58   e.g. 'bottom-left-angle', 'left-arrow', 'left-triangle', etc.
59   User defined bitmaps are physical bitmaps.
60
61   Internally, fringe bitmaps for a specific display row are
62   represented as a simple integer that is used as an index
63   into the table of all defined bitmaps.  This index is stored
64   in the `fringe' property of the physical bitmap symbol.
65
66   Logical bitmaps are mapped to physical bitmaps through the
67   buffer-local `fringe-indicator-alist' variable.
68
69   Each element of this alist is a cons (LOGICAL . PHYSICAL)
70   mapping a logical bitmap to a physical bitmap.
71   PHYSICAL is either a symbol to use in both left and right fringe,
72   or a cons of two symbols (LEFT . RIGHT) denoting different
73   bitmaps to use in left and right fringe.
74
75   LOGICAL is first looked up in the window's buffer's buffer-local
76   value of the fringe-indicator-alist variable, and if not present,
77   in the global value of fringe-indicator-alist.
78
79   If LOGICAL is not present in either alist, or the PHYSICAL value
80   found is nil, no bitmap is shown for the logical bitmap.
81
82   The `left-fringe' and `right-fringe' display properties
83   must specify physical bitmap symbols.
84*/
85
86extern Lisp_Object Qunknown;
87Lisp_Object Qtruncation, Qcontinuation, Qoverlay_arrow;
88Lisp_Object Qempty_line, Qtop_bottom;
89extern Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
90Lisp_Object Qhollow_small;
91
92enum fringe_bitmap_align
93{
94  ALIGN_BITMAP_CENTER = 0,
95  ALIGN_BITMAP_TOP,
96  ALIGN_BITMAP_BOTTOM
97};
98
99struct fringe_bitmap
100{
101  unsigned short *bits;
102  unsigned height : 8;
103  unsigned width : 8;
104  unsigned period : 8;
105  unsigned align : 2;
106  unsigned dynamic : 1;
107};
108
109
110/***********************************************************************
111			       Fringe bitmaps
112 ***********************************************************************/
113
114/* Undefined bitmap.  A question mark.  */
115/*
116  ..xxxx..
117  .xxxxxx.
118  xx....xx
119  xx....xx
120  ....xx..
121  ...xx...
122  ...xx...
123  ........
124  ...xx...
125  ...xx...
126*/
127static unsigned short question_mark_bits[] = {
128  0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
129
130/* An arrow like this: `<-'.  */
131/*
132  ...xx...
133  ..xx....
134  .xx.....
135  xxxxxx..
136  xxxxxx..
137  .xx.....
138  ..xx....
139  ...xx...
140*/
141static unsigned short left_arrow_bits[] = {
142   0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
143
144
145/* Right truncation arrow bitmap `->'.  */
146/*
147  ...xx...
148  ....xx..
149  .....xx.
150  ..xxxxxx
151  ..xxxxxx
152  .....xx.
153  ....xx..
154  ...xx...
155*/
156static unsigned short right_arrow_bits[] = {
157   0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
158
159
160/* Up arrow bitmap.  */
161/*
162  ...xx...
163  ..xxxx..
164  .xxxxxx.
165  xxxxxxxx
166  ...xx...
167  ...xx...
168  ...xx...
169  ...xx...
170*/
171static unsigned short up_arrow_bits[] = {
172   0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
173
174
175/* Down arrow bitmap.  */
176/*
177  ...xx...
178  ...xx...
179  ...xx...
180  ...xx...
181  xxxxxxxx
182  .xxxxxx.
183  ..xxxx..
184  ...xx...
185*/
186static unsigned short down_arrow_bits[] = {
187   0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
188
189/* Marker for continuation lines.  */
190/*
191  ..xxxx..
192  .xxxxx..
193  xx......
194  xxx..x..
195  xxxxxx..
196  .xxxxx..
197  ..xxxx..
198  .xxxxx..
199*/
200static unsigned short left_curly_arrow_bits[] = {
201   0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
202
203/* Marker for continued lines.  */
204/*
205  ..xxxx..
206  ..xxxxx.
207  ......xx
208  ..x..xxx
209  ..xxxxxx
210  ..xxxxx.
211  ..xxxx..
212  ..xxxxx.
213*/
214static unsigned short right_curly_arrow_bits[] = {
215   0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
216
217/* Reverse Overlay arrow bitmap.  A triangular arrow.  */
218/*
219  ......xx
220  ....xxxx
221  ...xxxxx
222  ..xxxxxx
223  ..xxxxxx
224  ...xxxxx
225  ....xxxx
226  ......xx
227*/
228static unsigned short left_triangle_bits[] = {
229   0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
230
231/* Overlay arrow bitmap.  A triangular arrow.  */
232/*
233  xx......
234  xxxx....
235  xxxxx...
236  xxxxxx..
237  xxxxxx..
238  xxxxx...
239  xxxx....
240  xx......
241*/
242static unsigned short right_triangle_bits[] = {
243   0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
244
245/* First line bitmap.  An top-left angle.  */
246/*
247  xxxxxx..
248  xxxxxx..
249  xx......
250  xx......
251  xx......
252  xx......
253  xx......
254  ........
255*/
256static unsigned short top_left_angle_bits[] = {
257   0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00};
258
259/* First line bitmap.  An right-up angle.  */
260/*
261  ..xxxxxx
262  ..xxxxxx
263  ......xx
264  ......xx
265  ......xx
266  ......xx
267  ......xx
268  ........
269*/
270static unsigned short top_right_angle_bits[] = {
271   0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
272
273/* Last line bitmap.  An left-down angle.  */
274/*
275  ........
276  xx......
277  xx......
278  xx......
279  xx......
280  xx......
281  xxxxxx..
282  xxxxxx..
283*/
284static unsigned short bottom_left_angle_bits[] = {
285   0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
286
287/* Last line bitmap.  An right-down angle.  */
288/*
289  ........
290  ......xx
291  ......xx
292  ......xx
293  ......xx
294  ......xx
295  ..xxxxxx
296  ..xxxxxx
297*/
298static unsigned short bottom_right_angle_bits[] = {
299   0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
300
301/* First/last line bitmap.  An left bracket.  */
302/*
303  xxxxxx..
304  xxxxxx..
305  xx......
306  xx......
307  xx......
308  xx......
309  xx......
310  xx......
311  xxxxxx..
312  xxxxxx..
313*/
314static unsigned short left_bracket_bits[] = {
315   0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
316
317/* First/last line bitmap.  An right bracket.  */
318/*
319  ..xxxxxx
320  ..xxxxxx
321  ......xx
322  ......xx
323  ......xx
324  ......xx
325  ......xx
326  ......xx
327  ..xxxxxx
328  ..xxxxxx
329*/
330static unsigned short right_bracket_bits[] = {
331  0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
332
333/* Filled box cursor bitmap.  A filled box; max 13 pixels high.  */
334/*
335  xxxxxxx.
336  xxxxxxx.
337  xxxxxxx.
338  xxxxxxx.
339  xxxxxxx.
340  xxxxxxx.
341  xxxxxxx.
342  xxxxxxx.
343  xxxxxxx.
344  xxxxxxx.
345  xxxxxxx.
346  xxxxxxx.
347  xxxxxxx.
348*/
349static unsigned short filled_rectangle_bits[] = {
350   0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
351
352/* Hollow box cursor bitmap.  A hollow box; max 13 pixels high.  */
353/*
354  xxxxxxx.
355  x.....x.
356  x.....x.
357  x.....x.
358  x.....x.
359  x.....x.
360  x.....x.
361  x.....x.
362  x.....x.
363  x.....x.
364  x.....x.
365  x.....x.
366  xxxxxxx.
367*/
368static unsigned short hollow_rectangle_bits[] = {
369   0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe};
370
371/* Hollow square bitmap.  */
372/*
373  .xxxxxx.
374  .x....x.
375  .x....x.
376  .x....x.
377  .x....x.
378  .xxxxxx.
379*/
380static unsigned short hollow_square_bits[] = {
381   0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
382
383/* Filled square bitmap.  */
384/*
385  .xxxxxx.
386  .xxxxxx.
387  .xxxxxx.
388  .xxxxxx.
389  .xxxxxx.
390  .xxxxxx.
391*/
392static unsigned short filled_square_bits[] = {
393   0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e};
394
395/* Bar cursor bitmap.  A vertical bar; max 13 pixels high.  */
396/*
397  xx......
398  xx......
399  xx......
400  xx......
401  xx......
402  xx......
403  xx......
404  xx......
405  xx......
406  xx......
407  xx......
408  xx......
409  xx......
410*/
411static unsigned short vertical_bar_bits[] = {
412   0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
413
414/* HBar cursor bitmap.  A horizontal bar; 2 pixels high.  */
415/*
416  xxxxxxx.
417  xxxxxxx.
418*/
419static unsigned short horizontal_bar_bits[] = {
420  0xfe, 0xfe};
421
422
423/* Bitmap drawn to indicate lines not displaying text if
424   `indicate-empty-lines' is non-nil.  */
425/*
426  ........
427  ..xxxx..
428  ........
429  ........
430  ..xxxx..
431  ........
432*/
433static unsigned short empty_line_bits[] = {
434  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
435  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
436  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
437  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
438  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
439  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
440  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
441  0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
442
443
444#define BYTES_PER_BITMAP_ROW  (sizeof (unsigned short))
445#define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
446#define FRBITS(bits)  bits, STANDARD_BITMAP_HEIGHT (bits)
447
448/* NOTE:  The order of these bitmaps must match the sequence
449   used in fringe.el to define the corresponding symbols.  */
450
451struct fringe_bitmap standard_bitmaps[] =
452{
453  { NULL, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */
454  { FRBITS (question_mark_bits),      8, 0, ALIGN_BITMAP_CENTER, 0 },
455  { FRBITS (left_arrow_bits),         8, 0, ALIGN_BITMAP_CENTER, 0 },
456  { FRBITS (right_arrow_bits),        8, 0, ALIGN_BITMAP_CENTER, 0 },
457  { FRBITS (up_arrow_bits),           8, 0, ALIGN_BITMAP_TOP,    0 },
458  { FRBITS (down_arrow_bits),         8, 0, ALIGN_BITMAP_BOTTOM, 0 },
459  { FRBITS (left_curly_arrow_bits),   8, 0, ALIGN_BITMAP_CENTER, 0 },
460  { FRBITS (right_curly_arrow_bits),  8, 0, ALIGN_BITMAP_CENTER, 0 },
461  { FRBITS (left_triangle_bits),      8, 0, ALIGN_BITMAP_CENTER, 0 },
462  { FRBITS (right_triangle_bits),     8, 0, ALIGN_BITMAP_CENTER, 0 },
463  { FRBITS (top_left_angle_bits),     8, 0, ALIGN_BITMAP_TOP,    0 },
464  { FRBITS (top_right_angle_bits),    8, 0, ALIGN_BITMAP_TOP,    0 },
465  { FRBITS (bottom_left_angle_bits),  8, 0, ALIGN_BITMAP_BOTTOM, 0 },
466  { FRBITS (bottom_right_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
467  { FRBITS (left_bracket_bits),       8, 0, ALIGN_BITMAP_CENTER, 0 },
468  { FRBITS (right_bracket_bits),      8, 0, ALIGN_BITMAP_CENTER, 0 },
469  { FRBITS (filled_rectangle_bits),   8, 0, ALIGN_BITMAP_CENTER, 0 },
470  { FRBITS (hollow_rectangle_bits),   8, 0, ALIGN_BITMAP_CENTER, 0 },
471  { FRBITS (filled_square_bits),      8, 0, ALIGN_BITMAP_CENTER, 0 },
472  { FRBITS (hollow_square_bits),      8, 0, ALIGN_BITMAP_CENTER, 0 },
473  { FRBITS (vertical_bar_bits),       8, 0, ALIGN_BITMAP_CENTER, 0 },
474  { FRBITS (horizontal_bar_bits),     8, 0, ALIGN_BITMAP_BOTTOM, 0 },
475  { FRBITS (empty_line_bits),         8, 3, ALIGN_BITMAP_TOP,    0 },
476};
477
478#define NO_FRINGE_BITMAP 0
479#define UNDEF_FRINGE_BITMAP 1
480#define MAX_STANDARD_FRINGE_BITMAPS (sizeof(standard_bitmaps)/sizeof(standard_bitmaps[0]))
481
482static struct fringe_bitmap **fringe_bitmaps;
483static Lisp_Object *fringe_faces;
484static int max_fringe_bitmaps;
485
486static int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS;
487
488
489/* Lookup bitmap number for symbol BITMAP.
490   Return 0 if not a bitmap.  */
491
492int
493lookup_fringe_bitmap (bitmap)
494     Lisp_Object bitmap;
495{
496  int bn;
497
498  bitmap = Fget (bitmap, Qfringe);
499  if (!INTEGERP (bitmap))
500    return 0;
501
502  bn = XINT (bitmap);
503  if (bn > NO_FRINGE_BITMAP
504      && bn < max_used_fringe_bitmap
505      && (bn < MAX_STANDARD_FRINGE_BITMAPS
506	  || fringe_bitmaps[bn] != NULL))
507    return bn;
508
509  return 0;
510}
511
512/* Get fringe bitmap name for bitmap number BN.
513
514   Found by traversing Vfringe_bitmaps comparing BN to the
515   fringe property for each symbol.
516
517   Return BN if not found in Vfringe_bitmaps.  */
518
519static Lisp_Object
520get_fringe_bitmap_name (bn)
521     int bn;
522{
523  Lisp_Object bitmaps;
524  Lisp_Object num;
525
526  /* Zero means no bitmap -- return nil.  */
527  if (bn <= 0)
528    return Qnil;
529
530  bitmaps = Vfringe_bitmaps;
531  num = make_number (bn);
532
533  while (CONSP (bitmaps))
534    {
535      Lisp_Object bitmap = XCAR (bitmaps);
536      if (EQ (num, Fget (bitmap, Qfringe)))
537	return bitmap;
538      bitmaps = XCDR (bitmaps);
539    }
540
541  return num;
542}
543
544
545/* Draw the bitmap WHICH in one of the left or right fringes of
546   window W.  ROW is the glyph row for which to display the bitmap; it
547   determines the vertical position at which the bitmap has to be
548   drawn.
549   LEFT_P is 1 for left fringe, 0 for right fringe.
550*/
551
552static void
553draw_fringe_bitmap_1 (w, row, left_p, overlay, which)
554     struct window *w;
555     struct glyph_row *row;
556     int left_p, overlay;
557     int which;
558{
559  struct frame *f = XFRAME (WINDOW_FRAME (w));
560  struct draw_fringe_bitmap_params p;
561  struct fringe_bitmap *fb;
562  int period;
563  int face_id = DEFAULT_FACE_ID;
564
565  p.cursor_p = 0;
566  p.overlay_p = (overlay & 1) == 1;
567  p.cursor_p = (overlay & 2) == 2;
568
569  if (which != NO_FRINGE_BITMAP)
570    {
571    }
572  else if (left_p)
573    {
574      which = row->left_fringe_bitmap;
575      face_id = row->left_fringe_face_id;
576    }
577  else
578    {
579      which = row->right_fringe_bitmap;
580      face_id = row->right_fringe_face_id;
581    }
582
583  if (face_id == DEFAULT_FACE_ID)
584    {
585      Lisp_Object face;
586
587      if ((face = fringe_faces[which], NILP (face))
588	  || (face_id = lookup_derived_face (f, face, 'A', FRINGE_FACE_ID, 0),
589	      face_id < 0))
590	face_id = FRINGE_FACE_ID;
591    }
592
593  fb = fringe_bitmaps[which];
594  if (fb == NULL)
595    fb = &standard_bitmaps[which < MAX_STANDARD_FRINGE_BITMAPS
596			   ? which : UNDEF_FRINGE_BITMAP];
597
598  period = fb->period;
599
600  /* Convert row to frame coordinates.  */
601  p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
602
603  p.which = which;
604  p.bits = fb->bits;
605  p.wd = fb->width;
606
607  p.h = fb->height;
608  p.dh = (period > 0 ? (p.y % period) : 0);
609  p.h -= p.dh;
610  /* Clip bitmap if too high.  */
611  if (p.h > row->height)
612    p.h = row->height;
613
614  p.face = FACE_FROM_ID (f, face_id);
615
616  if (p.face == NULL)
617    {
618      /* This could happen after clearing face cache.
619	 But it shouldn't happen anymore.  ++kfs */
620      return;
621    }
622
623  PREPARE_FACE_FOR_DISPLAY (f, p.face);
624
625  /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
626     the fringe.  */
627  p.bx = -1;
628  if (left_p)
629    {
630      int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
631      int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
632				   ? LEFT_MARGIN_AREA
633				   : TEXT_AREA));
634      if (p.wd > wd)
635	p.wd = wd;
636      p.x = x - p.wd - (wd - p.wd) / 2;
637
638      if (p.wd < wd || row->height > p.h)
639	{
640	  /* If W has a vertical border to its left, don't draw over it.  */
641	  wd -= ((!WINDOW_LEFTMOST_P (w)
642		  && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
643		 ? 1 : 0);
644	  p.bx = x - wd;
645	  p.nx = wd;
646	}
647    }
648  else
649    {
650      int x = window_box_right (w,
651				(WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
652				 ? RIGHT_MARGIN_AREA
653				 : TEXT_AREA));
654      int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
655      if (p.wd > wd)
656	p.wd = wd;
657      p.x = x + (wd - p.wd) / 2;
658      /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
659	 the fringe.  */
660      if (p.wd < wd || row->height > p.h)
661	{
662	  p.bx = x;
663	  p.nx = wd;
664	}
665    }
666
667  if (p.bx >= 0)
668    {
669      int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
670
671      p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
672      p.ny = row->visible_height;
673    }
674
675  /* Adjust y to the offset in the row to start drawing the bitmap.  */
676  switch (fb->align)
677    {
678    case ALIGN_BITMAP_CENTER:
679      p.y += (row->height - p.h) / 2;
680      break;
681    case ALIGN_BITMAP_BOTTOM:
682      p.h = fb->height;
683      p.y += (row->visible_height - p.h);
684      break;
685    case ALIGN_BITMAP_TOP:
686      break;
687    }
688
689  rif->draw_fringe_bitmap (w, row, &p);
690}
691
692static int
693get_logical_cursor_bitmap (w, cursor)
694     struct window *w;
695     Lisp_Object cursor;
696{
697  Lisp_Object cmap, bm = Qnil;
698
699  if ((cmap = XBUFFER (w->buffer)->fringe_cursor_alist), !NILP (cmap))
700    {
701      bm = Fassq (cursor, cmap);
702      if (CONSP (bm))
703	{
704	  if ((bm = XCDR (bm)), NILP (bm))
705	    return NO_FRINGE_BITMAP;
706	  return lookup_fringe_bitmap (bm);
707	}
708    }
709  if (EQ (cmap, buffer_defaults.fringe_cursor_alist))
710    return NO_FRINGE_BITMAP;
711  bm = Fassq (cursor, buffer_defaults.fringe_cursor_alist);
712  if (!CONSP (bm) || ((bm = XCDR (bm)), NILP (bm)))
713    return NO_FRINGE_BITMAP;
714  return lookup_fringe_bitmap (bm);
715}
716
717static int
718get_logical_fringe_bitmap (w, bitmap, right_p, partial_p)
719     struct window *w;
720     Lisp_Object bitmap;
721     int right_p, partial_p;
722{
723  Lisp_Object cmap, bm1 = Qnil, bm2 = Qnil, bm;
724  int ln1 = 0, ln2 = 0;
725  int ix1 = right_p;
726  int ix2 = ix1 + (partial_p ? 2 : 0);
727
728  /* Lookup in buffer-local fringe-indicator-alist before global alist.
729
730     Elements are:
731	BITMAP		-- use for all
732	(L R)		-- use for left right (whether partial or not)
733	(L R PL PR)	-- use for left rigth partial-left partial-right
734	If any value in local binding is not present or t, use global value.
735
736     If partial, lookup partial bitmap in default value if not found here.
737     If not partial, or no partial spec is present, use non-partial bitmap.  */
738
739  if ((cmap = XBUFFER (w->buffer)->fringe_indicator_alist), !NILP (cmap))
740    {
741      bm1 = Fassq (bitmap, cmap);
742      if (CONSP (bm1))
743	{
744	  if ((bm1 = XCDR (bm1)), NILP (bm1))
745	    return NO_FRINGE_BITMAP;
746	  if (CONSP (bm1))
747	    {
748	      ln1 = XINT (Flength (bm1));
749	      if (partial_p)
750		{
751		  if (ln1 > ix2)
752		    {
753		      bm = Fnth (make_number (ix2), bm1);
754		      if (!EQ (bm, Qt))
755			goto found;
756		    }
757		}
758	      else
759		{
760		  if (ln1 > ix1)
761		    {
762		      bm = Fnth (make_number (ix1), bm1);
763		      if (!EQ (bm, Qt))
764			goto found;
765		    }
766		}
767	    }
768	  else if ((bm = bm1, !EQ (bm, Qt)))
769	    goto found;
770	}
771    }
772
773  if (!EQ (cmap, buffer_defaults.fringe_indicator_alist)
774      && !NILP (buffer_defaults.fringe_indicator_alist))
775    {
776      bm2 = Fassq (bitmap, buffer_defaults.fringe_indicator_alist);
777      if (CONSP (bm2))
778	{
779	  if ((bm2 = XCDR (bm2)), !NILP (bm2))
780	    {
781	      if (CONSP (bm2))
782		{
783		  ln2 = XINT (Flength (bm2));
784		  if (partial_p)
785		    {
786		      if (ln2 > ix2)
787			{
788			  bm = Fnth (make_number (ix2), bm2);
789			  if (!EQ (bm, Qt))
790			    goto found;
791			}
792		    }
793		}
794	    }
795	}
796    }
797
798  if (ln1 > ix1)
799    {
800      bm = Fnth (make_number (ix1), bm1);
801      if (!EQ (bm, Qt))
802	goto found;
803    }
804
805  if (ln2 > ix1)
806    {
807      bm = Fnth (make_number (ix1), bm2);
808      if (!EQ (bm, Qt))
809	goto found;
810      return NO_FRINGE_BITMAP;
811    }
812  else if ((bm = bm2, NILP (bm)))
813    return NO_FRINGE_BITMAP;
814
815 found:
816  return lookup_fringe_bitmap (bm);
817}
818
819
820void
821draw_fringe_bitmap (w, row, left_p)
822     struct window *w;
823     struct glyph_row *row;
824     int left_p;
825{
826  int overlay = 0;
827
828  if (!left_p && row->cursor_in_fringe_p)
829    {
830      Lisp_Object cursor = Qnil;
831
832      switch (w->phys_cursor_type)
833	{
834	case HOLLOW_BOX_CURSOR:
835	  if (row->visible_height >= STANDARD_BITMAP_HEIGHT (hollow_rectangle_bits))
836	    cursor = Qhollow;
837	  else
838	    cursor = Qhollow_small;
839	  break;
840	case FILLED_BOX_CURSOR:
841	  cursor = Qbox;
842	  break;
843	case BAR_CURSOR:
844	  cursor = Qbar;
845	  break;
846	case HBAR_CURSOR:
847	  cursor = Qhbar;
848	  break;
849	case NO_CURSOR:
850	default:
851	  w->phys_cursor_on_p = 0;
852	  row->cursor_in_fringe_p = 0;
853	  break;
854	}
855      if (!NILP (cursor))
856	{
857	  int bm = get_logical_cursor_bitmap (w, cursor);
858	  if (bm != NO_FRINGE_BITMAP)
859	    {
860	      draw_fringe_bitmap_1 (w, row, 0, 2, bm);
861	      overlay = EQ (cursor, Qbox) ? 3 : 1;
862	    }
863	}
864    }
865
866  draw_fringe_bitmap_1 (w, row, left_p, overlay, NO_FRINGE_BITMAP);
867
868  if (left_p && row->overlay_arrow_bitmap != NO_FRINGE_BITMAP)
869    draw_fringe_bitmap_1 (w, row, 1, 1, row->overlay_arrow_bitmap);
870}
871
872
873/* Draw fringe bitmaps for glyph row ROW on window W.  Call this
874   function with input blocked.  */
875
876void
877draw_row_fringe_bitmaps (w, row)
878     struct window *w;
879     struct glyph_row *row;
880{
881  xassert (interrupt_input_blocked);
882
883  /* If row is completely invisible, because of vscrolling, we
884     don't have to draw anything.  */
885  if (row->visible_height <= 0)
886    return;
887
888  if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
889    draw_fringe_bitmap (w, row, 1);
890
891  if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
892    draw_fringe_bitmap (w, row, 0);
893}
894
895/* Draw the fringes of window W.  Only fringes for rows marked for
896   update in redraw_fringe_bitmaps_p are drawn.
897
898   Return >0 if left or right fringe was redrawn in any way.
899
900   If NO_FRINGE is non-zero, also return >0 if either fringe has zero width.
901
902   A return value >0 indicates that the vertical line between windows
903   needs update (as it may be drawn in the fringe).
904*/
905
906int
907draw_window_fringes (w, no_fringe)
908     struct window *w;
909     int no_fringe;
910{
911  struct glyph_row *row;
912  int yb = window_text_bottom_y (w);
913  int nrows = w->current_matrix->nrows;
914  int y = 0, rn;
915  int updated = 0;
916
917  if (w->pseudo_window_p)
918    return 0;
919
920  /* Must draw line if no fringe */
921  if (no_fringe
922      && (WINDOW_LEFT_FRINGE_WIDTH (w) == 0
923	  || WINDOW_RIGHT_FRINGE_WIDTH (w) == 0))
924    updated++;
925
926  for (y = 0, rn = 0, row = w->current_matrix->rows;
927       y < yb && rn < nrows;
928       y += row->height, ++row, ++rn)
929    {
930      if (!row->redraw_fringe_bitmaps_p)
931	continue;
932      draw_row_fringe_bitmaps (w, row);
933      row->redraw_fringe_bitmaps_p = 0;
934      updated++;
935    }
936
937  return updated;
938}
939
940
941/* Recalculate the bitmaps to show in the fringes of window W.
942   Only mark rows with modified bitmaps for update in redraw_fringe_bitmaps_p.
943
944   If KEEP_CURRENT_P is 0, update current_matrix too.  */
945
946int
947update_window_fringes (w, keep_current_p)
948     struct window *w;
949     int keep_current_p;
950{
951  struct glyph_row *row, *cur = 0;
952  int yb = window_text_bottom_y (w);
953  int rn, nrows = w->current_matrix->nrows;
954  int y;
955  int redraw_p = 0;
956  Lisp_Object boundary_top = Qnil, boundary_bot = Qnil;
957  Lisp_Object arrow_top = Qnil, arrow_bot = Qnil;
958  Lisp_Object empty_pos;
959  Lisp_Object ind = Qnil;
960#define MAX_BITMAP_CACHE (8*4)
961  int bitmap_cache[MAX_BITMAP_CACHE];
962
963  if (w->pseudo_window_p)
964    return 0;
965
966  if (!MINI_WINDOW_P (w)
967      && (ind = XBUFFER (w->buffer)->indicate_buffer_boundaries, !NILP (ind)))
968    {
969      if (EQ (ind, Qleft) || EQ (ind, Qright))
970	boundary_top = boundary_bot = arrow_top = arrow_bot = ind;
971      else if (CONSP (ind) && CONSP (XCAR (ind)))
972	{
973	  Lisp_Object pos;
974	  if (pos = Fassq (Qt, ind), !NILP (pos))
975	    boundary_top = boundary_bot = arrow_top = arrow_bot = XCDR (pos);
976	  if (pos = Fassq (Qtop, ind), !NILP (pos))
977	    boundary_top = XCDR (pos);
978	  if (pos = Fassq (Qbottom, ind), !NILP (pos))
979	    boundary_bot = XCDR (pos);
980	  if (pos = Fassq (Qup, ind), !NILP (pos))
981	    arrow_top = XCDR (pos);
982	  if (pos = Fassq (Qdown, ind), !NILP (pos))
983	    arrow_bot = XCDR (pos);
984	}
985      else
986	/* Anything else means boundary on left and no arrows.  */
987	boundary_top = boundary_bot = Qleft;
988    }
989
990  if (!NILP (ind))
991    {
992      int done_top = 0, done_bot = 0;
993
994      for (y = 0, rn = 0;
995	   y < yb && rn < nrows;
996	   y += row->height, ++rn)
997	{
998	  unsigned indicate_bob_p, indicate_top_line_p;
999	  unsigned indicate_eob_p, indicate_bottom_line_p;
1000
1001	  row = w->desired_matrix->rows + rn;
1002	  if (!row->enabled_p)
1003	    row = w->current_matrix->rows + rn;
1004
1005	  indicate_bob_p = row->indicate_bob_p;
1006	  indicate_top_line_p = row->indicate_top_line_p;
1007	  indicate_eob_p = row->indicate_eob_p;
1008	  indicate_bottom_line_p = row->indicate_bottom_line_p;
1009
1010	  row->indicate_bob_p = row->indicate_top_line_p = 0;
1011	  row->indicate_eob_p = row->indicate_bottom_line_p = 0;
1012
1013	  if (!row->mode_line_p)
1014	    {
1015	      if (!done_top)
1016		{
1017		  if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer))
1018		      && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
1019		    row->indicate_bob_p = !NILP (boundary_top);
1020		  else
1021		    row->indicate_top_line_p = !NILP (arrow_top);
1022		  done_top = 1;
1023		}
1024
1025	      if (!done_bot)
1026		{
1027		  if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer))
1028		      && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row))
1029		    row->indicate_eob_p = !NILP (boundary_bot), done_bot = 1;
1030		  else if (y + row->height >= yb)
1031		    row->indicate_bottom_line_p = !NILP (arrow_bot), done_bot = 1;
1032		}
1033	    }
1034
1035	  if (indicate_bob_p != row->indicate_bob_p
1036	      || indicate_top_line_p != row->indicate_top_line_p
1037	      || indicate_eob_p != row->indicate_eob_p
1038	      || indicate_bottom_line_p != row->indicate_bottom_line_p)
1039	    row->redraw_fringe_bitmaps_p = 1;
1040	}
1041    }
1042
1043  empty_pos = XBUFFER (w->buffer)->indicate_empty_lines;
1044  if (!NILP (empty_pos) && !EQ (empty_pos, Qright))
1045    empty_pos = WINDOW_LEFT_FRINGE_WIDTH (w) == 0 ? Qright : Qleft;
1046
1047  for (y = 0; y < MAX_BITMAP_CACHE; y++)
1048    bitmap_cache[y] = -1;
1049
1050#define LEFT_FRINGE(cache, which, partial_p)			\
1051  (bitmap_cache[cache*4+partial_p] >= 0				\
1052   ? bitmap_cache[cache*4+partial_p]				\
1053   : (bitmap_cache[cache*4+partial_p] =				\
1054      get_logical_fringe_bitmap (w, which, 0, partial_p)))
1055
1056#define RIGHT_FRINGE(cache, which, partial_p)			\
1057  (bitmap_cache[cache*4+2+partial_p] >= 0			\
1058   ? bitmap_cache[cache*4+2+partial_p]				\
1059   : (bitmap_cache[cache*4+2+partial_p] =			\
1060      get_logical_fringe_bitmap (w, which, 1, partial_p)))
1061
1062
1063  for (y = 0, rn = 0;
1064       y < yb && rn < nrows;
1065       y += row->height, rn++)
1066    {
1067      int left, right;
1068      unsigned left_face_id, right_face_id;
1069
1070      row = w->desired_matrix->rows + rn;
1071      cur = w->current_matrix->rows + rn;
1072      if (!row->enabled_p)
1073	row = cur;
1074
1075      left_face_id = right_face_id = DEFAULT_FACE_ID;
1076
1077      /* Decide which bitmap to draw in the left fringe.  */
1078      if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
1079	left = NO_FRINGE_BITMAP;
1080      else if (row->left_user_fringe_bitmap != NO_FRINGE_BITMAP)
1081	{
1082	  left = row->left_user_fringe_bitmap;
1083	  left_face_id = row->left_user_fringe_face_id;
1084	}
1085      else if (row->truncated_on_left_p)
1086	left = LEFT_FRINGE(0, Qtruncation, 0);
1087      else if (row->indicate_bob_p && EQ (boundary_top, Qleft))
1088	left = ((row->indicate_eob_p && EQ (boundary_bot, Qleft))
1089		? LEFT_FRINGE (1, Qtop_bottom, row->ends_at_zv_p)
1090		: LEFT_FRINGE (2, Qtop, 0));
1091      else if (row->indicate_eob_p && EQ (boundary_bot, Qleft))
1092	left = LEFT_FRINGE (3, Qbottom, row->ends_at_zv_p);
1093      else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
1094	left = LEFT_FRINGE (4, Qcontinuation, 0);
1095      else if (row->indicate_empty_line_p && EQ (empty_pos, Qleft))
1096	left = LEFT_FRINGE (5, Qempty_line, 0);
1097      else if (row->indicate_top_line_p && EQ (arrow_top, Qleft))
1098	left = LEFT_FRINGE (6, Qup, 0);
1099      else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qleft))
1100	left = LEFT_FRINGE (7, Qdown, 0);
1101      else
1102	left = NO_FRINGE_BITMAP;
1103
1104      /* Decide which bitmap to draw in the right fringe.  */
1105      if (WINDOW_RIGHT_FRINGE_WIDTH (w) == 0)
1106	right = NO_FRINGE_BITMAP;
1107      else if (row->right_user_fringe_bitmap != NO_FRINGE_BITMAP)
1108	{
1109	  right = row->right_user_fringe_bitmap;
1110	  right_face_id = row->right_user_fringe_face_id;
1111	}
1112      else if (row->truncated_on_right_p)
1113	right = RIGHT_FRINGE (0, Qtruncation, 0);
1114      else if (row->indicate_bob_p && EQ (boundary_top, Qright))
1115	right = ((row->indicate_eob_p && EQ (boundary_bot, Qright))
1116		 ? RIGHT_FRINGE (1, Qtop_bottom, row->ends_at_zv_p)
1117		 : RIGHT_FRINGE (2, Qtop, 0));
1118      else if (row->indicate_eob_p && EQ (boundary_bot, Qright))
1119	right = RIGHT_FRINGE (3, Qbottom, row->ends_at_zv_p);
1120      else if (row->continued_p)
1121	right = RIGHT_FRINGE (4, Qcontinuation, 0);
1122      else if (row->indicate_top_line_p && EQ (arrow_top, Qright))
1123	right = RIGHT_FRINGE (6, Qup, 0);
1124      else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qright))
1125	right = RIGHT_FRINGE (7, Qdown, 0);
1126      else if (row->indicate_empty_line_p && EQ (empty_pos, Qright))
1127	right = RIGHT_FRINGE (5, Qempty_line, 0);
1128      else
1129	right = NO_FRINGE_BITMAP;
1130
1131      if (row->y != cur->y
1132	  || row->visible_height != cur->visible_height
1133	  || row->ends_at_zv_p != cur->ends_at_zv_p
1134	  || left != cur->left_fringe_bitmap
1135	  || right != cur->right_fringe_bitmap
1136	  || left_face_id != cur->left_fringe_face_id
1137	  || right_face_id != cur->right_fringe_face_id
1138	  || cur->redraw_fringe_bitmaps_p)
1139	{
1140	  redraw_p = row->redraw_fringe_bitmaps_p = 1;
1141	  if (!keep_current_p)
1142	    {
1143	      cur->redraw_fringe_bitmaps_p = 1;
1144	      cur->left_fringe_bitmap = left;
1145	      cur->right_fringe_bitmap = right;
1146	      cur->left_fringe_face_id = left_face_id;
1147	      cur->right_fringe_face_id = right_face_id;
1148	    }
1149	}
1150
1151      if (row->overlay_arrow_bitmap < 0)
1152	row->overlay_arrow_bitmap = get_logical_fringe_bitmap (w, Qoverlay_arrow, 0, 0);
1153
1154      if (row->overlay_arrow_bitmap != cur->overlay_arrow_bitmap)
1155	{
1156	  redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1;
1157	  cur->overlay_arrow_bitmap = row->overlay_arrow_bitmap;
1158	}
1159
1160      row->left_fringe_bitmap = left;
1161      row->right_fringe_bitmap = right;
1162      row->left_fringe_face_id = left_face_id;
1163      row->right_fringe_face_id = right_face_id;
1164
1165      if (rn > 0 && row->redraw_fringe_bitmaps_p)
1166	row[-1].redraw_fringe_bitmaps_p = cur[-1].redraw_fringe_bitmaps_p = 1;
1167    }
1168
1169  return redraw_p && !keep_current_p;
1170}
1171
1172
1173/* Compute actual fringe widths for frame F.
1174
1175   If REDRAW is 1, redraw F if the fringe settings was actually
1176   modified and F is visible.
1177
1178   Since the combined left and right fringe must occupy an integral
1179   number of columns, we may need to add some pixels to each fringe.
1180   Typically, we add an equal amount (+/- 1 pixel) to each fringe,
1181   but a negative width value is taken literally (after negating it).
1182
1183   We never make the fringes narrower than specified.
1184*/
1185
1186void
1187compute_fringe_widths (f, redraw)
1188     struct frame *f;
1189     int redraw;
1190{
1191  int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
1192  int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
1193  int o_cols = FRAME_FRINGE_COLS (f);
1194
1195  Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
1196  Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
1197  int left_fringe_width, right_fringe_width;
1198
1199  if (!NILP (left_fringe))
1200    left_fringe = Fcdr (left_fringe);
1201  if (!NILP (right_fringe))
1202    right_fringe = Fcdr (right_fringe);
1203
1204  left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
1205		       XINT (left_fringe));
1206  right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
1207			XINT (right_fringe));
1208
1209  if (left_fringe_width || right_fringe_width)
1210    {
1211      int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
1212      int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
1213      int conf_wid = left_wid + right_wid;
1214      int font_wid = FRAME_COLUMN_WIDTH (f);
1215      int cols = (left_wid + right_wid + font_wid-1) / font_wid;
1216      int real_wid = cols * font_wid;
1217      if (left_wid && right_wid)
1218	{
1219	  if (left_fringe_width < 0)
1220	    {
1221	      /* Left fringe width is fixed, adjust right fringe if necessary */
1222	      FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
1223	      FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
1224	    }
1225	  else if (right_fringe_width < 0)
1226	    {
1227	      /* Right fringe width is fixed, adjust left fringe if necessary */
1228	      FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
1229	      FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
1230	    }
1231	  else
1232	    {
1233	      /* Adjust both fringes with an equal amount.
1234		 Note that we are doing integer arithmetic here, so don't
1235		 lose a pixel if the total width is an odd number.  */
1236	      int fill = real_wid - conf_wid;
1237	      FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
1238	      FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
1239	    }
1240	}
1241      else if (left_fringe_width)
1242	{
1243	  FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
1244	  FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
1245	}
1246      else
1247	{
1248	  FRAME_LEFT_FRINGE_WIDTH (f) = 0;
1249	  FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
1250	}
1251      FRAME_FRINGE_COLS (f) = cols;
1252    }
1253  else
1254    {
1255      FRAME_LEFT_FRINGE_WIDTH (f) = 0;
1256      FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
1257      FRAME_FRINGE_COLS (f) = 0;
1258    }
1259
1260  if (redraw && FRAME_VISIBLE_P (f))
1261    if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
1262	o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
1263	o_cols != FRAME_FRINGE_COLS (f))
1264      redraw_frame (f);
1265}
1266
1267
1268/* Free resources used by a user-defined bitmap.  */
1269
1270void
1271destroy_fringe_bitmap (n)
1272     int n;
1273{
1274  struct fringe_bitmap **fbp;
1275
1276  fringe_faces[n] = Qnil;
1277
1278  fbp = &fringe_bitmaps[n];
1279  if (*fbp && (*fbp)->dynamic)
1280    {
1281      if (rif && rif->destroy_fringe_bitmap)
1282	rif->destroy_fringe_bitmap (n);
1283      xfree (*fbp);
1284      *fbp = NULL;
1285    }
1286
1287  while (max_used_fringe_bitmap > MAX_STANDARD_FRINGE_BITMAPS
1288	 && fringe_bitmaps[max_used_fringe_bitmap - 1] == NULL)
1289    max_used_fringe_bitmap--;
1290}
1291
1292
1293DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap, Sdestroy_fringe_bitmap,
1294       1, 1, 0,
1295       doc: /* Destroy fringe bitmap BITMAP.
1296If BITMAP overrides a standard fringe bitmap, the original bitmap is restored.  */)
1297  (bitmap)
1298     Lisp_Object bitmap;
1299{
1300  int n;
1301
1302  CHECK_SYMBOL (bitmap);
1303  n = lookup_fringe_bitmap (bitmap);
1304  if (!n)
1305    return Qnil;
1306
1307  destroy_fringe_bitmap (n);
1308
1309  if (n >= MAX_STANDARD_FRINGE_BITMAPS)
1310    {
1311      Vfringe_bitmaps = Fdelq (bitmap, Vfringe_bitmaps);
1312      /* It would be better to remove the fringe property.  */
1313      Fput (bitmap, Qfringe, Qnil);
1314    }
1315
1316  return Qnil;
1317}
1318
1319
1320/* Initialize bitmap bit.
1321
1322   On X, we bit-swap the built-in bitmaps and reduce bitmap
1323   from short to char array if width is <= 8 bits.
1324
1325   On MAC with big-endian CPU, we need to byte-swap each short.
1326
1327   On W32 and MAC (little endian), there's no need to do this.
1328*/
1329
1330void
1331init_fringe_bitmap (which, fb, once_p)
1332     int which;
1333     struct fringe_bitmap *fb;
1334     int once_p;
1335{
1336  if (once_p || fb->dynamic)
1337    {
1338#if defined (HAVE_X_WINDOWS)
1339      static unsigned char swap_nibble[16]
1340	= { 0x0, 0x8, 0x4, 0xc,    /* 0000 1000 0100 1100 */
1341	    0x2, 0xa, 0x6, 0xe,    /* 0010 1010 0110 1110 */
1342	    0x1, 0x9, 0x5, 0xd,    /* 0001 1001 0101 1101 */
1343	    0x3, 0xb, 0x7, 0xf };  /* 0011 1011 0111 1111 */
1344      unsigned short *bits = fb->bits;
1345      int j;
1346
1347      if (fb->width <= 8)
1348	{
1349	  unsigned char *cbits = (unsigned char *)fb->bits;
1350	  for (j = 0; j < fb->height; j++)
1351	    {
1352	      unsigned short b = *bits++;
1353	      unsigned char c;
1354	      c = (unsigned char)((swap_nibble[b & 0xf] << 4)
1355				  | (swap_nibble[(b>>4) & 0xf]));
1356	      *cbits++ = (c >> (8 - fb->width));
1357	    }
1358	}
1359      else
1360	{
1361	  for (j = 0; j < fb->height; j++)
1362	    {
1363	      unsigned short b = *bits;
1364	      b = (unsigned short)((swap_nibble[b & 0xf] << 12)
1365				   | (swap_nibble[(b>>4) & 0xf] << 8)
1366				   | (swap_nibble[(b>>8) & 0xf] << 4)
1367				   | (swap_nibble[(b>>12) & 0xf]));
1368	      *bits++ = (b >> (16 - fb->width));
1369	    }
1370	}
1371#endif /* HAVE_X_WINDOWS */
1372
1373#if defined (MAC_OS) && defined (WORDS_BIG_ENDIAN)
1374      unsigned short *bits = fb->bits;
1375      int j;
1376      for (j = 0; j < fb->height; j++)
1377	{
1378	  unsigned short b = *bits;
1379	  *bits++ = ((b >> 8) & 0xff) | ((b & 0xff) << 8);
1380	}
1381#endif /* MAC_OS && WORDS_BIG_ENDIAN */
1382    }
1383
1384  if (!once_p)
1385    {
1386      destroy_fringe_bitmap (which);
1387
1388      if (rif && rif->define_fringe_bitmap)
1389	rif->define_fringe_bitmap (which, fb->bits, fb->height, fb->width);
1390
1391      fringe_bitmaps[which] = fb;
1392      if (which >= max_used_fringe_bitmap)
1393	max_used_fringe_bitmap = which + 1;
1394    }
1395}
1396
1397
1398DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap,
1399       2, 5, 0,
1400       doc: /* Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH.
1401BITMAP is a symbol identifying the new fringe bitmap.
1402BITS is either a string or a vector of integers.
1403HEIGHT is height of bitmap.  If HEIGHT is nil, use length of BITS.
1404WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
1405Optional fifth arg ALIGN may be one of `top', `center', or `bottom',
1406indicating the positioning of the bitmap relative to the rows where it
1407is used; the default is to center the bitmap.  Fourth arg may also be a
1408list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
1409should be repeated.
1410If BITMAP already exists, the existing definition is replaced.  */)
1411  (bitmap, bits, height, width, align)
1412     Lisp_Object bitmap, bits, height, width, align;
1413{
1414  int n, h, i, j;
1415  unsigned short *b;
1416  struct fringe_bitmap fb, *xfb;
1417  int fill1 = 0, fill2 = 0;
1418
1419  CHECK_SYMBOL (bitmap);
1420
1421  if (STRINGP (bits))
1422    h = SCHARS (bits);
1423  else if (VECTORP (bits))
1424    h = XVECTOR (bits)->size;
1425  else
1426    wrong_type_argument (Qsequencep, bits);
1427
1428  if (NILP (height))
1429    fb.height = h;
1430  else
1431    {
1432      CHECK_NUMBER (height);
1433      fb.height = min (XINT (height), 255);
1434      if (fb.height > h)
1435	{
1436	  fill1 = (fb.height - h) / 2;
1437	  fill2 = fb.height - h - fill1;
1438	}
1439    }
1440
1441  if (NILP (width))
1442    fb.width = 8;
1443  else
1444    {
1445      CHECK_NUMBER (width);
1446      fb.width = min (XINT (width), 255);
1447    }
1448
1449  fb.period = 0;
1450  fb.align = ALIGN_BITMAP_CENTER;
1451
1452  if (CONSP (align))
1453    {
1454      Lisp_Object period = XCDR (align);
1455      if (CONSP (period))
1456	{
1457	  period = XCAR (period);
1458	  if (!NILP (period))
1459	    {
1460	      fb.period = fb.height;
1461	      fb.height = 255;
1462	    }
1463	}
1464      align = XCAR (align);
1465    }
1466  if (EQ (align, Qtop))
1467    fb.align = ALIGN_BITMAP_TOP;
1468  else if (EQ (align, Qbottom))
1469    fb.align = ALIGN_BITMAP_BOTTOM;
1470  else if (!NILP (align) && !EQ (align, Qcenter))
1471    error ("Bad align argument");
1472
1473  n = lookup_fringe_bitmap (bitmap);
1474  if (!n)
1475    {
1476      if (max_used_fringe_bitmap < max_fringe_bitmaps)
1477	n = max_used_fringe_bitmap++;
1478      else
1479	{
1480	  for (n = MAX_STANDARD_FRINGE_BITMAPS;
1481	       n < max_fringe_bitmaps;
1482	       n++)
1483	    if (fringe_bitmaps[n] == NULL)
1484	      break;
1485
1486	  if (n == max_fringe_bitmaps)
1487	    {
1488	      if ((max_fringe_bitmaps + 20) > MAX_FRINGE_BITMAPS)
1489		error ("No free fringe bitmap slots");
1490
1491	      i = max_fringe_bitmaps;
1492	      max_fringe_bitmaps += 20;
1493	      fringe_bitmaps
1494		= ((struct fringe_bitmap **)
1495		   xrealloc (fringe_bitmaps, max_fringe_bitmaps * sizeof (struct fringe_bitmap *)));
1496	      fringe_faces
1497		= (Lisp_Object *) xrealloc (fringe_faces, max_fringe_bitmaps * sizeof (Lisp_Object));
1498
1499	      for (; i < max_fringe_bitmaps; i++)
1500		{
1501		  fringe_bitmaps[i] = NULL;
1502		  fringe_faces[i] = Qnil;
1503		}
1504	    }
1505	}
1506
1507      Vfringe_bitmaps = Fcons (bitmap, Vfringe_bitmaps);
1508      Fput (bitmap, Qfringe, make_number (n));
1509    }
1510
1511  fb.dynamic = 1;
1512
1513  xfb = (struct fringe_bitmap *) xmalloc (sizeof fb
1514					  + fb.height * BYTES_PER_BITMAP_ROW);
1515  fb.bits = b = (unsigned short *) (xfb + 1);
1516  bzero (b, fb.height);
1517
1518  j = 0;
1519  while (j < fb.height)
1520    {
1521      for (i = 0; i < fill1 && j < fb.height; i++)
1522	b[j++] = 0;
1523      for (i = 0; i < h && j < fb.height; i++)
1524	{
1525	  Lisp_Object elt = Faref (bits, make_number (i));
1526	  b[j++] = NUMBERP (elt) ? XINT (elt) : 0;
1527	}
1528      for (i = 0; i < fill2 && j < fb.height; i++)
1529	b[j++] = 0;
1530    }
1531
1532  *xfb = fb;
1533
1534  init_fringe_bitmap (n, xfb, 0);
1535
1536  return bitmap;
1537}
1538
1539DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face,
1540       1, 2, 0,
1541       doc: /* Set face for fringe bitmap BITMAP to FACE.
1542If FACE is nil, reset face to default fringe face.  */)
1543  (bitmap, face)
1544     Lisp_Object bitmap, face;
1545{
1546  int n;
1547  int face_id;
1548
1549  CHECK_SYMBOL (bitmap);
1550  n = lookup_fringe_bitmap (bitmap);
1551  if (!n)
1552    error ("Undefined fringe bitmap");
1553
1554  if (!NILP (face))
1555    {
1556      face_id = lookup_derived_face (SELECTED_FRAME (), face,
1557				     'A', FRINGE_FACE_ID, 1);
1558      if (face_id < 0)
1559	error ("No such face");
1560    }
1561
1562  fringe_faces[n] = face;
1563
1564  return Qnil;
1565}
1566
1567DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos, Sfringe_bitmaps_at_pos,
1568       0, 2, 0,
1569       doc: /* Return fringe bitmaps of row containing position POS in window WINDOW.
1570If WINDOW is nil, use selected window.  If POS is nil, use value of point
1571in that window.  Return value is a list (LEFT RIGHT OV), where LEFT
1572is the symbol for the bitmap in the left fringe (or nil if no bitmap),
1573RIGHT is similar for the right fringe, and OV is non-nil if there is an
1574overlay arrow in the left fringe.
1575Return nil if POS is not visible in WINDOW.  */)
1576  (pos, window)
1577     Lisp_Object pos, window;
1578{
1579  struct window *w;
1580  struct glyph_row *row;
1581  int textpos;
1582
1583  if (NILP (window))
1584    window = selected_window;
1585  CHECK_WINDOW (window);
1586  w = XWINDOW (window);
1587
1588  if (!NILP (pos))
1589    {
1590      CHECK_NUMBER_COERCE_MARKER (pos);
1591      textpos = XINT (pos);
1592    }
1593  else if (w == XWINDOW (selected_window))
1594    textpos = PT;
1595  else
1596    textpos = XMARKER (w->pointm)->charpos;
1597
1598  row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1599  row = row_containing_pos (w, textpos, row, NULL, 0);
1600  if (row)
1601    return list3 (get_fringe_bitmap_name (row->left_fringe_bitmap),
1602		  get_fringe_bitmap_name (row->right_fringe_bitmap),
1603		  (row->overlay_arrow_bitmap == 0 ? Qnil
1604		   : row->overlay_arrow_bitmap < 0 ? Qt
1605		   : get_fringe_bitmap_name (row->overlay_arrow_bitmap)));
1606  else
1607    return Qnil;
1608}
1609
1610
1611/***********************************************************************
1612			    Initialization
1613 ***********************************************************************/
1614
1615void
1616syms_of_fringe ()
1617{
1618  Qtruncation = intern ("truncation");
1619  staticpro (&Qtruncation);
1620  Qcontinuation = intern ("continuation");
1621  staticpro (&Qcontinuation);
1622  Qoverlay_arrow = intern ("overlay-arrow");
1623  staticpro (&Qoverlay_arrow);
1624  Qempty_line = intern ("empty-line");
1625  staticpro (&Qempty_line);
1626  Qtop_bottom = intern ("top-bottom");
1627  staticpro (&Qtop_bottom);
1628  Qhollow_small = intern ("hollow-small");
1629  staticpro (&Qhollow_small);
1630
1631  defsubr (&Sdestroy_fringe_bitmap);
1632  defsubr (&Sdefine_fringe_bitmap);
1633  defsubr (&Sfringe_bitmaps_at_pos);
1634  defsubr (&Sset_fringe_bitmap_face);
1635
1636  DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe,
1637    doc: /* *Non-nil means that newline may flow into the right fringe.
1638This means that display lines which are exactly as wide as the window
1639(not counting the final newline) will only occupy one screen line, by
1640showing (or hiding) the final newline in the right fringe; when point
1641is at the final newline, the cursor is shown in the right fringe.
1642If nil, also continue lines which are exactly as wide as the window.  */);
1643  Voverflow_newline_into_fringe = Qt;
1644
1645  DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps,
1646    doc: /* List of fringe bitmap symbols.  */);
1647  Vfringe_bitmaps = Qnil;
1648}
1649
1650/* Garbage collection hook */
1651
1652void
1653mark_fringe_data ()
1654{
1655  int i;
1656
1657  for (i = 0; i < max_fringe_bitmaps; i++)
1658    if (!NILP (fringe_faces[i]))
1659      mark_object (fringe_faces[i]);
1660}
1661
1662/* Initialize this module when Emacs starts.  */
1663
1664void
1665init_fringe_once ()
1666{
1667  int bt;
1668
1669  for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1670    init_fringe_bitmap(bt, &standard_bitmaps[bt], 1);
1671}
1672
1673void
1674init_fringe ()
1675{
1676  int i;
1677
1678  max_fringe_bitmaps = MAX_STANDARD_FRINGE_BITMAPS + 20;
1679
1680  fringe_bitmaps
1681    = (struct fringe_bitmap **) xmalloc (max_fringe_bitmaps * sizeof (struct fringe_bitmap *));
1682  fringe_faces
1683    = (Lisp_Object *) xmalloc (max_fringe_bitmaps * sizeof (Lisp_Object));
1684
1685  for (i = 0; i < max_fringe_bitmaps; i++)
1686    {
1687      fringe_bitmaps[i] = NULL;
1688      fringe_faces[i] = Qnil;
1689    }
1690}
1691
1692#if defined (HAVE_NTGUI) || defined (MAC_OS)
1693
1694void
1695#ifdef HAVE_NTGUI
1696w32_init_fringe ()
1697#else  /* MAC_OS */
1698mac_init_fringe ()
1699#endif
1700{
1701  int bt;
1702
1703  if (!rif)
1704    return;
1705
1706  for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1707    {
1708      struct fringe_bitmap *fb = &standard_bitmaps[bt];
1709      rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
1710    }
1711}
1712#endif
1713
1714#ifdef HAVE_NTGUI
1715void
1716w32_reset_fringes ()
1717{
1718  /* Destroy row bitmaps.  */
1719  int bt;
1720
1721  if (!rif)
1722    return;
1723
1724  for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++)
1725    rif->destroy_fringe_bitmap (bt);
1726}
1727
1728#endif /* HAVE_NTGUI */
1729
1730#endif /* HAVE_WINDOW_SYSTEM */
1731
1732/* arch-tag: 04596920-43eb-473d-b319-82712338162d
1733   (do not change this comment) */
1734