comparison src/window.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents de805c49cfc1
children da8ed4261e83
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
36 #include "glyphs.h" 36 #include "glyphs.h"
37 #include "redisplay.h" 37 #include "redisplay.h"
38 #include "window.h" 38 #include "window.h"
39 #include "elhash.h" 39 #include "elhash.h"
40 #include "commands.h" 40 #include "commands.h"
41 #include "gutter.h"
42 41
43 Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configurationp; 42 Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configurationp;
44 Lisp_Object Qdisplay_buffer; 43 Lisp_Object Qscroll_up, Qscroll_down, Qdisplay_buffer;
45 44
46 #ifdef MEMORY_USAGE_STATS 45 #ifdef MEMORY_USAGE_STATS
47 Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qother_redisplay; 46 Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qother_redisplay;
48 #ifdef HAVE_SCROLLBARS 47 #ifdef HAVE_SCROLLBARS
49 Lisp_Object Qscrollbar_instances; 48 Lisp_Object Qscrollbar_instances;
83 Lisp_Object Vvertical_divider_line_width; 82 Lisp_Object Vvertical_divider_line_width;
84 83
85 /* Spacing between outer egde of divider border and window edge */ 84 /* Spacing between outer egde of divider border and window edge */
86 Lisp_Object Vvertical_divider_spacing; 85 Lisp_Object Vvertical_divider_spacing;
87 86
88 /* How much to scroll by per-line. */
89 Lisp_Object Vwindow_pixel_scroll_increment;
90
91 /* Scroll if point lands on the bottom line and that line is partially 87 /* Scroll if point lands on the bottom line and that line is partially
92 clipped. */ 88 clipped. */
93 int scroll_on_clipped_lines; 89 int scroll_on_clipped_lines;
94 90
95 /* The minibuffer window of the selected frame. 91 /* The minibuffer window of the selected frame.
119 115
120 /* Number of lines of continuity in scrolling by screenfuls. */ 116 /* Number of lines of continuity in scrolling by screenfuls. */
121 int next_screen_context_lines; 117 int next_screen_context_lines;
122 118
123 /* List of freed window configurations with 1 - 10 windows. */ 119 /* List of freed window configurations with 1 - 10 windows. */
124 static Lisp_Object Vwindow_configuration_free_list[10]; 120 Lisp_Object Vwindow_configuration_free_list[10];
125 121
126 #define SET_LAST_MODIFIED(w, cache_too) \ 122 #define SET_LAST_MODIFIED(w, cache_too) \
127 do { \ 123 do { \
128 (w)->last_modified[CURRENT_DISP] = Qzero; \ 124 (w)->last_modified[CURRENT_DISP] = Qzero; \
129 (w)->last_modified[DESIRED_DISP] = Qzero; \ 125 (w)->last_modified[DESIRED_DISP] = Qzero; \
139 (w)->last_facechange[CMOTION_DISP] = Qzero; \ 135 (w)->last_facechange[CMOTION_DISP] = Qzero; \
140 } while (0) 136 } while (0)
141 137
142 138
143 #define MARK_DISP_VARIABLE(field) \ 139 #define MARK_DISP_VARIABLE(field) \
144 mark_object (window->field[CURRENT_DISP]); \ 140 markobj (window->field[CURRENT_DISP]); \
145 mark_object (window->field[DESIRED_DISP]); \ 141 markobj (window->field[DESIRED_DISP]); \
146 mark_object (window->field[CMOTION_DISP]); 142 markobj (window->field[CMOTION_DISP]);
147 143
148 static Lisp_Object 144 static Lisp_Object
149 mark_window (Lisp_Object obj) 145 mark_window (Lisp_Object obj, void (*markobj) (Lisp_Object))
150 { 146 {
151 struct window *window = XWINDOW (obj); 147 struct window *window = XWINDOW (obj);
152 mark_object (window->frame); 148 markobj (window->frame);
153 mark_object (window->mini_p); 149 markobj (window->mini_p);
154 mark_object (window->next); 150 markobj (window->next);
155 mark_object (window->prev); 151 markobj (window->prev);
156 mark_object (window->hchild); 152 markobj (window->hchild);
157 mark_object (window->vchild); 153 markobj (window->vchild);
158 mark_object (window->parent); 154 markobj (window->parent);
159 mark_object (window->buffer); 155 markobj (window->buffer);
160 MARK_DISP_VARIABLE (start); 156 MARK_DISP_VARIABLE (start);
161 MARK_DISP_VARIABLE (pointm); 157 MARK_DISP_VARIABLE (pointm);
162 mark_object (window->sb_point); /* #### move to scrollbar.c? */ 158 markobj (window->sb_point); /* #### move to scrollbar.c? */
163 mark_object (window->use_time); 159 markobj (window->use_time);
164 MARK_DISP_VARIABLE (last_modified); 160 MARK_DISP_VARIABLE (last_modified);
165 MARK_DISP_VARIABLE (last_point); 161 MARK_DISP_VARIABLE (last_point);
166 MARK_DISP_VARIABLE (last_start); 162 MARK_DISP_VARIABLE (last_start);
167 MARK_DISP_VARIABLE (last_facechange); 163 MARK_DISP_VARIABLE (last_facechange);
168 mark_object (window->line_cache_last_updated); 164 markobj (window->line_cache_last_updated);
169 mark_object (window->redisplay_end_trigger); 165 markobj (window->redisplay_end_trigger);
170 mark_object (window->subwindow_instance_cache); 166 markobj (window->subwindow_instance_cache);
171 167
172 mark_face_cachels (window->face_cachels); 168 mark_face_cachels (window->face_cachels, markobj);
173 mark_glyph_cachels (window->glyph_cachels); 169 mark_glyph_cachels (window->glyph_cachels, markobj);
174 170
175 #define WINDOW_SLOT(slot, compare) mark_object (window->slot) 171 #define WINDOW_SLOT(slot, compare) ((void) (markobj (window->slot)))
176 #include "winslots.h" 172 #include "winslots.h"
177 173
178 return Qnil; 174 return Qnil;
179 } 175 }
180 176
233 } 229 }
234 } 230 }
235 231
236 DEFINE_LRECORD_IMPLEMENTATION ("window", window, 232 DEFINE_LRECORD_IMPLEMENTATION ("window", window,
237 mark_window, print_window, finalize_window, 233 mark_window, print_window, finalize_window,
238 0, 0, 0, struct window); 234 0, 0, struct window);
239 235
240 236
241 #define INIT_DISP_VARIABLE(field, initialization) \ 237 #define INIT_DISP_VARIABLE(field, initialization) \
242 p->field[CURRENT_DISP] = initialization; \ 238 p->field[CURRENT_DISP] = initialization; \
243 p->field[DESIRED_DISP] = initialization; \ 239 p->field[DESIRED_DISP] = initialization; \
279 INIT_DISP_VARIABLE (last_start, Fmake_marker ()); 275 INIT_DISP_VARIABLE (last_start, Fmake_marker ());
280 INIT_DISP_VARIABLE (last_facechange, Qzero); 276 INIT_DISP_VARIABLE (last_facechange, Qzero);
281 p->face_cachels = Dynarr_new (face_cachel); 277 p->face_cachels = Dynarr_new (face_cachel);
282 p->glyph_cachels = Dynarr_new (glyph_cachel); 278 p->glyph_cachels = Dynarr_new (glyph_cachel);
283 p->line_start_cache = Dynarr_new (line_start_cache); 279 p->line_start_cache = Dynarr_new (line_start_cache);
284 p->subwindow_instance_cache = make_lisp_hash_table (30, 280 p->subwindow_instance_cache = make_lisp_hash_table (10,
285 HASH_TABLE_KEY_VALUE_WEAK, 281 HASH_TABLE_KEY_WEAK,
286 HASH_TABLE_EQUAL); 282 HASH_TABLE_EQ);
287 p->line_cache_last_updated = Qzero; 283 p->line_cache_last_updated = Qzero;
288 INIT_DISP_VARIABLE (last_point_x, 0); 284 INIT_DISP_VARIABLE (last_point_x, 0);
289 INIT_DISP_VARIABLE (last_point_y, 0); 285 INIT_DISP_VARIABLE (last_point_y, 0);
290 INIT_DISP_VARIABLE (window_end_pos, 0); 286 INIT_DISP_VARIABLE (window_end_pos, 0);
291 p->redisplay_end_trigger = Qnil; 287 p->redisplay_end_trigger = Qnil;
292
293 p->gutter_extent_modiff[0] = 0;
294 p->gutter_extent_modiff[1] = 0;
295 p->gutter_extent_modiff[2] = 0;
296 p->gutter_extent_modiff[3] = 0;
297 288
298 #define WINDOW_SLOT(slot, compare) p->slot = Qnil 289 #define WINDOW_SLOT(slot, compare) p->slot = Qnil
299 #include "winslots.h" 290 #include "winslots.h"
300 291
301 p->windows_changed = 1; 292 p->windows_changed = 1;
648 window_full_width_p (struct window *w) 639 window_full_width_p (struct window *w)
649 { 640 {
650 return window_is_leftmost (w) && window_is_rightmost (w); 641 return window_is_leftmost (w) && window_is_rightmost (w);
651 } 642 }
652 643
653 int 644 static int
654 window_is_highest (struct window *w) 645 window_is_highest (struct window *w)
655 { 646 {
656 Lisp_Object parent, current_ancestor, window; 647 Lisp_Object parent, current_ancestor, window;
657 648
658 XSETWINDOW (window, w); 649 XSETWINDOW (window, w);
676 return 1; 667 return 1;
677 else 668 else
678 return 0; 669 return 0;
679 } 670 }
680 671
681 int 672 static int
682 window_is_lowest (struct window *w) 673 window_is_lowest (struct window *w)
683 { 674 {
684 Lisp_Object parent, current_ancestor, window; 675 Lisp_Object parent, current_ancestor, window;
685 676
686 XSETWINDOW (window, w); 677 XSETWINDOW (window, w);
712 #endif 703 #endif
713 704
714 int 705 int
715 window_truncation_on (struct window *w) 706 window_truncation_on (struct window *w)
716 { 707 {
717 /* Minibuffer windows are never truncated.
718 #### is this the right way ? */
719 if (MINI_WINDOW_P (w))
720 return 0;
721
722 /* Horizontally scrolled windows are truncated. */ 708 /* Horizontally scrolled windows are truncated. */
723 if (w->hscroll) 709 if (w->hscroll)
724 return 1; 710 return 1;
725 711
726 /* If truncate_partial_width_windows is true and the window is not 712 /* If truncate_partial_width_windows is true and the window is not
734 if (!NILP (XBUFFER (w->buffer)->truncate_lines)) 720 if (!NILP (XBUFFER (w->buffer)->truncate_lines))
735 return 1; 721 return 1;
736 722
737 return 0; 723 return 0;
738 } 724 }
739
740 DEFUN ("window-truncated-p", Fwindow_truncated_p, 0, 1, 0, /*
741 Returns non-nil if text in the window is truncated.
742 */
743 (window))
744 {
745 struct window *w = decode_window (window);
746
747 return window_truncation_on (w) ? Qt : Qnil;
748 }
749
750 725
751 static int 726 static int
752 have_undivided_common_edge (struct window *w_right, void *closure) 727 have_undivided_common_edge (struct window *w_right, void *closure)
753 { 728 {
754 struct window *w_left = (struct window *) closure; 729 struct window *w_left = (struct window *) closure;
995 window_right_margin_width (struct window *w) 970 window_right_margin_width (struct window *w)
996 { 971 {
997 return margin_width_internal (w, 0); 972 return margin_width_internal (w, 0);
998 } 973 }
999 974
975 static int
976 window_top_toolbar_height (struct window *w)
977 {
978 /* #### implement this shit. */
979 return 0;
980 }
981
982 /* #### Currently used in scrollbar.c. Does it actually need to be? */
983 int
984 window_bottom_toolbar_height (struct window *w)
985 {
986 return 0;
987 }
988
989 static int
990 window_left_toolbar_width (struct window *w)
991 {
992 return 0;
993 }
994
995 static int
996 window_right_toolbar_width (struct window *w)
997 {
998 return 0;
999 }
1000
1000 /***************************************************************************** 1001 /*****************************************************************************
1001 Window Gutters 1002 Window Gutters
1002 1003
1003 The gutters of a window are those areas in the boundary defined by 1004 The gutters of a window are those areas in the boundary defined by
1004 w->pixel_top, w->pixel_left, w->pixel_height and w->pixel_width which 1005 w->pixel_top, w->pixel_left, w->pixel_height and w->pixel_width which
1013 functions refer to the Y coord for bottom and top gutters and the X 1014 functions refer to the Y coord for bottom and top gutters and the X
1014 coord for left and right gutters. All starting positions are 1015 coord for left and right gutters. All starting positions are
1015 relative to the frame, not the window. 1016 relative to the frame, not the window.
1016 ****************************************************************************/ 1017 ****************************************************************************/
1017 1018
1018 static int 1019 int
1019 window_top_window_gutter_height (struct window *w) 1020 window_top_gutter_height (struct window *w)
1020 { 1021 {
1022 int toolbar_height = window_top_toolbar_height (w);
1023
1021 if (!NILP (w->hchild) || !NILP (w->vchild)) 1024 if (!NILP (w->hchild) || !NILP (w->vchild))
1022 return 0; 1025 return 0;
1023 1026
1024 #ifdef HAVE_SCROLLBARS 1027 #ifdef HAVE_SCROLLBARS
1025 if (!NILP (w->scrollbar_on_top_p)) 1028 if (!NILP (w->scrollbar_on_top_p))
1026 return window_scrollbar_height (w); 1029 return window_scrollbar_height (w) + toolbar_height;
1027 else 1030 else
1028 #endif 1031 #endif
1029 return 0; 1032 return toolbar_height;
1030 } 1033 }
1031 1034
1032 int 1035 int
1033 window_top_gutter_height (struct window *w) 1036 window_bottom_gutter_height (struct window *w)
1034 { 1037 {
1035 return window_top_window_gutter_height (w); 1038 int other_height;
1036 }
1037
1038 static int
1039 window_bottom_window_gutter_height (struct window *w)
1040 {
1041 int gutter;
1042 1039
1043 if (!NILP (w->hchild) || !NILP (w->vchild)) 1040 if (!NILP (w->hchild) || !NILP (w->vchild))
1044 return 0; 1041 return 0;
1045 1042 else
1046 gutter = window_modeline_height (w); 1043 other_height =
1044 window_modeline_height (w) + window_bottom_toolbar_height (w);
1047 1045
1048 #ifdef HAVE_SCROLLBARS 1046 #ifdef HAVE_SCROLLBARS
1049 if (NILP (w->scrollbar_on_top_p)) 1047 if (NILP (w->scrollbar_on_top_p))
1050 return window_scrollbar_height (w) + gutter; 1048 return window_scrollbar_height (w) + other_height;
1051 else 1049 else
1052 #endif 1050 #endif
1053 return gutter; 1051 return other_height;
1054 } 1052 }
1055 1053
1056 int 1054 int
1057 window_bottom_gutter_height (struct window *w) 1055 window_left_gutter_width (struct window *w, int modeline)
1058 { 1056 {
1059 return window_bottom_window_gutter_height (w); 1057 int gutter = window_left_toolbar_width (w);
1060 } 1058
1061
1062 static int
1063 window_left_window_gutter_width (struct window *w, int modeline)
1064 {
1065 if (!NILP (w->hchild) || !NILP (w->vchild)) 1059 if (!NILP (w->hchild) || !NILP (w->vchild))
1066 return 0; 1060 return 0;
1067 1061
1062
1068 #ifdef HAVE_SCROLLBARS 1063 #ifdef HAVE_SCROLLBARS
1069 if (!modeline && !NILP (w->scrollbar_on_left_p)) 1064 if (!modeline && !NILP (w->scrollbar_on_left_p))
1070 return window_scrollbar_width (w); 1065 gutter += window_scrollbar_width (w);
1071 #endif 1066 #endif
1072 1067
1073 return 0; 1068 return gutter;
1074 } 1069 }
1075 1070
1076 int 1071 int
1077 window_left_gutter_width (struct window *w, int modeline) 1072 window_right_gutter_width (struct window *w, int modeline)
1078 { 1073 {
1079 return window_left_window_gutter_width (w, modeline); 1074 int gutter = window_right_toolbar_width (w);
1080 }
1081
1082 static int
1083 window_right_window_gutter_width (struct window *w, int modeline)
1084 {
1085 int gutter = 0;
1086 1075
1087 if (!NILP (w->hchild) || !NILP (w->vchild)) 1076 if (!NILP (w->hchild) || !NILP (w->vchild))
1088 return 0; 1077 return 0;
1089 1078
1090 #ifdef HAVE_SCROLLBARS 1079 #ifdef HAVE_SCROLLBARS
1094 1083
1095 if (window_needs_vertical_divider (w)) 1084 if (window_needs_vertical_divider (w))
1096 gutter += window_divider_width (w); 1085 gutter += window_divider_width (w);
1097 1086
1098 return gutter; 1087 return gutter;
1099 }
1100
1101 int
1102 window_right_gutter_width (struct window *w, int modeline)
1103 {
1104 return window_right_window_gutter_width (w, modeline);
1105 }
1106
1107 static int
1108 window_pixel_height (struct window* w)
1109 {
1110 return WINDOW_HEIGHT (w);
1111 } 1088 }
1112 1089
1113 1090
1114 DEFUN ("windowp", Fwindowp, 1, 1, 0, /* 1091 DEFUN ("windowp", Fwindowp, 1, 1, 0, /*
1115 Return t if OBJ is a window. 1092 Return t if OBJ is a window.
1144 struct frame *f = decode_frame_or_selected (con_dev_or_frame); 1121 struct frame *f = decode_frame_or_selected (con_dev_or_frame);
1145 return FRAME_SELECTED_WINDOW (f); 1122 return FRAME_SELECTED_WINDOW (f);
1146 } 1123 }
1147 } 1124 }
1148 1125
1149 DEFUN ("last-nonminibuf-window", Flast_nonminibuf_window, 0, 1, 0, /*
1150 Return the last selected window that is not a minibuffer window.
1151 If the optional argument CON-DEV-OR-FRAME is specified and is a frame,
1152 return the last non-minibuffer window used by that frame. If
1153 CON-DEV-OR-FRAME is a device, then the selected frame on that device
1154 will be used. If CON-DEV-OR-FRAME is a console, the selected frame on
1155 that console's selected device will be used. Otherwise, the selected
1156 frame is used.
1157 */
1158 (con_dev_or_frame))
1159 {
1160 if (NILP (con_dev_or_frame) && NILP (Fselected_device (Qnil)))
1161 return Qnil; /* happens at startup */
1162
1163 {
1164 struct frame *f = decode_frame_or_selected (con_dev_or_frame);
1165 return FRAME_LAST_NONMINIBUF_WINDOW (f);
1166 }
1167 }
1168
1169 DEFUN ("minibuffer-window", Fminibuffer_window, 0, 1, 0, /* 1126 DEFUN ("minibuffer-window", Fminibuffer_window, 0, 1, 0, /*
1170 Return the window used now for minibuffers. 1127 Return the window used now for minibuffers.
1171 If the optional argument CON-DEV-OR-FRAME is specified and is a frame, return 1128 If the optional argument CON-DEV-OR-FRAME is specified and is a frame, return
1172 the minibuffer window used by that frame. If CON-DEV-OR-FRAME is a device, 1129 the minibuffer window used by that frame. If CON-DEV-OR-FRAME is a device,
1173 then the selected frame on that device will be used. If CON-DEV-OR-FRAME 1130 then the selected frame on that device will be used. If CON-DEV-OR-FRAME
1177 (con_dev_or_frame)) 1134 (con_dev_or_frame))
1178 { 1135 {
1179 return FRAME_MINIBUF_WINDOW (decode_frame_or_selected (con_dev_or_frame)); 1136 return FRAME_MINIBUF_WINDOW (decode_frame_or_selected (con_dev_or_frame));
1180 } 1137 }
1181 1138
1182 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, 0, 1, 0, /* 1139 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, 1, 1, 0, /*
1183 Return non-nil if WINDOW is a minibuffer window. 1140 Return non-nil if WINDOW is a minibuffer window.
1184 */ 1141 */
1185 (window)) 1142 (window))
1186 { 1143 {
1187 return MINI_WINDOW_P (decode_window (window)) ? Qt : Qnil; 1144 return MINI_WINDOW_P (decode_window (window)) ? Qt : Qnil;
1323 default font; therefore, the number of displayed lines will probably 1280 default font; therefore, the number of displayed lines will probably
1324 be different. 1281 be different.
1325 Use `window-height' to get consistent results in geometry calculations. 1282 Use `window-height' to get consistent results in geometry calculations.
1326 Use `window-displayed-height' to get the actual number of lines 1283 Use `window-displayed-height' to get the actual number of lines
1327 currently displayed in a window. 1284 currently displayed in a window.
1328
1329 The names are somewhat confusing; here's a table to help out:
1330
1331 width height
1332 -------------------------------------------------------------------------
1333 w/o gutters
1334 (rows/columns) window-width window-text-area-height
1335 (pixels) window-text-area-pixel-width window-text-area-pixel-height
1336
1337 with gutters
1338 (rows/columns) window-full-width window-height
1339 (pixels) window-pixel-width window-pixel-height
1340
1341 actually displayed
1342 (rows/columns) ---- window-displayed-height
1343 (pixels) ---- window-displayed-text-pixel-height
1344 */ 1285 */
1345 (window)) 1286 (window))
1346 { 1287 {
1347 return make_int (window_char_height (decode_window (window), 1)); 1288 return make_int (window_char_height (decode_window (window), 1));
1348 } 1289 }
1365 Return the height of WINDOW in pixels. Defaults to current window. 1306 Return the height of WINDOW in pixels. Defaults to current window.
1366 This includes the window's modeline and horizontal scrollbar (if any). 1307 This includes the window's modeline and horizontal scrollbar (if any).
1367 */ 1308 */
1368 (window)) 1309 (window))
1369 { 1310 {
1370 return make_int (window_pixel_height (decode_window (window))); 1311 return make_int (decode_window (window)->pixel_height);
1371 }
1372
1373 DEFUN ("window-text-area-height", Fwindow_text_area_height, 0, 1, 0, /*
1374 Return the number of default lines in the text area of WINDOW.
1375 This actually works by dividing the window's text area pixel height (i.e.
1376 excluding the modeline and horizontal scrollbar, if any) by the height of the
1377 default font; therefore, the number of displayed lines will probably
1378 be different.
1379 See also `window-height' and `window-displayed-height'.
1380 */
1381 (window))
1382 {
1383 return make_int (window_char_height (decode_window (window), 0));
1384 } 1312 }
1385 1313
1386 DEFUN ("window-text-area-pixel-height", 1314 DEFUN ("window-text-area-pixel-height",
1387 Fwindow_text_area_pixel_height, 0, 1, 0, /* 1315 Fwindow_text_area_pixel_height, 0, 1, 0, /*
1388 Return the height in pixels of the text-displaying portion of WINDOW. 1316 Return the height in pixels of the text-displaying portion of WINDOW.
1415 line_start_cache_dynarr *cache; 1343 line_start_cache_dynarr *cache;
1416 1344
1417 if (NILP (window)) 1345 if (NILP (window))
1418 window = Fselected_window (Qnil); 1346 window = Fselected_window (Qnil);
1419 1347
1420 CHECK_LIVE_WINDOW (window); 1348 CHECK_WINDOW (window);
1421 w = XWINDOW (window); 1349 w = XWINDOW (window);
1422 1350
1423 start = marker_position (w->start[CURRENT_DISP]); 1351 start = marker_position (w->start[CURRENT_DISP]);
1424 hlimit = WINDOW_TEXT_HEIGHT (w); 1352 hlimit = WINDOW_TEXT_HEIGHT (w);
1425 eobuf = BUF_ZV (XBUFFER (w->buffer)); 1353 eobuf = BUF_ZV (XBUFFER (w->buffer));
1459 RETURN_NOT_REACHED(make_int (0)) /* shut up compiler */ 1387 RETURN_NOT_REACHED(make_int (0)) /* shut up compiler */
1460 } 1388 }
1461 1389
1462 DEFUN ("window-width", Fwindow_width, 0, 1, 0, /* 1390 DEFUN ("window-width", Fwindow_width, 0, 1, 0, /*
1463 Return the number of display columns in WINDOW. 1391 Return the number of display columns in WINDOW.
1464 This is the width that is usable columns available for text in WINDOW, 1392 This is the width that is usable columns available for text in WINDOW.
1465 and does not include vertical scrollbars, dividers, or the like. See also
1466 `window-full-width' and `window-height'.
1467 */ 1393 */
1468 (window)) 1394 (window))
1469 { 1395 {
1470 return make_int (window_char_width (decode_window (window), 0)); 1396 return make_int (window_char_width (decode_window (window), 0));
1471 }
1472
1473 DEFUN ("window-full-width", Fwindow_full_width, 0, 1, 0, /*
1474 Return the total number of columns in WINDOW.
1475 This is like `window-width' but includes vertical scrollbars, dividers,
1476 etc.
1477 */
1478 (window))
1479 {
1480 return make_int (window_char_width (decode_window (window), 1));
1481 } 1397 }
1482 1398
1483 DEFUN ("window-pixel-width", Fwindow_pixel_width, 0, 1, 0, /* 1399 DEFUN ("window-pixel-width", Fwindow_pixel_width, 0, 1, 0, /*
1484 Return the width of WINDOW in pixels. Defaults to current window. 1400 Return the width of WINDOW in pixels. Defaults to current window.
1485 */ 1401 */
1507 (window)) 1423 (window))
1508 { 1424 {
1509 return make_int (decode_window (window)->hscroll); 1425 return make_int (decode_window (window)->hscroll);
1510 } 1426 }
1511 1427
1428 #ifdef MODELINE_IS_SCROLLABLE
1512 DEFUN ("modeline-hscroll", Fmodeline_hscroll, 0, 1, 0, /* 1429 DEFUN ("modeline-hscroll", Fmodeline_hscroll, 0, 1, 0, /*
1513 Return the horizontal scrolling ammount of WINDOW's modeline. 1430 Return the number of columns by which WINDOW's modeline is scrolled from
1514 If the window has no modeline, return nil. 1431 left margin. If the window has no modeline, return nil.
1515 */ 1432 */
1516 (window)) 1433 (window))
1517 { 1434 {
1518 struct window *w = decode_window (window); 1435 struct window *w = decode_window (window);
1519 1436
1520 return (WINDOW_HAS_MODELINE_P (w)) ? make_int ((int) w->modeline_hscroll) : 1437 return (WINDOW_HAS_MODELINE_P (w)) ? make_int (w->modeline_hscroll) : Qnil;
1521 Qnil;
1522 } 1438 }
1523 1439
1524 DEFUN ("set-modeline-hscroll", Fset_modeline_hscroll, 2, 2, 0, /* 1440 DEFUN ("set-modeline-hscroll", Fset_modeline_hscroll, 2, 2, 0, /*
1525 Set the horizontal scrolling ammount of WINDOW's modeline to NCOL. 1441 Set number of columns WINDOW's modeline is scrolled from left margin to NCOL.
1526 If NCOL is negative, it will silently be forced to 0. 1442 NCOL should be zero or positive. If NCOL is negative, it will be forced to 0.
1527 If the window has no modeline, return nil. Otherwise, return the actual 1443 If the window has no modeline, do nothing and return nil.
1528 value that was set.
1529 */ 1444 */
1530 (window, ncol)) 1445 (window, ncol))
1531 { 1446 {
1532 struct window *w = decode_window (window); 1447 struct window *w = decode_window (window);
1533 1448
1534 if (WINDOW_HAS_MODELINE_P (w)) 1449 if (WINDOW_HAS_MODELINE_P (w))
1535 { 1450 {
1536 Charcount ncols; 1451 int ncols;
1537
1538 CHECK_INT (ncol); 1452 CHECK_INT (ncol);
1539 ncols = (XINT (ncol) <= 0) ? 0 : (Charcount) XINT (ncol); 1453 ncols = XINT (ncol);
1540 if (ncols != w->modeline_hscroll) 1454 if (ncols < 0) ncols = 0;
1541 { 1455 if (w->modeline_hscroll != ncols)
1542 MARK_MODELINE_CHANGED; 1456 MARK_MODELINE_CHANGED;
1543 w->modeline_hscroll = ncols; 1457 w->modeline_hscroll = ncols;
1544 } 1458 return ncol;
1545 return make_int ((int) ncols); 1459 }
1546 }
1547
1548 return Qnil; 1460 return Qnil;
1549 } 1461 }
1462 #endif /* MODELINE_IS_SCROLLABLE */
1550 1463
1551 DEFUN ("set-window-hscroll", Fset_window_hscroll, 2, 2, 0, /* 1464 DEFUN ("set-window-hscroll", Fset_window_hscroll, 2, 2, 0, /*
1552 Set number of columns WINDOW is scrolled from left margin to NCOL. 1465 Set number of columns WINDOW is scrolled from left margin to NCOL.
1553 NCOL should be zero or positive. 1466 NCOL should be zero or positive.
1554 */ 1467 */
1596 #endif /* 0 */ 1509 #endif /* 0 */
1597 1510
1598 DEFUN ("window-pixel-edges", Fwindow_pixel_edges, 0, 1, 0, /* 1511 DEFUN ("window-pixel-edges", Fwindow_pixel_edges, 0, 1, 0, /*
1599 Return a list of the pixel edge coordinates of WINDOW. 1512 Return a list of the pixel edge coordinates of WINDOW.
1600 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame. 1513 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.
1601 The frame toolbars, menubars and gutters are considered to be outside of this area. 1514 The frame toolbars and menubars are considered to be outside of this area.
1602 */ 1515 */
1603 (window)) 1516 (window))
1604 { 1517 {
1605 struct window *w = decode_window (window); 1518 struct window *w = decode_window (window);
1606 1519 struct frame *f = XFRAME (w->frame);
1607 int left = w->pixel_left; 1520
1608 int top = w->pixel_top; 1521 int left = w->pixel_left - FRAME_LEFT_BORDER_END (f);
1522 int top = w->pixel_top - FRAME_TOP_BORDER_END (f);
1609 1523
1610 return list4 (make_int (left), 1524 return list4 (make_int (left),
1611 make_int (top), 1525 make_int (top),
1612 make_int (left + w->pixel_width), 1526 make_int (left + w->pixel_width),
1613 make_int (top + w->pixel_height)); 1527 make_int (top + w->pixel_height));
1690 else 1604 else
1691 { 1605 {
1692 Bufpos startp = marker_position (w->start[CURRENT_DISP]); 1606 Bufpos startp = marker_position (w->start[CURRENT_DISP]);
1693 return make_int (end_of_last_line (w, startp)); 1607 return make_int (end_of_last_line (w, startp));
1694 } 1608 }
1695 }
1696
1697 DEFUN ("window-last-line-visible-height", Fwindow_last_line_visible_height, 0, 1, 0, /*
1698 Return pixel height of visible part of last window line if it is clipped.
1699 If the last line is not clipped, return nil.
1700 */
1701 (window))
1702 {
1703 struct window *w = decode_window (window);
1704 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
1705 int num_lines = Dynarr_length (dla);
1706 struct display_line *dl;
1707
1708 /* No lines - no clipped lines */
1709 if (num_lines == 0 || (num_lines == 1 && Dynarr_atp (dla, 0)->modeline))
1710 return Qnil;
1711
1712 dl = Dynarr_atp (dla, num_lines - 1);
1713 if (dl->clip == 0)
1714 return Qnil;
1715
1716 return make_int (dl->ascent + dl->descent - dl->clip);
1717 } 1609 }
1718 1610
1719 DEFUN ("set-window-point", Fset_window_point, 2, 2, 0, /* 1611 DEFUN ("set-window-point", Fset_window_point, 2, 2, 0, /*
1720 Make point value in WINDOW be at position POS in WINDOW's buffer. 1612 Make point value in WINDOW be at position POS in WINDOW's buffer.
1721 */ 1613 */
1865 } 1757 }
1866 1758
1867 /* #### Here, if replacement is a vertical combination 1759 /* #### Here, if replacement is a vertical combination
1868 and so is its new parent, we should make replacement's 1760 and so is its new parent, we should make replacement's
1869 children be children of that parent instead. */ 1761 children be children of that parent instead. */
1870
1871 ERROR_CHECK_SUBWINDOW_CACHE (p);
1872 }
1873
1874 static int
1875 window_unmap_subwindows_cache_mapper (Lisp_Object key, Lisp_Object value,
1876 void *flag_closure)
1877 {
1878 /* value can be nil; we cache failures as well as successes */
1879 if (!NILP (value))
1880 {
1881 struct frame* f = XFRAME (XIMAGE_INSTANCE_FRAME (value));
1882 unmap_subwindow (value);
1883 /* In case GC doesn't catch up fast enough, remove from the frame
1884 cache also. Otherwise code that checks the sanity of the instance
1885 will fail. */
1886 XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))
1887 = delq_no_quit (value, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)));
1888 }
1889 return 0;
1890 }
1891
1892 static void
1893 window_unmap_subwindows (struct window* w)
1894 {
1895 assert (!NILP (w->subwindow_instance_cache));
1896 elisp_maphash (window_unmap_subwindows_cache_mapper,
1897 w->subwindow_instance_cache, 0);
1898 } 1762 }
1899 1763
1900 /* we're deleting W; set the structure of W to indicate this. */ 1764 /* we're deleting W; set the structure of W to indicate this. */
1901 1765
1902 static void 1766 static void
1903 mark_window_as_deleted (struct window *w) 1767 mark_window_as_deleted (struct window *w)
1904 { 1768 {
1905 /* The window instance cache is going away now, so need to get the
1906 cachels reset by redisplay. */
1907 MARK_FRAME_SUBWINDOWS_CHANGED (XFRAME (WINDOW_FRAME (w)));
1908
1909 /* The cache is going away. If we leave unmapping to
1910 reset_subwindow_cachels then we get in a situation where the
1911 domain (the window) has been deleted but we still need access to
1912 its attributes in order to unmap windows properly. Since the
1913 subwindows are going to get GC'd anyway as a result of the domain
1914 going away, it is safer to just unmap them all while we know the
1915 domain is still valid. */
1916 ERROR_CHECK_SUBWINDOW_CACHE (w);
1917 window_unmap_subwindows (w);
1918
1919 /* In the loop 1769 /* In the loop
1920 (while t (split-window) (delete-window)) 1770 (while t (split-window) (delete-window))
1921 we end up with a tree of deleted windows which are all connected 1771 we end up with a tree of deleted windows which are all connected
1922 through the `next' slot. This might not seem so bad, as they're 1772 through the `next' slot. This might not seem so bad, as they're
1923 deleted, and will presumably be GCed - but if even *one* of those 1773 deleted, and will presumably be GCed - but if even *one* of those
1925 configuration, then *all* of those windows stick around. 1775 configuration, then *all* of those windows stick around.
1926 1776
1927 Since the window-configuration code doesn't need any of the 1777 Since the window-configuration code doesn't need any of the
1928 pointers to other windows (they are all recreated from the 1778 pointers to other windows (they are all recreated from the
1929 window-config data), we set them all to nil so that we 1779 window-config data), we set them all to nil so that we
1930 are able to collect more actual garbage. */ 1780 are able to collect more actual garbage.
1781 */
1931 w->next = Qnil; 1782 w->next = Qnil;
1932 w->prev = Qnil; 1783 w->prev = Qnil;
1933 w->hchild = Qnil; 1784 w->hchild = Qnil;
1934 w->vchild = Qnil; 1785 w->vchild = Qnil;
1935 w->parent = Qnil; 1786 w->parent = Qnil;
1936 w->subwindow_instance_cache = Qnil;
1937 1787
1938 w->dead = 1; 1788 w->dead = 1;
1939 1789
1940 /* Free the extra data structures attached to windows immediately so 1790 /* Free the extra data structures attached to windows immediately so
1941 they don't sit around consuming excess space. They will be 1791 they don't sit around consuming excess space. They will be
1968 deleted window; it's OK to delete an already-deleted window. */ 1818 deleted window; it's OK to delete an already-deleted window. */
1969 if (NILP (window)) 1819 if (NILP (window))
1970 window = Fselected_window (Qnil); 1820 window = Fselected_window (Qnil);
1971 else 1821 else
1972 CHECK_WINDOW (window); 1822 CHECK_WINDOW (window);
1973
1974 w = XWINDOW (window); 1823 w = XWINDOW (window);
1975 1824
1976 /* It's okay to delete an already-deleted window. */ 1825 /* It's okay to delete an already-deleted window. */
1977 if (! WINDOW_LIVE_P (w)) 1826 if (! WINDOW_LIVE_P (w))
1978 return Qnil; 1827 return Qnil;
2002 /* At this point, we know the window has a parent. */ 1851 /* At this point, we know the window has a parent. */
2003 parent = w->parent; 1852 parent = w->parent;
2004 par = XWINDOW (parent); 1853 par = XWINDOW (parent);
2005 1854
2006 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f); 1855 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
2007 /* It's quite likely that deleting a window will result in
2008 subwindows needing to be deleted also (since they are cached
2009 per-window). So we mark them as changed, so that the cachels will
2010 get reset by redisplay and thus deleted subwindows can get
2011 GC'd. */
2012 MARK_FRAME_SUBWINDOWS_CHANGED (f);
2013 1856
2014 /* Are we trying to delete any frame's selected window? 1857 /* Are we trying to delete any frame's selected window?
2015 Note that we could be dealing with a non-leaf window 1858 Note that we could be dealing with a non-leaf window
2016 where the selected window is one of our children. 1859 where the selected window is one of our children.
2017 So, we check by scanning all the ancestors of the 1860 So, we check by scanning all the ancestors of the
2739 { 2582 {
2740 Lisp_Object new_buffer; 2583 Lisp_Object new_buffer;
2741 new_buffer = Fother_buffer (obj, Qnil, Qnil); 2584 new_buffer = Fother_buffer (obj, Qnil, Qnil);
2742 if (NILP (new_buffer)) 2585 if (NILP (new_buffer))
2743 new_buffer = Fget_buffer_create (QSscratch); 2586 new_buffer = Fget_buffer_create (QSscratch);
2744 Fset_window_buffer (w, new_buffer, Qnil); 2587 Fset_window_buffer (w, new_buffer);
2745 if (EQ (w, Fselected_window (Qnil))) 2588 if (EQ (w, Fselected_window (Qnil)))
2746 Fset_buffer (p->buffer); 2589 Fset_buffer (p->buffer);
2747 } 2590 }
2748 else 2591 else
2749 Fdelete_window (w, Qnil); 2592 Fdelete_window (w, Qnil);
2811 else 2654 else
2812 { 2655 {
2813 /* Otherwise show a different buffer in the 2656 /* Otherwise show a different buffer in the
2814 window. */ 2657 window. */
2815 p->dedicated = Qnil; 2658 p->dedicated = Qnil;
2816 Fset_window_buffer (w, another_buffer, Qnil); 2659 Fset_window_buffer (w, another_buffer);
2817 if (EQ (w, Fselected_window (Qnil))) 2660 if (EQ (w, Fselected_window (Qnil)))
2818 Fset_buffer (p->buffer); 2661 Fset_buffer (p->buffer);
2819 } 2662 }
2820 } 2663 }
2821 break; 2664 break;
3112 window_min_width = MIN_SAFE_WINDOW_WIDTH; 2955 window_min_width = MIN_SAFE_WINDOW_WIDTH;
3113 if (window_min_height < MIN_SAFE_WINDOW_HEIGHT) 2956 if (window_min_height < MIN_SAFE_WINDOW_HEIGHT)
3114 window_min_height = MIN_SAFE_WINDOW_HEIGHT; 2957 window_min_height = MIN_SAFE_WINDOW_HEIGHT;
3115 } 2958 }
3116 2959
3117 static int
3118 frame_min_height (struct frame *frame)
3119 {
3120 /* For height, we have to see whether the frame has a minibuffer, and
3121 whether it wants a modeline. */
3122 return (FRAME_MINIBUF_ONLY_P (frame) ? MIN_SAFE_WINDOW_HEIGHT - 1
3123 : (! FRAME_HAS_MINIBUF_P (frame)) ? MIN_SAFE_WINDOW_HEIGHT
3124 : 2 * MIN_SAFE_WINDOW_HEIGHT - 1);
3125 }
3126
3127 /* Return non-zero if both frame sizes are less than or equal to
3128 minimal allowed values. ROWS and COLS are in characters */
3129 int
3130 frame_size_valid_p (struct frame *frame, int rows, int cols)
3131 {
3132 return (rows >= frame_min_height (frame)
3133 && cols >= MIN_SAFE_WINDOW_WIDTH);
3134 }
3135
3136 /* Return non-zero if both frame sizes are less than or equal to
3137 minimal allowed values. WIDTH and HEIGHT are in pixels */
3138 int
3139 frame_pixsize_valid_p (struct frame *frame, int width, int height)
3140 {
3141 int rows, cols;
3142 pixel_to_real_char_size (frame, width, height, &cols, &rows);
3143 return frame_size_valid_p (frame, rows, cols);
3144 }
3145
3146 /* If *ROWS or *COLS are too small a size for FRAME, set them to the 2960 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
3147 minimum allowable size. */ 2961 minimum allowable size. */
3148 void 2962 void
3149 check_frame_size (struct frame *frame, int *rows, int *cols) 2963 check_frame_size (struct frame *frame, int *rows, int *cols)
3150 { 2964 {
3151 int min_height = frame_min_height (frame); 2965 /* For height, we have to see whether the frame has a minibuffer, and
2966 whether it wants a modeline. */
2967 int min_height =
2968 (FRAME_MINIBUF_ONLY_P (frame) ? MIN_SAFE_WINDOW_HEIGHT - 1
2969 : (! FRAME_HAS_MINIBUF_P (frame)) ? MIN_SAFE_WINDOW_HEIGHT
2970 : 2 * MIN_SAFE_WINDOW_HEIGHT - 1);
3152 2971
3153 if (*rows < min_height) 2972 if (*rows < min_height)
3154 *rows = min_height; 2973 *rows = min_height;
3155 if (*cols < MIN_SAFE_WINDOW_WIDTH) 2974 if (*cols < MIN_SAFE_WINDOW_WIDTH)
3156 *cols = MIN_SAFE_WINDOW_WIDTH; 2975 *cols = MIN_SAFE_WINDOW_WIDTH;
3296 } 3115 }
3297 3116
3298 3117
3299 static int window_select_count; 3118 static int window_select_count;
3300 3119
3301 DEFUN ("set-window-buffer", Fset_window_buffer, 2, 3, 0, /* 3120 DEFUN ("set-window-buffer", Fset_window_buffer, 2, 2, 0, /*
3302 Make WINDOW display BUFFER as its contents. 3121 Make WINDOW display BUFFER as its contents.
3303 BUFFER can be a buffer or buffer name. 3122 BUFFER can be a buffer or buffer name.
3304 3123 */
3305 With non-nil optional argument `norecord', do not modify the 3124 (window, buffer))
3306 global or per-frame buffer ordering.
3307 */
3308 (window, buffer, norecord))
3309 { 3125 {
3310 Lisp_Object tem; 3126 Lisp_Object tem;
3311 struct window *w = decode_window (window); 3127 struct window *w = decode_window (window);
3312 3128
3313 buffer = Fget_buffer (buffer); 3129 buffer = Fget_buffer (buffer);
3362 SET_LAST_FACECHANGE (w); 3178 SET_LAST_FACECHANGE (w);
3363 MARK_WINDOWS_CHANGED (w); 3179 MARK_WINDOWS_CHANGED (w);
3364 recompute_all_cached_specifiers_in_window (w); 3180 recompute_all_cached_specifiers_in_window (w);
3365 if (EQ (window, Fselected_window (Qnil))) 3181 if (EQ (window, Fselected_window (Qnil)))
3366 { 3182 {
3367 if (NILP (norecord))
3368 Frecord_buffer (buffer);
3369
3370 Fset_buffer (buffer); 3183 Fset_buffer (buffer);
3371 } 3184 }
3372 return Qnil; 3185 return Qnil;
3373 } 3186 }
3374 3187
3389 w = XWINDOW (window); 3202 w = XWINDOW (window);
3390 3203
3391 /* we have already caught dead-window errors */ 3204 /* we have already caught dead-window errors */
3392 if (!NILP (w->hchild) || !NILP (w->vchild)) 3205 if (!NILP (w->hchild) || !NILP (w->vchild))
3393 error ("Trying to select non-leaf window"); 3206 error ("Trying to select non-leaf window");
3394 3207
3395 w->use_time = make_int (++window_select_count); 3208 w->use_time = make_int (++window_select_count);
3396
3397 if (EQ (window, old_selected_window)) 3209 if (EQ (window, old_selected_window))
3398 return window; 3210 return window;
3399 3211
3400 /* deselect the old window, if it exists (it might not exist if 3212 /* deselect the old window, if it exists (it might not exist if
3401 the selected device has no frames, which occurs at startup) */ 3213 the selected device has no frames, which occurs at startup) */
3515 /* Don't copy the pointers to the line start cache or the face 3327 /* Don't copy the pointers to the line start cache or the face
3516 instances. */ 3328 instances. */
3517 p->line_start_cache = Dynarr_new (line_start_cache); 3329 p->line_start_cache = Dynarr_new (line_start_cache);
3518 p->face_cachels = Dynarr_new (face_cachel); 3330 p->face_cachels = Dynarr_new (face_cachel);
3519 p->glyph_cachels = Dynarr_new (glyph_cachel); 3331 p->glyph_cachels = Dynarr_new (glyph_cachel);
3520 p->subwindow_instance_cache =
3521 make_lisp_hash_table (30,
3522 HASH_TABLE_KEY_VALUE_WEAK,
3523 HASH_TABLE_EQUAL);
3524 3332
3525 /* Put new into window structure in place of window */ 3333 /* Put new into window structure in place of window */
3526 replace_window (window, new); 3334 replace_window (window, new);
3527 3335
3528 o->next = Qnil; 3336 o->next = Qnil;
3556 int psize; 3364 int psize;
3557 3365
3558 if (NILP (window)) 3366 if (NILP (window))
3559 window = Fselected_window (Qnil); 3367 window = Fselected_window (Qnil);
3560 else 3368 else
3561 CHECK_LIVE_WINDOW (window); 3369 CHECK_WINDOW (window);
3562 3370
3563 o = XWINDOW (window); 3371 o = XWINDOW (window);
3564 f = XFRAME (WINDOW_FRAME (o)); 3372 f = XFRAME (WINDOW_FRAME (o));
3565 3373
3566 if (NILP (chsize)) 3374 if (NILP (chsize))
3672 3480
3673 XFRAME (p->frame)->mirror_dirty = 1; 3481 XFRAME (p->frame)->mirror_dirty = 1;
3674 /* do this last (after the window is completely initialized and 3482 /* do this last (after the window is completely initialized and
3675 the mirror-dirty flag is set) so that specifier recomputation 3483 the mirror-dirty flag is set) so that specifier recomputation
3676 caused as a result of this will work properly and not abort. */ 3484 caused as a result of this will work properly and not abort. */
3677 Fset_window_buffer (new, o->buffer, Qt); 3485 Fset_window_buffer (new, o->buffer);
3678 return new; 3486 return new;
3679 } 3487 }
3680 3488
3681 3489
3682 DEFUN ("enlarge-window", Fenlarge_window, 1, 3, "_p", /* 3490 DEFUN ("enlarge-window", Fenlarge_window, 1, 3, "_p", /*
3734 /* inpixels */ 1); 3542 /* inpixels */ 1);
3735 return Qnil; 3543 return Qnil;
3736 } 3544 }
3737 3545
3738 static int 3546 static int
3547 window_pixel_height (Lisp_Object window)
3548 {
3549 return WINDOW_HEIGHT (XWINDOW (window));
3550 }
3551
3552 static int
3739 window_pixel_height_to_char_height (struct window *w, int pixel_height, 3553 window_pixel_height_to_char_height (struct window *w, int pixel_height,
3740 int include_gutters_p) 3554 int include_gutters_p)
3741 { 3555 {
3742 int avail_height; 3556 int avail_height;
3743 int defheight, defwidth; 3557 int defheight, defwidth;
3746 3560
3747 XSETWINDOW (window, w); 3561 XSETWINDOW (window, w);
3748 3562
3749 avail_height = (pixel_height - 3563 avail_height = (pixel_height -
3750 (include_gutters_p ? 0 : 3564 (include_gutters_p ? 0 :
3751 window_top_window_gutter_height (w) + 3565 window_top_gutter_height (w) +
3752 window_bottom_window_gutter_height (w))); 3566 window_bottom_gutter_height (w)));
3753 3567
3754 default_face_height_and_width (window, &defheight, &defwidth); 3568 default_face_height_and_width (window, &defheight, &defwidth);
3755 3569
3756 char_height = avail_height / defheight; 3570 char_height = avail_height / defheight;
3757 3571
3778 default_face_height_and_width (window, &defheight, &defwidth); 3592 default_face_height_and_width (window, &defheight, &defwidth);
3779 3593
3780 avail_height = char_height * defheight; 3594 avail_height = char_height * defheight;
3781 pixel_height = (avail_height + 3595 pixel_height = (avail_height +
3782 (include_gutters_p ? 0 : 3596 (include_gutters_p ? 0 :
3783 window_top_window_gutter_height (w) + 3597 window_top_gutter_height (w) +
3784 window_bottom_window_gutter_height (w))); 3598 window_bottom_gutter_height (w)));
3785 3599
3786 /* It's the calling function's responsibility to check these values 3600 /* It's the calling function's responsibility to check these values
3787 and make sure they're not out of range. 3601 and make sure they're not out of range.
3788 3602
3789 #### We need to go through the calling functions and actually 3603 #### We need to go through the calling functions and actually
3792 } 3606 }
3793 3607
3794 /* Return number of default lines of text can fit in the window W. 3608 /* Return number of default lines of text can fit in the window W.
3795 If INCLUDE_GUTTERS_P is 1, include "gutter" space (modeline plus 3609 If INCLUDE_GUTTERS_P is 1, include "gutter" space (modeline plus
3796 horizontal scrollbar) in the space that is used for the calculation. 3610 horizontal scrollbar) in the space that is used for the calculation.
3797 This doesn't include space used by the frame gutters.
3798 */ 3611 */
3799 int 3612 int
3800 window_char_height (struct window *w, int include_gutters_p) 3613 window_char_height (struct window *w, int include_gutters_p)
3801 { 3614 {
3802 return window_pixel_height_to_char_height (w, window_pixel_height (w), 3615 return window_pixel_height_to_char_height (w, WINDOW_HEIGHT (w),
3803 include_gutters_p); 3616 include_gutters_p);
3804 } 3617 }
3805 3618
3806 /* 3619 /*
3807 * Return number of lines currently displayed in window w. If 3620 * Return number of lines currently displayed in window w. If
3877 window_pixel_width (Lisp_Object window) 3690 window_pixel_width (Lisp_Object window)
3878 { 3691 {
3879 return WINDOW_WIDTH (XWINDOW (window)); 3692 return WINDOW_WIDTH (XWINDOW (window));
3880 } 3693 }
3881 3694
3882 /* Calculate the pixel of a window, optionally including margin space
3883 but no vertical gutters. */
3884 static int 3695 static int
3885 window_pixel_width_to_char_width (struct window *w, int pixel_width, 3696 window_pixel_width_to_char_width (struct window *w, int pixel_width,
3886 int include_margins_p) 3697 int include_margins_p)
3887 { 3698 {
3888 int avail_width; 3699 int avail_width;
3923 3734
3924 default_face_height_and_width (window, &defheight, &defwidth); 3735 default_face_height_and_width (window, &defheight, &defwidth);
3925 3736
3926 avail_width = char_width * defwidth; 3737 avail_width = char_width * defwidth;
3927 pixel_width = (avail_width + 3738 pixel_width = (avail_width +
3928 window_left_window_gutter_width (w, 0) + 3739 window_left_gutter_width (w, 0) +
3929 window_right_window_gutter_width (w, 0) + 3740 window_right_gutter_width (w, 0) +
3930 (include_margins_p ? 0 : window_left_margin_width (w)) + 3741 (include_margins_p ? 0 : window_left_margin_width (w)) +
3931 (include_margins_p ? 0 : window_right_margin_width (w))); 3742 (include_margins_p ? 0 : window_right_margin_width (w)));
3932 3743
3933 /* It's the calling function's responsibility to check these values 3744 /* It's the calling function's responsibility to check these values
3934 and make sure they're not out of range. 3745 and make sure they're not out of range.
3962 (widthflag ? window_char_width (w, 0) : window_char_height (w, 1)) 3773 (widthflag ? window_char_width (w, 0) : window_char_height (w, 1))
3963 3774
3964 #define MINCHARSIZE(window) \ 3775 #define MINCHARSIZE(window) \
3965 (widthflag ? window_min_width : MINI_WINDOW_P (XWINDOW (window)) \ 3776 (widthflag ? window_min_width : MINI_WINDOW_P (XWINDOW (window)) \
3966 ? 1 : window_min_height) 3777 ? 1 : window_min_height)
3967
3968 static int
3969 window_pixheight (Lisp_Object w)
3970 {
3971 return window_pixel_height (XWINDOW (w));
3972 }
3973 3778
3974 /* Unlike set_window_pixheight, this function 3779 /* Unlike set_window_pixheight, this function
3975 also changes the heights of the siblings so as to 3780 also changes the heights of the siblings so as to
3976 keep everything consistent. */ 3781 keep everything consistent. */
3977 3782
3984 struct window *w; 3789 struct window *w;
3985 struct frame *f; 3790 struct frame *f;
3986 int *sizep; 3791 int *sizep;
3987 int (*sizefun) (Lisp_Object) = (widthflag 3792 int (*sizefun) (Lisp_Object) = (widthflag
3988 ? window_pixel_width 3793 ? window_pixel_width
3989 : window_pixheight); 3794 : window_pixel_height);
3990 void (*setsizefun) (Lisp_Object, int, int) = (widthflag 3795 void (*setsizefun) (Lisp_Object, int, int) = (widthflag
3991 ? set_window_pixwidth 3796 ? set_window_pixwidth
3992 : set_window_pixheight); 3797 : set_window_pixheight);
3993 int dim; 3798 int dim;
3994 int defheight, defwidth; 3799 int defheight, defwidth;
4119 } 3924 }
4120 3925
4121 SET_LAST_MODIFIED (w, 0); 3926 SET_LAST_MODIFIED (w, 0);
4122 SET_LAST_FACECHANGE (w); 3927 SET_LAST_FACECHANGE (w);
4123 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f); 3928 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
4124 /* overkill maybe, but better to be correct */
4125 MARK_FRAME_GUTTERS_CHANGED (f);
4126 } 3929 }
4127 #undef MINSIZE 3930 #undef MINSIZE
4128 #undef CURBEG 3931 #undef CURBEG
4129 #undef CURSIZE 3932 #undef CURSIZE
4130 #undef CURCHARSIZE 3933 #undef CURCHARSIZE
4131 #undef MINCHARSIZE 3934 #undef MINCHARSIZE
4132 3935
4133 3936
4134 3937
4135 /* Scroll contents of window WINDOW up N lines. If N < (top line height / 3938 /* Scroll contents of window WINDOW up N lines. */
4136 average line height) then we just adjust the top clip. */
4137 void 3939 void
4138 window_scroll (Lisp_Object window, Lisp_Object n, int direction, 3940 window_scroll (Lisp_Object window, Lisp_Object n, int direction,
4139 Error_behavior errb) 3941 Error_behavior errb)
4140 { 3942 {
4141 struct window *w = XWINDOW (window); 3943 struct window *w = XWINDOW (window);
4142 struct buffer *b = XBUFFER (w->buffer); 3944 struct buffer *b = XBUFFER (w->buffer);
4143 int selected = EQ (window, Fselected_window (Qnil)); 3945 int selected = EQ (window, Fselected_window (Qnil));
4144 int value = 0; 3946 int value = 0;
4145 Lisp_Object point, tem; 3947 Lisp_Object point, tem;
4146 display_line_dynarr *dla;
4147 int fheight, fwidth, modeline = 0;
4148 struct display_line* dl;
4149 3948
4150 if (selected) 3949 if (selected)
4151 point = make_int (BUF_PT (b)); 3950 point = make_int (BUF_PT (b));
4152 else 3951 else
4153 { 3952 {
4173 { 3972 {
4174 Fvertical_motion (make_int (-window_char_height (w, 0) / 2), 3973 Fvertical_motion (make_int (-window_char_height (w, 0) / 2),
4175 window, Qnil); 3974 window, Qnil);
4176 Fset_marker (w->start[CURRENT_DISP], point, w->buffer); 3975 Fset_marker (w->start[CURRENT_DISP], point, w->buffer);
4177 w->start_at_line_beg = beginning_of_line_p (b, XINT (point)); 3976 w->start_at_line_beg = beginning_of_line_p (b, XINT (point));
4178 WINDOW_TEXT_TOP_CLIP (w) = 0;
4179 MARK_WINDOWS_CHANGED (w); 3977 MARK_WINDOWS_CHANGED (w);
4180 } 3978 }
4181 3979
4182 if (!NILP (n)) 3980 if (!NILP (n))
4183 { 3981 {
4217 4015
4218 if (direction == 1 && !value) 4016 if (direction == 1 && !value)
4219 { 4017 {
4220 return; 4018 return;
4221 } 4019 }
4222 4020 else if (value > 0)
4223 /* Determine parameters to test for partial line scrolling with. */ 4021 {
4224 dla = window_display_lines (w, CURRENT_DISP); 4022 int vtarget;
4225 4023 Bufpos startp, old_start;
4226 if (INTP (Vwindow_pixel_scroll_increment)) 4024
4227 fheight = XINT (Vwindow_pixel_scroll_increment); 4025 old_start = marker_position (w->start[CURRENT_DISP]);
4228 else if (!NILP (Vwindow_pixel_scroll_increment)) 4026 startp = vmotion (w, old_start, value, &vtarget);
4229 default_face_height_and_width (window, &fheight, &fwidth); 4027
4230 4028 if (vtarget < value &&
4231 if (Dynarr_length (dla) >= 1) 4029 (w->window_end_pos[CURRENT_DISP] == -1
4232 modeline = Dynarr_atp (dla, 0)->modeline; 4030 || (BUF_Z (b) - w->window_end_pos[CURRENT_DISP] > BUF_ZV (b))))
4233
4234 dl = Dynarr_atp (dla, modeline);
4235
4236 if (value > 0)
4237 {
4238 /* Go for partial display line scrolling. This just means bumping
4239 the clip by a reasonable amount and redisplaying, everything else
4240 remains unchanged. */
4241 if (!NILP (Vwindow_pixel_scroll_increment)
4242 &&
4243 Dynarr_length (dla) >= (1 + modeline)
4244 &&
4245 (dl->ascent - dl->top_clip) - fheight * value > 0)
4246 { 4031 {
4247 WINDOW_TEXT_TOP_CLIP (w) += value * fheight; 4032 maybe_signal_error (Qend_of_buffer, Qnil, Qwindow, errb);
4248 MARK_WINDOWS_CHANGED (w); 4033 return;
4249 } 4034 }
4250 else 4035 else
4251 { 4036 {
4252 int vtarget; 4037 set_marker_restricted (w->start[CURRENT_DISP], make_int (startp),
4253 Bufpos startp, old_start; 4038 w->buffer);
4254 4039 w->force_start = 1;
4255 if (WINDOW_TEXT_TOP_CLIP (w)) 4040 w->start_at_line_beg = beginning_of_line_p (b, startp);
4041 MARK_WINDOWS_CHANGED (w);
4042
4043 if (!point_would_be_visible (w, startp, XINT (point)))
4256 { 4044 {
4257 WINDOW_TEXT_TOP_CLIP (w) = 0; 4045 if (selected)
4258 MARK_WINDOWS_CHANGED (w); 4046 BUF_SET_PT (b, startp);
4259 } 4047 else
4260 4048 set_marker_restricted (w->pointm[CURRENT_DISP],
4261 old_start = marker_position (w->start[CURRENT_DISP]); 4049 make_int (startp),
4262 startp = vmotion (w, old_start, value, &vtarget); 4050 w->buffer);
4263
4264 if (vtarget < value &&
4265 (w->window_end_pos[CURRENT_DISP] == -1
4266 || (BUF_Z (b) - w->window_end_pos[CURRENT_DISP] > BUF_ZV (b))))
4267 {
4268 maybe_signal_error (Qend_of_buffer, Qnil, Qwindow, errb);
4269 return;
4270 }
4271 else
4272 {
4273 set_marker_restricted (w->start[CURRENT_DISP], make_int (startp),
4274 w->buffer);
4275 w->force_start = 1;
4276 w->start_at_line_beg = beginning_of_line_p (b, startp);
4277 MARK_WINDOWS_CHANGED (w);
4278
4279 if (!point_would_be_visible (w, startp, XINT (point)))
4280 {
4281 if (selected)
4282 BUF_SET_PT (b, startp);
4283 else
4284 set_marker_restricted (w->pointm[CURRENT_DISP],
4285 make_int (startp),
4286 w->buffer);
4287 }
4288 } 4051 }
4289 } 4052 }
4290 } 4053 }
4291 else if (value < 0) 4054 else if (value < 0)
4292 { 4055 {
4293 /* Go for partial display line scrolling. This just means bumping 4056 int vtarget;
4294 the clip by a reasonable amount and redisplaying, everything else 4057 Bufpos startp, old_start;
4295 remains unchanged. */ 4058
4296 if (!NILP (Vwindow_pixel_scroll_increment) 4059 old_start = marker_position (w->start[CURRENT_DISP]);
4297 && 4060 startp = vmotion (w, old_start, value, &vtarget);
4298 Dynarr_length (dla) >= (1 + modeline) 4061
4299 && 4062 if (vtarget > value
4300 (dl->ascent - dl->top_clip) - fheight * value < 4063 && marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b))
4301 (dl->ascent + dl->descent - dl->clip)
4302 &&
4303 WINDOW_TEXT_TOP_CLIP (w) + value * fheight > 0)
4304 { 4064 {
4305 WINDOW_TEXT_TOP_CLIP (w) += value * fheight; 4065 maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb);
4306 MARK_WINDOWS_CHANGED (w); 4066 return;
4307 } 4067 }
4308 else 4068 else
4309 { 4069 {
4310 int vtarget; 4070 set_marker_restricted (w->start[CURRENT_DISP], make_int (startp),
4311 Bufpos startp, old_start; 4071 w->buffer);
4312 4072 w->force_start = 1;
4313 if (WINDOW_TEXT_TOP_CLIP (w)) 4073 w->start_at_line_beg = beginning_of_line_p (b, startp);
4074 MARK_WINDOWS_CHANGED (w);
4075
4076 if (!point_would_be_visible (w, startp, XINT (point)))
4314 { 4077 {
4315 WINDOW_TEXT_TOP_CLIP (w) = 0; 4078 Bufpos new_point;
4316 MARK_WINDOWS_CHANGED (w); 4079
4317 } 4080 if (MINI_WINDOW_P (w))
4318 4081 new_point = startp;
4319 old_start = marker_position (w->start[CURRENT_DISP]); 4082 else
4320 startp = vmotion (w, old_start, value, &vtarget); 4083 new_point = start_of_last_line (w, startp);
4321 4084
4322 if (vtarget > value 4085 if (selected)
4323 && marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b)) 4086 BUF_SET_PT (b, new_point);
4324 { 4087 else
4325 maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb); 4088 set_marker_restricted (w->pointm[CURRENT_DISP],
4326 return; 4089 make_int (new_point),
4327 } 4090 w->buffer);
4328 else
4329 {
4330 set_marker_restricted (w->start[CURRENT_DISP], make_int (startp),
4331 w->buffer);
4332 w->force_start = 1;
4333 w->start_at_line_beg = beginning_of_line_p (b, startp);
4334 MARK_WINDOWS_CHANGED (w);
4335
4336 /* #### Scroll back by less than a line. This code was
4337 originally for scrolling over large pixmaps and it
4338 loses when a line being *exposed* at the top of the
4339 window is bigger than the current one. However, for
4340 pixel based scrolling in general we can guess that
4341 the line we are going to display is probably the same
4342 size as the one we are on. In that instance we can
4343 have a reasonable stab at a suitable top clip. Fixing
4344 this properly is hard (and probably slow) as we would
4345 have to call redisplay to figure out the exposed line
4346 size. */
4347 if (!NILP (Vwindow_pixel_scroll_increment)
4348 && Dynarr_length (dla) >= (1 + modeline)
4349 && dl->ascent + fheight * value > 0)
4350 {
4351 WINDOW_TEXT_TOP_CLIP (w) = (dl->ascent + fheight * value);
4352 }
4353
4354 if (!point_would_be_visible (w, startp, XINT (point)))
4355 {
4356 Bufpos new_point;
4357
4358 if (MINI_WINDOW_P (w))
4359 new_point = startp;
4360 else
4361 new_point = start_of_last_line (w, startp);
4362
4363 if (selected)
4364 BUF_SET_PT (b, new_point);
4365 else
4366 set_marker_restricted (w->pointm[CURRENT_DISP],
4367 make_int (new_point),
4368 w->buffer);
4369 }
4370 } 4091 }
4371 } 4092 }
4372 } 4093 }
4373 else /* value == 0 && direction == -1 */ 4094 else /* value == 0 && direction == -1 */
4374 { 4095 {
4375 if (WINDOW_TEXT_TOP_CLIP (w))
4376 {
4377 WINDOW_TEXT_TOP_CLIP (w) = 0;
4378 MARK_WINDOWS_CHANGED (w);
4379 }
4380 if (marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b)) 4096 if (marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b))
4381 { 4097 {
4382 maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb); 4098 maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb);
4383 return; 4099 return;
4384 } 4100 }
4412 make_int (new_point), 4128 make_int (new_point),
4413 w->buffer); 4129 w->buffer);
4414 } 4130 }
4415 } 4131 }
4416 } 4132 }
4133
4417 } 4134 }
4418 4135
4419 DEFUN ("scroll-up", Fscroll_up, 0, 1, "_P", /* 4136 DEFUN ("scroll-up", Fscroll_up, 0, 1, "_P", /*
4420 Scroll text of current window upward N lines; or near full screen if no arg. 4137 Scroll text of current window upward N lines; or near full screen if no arg.
4421 A near full screen is `next-screen-context-lines' less than a full screen. 4138 A near full screen is `next-screen-context-lines' less than a full screen.
4585 /* Don't use decode_window() because we need the new value of 4302 /* Don't use decode_window() because we need the new value of
4586 WINDOW. */ 4303 WINDOW. */
4587 if (NILP (window)) 4304 if (NILP (window))
4588 window = Fselected_window (Qnil); 4305 window = Fselected_window (Qnil);
4589 else 4306 else
4590 CHECK_LIVE_WINDOW (window); 4307 CHECK_WINDOW (window);
4591 w = XWINDOW (window); 4308 w = XWINDOW (window);
4592 b = XBUFFER (w->buffer); 4309 b = XBUFFER (w->buffer);
4593 4310
4594 height = window_displayed_height (w); 4311 height = window_displayed_height (w);
4595 selected = EQ (window, Fselected_window (w->frame)); 4312 selected = EQ (window, Fselected_window (w->frame));
4887 int pixel_left; 4604 int pixel_left;
4888 int pixel_top; 4605 int pixel_top;
4889 int pixel_width; 4606 int pixel_width;
4890 int pixel_height; 4607 int pixel_height;
4891 int hscroll; 4608 int hscroll;
4892 Charcount modeline_hscroll; 4609 int modeline_hscroll;
4893 int parent_index; /* index into saved_windows */ 4610 int parent_index; /* index into saved_windows */
4894 int prev_index; /* index into saved_windows */ 4611 int prev_index; /* index into saved_windows */
4895 char start_at_line_beg; /* boolean */ 4612 char start_at_line_beg; /* boolean */
4896 4613
4897 #define WINDOW_SLOT_DECLARATION 4614 #define WINDOW_SLOT_DECLARATION
4924 4641
4925 #define SAVED_WINDOW_N(conf, n) (&((conf)->saved_windows[(n)])) 4642 #define SAVED_WINDOW_N(conf, n) (&((conf)->saved_windows[(n)]))
4926 #define XWINDOW_CONFIGURATION(x) XRECORD (x, window_configuration, struct window_config) 4643 #define XWINDOW_CONFIGURATION(x) XRECORD (x, window_configuration, struct window_config)
4927 #define XSETWINDOW_CONFIGURATION(x, p) XSETRECORD (x, p, window_configuration) 4644 #define XSETWINDOW_CONFIGURATION(x, p) XSETRECORD (x, p, window_configuration)
4928 #define WINDOW_CONFIGURATIONP(x) RECORDP (x, window_configuration) 4645 #define WINDOW_CONFIGURATIONP(x) RECORDP (x, window_configuration)
4646 #define GC_WINDOW_CONFIGURATIONP(x) GC_RECORDP (x, window_configuration)
4929 #define CHECK_WINDOW_CONFIGURATION(x) CHECK_RECORD (x, window_configuration) 4647 #define CHECK_WINDOW_CONFIGURATION(x) CHECK_RECORD (x, window_configuration)
4930 4648
4931 static Lisp_Object 4649 static Lisp_Object
4932 mark_window_config (Lisp_Object obj) 4650 mark_window_config (Lisp_Object obj, void (*markobj) (Lisp_Object))
4933 { 4651 {
4934 struct window_config *config = XWINDOW_CONFIGURATION (obj); 4652 struct window_config *config = XWINDOW_CONFIGURATION (obj);
4935 int i; 4653 int i;
4936 mark_object (config->current_window); 4654 markobj (config->current_window);
4937 mark_object (config->current_buffer); 4655 markobj (config->current_buffer);
4938 mark_object (config->minibuffer_scroll_window); 4656 markobj (config->minibuffer_scroll_window);
4939 mark_object (config->root_window); 4657 markobj (config->root_window);
4940 4658
4941 for (i = 0; i < config->saved_windows_count; i++) 4659 for (i = 0; i < config->saved_windows_count; i++)
4942 { 4660 {
4943 struct saved_window *s = SAVED_WINDOW_N (config, i); 4661 struct saved_window *s = SAVED_WINDOW_N (config, i);
4944 mark_object (s->window); 4662 markobj (s->window);
4945 mark_object (s->buffer); 4663 markobj (s->buffer);
4946 mark_object (s->start); 4664 markobj (s->start);
4947 mark_object (s->pointm); 4665 markobj (s->pointm);
4948 mark_object (s->sb_point); 4666 markobj (s->sb_point);
4949 mark_object (s->mark); 4667 markobj (s->mark);
4950 #if 0 4668 #if 0
4951 /* #### This looked like this. I do not see why specifier cached 4669 /* #### This looked like this. I do not see why specifier cached
4952 values should not be marked, as such specifiers as toolbars 4670 values should not be marked, as such specifiers as toolbars
4953 might have GC-able instances. Freed configs are not marked, 4671 might have GC-able instances. Freed configs are not marked,
4954 aren't they? -- kkm */ 4672 aren't they? -- kkm */
4955 mark_object (s->dedicated); 4673 markobj (s->dedicated);
4956 #else 4674 #else
4957 #define WINDOW_SLOT(slot, compare) mark_object (s->slot) 4675 #define WINDOW_SLOT(slot, compare) ((void) (markobj (s->slot)))
4958 #include "winslots.h" 4676 #include "winslots.h"
4959 #endif 4677 #endif
4960 } 4678 }
4961 return Qnil; 4679 return Qnil;
4962 } 4680 }
4968 /* n - 1 because zero-sized arrays aren't ANSI C */ 4686 /* n - 1 because zero-sized arrays aren't ANSI C */
4969 (n - 1) *sizeof (struct saved_window)); 4687 (n - 1) *sizeof (struct saved_window));
4970 } 4688 }
4971 4689
4972 static size_t 4690 static size_t
4973 sizeof_window_config (const void *h) 4691 sizeof_window_config (CONST void *h)
4974 { 4692 {
4975 const struct window_config *c = (const struct window_config *) h; 4693 CONST struct window_config *c = (CONST struct window_config *) h;
4976 return sizeof_window_config_for_n_windows (c->saved_windows_count); 4694 return sizeof_window_config_for_n_windows (c->saved_windows_count);
4977 } 4695 }
4978 4696
4979 static void 4697 static void
4980 print_window_config (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) 4698 print_window_config (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
4991 4709
4992 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("window-configuration", 4710 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("window-configuration",
4993 window_configuration, 4711 window_configuration,
4994 mark_window_config, 4712 mark_window_config,
4995 print_window_config, 4713 print_window_config,
4996 0, 0, 0, 0, sizeof_window_config, 4714 0, 0, 0, sizeof_window_config,
4997 struct window_config); 4715 struct window_config);
4998 4716
4999 4717
5000 /* Returns a boolean indicating whether the two saved windows are 4718 /* Returns a boolean indicating whether the two saved windows are
5001 identical. */ 4719 identical. */
5149 int previous_pixel_height; 4867 int previous_pixel_height;
5150 int previous_pixel_left; 4868 int previous_pixel_left;
5151 int previous_pixel_width; 4869 int previous_pixel_width;
5152 int previous_minibuf_height, previous_minibuf_top,previous_minibuf_width; 4870 int previous_minibuf_height, previous_minibuf_top,previous_minibuf_width;
5153 int real_font_height; 4871 int real_font_height;
5154 int converted_minibuf_height,target_minibuf_height; 4872 int converted_minibuf_height,target_minibuf_height;
5155 int specpdl_count = specpdl_depth (); 4873 int specpdl_count = specpdl_depth ();
5156 4874
5157 GCPRO1 (configuration); 4875 GCPRO1 (configuration);
5158 4876
5159 CHECK_WINDOW_CONFIGURATION (configuration); 4877 CHECK_WINDOW_CONFIGURATION (configuration);
5214 begin_dont_check_for_quit (); 4932 begin_dont_check_for_quit ();
5215 record_unwind_protect (free_window_configuration, old_window_config); 4933 record_unwind_protect (free_window_configuration, old_window_config);
5216 4934
5217 mark_windows_in_use (f, 1); 4935 mark_windows_in_use (f, 1);
5218 4936
5219 /* Force subwindows to be reinstantiated. They are all going
5220 anyway and if we don't do this GC may not happen between now
5221 and the next time we check their integrity. */
5222 reset_frame_subwindow_instance_cache (f);
5223
5224 #if 0 4937 #if 0
5225 /* JV: This is bogus, 4938 /* JV: This is bogus,
5226 First of all, the units are inconsistent. The frame sizes are measured 4939 First of all, the units are inconsistent. The frame sizes are measured
5227 in characters but the window sizes are stored in pixels. So if a 4940 in characters but the window sizes are stored in pixels. So if a
5228 font size change happened between saving and restoring, the 4941 font size change happened between saving and restoring, the
5229 frame "sizes" maybe equal but the windows still should be 4942 frame "sizes" maybe equal but the windows still should be
5230 resized. This is tickled alot by the new "character size 4943 resized. This is tickled alot by the new "character size
5231 stays constant" policy in 21.0. It leads to very wierd 4944 stays constant" policy in 21.0. It leads to very wierd
5232 glitches (and possibly crashes when asserts are tickled). 4945 glitches (and possibly craches when asserts are tickled).
5233 4946
5234 Just changing the units doens't help because changing the 4947 Just changing the units doens't help because changing the
5235 toolbar configuration can also change the pixel positions. 4948 toolbar configuration can also change the pixel positions.
5236 Luckily there is a much simpler way of doing this, see below. 4949 Luckily there is a much simpler way of doing this, see below.
5237 */ 4950 */
5243 back. We keep track of the prevailing height in these variables. */ 4956 back. We keep track of the prevailing height in these variables. */
5244 if (config->frame_height != FRAME_HEIGHT (f) 4957 if (config->frame_height != FRAME_HEIGHT (f)
5245 || config->frame_width != FRAME_WIDTH (f)) 4958 || config->frame_width != FRAME_WIDTH (f))
5246 change_frame_size (f, config->frame_height, config->frame_width, 0); 4959 change_frame_size (f, config->frame_height, config->frame_width, 0);
5247 #endif 4960 #endif
5248 4961
5249 previous_pixel_top = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top; 4962 previous_pixel_top = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top;
5250 previous_pixel_height = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_height; 4963 previous_pixel_height = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_height;
5251 previous_pixel_left = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left; 4964 previous_pixel_left = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left;
5252 previous_pixel_width = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_width; 4965 previous_pixel_width = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_width;
5253 4966
5254 /* remember some properties of the minibuffer */ 4967 /* remember some properties of the minibuffer */
5255 4968
5256 default_face_height_and_width (frame, &real_font_height, 0); 4969 default_face_height_and_width (frame, &real_font_height, 0);
5257 assert(real_font_height > 0); 4970 assert(real_font_height > 0);
5258 4971
5259 if (FRAME_HAS_MINIBUF_P (f) && ! FRAME_MINIBUF_ONLY_P (f)) 4972 if (FRAME_HAS_MINIBUF_P (f) && ! FRAME_MINIBUF_ONLY_P (f))
5260 { 4973 {
5261 previous_minibuf_height 4974 previous_minibuf_height
5262 = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height; 4975 = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height;
5263 previous_minibuf_top 4976 previous_minibuf_top
5266 = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_width; 4979 = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_width;
5267 } 4980 }
5268 else 4981 else
5269 { 4982 {
5270 previous_minibuf_height = 0; 4983 previous_minibuf_height = 0;
5271 previous_minibuf_top = 0;
5272 previous_minibuf_width = 0; 4984 previous_minibuf_width = 0;
5273 } 4985 }
5274 converted_minibuf_height = 4986 converted_minibuf_height =
5275 (previous_minibuf_height % real_font_height) == 0 ? 4987 (previous_minibuf_height % real_font_height) == 0 ?
5276 - (previous_minibuf_height / real_font_height ) : /* lines */ 4988 - (previous_minibuf_height / real_font_height ) : /* lines */
5277 previous_minibuf_height; /* pixels */ 4989 previous_minibuf_height; /* pixels */
5278 4990
5279 /* Temporarily avoid any problems with windows that are smaller 4991 /* Temporarily avoid any problems with windows that are smaller
5280 than they are supposed to be. */ 4992 than they are supposed to be. */
5281 window_min_height = 1; 4993 window_min_height = 1;
5282 window_min_width = 1; 4994 window_min_width = 1;
5283 4995
5300 } 5012 }
5301 if (!w->glyph_cachels) 5013 if (!w->glyph_cachels)
5302 w->glyph_cachels = Dynarr_new (glyph_cachel); 5014 w->glyph_cachels = Dynarr_new (glyph_cachel);
5303 if (!w->line_start_cache) 5015 if (!w->line_start_cache)
5304 w->line_start_cache = Dynarr_new (line_start_cache); 5016 w->line_start_cache = Dynarr_new (line_start_cache);
5305 w->gutter_extent_modiff[0] = 0;
5306 w->gutter_extent_modiff[1] = 0;
5307 w->gutter_extent_modiff[2] = 0;
5308 w->gutter_extent_modiff[3] = 0;
5309 w->dead = 0; 5017 w->dead = 0;
5310 5018
5311 if (p->parent_index >= 0) 5019 if (p->parent_index >= 0)
5312 w->parent = SAVED_WINDOW_N (config, p->parent_index)->window; 5020 w->parent = SAVED_WINDOW_N (config, p->parent_index)->window;
5313 else 5021 else
5361 WINDOW_WIDTH (w) = WINDOW_WIDTH (p); 5069 WINDOW_WIDTH (w) = WINDOW_WIDTH (p);
5362 WINDOW_HEIGHT (w) = WINDOW_HEIGHT (p); 5070 WINDOW_HEIGHT (w) = WINDOW_HEIGHT (p);
5363 w->hscroll = p->hscroll; 5071 w->hscroll = p->hscroll;
5364 w->modeline_hscroll = p->modeline_hscroll; 5072 w->modeline_hscroll = p->modeline_hscroll;
5365 w->line_cache_last_updated = Qzero; 5073 w->line_cache_last_updated = Qzero;
5366 /* The subwindow instance cache isn't preserved across
5367 window configurations, and in fact doing so would be
5368 wrong. We just reset to zero and then redisplay will fill
5369 it up as needed. */
5370 w->subwindow_instance_cache =
5371 make_lisp_hash_table (30,
5372 HASH_TABLE_KEY_VALUE_WEAK,
5373 HASH_TABLE_EQUAL);
5374 SET_LAST_MODIFIED (w, 1); 5074 SET_LAST_MODIFIED (w, 1);
5375 SET_LAST_FACECHANGE (w); 5075 SET_LAST_FACECHANGE (w);
5376 w->config_mark = 0; 5076 w->config_mark = 0;
5377 5077
5378 #define WINDOW_SLOT(slot, compare) w->slot = p->slot 5078 #define WINDOW_SLOT(slot, compare) w->slot = p->slot;
5379 #include "winslots.h" 5079 #include "winslots.h"
5380 5080
5381 /* Reinstall the saved buffer and pointers into it. */ 5081 /* Reinstall the saved buffer and pointers into it. */
5382 if (NILP (p->buffer)) 5082 if (NILP (p->buffer))
5383 w->buffer = p->buffer; 5083 w->buffer = p->buffer;
5467 We take the old value if is in the same units but differs from the 5167 We take the old value if is in the same units but differs from the
5468 current value. 5168 current value.
5469 5169
5470 #### Now we get more cases correct then ever before, but 5170 #### Now we get more cases correct then ever before, but
5471 are we treating all? For instance what if the frames minibuf window 5171 are we treating all? For instance what if the frames minibuf window
5472 is no longer the same one? 5172 is no longer the same one?
5473 */ 5173 */
5474 target_minibuf_height = previous_minibuf_height; 5174 target_minibuf_height = previous_minibuf_height;
5475 if (converted_minibuf_height && 5175 if (converted_minibuf_height &&
5476 (converted_minibuf_height * config->minibuf_height) > 0 && 5176 (converted_minibuf_height * config->minibuf_height) > 0 &&
5477 (converted_minibuf_height != config->minibuf_height)) 5177 (converted_minibuf_height != config->minibuf_height))
5490 set_window_pixheight (FRAME_MINIBUF_WINDOW (f), 5190 set_window_pixheight (FRAME_MINIBUF_WINDOW (f),
5491 target_minibuf_height, 0); 5191 target_minibuf_height, 0);
5492 set_window_pixwidth (FRAME_MINIBUF_WINDOW (f), 5192 set_window_pixwidth (FRAME_MINIBUF_WINDOW (f),
5493 previous_minibuf_width, 0); 5193 previous_minibuf_width, 0);
5494 } 5194 }
5495 5195
5496 /* This is a better way to deal with frame resizing, etc. 5196 /* This is a better way to deal with frame resizing, etc.
5497 What we _actually_ want is for the old (just restored) 5197 What we _actually_ want is for the old (just restored)
5498 root window to fit 5198 root window to fit
5499 into the place of the new one. So we just do that. Simple! */ 5199 into the place of the new one. So we just do that. Simple! */
5500 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top = previous_pixel_top; 5200 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top = previous_pixel_top;
5505 (target_minibuf_height - previous_minibuf_height), 0); 5205 (target_minibuf_height - previous_minibuf_height), 0);
5506 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left = previous_pixel_left; 5206 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left = previous_pixel_left;
5507 /* Note that this function also updates the subwindow 5207 /* Note that this function also updates the subwindow
5508 "pixel_left"s */ 5208 "pixel_left"s */
5509 set_window_pixwidth (FRAME_ROOT_WINDOW (f), previous_pixel_width, 0); 5209 set_window_pixwidth (FRAME_ROOT_WINDOW (f), previous_pixel_width, 0);
5510 5210
5511 /* If restoring in the current frame make the window current, 5211 /* If restoring in the current frame make the window current,
5512 otherwise just update the frame selected_window slot to be 5212 otherwise just update the frame selected_window slot to be
5513 the restored current_window. */ 5213 the restored current_window. */
5514 if (f == selected_frame ()) 5214 if (f == selected_frame ())
5515 { 5215 {
5516 #if 0
5517 /* When using `pop-window-configuration', often the minibuffer 5216 /* When using `pop-window-configuration', often the minibuffer
5518 ends up as the selected window even though it's not active ... 5217 ends up as the selected window even though it's not active ...
5519 I really don't know the cause of this, but it should never 5218 I really don't know the cause of this, but it should never
5520 happen. This kludge should fix it. 5219 happen. This kludge should fix it.
5521 5220
5522 #### Find out why this is really going wrong. */ 5221 #### Find out why this is really going wrong. */
5523 if (!minibuf_level && 5222 if (!minibuf_level &&
5524 MINI_WINDOW_P (XWINDOW (config->current_window))) 5223 MINI_WINDOW_P (XWINDOW (config->current_window)))
5525 window_to_select = Fnext_window (config->current_window, 5224 Fselect_window (Fnext_window (config->current_window,
5526 Qnil, Qnil, Qnil); 5225 Qnil, Qnil, Qnil),
5226 Qnil);
5527 else 5227 else
5528 window_to_select = config->current_window; 5228 Fselect_window (config->current_window, Qnil);
5529 #endif
5530 /* Do this last so that buffer stacking is calculated
5531 correctly. */
5532 Fselect_window (config->current_window, Qnil);
5533
5534 if (!NILP (new_current_buffer)) 5229 if (!NILP (new_current_buffer))
5535 { 5230 Fset_buffer (new_current_buffer);
5536 Fset_buffer (new_current_buffer);
5537 Frecord_buffer (new_current_buffer);
5538 }
5539 else 5231 else
5540 { 5232 Fset_buffer (XWINDOW (Fselected_window (Qnil))->buffer);
5541 Fset_buffer (XWINDOW (config->current_window)->buffer);
5542 Frecord_buffer (XWINDOW (config->current_window)->buffer);
5543 }
5544 } 5233 }
5545 else 5234 else
5546 set_frame_selected_window (f, config->current_window); 5235 set_frame_selected_window (f, config->current_window);
5547 } 5236 }
5548 else 5237 else
5658 WINDOW_WIDTH (p) = WINDOW_WIDTH (w); 5347 WINDOW_WIDTH (p) = WINDOW_WIDTH (w);
5659 WINDOW_HEIGHT (p) = WINDOW_HEIGHT (w); 5348 WINDOW_HEIGHT (p) = WINDOW_HEIGHT (w);
5660 p->hscroll = w->hscroll; 5349 p->hscroll = w->hscroll;
5661 p->modeline_hscroll = w->modeline_hscroll; 5350 p->modeline_hscroll = w->modeline_hscroll;
5662 5351
5663 #define WINDOW_SLOT(slot, compare) p->slot = w->slot 5352 #define WINDOW_SLOT(slot, compare) p->slot = w->slot;
5664 #include "winslots.h" 5353 #include "winslots.h"
5665 5354
5666 if (!NILP (w->buffer)) 5355 if (!NILP (w->buffer))
5667 { 5356 {
5668 /* Save w's value of point in the window configuration. 5357 /* Save w's value of point in the window configuration.
5747 &lrecord_window_configuration); 5436 &lrecord_window_configuration);
5748 XSETWINDOW_CONFIGURATION (result, config); 5437 XSETWINDOW_CONFIGURATION (result, config);
5749 /* 5438 /*
5750 config->frame_width = FRAME_WIDTH (f); 5439 config->frame_width = FRAME_WIDTH (f);
5751 config->frame_height = FRAME_HEIGHT (f); */ 5440 config->frame_height = FRAME_HEIGHT (f); */
5752 /* When using `push-window-configuration', often the minibuffer ends 5441 config->current_window = FRAME_SELECTED_WINDOW (f);
5753 up as the selected window because functions run as the result of
5754 user interaction e.g. hyper-apropros. It seems to me the sensible
5755 thing to do is not record the minibuffer here. */
5756 if (FRAME_MINIBUF_ONLY_P (f) || minibuf_level)
5757 config->current_window = FRAME_SELECTED_WINDOW (f);
5758 else
5759 config->current_window = FRAME_LAST_NONMINIBUF_WINDOW (f);
5760 XSETBUFFER (config->current_buffer, current_buffer); 5442 XSETBUFFER (config->current_buffer, current_buffer);
5761 config->minibuffer_scroll_window = Vminibuffer_scroll_window; 5443 config->minibuffer_scroll_window = Vminibuffer_scroll_window;
5762 config->root_window = FRAME_ROOT_WINDOW (f); 5444 config->root_window = FRAME_ROOT_WINDOW (f);
5763 config->min_height = window_min_height; 5445 config->min_height = window_min_height;
5764 config->min_width = window_min_width; 5446 config->min_width = window_min_width;
5765 config->saved_windows_count = n_windows; 5447 config->saved_windows_count = n_windows;
5766 save_window_save (FRAME_ROOT_WINDOW (f), config, 0); 5448 save_window_save (FRAME_ROOT_WINDOW (f), config, 0);
5767 5449
5768 /* save the minibuffer height using the heuristics from 5450 /* save the minibuffer height using the heuristics from
5769 change_frame_size_1 */ 5451 change_frame_size_1 */
5770 5452
5771 XSETFRAME (frame, f); /* frame could have been nil ! */ 5453 XSETFRAME (frame, f); /* frame could have been nil ! */
5772 default_face_height_and_width (frame, &real_font_height, 0); 5454 default_face_height_and_width (frame, &real_font_height, 0);
5773 assert(real_font_height > 0); 5455 assert(real_font_height > 0);
5774 5456
5775 if (FRAME_HAS_MINIBUF_P (f) && ! FRAME_MINIBUF_ONLY_P (f)) 5457 if (FRAME_HAS_MINIBUF_P (f) && ! FRAME_MINIBUF_ONLY_P (f))
5776 minibuf_height = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height; 5458 minibuf_height = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height;
5777 else 5459 else
5778 minibuf_height = 0; 5460 minibuf_height = 0;
5779 config->minibuf_height = (minibuf_height % real_font_height) == 0 ? 5461 config->minibuf_height = (minibuf_height % real_font_height) == 0 ?
5807 Fcurrent_window_configuration (Qnil)); 5489 Fcurrent_window_configuration (Qnil));
5808 val = Fprogn (args); 5490 val = Fprogn (args);
5809 return unbind_to (speccount, val); 5491 return unbind_to (speccount, val);
5810 } 5492 }
5811 5493
5812 DEFUN ("current-pixel-column", Fcurrent_pixel_column, 0, 2, 0, /*
5813 Return the horizontal pixel position of POS in window.
5814 Beginning of line is column 0. This is calculated using the redisplay
5815 display tables. If WINDOW is nil, the current window is assumed.
5816 If POS is nil, point is assumed. Note that POS must be visible for
5817 a non-nil result to be returned.
5818 */
5819 (window, pos))
5820 {
5821 struct window* w = decode_window (window);
5822 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
5823
5824 struct display_line *dl = 0;
5825 struct display_block *db = 0;
5826 struct rune* rb = 0;
5827 int y = w->last_point_y[CURRENT_DISP];
5828 int x = w->last_point_x[CURRENT_DISP];
5829
5830 if (MINI_WINDOW_P (w))
5831 return Qnil;
5832
5833 if (y<0 || x<0 || y >= Dynarr_length (dla) || !NILP (pos))
5834 {
5835 int first_line, i;
5836 Bufpos point;
5837
5838 if (NILP (pos))
5839 pos = Fwindow_point (window);
5840
5841 CHECK_INT (pos);
5842 point = XINT (pos);
5843
5844 if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline)
5845 first_line = 1;
5846 else
5847 first_line = 0;
5848
5849 for (i = first_line; i < Dynarr_length (dla); i++)
5850 {
5851 dl = Dynarr_atp (dla, i);
5852 /* find the vertical location first */
5853 if (point >= dl->bufpos && point <= dl->end_bufpos)
5854 {
5855 db = get_display_block_from_line (dl, TEXT);
5856 for (i = 0; i < Dynarr_length (db->runes); i++)
5857 {
5858 rb = Dynarr_atp (db->runes, i);
5859 if (point <= rb->bufpos)
5860 goto found_bufpos;
5861 }
5862 return Qnil;
5863 }
5864 }
5865 return Qnil;
5866 found_bufpos:
5867 ;
5868 }
5869 else
5870 {
5871 /* optimised case */
5872 dl = Dynarr_atp (dla, y);
5873 db = get_display_block_from_line (dl, TEXT);
5874
5875 if (x >= Dynarr_length (db->runes))
5876 return Qnil;
5877
5878 rb = Dynarr_atp (db->runes, x);
5879 }
5880
5881 return make_int (rb->xpos - WINDOW_LEFT (w));
5882 }
5883
5884 5494
5885 #ifdef DEBUG_XEMACS 5495 #ifdef DEBUG_XEMACS
5886 /* This is short and simple in elisp, but... it was written to debug 5496 /* This is short and simple in elisp, but... it was written to debug
5887 problems purely on the C side. That is where we need to call it so 5497 problems purely on the C side. That is where we need to call it so
5888 here it is. */ 5498 here it is. */
5894 5504
5895 if (NILP (child)) 5505 if (NILP (child))
5896 child = Fwindow_first_hchild (window); 5506 child = Fwindow_first_hchild (window);
5897 5507
5898 for (i = level; i > 0; i--) 5508 for (i = level; i > 0; i--)
5899 stderr_out ("\t"); 5509 putc ('\t', stderr);
5900 5510
5901 stderr_out ("#<window"); 5511 fputs ("#<window", stderr);
5902 { 5512 {
5903 Lisp_Object buffer = XWINDOW (window)->buffer; 5513 Lisp_Object buffer = XWINDOW (window)->buffer;
5904 if (!NILP (buffer) && BUFFERP (buffer)) 5514 if (!NILP (buffer) && BUFFERP (buffer))
5905 stderr_out (" on %s", XSTRING_DATA (XBUFFER (buffer)->name)); 5515 fprintf (stderr, " on %s", XSTRING_DATA (XBUFFER (buffer)->name));
5906 } 5516 }
5907 stderr_out (" 0x%x>", XWINDOW (window)->header.uid); 5517 fprintf (stderr, " 0x%x>", XWINDOW (window)->header.uid);
5908 5518
5909 while (!NILP (child)) 5519 while (!NILP (child))
5910 { 5520 {
5911 debug_print_window (child, level + 1); 5521 debug_print_window (child, level + 1);
5912 child = Fwindow_next_child (child); 5522 child = Fwindow_next_child (child);
5928 /************************************************************************/ 5538 /************************************************************************/
5929 5539
5930 void 5540 void
5931 syms_of_window (void) 5541 syms_of_window (void)
5932 { 5542 {
5933 INIT_LRECORD_IMPLEMENTATION (window);
5934 INIT_LRECORD_IMPLEMENTATION (window_configuration);
5935
5936 defsymbol (&Qwindowp, "windowp"); 5543 defsymbol (&Qwindowp, "windowp");
5937 defsymbol (&Qwindow_live_p, "window-live-p"); 5544 defsymbol (&Qwindow_live_p, "window-live-p");
5938 defsymbol (&Qwindow_configurationp, "window-configuration-p"); 5545 defsymbol (&Qwindow_configurationp, "window-configuration-p");
5546 defsymbol (&Qscroll_up, "scroll-up");
5547 defsymbol (&Qscroll_down, "scroll-down");
5939 defsymbol (&Qtemp_buffer_show_hook, "temp-buffer-show-hook"); 5548 defsymbol (&Qtemp_buffer_show_hook, "temp-buffer-show-hook");
5940 defsymbol (&Qdisplay_buffer, "display-buffer"); 5549 defsymbol (&Qdisplay_buffer, "display-buffer");
5941 5550
5942 #ifdef MEMORY_USAGE_STATS 5551 #ifdef MEMORY_USAGE_STATS
5943 defsymbol (&Qface_cache, "face-cache"); 5552 defsymbol (&Qface_cache, "face-cache");
5949 defsymbol (&Qother_redisplay, "other-redisplay"); 5558 defsymbol (&Qother_redisplay, "other-redisplay");
5950 /* Qother in general.c */ 5559 /* Qother in general.c */
5951 #endif 5560 #endif
5952 5561
5953 DEFSUBR (Fselected_window); 5562 DEFSUBR (Fselected_window);
5954 DEFSUBR (Flast_nonminibuf_window);
5955 DEFSUBR (Fminibuffer_window); 5563 DEFSUBR (Fminibuffer_window);
5956 DEFSUBR (Fwindow_minibuffer_p); 5564 DEFSUBR (Fwindow_minibuffer_p);
5957 DEFSUBR (Fwindowp); 5565 DEFSUBR (Fwindowp);
5958 DEFSUBR (Fwindow_live_p); 5566 DEFSUBR (Fwindow_live_p);
5959 DEFSUBR (Fwindow_first_hchild); 5567 DEFSUBR (Fwindow_first_hchild);
5960 DEFSUBR (Fwindow_first_vchild); 5568 DEFSUBR (Fwindow_first_vchild);
5961 DEFSUBR (Fwindow_next_child); 5569 DEFSUBR (Fwindow_next_child);
5962 DEFSUBR (Fwindow_previous_child); 5570 DEFSUBR (Fwindow_previous_child);
5963 DEFSUBR (Fwindow_parent); 5571 DEFSUBR (Fwindow_parent);
5964 DEFSUBR (Fwindow_lowest_p); 5572 DEFSUBR (Fwindow_lowest_p);
5965 DEFSUBR (Fwindow_truncated_p);
5966 DEFSUBR (Fwindow_highest_p); 5573 DEFSUBR (Fwindow_highest_p);
5967 DEFSUBR (Fwindow_leftmost_p); 5574 DEFSUBR (Fwindow_leftmost_p);
5968 DEFSUBR (Fwindow_rightmost_p); 5575 DEFSUBR (Fwindow_rightmost_p);
5969 DEFSUBR (Fpos_visible_in_window_p); 5576 DEFSUBR (Fpos_visible_in_window_p);
5970 DEFSUBR (Fwindow_buffer); 5577 DEFSUBR (Fwindow_buffer);
5971 DEFSUBR (Fwindow_frame); 5578 DEFSUBR (Fwindow_frame);
5972 DEFSUBR (Fwindow_height); 5579 DEFSUBR (Fwindow_height);
5973 DEFSUBR (Fwindow_displayed_height); 5580 DEFSUBR (Fwindow_displayed_height);
5974 DEFSUBR (Fwindow_width); 5581 DEFSUBR (Fwindow_width);
5975 DEFSUBR (Fwindow_full_width);
5976 DEFSUBR (Fwindow_pixel_height); 5582 DEFSUBR (Fwindow_pixel_height);
5977 DEFSUBR (Fwindow_pixel_width); 5583 DEFSUBR (Fwindow_pixel_width);
5978 DEFSUBR (Fwindow_text_area_height);
5979 DEFSUBR (Fwindow_text_area_pixel_height); 5584 DEFSUBR (Fwindow_text_area_pixel_height);
5980 DEFSUBR (Fwindow_displayed_text_pixel_height); 5585 DEFSUBR (Fwindow_displayed_text_pixel_height);
5981 DEFSUBR (Fwindow_text_area_pixel_width); 5586 DEFSUBR (Fwindow_text_area_pixel_width);
5982 DEFSUBR (Fwindow_hscroll); 5587 DEFSUBR (Fwindow_hscroll);
5983 DEFSUBR (Fset_window_hscroll); 5588 #ifdef MODELINE_IS_SCROLLABLE
5984 DEFSUBR (Fmodeline_hscroll); 5589 DEFSUBR (Fmodeline_hscroll);
5985 DEFSUBR (Fset_modeline_hscroll); 5590 DEFSUBR (Fset_modeline_hscroll);
5591 #endif /* MODELINE_IS_SCROLLABLE */
5986 #if 0 /* bogus FSF crock */ 5592 #if 0 /* bogus FSF crock */
5987 DEFSUBR (Fwindow_redisplay_end_trigger); 5593 DEFSUBR (Fwindow_redisplay_end_trigger);
5988 DEFSUBR (Fset_window_redisplay_end_trigger); 5594 DEFSUBR (Fset_window_redisplay_end_trigger);
5989 #endif 5595 #endif
5596 DEFSUBR (Fset_window_hscroll);
5990 DEFSUBR (Fwindow_pixel_edges); 5597 DEFSUBR (Fwindow_pixel_edges);
5991 DEFSUBR (Fwindow_text_area_pixel_edges); 5598 DEFSUBR (Fwindow_text_area_pixel_edges);
5992 DEFSUBR (Fwindow_point); 5599 DEFSUBR (Fwindow_point);
5993 DEFSUBR (Fwindow_start); 5600 DEFSUBR (Fwindow_start);
5994 DEFSUBR (Fwindow_end); 5601 DEFSUBR (Fwindow_end);
5995 DEFSUBR (Fwindow_last_line_visible_height);
5996 DEFSUBR (Fset_window_point); 5602 DEFSUBR (Fset_window_point);
5997 DEFSUBR (Fset_window_start); 5603 DEFSUBR (Fset_window_start);
5998 DEFSUBR (Fwindow_dedicated_p); 5604 DEFSUBR (Fwindow_dedicated_p);
5999 DEFSUBR (Fset_window_dedicated_p); 5605 DEFSUBR (Fset_window_dedicated_p);
6000 DEFSUBR (Fnext_window); 5606 DEFSUBR (Fnext_window);
6030 #endif 5636 #endif
6031 DEFSUBR (Fwindow_configuration_p); 5637 DEFSUBR (Fwindow_configuration_p);
6032 DEFSUBR (Fset_window_configuration); 5638 DEFSUBR (Fset_window_configuration);
6033 DEFSUBR (Fcurrent_window_configuration); 5639 DEFSUBR (Fcurrent_window_configuration);
6034 DEFSUBR (Fsave_window_excursion); 5640 DEFSUBR (Fsave_window_excursion);
6035 DEFSUBR (Fcurrent_pixel_column);
6036 } 5641 }
6037 5642
6038 void 5643 void
6039 reinit_vars_of_window (void) 5644 vars_of_window (void)
6040 { 5645 {
6041 int i;
6042 /* Make sure all windows get marked */ 5646 /* Make sure all windows get marked */
6043 minibuf_window = Qnil; 5647 minibuf_window = Qnil;
6044 staticpro_nodump (&minibuf_window); 5648 staticpro (&minibuf_window);
6045
6046 for (i = 0; i < countof (Vwindow_configuration_free_list); i++)
6047 {
6048 Vwindow_configuration_free_list[i] =
6049 make_lcrecord_list (sizeof_window_config_for_n_windows (i + 1),
6050 &lrecord_window_configuration);
6051 staticpro_nodump (&Vwindow_configuration_free_list[i]);
6052 }
6053 }
6054
6055 void
6056 vars_of_window (void)
6057 {
6058 reinit_vars_of_window ();
6059 5649
6060 DEFVAR_BOOL ("scroll-on-clipped-lines", &scroll_on_clipped_lines /* 5650 DEFVAR_BOOL ("scroll-on-clipped-lines", &scroll_on_clipped_lines /*
6061 *Non-nil means to scroll if point lands on a line which is clipped. 5651 *Non-nil means to scroll if point lands on a line which is clipped.
6062 */ ); 5652 */ );
6063 scroll_on_clipped_lines = 1; 5653 scroll_on_clipped_lines = 1;
6084 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer /* 5674 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer /*
6085 If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. 5675 If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.
6086 */ ); 5676 */ );
6087 Vother_window_scroll_buffer = Qnil; 5677 Vother_window_scroll_buffer = Qnil;
6088 5678
6089 DEFVAR_LISP ("window-pixel-scroll-increment", &Vwindow_pixel_scroll_increment /*
6090 *Number of pixels to scroll by per requested line.
6091 If nil then normal line scrolling occurs regardless of line height.
6092 If t then scrolling is done in increments equal to the height of the default face.
6093 */ );
6094 Vwindow_pixel_scroll_increment = Qt;
6095
6096 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines /* 5679 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines /*
6097 *Number of lines of continuity when scrolling by screenfuls. 5680 *Number of lines of continuity when scrolling by screenfuls.
6098 */ ); 5681 */ );
6099 next_screen_context_lines = 2; 5682 next_screen_context_lines = 2;
6100 5683
6105 5688
6106 DEFVAR_INT ("window-min-width", &window_min_width /* 5689 DEFVAR_INT ("window-min-width", &window_min_width /*
6107 *Delete any window less than this wide. 5690 *Delete any window less than this wide.
6108 */ ); 5691 */ );
6109 window_min_width = 10; 5692 window_min_width = 10;
5693
5694 {
5695 int i;
5696
5697 for (i = 0; i < countof (Vwindow_configuration_free_list); i++)
5698 {
5699 Vwindow_configuration_free_list[i] =
5700 make_lcrecord_list (sizeof_window_config_for_n_windows (i + 1),
5701 &lrecord_window_configuration);
5702 staticpro (&Vwindow_configuration_free_list[i]);
5703 }
5704 }
6110 } 5705 }
6111 5706
6112 void 5707 void
6113 specifier_vars_of_window (void) 5708 specifier_vars_of_window (void)
6114 { 5709 {
6125 set_specifier_fallback (Vmodeline_shadow_thickness, 5720 set_specifier_fallback (Vmodeline_shadow_thickness,
6126 list1 (Fcons (Qnil, Qzero))); 5721 list1 (Fcons (Qnil, Qzero)));
6127 Fadd_spec_to_specifier (Vmodeline_shadow_thickness, make_int (2), 5722 Fadd_spec_to_specifier (Vmodeline_shadow_thickness, make_int (2),
6128 Qnil, Qnil, Qnil); 5723 Qnil, Qnil, Qnil);
6129 set_specifier_caching (Vmodeline_shadow_thickness, 5724 set_specifier_caching (Vmodeline_shadow_thickness,
6130 offsetof (struct window, modeline_shadow_thickness), 5725 slot_offset (struct window,
5726 modeline_shadow_thickness),
6131 modeline_shadow_thickness_changed, 5727 modeline_shadow_thickness_changed,
6132 0, 0); 5728 0, 0);
6133 5729
6134 DEFVAR_SPECIFIER ("has-modeline-p", &Vhas_modeline_p /* 5730 DEFVAR_SPECIFIER ("has-modeline-p", &Vhas_modeline_p /*
6135 *Whether the modeline should be displayed. 5731 *Whether the modeline should be displayed.
6137 */ ); 5733 */ );
6138 Vhas_modeline_p = Fmake_specifier (Qboolean); 5734 Vhas_modeline_p = Fmake_specifier (Qboolean);
6139 set_specifier_fallback (Vhas_modeline_p, 5735 set_specifier_fallback (Vhas_modeline_p,
6140 list1 (Fcons (Qnil, Qt))); 5736 list1 (Fcons (Qnil, Qt)));
6141 set_specifier_caching (Vhas_modeline_p, 5737 set_specifier_caching (Vhas_modeline_p,
6142 offsetof (struct window, has_modeline_p), 5738 slot_offset (struct window,
5739 has_modeline_p),
6143 /* #### It's strange that we need a special 5740 /* #### It's strange that we need a special
6144 flag to indicate that the shadow-thickness 5741 flag to indicate that the shadow-thickness
6145 has changed, but not one to indicate that 5742 has changed, but not one to indicate that
6146 the modeline has been turned off or on. */ 5743 the modeline has been turned off or on. */
6147 some_window_value_changed, 5744 some_window_value_changed,
6159 */ ); 5756 */ );
6160 Vvertical_divider_always_visible_p = Fmake_specifier (Qboolean); 5757 Vvertical_divider_always_visible_p = Fmake_specifier (Qboolean);
6161 set_specifier_fallback (Vvertical_divider_always_visible_p, 5758 set_specifier_fallback (Vvertical_divider_always_visible_p,
6162 list1 (Fcons (Qnil, Qt))); 5759 list1 (Fcons (Qnil, Qt)));
6163 set_specifier_caching (Vvertical_divider_always_visible_p, 5760 set_specifier_caching (Vvertical_divider_always_visible_p,
6164 offsetof (struct window, 5761 slot_offset (struct window,
6165 vertical_divider_always_visible_p), 5762 vertical_divider_always_visible_p),
6166 vertical_divider_changed_in_window, 5763 vertical_divider_changed_in_window,
6167 0, 0); 5764 0, 0);
6168 5765
6169 DEFVAR_SPECIFIER ("vertical-divider-shadow-thickness", &Vvertical_divider_shadow_thickness /* 5766 DEFVAR_SPECIFIER ("vertical-divider-shadow-thickness", &Vvertical_divider_shadow_thickness /*
6170 *How thick to draw 3D shadows around vertical dividers. 5767 *How thick to draw 3D shadows around vertical dividers.
6174 set_specifier_fallback (Vvertical_divider_shadow_thickness, 5771 set_specifier_fallback (Vvertical_divider_shadow_thickness,
6175 list1 (Fcons (Qnil, Qzero))); 5772 list1 (Fcons (Qnil, Qzero)));
6176 Fadd_spec_to_specifier (Vvertical_divider_shadow_thickness, make_int (2), 5773 Fadd_spec_to_specifier (Vvertical_divider_shadow_thickness, make_int (2),
6177 Qnil, Qnil, Qnil); 5774 Qnil, Qnil, Qnil);
6178 set_specifier_caching (Vvertical_divider_shadow_thickness, 5775 set_specifier_caching (Vvertical_divider_shadow_thickness,
6179 offsetof (struct window, 5776 slot_offset (struct window,
6180 vertical_divider_shadow_thickness), 5777 vertical_divider_shadow_thickness),
6181 vertical_divider_changed_in_window, 5778 vertical_divider_changed_in_window,
6182 0, 0); 5779 0, 0);
6183 DEFVAR_SPECIFIER ("vertical-divider-line-width", &Vvertical_divider_line_width /* 5780 DEFVAR_SPECIFIER ("vertical-divider-line-width", &Vvertical_divider_line_width /*
6184 *The width of the vertical dividers, not including shadows. 5781 *The width of the vertical dividers, not including shadows.
6185 5782
6205 fb = Fcons (Fcons (list1 (Qmswindows), make_int (3)), fb); 5802 fb = Fcons (Fcons (list1 (Qmswindows), make_int (3)), fb);
6206 #endif 5803 #endif
6207 set_specifier_fallback (Vvertical_divider_line_width, fb); 5804 set_specifier_fallback (Vvertical_divider_line_width, fb);
6208 } 5805 }
6209 set_specifier_caching (Vvertical_divider_line_width, 5806 set_specifier_caching (Vvertical_divider_line_width,
6210 offsetof (struct window, 5807 slot_offset (struct window,
6211 vertical_divider_line_width), 5808 vertical_divider_line_width),
6212 vertical_divider_changed_in_window, 5809 vertical_divider_changed_in_window,
6213 0, 0); 5810 0, 0);
6214 5811
6215 DEFVAR_SPECIFIER ("vertical-divider-spacing", &Vvertical_divider_spacing /* 5812 DEFVAR_SPECIFIER ("vertical-divider-spacing", &Vvertical_divider_spacing /*
6216 *How much space to leave around the vertical dividers. 5813 *How much space to leave around the vertical dividers.
6235 fb = Fcons (Fcons (list1 (Qmswindows), Qzero), fb); 5832 fb = Fcons (Fcons (list1 (Qmswindows), Qzero), fb);
6236 #endif 5833 #endif
6237 set_specifier_fallback (Vvertical_divider_spacing, fb); 5834 set_specifier_fallback (Vvertical_divider_spacing, fb);
6238 } 5835 }
6239 set_specifier_caching (Vvertical_divider_spacing, 5836 set_specifier_caching (Vvertical_divider_spacing,
6240 offsetof (struct window, vertical_divider_spacing), 5837 slot_offset (struct window,
5838 vertical_divider_spacing),
6241 vertical_divider_changed_in_window, 5839 vertical_divider_changed_in_window,
6242 0, 0); 5840 0, 0);
6243 } 5841 }