comparison src/window.c @ 1149:a123f88fa975

[xemacs-hg @ 2002-12-08 10:24:33 by michaels] 2002-12-02 Mike Sperber <mike@xemacs.org> * The Great Window Configuration rewrite: Re-implement window configuration functionality in Emacs Lisp. * window.h (Fcurrent_window_configuration): Don't export anymore. (Qcurrent_window_configuration): Declare. (Qset_window_configuration): Declare. * event-stream.c (execute_help_form): * bytecode.c (execute_rare_opcode): Call out to Lisp to save window excursion. * window.c (Qcurrent_window_configuration): Declare. (Qwindow_configurationp): (Vwindow_configuration_free_list): (Qset_window_configuration): (Qtemp_buffer_show_hook): (struct saved_window): (struct window_config): (SAVED_WINDOW_N): (XWINDOW_CONFIGURATION): (wrap_window_configuration): (WINDOW_CONFIGURATIONP): (CHECK_WINDOW_CONFIGURATION): (mark_window_config): (sizeof_window_config_for_n_windows): (sizeof_window_config): (print_window_config): (saved_window_equal): (window_config_equal): (Fwindow_configuration_p): (mark_windows_in_use_closure): (mark_windows_in_use): (free_window_configuration): (Fset_window_configuration): (count_windows): (saved_window_index): (save_window_save): (Fcurrent_window_configuration): (Fsave_window_excursion): Remove. (mark_window_as_deleted): Rectify comment about `set-window-configuration'. (Fset_window_buffer): Reinstate code not activated because of old implementation of window configurations. (temp_output_buffer_show): Don't run `temp-buffer-show-hook' anymore---this wasn't supposed to happen anyway according to the documentation of `temp-buffer-show-function'. (reinit_vars_of_window): Don't do the window configuration stuff no more (vars_of_window): Don't set up `temp-buffer-show-hook' any more. 2002-12-02 Mike Sperber <mike@xemacs.org> * The Great Window Configuration rewrite: Re-implement window configuration functionality in Emacs Lisp. * window-xemacs.el (current-window-configuration): (set-window-configuration): (plus many functions they depend on) Re-implement window configurations in Emacs Lisp.
author michaels
date Sun, 08 Dec 2002 10:25:14 +0000
parents e6409999af4b
children 8e95979f01c6
comparison
equal deleted inserted replaced
1148:1649f1fb3177 1149:a123f88fa975
49 #include "gutter.h" 49 #include "gutter.h"
50 #include "objects.h" 50 #include "objects.h"
51 #include "redisplay.h" 51 #include "redisplay.h"
52 #include "window-impl.h" 52 #include "window-impl.h"
53 53
54 Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configurationp; 54 Lisp_Object Qwindowp, Qwindow_live_p;
55 Lisp_Object Qdisplay_buffer; 55 Lisp_Object Qdisplay_buffer;
56 56
57 #ifdef MEMORY_USAGE_STATS 57 #ifdef MEMORY_USAGE_STATS
58 Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qother_redisplay; 58 Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qother_redisplay;
59 #ifdef HAVE_SCROLLBARS 59 #ifdef HAVE_SCROLLBARS
117 Lisp_Object Vother_window_scroll_buffer; 117 Lisp_Object Vother_window_scroll_buffer;
118 118
119 /* Non-nil means it's the function to call to display temp buffers. */ 119 /* Non-nil means it's the function to call to display temp buffers. */
120 Lisp_Object Vtemp_buffer_show_function; 120 Lisp_Object Vtemp_buffer_show_function;
121 121
122 Lisp_Object Vtemp_buffer_show_hook;
123
124 /* If a window gets smaller than either of these, it is removed. */ 122 /* If a window gets smaller than either of these, it is removed. */
125 Fixnum window_min_height; 123 Fixnum window_min_height;
126 Fixnum window_min_width; 124 Fixnum window_min_width;
127 125
128 /* Hook run at end of temp_output_buffer_show. */
129 Lisp_Object Qtemp_buffer_show_hook;
130
131 /* Number of lines of continuity in scrolling by screenfuls. */ 126 /* Number of lines of continuity in scrolling by screenfuls. */
132 Fixnum next_screen_context_lines; 127 Fixnum next_screen_context_lines;
133 128
134 /* List of freed window configurations with 1 - 10 windows. */ 129 Lisp_Object Qcurrent_window_configuration, Qset_window_configuration;
135 static Lisp_Object Vwindow_configuration_free_list[10];
136 130
137 Lisp_Object Qtruncate_partial_width_windows; 131 Lisp_Object Qtruncate_partial_width_windows;
138 132
139 #define SET_LAST_MODIFIED(w, cache_too) \ 133 #define SET_LAST_MODIFIED(w, cache_too) \
140 do { \ 134 do { \
2027 /* Free the extra data structures attached to windows immediately so 2021 /* Free the extra data structures attached to windows immediately so
2028 they don't sit around consuming excess space. They will be 2022 they don't sit around consuming excess space. They will be
2029 reinitialized by the window-configuration code as necessary. */ 2023 reinitialized by the window-configuration code as necessary. */
2030 finalize_window ((void *) w, 0); 2024 finalize_window ((void *) w, 0);
2031 2025
2032 /* "Nobody should be accessing anything in this object any more...", 2026 /* Nobody should be accessing anything in this object any more,
2033 I said, but unfortunately that's not quite true.
2034 set-window-configuration undeletes the window and relies on
2035 certain items to be there already. Fuckme! we really should
2036 rewrite it in Lisp and just recreate the windows. (But does any
2037 code depend on the pointers being the same? At the very least,
2038 we should reinit everything in the window.)
2039
2040 Nobody should be accessing anything in this object any more,
2041 and making them Qnil allows for better GC'ing in case a pointer 2027 and making them Qnil allows for better GC'ing in case a pointer
2042 to the dead window continues to hang around. Zero all other 2028 to the dead window continues to hang around. Zero all other
2043 structs in case someone tries to access something through them. 2029 structs in case someone tries to access something through them.
2044 2030
2045 (So, in point of fact, we zero out all of the "saved" slots, 2031 (So, in point of fact, we zero out all of the "saved" slots,
2053 (while t (split-window) (delete-window)) 2039 (while t (split-window) (delete-window))
2054 we end up with a tree of deleted windows which are all connected 2040 we end up with a tree of deleted windows which are all connected
2055 through the `next' slot. This might not seem so bad, as they're 2041 through the `next' slot. This might not seem so bad, as they're
2056 deleted, and will presumably be GCed - but if even *one* of those 2042 deleted, and will presumably be GCed - but if even *one* of those
2057 windows is still being pointed to, by the user, or by a window 2043 windows is still being pointed to, by the user, or by a window
2058 configuration, then *all* of those windows stick around. 2044 configuration, then *all* of those windows stick around. */
2059
2060 Since the window-configuration code doesn't need any of the
2061 pointers to other windows (they are all recreated from the
2062 window-config data), we set them all to nil so that we
2063 are able to collect more actual garbage. */
2064 2045
2065 #define WINDOW_SLOT(slot) 2046 #define WINDOW_SLOT(slot)
2066 #define WINDOW_SAVED_SLOT(slot, compare) w->slot = Qnil; 2047 #define WINDOW_SAVED_SLOT(slot, compare) w->slot = Qnil;
2067 #include "winslots.h" 2048 #include "winslots.h"
2068 2049
2193 unchain_marker (w->pointm[CMOTION_DISP]); 2174 unchain_marker (w->pointm[CMOTION_DISP]);
2194 unchain_marker (w->start[CURRENT_DISP]); 2175 unchain_marker (w->start[CURRENT_DISP]);
2195 unchain_marker (w->start[DESIRED_DISP]); 2176 unchain_marker (w->start[DESIRED_DISP]);
2196 unchain_marker (w->start[CMOTION_DISP]); 2177 unchain_marker (w->start[CMOTION_DISP]);
2197 unchain_marker (w->sb_point); 2178 unchain_marker (w->sb_point);
2198 /* This breaks set-window-configuration if windows in the saved 2179 w->buffer = Qnil;
2199 configuration get deleted and multiple frames are in use. */
2200 /* w->buffer = Qnil; */
2201 } 2180 }
2202 2181
2203 /* close up the hole in the sibling list */ 2182 /* close up the hole in the sibling list */
2204 if (!NILP (w->next)) 2183 if (!NILP (w->next))
2205 XWINDOW (w->next)->prev = w->prev; 2184 XWINDOW (w->next)->prev = w->prev;
3549 invalid_operation ("Attempt to display deleted buffer", Qunbound); 3528 invalid_operation ("Attempt to display deleted buffer", Qunbound);
3550 3529
3551 tem = w->buffer; 3530 tem = w->buffer;
3552 if (NILP (tem)) 3531 if (NILP (tem))
3553 invalid_operation ("Window is deleted", Qunbound); 3532 invalid_operation ("Window is deleted", Qunbound);
3554
3555 /* While this seems like a logical thing to do, it causes problems
3556 because of saved window configurations. It is possible for a
3557 buffer to get restored into a window in which it is already being
3558 displayed, but start and point are actually at completely
3559 different locations. So we let this function complete fully and
3560 it will then make sure redisplay correctly updates things.
3561
3562 #### This is a kludge. The correct approach is not to do this
3563 but to fix set-window-configuration. */
3564 #if 0
3565 else if (EQ (tem, buffer)) 3533 else if (EQ (tem, buffer))
3566 return Qnil; 3534 return Qnil;
3567 #endif
3568 else if (! EQ (tem, Qt)) /* w->buffer is t when the window 3535 else if (! EQ (tem, Qt)) /* w->buffer is t when the window
3569 is first being set up. */ 3536 is first being set up. */
3570 { 3537 {
3571 if (!NILP (w->dedicated) && !EQ (tem, buffer)) 3538 if (!NILP (w->dedicated) && !EQ (tem, buffer))
3572 signal_error (Qinvalid_operation, "Window is dedicated to buffer", tem); 3539 signal_error (Qinvalid_operation, "Window is dedicated to buffer", tem);
3741 w->hscroll = 0; 3708 w->hscroll = 0;
3742 w->modeline_hscroll = 0; 3709 w->modeline_hscroll = 0;
3743 set_marker_restricted (w->start[CURRENT_DISP], make_int (1), buf); 3710 set_marker_restricted (w->start[CURRENT_DISP], make_int (1), buf);
3744 set_marker_restricted (w->pointm[CURRENT_DISP], make_int (1), buf); 3711 set_marker_restricted (w->pointm[CURRENT_DISP], make_int (1), buf);
3745 set_marker_restricted (w->sb_point, make_int (1), buf); 3712 set_marker_restricted (w->sb_point, make_int (1), buf);
3746
3747 /* Run temp-buffer-show-hook, with the chosen window selected. */
3748 if (!preparing_for_armageddon)
3749 {
3750 Lisp_Object tem;
3751 tem = Fboundp (Qtemp_buffer_show_hook);
3752 if (!NILP (tem))
3753 {
3754 tem = Fsymbol_value (Qtemp_buffer_show_hook);
3755 if (!NILP (tem))
3756 {
3757 int count = specpdl_depth ();
3758
3759 /* Select the window that was chosen, for running
3760 the hook. */
3761 record_unwind_protect (save_window_excursion_unwind,
3762 Fcurrent_window_configuration (Qnil));
3763
3764 Fselect_window (window, Qnil);
3765 run_hook (Qtemp_buffer_show_hook);
3766 unbind_to (count);
3767 }
3768 }
3769 }
3770 } 3713 }
3771 } 3714 }
3772 3715
3773 static void 3716 static void
3774 make_dummy_parent (Lisp_Object window) 3717 make_dummy_parent (Lisp_Object window)
5144 5087
5145 return Fnreverse (val); 5088 return Fnreverse (val);
5146 } 5089 }
5147 5090
5148 #endif /* MEMORY_USAGE_STATS */ 5091 #endif /* MEMORY_USAGE_STATS */
5149
5150 5092
5151 /************************************************************************/
5152 /* Window configurations */
5153 /************************************************************************/
5154
5155 /* #### This window configuration stuff has had serious bugs lurking in it
5156 for years; it would be a -huge- win if this was reimplemented in lisp.
5157 */
5158
5159 /* If you add anything to this structure make sure saved_window_equal
5160 knows about it. */
5161 struct saved_window
5162 {
5163 Lisp_Object window; /* window */
5164 Lisp_Object buffer; /* buffer */
5165 Lisp_Object start; /* copied marker */
5166 Lisp_Object pointm; /* copied marker */
5167 Lisp_Object sb_point; /* copied marker */
5168 Lisp_Object mark; /* copied marker */
5169 int pixel_left;
5170 int pixel_top;
5171 int pixel_width;
5172 int pixel_height;
5173 int hscroll;
5174 Charcount modeline_hscroll;
5175 int parent_index; /* index into saved_windows */
5176 int prev_index; /* index into saved_windows */
5177 char start_at_line_beg; /* boolean */
5178
5179 #define WINDOW_SLOT_DECLARATION
5180 #define WINDOW_SLOT(slot)
5181 #define WINDOW_SAVED_SLOT(slot, compare) Lisp_Object slot;
5182 #include "winslots.h"
5183 };
5184
5185 /* If you add anything to this structure make sure window_config_equal
5186 knows about it. */
5187 struct window_config
5188 {
5189 struct lcrecord_header header;
5190 /* int frame_width; No longer needed, JV
5191 int frame_height; */
5192 #if 0 /* FSFmacs */
5193 Lisp_Object selected_frame;
5194 #endif
5195 Lisp_Object current_window;
5196 Lisp_Object current_buffer;
5197 Lisp_Object minibuffer_scroll_window;
5198 Lisp_Object root_window;
5199 int minibuf_height; /* 0 = no minibuffer, <0, size in lines, >0 in pixels */
5200 /* Record the values of window-min-width and window-min-height
5201 so that window sizes remain consistent with them. */
5202 int min_width, min_height;
5203 int saved_windows_count;
5204 /* Zero-sized arrays aren't ANSI C */
5205 struct saved_window saved_windows[1];
5206 };
5207
5208 #define SAVED_WINDOW_N(conf, n) (&((conf)->saved_windows[(n)]))
5209 #define XWINDOW_CONFIGURATION(x) XRECORD (x, window_configuration, struct window_config)
5210 #define wrap_window_configuration(p) wrap_record (p, window_configuration)
5211 #define WINDOW_CONFIGURATIONP(x) RECORDP (x, window_configuration)
5212 #define CHECK_WINDOW_CONFIGURATION(x) CHECK_RECORD (x, window_configuration)
5213
5214 #ifdef USE_KKCC
5215 static const struct struct_description saved_window_description = {
5216 };
5217
5218 static const struct lrecord_description window_config_description [] = {
5219 { XD_LISP_OBJECT, offsetof (struct window_config, current_window) },
5220 { XD_LISP_OBJECT, offsetof (struct window_config, current_buffer) },
5221 { XD_LISP_OBJECT, offsetof (struct window_config, minibuffer_scroll_window) },
5222 { XD_LISP_OBJECT, offsetof (struct window_config, root_window) },
5223 { XD_END }
5224 };
5225 #endif /* USE_KKCC */
5226
5227 static Lisp_Object
5228 mark_window_config (Lisp_Object obj)
5229 {
5230 struct window_config *config = XWINDOW_CONFIGURATION (obj);
5231 int i;
5232 mark_object (config->current_window);
5233 mark_object (config->current_buffer);
5234 mark_object (config->minibuffer_scroll_window);
5235 mark_object (config->root_window);
5236
5237 for (i = 0; i < config->saved_windows_count; i++)
5238 {
5239 struct saved_window *s = SAVED_WINDOW_N (config, i);
5240 mark_object (s->window);
5241 mark_object (s->buffer);
5242 mark_object (s->start);
5243 mark_object (s->pointm);
5244 mark_object (s->sb_point);
5245 mark_object (s->mark);
5246 #if 0
5247 /* #### This looked like this. I do not see why specifier cached
5248 values should not be marked, as such specifiers as toolbars
5249 might have GC-able instances. Freed configs are not marked,
5250 aren't they? -- kkm */
5251 mark_object (s->dedicated);
5252 #else
5253 #define WINDOW_SLOT(slot)
5254 #define WINDOW_SAVED_SLOT(slot, compare) mark_object (s->slot);
5255 #include "winslots.h"
5256 #endif
5257 }
5258 return Qnil;
5259 }
5260
5261 inline static Bytecount
5262 sizeof_window_config_for_n_windows (int n)
5263 {
5264 return FLEXIBLE_ARRAY_STRUCT_SIZEOF (struct window_config,
5265 struct saved_window, saved_windows, n);
5266 }
5267
5268 static Bytecount
5269 sizeof_window_config (const void *h)
5270 {
5271 const struct window_config *c = (const struct window_config *) h;
5272 return sizeof_window_config_for_n_windows (c->saved_windows_count);
5273 }
5274
5275 static void
5276 print_window_config (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
5277 {
5278 struct window_config *config = XWINDOW_CONFIGURATION (obj);
5279 if (print_readably)
5280 printing_unreadable_object ("#<window-configuration 0x%x>",
5281 config->header.uid);
5282 write_c_string (printcharfun, "#<window-configuration ");
5283 write_fmt_string (printcharfun, "0x%x>", config->header.uid);
5284 }
5285
5286 #ifdef USE_KKCC
5287 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("window-configuration",
5288 window_configuration,
5289 0, /*dumpable-flag*/
5290 mark_window_config,
5291 print_window_config,
5292 0, 0, 0,
5293 0/*window_config_description*/, sizeof_window_config,
5294 struct window_config);
5295 #else /* not USE_KKCC */
5296 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("window-configuration",
5297 window_configuration,
5298 mark_window_config,
5299 print_window_config,
5300 0, 0, 0, 0, sizeof_window_config,
5301 struct window_config);
5302 #endif /* not USE_KKCC */
5303
5304 /* Returns a boolean indicating whether the two saved windows are
5305 identical. */
5306 static int
5307 saved_window_equal (struct saved_window *win1, struct saved_window *win2)
5308 {
5309 #define WINDOW_SLOT(slot)
5310 #define WINDOW_SAVED_SLOT(slot, compare) \
5311 if (!compare (win1->slot, win2->slot)) \
5312 return 0;
5313 #include "winslots.h"
5314
5315 return
5316 EQ (win1->window, win2->window) &&
5317 EQ (win1->buffer, win2->buffer) &&
5318 internal_equal (win1->start, win2->start, 0) &&
5319 internal_equal (win1->pointm, win2->pointm, 0) &&
5320 internal_equal (win1->sb_point, win2->sb_point, 0) &&
5321 internal_equal (win1->mark, win2->mark, 0) &&
5322 win1->pixel_left == win2->pixel_left &&
5323 win1->pixel_top == win2->pixel_top &&
5324 win1->pixel_width == win2->pixel_width &&
5325 win1->pixel_height == win2->pixel_height &&
5326 win1->hscroll == win2->hscroll &&
5327 win1->modeline_hscroll == win2->modeline_hscroll &&
5328 win1->parent_index == win2->parent_index &&
5329 win1->prev_index == win2->prev_index &&
5330 win1->start_at_line_beg == win2->start_at_line_beg;
5331 }
5332
5333 /* Returns a boolean indicating whether the two given configurations
5334 are identical. */
5335 static int
5336 window_config_equal (Lisp_Object conf1, Lisp_Object conf2)
5337 {
5338 struct window_config *fig1, *fig2;
5339 int i;
5340
5341 /* First check if they are truly the same. */
5342 if (EQ (conf1, conf2))
5343 return 1;
5344
5345 fig1 = XWINDOW_CONFIGURATION (conf1);
5346 fig2 = XWINDOW_CONFIGURATION (conf2);
5347
5348 if (!((fig1->saved_windows_count == fig2->saved_windows_count) &&
5349 EQ (fig1->current_window, fig2->current_window) &&
5350 EQ (fig1->current_buffer, fig2->current_buffer) &&
5351 EQ (fig1->root_window, fig2->root_window) &&
5352 EQ (fig1->minibuffer_scroll_window, fig2->minibuffer_scroll_window)))
5353 /* &&
5354 fig1->frame_width == fig2->frame_width &&
5355 fig1->frame_height == fig2->frame_height)) */
5356 return 0;
5357
5358 for (i = 0; i < fig1->saved_windows_count; i++)
5359 {
5360 if (!saved_window_equal (SAVED_WINDOW_N (fig1, i),
5361 SAVED_WINDOW_N (fig2, i)))
5362 return 0;
5363 }
5364
5365 return 1;
5366 }
5367
5368 DEFUN ("window-configuration-p", Fwindow_configuration_p, 1, 1, 0, /*
5369 Return t if OBJECT is a window-configuration object.
5370 */
5371 (object))
5372 {
5373 return WINDOW_CONFIGURATIONP (object) ? Qt : Qnil;
5374 }
5375
5376 static int
5377 mark_windows_in_use_closure (struct window *w, void *closure)
5378 {
5379 int mark = *(int *)closure;
5380 w->config_mark = mark;
5381 return 0;
5382 }
5383
5384 static void
5385 mark_windows_in_use (struct frame *f, int mark)
5386 {
5387 map_windows (f, mark_windows_in_use_closure, &mark);
5388 }
5389
5390 /* Lisp_Object return value so it can be used in record_unwind_protect() */
5391 static Lisp_Object
5392 free_window_configuration (Lisp_Object window_config)
5393 {
5394 int i;
5395 struct window_config *config = XWINDOW_CONFIGURATION (window_config);
5396
5397 /* Free all the markers. It's not completely necessary that
5398 we do this (window configs sitting in a free list aren't
5399 marked normally so the markers wouldn't be marked anyway)
5400 but it's more efficient. */
5401 for (i = 0; i < config->saved_windows_count; i++)
5402 {
5403 struct saved_window *p = SAVED_WINDOW_N (config, i);
5404
5405 if (!NILP (p->pointm))
5406 {
5407 free_marker (XMARKER (p->pointm));
5408 p->pointm = Qnil;
5409 }
5410 if (!NILP (p->start))
5411 {
5412 free_marker (XMARKER (p->start));
5413 p->start = Qnil;
5414 }
5415 if (!NILP (p->sb_point))
5416 {
5417 free_marker (XMARKER (p->sb_point));
5418 p->sb_point = Qnil;
5419 }
5420 if (!NILP (p->mark))
5421 {
5422 free_marker (XMARKER (p->mark));
5423 p->mark = Qnil;
5424 }
5425 }
5426
5427 if (config->saved_windows_count <= countof (Vwindow_configuration_free_list))
5428 free_managed_lcrecord (Vwindow_configuration_free_list
5429 [config->saved_windows_count - 1],
5430 window_config);
5431
5432 return Qnil;
5433 }
5434
5435 DEFUN ("set-window-configuration", Fset_window_configuration, 1, 1, 0, /*
5436 Set the configuration of windows and buffers as specified by CONFIGURATION.
5437 CONFIGURATION must be a value previously returned
5438 by `current-window-configuration' (which see).
5439 */
5440 (configuration))
5441 {
5442 struct window *w;
5443 struct window_config *config;
5444 struct saved_window *p;
5445 Lisp_Object new_current_buffer;
5446 int k;
5447 Lisp_Object frame;
5448 struct frame *f;
5449 struct gcpro gcpro1;
5450 Lisp_Object old_window_config;
5451 /* int previous_frame_height;
5452 int previous_frame_width;*/
5453 int previous_pixel_top;
5454 int previous_pixel_height;
5455 int previous_pixel_left;
5456 int previous_pixel_width;
5457 int previous_minibuf_height, previous_minibuf_top,previous_minibuf_width;
5458 int real_font_height;
5459 int converted_minibuf_height,target_minibuf_height;
5460 int specpdl_count = specpdl_depth ();
5461
5462 GCPRO1 (configuration);
5463
5464 CHECK_WINDOW_CONFIGURATION (configuration);
5465 config = XWINDOW_CONFIGURATION (configuration);
5466
5467 frame = XWINDOW (SAVED_WINDOW_N (config, 0)->window)->frame;
5468 f = XFRAME (frame);
5469
5470 /* Do not signal an error here if the frame was deleted. There are
5471 reasonable cases where we could get here with a deleted frame and
5472 just want to do close to nothing instead. */
5473
5474 if (FRAME_LIVE_P (f))
5475 {
5476 /* restore the frame characteristics */
5477
5478 new_current_buffer = config->current_buffer;
5479 if (!BUFFER_LIVE_P (XBUFFER (new_current_buffer)))
5480 new_current_buffer = Qnil;
5481
5482 /*
5483 * Assumed precondition: w->config_mark = 0 for all w
5484 * This procedure should ensure this is true by the time it exits
5485 * to ensure the precondition for future calls.
5486 *
5487 * We use w->config_mark to know whether we're modifying a
5488 * window that is currently visible on the frame (#### we
5489 * should just be able to check whether the window is dead
5490 * or not, but this way is safer?). As we process each
5491 * window, we set its config_mark to 0. At the end, we
5492 * go through all the windows that used to be on the frame,
5493 * set each one's config_mark to 0 (to maintain the
5494 * assumed precondition) and delete each one that's no
5495 * longer in use.
5496 *
5497 * #### Using a window-configuration to keep track of
5498 * the current windows is wasteful. All we need is the
5499 * list of windows, so we could just use a dynarr.
5500 */
5501 old_window_config = Fcurrent_window_configuration (frame);
5502
5503 /* If the new configuration is already equal to the old, then stop
5504 right here. This saves the work below and it also saves
5505 triggering a full redisplay of this window. This is a huge win
5506 when using the mouse since the mode motion code uses
5507 save-window-excursion extensively but will rarely cause the
5508 configuration to actually change. */
5509 if (window_config_equal (configuration, old_window_config))
5510 {
5511 free_window_configuration (old_window_config);
5512 UNGCPRO;
5513 return Qnil;
5514 }
5515
5516 /* We can't quit or even check for quit because that may cause
5517 investigation of the frame state, which may crash if the frame is
5518 in an inconsistent state. */
5519 begin_dont_check_for_quit ();
5520 record_unwind_protect (free_window_configuration, old_window_config);
5521
5522 mark_windows_in_use (f, 1);
5523 #ifdef BROKEN_SUBWINDOW_REDISPLAY
5524 /* Force subwindows to be remapped. This is overkill but saves
5525 us having to rely on the redisplay code to unmap any extant
5526 subwindows.
5527
5528 #### It does cause some extra flashing though which we could
5529 possibly avoid. So consider trying to get redisplay to work
5530 correctly.
5531
5532 Removing the instances from the frame cache is wrong because
5533 an instance is only put in the frame cache when it is
5534 instantiated. So if we do this there is a chance that stuff
5535 will never get put back in the frame cache. */
5536 reset_frame_subwindow_instance_cache (f);
5537 #endif
5538 #if 0
5539 /* JV: This is bogus,
5540 First of all, the units are inconsistent. The frame sizes are measured
5541 in characters but the window sizes are stored in pixels. So if a
5542 font size change happened between saving and restoring, the
5543 frame "sizes" maybe equal but the windows still should be
5544 resized. This is tickled a lot by the new "character size
5545 stays constant" policy in 21.0. It leads to very weird
5546 glitches (and possibly crashes when asserts are tickled).
5547
5548 Just changing the units doesn't help because changing the
5549 toolbar configuration can also change the pixel positions.
5550 Luckily there is a much simpler way of doing this, see below.
5551 */
5552 previous_frame_width = FRAME_WIDTH (f);
5553 previous_frame_height = FRAME_HEIGHT (f);
5554 /* If the frame has been resized since this window configuration was
5555 made, we change the frame to the size specified in the
5556 configuration, restore the configuration, and then resize it
5557 back. We keep track of the prevailing height in these variables. */
5558 if (config->frame_height != FRAME_HEIGHT (f)
5559 || config->frame_width != FRAME_WIDTH (f))
5560 change_frame_size (f, config->frame_height, config->frame_width, 0);
5561 #endif
5562
5563 previous_pixel_top = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top;
5564 previous_pixel_height = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_height;
5565 previous_pixel_left = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left;
5566 previous_pixel_width = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_width;
5567
5568 /* remember some properties of the minibuffer */
5569
5570 default_face_height_and_width (frame, &real_font_height, 0);
5571 assert(real_font_height > 0);
5572
5573 if (FRAME_HAS_MINIBUF_P (f) && ! FRAME_MINIBUF_ONLY_P (f))
5574 {
5575 previous_minibuf_height
5576 = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height;
5577 previous_minibuf_top
5578 = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_top;
5579 previous_minibuf_width
5580 = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_width;
5581 }
5582 else
5583 {
5584 previous_minibuf_height = 0;
5585 previous_minibuf_top = 0;
5586 previous_minibuf_width = 0;
5587 }
5588 converted_minibuf_height =
5589 (previous_minibuf_height % real_font_height) == 0 ?
5590 - (previous_minibuf_height / real_font_height ) : /* lines */
5591 previous_minibuf_height; /* pixels */
5592
5593 /* Temporarily avoid any problems with windows that are smaller
5594 than they are supposed to be. */
5595 window_min_height = 1;
5596 window_min_width = 1;
5597
5598 /* OK, now restore all the windows in the window config.
5599 This may involve "undeleting" windows, since the
5600 windows in the window config may be deleted.
5601 */
5602 for (k = 0; k < config->saved_windows_count; k++)
5603 {
5604 p = SAVED_WINDOW_N (config, k);
5605 w = XWINDOW (p->window);
5606 w->next = Qnil;
5607
5608 /* The window might be dead. In this case, its redisplay
5609 structures were freed, so we need to reallocate them. */
5610 if (!w->face_cachels)
5611 {
5612 w->face_cachels = Dynarr_new (face_cachel);
5613 reset_face_cachels (w);
5614 }
5615 if (!w->glyph_cachels)
5616 w->glyph_cachels = Dynarr_new (glyph_cachel);
5617 if (!w->line_start_cache)
5618 w->line_start_cache = Dynarr_new (line_start_cache);
5619 w->gutter_extent_modiff[0] = 0;
5620 w->gutter_extent_modiff[1] = 0;
5621 w->gutter_extent_modiff[2] = 0;
5622 w->gutter_extent_modiff[3] = 0;
5623 w->dead = 0;
5624
5625 note_object_created (p->window);
5626
5627 if (p->parent_index >= 0)
5628 w->parent = SAVED_WINDOW_N (config, p->parent_index)->window;
5629 else
5630 w->parent = Qnil;
5631
5632 if (p->prev_index >= 0)
5633 {
5634 w->prev = SAVED_WINDOW_N (config, p->prev_index)->window;
5635
5636 /* This is true for a minibuffer-only frame. */
5637 if (!NILP (w->mini_p) && EQ (w->prev, p->window))
5638 w->next = Qnil;
5639 else
5640 XWINDOW (w->prev)->next = p->window;
5641 }
5642 else
5643 {
5644 w->prev = Qnil;
5645 if (!NILP (w->parent))
5646 {
5647 if (WINDOW_WIDTH (p) == WINDOW_WIDTH (XWINDOW (w->parent)))
5648 {
5649 XWINDOW (w->parent)->vchild = p->window;
5650 XWINDOW (w->parent)->hchild = Qnil;
5651 }
5652 else
5653 {
5654 XWINDOW (w->parent)->hchild = p->window;
5655 XWINDOW (w->parent)->vchild = Qnil;
5656 }
5657 }
5658 }
5659 if (!w->config_mark)
5660 {
5661 /* #### This should be equivalent to the window previously
5662 having been dead. If we're brave, we'll put in an
5663 assertion to this effect. */
5664 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
5665 }
5666 else /* if (!EQ (w->buffer, p->buffer)) */
5667 {
5668 /* With the new redisplay we let it know that a change has
5669 been made and it will take care of the rest. If we don't
5670 tell it something has possibly changed it could lead to
5671 incorrect display. */
5672 MARK_WINDOWS_CHANGED (w);
5673 }
5674
5675 WINDOW_LEFT (w) = WINDOW_LEFT (p);
5676 WINDOW_TOP (w) = WINDOW_TOP (p);
5677 WINDOW_WIDTH (w) = WINDOW_WIDTH (p);
5678 WINDOW_HEIGHT (w) = WINDOW_HEIGHT (p);
5679 w->hscroll = p->hscroll;
5680 w->modeline_hscroll = p->modeline_hscroll;
5681 w->line_cache_last_updated = Qzero;
5682 /* When we restore a window's configuration, the identity of
5683 the window hasn't actually changed - so there is no
5684 reason why we shouldn't preserve the instance cache for
5685 it - unless it was originally deleted. This will often
5686 buy us something as we will not have to re-instantiate
5687 all the instances. This is because this is an instance
5688 cache - not a display cache. Preserving the display cache
5689 would definitely be wrong.
5690
5691 We specifically want to do this for tabs, since for some
5692 reason finding a file will cause the configuration to be
5693 set. */
5694 if (NILP (w->subwindow_instance_cache))
5695 w->subwindow_instance_cache =
5696 make_image_instance_cache_hash_table ();
5697
5698 SET_LAST_MODIFIED (w, 1);
5699 SET_LAST_FACECHANGE (w);
5700 w->config_mark = 0;
5701
5702 /* #### Consider making the instance cache a WINDOW_SAVED_SLOT. */
5703 #define WINDOW_SLOT(slot)
5704 #define WINDOW_SAVED_SLOT(slot, compare) w->slot = p->slot;
5705 #include "winslots.h"
5706
5707 /* Reinstall the saved buffer and pointers into it. */
5708 if (NILP (p->buffer))
5709 w->buffer = p->buffer;
5710 else
5711 {
5712 if (BUFFER_LIVE_P (XBUFFER (p->buffer)))
5713 /* If saved buffer is alive, install it. */
5714 {
5715 w->buffer = p->buffer;
5716 w->start_at_line_beg = p->start_at_line_beg;
5717 set_marker_restricted (w->start[CURRENT_DISP],
5718 Fmarker_position (p->start),
5719 w->buffer);
5720 set_marker_restricted (w->pointm[CURRENT_DISP],
5721 Fmarker_position (p->pointm),
5722 w->buffer);
5723 set_marker_restricted (w->sb_point,
5724 Fmarker_position (p->sb_point),
5725 w->buffer);
5726 Fset_marker (XBUFFER (w->buffer)->mark,
5727 Fmarker_position (p->mark), w->buffer);
5728
5729 /* As documented in Fcurrent_window_configuration, don't
5730 save the location of point in the buffer which was current
5731 when the window configuration was recorded. */
5732 if (!EQ (p->buffer, new_current_buffer) &&
5733 XBUFFER (p->buffer) == current_buffer)
5734 Fgoto_char (w->pointm[CURRENT_DISP], Qnil);
5735 }
5736 else if (NILP (w->buffer) ||
5737 !BUFFER_LIVE_P (XBUFFER (w->buffer)))
5738 /* Else if window's old buffer is dead too, get a live one. */
5739 {
5740 /* #### The following line makes me nervous... */
5741 /* w->buffer = Fcdr (Fcar (XFRAME (w->frame)->buffer_alist));*/
5742 w->buffer = Fget_buffer_create (QSscratch);
5743 /* w->buffer = Fother_buffer (Qnil, w->frame, Qnil); */
5744 /* This will set the markers to beginning of visible
5745 range. */
5746 set_marker_restricted (w->start[CURRENT_DISP], Qzero, w->buffer);
5747 set_marker_restricted (w->pointm[CURRENT_DISP], Qzero,
5748 w->buffer);
5749 set_marker_restricted (w->sb_point, Qzero, w->buffer);
5750 w->start_at_line_beg = 1;
5751 }
5752 else
5753 /* Keeping window's old buffer; make sure the markers
5754 are real. */
5755 {
5756 /* Set window markers at start of visible range. */
5757 if (XMARKER (w->start[CURRENT_DISP])->buffer == 0)
5758 set_marker_restricted (w->start[CURRENT_DISP], Qzero,
5759 w->buffer);
5760 if (XMARKER (w->sb_point)->buffer == 0)
5761 set_marker_restricted (w->sb_point, Qzero, w->buffer);
5762 if (XMARKER (w->pointm[CURRENT_DISP])->buffer == 0)
5763 set_marker_restricted (w->pointm[CURRENT_DISP],
5764 make_int
5765 (BUF_PT (XBUFFER (w->buffer))),
5766 w->buffer);
5767 w->start_at_line_beg = 1;
5768 }
5769 }
5770 }
5771
5772 FRAME_ROOT_WINDOW (f) = config->root_window;
5773 /* Note that FSFmacs unilaterally calls Fselect_window() here, and
5774 then calls do_switch_frame() below to select the frame that was
5775 recorded in the window config as being selected.
5776
5777 Instead, we don't ever change the selected frame, and either
5778 call Fselect_window() below if the window config's frame is
5779 currently selected, or just set the selected window of the
5780 window config's frame. */
5781
5782 #if 0
5783 /* Set the frame height to the value it had before this function. */
5784 if (previous_frame_height != FRAME_HEIGHT (f)
5785 || previous_frame_width != FRAME_WIDTH (f))
5786 change_frame_size (f, previous_frame_height, previous_frame_width, 0);
5787 #endif
5788 /* We just reset the size and position of the minibuffer, to its old
5789 value, which needn't be valid. So we do some magic to see which value
5790 to actually take. Then we set it.
5791
5792 The magic:
5793 We take the old value if is in the same units but differs from the
5794 current value.
5795
5796 #### Now we get more cases correct then ever before, but
5797 are we treating all? For instance what if the frames minibuf window
5798 is no longer the same one?
5799 */
5800 target_minibuf_height = previous_minibuf_height;
5801 if (converted_minibuf_height &&
5802 (converted_minibuf_height * config->minibuf_height) > 0 &&
5803 (converted_minibuf_height != config->minibuf_height))
5804 {
5805 target_minibuf_height = config->minibuf_height < 0 ?
5806 - (config->minibuf_height * real_font_height) :
5807 config->minibuf_height;
5808 target_minibuf_height =
5809 max(target_minibuf_height,real_font_height);
5810 }
5811 if (previous_minibuf_height)
5812 {
5813 XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_top
5814 = previous_minibuf_top -
5815 (target_minibuf_height - previous_minibuf_height);
5816 set_window_pixheight (FRAME_MINIBUF_WINDOW (f),
5817 target_minibuf_height, 0);
5818 set_window_pixwidth (FRAME_MINIBUF_WINDOW (f),
5819 previous_minibuf_width, 0);
5820 }
5821
5822 /* This is a better way to deal with frame resizing, etc.
5823 What we _actually_ want is for the old (just restored)
5824 root window to fit
5825 into the place of the new one. So we just do that. Simple! */
5826 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top = previous_pixel_top;
5827 /* Note that this function also updates the subwindow
5828 "pixel_top"s */
5829 set_window_pixheight (FRAME_ROOT_WINDOW (f),
5830 previous_pixel_height -
5831 (target_minibuf_height - previous_minibuf_height), 0);
5832 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left = previous_pixel_left;
5833 /* Note that this function also updates the subwindow
5834 "pixel_left"s */
5835 set_window_pixwidth (FRAME_ROOT_WINDOW (f), previous_pixel_width, 0);
5836
5837 /* If restoring in the current frame make the window current,
5838 otherwise just update the frame selected_window slot to be
5839 the restored current_window. */
5840 if (f == selected_frame ())
5841 {
5842 #if 0
5843 /* When using `pop-window-configuration', often the minibuffer
5844 ends up as the selected window even though it's not active ...
5845 I really don't know the cause of this, but it should never
5846 happen. This kludge should fix it.
5847
5848 #### Find out why this is really going wrong. */
5849 if (!minibuf_level &&
5850 MINI_WINDOW_P (XWINDOW (config->current_window)))
5851 window_to_select = Fnext_window (config->current_window,
5852 Qnil, Qnil, Qnil);
5853 else
5854 window_to_select = config->current_window;
5855 #endif
5856 /* Do this last so that buffer stacking is calculated
5857 correctly. */
5858 Fselect_window (config->current_window, Qnil);
5859
5860 if (!NILP (new_current_buffer))
5861 {
5862 Fset_buffer (new_current_buffer);
5863 Frecord_buffer (new_current_buffer);
5864 }
5865 else
5866 {
5867 Fset_buffer (XWINDOW (config->current_window)->buffer);
5868 Frecord_buffer (XWINDOW (config->current_window)->buffer);
5869 }
5870 }
5871 else
5872 set_frame_selected_window (f, config->current_window);
5873 }
5874 else
5875 old_window_config = Qnil; /* Warning suppression */
5876
5877 /* Restore the minimum heights recorded in the configuration. */
5878 window_min_height = config->min_height;
5879 window_min_width = config->min_width;
5880
5881 #if 0 /* FSFmacs */
5882 /* see above comment */
5883 /* Fselect_window will have made f the selected frame, so we
5884 reselect the proper frame here. Fhandle_switch_frame will change the
5885 selected window too, but that doesn't make the call to
5886 Fselect_window above totally superfluous; it still sets f's
5887 selected window. */
5888 if (FRAME_LIVE_P (XFRAME (config->selected_frame)))
5889 do_switch_frame (config->selected_frame, Qnil, 0);
5890 #endif
5891
5892 Vminibuffer_scroll_window = config->minibuffer_scroll_window;
5893
5894 if (FRAME_LIVE_P (f))
5895 {
5896 /* Do this before calling recompute_all_cached_specifiers_in_window()
5897 so that things like redisplay_redraw_cursor() won't abort due
5898 to no window mirror present. */
5899 f->mirror_dirty = 1;
5900
5901 config = XWINDOW_CONFIGURATION (old_window_config);
5902 for (k = 0; k < config->saved_windows_count; k++)
5903 {
5904 p = SAVED_WINDOW_N (config, k);
5905 w = XWINDOW (p->window);
5906 /* Remember, we set w->config_mark on all currently visible
5907 windows, and reset it on all newly visible windows.
5908 Any windows still marked need to be deleted. */
5909 if (w->config_mark)
5910 {
5911 mark_window_as_deleted (w);
5912 w->config_mark = 0;
5913 }
5914 else
5915 {
5916 /* We just potentially changed the window's buffer and
5917 potentially turned a dead window into a live one,
5918 so we need to recompute the cached specifier values. */
5919 recompute_all_cached_specifiers_in_window (w);
5920 }
5921 }
5922 }
5923
5924 /* Now restore things, when everything else if OK. */
5925
5926 unbind_to (specpdl_count);
5927
5928 UNGCPRO;
5929
5930 return Qnil;
5931 }
5932
5933 /* Mark all subwindows of a window as deleted. The argument 5093 /* Mark all subwindows of a window as deleted. The argument
5934 W is actually the subwindow tree of the window in question. */ 5094 W is actually the subwindow tree of the window in question. */
5935 5095
5936 void 5096 void
5937 delete_all_subwindows (struct window *w) 5097 delete_all_subwindows (struct window *w)
5941 if (!NILP (w->hchild)) delete_all_subwindows (XWINDOW (w->hchild)); 5101 if (!NILP (w->hchild)) delete_all_subwindows (XWINDOW (w->hchild));
5942 5102
5943 mark_window_as_deleted (w); 5103 mark_window_as_deleted (w);
5944 } 5104 }
5945 5105
5946
5947 static int
5948 count_windows (struct window *window)
5949 {
5950 return 1 +
5951 (!NILP (window->next) ? count_windows (XWINDOW (window->next)) : 0) +
5952 (!NILP (window->vchild) ? count_windows (XWINDOW (window->vchild)) : 0) +
5953 (!NILP (window->hchild) ? count_windows (XWINDOW (window->hchild)) : 0);
5954 }
5955
5956 static int
5957 saved_window_index (Lisp_Object window, struct window_config *config, int lim)
5958 {
5959 int j;
5960 for (j = 0; j < lim; j++)
5961 {
5962 if (EQ (SAVED_WINDOW_N (config, j)->window, window))
5963 return j;
5964 }
5965 abort ();
5966 return 0; /* suppress compiler warning */
5967 }
5968
5969 static int
5970 save_window_save (Lisp_Object window, struct window_config *config, int i)
5971 {
5972 struct window *w;
5973
5974 for (; !NILP (window); window = w->next)
5975 {
5976 struct saved_window *p = SAVED_WINDOW_N (config, i);
5977
5978 w = XWINDOW (window);
5979 i++;
5980 p->window = window;
5981 p->buffer = w->buffer;
5982 WINDOW_LEFT (p) = WINDOW_LEFT (w);
5983 WINDOW_TOP (p) = WINDOW_TOP (w);
5984 WINDOW_WIDTH (p) = WINDOW_WIDTH (w);
5985 WINDOW_HEIGHT (p) = WINDOW_HEIGHT (w);
5986 p->hscroll = w->hscroll;
5987 p->modeline_hscroll = w->modeline_hscroll;
5988
5989 #define WINDOW_SLOT(slot)
5990 #define WINDOW_SAVED_SLOT(slot, compare) p->slot = w->slot;
5991 #include "winslots.h"
5992
5993 if (!NILP (w->buffer))
5994 {
5995 /* Save w's value of point in the window configuration.
5996 If w is the selected window, then get the value of point
5997 from the buffer; pointm is garbage in the selected window. */
5998 if (EQ (window, Fselected_window (Qnil)))
5999 {
6000 p->pointm = noseeum_make_marker ();
6001 Fset_marker (p->pointm,
6002 make_int (BUF_PT (XBUFFER (w->buffer))),
6003 w->buffer);
6004 }
6005 else
6006 p->pointm = noseeum_copy_marker (w->pointm[CURRENT_DISP], Qnil);
6007
6008 p->start = noseeum_copy_marker (w->start[CURRENT_DISP], Qnil);
6009 p->sb_point = noseeum_copy_marker (w->sb_point, Qnil);
6010 p->start_at_line_beg = w->start_at_line_beg;
6011
6012 p->mark = noseeum_copy_marker (XBUFFER (w->buffer)->mark, Qnil);
6013 }
6014 else
6015 {
6016 p->pointm = Qnil;
6017 p->start = Qnil;
6018 p->sb_point = Qnil;
6019 p->mark = Qnil;
6020 p->start_at_line_beg = 0;
6021 }
6022
6023 if (NILP (w->parent))
6024 p->parent_index = -1;
6025 else
6026 p->parent_index = saved_window_index (w->parent, config, i);
6027 if (NILP (w->prev))
6028 p->prev_index = -1;
6029 else
6030 p->prev_index = saved_window_index (w->prev, config, i);
6031 if (!NILP (w->vchild))
6032 i = save_window_save (w->vchild, config, i);
6033 if (!NILP (w->hchild))
6034 i = save_window_save (w->hchild, config, i);
6035 }
6036
6037 return i;
6038 }
6039
6040 #if 0 /* FSFmacs */
6041 /* Added to doc string:
6042
6043 This also records the currently selected frame, and FRAME's focus
6044 redirection (see `redirect-frame-focus').
6045
6046 */
6047 #endif
6048
6049 DEFUN ("current-window-configuration", Fcurrent_window_configuration, 0, 1, 0, /*
6050 Return an object representing the current window configuration of FRAME.
6051 If FRAME is nil or omitted, use the selected frame.
6052 This describes the number of windows, their sizes and current buffers,
6053 and for each window on FRAME the displayed buffer, where display
6054 starts, and the positions of point and mark.
6055 An exception is made for point in the current buffer:
6056 its value is -not- saved.
6057 */
6058 (frame))
6059 {
6060 Lisp_Object result;
6061 struct frame *f = decode_frame (frame);
6062 struct window_config *config;
6063 int n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
6064 int minibuf_height;
6065 int real_font_height;
6066
6067 if (n_windows <= countof (Vwindow_configuration_free_list))
6068 config = XWINDOW_CONFIGURATION (allocate_managed_lcrecord
6069 (Vwindow_configuration_free_list
6070 [n_windows - 1]));
6071 else
6072 /* More than ten windows; just allocate directly */
6073 config = (struct window_config *)
6074 alloc_lcrecord (sizeof_window_config_for_n_windows (n_windows),
6075 &lrecord_window_configuration);
6076 result = wrap_window_configuration (config);
6077 /*
6078 config->frame_width = FRAME_WIDTH (f);
6079 config->frame_height = FRAME_HEIGHT (f); */
6080 /* #### When using `push-window-configuration', often the minibuffer ends
6081 up as the selected window because functions run as the result of
6082 user interaction e.g. hyper-apropos. It seems to me the sensible
6083 thing to do is not record the minibuffer here.
6084
6085 #### Unfortunately this is a change to previous behaviour, however logical
6086 it may be, so revert for the moment. */
6087 #if 0
6088 if (FRAME_MINIBUF_ONLY_P (f) || minibuf_level)
6089 config->current_window = FRAME_SELECTED_WINDOW (f);
6090 else
6091 config->current_window = FRAME_LAST_NONMINIBUF_WINDOW (f);
6092 #endif
6093 config->current_window = FRAME_SELECTED_WINDOW (f);
6094 config->current_buffer = wrap_buffer (current_buffer);
6095 config->minibuffer_scroll_window = Vminibuffer_scroll_window;
6096 config->root_window = FRAME_ROOT_WINDOW (f);
6097 config->min_height = window_min_height;
6098 config->min_width = window_min_width;
6099 config->saved_windows_count = n_windows;
6100 save_window_save (FRAME_ROOT_WINDOW (f), config, 0);
6101
6102 /* save the minibuffer height using the heuristics from
6103 change_frame_size_1 */
6104
6105 frame = wrap_frame (f); /* frame could have been nil ! */
6106 default_face_height_and_width (frame, &real_font_height, 0);
6107 assert(real_font_height > 0);
6108
6109 if (FRAME_HAS_MINIBUF_P (f) && ! FRAME_MINIBUF_ONLY_P (f))
6110 minibuf_height = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height;
6111 else
6112 minibuf_height = 0;
6113 config->minibuf_height = (minibuf_height % real_font_height) == 0 ?
6114 - (minibuf_height / real_font_height ) : /* lines */
6115 minibuf_height; /* pixels */
6116
6117 return result;
6118 }
6119
6120 Lisp_Object 5106 Lisp_Object
6121 save_window_excursion_unwind (Lisp_Object window_config) 5107 save_window_excursion_unwind (Lisp_Object window_config)
6122 { 5108 {
6123 Lisp_Object val = Fset_window_configuration (window_config); 5109 Lisp_Object val = call1 (Qset_window_configuration, window_config);
6124 free_window_configuration (window_config);
6125 return val; 5110 return val;
6126 } 5111 }
6127 5112
6128 DEFUN ("save-window-excursion", Fsave_window_excursion, 0, UNEVALLED, 0, /* 5113 DEFUN ("save-window-excursion", Fsave_window_excursion, 0, UNEVALLED, 0, /*
6129 Execute body, preserving window sizes and contents. 5114 Execute body, preserving window sizes and contents.
6135 { 5120 {
6136 /* This function can GC */ 5121 /* This function can GC */
6137 int speccount = specpdl_depth (); 5122 int speccount = specpdl_depth ();
6138 5123
6139 record_unwind_protect (save_window_excursion_unwind, 5124 record_unwind_protect (save_window_excursion_unwind,
6140 Fcurrent_window_configuration (Qnil)); 5125 call1 (Qcurrent_window_configuration, Qnil));
6141 return unbind_to_1 (speccount, Fprogn (args)); 5126 return unbind_to_1 (speccount, Fprogn (args));
6142 } 5127 }
6143 5128
6144 DEFUN ("current-pixel-column", Fcurrent_pixel_column, 0, 2, 0, /* 5129 DEFUN ("current-pixel-column", Fcurrent_pixel_column, 0, 2, 0, /*
6145 Return the horizontal pixel position of POS in window. 5130 Return the horizontal pixel position of POS in window.
6146 Beginning of line is column 0. This is calculated using the redisplay 5131 Beginning of line is column 0. This is calculated using the redisplay
6147 display tables. If WINDOW is nil, the current window is assumed. 5132 display tables. If WINDOW is nil, the current window is assumed.
6148 If POS is nil, point is assumed. Note that POS must be visible for 5133 If POS is nil, point is assumed. Note that POS must be visible for
6261 5246
6262 void 5247 void
6263 syms_of_window (void) 5248 syms_of_window (void)
6264 { 5249 {
6265 INIT_LRECORD_IMPLEMENTATION (window); 5250 INIT_LRECORD_IMPLEMENTATION (window);
6266 INIT_LRECORD_IMPLEMENTATION (window_configuration);
6267 INIT_LRECORD_IMPLEMENTATION (window_mirror); 5251 INIT_LRECORD_IMPLEMENTATION (window_mirror);
6268 5252
6269 DEFSYMBOL (Qwindowp); 5253 DEFSYMBOL (Qwindowp);
6270 DEFSYMBOL (Qwindow_live_p); 5254 DEFSYMBOL (Qwindow_live_p);
6271 DEFSYMBOL_MULTIWORD_PREDICATE (Qwindow_configurationp);
6272 DEFSYMBOL (Qtemp_buffer_show_hook);
6273 DEFSYMBOL (Qdisplay_buffer); 5255 DEFSYMBOL (Qdisplay_buffer);
6274 5256
6275 #ifdef MEMORY_USAGE_STATS 5257 #ifdef MEMORY_USAGE_STATS
6276 DEFSYMBOL (Qface_cache); 5258 DEFSYMBOL (Qface_cache);
6277 DEFSYMBOL (Qglyph_cache); 5259 DEFSYMBOL (Qglyph_cache);
6282 DEFSYMBOL (Qother_redisplay); 5264 DEFSYMBOL (Qother_redisplay);
6283 /* Qother in general.c */ 5265 /* Qother in general.c */
6284 #endif 5266 #endif
6285 5267
6286 DEFSYMBOL (Qtruncate_partial_width_windows); 5268 DEFSYMBOL (Qtruncate_partial_width_windows);
5269 DEFSYMBOL (Qcurrent_window_configuration);
5270 DEFSYMBOL (Qset_window_configuration);
6287 5271
6288 DEFSUBR (Fselected_window); 5272 DEFSUBR (Fselected_window);
6289 DEFSUBR (Flast_nonminibuf_window); 5273 DEFSUBR (Flast_nonminibuf_window);
6290 DEFSUBR (Fminibuffer_window); 5274 DEFSUBR (Fminibuffer_window);
6291 DEFSUBR (Fwindow_minibuffer_p); 5275 DEFSUBR (Fwindow_minibuffer_p);
6361 DEFSUBR (Fcenter_to_window_line); 5345 DEFSUBR (Fcenter_to_window_line);
6362 DEFSUBR (Fmove_to_window_line); 5346 DEFSUBR (Fmove_to_window_line);
6363 #ifdef MEMORY_USAGE_STATS 5347 #ifdef MEMORY_USAGE_STATS
6364 DEFSUBR (Fwindow_memory_usage); 5348 DEFSUBR (Fwindow_memory_usage);
6365 #endif 5349 #endif
6366 DEFSUBR (Fwindow_configuration_p);
6367 DEFSUBR (Fset_window_configuration);
6368 DEFSUBR (Fcurrent_window_configuration);
6369 DEFSUBR (Fsave_window_excursion); 5350 DEFSUBR (Fsave_window_excursion);
6370 DEFSUBR (Fcurrent_pixel_column); 5351 DEFSUBR (Fcurrent_pixel_column);
6371 } 5352 }
6372 5353
6373 void 5354 void
6374 reinit_vars_of_window (void) 5355 reinit_vars_of_window (void)
6375 { 5356 {
6376 int i;
6377 /* Make sure all windows get marked */ 5357 /* Make sure all windows get marked */
6378 minibuf_window = Qnil; 5358 minibuf_window = Qnil;
6379 staticpro_nodump (&minibuf_window); 5359 staticpro_nodump (&minibuf_window);
6380
6381 for (i = 0; i < countof (Vwindow_configuration_free_list); i++)
6382 {
6383 Vwindow_configuration_free_list[i] =
6384 make_lcrecord_list (sizeof_window_config_for_n_windows (i + 1),
6385 &lrecord_window_configuration);
6386 staticpro_nodump (&Vwindow_configuration_free_list[i]);
6387 }
6388 } 5360 }
6389 5361
6390 void 5362 void
6391 vars_of_window (void) 5363 vars_of_window (void)
6392 { 5364 {
6394 5366
6395 DEFVAR_BOOL ("scroll-on-clipped-lines", &scroll_on_clipped_lines /* 5367 DEFVAR_BOOL ("scroll-on-clipped-lines", &scroll_on_clipped_lines /*
6396 *Non-nil means to scroll if point lands on a line which is clipped. 5368 *Non-nil means to scroll if point lands on a line which is clipped.
6397 */ ); 5369 */ );
6398 scroll_on_clipped_lines = 1; 5370 scroll_on_clipped_lines = 1;
6399
6400 DEFVAR_LISP ("temp-buffer-show-hook", &Vtemp_buffer_show_hook /*
6401 See `temp-buffer-show-function'.
6402 */ );
6403 Vtemp_buffer_show_hook = Qnil;
6404 5371
6405 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function /* 5372 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function /*
6406 Non-nil means call as function to display a help buffer. 5373 Non-nil means call as function to display a help buffer.
6407 The function is called with one argument, the buffer to be displayed. 5374 The function is called with one argument, the buffer to be displayed.
6408 Used by `with-output-to-temp-buffer'. 5375 Used by `with-output-to-temp-buffer'.