(coded-charset-entity-reference-alist): Add setting for
[chise/xemacs-chise.git.1] / src / window.c
index ef0cf7f..94be607 100644 (file)
@@ -50,6 +50,8 @@ Lisp_Object Qscrollbar_instances;
 #endif
 #endif
 
+extern int allow_deletion_of_last_visible_frame;
+
 EXFUN (Fnext_window, 4);
 
 static int window_pixel_width_to_char_width (struct window *w,
@@ -111,18 +113,20 @@ Lisp_Object Vtemp_buffer_show_function;
 Lisp_Object Vtemp_buffer_show_hook;
 
 /* If a window gets smaller than either of these, it is removed. */
-int window_min_height;
-int window_min_width;
+Fixnum window_min_height;
+Fixnum window_min_width;
 
 /* Hook run at end of temp_output_buffer_show.  */
 Lisp_Object Qtemp_buffer_show_hook;
 
 /* Number of lines of continuity in scrolling by screenfuls.  */
-int next_screen_context_lines;
+Fixnum next_screen_context_lines;
 
 /* List of freed window configurations with 1 - 10 windows. */
 static Lisp_Object Vwindow_configuration_free_list[10];
 
+Lisp_Object Qtruncate_partial_width_windows;
+
 #define SET_LAST_MODIFIED(w, cache_too)                \
 do {                                           \
   (w)->last_modified[CURRENT_DISP] = Qzero;    \
@@ -281,9 +285,8 @@ allocate_window (void)
   p->face_cachels     = Dynarr_new (face_cachel);
   p->glyph_cachels    = Dynarr_new (glyph_cachel);
   p->line_start_cache = Dynarr_new (line_start_cache);
-  p->subwindow_instance_cache = make_lisp_hash_table (30,
-                                                     HASH_TABLE_KEY_VALUE_WEAK,
-                                                     HASH_TABLE_EQ);
+  p->subwindow_instance_cache = make_image_instance_cache_hash_table ();
+
   p->line_cache_last_updated = Qzero;
   INIT_DISP_VARIABLE (last_point_x, 0);
   INIT_DISP_VARIABLE (last_point_y, 0);
@@ -489,7 +492,7 @@ real_window (struct window_mirror *mir, int no_abort)
   Lisp_Object retval = real_window_internal (mir->frame->root_window,
                                             mir->frame->root_mirror, mir);
   if (NILP (retval) && !no_abort)
-    abort ();
+    ABORT ();
 
   return retval;
 }
@@ -551,7 +554,7 @@ window_display_lines (struct window *w, int which)
     update_frame_window_mirror (XFRAME (w->frame));
   t = find_window_mirror (w);
   if (!t)
-    abort ();
+    ABORT ();
 
   if (which == CURRENT_DISP)
     return t->current_display_lines;
@@ -561,7 +564,7 @@ window_display_lines (struct window *w, int which)
     /* The CMOTION_DISP display lines are global. */
     return cmotion_display_lines;
   else
-    abort ();
+    ABORT ();
 
   return 0;    /* shut up compiler */
 }
@@ -575,7 +578,7 @@ window_display_buffer (struct window *w)
     update_frame_window_mirror (XFRAME (w->frame));
   t = find_window_mirror (w);
   if (!t)
-    abort ();
+    ABORT ();
 
   return t->buffer;
 }
@@ -589,7 +592,7 @@ set_window_display_buffer (struct window *w, struct buffer *b)
     update_frame_window_mirror (XFRAME (w->frame));
   t = find_window_mirror (w);
   if (!t)
-    abort ();
+    ABORT ();
 
   t->buffer = b;
 }
@@ -725,7 +728,8 @@ window_truncation_on (struct window *w)
 
   /* If truncate_partial_width_windows is true and the window is not
      the full width of the frame it is truncated. */
-  if (truncate_partial_width_windows
+  if (!NILP (symbol_value_in_buffer (Qtruncate_partial_width_windows,
+                                    w->buffer))
       && !(window_is_leftmost (w) && window_is_rightmost (w)))
     return 1;
 
@@ -919,7 +923,7 @@ window_modeline_height (struct window *w)
                modeline_height = (Dynarr_atp (dla, 0)->ascent +
                                   Dynarr_atp (dla, 0)->descent);
              else
-               /* This should be an abort except I'm not yet 100%
+               /* This should be an ABORT except I'm not yet 100%
                    confident that it won't ever get hit (though I
                    haven't been able to trigger it).  It is extremely
                    unlikely to cause any noticeable problem and even if
@@ -1805,7 +1809,7 @@ unshow_buffer (struct window *w)
   Lisp_Object buf = w->buffer;
 
   if (XBUFFER (buf) != XMARKER (w->pointm[CURRENT_DISP])->buffer)
-    abort ();
+    ABORT ();
 
   /* FSF disables this check, so I'll do it too.  I hope it won't
      break things.  --ben */
@@ -2107,9 +2111,13 @@ will automatically call `save-buffers-kill-emacs'.)
   else if (!NILP (w->vchild))
     delete_all_subwindows (XWINDOW (w->vchild));
 
+  /* Warning: mark_window_as_deleted calls window_unmap_subwindows and
+     therefore redisplay, so it requires the mirror structure to be
+     correct.  We must dirty the mirror before it is called.  */
+  f->mirror_dirty = 1;
+
   mark_window_as_deleted (w);
 
-  f->mirror_dirty = 1;
   return Qnil;
 }
 
@@ -2535,6 +2543,7 @@ enum window_loop
   GET_LRU_WINDOW,              /* Arg is t for full-width windows only */
   DELETE_OTHER_WINDOWS,                /* Arg is window not to delete */
   DELETE_BUFFER_WINDOWS,       /* Arg is buffer */
+  UNDEDICATE_BUFFER,            /* Arg is buffer */
   GET_LARGEST_WINDOW,
   GET_BUFFER_WINDOW_COUNT,     /* Arg is buffer */
   GET_BUFFER_MRU_WINDOW                /* Arg is buffer */
@@ -2614,7 +2623,7 @@ window_loop (enum window_loop type,
         We can't just wait until we hit the first window again,
         because it might be deleted.  */
 
-      last_window = Fprevious_window (w, mini ? Qt : Qnil, frame_arg, Qt);
+      last_window = Fprevious_window (w, mini ? Qt : Qnil, frame_arg, device);
 
       best_window = Qnil;
       for (;;)
@@ -2629,7 +2638,17 @@ window_loop (enum window_loop type,
          /* Given the outstanding quality of the rest of this code,
             I feel no shame about putting this piece of shit in. */
          if (++lose_lose >= 500)
-           return Qnil;
+           {
+             /* Call to ABORT() added by Darryl Okahata (16 Nov. 2001),
+                at Ben's request, to catch any remaining bugs.
+
+                If you find that XEmacs is ABORTing here, and you
+                need to be up and running ASAP, it should be safe to
+                comment out the following ABORT(), as long as you
+                leave the "break;" alone.  */
+             ABORT();
+             break;    /* <--- KEEP THIS HERE!  Do not delete!  */
+           }
 
          /* Note that we do not pay attention here to whether
             the frame is visible, since Fnext_window skips non-visible frames
@@ -2687,6 +2706,13 @@ window_loop (enum window_loop type,
                  break;
                }
 
+              case UNDEDICATE_BUFFER:
+                {
+                  if ((XBUFFER (p->buffer) == XBUFFER (obj)))
+                    p->dedicated = Qnil;
+                  break;
+                }
+
              case DELETE_OTHER_WINDOWS:
                {
                  /* Don't delete the last window on a frame; this can
@@ -2707,7 +2733,8 @@ window_loop (enum window_loop type,
                         of its own, kill the frame.  */
                      if (EQ (w, FRAME_ROOT_WINDOW (f))
                          && !NILP (p->dedicated)
-                         && other_visible_frames (f))
+                         && (allow_deletion_of_last_visible_frame
+                             || other_visible_frames (f)))
                        {
                          /* Skip the other windows on this frame.
                             There might be one, the minibuffer!  */
@@ -2770,7 +2797,7 @@ window_loop (enum window_loop type,
                }
 
              default:
-               abort ();
+               ABORT ();
              }
 
          if (EQ (w, last_window))
@@ -2813,6 +2840,12 @@ buffer_window_mru (struct window *w)
 
 #endif
 
+void
+undedicate_windows (Lisp_Object buffer, Lisp_Object frame)
+{
+    window_loop (UNDEDICATE_BUFFER, buffer, 0, frame, 1, Qnil);
+}
+
 \f
 DEFUN ("get-lru-window", Fget_lru_window, 0, 2, 0, /*
 Return the window least recently selected or used for display.
@@ -2862,7 +2895,7 @@ Any other non-nil value means search all devices.
   w = window_loop (GET_LRU_WINDOW, Qnil, 0, which_frames, 1, which_devices);
 
   /* At this point we damn well better have found something. */
-  if (NILP (w)) abort ();
+  if (NILP (w)) ABORT ();
 #endif
 
   return w;
@@ -3155,7 +3188,8 @@ Any other non-nil value means search all devices.
          if (!NILP (XWINDOW (window)->dedicated)
              && EQ (window,
                     FRAME_ROOT_WINDOW (XFRAME (frame)))
-             && other_visible_frames (XFRAME (frame)))
+             && (allow_deletion_of_last_visible_frame
+                 || other_visible_frames (XFRAME (frame))))
            {
              delete_frame_internal (XFRAME (frame), 0, 0, 0); /* GC */
            }
@@ -3604,9 +3638,7 @@ make_dummy_parent (Lisp_Object window)
   p->face_cachels     = Dynarr_new (face_cachel);
   p->glyph_cachels    = Dynarr_new (glyph_cachel);
   p->subwindow_instance_cache =
-    make_lisp_hash_table (30,
-                         HASH_TABLE_KEY_VALUE_WEAK,
-                         HASH_TABLE_EQ);
+    make_image_instance_cache_hash_table ();
 
   /* Put new into window structure in place of window */
   replace_window (window, new);
@@ -3630,8 +3662,9 @@ make_dummy_parent (Lisp_Object window)
 DEFUN ("split-window", Fsplit_window, 0, 3, "", /*
 Split WINDOW, putting SIZE lines in the first of the pair.
 WINDOW defaults to the selected one and SIZE to half its size.
-If optional third arg HORFLAG is non-nil, split side by side
-and put SIZE columns in the first of the pair.
+If optional third arg HORFLAG is non-nil, split side by side and put
+SIZE columns in the first of the pair. The newly created window is
+returned.
 */
        (window, size, horflag))
 {
@@ -3655,7 +3688,7 @@ and put SIZE columns in the first of the pair.
        /* In the new scheme, we are symmetric with respect to separators
           so there is no need to do weird things here. */
        {
-         psize = WINDOW_WIDTH (o) >> 1;
+         psize = (WINDOW_WIDTH (o) + window_divider_width (o)) >> 1;
          csize = window_pixel_width_to_char_width (o, psize, 0);
         }
       else
@@ -3767,7 +3800,7 @@ and put SIZE columns in the first of the pair.
   XFRAME (p->frame)->mirror_dirty = 1;
   /* do this last (after the window is completely initialized and
      the mirror-dirty flag is set) so that specifier recomputation
-     caused as a result of this will work properly and not abort. */
+     caused as a result of this will work properly and not ABORT. */
   Fset_window_buffer (new, o->buffer, Qt);
   return new;
 }
@@ -4334,7 +4367,7 @@ window_scroll (Lisp_Object window, Lisp_Object count, int direction,
          &&
          Dynarr_length (dla) >= (1 + modeline)
          &&
-         (dl->ascent - dl->top_clip) - fheight * value > 0)
+         (dl->ascent - dl->top_clip) > fheight * value)
        {
          WINDOW_TEXT_TOP_CLIP (w) += value * fheight;
          MARK_WINDOWS_CHANGED (w);
@@ -4516,6 +4549,11 @@ When calling from a program, supply an integer as argument or nil.
 On attempt to scroll past end of buffer, `end-of-buffer' is signaled.
 On attempt to scroll past beginning of buffer, `beginning-of-buffer' is
 signaled.
+
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details.
 */
        (count))
 {
@@ -4531,6 +4569,11 @@ When calling from a program, supply a number as argument or nil.
 On attempt to scroll past end of buffer, `end-of-buffer' is signaled.
 On attempt to scroll past beginning of buffer, `beginning-of-buffer' is
 signaled.
+
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details.
 */
        (count))
 {
@@ -4603,6 +4646,11 @@ showing that buffer, popping the buffer up if necessary.
 DEFUN ("scroll-left", Fscroll_left, 0, 1, "_P", /*
 Scroll selected window display COUNT columns left.
 Default for COUNT is window width minus 2.
+
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details.
 */
        (count))
 {
@@ -4618,6 +4666,11 @@ Default for COUNT is window width minus 2.
 DEFUN ("scroll-right", Fscroll_right, 0, 1, "_P", /*
 Scroll selected window display COUNT columns right.
 Default for COUNT is window width minus 2.
+
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details.
 */
        (count))
 {
@@ -5009,7 +5062,7 @@ struct window_config
   /* Record the values of window-min-width and window-min-height
      so that window sizes remain consistent with them.  */
   int min_width, min_height;
-  int saved_windows_count;
+  unsigned int saved_windows_count;
   /* Zero-sized arrays aren't ANSI C */
   struct saved_window saved_windows[1];
 };
@@ -5024,7 +5077,7 @@ static Lisp_Object
 mark_window_config (Lisp_Object obj)
 {
   struct window_config *config = XWINDOW_CONFIGURATION (obj);
-  int i;
+  unsigned int i;
   mark_object (config->current_window);
   mark_object (config->current_buffer);
   mark_object (config->minibuffer_scroll_window);
@@ -5053,12 +5106,11 @@ mark_window_config (Lisp_Object obj)
   return Qnil;
 }
 
-static size_t
-sizeof_window_config_for_n_windows (int n)
+inline static size_t
+sizeof_window_config_for_n_windows (unsigned int n)
 {
-  return (sizeof (struct window_config) +
-         /* n - 1 because zero-sized arrays aren't ANSI C */
-         (n - 1) *sizeof (struct saved_window));
+  return FLEXIBLE_ARRAY_STRUCT_SIZEOF (struct window_config,
+                                      struct saved_window, saved_windows, n);
 }
 
 static size_t
@@ -5123,7 +5175,7 @@ static int
 window_config_equal (Lisp_Object conf1, Lisp_Object conf2)
 {
   struct window_config *fig1, *fig2;
-  int i;
+  unsigned int i;
 
   /* First check if they are truly the same. */
   if (EQ (conf1, conf2))
@@ -5178,7 +5230,7 @@ mark_windows_in_use (struct frame *f, int mark)
 static Lisp_Object
 free_window_configuration (Lisp_Object window_config)
 {
-  int i;
+  unsigned int i;
   struct window_config *config = XWINDOW_CONFIGURATION (window_config);
 
   /* Free all the markers.  It's not completely necessary that
@@ -5230,7 +5282,7 @@ by `current-window-configuration' (which see).
   struct window_config *config;
   struct saved_window *p;
   Lisp_Object new_current_buffer;
-  int k;
+  unsigned int k;
   Lisp_Object frame;
   struct frame *f;
   struct gcpro gcpro1;
@@ -5478,9 +5530,8 @@ by `current-window-configuration' (which see).
             set. */
          if (NILP (w->subwindow_instance_cache))
            w->subwindow_instance_cache =
-             make_lisp_hash_table (30,
-                                   HASH_TABLE_KEY_VALUE_WEAK,
-                                   HASH_TABLE_EQ);
+             make_image_instance_cache_hash_table ();
+
          SET_LAST_MODIFIED (w, 1);
          SET_LAST_FACECHANGE (w);
          w->config_mark = 0;
@@ -5679,7 +5730,7 @@ by `current-window-configuration' (which see).
   if (FRAME_LIVE_P (f))
     {
       /* Do this before calling recompute_all_cached_specifiers_in_window()
-        so that things like redisplay_redraw_cursor() won't abort due
+        so that things like redisplay_redraw_cursor() won't ABORT due
         to no window mirror present. */
       f->mirror_dirty = 1;
 
@@ -5729,7 +5780,7 @@ delete_all_subwindows (struct window *w)
 }
 
 \f
-static int
+static unsigned int
 count_windows (struct window *window)
 {
   return 1 +
@@ -5747,7 +5798,7 @@ saved_window_index (Lisp_Object window, struct window_config *config, int lim)
       if (EQ (SAVED_WINDOW_N (config, j)->window, window))
        return j;
     }
-  abort ();
+  ABORT ();
   return 0;    /* suppress compiler warning */
 }
 
@@ -5844,7 +5895,7 @@ its value is -not- saved.
   Lisp_Object result;
   struct frame *f = decode_frame (frame);
   struct window_config *config;
-  int n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
+  unsigned int n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
   int minibuf_height;
   int real_font_height;
 
@@ -5861,14 +5912,20 @@ its value is -not- saved.
   /*
   config->frame_width = FRAME_WIDTH (f);
   config->frame_height = FRAME_HEIGHT (f); */
-  /* When using `push-window-configuration', often the minibuffer ends
+  /* #### When using `push-window-configuration', often the minibuffer ends
      up as the selected window because functions run as the result of
      user interaction e.g. hyper-apropos. It seems to me the sensible
-     thing to do is not record the minibuffer here. */
+     thing to do is not record the minibuffer here. 
+
+     #### Unfortunately this is a change to previous behaviour, however logical
+     it may be, so revert for the moment. */
+#if 0
   if (FRAME_MINIBUF_ONLY_P (f) || minibuf_level)
     config->current_window = FRAME_SELECTED_WINDOW (f);
   else
     config->current_window = FRAME_LAST_NONMINIBUF_WINDOW (f);
+#endif
+  config->current_window = FRAME_SELECTED_WINDOW (f);
   XSETBUFFER (config->current_buffer, current_buffer);
   config->minibuffer_scroll_window = Vminibuffer_scroll_window;
   config->root_window = FRAME_ROOT_WINDOW (f);
@@ -6062,6 +6119,8 @@ syms_of_window (void)
   /* Qother in general.c */
 #endif
 
+  DEFSYMBOL (Qtruncate_partial_width_windows);
+  
   DEFSUBR (Fselected_window);
   DEFSUBR (Flast_nonminibuf_window);
   DEFSUBR (Fminibuffer_window);
@@ -6150,7 +6209,7 @@ syms_of_window (void)
 void
 reinit_vars_of_window (void)
 {
-  int i;
+  unsigned int i;
   /* Make sure all windows get marked */
   minibuf_window = Qnil;
   staticpro_nodump (&minibuf_window);
@@ -6310,6 +6369,9 @@ This is a specifier; use `set-specifier' to change it.
 #ifdef HAVE_TTY
     fb = Fcons (Fcons (list1 (Qtty), make_int (1)), fb);
 #endif
+#ifdef HAVE_GTK
+    fb = Fcons (Fcons (list1 (Qgtk), make_int (3)), fb);
+#endif
 #ifdef HAVE_X_WINDOWS
     fb = Fcons (Fcons (list1 (Qx), make_int (3)), fb);
 #endif
@@ -6344,6 +6406,9 @@ This is a specifier; use `set-specifier' to change it.
        Should not the same value be the fallback under X? - kkm */
     fb = Fcons (Fcons (list1 (Qx), make_int (2)), fb);
 #endif
+#ifdef HAVE_GTK
+    fb = Fcons (Fcons (list1 (Qgtk), Qzero), fb);
+#endif
 #ifdef HAVE_MS_WINDOWS
     fb = Fcons (Fcons (list1 (Qmswindows), Qzero), fb);
 #endif