(Finternal_face_x_get_resource): Do it on Windows and Mac too.
[bpt/emacs.git] / src / buffer.c
index 95876c1..bb6b9fe 100644 (file)
@@ -1,5 +1,5 @@
 /* Buffer manipulation primitives for GNU Emacs.
-   Copyright (C) 1985,86,87,88,89,93,94,95,97,98, 1999, 2000, 2001, 2002
+   Copyright (C) 1985,86,87,88,89,93,94,95,97,98, 1999, 2000, 2001, 02, 2003
        Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -150,6 +150,7 @@ Lisp_Object Vinhibit_read_only;
 /* List of functions to call that can query about killing a buffer.
    If any of these functions returns nil, we don't kill it.  */
 Lisp_Object Vkill_buffer_query_functions;
+Lisp_Object Qkill_buffer_query_functions;
 
 /* List of functions to call before changing an unmodified buffer.  */
 Lisp_Object Vfirst_change_hook;
@@ -419,10 +420,11 @@ The value is never nil.  */)
   XSETBUFFER (buf, b);
   Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil));
 
-  /* Fixme:  Protect against errors, which would trigger infinite
-     regress?  */
+  /* An error in calling the function here (should someone redfine it)
+     can lead to infinite regress until you run out of stack.  rms
+     says that's not worth protecting against.  */
   if (!NILP (Ffboundp (Qucs_set_table_for_input)))
-    /* buff is on buffer-alist, so no gcpro */
+    /* buf is on buffer-alist, so no gcpro.  */
     call1 (Qucs_set_table_for_input, buf);
 
   return buf;
@@ -464,13 +466,13 @@ copy_overlays (b, list)
       OVERLAY_START (overlay) = start;
       OVERLAY_END (overlay) = end;
       OVERLAY_PLIST (overlay) = Fcopy_sequence (OVERLAY_PLIST (old_overlay));
-      
+
       result = Fcons (overlay, result);
     }
 
   return Fnreverse (result);
 }
-     
+
 
 /* Clone per-buffer values of buffer FROM.
 
@@ -487,7 +489,7 @@ clone_per_buffer_values (from, to)
   int offset;
 
   XSETBUFFER (to_buffer, to);
-  
+
   for (offset = PER_BUFFER_VAR_OFFSET (name) + sizeof (Lisp_Object);
        offset < sizeof *to;
        offset += sizeof (Lisp_Object))
@@ -507,7 +509,7 @@ clone_per_buffer_values (from, to)
     }
 
   bcopy (from->local_flags, to->local_flags, sizeof to->local_flags);
-  
+
   to->overlays_before = copy_overlays (to, from->overlays_before);
   to->overlays_after = copy_overlays (to, from->overlays_after);
 }
@@ -683,7 +685,6 @@ reset_buffer_local_variables (b, permanent_too)
      We ignore it here.  */
   b->major_mode = Qfundamental_mode;
   b->keymap = Qnil;
-  b->abbrev_table = Vfundamental_mode_abbrev_table;
   b->mode_name = QSFundamental;
   b->minor_modes = Qnil;
 
@@ -816,7 +817,7 @@ If BUFFER is not indirect, return nil.  */)
 }
 
 DEFUN ("buffer-local-value", Fbuffer_local_value,
-       Sbuffer_local_value, 2, 2, 0, 
+       Sbuffer_local_value, 2, 2, 0,
        doc: /* Return the value of VARIABLE in BUFFER.
 If VARIABLE does not have a buffer-local binding in BUFFER, the value
 is the default binding of variable. */)
@@ -833,7 +834,7 @@ is the default binding of variable. */)
 
   /* Look in local_var_list */
   result = Fassoc (symbol, buf->local_var_alist);
-  if (NILP (result)) 
+  if (NILP (result))
     {
       int offset, idx;
       int found = 0;
@@ -846,8 +847,8 @@ is the default binding of variable. */)
        {
          idx = PER_BUFFER_IDX (offset);
          if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx))
-             && SYMBOLP (PER_BUFFER_SYMBOL (offset)) 
-             && EQ (PER_BUFFER_SYMBOL (offset), symbol)) 
+             && SYMBOLP (PER_BUFFER_SYMBOL (offset))
+             && EQ (PER_BUFFER_SYMBOL (offset), symbol))
            {
              result = PER_BUFFER_VALUE (buf, offset);
              found = 1;
@@ -1005,7 +1006,7 @@ A non-nil FLAG means mark the buffer modified.  */)
 #endif /* CLASH_DETECTION */
 
   SAVE_MODIFF = NILP (flag) ? MODIFF : 0;
-  
+
   /* Set update_mode_lines only if buffer is displayed in some window.
      Packages like jit-lock or lazy-lock preserve a buffer's modified
      state by recording/restoring the state around blocks of code.
@@ -1024,7 +1025,7 @@ A non-nil FLAG means mark the buffer modified.  */)
       ++update_mode_lines;
       current_buffer->prevent_redisplay_optimizations_p = 1;
     }
-  
+
   return flag;
 }
 
@@ -1038,7 +1039,7 @@ state of the current buffer.  Use with care.  */)
 {
 #ifdef CLASH_DETECTION
   Lisp_Object fn;
-  
+
   /* If buffer becoming modified, lock the file.
      If buffer becoming unmodified, unlock the file.  */
 
@@ -1053,7 +1054,7 @@ state of the current buffer.  Use with care.  */)
        unlock_file (fn);
     }
 #endif /* CLASH_DETECTION */
-  
+
   SAVE_MODIFF = NILP (flag) ? MODIFF : 0;
   return flag;
 }
@@ -1152,7 +1153,7 @@ If BUFFER is omitted or nil, some interesting buffer is returned.  */)
 
   /* Consider buffers that have been seen in the selected frame
      before other buffers.  */
-    
+
   tem = frame_buffer_list (frame);
   add_ons = Qnil;
   while (CONSP (tem))
@@ -1293,8 +1294,8 @@ with SIGHUP.  */)
       && BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
     {
       GCPRO1 (buf);
-      tem = do_yes_or_no_p (format1 ("Buffer %s modified; kill anyway? ",
-                                    SDATA (b->name)));
+      tem = do_yes_or_no_p (format2 ("Buffer %s modified; kill anyway? ",
+                                    b->name, make_number (0)));
       UNGCPRO;
       if (NILP (tem))
        return Qnil;
@@ -1303,19 +1304,16 @@ with SIGHUP.  */)
   /* Run hooks with the buffer to be killed the current buffer.  */
   {
     int count = SPECPDL_INDEX ();
-    Lisp_Object list;
+    Lisp_Object arglist[1];
 
     record_unwind_protect (save_excursion_restore, save_excursion_save ());
     set_buffer_internal (b);
 
     /* First run the query functions; if any query is answered no,
        don't kill the buffer.  */
-    for (list = Vkill_buffer_query_functions; CONSP (list); list = XCDR (list))
-      {
-       tem = call0 (XCAR (list));
-       if (NILP (tem))
-         return unbind_to (count, Qnil);
-      }
+    arglist[0] = Qkill_buffer_query_functions;
+    if (NILP (Frun_hook_with_args_until_failure (1, arglist)))
+      return unbind_to (count, Qnil);
 
     /* Then run the hooks.  */
     Frun_hooks (1, &Qkill_buffer_hook);
@@ -1354,7 +1352,7 @@ with SIGHUP.  */)
 
       UNGCPRO;
     }
-  
+
   /* Make this buffer not be current.
      In the process, notice if this is the sole visible buffer
      and give up if so.  */
@@ -1495,7 +1493,7 @@ record_buffer (buf)
     Vbuffer_alist = XCDR (Vbuffer_alist);
   else
     XSETCDR (prev, XCDR (XCDR (prev)));
-       
+
   XSETCDR (link, Vbuffer_alist);
   Vbuffer_alist = link;
 
@@ -1519,7 +1517,7 @@ record_buffer (buf)
                               XCDR (frame_buffer_list (frame)));
       else
        XSETCDR (prev, XCDR (XCDR (prev)));
-       
+
       XSETCDR (link, frame_buffer_list (frame));
       set_frame_buffer_list (frame, link);
     }
@@ -1549,7 +1547,7 @@ the current buffer's major mode.  */)
          && NILP (Fget (current_buffer->major_mode, Qmode_class)))
        function = current_buffer->major_mode;
     }
-  
+
   if (NILP (function) || EQ (function, Qfundamental_mode))
     return Qnil;
 
@@ -1609,7 +1607,7 @@ switch_to_buffer_1 (buffer, norecord)
   Fset_window_buffer (EQ (selected_window, minibuf_window)
                      ? Fnext_window (minibuf_window, Qnil, Qnil)
                      : selected_window,
-                     buf);
+                     buf, Qnil);
 
   return buf;
 }
@@ -1662,9 +1660,9 @@ do not put this buffer at the front of the list of recently selected ones.  */)
     }
   Fset_buffer (buf);
   if (NILP (norecord))
-    /* This seems bogus since Fselect_window will call record_buffer anyway.  */
+    /* Why bother ?  Fselect_window will do it for us anyway.  -stef  */
     record_buffer (buf);
-  Fselect_window (Fdisplay_buffer (buf, other_window, Qnil));
+  Fselect_window (Fdisplay_buffer (buf, other_window, Qnil), norecord);
   return buf;
 }
 
@@ -1709,7 +1707,7 @@ set_buffer_internal_1 (b)
   if (b->text->beg == NULL)
     enlarge_buffer_text (b, 0);
 #endif /* USE_MMAP_FOR_BUFFERS */
-  
+
   if (current_buffer == b)
     return;
 
@@ -1937,7 +1935,7 @@ selected window if it is displayed there.  */)
   else
     {
       Lisp_Object buf1;
-      
+
       buf1 = Fget_buffer (buffer);
       if (NILP (buf1))
        nsberror (buffer);
@@ -2051,8 +2049,8 @@ but the contents viewed as characters do change.  */)
   Lisp_Object tail, markers;
   struct buffer *other;
   int undo_enabled_p = !EQ (current_buffer->undo_list, Qt);
-  int begv = BEGV, zv = ZV;
-  int narrowed = (BEG != begv || Z != zv);
+  int begv, zv;
+  int narrowed = (BEG != BEGV || Z != ZV);
   int modified_p = !NILP (Fbuffer_modified_p (Qnil));
 
   if (current_buffer->base_buffer)
@@ -2070,6 +2068,11 @@ but the contents viewed as characters do change.  */)
   /* If the cached position is for this buffer, clear it out.  */
   clear_charpos_cache (current_buffer);
 
+  if (NILP (flag))
+    begv = BEGV_BYTE, zv = ZV_BYTE;
+  else
+    begv = BEGV, zv = ZV;
+
   if (narrowed)
     Fwiden ();
 
@@ -2175,7 +2178,7 @@ but the contents viewed as characters do change.  */)
              p = GAP_END_ADDR;
              stop = Z;
            }
-             
+
          if (UNIBYTE_STR_AS_MULTIBYTE_P (p, stop - pos, bytes))
            p += bytes, pos += bytes;
          else
@@ -2288,6 +2291,17 @@ but the contents viewed as characters do change.  */)
   if (!modified_p && !NILP (Fbuffer_modified_p (Qnil)))
     Fset_buffer_modified_p (Qnil);
 
+#ifdef subprocesses
+  /* Update coding systems of this buffer's process (if any).  */
+  {
+    Lisp_Object process;
+
+    process = Fget_buffer_process (Fcurrent_buffer ());
+    if (PROCESSP (process))
+      setup_process_coding_systems (process);
+  }
+#endif /* subprocesses */
+
   return flag;
 }
 \f
@@ -2328,7 +2342,7 @@ the normal hook `change-major-mode-hook'.  */)
 
   /* Any which are supposed to be permanent,
      make local again, with the same values they had.  */
-     
+
   for (alist = oalist; !NILP (alist); alist = XCDR (alist))
     {
       sym = XCAR (XCAR (alist));
@@ -2390,7 +2404,7 @@ swap_out_buffer_local_variables (b)
 }
 \f
 /* Find all the overlays in the current buffer that contain position POS.
-   Return the number found, and store them in a vector in *VEC_PTR.  
+   Return the number found, and store them in a vector in *VEC_PTR.
    Store in *LEN_PTR the size allocated for the vector.
    Store in *NEXT_PTR the next position after POS where an overlay starts,
      or ZV if there are no more overlays.
@@ -2542,7 +2556,7 @@ overlays_at (pos, extend, vec_ptr, len_ptr, next_ptr, prev_ptr, change_req)
 /* Find all the overlays in the current buffer that overlap the range BEG-END
    or are empty at BEG.
 
-   Return the number found, and store them in a vector in *VEC_PTR.  
+   Return the number found, and store them in a vector in *VEC_PTR.
    Store in *LEN_PTR the size allocated for the vector.
    Store in *NEXT_PTR the next position after POS where an overlay starts,
      or ZV if there are no more overlays.
@@ -2558,7 +2572,7 @@ overlays_at (pos, extend, vec_ptr, len_ptr, next_ptr, prev_ptr, change_req)
    and we store only as many overlays as will fit.
    But we still return the total number of overlays.  */
 
-int
+static int
 overlays_in (beg, end, extend, vec_ptr, len_ptr, next_ptr, prev_ptr)
      int beg, end;
      int extend;
@@ -2691,7 +2705,7 @@ mouse_face_overlay_overlaps (overlay)
   int end = OVERLAY_POSITION (OVERLAY_END (overlay));
   int n, i, size;
   Lisp_Object *v, tem;
-  
+
   size = 10;
   v = (Lisp_Object *) alloca (size * sizeof *v);
   n = overlays_in (start, end, 0, &v, &size, NULL, NULL);
@@ -3545,7 +3559,7 @@ rear delimiter advance when text is inserted there.  */)
   XOVERLAY (overlay)->end = end;
   XOVERLAY (overlay)->plist = Qnil;
 
-  /* Put the new overlay on the wrong list.  */ 
+  /* Put the new overlay on the wrong list.  */
   end = OVERLAY_END (overlay);
   if (OVERLAY_POSITION (end) < XINT (b->overlay_center))
     b->overlays_after = Fcons (overlay, b->overlays_after);
@@ -3576,7 +3590,7 @@ modify_overlay (buf, start, end)
     }
 
   BUF_COMPUTE_UNCHANGED (buf, start, end);
-  
+
   /* If this is a buffer not in the selected window,
      we must do other windows.  */
   if (buf != XBUFFER (XWINDOW (selected_window)->buffer))
@@ -3682,7 +3696,7 @@ buffer.  */)
   Fset_marker (OVERLAY_START (overlay), beg, buffer);
   Fset_marker (OVERLAY_END   (overlay), end, buffer);
 
-  /* Put the overlay on the wrong list.  */ 
+  /* Put the overlay on the wrong list.  */
   end = OVERLAY_END (overlay);
   if (OVERLAY_POSITION (end) < XINT (b->overlay_center))
     b->overlays_after = Fcons (overlay, b->overlays_after);
@@ -3712,7 +3726,7 @@ DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
 
   b = XBUFFER (buffer);
   specbind (Qinhibit_quit, Qt);
-  
+
   b->overlays_before = Fdelq (overlay, b->overlays_before);
   b->overlays_after = Fdelq (overlay, b->overlays_after);
   modify_overlay (b,
@@ -3934,7 +3948,9 @@ However, the overlays you get are the real objects that the buffer uses.  */)
 }
 
 DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
-       doc: /* Recenter the overlays of the current buffer around position POS.  */)
+       doc: /* Recenter the overlays of the current buffer around position POS.
+That makes overlay lookup faster for positions near POS (but perhaps slower
+for positions far away from POS).  */)
      (pos)
      Lisp_Object pos;
 {
@@ -4276,21 +4292,21 @@ buffer_slot_type_mismatch (offset)
 {
   Lisp_Object sym;
   char *type_name;
-  
+
   switch (XINT (PER_BUFFER_TYPE (offset)))
     {
     case Lisp_Int:
       type_name = "integers";
       break;
-      
+
     case Lisp_String:
       type_name = "strings";
       break;
-      
+
     case Lisp_Symbol:
       type_name = "symbols";
       break;
-      
+
     default:
       abort ();
     }
@@ -4353,7 +4369,7 @@ struct mmap_region
 {
   /* User-specified size.  */
   size_t nbytes_specified;
-  
+
   /* Number of bytes mapped */
   size_t nbytes_mapped;
 
@@ -4444,7 +4460,7 @@ mmap_find (start, end)
 {
   struct mmap_region *r;
   char *s = (char *) start, *e = (char *) end;
-  
+
   for (r = mmap_regions; r; r = r->next)
     {
       char *rstart = (char *) r;
@@ -4478,7 +4494,7 @@ mmap_free_1 (r)
     r->prev->next = r->next;
   else
     mmap_regions = r->next;
-  
+
   if (munmap ((POINTER_TYPE *) r, r->nbytes_mapped) == -1)
     {
       fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
@@ -4516,7 +4532,7 @@ mmap_enlarge (r, npages)
   else if (npages > 0)
     {
       nbytes = npages * mmap_page_size;
-      
+
       /* Try to map additional pages at the end of the region.  We
         cannot do this if the address range is already occupied by
         something else because mmap deletes any previous mapping.
@@ -4524,7 +4540,7 @@ mmap_enlarge (r, npages)
       if (!MMAP_ALLOCATED_P (region_end, region_end + nbytes))
        {
          POINTER_TYPE *p;
-      
+
          p = mmap (region_end, nbytes, PROT_READ | PROT_WRITE,
                    MAP_ANON | MAP_PRIVATE | MAP_FIXED, mmap_fd, 0);
          if (p == MAP_FAILED)
@@ -4605,7 +4621,7 @@ mmap_alloc (var, nbytes)
   map = ROUND (nbytes + MMAP_REGION_STRUCT_SIZE, mmap_page_size);
   p = mmap (NULL, map, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
            mmap_fd, 0);
-  
+
   if (p == MAP_FAILED)
     {
       if (errno != ENOMEM)
@@ -4615,7 +4631,7 @@ mmap_alloc (var, nbytes)
   else
     {
       struct mmap_region *r = (struct mmap_region *) p;
-      
+
       r->nbytes_specified = nbytes;
       r->nbytes_mapped = map;
       r->var = var;
@@ -4624,10 +4640,10 @@ mmap_alloc (var, nbytes)
       if (r->next)
        r->next->prev = r;
       mmap_regions = r;
-      
+
       p = MMAP_USER_AREA (p);
     }
-  
+
   return *var = p;
 }
 
@@ -4643,12 +4659,12 @@ mmap_realloc (var, nbytes)
      size_t nbytes;
 {
   POINTER_TYPE *result;
-  
+
   mmap_init ();
 
   if (*var == NULL)
     result = mmap_alloc (var, nbytes);
-  else if (nbytes == 0) 
+  else if (nbytes == 0)
     {
       mmap_free (var);
       result = mmap_alloc (var, nbytes);
@@ -4657,7 +4673,7 @@ mmap_realloc (var, nbytes)
     {
       struct mmap_region *r = MMAP_REGION (*var);
       size_t room = r->nbytes_mapped - MMAP_REGION_STRUCT_SIZE;
-      
+
       if (room < nbytes)
        {
          /* Must enlarge.  */
@@ -4718,7 +4734,7 @@ mmap_free (var)
      POINTER_TYPE **var;
 {
   mmap_init ();
-  
+
   if (*var)
     {
       mmap_free_1 (MMAP_REGION (*var));
@@ -4747,11 +4763,11 @@ mmap_init ()
   if (mmap_initialized_p)
     return;
   mmap_initialized_p = 1;
-  
+
 #if MAP_ANON != 0
   mmap_fd = -1;
 #endif
-  
+
   mmap_page_size = getpagesize ();
 }
 
@@ -4778,7 +4794,7 @@ alloc_buffer_text (b, nbytes)
      size_t nbytes;
 {
   POINTER_TYPE *p;
-  
+
   BLOCK_INPUT;
 #if defined USE_MMAP_FOR_BUFFERS
   p = mmap_alloc ((POINTER_TYPE **) &b->text->beg, nbytes);
@@ -4787,7 +4803,7 @@ alloc_buffer_text (b, nbytes)
 #else
   p = xmalloc (nbytes);
 #endif
-  
+
   if (p == NULL)
     {
       UNBLOCK_INPUT;
@@ -4817,7 +4833,7 @@ enlarge_buffer_text (b, delta)
 #else
   p = xrealloc (b->text->beg, nbytes);
 #endif
-  
+
   if (p == NULL)
     {
       UNBLOCK_INPUT;
@@ -4844,7 +4860,7 @@ free_buffer_text (b)
 #else
   xfree (b->text->beg);
 #endif
-  
+
   BUF_BEG_ADDR (b) = NULL;
   UNBLOCK_INPUT;
 }
@@ -4916,6 +4932,13 @@ init_buffer_once ()
   buffer_defaults.cache_long_line_scans = Qnil;
   buffer_defaults.file_truename = Qnil;
   XSETFASTINT (buffer_defaults.display_count, 0);
+  XSETFASTINT (buffer_defaults.left_margin_cols, 0);
+  XSETFASTINT (buffer_defaults.right_margin_cols, 0);
+  buffer_defaults.left_fringe_width = Qnil;
+  buffer_defaults.right_fringe_width = Qnil;
+  buffer_defaults.fringes_outside_margins = Qnil;
+  buffer_defaults.scroll_bar_width = Qnil;
+  buffer_defaults.vertical_scroll_bar_type = Qt;
   buffer_defaults.indicate_empty_lines = Qnil;
   buffer_defaults.scroll_up_aggressively = Qnil;
   buffer_defaults.scroll_down_aggressively = Qnil;
@@ -4975,11 +4998,16 @@ init_buffer_once ()
   XSETFASTINT (buffer_local_flags.cache_long_line_scans, idx); ++idx;
   XSETFASTINT (buffer_local_flags.category_table, idx); ++idx;
   XSETFASTINT (buffer_local_flags.direction_reversed, idx); ++idx;
-  XSETFASTINT (buffer_local_flags.buffer_file_coding_system, idx); 
+  XSETFASTINT (buffer_local_flags.buffer_file_coding_system, idx);
   /* Make this one a permanent local.  */
   buffer_permanent_local_flags[idx++] = 1;
-  XSETFASTINT (buffer_local_flags.left_margin_width, idx); ++idx;
-  XSETFASTINT (buffer_local_flags.right_margin_width, idx); ++idx;
+  XSETFASTINT (buffer_local_flags.left_margin_cols, idx); ++idx;
+  XSETFASTINT (buffer_local_flags.right_margin_cols, idx); ++idx;
+  XSETFASTINT (buffer_local_flags.left_fringe_width, idx); ++idx;
+  XSETFASTINT (buffer_local_flags.right_fringe_width, idx); ++idx;
+  XSETFASTINT (buffer_local_flags.fringes_outside_margins, idx); ++idx;
+  XSETFASTINT (buffer_local_flags.scroll_bar_width, idx); ++idx;
+  XSETFASTINT (buffer_local_flags.vertical_scroll_bar_type, idx); ++idx;
   XSETFASTINT (buffer_local_flags.indicate_empty_lines, idx); ++idx;
   XSETFASTINT (buffer_local_flags.scroll_up_aggressively, idx); ++idx;
   XSETFASTINT (buffer_local_flags.scroll_down_aggressively, idx); ++idx;
@@ -4991,7 +5019,7 @@ init_buffer_once ()
   if (idx >= MAX_PER_BUFFER_VARS)
     abort ();
   last_per_buffer_idx = idx;
-  
+
   Vbuffer_alist = Qnil;
   current_buffer = 0;
   all_buffers = 0;
@@ -5008,6 +5036,7 @@ init_buffer_once ()
   Qpermanent_local = intern ("permanent-local");
 
   Qkill_buffer_hook = intern ("kill-buffer-hook");
+  Fput (Qkill_buffer_hook, Qpermanent_local, Qt);
 
   Qucs_set_table_for_input = intern ("ucs-set-table-for-input");
 
@@ -5036,13 +5065,13 @@ init_buffer ()
       text pointers will have been set to null in the dumped Emacs.
       Map new memory.  */
    struct buffer *b;
-   
+
    for (b = all_buffers; b; b = b->next)
      if (b->text->beg == NULL)
        enlarge_buffer_text (b, 0);
  }
 #endif /* USE_MMAP_FOR_BUFFERS */
-  
+
   Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
   if (NILP (buffer_defaults.enable_multibyte_characters))
     Fset_buffer_multibyte (Qnil);
@@ -5140,6 +5169,9 @@ syms_of_buffer ()
   staticpro (&Qafter_change_functions);
   staticpro (&Qucs_set_table_for_input);
 
+  Qkill_buffer_query_functions = intern ("kill-buffer-query-functions");
+  staticpro (&Qkill_buffer_query_functions);
+
   Fput (Qprotected_field, Qerror_conditions,
        Fcons (Qprotected_field, Fcons (Qerror, Qnil)));
   Fput (Qprotected_field, Qerror_message,
@@ -5179,19 +5211,19 @@ This is the same as (default-value 'ctl-arrow).  */);
 
    DEFVAR_LISP_NOPRO ("default-direction-reversed",
                      &buffer_defaults.direction_reversed,
-                     doc: /* Default value of `direction_reversed' for buffers that do not override it.
+                     doc: /* Default value of `direction-reversed' for buffers that do not override it.
 This is the same as (default-value 'direction-reversed).  */);
+
    DEFVAR_LISP_NOPRO ("default-enable-multibyte-characters",
                      &buffer_defaults.enable_multibyte_characters,
                      doc: /* *Default value of `enable-multibyte-characters' for buffers not overriding it.
 This is the same as (default-value 'enable-multibyte-characters).  */);
+
    DEFVAR_LISP_NOPRO ("default-buffer-file-coding-system",
                      &buffer_defaults.buffer_file_coding_system,
                      doc: /* Default value of `buffer-file-coding-system' for buffers not overriding it.
 This is the same as (default-value 'buffer-file-coding-system).  */);
+
   DEFVAR_LISP_NOPRO ("default-truncate-lines",
                     &buffer_defaults.truncate_lines,
                     doc: /* Default value of `truncate-lines' for buffers that do not override it.
@@ -5218,7 +5250,7 @@ This is the same as (default-value 'tab-width).  */);
 This is the same as (default-value 'case-fold-search).  */);
 
 #ifdef DOS_NT
-  DEFVAR_LISP_NOPRO ("default-buffer-file-type", 
+  DEFVAR_LISP_NOPRO ("default-buffer-file-type",
                     &buffer_defaults.buffer_file_type,
                     doc: /* Default file type for buffers that do not override it.
 This is the same as (default-value 'buffer-file-type).
@@ -5226,39 +5258,64 @@ The file type is nil for text, t for binary.  */);
 #endif
 
   DEFVAR_LISP_NOPRO ("default-left-margin-width",
-                    &buffer_defaults.left_margin_width,
+                    &buffer_defaults.left_margin_cols,
                     doc: /* Default value of `left-margin-width' for buffers that don't override it.
 This is the same as (default-value 'left-margin-width).  */);
 
   DEFVAR_LISP_NOPRO ("default-right-margin-width",
-                    &buffer_defaults.right_margin_width,
-                    doc: /* Default value of `right_margin_width' for buffers that don't override it.
+                    &buffer_defaults.right_margin_cols,
+                    doc: /* Default value of `right-margin-width' for buffers that don't override it.
 This is the same as (default-value 'right-margin-width).  */);
-  
+
+  DEFVAR_LISP_NOPRO ("default-left-fringe-width",
+                    &buffer_defaults.left_fringe_width,
+                    doc: /* Default value of `left-fringe-width' for buffers that don't override it.
+This is the same as (default-value 'left-fringe-width).  */);
+
+  DEFVAR_LISP_NOPRO ("default-right-fringe-width",
+                    &buffer_defaults.right_fringe_width,
+                    doc: /* Default value of `right-fringe-width' for buffers that don't override it.
+This is the same as (default-value 'right-fringe-width).  */);
+
+  DEFVAR_LISP_NOPRO ("default-fringes-outside-margins",
+                    &buffer_defaults.fringes_outside_margins,
+                    doc: /* Default value of `fringes-outside-margins' for buffers that don't override it.
+This is the same as (default-value 'fringes-outside-margins).  */);
+
+  DEFVAR_LISP_NOPRO ("default-scroll-bar-width",
+                    &buffer_defaults.scroll_bar_width,
+                    doc: /* Default value of `scroll-bar-width' for buffers that don't override it.
+This is the same as (default-value 'scroll-bar-width).  */);
+
+  DEFVAR_LISP_NOPRO ("default-vertical-scroll-bar",
+                    &buffer_defaults.vertical_scroll_bar_type,
+                    doc: /* Default value of `vertical-scroll-bar' for buffers that don't override it.
+This is the same as (default-value 'vertical-scroll-bar).  */);
+
   DEFVAR_LISP_NOPRO ("default-indicate-empty-lines",
                     &buffer_defaults.indicate_empty_lines,
                     doc: /* Default value of `indicate-empty-lines' for buffers that don't override it.
 This is the same as (default-value 'indicate-empty-lines).  */);
-  
+
   DEFVAR_LISP_NOPRO ("default-scroll-up-aggressively",
                     &buffer_defaults.scroll_up_aggressively,
                     doc: /* Default value of `scroll-up-aggressively'.
 This value applies in buffers that don't have their own local values.
 This variable is an alias for (default-value 'scroll-up-aggressively).  */);
-  
+
   DEFVAR_LISP_NOPRO ("default-scroll-down-aggressively",
                     &buffer_defaults.scroll_down_aggressively,
                     doc: /* Default value of `scroll-down-aggressively'.
 This value applies in buffers that don't have their own local values.
 This variable is an alias for (default-value 'scroll-down-aggressively).  */);
-  
+
   DEFVAR_PER_BUFFER ("header-line-format",
                     &current_buffer->header_line_format,
                     Qnil,
                     doc: /* Analogous to `mode-line-format', but controls the header line.
 The header line appears, optionally, at the top of a window;
 the mode line appears at the bottom.  */);
-  
+
   DEFVAR_PER_BUFFER ("mode-line-format", &current_buffer->mode_line_format,
                     Qnil,
                     doc: /* Template for displaying mode line for current buffer.
@@ -5269,7 +5326,7 @@ For a symbol, its value is used (but it is ignored if t or nil).
  A string appearing directly as the value of a symbol is processed verbatim
  in that the %-constructs below are not recognized.
  Note that unless the symbol is marked as a `risky-local-variable', all
- properties in any strings, as well as all :eval and :propertize forms 
+ properties in any strings, as well as all :eval and :propertize forms
  in the value of that symbol will be ignored.
 For a list of the form `(:eval FORM)', FORM is evaluated and the result
  is used as a mode line element.  Be careful--FORM should not load any files,
@@ -5349,7 +5406,7 @@ in the current display table (if there is one).  */);
 
   DEFVAR_PER_BUFFER ("enable-multibyte-characters",
                     &current_buffer->enable_multibyte_characters,
-                    make_number (-1),
+                    Qnil,
                     doc: /* Non-nil means the buffer contents are regarded as multi-byte characters.
 Otherwise they are regarded as unibyte.  This affects the display,
 file I/O and the behavior of various editing commands.
@@ -5359,6 +5416,7 @@ use the function `set-buffer-multibyte' to change a buffer's representation.
 Changing its default value with `setq-default' is supported.
 See also variable `default-enable-multibyte-characters' and Info node
 `(elisp)Text Representations'.  */);
+  XSYMBOL (intern ("enable-multibyte-characters"))->constant = 1;
 
   DEFVAR_PER_BUFFER ("buffer-file-coding-system",
                     &current_buffer->buffer_file_coding_system, Qnil,
@@ -5502,22 +5560,51 @@ In addition, a char-table has six extra slots to control the display of:
 
 See also the functions `display-table-slot' and `set-display-table-slot'.  */);
 
-  DEFVAR_PER_BUFFER ("left-margin-width", &current_buffer->left_margin_width,
+  DEFVAR_PER_BUFFER ("left-margin-width", &current_buffer->left_margin_cols,
                     Qnil,
                     doc: /* *Width of left marginal area for display of a buffer.
 A value of nil means no marginal area.  */);
-  
-  DEFVAR_PER_BUFFER ("right-margin-width", &current_buffer->right_margin_width,
+
+  DEFVAR_PER_BUFFER ("right-margin-width", &current_buffer->right_margin_cols,
                     Qnil,
                     doc: /* *Width of right marginal area for display of a buffer.
 A value of nil means no marginal area.  */);
-  
+
+  DEFVAR_PER_BUFFER ("left-fringe-width", &current_buffer->left_fringe_width,
+                    Qnil,
+                    doc: /* *Width of this buffer's left fringe (in pixels).
+A value of 0 means no left fringe is shown in this buffer's window.
+A value of nil means to use the left fringe width from the window's frame.  */);
+
+  DEFVAR_PER_BUFFER ("right-fringe-width", &current_buffer->right_fringe_width,
+                    Qnil,
+                    doc: /* *Width of this buffer's right fringe (in pixels).
+A value of 0 means no right fringe is shown in this buffer's window.
+A value of nil means to use the right fringe width from the window's frame.  */);
+
+  DEFVAR_PER_BUFFER ("fringes-outside-margins", &current_buffer->fringes_outside_margins,
+                    Qnil,
+                    doc: /* *Non-nil means to display fringes outside display margins.
+A value of nil means to display fringes between margins and buffer text.  */);
+
+  DEFVAR_PER_BUFFER ("scroll-bar-width", &current_buffer->scroll_bar_width,
+                    Qnil,
+                    doc: /* *Width of this buffer's scroll bars in pixels.
+A value of nil means to use the scroll bar width from the window's frame.  */);
+
+  DEFVAR_PER_BUFFER ("vertical-scroll-bar", &current_buffer->vertical_scroll_bar_type,
+                    Qnil,
+                    doc: /* *Position of this buffer's vertical scroll bar.
+A value of left or right means to place the vertical scroll bar at that side
+of the window; a value of nil means that this window has no vertical scroll bar.
+A value of t means to use the vertical scroll bar type from the window's frame.  */);
+
   DEFVAR_PER_BUFFER ("indicate-empty-lines",
                     &current_buffer->indicate_empty_lines, Qnil,
                     doc: /* *Visually indicate empty lines after the buffer end.
 If non-nil, a bitmap is displayed in the left fringe of a window on
 window-systems.  */);
-  
+
   DEFVAR_PER_BUFFER ("scroll-up-aggressively",
                     &current_buffer->scroll_up_aggressively, Qnil,
                     doc: /* How far to scroll windows upward.
@@ -5530,7 +5617,7 @@ case that you moved off with C-f means scrolling just one line.  1.0 means
 point goes at the top, so that in that simple case, the window
 window scrolls by a full window height.  Meaningful values are
 between 0.0 and 1.0, inclusive.  */);
-  
+
   DEFVAR_PER_BUFFER ("scroll-down-aggressively",
                     &current_buffer->scroll_down_aggressively, Qnil,
                     doc: /* How far to scroll windows downward.
@@ -5543,7 +5630,7 @@ case that you moved off with C-b means scrolling just one line.  1.0 means
 point goes at the bottom, so that in that simple case, the window
 window scrolls by a full window height.  Meaningful values are
 between 0.0 and 1.0, inclusive.  */);
-  
+
 /*DEFVAR_LISP ("debug-check-symbol", &Vcheck_symbol,
     "Don't ask.");
 */
@@ -5663,7 +5750,7 @@ functions; it should only affect their performance.  */);
   DEFVAR_PER_BUFFER ("buffer-file-format", &current_buffer->file_format, Qnil,
                     doc: /* List of formats to use when saving this buffer.
 Formats are defined by `format-alist'.  This variable is
-set when a file is visited.  Automatically local in all buffers.  */);
+set when a file is visited.  */);
 
   DEFVAR_PER_BUFFER ("buffer-invisibility-spec",
                     &current_buffer->invisibility_spec, Qnil,