Simplify and avoid signal-handling races.
[bpt/emacs.git] / src / fringe.c
index 727547b..d788503 100644 (file)
@@ -1,5 +1,5 @@
 /* Fringe handling (split from xdisp.c).
-   Copyright (C) 1985-1988, 1993-1995, 1997-2011  Free Software Foundation, Inc.
+   Copyright (C) 1985-1988, 1993-1995, 1997-2012  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -18,12 +18,12 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <stdio.h>
-#include <setjmp.h>
 
 #include "lisp.h"
 #include "frame.h"
 #include "window.h"
 #include "dispextern.h"
+#include "character.h"
 #include "buffer.h"
 #include "blockinput.h"
 #include "termhooks.h"
@@ -35,7 +35,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    Logical bitmaps are used internally to denote things like
    'end-of-buffer', 'left-truncation', 'overlay-arrow', etc.
 
-   Physical bitmaps specify the visual appearence of the bitmap,
+   Physical bitmaps specify the visual appearance of the bitmap,
    e.g. 'bottom-left-angle', 'left-arrow', 'left-triangle', etc.
    User defined bitmaps are physical bitmaps.
 
@@ -106,6 +106,22 @@ struct fringe_bitmap
 static unsigned short question_mark_bits[] = {
   0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
 
+/* An exclamation mark.  */
+/*
+  ...XX...
+  ...XX...
+  ...XX...
+  ...XX...
+  ...XX...
+  ...XX...
+  ...XX...
+  ........
+  ...XX...
+  ...XX...
+*/
+static unsigned short exclamation_mark_bits[] = {
+  0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18};
+
 /* An arrow like this: `<-'.  */
 /*
   ...xx...
@@ -431,6 +447,7 @@ static struct fringe_bitmap standard_bitmaps[] =
 {
   { NULL, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */
   { FRBITS (question_mark_bits),      8, 0, ALIGN_BITMAP_CENTER, 0 },
+  { FRBITS (exclamation_mark_bits),   8, 0, ALIGN_BITMAP_CENTER, 0 },
   { FRBITS (left_arrow_bits),         8, 0, ALIGN_BITMAP_CENTER, 0 },
   { FRBITS (right_arrow_bits),        8, 0, ALIGN_BITMAP_CENTER, 0 },
   { FRBITS (up_arrow_bits),           8, 0, ALIGN_BITMAP_TOP,    0 },
@@ -641,7 +658,14 @@ draw_fringe_bitmap_1 (struct window *w, struct glyph_row *row, int left_p, int o
        {
          /* If W has a vertical border to its left, don't draw over it.  */
          wd -= ((!WINDOW_LEFTMOST_P (w)
-                 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
+                 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
+                 /* But don't reduce the fringe width if the window
+                    has a left margin, because that means we are not
+                    in danger of drawing over the vertical border,
+                    and OTOH leaving out that one pixel leaves behind
+                    traces of the cursor, if it was in column zero
+                    before drawing non-empty margin area.  */
+                 && NILP (w->left_margin_cols))
                 ? 1 : 0);
          p.bx = x - wd;
          p.nx = wd;
@@ -848,7 +872,7 @@ draw_fringe_bitmap (struct window *w, struct glyph_row *row, int left_p)
 void
 draw_row_fringe_bitmaps (struct window *w, struct glyph_row *row)
 {
-  xassert (interrupt_input_blocked);
+  eassert (input_blocked_p ());
 
   /* If row is completely invisible, because of vscrolling, we
      don't have to draw anything.  */
@@ -928,7 +952,7 @@ update_window_fringes (struct window *w, int keep_current_p)
   int top_ind_rn, bot_ind_rn;
   int top_ind_min_y, bot_ind_max_y;
 
-  /* top_ind_rn is set to a nonnegative value whenver
+  /* top_ind_rn is set to a nonnegative value whenever
      row->indicate_bob_p is set, so it's OK that top_row_ends_at_zv_p
      is not initialized here.  Similarly for bot_ind_rn,
      row->indicate_eob_p and bot_row_ends_at_zv_p.  */
@@ -1615,12 +1639,10 @@ If BITMAP already exists, the existing definition is replaced.  */)
                error ("No free fringe bitmap slots");
 
              i = max_fringe_bitmaps;
-             fringe_bitmaps
-               = ((struct fringe_bitmap **)
-                  xrealloc (fringe_bitmaps, bitmaps * sizeof *fringe_bitmaps));
-             fringe_faces
-               = (Lisp_Object *) xrealloc (fringe_faces,
-                                           bitmaps * sizeof *fringe_faces);
+             fringe_bitmaps = xrealloc (fringe_bitmaps,
+                                        bitmaps * sizeof *fringe_bitmaps);
+             fringe_faces = xrealloc (fringe_faces,
+                                      bitmaps * sizeof *fringe_faces);
 
              for (i = max_fringe_bitmaps; i < bitmaps; i++)
                {
@@ -1638,8 +1660,7 @@ If BITMAP already exists, the existing definition is replaced.  */)
 
   fb.dynamic = 1;
 
-  xfb = (struct fringe_bitmap *) xmalloc (sizeof fb
-                                         + fb.height * BYTES_PER_BITMAP_ROW);
+  xfb = xmalloc (sizeof fb + fb.height * BYTES_PER_BITMAP_ROW);
   fb.bits = b = (unsigned short *) (xfb + 1);
   memset (b, 0, fb.height);
 
@@ -1671,23 +1692,27 @@ If FACE is nil, reset face to default fringe face.  */)
   (Lisp_Object bitmap, Lisp_Object face)
 {
   int n;
-  int face_id;
 
   CHECK_SYMBOL (bitmap);
   n = lookup_fringe_bitmap (bitmap);
   if (!n)
     error ("Undefined fringe bitmap");
 
+  /* The purpose of the following code is to signal an error if FACE
+     is not a face.  This is for the caller's convenience only; the
+     redisplay code should be able to fail gracefully.  Skip the check
+     if FRINGE_FACE_ID is unrealized (as in batch mode and during
+     daemon startup).  */
   if (!NILP (face))
     {
-      face_id = lookup_derived_face (SELECTED_FRAME (), face,
-                                    FRINGE_FACE_ID, 1);
-      if (face_id < 0)
+      struct frame *f = SELECTED_FRAME ();
+
+      if (FACE_FROM_ID (f, FRINGE_FACE_ID)
+         && lookup_derived_face (f, face, FRINGE_FACE_ID, 1) < 0)
        error ("No such face");
     }
 
   fringe_faces[n] = face;
-
   return Qnil;
 }
 
@@ -1756,7 +1781,7 @@ syms_of_fringe (void)
   defsubr (&Sset_fringe_bitmap_face);
 
   DEFVAR_LISP ("overflow-newline-into-fringe", Voverflow_newline_into_fringe,
-    doc: /* *Non-nil means that newline may flow into the right fringe.
+    doc: /* Non-nil means that newline may flow into the right fringe.
 This means that display lines which are exactly as wide as the window
 (not counting the final newline) will only occupy one screen line, by
 showing (or hiding) the final newline in the right fringe; when point
@@ -1799,16 +1824,11 @@ init_fringe (void)
 
   max_fringe_bitmaps = MAX_STANDARD_FRINGE_BITMAPS + 20;
 
-  fringe_bitmaps
-    = (struct fringe_bitmap **) xmalloc (max_fringe_bitmaps * sizeof (struct fringe_bitmap *));
-  fringe_faces
-    = (Lisp_Object *) xmalloc (max_fringe_bitmaps * sizeof (Lisp_Object));
+  fringe_bitmaps = xzalloc (max_fringe_bitmaps * sizeof *fringe_bitmaps);
+  fringe_faces = xmalloc (max_fringe_bitmaps * sizeof *fringe_faces);
 
   for (i = 0; i < max_fringe_bitmaps; i++)
-    {
-      fringe_bitmaps[i] = NULL;
-      fringe_faces[i] = Qnil;
-    }
+    fringe_faces[i] = Qnil;
 }
 
 #ifdef HAVE_NTGUI