comparison src/window.c @ 398:74fd4e045ea6 r21-2-29

Import from CVS: tag r21-2-29
author cvs
date Mon, 13 Aug 2007 11:13:30 +0200
parents bbff43aa5eb7
children a86b2b5e0111
comparison
equal deleted inserted replaced
397:f4aeb21a5bad 398:74fd4e045ea6
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"
41 42
42 Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configurationp; 43 Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configurationp;
43 Lisp_Object Qscroll_up, Qscroll_down, Qdisplay_buffer; 44 Lisp_Object Qdisplay_buffer;
44 45
45 #ifdef MEMORY_USAGE_STATS 46 #ifdef MEMORY_USAGE_STATS
46 Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qother_redisplay; 47 Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qother_redisplay;
47 #ifdef HAVE_SCROLLBARS 48 #ifdef HAVE_SCROLLBARS
48 Lisp_Object Qscrollbar_instances; 49 Lisp_Object Qscrollbar_instances;
82 Lisp_Object Vvertical_divider_line_width; 83 Lisp_Object Vvertical_divider_line_width;
83 84
84 /* Spacing between outer egde of divider border and window edge */ 85 /* Spacing between outer egde of divider border and window edge */
85 Lisp_Object Vvertical_divider_spacing; 86 Lisp_Object Vvertical_divider_spacing;
86 87
88 /* How much to scroll by per-line. */
89 Lisp_Object Vwindow_pixel_scroll_increment;
90
87 /* Scroll if point lands on the bottom line and that line is partially 91 /* Scroll if point lands on the bottom line and that line is partially
88 clipped. */ 92 clipped. */
89 int scroll_on_clipped_lines; 93 int scroll_on_clipped_lines;
90 94
91 /* The minibuffer window of the selected frame. 95 /* The minibuffer window of the selected frame.
115 119
116 /* Number of lines of continuity in scrolling by screenfuls. */ 120 /* Number of lines of continuity in scrolling by screenfuls. */
117 int next_screen_context_lines; 121 int next_screen_context_lines;
118 122
119 /* List of freed window configurations with 1 - 10 windows. */ 123 /* List of freed window configurations with 1 - 10 windows. */
120 Lisp_Object Vwindow_configuration_free_list[10]; 124 static Lisp_Object Vwindow_configuration_free_list[10];
121 125
122 #define SET_LAST_MODIFIED(w, cache_too) \ 126 #define SET_LAST_MODIFIED(w, cache_too) \
123 do { \ 127 do { \
124 (w)->last_modified[CURRENT_DISP] = Qzero; \ 128 (w)->last_modified[CURRENT_DISP] = Qzero; \
125 (w)->last_modified[DESIRED_DISP] = Qzero; \ 129 (w)->last_modified[DESIRED_DISP] = Qzero; \
135 (w)->last_facechange[CMOTION_DISP] = Qzero; \ 139 (w)->last_facechange[CMOTION_DISP] = Qzero; \
136 } while (0) 140 } while (0)
137 141
138 142
139 #define MARK_DISP_VARIABLE(field) \ 143 #define MARK_DISP_VARIABLE(field) \
140 markobj (window->field[CURRENT_DISP]); \ 144 mark_object (window->field[CURRENT_DISP]); \
141 markobj (window->field[DESIRED_DISP]); \ 145 mark_object (window->field[DESIRED_DISP]); \
142 markobj (window->field[CMOTION_DISP]); 146 mark_object (window->field[CMOTION_DISP]);
143 147
144 static Lisp_Object 148 static Lisp_Object
145 mark_window (Lisp_Object obj, void (*markobj) (Lisp_Object)) 149 mark_window (Lisp_Object obj)
146 { 150 {
147 struct window *window = XWINDOW (obj); 151 struct window *window = XWINDOW (obj);
148 markobj (window->frame); 152 mark_object (window->frame);
149 markobj (window->mini_p); 153 mark_object (window->mini_p);
150 markobj (window->next); 154 mark_object (window->next);
151 markobj (window->prev); 155 mark_object (window->prev);
152 markobj (window->hchild); 156 mark_object (window->hchild);
153 markobj (window->vchild); 157 mark_object (window->vchild);
154 markobj (window->parent); 158 mark_object (window->parent);
155 markobj (window->buffer); 159 mark_object (window->buffer);
156 MARK_DISP_VARIABLE (start); 160 MARK_DISP_VARIABLE (start);
157 MARK_DISP_VARIABLE (pointm); 161 MARK_DISP_VARIABLE (pointm);
158 markobj (window->sb_point); /* #### move to scrollbar.c? */ 162 mark_object (window->sb_point); /* #### move to scrollbar.c? */
159 markobj (window->use_time); 163 mark_object (window->use_time);
160 MARK_DISP_VARIABLE (last_modified); 164 MARK_DISP_VARIABLE (last_modified);
161 MARK_DISP_VARIABLE (last_point); 165 MARK_DISP_VARIABLE (last_point);
162 MARK_DISP_VARIABLE (last_start); 166 MARK_DISP_VARIABLE (last_start);
163 MARK_DISP_VARIABLE (last_facechange); 167 MARK_DISP_VARIABLE (last_facechange);
164 markobj (window->line_cache_last_updated); 168 mark_object (window->line_cache_last_updated);
165 markobj (window->redisplay_end_trigger); 169 mark_object (window->redisplay_end_trigger);
166 markobj (window->subwindow_instance_cache); 170 mark_object (window->subwindow_instance_cache);
167 171
168 mark_face_cachels (window->face_cachels, markobj); 172 mark_face_cachels (window->face_cachels);
169 mark_glyph_cachels (window->glyph_cachels, markobj); 173 mark_glyph_cachels (window->glyph_cachels);
170 174
171 #define WINDOW_SLOT(slot, compare) ((void) (markobj (window->slot))) 175 #define WINDOW_SLOT(slot, compare) mark_object (window->slot)
172 #include "winslots.h" 176 #include "winslots.h"
173 177
174 return Qnil; 178 return Qnil;
175 } 179 }
176 180
229 } 233 }
230 } 234 }
231 235
232 DEFINE_LRECORD_IMPLEMENTATION ("window", window, 236 DEFINE_LRECORD_IMPLEMENTATION ("window", window,
233 mark_window, print_window, finalize_window, 237 mark_window, print_window, finalize_window,
234 0, 0, struct window); 238 0, 0, 0, struct window);
235 239
236 240
237 #define INIT_DISP_VARIABLE(field, initialization) \ 241 #define INIT_DISP_VARIABLE(field, initialization) \
238 p->field[CURRENT_DISP] = initialization; \ 242 p->field[CURRENT_DISP] = initialization; \
239 p->field[DESIRED_DISP] = initialization; \ 243 p->field[DESIRED_DISP] = initialization; \
250 reset_face_cachels will fail. */ 254 reset_face_cachels will fail. */
251 Lisp_Object 255 Lisp_Object
252 allocate_window (void) 256 allocate_window (void)
253 { 257 {
254 Lisp_Object val; 258 Lisp_Object val;
255 struct window *p = alloc_lcrecord_type (struct window, lrecord_window); 259 struct window *p = alloc_lcrecord_type (struct window, &lrecord_window);
256 260
257 zero_lcrecord (p); 261 zero_lcrecord (p);
258 XSETWINDOW (val, p); 262 XSETWINDOW (val, p);
259 263
260 p->dead = 0; 264 p->dead = 0;
639 window_full_width_p (struct window *w) 643 window_full_width_p (struct window *w)
640 { 644 {
641 return window_is_leftmost (w) && window_is_rightmost (w); 645 return window_is_leftmost (w) && window_is_rightmost (w);
642 } 646 }
643 647
644 static int 648 int
645 window_is_highest (struct window *w) 649 window_is_highest (struct window *w)
646 { 650 {
647 Lisp_Object parent, current_ancestor, window; 651 Lisp_Object parent, current_ancestor, window;
648 652
649 XSETWINDOW (window, w); 653 XSETWINDOW (window, w);
667 return 1; 671 return 1;
668 else 672 else
669 return 0; 673 return 0;
670 } 674 }
671 675
672 static int 676 int
673 window_is_lowest (struct window *w) 677 window_is_lowest (struct window *w)
674 { 678 {
675 Lisp_Object parent, current_ancestor, window; 679 Lisp_Object parent, current_ancestor, window;
676 680
677 XSETWINDOW (window, w); 681 XSETWINDOW (window, w);
703 #endif 707 #endif
704 708
705 int 709 int
706 window_truncation_on (struct window *w) 710 window_truncation_on (struct window *w)
707 { 711 {
712 /* Minibuffer windows are never truncated.
713 #### is this the right way ? */
714 if (MINI_WINDOW_P (w))
715 return 0;
716
708 /* Horizontally scrolled windows are truncated. */ 717 /* Horizontally scrolled windows are truncated. */
709 if (w->hscroll) 718 if (w->hscroll)
710 return 1; 719 return 1;
711 720
712 /* If truncate_partial_width_windows is true and the window is not 721 /* If truncate_partial_width_windows is true and the window is not
720 if (!NILP (XBUFFER (w->buffer)->truncate_lines)) 729 if (!NILP (XBUFFER (w->buffer)->truncate_lines))
721 return 1; 730 return 1;
722 731
723 return 0; 732 return 0;
724 } 733 }
734
735 DEFUN ("window-truncated-p", Fwindow_truncated_p, 0, 1, 0, /*
736 Returns non-nil if text in the window is truncated.
737 */
738 (window))
739 {
740 struct window *w = decode_window (window);
741
742 return window_truncation_on (w) ? Qt : Qnil;
743 }
744
725 745
726 static int 746 static int
727 have_undivided_common_edge (struct window *w_right, void *closure) 747 have_undivided_common_edge (struct window *w_right, void *closure)
728 { 748 {
729 struct window *w_left = (struct window *) closure; 749 struct window *w_left = (struct window *) closure;
970 window_right_margin_width (struct window *w) 990 window_right_margin_width (struct window *w)
971 { 991 {
972 return margin_width_internal (w, 0); 992 return margin_width_internal (w, 0);
973 } 993 }
974 994
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
1001 /***************************************************************************** 995 /*****************************************************************************
1002 Window Gutters 996 Window Gutters
1003 997
1004 The gutters of a window are those areas in the boundary defined by 998 The gutters of a window are those areas in the boundary defined by
1005 w->pixel_top, w->pixel_left, w->pixel_height and w->pixel_width which 999 w->pixel_top, w->pixel_left, w->pixel_height and w->pixel_width which
1017 ****************************************************************************/ 1011 ****************************************************************************/
1018 1012
1019 int 1013 int
1020 window_top_gutter_height (struct window *w) 1014 window_top_gutter_height (struct window *w)
1021 { 1015 {
1022 int toolbar_height = window_top_toolbar_height (w); 1016 int gutter = WINDOW_REAL_TOP_GUTTER_BOUNDS (w);
1023 1017
1024 if (!NILP (w->hchild) || !NILP (w->vchild)) 1018 if (!NILP (w->hchild) || !NILP (w->vchild))
1025 return 0; 1019 return 0;
1026 1020
1027 #ifdef HAVE_SCROLLBARS 1021 #ifdef HAVE_SCROLLBARS
1028 if (!NILP (w->scrollbar_on_top_p)) 1022 if (!NILP (w->scrollbar_on_top_p))
1029 return window_scrollbar_height (w) + toolbar_height; 1023 return window_scrollbar_height (w) + gutter;
1030 else 1024 else
1031 #endif 1025 #endif
1032 return toolbar_height; 1026 return gutter;
1033 } 1027 }
1034 1028
1035 int 1029 int
1036 window_bottom_gutter_height (struct window *w) 1030 window_bottom_gutter_height (struct window *w)
1037 { 1031 {
1038 int other_height; 1032 int gutter = WINDOW_REAL_BOTTOM_GUTTER_BOUNDS (w);
1039 1033
1040 if (!NILP (w->hchild) || !NILP (w->vchild)) 1034 if (!NILP (w->hchild) || !NILP (w->vchild))
1041 return 0; 1035 return 0;
1042 else 1036
1043 other_height = 1037 gutter += window_modeline_height (w);
1044 window_modeline_height (w) + window_bottom_toolbar_height (w);
1045 1038
1046 #ifdef HAVE_SCROLLBARS 1039 #ifdef HAVE_SCROLLBARS
1047 if (NILP (w->scrollbar_on_top_p)) 1040 if (NILP (w->scrollbar_on_top_p))
1048 return window_scrollbar_height (w) + other_height; 1041 return window_scrollbar_height (w) + gutter;
1049 else 1042 else
1050 #endif 1043 #endif
1051 return other_height; 1044 return gutter;
1052 } 1045 }
1053 1046
1054 int 1047 int
1055 window_left_gutter_width (struct window *w, int modeline) 1048 window_left_gutter_width (struct window *w, int modeline)
1056 { 1049 {
1057 int gutter = window_left_toolbar_width (w); 1050 int gutter = WINDOW_REAL_LEFT_GUTTER_BOUNDS (w);
1058 1051
1059 if (!NILP (w->hchild) || !NILP (w->vchild)) 1052 if (!NILP (w->hchild) || !NILP (w->vchild))
1060 return 0; 1053 return 0;
1061
1062 1054
1063 #ifdef HAVE_SCROLLBARS 1055 #ifdef HAVE_SCROLLBARS
1064 if (!modeline && !NILP (w->scrollbar_on_left_p)) 1056 if (!modeline && !NILP (w->scrollbar_on_left_p))
1065 gutter += window_scrollbar_width (w); 1057 gutter += window_scrollbar_width (w);
1066 #endif 1058 #endif
1069 } 1061 }
1070 1062
1071 int 1063 int
1072 window_right_gutter_width (struct window *w, int modeline) 1064 window_right_gutter_width (struct window *w, int modeline)
1073 { 1065 {
1074 int gutter = window_right_toolbar_width (w); 1066 int gutter = WINDOW_REAL_RIGHT_GUTTER_BOUNDS (w);
1075 1067
1076 if (!NILP (w->hchild) || !NILP (w->vchild)) 1068 if (!NILP (w->hchild) || !NILP (w->vchild))
1077 return 0; 1069 return 0;
1078 1070
1079 #ifdef HAVE_SCROLLBARS 1071 #ifdef HAVE_SCROLLBARS
1121 struct frame *f = decode_frame_or_selected (con_dev_or_frame); 1113 struct frame *f = decode_frame_or_selected (con_dev_or_frame);
1122 return FRAME_SELECTED_WINDOW (f); 1114 return FRAME_SELECTED_WINDOW (f);
1123 } 1115 }
1124 } 1116 }
1125 1117
1118 DEFUN ("last-nonminibuf-window", Flast_nonminibuf_window, 0, 1, 0, /*
1119 Return the last selected window that is not a minibuffer window.
1120 If the optional argument CON-DEV-OR-FRAME is specified and is a frame,
1121 return the last non-minibuffer window used by that frame. If
1122 CON-DEV-OR-FRAME is a device, then the selected frame on that device
1123 will be used. If CON-DEV-OR-FRAME is a console, the selected frame on
1124 that console's selected device will be used. Otherwise, the selected
1125 frame is used.
1126 */
1127 (con_dev_or_frame))
1128 {
1129 if (NILP (con_dev_or_frame) && NILP (Fselected_device (Qnil)))
1130 return Qnil; /* happens at startup */
1131
1132 {
1133 struct frame *f = decode_frame_or_selected (con_dev_or_frame);
1134 return FRAME_LAST_NONMINIBUF_WINDOW (f);
1135 }
1136 }
1137
1126 DEFUN ("minibuffer-window", Fminibuffer_window, 0, 1, 0, /* 1138 DEFUN ("minibuffer-window", Fminibuffer_window, 0, 1, 0, /*
1127 Return the window used now for minibuffers. 1139 Return the window used now for minibuffers.
1128 If the optional argument CON-DEV-OR-FRAME is specified and is a frame, return 1140 If the optional argument CON-DEV-OR-FRAME is specified and is a frame, return
1129 the minibuffer window used by that frame. If CON-DEV-OR-FRAME is a device, 1141 the minibuffer window used by that frame. If CON-DEV-OR-FRAME is a device,
1130 then the selected frame on that device will be used. If CON-DEV-OR-FRAME 1142 then the selected frame on that device will be used. If CON-DEV-OR-FRAME
1134 (con_dev_or_frame)) 1146 (con_dev_or_frame))
1135 { 1147 {
1136 return FRAME_MINIBUF_WINDOW (decode_frame_or_selected (con_dev_or_frame)); 1148 return FRAME_MINIBUF_WINDOW (decode_frame_or_selected (con_dev_or_frame));
1137 } 1149 }
1138 1150
1139 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, 1, 1, 0, /* 1151 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, 0, 1, 0, /*
1140 Return non-nil if WINDOW is a minibuffer window. 1152 Return non-nil if WINDOW is a minibuffer window.
1141 */ 1153 */
1142 (window)) 1154 (window))
1143 { 1155 {
1144 return MINI_WINDOW_P (decode_window (window)) ? Qt : Qnil; 1156 return MINI_WINDOW_P (decode_window (window)) ? Qt : Qnil;
1343 line_start_cache_dynarr *cache; 1355 line_start_cache_dynarr *cache;
1344 1356
1345 if (NILP (window)) 1357 if (NILP (window))
1346 window = Fselected_window (Qnil); 1358 window = Fselected_window (Qnil);
1347 1359
1348 CHECK_WINDOW (window); 1360 CHECK_LIVE_WINDOW (window);
1349 w = XWINDOW (window); 1361 w = XWINDOW (window);
1350 1362
1351 start = marker_position (w->start[CURRENT_DISP]); 1363 start = marker_position (w->start[CURRENT_DISP]);
1352 hlimit = WINDOW_TEXT_HEIGHT (w); 1364 hlimit = WINDOW_TEXT_HEIGHT (w);
1353 eobuf = BUF_ZV (XBUFFER (w->buffer)); 1365 eobuf = BUF_ZV (XBUFFER (w->buffer));
1423 (window)) 1435 (window))
1424 { 1436 {
1425 return make_int (decode_window (window)->hscroll); 1437 return make_int (decode_window (window)->hscroll);
1426 } 1438 }
1427 1439
1428 #ifdef MODELINE_IS_SCROLLABLE
1429 DEFUN ("modeline-hscroll", Fmodeline_hscroll, 0, 1, 0, /* 1440 DEFUN ("modeline-hscroll", Fmodeline_hscroll, 0, 1, 0, /*
1430 Return the number of columns by which WINDOW's modeline is scrolled from 1441 Return the horizontal scrolling ammount of WINDOW's modeline.
1431 left margin. If the window has no modeline, return nil. 1442 If the window has no modeline, return nil.
1432 */ 1443 */
1433 (window)) 1444 (window))
1434 { 1445 {
1435 struct window *w = decode_window (window); 1446 struct window *w = decode_window (window);
1436 1447
1437 return (WINDOW_HAS_MODELINE_P (w)) ? make_int (w->modeline_hscroll) : Qnil; 1448 return (WINDOW_HAS_MODELINE_P (w)) ? make_int ((int) w->modeline_hscroll) :
1449 Qnil;
1438 } 1450 }
1439 1451
1440 DEFUN ("set-modeline-hscroll", Fset_modeline_hscroll, 2, 2, 0, /* 1452 DEFUN ("set-modeline-hscroll", Fset_modeline_hscroll, 2, 2, 0, /*
1441 Set number of columns WINDOW's modeline is scrolled from left margin to NCOL. 1453 Set the horizontal scrolling ammount of WINDOW's modeline to NCOL.
1442 NCOL should be zero or positive. If NCOL is negative, it will be forced to 0. 1454 If NCOL is negative, it will silently be forced to 0.
1443 If the window has no modeline, do nothing and return nil. 1455 If the window has no modeline, return nil. Otherwise, return the actual
1456 value that was set.
1444 */ 1457 */
1445 (window, ncol)) 1458 (window, ncol))
1446 { 1459 {
1447 struct window *w = decode_window (window); 1460 struct window *w = decode_window (window);
1448 1461
1449 if (WINDOW_HAS_MODELINE_P (w)) 1462 if (WINDOW_HAS_MODELINE_P (w))
1450 { 1463 {
1451 int ncols; 1464 Charcount ncols;
1465
1452 CHECK_INT (ncol); 1466 CHECK_INT (ncol);
1453 ncols = XINT (ncol); 1467 ncols = (XINT (ncol) <= 0) ? 0 : (Charcount) XINT (ncol);
1454 if (ncols < 0) ncols = 0; 1468 if (ncols != w->modeline_hscroll)
1455 if (w->modeline_hscroll != ncols) 1469 {
1456 MARK_MODELINE_CHANGED; 1470 MARK_MODELINE_CHANGED;
1457 w->modeline_hscroll = ncols; 1471 w->modeline_hscroll = ncols;
1458 return ncol; 1472 }
1459 } 1473 return make_int ((int) ncols);
1474 }
1475
1460 return Qnil; 1476 return Qnil;
1461 } 1477 }
1462 #endif /* MODELINE_IS_SCROLLABLE */
1463 1478
1464 DEFUN ("set-window-hscroll", Fset_window_hscroll, 2, 2, 0, /* 1479 DEFUN ("set-window-hscroll", Fset_window_hscroll, 2, 2, 0, /*
1465 Set number of columns WINDOW is scrolled from left margin to NCOL. 1480 Set number of columns WINDOW is scrolled from left margin to NCOL.
1466 NCOL should be zero or positive. 1481 NCOL should be zero or positive.
1467 */ 1482 */
1604 else 1619 else
1605 { 1620 {
1606 Bufpos startp = marker_position (w->start[CURRENT_DISP]); 1621 Bufpos startp = marker_position (w->start[CURRENT_DISP]);
1607 return make_int (end_of_last_line (w, startp)); 1622 return make_int (end_of_last_line (w, startp));
1608 } 1623 }
1624 }
1625
1626 DEFUN ("window-last-line-visible-height", Fwindow_last_line_visible_height, 0, 1, 0, /*
1627 Return pixel height of visible part of last window line if it is clipped.
1628 If the last line is not clipped, return nil.
1629 */
1630 (window))
1631 {
1632 struct window *w = decode_window (window);
1633 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
1634 int num_lines = Dynarr_length (dla);
1635 struct display_line *dl;
1636
1637 /* No lines - no clipped lines */
1638 if (num_lines == 0 || (num_lines == 1 && Dynarr_atp (dla, 0)->modeline))
1639 return Qnil;
1640
1641 dl = Dynarr_atp (dla, num_lines - 1);
1642 if (dl->clip == 0)
1643 return Qnil;
1644
1645 return make_int (dl->ascent + dl->descent - dl->clip);
1609 } 1646 }
1610 1647
1611 DEFUN ("set-window-point", Fset_window_point, 2, 2, 0, /* 1648 DEFUN ("set-window-point", Fset_window_point, 2, 2, 0, /*
1612 Make point value in WINDOW be at position POS in WINDOW's buffer. 1649 Make point value in WINDOW be at position POS in WINDOW's buffer.
1613 */ 1650 */
1851 /* At this point, we know the window has a parent. */ 1888 /* At this point, we know the window has a parent. */
1852 parent = w->parent; 1889 parent = w->parent;
1853 par = XWINDOW (parent); 1890 par = XWINDOW (parent);
1854 1891
1855 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f); 1892 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
1893 /* It's quite likely that deleting a window will result in
1894 subwindows needing to be deleted also (since they are cached
1895 per-window). So we mark them as changed, so that the cachels will
1896 get reset by redisplay and thus deleted subwindows can get
1897 GC'd. */
1898 MARK_FRAME_SUBWINDOWS_CHANGED (f);
1856 1899
1857 /* Are we trying to delete any frame's selected window? 1900 /* Are we trying to delete any frame's selected window?
1858 Note that we could be dealing with a non-leaf window 1901 Note that we could be dealing with a non-leaf window
1859 where the selected window is one of our children. 1902 where the selected window is one of our children.
1860 So, we check by scanning all the ancestors of the 1903 So, we check by scanning all the ancestors of the
2582 { 2625 {
2583 Lisp_Object new_buffer; 2626 Lisp_Object new_buffer;
2584 new_buffer = Fother_buffer (obj, Qnil, Qnil); 2627 new_buffer = Fother_buffer (obj, Qnil, Qnil);
2585 if (NILP (new_buffer)) 2628 if (NILP (new_buffer))
2586 new_buffer = Fget_buffer_create (QSscratch); 2629 new_buffer = Fget_buffer_create (QSscratch);
2587 Fset_window_buffer (w, new_buffer); 2630 Fset_window_buffer (w, new_buffer, Qnil);
2588 if (EQ (w, Fselected_window (Qnil))) 2631 if (EQ (w, Fselected_window (Qnil)))
2589 Fset_buffer (p->buffer); 2632 Fset_buffer (p->buffer);
2590 } 2633 }
2591 else 2634 else
2592 Fdelete_window (w, Qnil); 2635 Fdelete_window (w, Qnil);
2654 else 2697 else
2655 { 2698 {
2656 /* Otherwise show a different buffer in the 2699 /* Otherwise show a different buffer in the
2657 window. */ 2700 window. */
2658 p->dedicated = Qnil; 2701 p->dedicated = Qnil;
2659 Fset_window_buffer (w, another_buffer); 2702 Fset_window_buffer (w, another_buffer, Qnil);
2660 if (EQ (w, Fselected_window (Qnil))) 2703 if (EQ (w, Fselected_window (Qnil)))
2661 Fset_buffer (p->buffer); 2704 Fset_buffer (p->buffer);
2662 } 2705 }
2663 } 2706 }
2664 break; 2707 break;
2955 window_min_width = MIN_SAFE_WINDOW_WIDTH; 2998 window_min_width = MIN_SAFE_WINDOW_WIDTH;
2956 if (window_min_height < MIN_SAFE_WINDOW_HEIGHT) 2999 if (window_min_height < MIN_SAFE_WINDOW_HEIGHT)
2957 window_min_height = MIN_SAFE_WINDOW_HEIGHT; 3000 window_min_height = MIN_SAFE_WINDOW_HEIGHT;
2958 } 3001 }
2959 3002
3003 static int
3004 frame_min_height (struct frame *frame)
3005 {
3006 /* For height, we have to see whether the frame has a minibuffer, and
3007 whether it wants a modeline. */
3008 return (FRAME_MINIBUF_ONLY_P (frame) ? MIN_SAFE_WINDOW_HEIGHT - 1
3009 : (! FRAME_HAS_MINIBUF_P (frame)) ? MIN_SAFE_WINDOW_HEIGHT
3010 : 2 * MIN_SAFE_WINDOW_HEIGHT - 1);
3011 }
3012
3013 /* Return non-zero if both frame sizes are less than or equal to
3014 minimal allowed values. ROWS and COLS are in characters */
3015 int
3016 frame_size_valid_p (struct frame *frame, int rows, int cols)
3017 {
3018 return (rows >= frame_min_height (frame)
3019 && cols >= MIN_SAFE_WINDOW_WIDTH);
3020 }
3021
3022 /* Return non-zero if both frame sizes are less than or equal to
3023 minimal allowed values. WIDTH and HEIGHT are in pixels */
3024 int
3025 frame_pixsize_valid_p (struct frame *frame, int width, int height)
3026 {
3027 int rows, cols;
3028 pixel_to_real_char_size (frame, width, height, &cols, &rows);
3029 return frame_size_valid_p (frame, rows, cols);
3030 }
3031
2960 /* If *ROWS or *COLS are too small a size for FRAME, set them to the 3032 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
2961 minimum allowable size. */ 3033 minimum allowable size. */
2962 void 3034 void
2963 check_frame_size (struct frame *frame, int *rows, int *cols) 3035 check_frame_size (struct frame *frame, int *rows, int *cols)
2964 { 3036 {
2965 /* For height, we have to see whether the frame has a minibuffer, and 3037 int min_height = frame_min_height (frame);
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);
2971 3038
2972 if (*rows < min_height) 3039 if (*rows < min_height)
2973 *rows = min_height; 3040 *rows = min_height;
2974 if (*cols < MIN_SAFE_WINDOW_WIDTH) 3041 if (*cols < MIN_SAFE_WINDOW_WIDTH)
2975 *cols = MIN_SAFE_WINDOW_WIDTH; 3042 *cols = MIN_SAFE_WINDOW_WIDTH;
3115 } 3182 }
3116 3183
3117 3184
3118 static int window_select_count; 3185 static int window_select_count;
3119 3186
3120 DEFUN ("set-window-buffer", Fset_window_buffer, 2, 2, 0, /* 3187 DEFUN ("set-window-buffer", Fset_window_buffer, 2, 3, 0, /*
3121 Make WINDOW display BUFFER as its contents. 3188 Make WINDOW display BUFFER as its contents.
3122 BUFFER can be a buffer or buffer name. 3189 BUFFER can be a buffer or buffer name.
3123 */ 3190
3124 (window, buffer)) 3191 With non-nil optional argument `norecord', do not modify the
3192 global or per-frame buffer ordering.
3193 */
3194 (window, buffer, norecord))
3125 { 3195 {
3126 Lisp_Object tem; 3196 Lisp_Object tem;
3127 struct window *w = decode_window (window); 3197 struct window *w = decode_window (window);
3128 3198
3129 buffer = Fget_buffer (buffer); 3199 buffer = Fget_buffer (buffer);
3178 SET_LAST_FACECHANGE (w); 3248 SET_LAST_FACECHANGE (w);
3179 MARK_WINDOWS_CHANGED (w); 3249 MARK_WINDOWS_CHANGED (w);
3180 recompute_all_cached_specifiers_in_window (w); 3250 recompute_all_cached_specifiers_in_window (w);
3181 if (EQ (window, Fselected_window (Qnil))) 3251 if (EQ (window, Fselected_window (Qnil)))
3182 { 3252 {
3253 if (NILP (norecord))
3254 Frecord_buffer (buffer);
3255
3183 Fset_buffer (buffer); 3256 Fset_buffer (buffer);
3184 } 3257 }
3185 return Qnil; 3258 return Qnil;
3186 } 3259 }
3187 3260
3317 static void 3390 static void
3318 make_dummy_parent (Lisp_Object window) 3391 make_dummy_parent (Lisp_Object window)
3319 { 3392 {
3320 Lisp_Object new; 3393 Lisp_Object new;
3321 struct window *o = XWINDOW (window); 3394 struct window *o = XWINDOW (window);
3322 struct window *p = alloc_lcrecord_type (struct window, lrecord_window); 3395 struct window *p = alloc_lcrecord_type (struct window, &lrecord_window);
3323 3396
3324 XSETWINDOW (new, p); 3397 XSETWINDOW (new, p);
3325 copy_lcrecord (p, o); 3398 copy_lcrecord (p, o);
3326 3399
3327 /* Don't copy the pointers to the line start cache or the face 3400 /* Don't copy the pointers to the line start cache or the face
3364 int psize; 3437 int psize;
3365 3438
3366 if (NILP (window)) 3439 if (NILP (window))
3367 window = Fselected_window (Qnil); 3440 window = Fselected_window (Qnil);
3368 else 3441 else
3369 CHECK_WINDOW (window); 3442 CHECK_LIVE_WINDOW (window);
3370 3443
3371 o = XWINDOW (window); 3444 o = XWINDOW (window);
3372 f = XFRAME (WINDOW_FRAME (o)); 3445 f = XFRAME (WINDOW_FRAME (o));
3373 3446
3374 if (NILP (chsize)) 3447 if (NILP (chsize))
3480 3553
3481 XFRAME (p->frame)->mirror_dirty = 1; 3554 XFRAME (p->frame)->mirror_dirty = 1;
3482 /* do this last (after the window is completely initialized and 3555 /* do this last (after the window is completely initialized and
3483 the mirror-dirty flag is set) so that specifier recomputation 3556 the mirror-dirty flag is set) so that specifier recomputation
3484 caused as a result of this will work properly and not abort. */ 3557 caused as a result of this will work properly and not abort. */
3485 Fset_window_buffer (new, o->buffer); 3558 Fset_window_buffer (new, o->buffer, Qt);
3486 return new; 3559 return new;
3487 } 3560 }
3488 3561
3489 3562
3490 DEFUN ("enlarge-window", Fenlarge_window, 1, 3, "_p", /* 3563 DEFUN ("enlarge-window", Fenlarge_window, 1, 3, "_p", /*
3924 } 3997 }
3925 3998
3926 SET_LAST_MODIFIED (w, 0); 3999 SET_LAST_MODIFIED (w, 0);
3927 SET_LAST_FACECHANGE (w); 4000 SET_LAST_FACECHANGE (w);
3928 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f); 4001 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f);
4002 /* overkill maybe, but better to be correct */
4003 MARK_FRAME_GUTTERS_CHANGED (f);
3929 } 4004 }
3930 #undef MINSIZE 4005 #undef MINSIZE
3931 #undef CURBEG 4006 #undef CURBEG
3932 #undef CURSIZE 4007 #undef CURSIZE
3933 #undef CURCHARSIZE 4008 #undef CURCHARSIZE
3934 #undef MINCHARSIZE 4009 #undef MINCHARSIZE
3935 4010
3936 4011
3937 4012
3938 /* Scroll contents of window WINDOW up N lines. */ 4013 /* Scroll contents of window WINDOW up N lines. If N < (top line height /
4014 average line height) then we just adjust the top clip. */
3939 void 4015 void
3940 window_scroll (Lisp_Object window, Lisp_Object n, int direction, 4016 window_scroll (Lisp_Object window, Lisp_Object n, int direction,
3941 Error_behavior errb) 4017 Error_behavior errb)
3942 { 4018 {
3943 struct window *w = XWINDOW (window); 4019 struct window *w = XWINDOW (window);
3944 struct buffer *b = XBUFFER (w->buffer); 4020 struct buffer *b = XBUFFER (w->buffer);
3945 int selected = EQ (window, Fselected_window (Qnil)); 4021 int selected = EQ (window, Fselected_window (Qnil));
3946 int value = 0; 4022 int value = 0;
3947 Lisp_Object point, tem; 4023 Lisp_Object point, tem;
4024 display_line_dynarr *dla;
4025 int fheight, fwidth, modeline = 0;
4026 struct display_line* dl;
3948 4027
3949 if (selected) 4028 if (selected)
3950 point = make_int (BUF_PT (b)); 4029 point = make_int (BUF_PT (b));
3951 else 4030 else
3952 { 4031 {
3972 { 4051 {
3973 Fvertical_motion (make_int (-window_char_height (w, 0) / 2), 4052 Fvertical_motion (make_int (-window_char_height (w, 0) / 2),
3974 window, Qnil); 4053 window, Qnil);
3975 Fset_marker (w->start[CURRENT_DISP], point, w->buffer); 4054 Fset_marker (w->start[CURRENT_DISP], point, w->buffer);
3976 w->start_at_line_beg = beginning_of_line_p (b, XINT (point)); 4055 w->start_at_line_beg = beginning_of_line_p (b, XINT (point));
4056 WINDOW_TEXT_TOP_CLIP (w) = 0;
3977 MARK_WINDOWS_CHANGED (w); 4057 MARK_WINDOWS_CHANGED (w);
3978 } 4058 }
3979 4059
3980 if (!NILP (n)) 4060 if (!NILP (n))
3981 { 4061 {
4015 4095
4016 if (direction == 1 && !value) 4096 if (direction == 1 && !value)
4017 { 4097 {
4018 return; 4098 return;
4019 } 4099 }
4020 else if (value > 0) 4100
4021 { 4101 /* Determine parameters to test for partial line scrolling with. */
4022 int vtarget; 4102 dla = window_display_lines (w, CURRENT_DISP);
4023 Bufpos startp, old_start; 4103
4024 4104 if (INTP (Vwindow_pixel_scroll_increment))
4025 old_start = marker_position (w->start[CURRENT_DISP]); 4105 fheight = XINT (Vwindow_pixel_scroll_increment);
4026 startp = vmotion (w, old_start, value, &vtarget); 4106 else if (!NILP (Vwindow_pixel_scroll_increment))
4027 4107 default_face_height_and_width (window, &fheight, &fwidth);
4028 if (vtarget < value && 4108
4029 (w->window_end_pos[CURRENT_DISP] == -1 4109 if (Dynarr_length (dla) >= 1)
4030 || (BUF_Z (b) - w->window_end_pos[CURRENT_DISP] > BUF_ZV (b)))) 4110 modeline = Dynarr_atp (dla, 0)->modeline;
4111
4112 dl = Dynarr_atp (dla, modeline);
4113
4114 if (value > 0)
4115 {
4116 /* Go for partial display line scrolling. This just means bumping
4117 the clip by a reasonable amount and redisplaying, everything else
4118 remains unchanged. */
4119 if (!NILP (Vwindow_pixel_scroll_increment)
4120 &&
4121 Dynarr_length (dla) >= (1 + modeline)
4122 &&
4123 (dl->ascent - dl->top_clip) - fheight * value > 0)
4031 { 4124 {
4032 maybe_signal_error (Qend_of_buffer, Qnil, Qwindow, errb); 4125 WINDOW_TEXT_TOP_CLIP (w) += value * fheight;
4033 return; 4126 MARK_WINDOWS_CHANGED (w);
4034 } 4127 }
4035 else 4128 else
4036 { 4129 {
4037 set_marker_restricted (w->start[CURRENT_DISP], make_int (startp), 4130 int vtarget;
4038 w->buffer); 4131 Bufpos startp, old_start;
4039 w->force_start = 1; 4132
4040 w->start_at_line_beg = beginning_of_line_p (b, startp); 4133 if (WINDOW_TEXT_TOP_CLIP (w))
4041 MARK_WINDOWS_CHANGED (w);
4042
4043 if (!point_would_be_visible (w, startp, XINT (point)))
4044 { 4134 {
4045 if (selected) 4135 WINDOW_TEXT_TOP_CLIP (w) = 0;
4046 BUF_SET_PT (b, startp); 4136 MARK_WINDOWS_CHANGED (w);
4047 else 4137 }
4048 set_marker_restricted (w->pointm[CURRENT_DISP], 4138
4049 make_int (startp), 4139 old_start = marker_position (w->start[CURRENT_DISP]);
4050 w->buffer); 4140 startp = vmotion (w, old_start, value, &vtarget);
4141
4142 if (vtarget < value &&
4143 (w->window_end_pos[CURRENT_DISP] == -1
4144 || (BUF_Z (b) - w->window_end_pos[CURRENT_DISP] > BUF_ZV (b))))
4145 {
4146 maybe_signal_error (Qend_of_buffer, Qnil, Qwindow, errb);
4147 return;
4148 }
4149 else
4150 {
4151 set_marker_restricted (w->start[CURRENT_DISP], make_int (startp),
4152 w->buffer);
4153 w->force_start = 1;
4154 w->start_at_line_beg = beginning_of_line_p (b, startp);
4155 MARK_WINDOWS_CHANGED (w);
4156
4157 if (!point_would_be_visible (w, startp, XINT (point)))
4158 {
4159 if (selected)
4160 BUF_SET_PT (b, startp);
4161 else
4162 set_marker_restricted (w->pointm[CURRENT_DISP],
4163 make_int (startp),
4164 w->buffer);
4165 }
4051 } 4166 }
4052 } 4167 }
4053 } 4168 }
4054 else if (value < 0) 4169 else if (value < 0)
4055 { 4170 {
4056 int vtarget; 4171 /* Go for partial display line scrolling. This just means bumping
4057 Bufpos startp, old_start; 4172 the clip by a reasonable amount and redisplaying, everything else
4058 4173 remains unchanged. */
4059 old_start = marker_position (w->start[CURRENT_DISP]); 4174 if (!NILP (Vwindow_pixel_scroll_increment)
4060 startp = vmotion (w, old_start, value, &vtarget); 4175 &&
4061 4176 Dynarr_length (dla) >= (1 + modeline)
4062 if (vtarget > value 4177 &&
4063 && marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b)) 4178 (dl->ascent - dl->top_clip) - fheight * value <
4179 (dl->ascent + dl->descent - dl->clip)
4180 &&
4181 WINDOW_TEXT_TOP_CLIP (w) + value * fheight > 0)
4064 { 4182 {
4065 maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb); 4183 WINDOW_TEXT_TOP_CLIP (w) += value * fheight;
4066 return; 4184 MARK_WINDOWS_CHANGED (w);
4067 } 4185 }
4068 else 4186 else
4069 { 4187 {
4070 set_marker_restricted (w->start[CURRENT_DISP], make_int (startp), 4188 int vtarget;
4071 w->buffer); 4189 Bufpos startp, old_start;
4072 w->force_start = 1; 4190
4073 w->start_at_line_beg = beginning_of_line_p (b, startp); 4191 if (WINDOW_TEXT_TOP_CLIP (w))
4074 MARK_WINDOWS_CHANGED (w);
4075
4076 if (!point_would_be_visible (w, startp, XINT (point)))
4077 { 4192 {
4078 Bufpos new_point; 4193 WINDOW_TEXT_TOP_CLIP (w) = 0;
4079 4194 MARK_WINDOWS_CHANGED (w);
4080 if (MINI_WINDOW_P (w)) 4195 }
4081 new_point = startp; 4196
4082 else 4197 old_start = marker_position (w->start[CURRENT_DISP]);
4083 new_point = start_of_last_line (w, startp); 4198 startp = vmotion (w, old_start, value, &vtarget);
4084 4199
4085 if (selected) 4200 if (vtarget > value
4086 BUF_SET_PT (b, new_point); 4201 && marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b))
4087 else 4202 {
4088 set_marker_restricted (w->pointm[CURRENT_DISP], 4203 maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb);
4089 make_int (new_point), 4204 return;
4090 w->buffer); 4205 }
4206 else
4207 {
4208 set_marker_restricted (w->start[CURRENT_DISP], make_int (startp),
4209 w->buffer);
4210 w->force_start = 1;
4211 w->start_at_line_beg = beginning_of_line_p (b, startp);
4212 MARK_WINDOWS_CHANGED (w);
4213
4214 /* #### Scroll back by less than a line. This code was
4215 originally for scrolling over large pixmaps and it
4216 loses when a line being *exposed* at the top of the
4217 window is bigger than the current one. However, for
4218 pixel based scrolling in general we can guess that
4219 the line we are going to display is probably the same
4220 size as the one we are on. In that instance we can
4221 have a reasonable stab at a suitable top clip. Fixing
4222 this properly is hard (and probably slow) as we would
4223 have to call redisplay to figure out the exposed line
4224 size. */
4225 if (!NILP (Vwindow_pixel_scroll_increment)
4226 && Dynarr_length (dla) >= (1 + modeline)
4227 && dl->ascent + fheight * value > 0)
4228 {
4229 WINDOW_TEXT_TOP_CLIP (w) = (dl->ascent + fheight * value);
4230 }
4231
4232 if (!point_would_be_visible (w, startp, XINT (point)))
4233 {
4234 Bufpos new_point;
4235
4236 if (MINI_WINDOW_P (w))
4237 new_point = startp;
4238 else
4239 new_point = start_of_last_line (w, startp);
4240
4241 if (selected)
4242 BUF_SET_PT (b, new_point);
4243 else
4244 set_marker_restricted (w->pointm[CURRENT_DISP],
4245 make_int (new_point),
4246 w->buffer);
4247 }
4091 } 4248 }
4092 } 4249 }
4093 } 4250 }
4094 else /* value == 0 && direction == -1 */ 4251 else /* value == 0 && direction == -1 */
4095 { 4252 {
4253 if (WINDOW_TEXT_TOP_CLIP (w))
4254 {
4255 WINDOW_TEXT_TOP_CLIP (w) = 0;
4256 MARK_WINDOWS_CHANGED (w);
4257 }
4096 if (marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b)) 4258 if (marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b))
4097 { 4259 {
4098 maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb); 4260 maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb);
4099 return; 4261 return;
4100 } 4262 }
4128 make_int (new_point), 4290 make_int (new_point),
4129 w->buffer); 4291 w->buffer);
4130 } 4292 }
4131 } 4293 }
4132 } 4294 }
4133
4134 } 4295 }
4135 4296
4136 DEFUN ("scroll-up", Fscroll_up, 0, 1, "_P", /* 4297 DEFUN ("scroll-up", Fscroll_up, 0, 1, "_P", /*
4137 Scroll text of current window upward N lines; or near full screen if no arg. 4298 Scroll text of current window upward N lines; or near full screen if no arg.
4138 A near full screen is `next-screen-context-lines' less than a full screen. 4299 A near full screen is `next-screen-context-lines' less than a full screen.
4302 /* Don't use decode_window() because we need the new value of 4463 /* Don't use decode_window() because we need the new value of
4303 WINDOW. */ 4464 WINDOW. */
4304 if (NILP (window)) 4465 if (NILP (window))
4305 window = Fselected_window (Qnil); 4466 window = Fselected_window (Qnil);
4306 else 4467 else
4307 CHECK_WINDOW (window); 4468 CHECK_LIVE_WINDOW (window);
4308 w = XWINDOW (window); 4469 w = XWINDOW (window);
4309 b = XBUFFER (w->buffer); 4470 b = XBUFFER (w->buffer);
4310 4471
4311 height = window_displayed_height (w); 4472 height = window_displayed_height (w);
4312 selected = EQ (window, Fselected_window (w->frame)); 4473 selected = EQ (window, Fselected_window (w->frame));
4604 int pixel_left; 4765 int pixel_left;
4605 int pixel_top; 4766 int pixel_top;
4606 int pixel_width; 4767 int pixel_width;
4607 int pixel_height; 4768 int pixel_height;
4608 int hscroll; 4769 int hscroll;
4609 int modeline_hscroll; 4770 Charcount modeline_hscroll;
4610 int parent_index; /* index into saved_windows */ 4771 int parent_index; /* index into saved_windows */
4611 int prev_index; /* index into saved_windows */ 4772 int prev_index; /* index into saved_windows */
4612 char start_at_line_beg; /* boolean */ 4773 char start_at_line_beg; /* boolean */
4613 4774
4614 #define WINDOW_SLOT_DECLARATION 4775 #define WINDOW_SLOT_DECLARATION
4619 /* If you add anything to this structure make sure window_config_equal 4780 /* If you add anything to this structure make sure window_config_equal
4620 knows about it. */ 4781 knows about it. */
4621 struct window_config 4782 struct window_config
4622 { 4783 {
4623 struct lcrecord_header header; 4784 struct lcrecord_header header;
4624 int frame_width; 4785 /* int frame_width; No longer needed, JV
4625 int frame_height; 4786 int frame_height; */
4626 #if 0 /* FSFmacs */ 4787 #if 0 /* FSFmacs */
4627 Lisp_Object selected_frame; 4788 Lisp_Object selected_frame;
4628 #endif 4789 #endif
4629 Lisp_Object current_window; 4790 Lisp_Object current_window;
4630 Lisp_Object current_buffer; 4791 Lisp_Object current_buffer;
4631 Lisp_Object minibuffer_scroll_window; 4792 Lisp_Object minibuffer_scroll_window;
4632 Lisp_Object root_window; 4793 Lisp_Object root_window;
4794 int minibuf_height; /* 0 = no minibuffer, <0, size in lines, >0 in pixels */
4633 /* Record the values of window-min-width and window-min-height 4795 /* Record the values of window-min-width and window-min-height
4634 so that window sizes remain consistent with them. */ 4796 so that window sizes remain consistent with them. */
4635 int min_width, min_height; 4797 int min_width, min_height;
4636 int saved_windows_count; 4798 int saved_windows_count;
4637 /* Zero-sized arrays aren't ANSI C */ 4799 /* Zero-sized arrays aren't ANSI C */
4640 4802
4641 #define SAVED_WINDOW_N(conf, n) (&((conf)->saved_windows[(n)])) 4803 #define SAVED_WINDOW_N(conf, n) (&((conf)->saved_windows[(n)]))
4642 #define XWINDOW_CONFIGURATION(x) XRECORD (x, window_configuration, struct window_config) 4804 #define XWINDOW_CONFIGURATION(x) XRECORD (x, window_configuration, struct window_config)
4643 #define XSETWINDOW_CONFIGURATION(x, p) XSETRECORD (x, p, window_configuration) 4805 #define XSETWINDOW_CONFIGURATION(x, p) XSETRECORD (x, p, window_configuration)
4644 #define WINDOW_CONFIGURATIONP(x) RECORDP (x, window_configuration) 4806 #define WINDOW_CONFIGURATIONP(x) RECORDP (x, window_configuration)
4645 #define GC_WINDOW_CONFIGURATIONP(x) GC_RECORDP (x, window_configuration)
4646 #define CHECK_WINDOW_CONFIGURATION(x) CHECK_RECORD (x, window_configuration) 4807 #define CHECK_WINDOW_CONFIGURATION(x) CHECK_RECORD (x, window_configuration)
4647 4808
4648 static Lisp_Object 4809 static Lisp_Object
4649 mark_window_config (Lisp_Object obj, void (*markobj) (Lisp_Object)) 4810 mark_window_config (Lisp_Object obj)
4650 { 4811 {
4651 struct window_config *config = XWINDOW_CONFIGURATION (obj); 4812 struct window_config *config = XWINDOW_CONFIGURATION (obj);
4652 int i; 4813 int i;
4653 markobj (config->current_window); 4814 mark_object (config->current_window);
4654 markobj (config->current_buffer); 4815 mark_object (config->current_buffer);
4655 markobj (config->minibuffer_scroll_window); 4816 mark_object (config->minibuffer_scroll_window);
4656 markobj (config->root_window); 4817 mark_object (config->root_window);
4657 4818
4658 for (i = 0; i < config->saved_windows_count; i++) 4819 for (i = 0; i < config->saved_windows_count; i++)
4659 { 4820 {
4660 struct saved_window *s = SAVED_WINDOW_N (config, i); 4821 struct saved_window *s = SAVED_WINDOW_N (config, i);
4661 markobj (s->window); 4822 mark_object (s->window);
4662 markobj (s->buffer); 4823 mark_object (s->buffer);
4663 markobj (s->start); 4824 mark_object (s->start);
4664 markobj (s->pointm); 4825 mark_object (s->pointm);
4665 markobj (s->sb_point); 4826 mark_object (s->sb_point);
4666 markobj (s->mark); 4827 mark_object (s->mark);
4667 #if 0 4828 #if 0
4668 /* #### This looked like this. I do not see why specifier cached 4829 /* #### This looked like this. I do not see why specifier cached
4669 values should not be marked, as such specifiers as toolbars 4830 values should not be marked, as such specifiers as toolbars
4670 might have GC-able instances. Freed configs are not marked, 4831 might have GC-able instances. Freed configs are not marked,
4671 aren't they? -- kkm */ 4832 aren't they? -- kkm */
4672 markobj (s->dedicated); 4833 mark_object (s->dedicated);
4673 #else 4834 #else
4674 #define WINDOW_SLOT(slot, compare) ((void) (markobj (s->slot))) 4835 #define WINDOW_SLOT(slot, compare) mark_object (s->slot)
4675 #include "winslots.h" 4836 #include "winslots.h"
4676 #endif 4837 #endif
4677 } 4838 }
4678 return Qnil; 4839 return Qnil;
4679 } 4840 }
4685 /* n - 1 because zero-sized arrays aren't ANSI C */ 4846 /* n - 1 because zero-sized arrays aren't ANSI C */
4686 (n - 1) *sizeof (struct saved_window)); 4847 (n - 1) *sizeof (struct saved_window));
4687 } 4848 }
4688 4849
4689 static size_t 4850 static size_t
4690 sizeof_window_config (CONST void *h) 4851 sizeof_window_config (const void *h)
4691 { 4852 {
4692 CONST struct window_config *c = (CONST struct window_config *) h; 4853 const struct window_config *c = (const struct window_config *) h;
4693 return sizeof_window_config_for_n_windows (c->saved_windows_count); 4854 return sizeof_window_config_for_n_windows (c->saved_windows_count);
4694 } 4855 }
4695 4856
4696 static void 4857 static void
4697 print_window_config (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) 4858 print_window_config (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
4708 4869
4709 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("window-configuration", 4870 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("window-configuration",
4710 window_configuration, 4871 window_configuration,
4711 mark_window_config, 4872 mark_window_config,
4712 print_window_config, 4873 print_window_config,
4713 0, 0, 0, sizeof_window_config, 4874 0, 0, 0, 0, sizeof_window_config,
4714 struct window_config); 4875 struct window_config);
4715 4876
4716 4877
4717 /* Returns a boolean indicating whether the two saved windows are 4878 /* Returns a boolean indicating whether the two saved windows are
4718 identical. */ 4879 identical. */
4759 4920
4760 if (!((fig1->saved_windows_count == fig2->saved_windows_count) && 4921 if (!((fig1->saved_windows_count == fig2->saved_windows_count) &&
4761 EQ (fig1->current_window, fig2->current_window) && 4922 EQ (fig1->current_window, fig2->current_window) &&
4762 EQ (fig1->current_buffer, fig2->current_buffer) && 4923 EQ (fig1->current_buffer, fig2->current_buffer) &&
4763 EQ (fig1->root_window, fig2->root_window) && 4924 EQ (fig1->root_window, fig2->root_window) &&
4764 EQ (fig1->minibuffer_scroll_window, fig2->minibuffer_scroll_window) && 4925 EQ (fig1->minibuffer_scroll_window, fig2->minibuffer_scroll_window)))
4926 /* &&
4765 fig1->frame_width == fig2->frame_width && 4927 fig1->frame_width == fig2->frame_width &&
4766 fig1->frame_height == fig2->frame_height)) 4928 fig1->frame_height == fig2->frame_height)) */
4767 return 0; 4929 return 0;
4768 4930
4769 for (i = 0; i < fig1->saved_windows_count; i++) 4931 for (i = 0; i < fig1->saved_windows_count; i++)
4770 { 4932 {
4771 if (!saved_window_equal (SAVED_WINDOW_N (fig1, i), 4933 if (!saved_window_equal (SAVED_WINDOW_N (fig1, i),
4857 int k; 5019 int k;
4858 Lisp_Object frame; 5020 Lisp_Object frame;
4859 struct frame *f; 5021 struct frame *f;
4860 struct gcpro gcpro1; 5022 struct gcpro gcpro1;
4861 Lisp_Object old_window_config; 5023 Lisp_Object old_window_config;
4862 int previous_frame_height; 5024 /* int previous_frame_height;
4863 int previous_frame_width; 5025 int previous_frame_width;*/
5026 int previous_pixel_top;
5027 int previous_pixel_height;
5028 int previous_pixel_left;
5029 int previous_pixel_width;
5030 int previous_minibuf_height, previous_minibuf_top,previous_minibuf_width;
5031 int real_font_height;
5032 int converted_minibuf_height,target_minibuf_height;
4864 int specpdl_count = specpdl_depth (); 5033 int specpdl_count = specpdl_depth ();
4865 5034
4866 GCPRO1 (configuration); 5035 GCPRO1 (configuration);
4867 5036
4868 CHECK_WINDOW_CONFIGURATION (configuration); 5037 CHECK_WINDOW_CONFIGURATION (configuration);
4923 begin_dont_check_for_quit (); 5092 begin_dont_check_for_quit ();
4924 record_unwind_protect (free_window_configuration, old_window_config); 5093 record_unwind_protect (free_window_configuration, old_window_config);
4925 5094
4926 mark_windows_in_use (f, 1); 5095 mark_windows_in_use (f, 1);
4927 5096
5097 #if 0
5098 /* JV: This is bogus,
5099 First of all, the units are inconsistent. The frame sizes are measured
5100 in characters but the window sizes are stored in pixels. So if a
5101 font size change happened between saving and restoring, the
5102 frame "sizes" maybe equal but the windows still should be
5103 resized. This is tickled alot by the new "character size
5104 stays constant" policy in 21.0. It leads to very wierd
5105 glitches (and possibly craches when asserts are tickled).
5106
5107 Just changing the units doens't help because changing the
5108 toolbar configuration can also change the pixel positions.
5109 Luckily there is a much simpler way of doing this, see below.
5110 */
4928 previous_frame_width = FRAME_WIDTH (f); 5111 previous_frame_width = FRAME_WIDTH (f);
4929 previous_frame_height = FRAME_HEIGHT (f); 5112 previous_frame_height = FRAME_HEIGHT (f);
4930 /* If the frame has been resized since this window configuration was 5113 /* If the frame has been resized since this window configuration was
4931 made, we change the frame to the size specified in the 5114 made, we change the frame to the size specified in the
4932 configuration, restore the configuration, and then resize it 5115 configuration, restore the configuration, and then resize it
4933 back. We keep track of the prevailing height in these variables. */ 5116 back. We keep track of the prevailing height in these variables. */
4934 if (config->frame_height != FRAME_HEIGHT (f) 5117 if (config->frame_height != FRAME_HEIGHT (f)
4935 || config->frame_width != FRAME_WIDTH (f)) 5118 || config->frame_width != FRAME_WIDTH (f))
4936 change_frame_size (f, config->frame_height, config->frame_width, 0); 5119 change_frame_size (f, config->frame_height, config->frame_width, 0);
5120 #endif
5121
5122 previous_pixel_top = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top;
5123 previous_pixel_height = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_height;
5124 previous_pixel_left = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left;
5125 previous_pixel_width = XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_width;
5126
5127 /* remember some properties of the minibuffer */
5128
5129 default_face_height_and_width (frame, &real_font_height, 0);
5130 assert(real_font_height > 0);
5131
5132 if (FRAME_HAS_MINIBUF_P (f) && ! FRAME_MINIBUF_ONLY_P (f))
5133 {
5134 previous_minibuf_height
5135 = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height;
5136 previous_minibuf_top
5137 = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_top;
5138 previous_minibuf_width
5139 = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_width;
5140 }
5141 else
5142 {
5143 previous_minibuf_height = 0;
5144 previous_minibuf_top = 0;
5145 previous_minibuf_width = 0;
5146 }
5147 converted_minibuf_height =
5148 (previous_minibuf_height % real_font_height) == 0 ?
5149 - (previous_minibuf_height / real_font_height ) : /* lines */
5150 previous_minibuf_height; /* pixels */
4937 5151
4938 /* Temporarily avoid any problems with windows that are smaller 5152 /* Temporarily avoid any problems with windows that are smaller
4939 than they are supposed to be. */ 5153 than they are supposed to be. */
4940 window_min_height = 1; 5154 window_min_height = 1;
4941 window_min_width = 1; 5155 window_min_width = 1;
5020 w->line_cache_last_updated = Qzero; 5234 w->line_cache_last_updated = Qzero;
5021 SET_LAST_MODIFIED (w, 1); 5235 SET_LAST_MODIFIED (w, 1);
5022 SET_LAST_FACECHANGE (w); 5236 SET_LAST_FACECHANGE (w);
5023 w->config_mark = 0; 5237 w->config_mark = 0;
5024 5238
5025 #define WINDOW_SLOT(slot, compare) w->slot = p->slot; 5239 #define WINDOW_SLOT(slot, compare) w->slot = p->slot
5026 #include "winslots.h" 5240 #include "winslots.h"
5027 5241
5028 /* Reinstall the saved buffer and pointers into it. */ 5242 /* Reinstall the saved buffer and pointers into it. */
5029 if (NILP (p->buffer)) 5243 if (NILP (p->buffer))
5030 w->buffer = p->buffer; 5244 w->buffer = p->buffer;
5098 Instead, we don't ever change the selected frame, and either 5312 Instead, we don't ever change the selected frame, and either
5099 call Fselect_window() below if the window config's frame is 5313 call Fselect_window() below if the window config's frame is
5100 currently selected, or just set the selected window of the 5314 currently selected, or just set the selected window of the
5101 window config's frame. */ 5315 window config's frame. */
5102 5316
5317 #if 0
5103 /* Set the frame height to the value it had before this function. */ 5318 /* Set the frame height to the value it had before this function. */
5104 if (previous_frame_height != FRAME_HEIGHT (f) 5319 if (previous_frame_height != FRAME_HEIGHT (f)
5105 || previous_frame_width != FRAME_WIDTH (f)) 5320 || previous_frame_width != FRAME_WIDTH (f))
5106 change_frame_size (f, previous_frame_height, previous_frame_width, 0); 5321 change_frame_size (f, previous_frame_height, previous_frame_width, 0);
5322 #endif
5323 /* We just reset the size and position of the minibuffer, to its old
5324 value, which needn't be valid. So we do some magic to see which value
5325 to actually take. Then we set it.
5326
5327 The magic:
5328 We take the old value if is in the same units but differs from the
5329 current value.
5330
5331 #### Now we get more cases correct then ever before, but
5332 are we treating all? For instance what if the frames minibuf window
5333 is no longer the same one?
5334 */
5335 target_minibuf_height = previous_minibuf_height;
5336 if (converted_minibuf_height &&
5337 (converted_minibuf_height * config->minibuf_height) > 0 &&
5338 (converted_minibuf_height != config->minibuf_height))
5339 {
5340 target_minibuf_height = config->minibuf_height < 0 ?
5341 - (config->minibuf_height * real_font_height) :
5342 config->minibuf_height;
5343 target_minibuf_height =
5344 max(target_minibuf_height,real_font_height);
5345 }
5346 if (previous_minibuf_height)
5347 {
5348 XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_top
5349 = previous_minibuf_top -
5350 (target_minibuf_height - previous_minibuf_height);
5351 set_window_pixheight (FRAME_MINIBUF_WINDOW (f),
5352 target_minibuf_height, 0);
5353 set_window_pixwidth (FRAME_MINIBUF_WINDOW (f),
5354 previous_minibuf_width, 0);
5355 }
5356
5357 /* This is a better way to deal with frame resizing, etc.
5358 What we _actually_ want is for the old (just restored)
5359 root window to fit
5360 into the place of the new one. So we just do that. Simple! */
5361 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top = previous_pixel_top;
5362 /* Note that this function also updates the subwindow
5363 "pixel_top"s */
5364 set_window_pixheight (FRAME_ROOT_WINDOW (f),
5365 previous_pixel_height -
5366 (target_minibuf_height - previous_minibuf_height), 0);
5367 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left = previous_pixel_left;
5368 /* Note that this function also updates the subwindow
5369 "pixel_left"s */
5370 set_window_pixwidth (FRAME_ROOT_WINDOW (f), previous_pixel_width, 0);
5107 5371
5108 /* If restoring in the current frame make the window current, 5372 /* If restoring in the current frame make the window current,
5109 otherwise just update the frame selected_window slot to be 5373 otherwise just update the frame selected_window slot to be
5110 the restored current_window. */ 5374 the restored current_window. */
5111 if (f == selected_frame ()) 5375 if (f == selected_frame ())
5244 WINDOW_WIDTH (p) = WINDOW_WIDTH (w); 5508 WINDOW_WIDTH (p) = WINDOW_WIDTH (w);
5245 WINDOW_HEIGHT (p) = WINDOW_HEIGHT (w); 5509 WINDOW_HEIGHT (p) = WINDOW_HEIGHT (w);
5246 p->hscroll = w->hscroll; 5510 p->hscroll = w->hscroll;
5247 p->modeline_hscroll = w->modeline_hscroll; 5511 p->modeline_hscroll = w->modeline_hscroll;
5248 5512
5249 #define WINDOW_SLOT(slot, compare) p->slot = w->slot; 5513 #define WINDOW_SLOT(slot, compare) p->slot = w->slot
5250 #include "winslots.h" 5514 #include "winslots.h"
5251 5515
5252 if (!NILP (w->buffer)) 5516 if (!NILP (w->buffer))
5253 { 5517 {
5254 /* Save w's value of point in the window configuration. 5518 /* Save w's value of point in the window configuration.
5317 { 5581 {
5318 Lisp_Object result; 5582 Lisp_Object result;
5319 struct frame *f = decode_frame (frame); 5583 struct frame *f = decode_frame (frame);
5320 struct window_config *config; 5584 struct window_config *config;
5321 int n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f))); 5585 int n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
5586 int minibuf_height;
5587 int real_font_height;
5322 5588
5323 if (n_windows <= countof (Vwindow_configuration_free_list)) 5589 if (n_windows <= countof (Vwindow_configuration_free_list))
5324 config = XWINDOW_CONFIGURATION (allocate_managed_lcrecord 5590 config = XWINDOW_CONFIGURATION (allocate_managed_lcrecord
5325 (Vwindow_configuration_free_list 5591 (Vwindow_configuration_free_list
5326 [n_windows - 1])); 5592 [n_windows - 1]));
5327 else 5593 else
5328 /* More than ten windows; just allocate directly */ 5594 /* More than ten windows; just allocate directly */
5329 config = (struct window_config *) 5595 config = (struct window_config *)
5330 alloc_lcrecord (sizeof_window_config_for_n_windows (n_windows), 5596 alloc_lcrecord (sizeof_window_config_for_n_windows (n_windows),
5331 lrecord_window_configuration); 5597 &lrecord_window_configuration);
5332 XSETWINDOW_CONFIGURATION (result, config); 5598 XSETWINDOW_CONFIGURATION (result, config);
5333 5599 /*
5334 config->frame_width = FRAME_WIDTH (f); 5600 config->frame_width = FRAME_WIDTH (f);
5335 config->frame_height = FRAME_HEIGHT (f); 5601 config->frame_height = FRAME_HEIGHT (f); */
5336 config->current_window = FRAME_SELECTED_WINDOW (f); 5602 config->current_window = FRAME_SELECTED_WINDOW (f);
5337 XSETBUFFER (config->current_buffer, current_buffer); 5603 XSETBUFFER (config->current_buffer, current_buffer);
5338 config->minibuffer_scroll_window = Vminibuffer_scroll_window; 5604 config->minibuffer_scroll_window = Vminibuffer_scroll_window;
5339 config->root_window = FRAME_ROOT_WINDOW (f); 5605 config->root_window = FRAME_ROOT_WINDOW (f);
5340 config->min_height = window_min_height; 5606 config->min_height = window_min_height;
5341 config->min_width = window_min_width; 5607 config->min_width = window_min_width;
5342 config->saved_windows_count = n_windows; 5608 config->saved_windows_count = n_windows;
5343 save_window_save (FRAME_ROOT_WINDOW (f), config, 0); 5609 save_window_save (FRAME_ROOT_WINDOW (f), config, 0);
5610
5611 /* save the minibuffer height using the heuristics from
5612 change_frame_size_1 */
5613
5614 XSETFRAME (frame, f); /* frame could have been nil ! */
5615 default_face_height_and_width (frame, &real_font_height, 0);
5616 assert(real_font_height > 0);
5617
5618 if (FRAME_HAS_MINIBUF_P (f) && ! FRAME_MINIBUF_ONLY_P (f))
5619 minibuf_height = XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height;
5620 else
5621 minibuf_height = 0;
5622 config->minibuf_height = (minibuf_height % real_font_height) == 0 ?
5623 - (minibuf_height / real_font_height ) : /* lines */
5624 minibuf_height; /* pixels */
5625
5344 return result; 5626 return result;
5345 } 5627 }
5346 5628
5347 Lisp_Object 5629 Lisp_Object
5348 save_window_excursion_unwind (Lisp_Object window_config) 5630 save_window_excursion_unwind (Lisp_Object window_config)
5366 5648
5367 record_unwind_protect (save_window_excursion_unwind, 5649 record_unwind_protect (save_window_excursion_unwind,
5368 Fcurrent_window_configuration (Qnil)); 5650 Fcurrent_window_configuration (Qnil));
5369 val = Fprogn (args); 5651 val = Fprogn (args);
5370 return unbind_to (speccount, val); 5652 return unbind_to (speccount, val);
5653 }
5654
5655 DEFUN ("current-pixel-column", Fcurrent_pixel_column, 0, 2, 0, /*
5656 Return the horizontal pixel position of POS in window.
5657 Beginning of line is column 0. This is calculated using the redisplay
5658 display tables. If WINDOW is nil, the current window is assumed.
5659 If POS is nil, point is assumed. Note that POS must be visible for
5660 a non-nil result to be returned.
5661 */
5662 (window, pos))
5663 {
5664 struct window* w = decode_window (window);
5665 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
5666
5667 struct display_line *dl = 0;
5668 struct display_block *db = 0;
5669 struct rune* rb = 0;
5670 int y = w->last_point_y[CURRENT_DISP];
5671 int x = w->last_point_x[CURRENT_DISP];
5672
5673 if (MINI_WINDOW_P (w))
5674 return Qnil;
5675
5676 if (y<0 || x<0 || y >= Dynarr_length (dla) || !NILP (pos))
5677 {
5678 int first_line, i;
5679 Bufpos point;
5680
5681 if (NILP (pos))
5682 pos = Fwindow_point (window);
5683
5684 CHECK_INT (pos);
5685 point = XINT (pos);
5686
5687 if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline)
5688 first_line = 1;
5689 else
5690 first_line = 0;
5691
5692 for (i = first_line; i < Dynarr_length (dla); i++)
5693 {
5694 dl = Dynarr_atp (dla, i);
5695 /* find the vertical location first */
5696 if (point >= dl->bufpos && point <= dl->end_bufpos)
5697 {
5698 db = get_display_block_from_line (dl, TEXT);
5699 for (i = 0; i < Dynarr_length (db->runes); i++)
5700 {
5701 rb = Dynarr_atp (db->runes, i);
5702 if (point <= rb->bufpos)
5703 goto found_bufpos;
5704 }
5705 return Qnil;
5706 }
5707 }
5708 return Qnil;
5709 found_bufpos:
5710 ;
5711 }
5712 else
5713 {
5714 /* optimised case */
5715 dl = Dynarr_atp (dla, y);
5716 db = get_display_block_from_line (dl, TEXT);
5717
5718 if (x >= Dynarr_length (db->runes))
5719 return Qnil;
5720
5721 rb = Dynarr_atp (db->runes, x);
5722 }
5723
5724 return make_int (rb->xpos - WINDOW_LEFT (w));
5371 } 5725 }
5372 5726
5373 5727
5374 #ifdef DEBUG_XEMACS 5728 #ifdef DEBUG_XEMACS
5375 /* This is short and simple in elisp, but... it was written to debug 5729 /* This is short and simple in elisp, but... it was written to debug
5420 syms_of_window (void) 5774 syms_of_window (void)
5421 { 5775 {
5422 defsymbol (&Qwindowp, "windowp"); 5776 defsymbol (&Qwindowp, "windowp");
5423 defsymbol (&Qwindow_live_p, "window-live-p"); 5777 defsymbol (&Qwindow_live_p, "window-live-p");
5424 defsymbol (&Qwindow_configurationp, "window-configuration-p"); 5778 defsymbol (&Qwindow_configurationp, "window-configuration-p");
5425 defsymbol (&Qscroll_up, "scroll-up");
5426 defsymbol (&Qscroll_down, "scroll-down");
5427 defsymbol (&Qtemp_buffer_show_hook, "temp-buffer-show-hook"); 5779 defsymbol (&Qtemp_buffer_show_hook, "temp-buffer-show-hook");
5428 defsymbol (&Qdisplay_buffer, "display-buffer"); 5780 defsymbol (&Qdisplay_buffer, "display-buffer");
5429 5781
5430 #ifdef MEMORY_USAGE_STATS 5782 #ifdef MEMORY_USAGE_STATS
5431 defsymbol (&Qface_cache, "face-cache"); 5783 defsymbol (&Qface_cache, "face-cache");
5437 defsymbol (&Qother_redisplay, "other-redisplay"); 5789 defsymbol (&Qother_redisplay, "other-redisplay");
5438 /* Qother in general.c */ 5790 /* Qother in general.c */
5439 #endif 5791 #endif
5440 5792
5441 DEFSUBR (Fselected_window); 5793 DEFSUBR (Fselected_window);
5794 DEFSUBR (Flast_nonminibuf_window);
5442 DEFSUBR (Fminibuffer_window); 5795 DEFSUBR (Fminibuffer_window);
5443 DEFSUBR (Fwindow_minibuffer_p); 5796 DEFSUBR (Fwindow_minibuffer_p);
5444 DEFSUBR (Fwindowp); 5797 DEFSUBR (Fwindowp);
5445 DEFSUBR (Fwindow_live_p); 5798 DEFSUBR (Fwindow_live_p);
5446 DEFSUBR (Fwindow_first_hchild); 5799 DEFSUBR (Fwindow_first_hchild);
5447 DEFSUBR (Fwindow_first_vchild); 5800 DEFSUBR (Fwindow_first_vchild);
5448 DEFSUBR (Fwindow_next_child); 5801 DEFSUBR (Fwindow_next_child);
5449 DEFSUBR (Fwindow_previous_child); 5802 DEFSUBR (Fwindow_previous_child);
5450 DEFSUBR (Fwindow_parent); 5803 DEFSUBR (Fwindow_parent);
5451 DEFSUBR (Fwindow_lowest_p); 5804 DEFSUBR (Fwindow_lowest_p);
5805 DEFSUBR (Fwindow_truncated_p);
5452 DEFSUBR (Fwindow_highest_p); 5806 DEFSUBR (Fwindow_highest_p);
5453 DEFSUBR (Fwindow_leftmost_p); 5807 DEFSUBR (Fwindow_leftmost_p);
5454 DEFSUBR (Fwindow_rightmost_p); 5808 DEFSUBR (Fwindow_rightmost_p);
5455 DEFSUBR (Fpos_visible_in_window_p); 5809 DEFSUBR (Fpos_visible_in_window_p);
5456 DEFSUBR (Fwindow_buffer); 5810 DEFSUBR (Fwindow_buffer);
5462 DEFSUBR (Fwindow_pixel_width); 5816 DEFSUBR (Fwindow_pixel_width);
5463 DEFSUBR (Fwindow_text_area_pixel_height); 5817 DEFSUBR (Fwindow_text_area_pixel_height);
5464 DEFSUBR (Fwindow_displayed_text_pixel_height); 5818 DEFSUBR (Fwindow_displayed_text_pixel_height);
5465 DEFSUBR (Fwindow_text_area_pixel_width); 5819 DEFSUBR (Fwindow_text_area_pixel_width);
5466 DEFSUBR (Fwindow_hscroll); 5820 DEFSUBR (Fwindow_hscroll);
5467 #ifdef MODELINE_IS_SCROLLABLE 5821 DEFSUBR (Fset_window_hscroll);
5468 DEFSUBR (Fmodeline_hscroll); 5822 DEFSUBR (Fmodeline_hscroll);
5469 DEFSUBR (Fset_modeline_hscroll); 5823 DEFSUBR (Fset_modeline_hscroll);
5470 #endif /* MODELINE_IS_SCROLLABLE */
5471 #if 0 /* bogus FSF crock */ 5824 #if 0 /* bogus FSF crock */
5472 DEFSUBR (Fwindow_redisplay_end_trigger); 5825 DEFSUBR (Fwindow_redisplay_end_trigger);
5473 DEFSUBR (Fset_window_redisplay_end_trigger); 5826 DEFSUBR (Fset_window_redisplay_end_trigger);
5474 #endif 5827 #endif
5475 DEFSUBR (Fset_window_hscroll);
5476 DEFSUBR (Fwindow_pixel_edges); 5828 DEFSUBR (Fwindow_pixel_edges);
5477 DEFSUBR (Fwindow_text_area_pixel_edges); 5829 DEFSUBR (Fwindow_text_area_pixel_edges);
5478 DEFSUBR (Fwindow_point); 5830 DEFSUBR (Fwindow_point);
5479 DEFSUBR (Fwindow_start); 5831 DEFSUBR (Fwindow_start);
5480 DEFSUBR (Fwindow_end); 5832 DEFSUBR (Fwindow_end);
5833 DEFSUBR (Fwindow_last_line_visible_height);
5481 DEFSUBR (Fset_window_point); 5834 DEFSUBR (Fset_window_point);
5482 DEFSUBR (Fset_window_start); 5835 DEFSUBR (Fset_window_start);
5483 DEFSUBR (Fwindow_dedicated_p); 5836 DEFSUBR (Fwindow_dedicated_p);
5484 DEFSUBR (Fset_window_dedicated_p); 5837 DEFSUBR (Fset_window_dedicated_p);
5485 DEFSUBR (Fnext_window); 5838 DEFSUBR (Fnext_window);
5515 #endif 5868 #endif
5516 DEFSUBR (Fwindow_configuration_p); 5869 DEFSUBR (Fwindow_configuration_p);
5517 DEFSUBR (Fset_window_configuration); 5870 DEFSUBR (Fset_window_configuration);
5518 DEFSUBR (Fcurrent_window_configuration); 5871 DEFSUBR (Fcurrent_window_configuration);
5519 DEFSUBR (Fsave_window_excursion); 5872 DEFSUBR (Fsave_window_excursion);
5873 DEFSUBR (Fcurrent_pixel_column);
5874 }
5875
5876 void
5877 reinit_vars_of_window (void)
5878 {
5879 int i;
5880 /* Make sure all windows get marked */
5881 minibuf_window = Qnil;
5882 staticpro_nodump (&minibuf_window);
5883
5884 for (i = 0; i < countof (Vwindow_configuration_free_list); i++)
5885 {
5886 Vwindow_configuration_free_list[i] =
5887 make_lcrecord_list (sizeof_window_config_for_n_windows (i + 1),
5888 &lrecord_window_configuration);
5889 staticpro_nodump (&Vwindow_configuration_free_list[i]);
5890 }
5520 } 5891 }
5521 5892
5522 void 5893 void
5523 vars_of_window (void) 5894 vars_of_window (void)
5524 { 5895 {
5525 /* Make sure all windows get marked */ 5896 reinit_vars_of_window ();
5526 minibuf_window = Qnil;
5527 staticpro (&minibuf_window);
5528 5897
5529 DEFVAR_BOOL ("scroll-on-clipped-lines", &scroll_on_clipped_lines /* 5898 DEFVAR_BOOL ("scroll-on-clipped-lines", &scroll_on_clipped_lines /*
5530 *Non-nil means to scroll if point lands on a line which is clipped. 5899 *Non-nil means to scroll if point lands on a line which is clipped.
5531 */ ); 5900 */ );
5532 scroll_on_clipped_lines = 1; 5901 scroll_on_clipped_lines = 1;
5553 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer /* 5922 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer /*
5554 If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. 5923 If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.
5555 */ ); 5924 */ );
5556 Vother_window_scroll_buffer = Qnil; 5925 Vother_window_scroll_buffer = Qnil;
5557 5926
5927 DEFVAR_LISP ("window-pixel-scroll-increment", &Vwindow_pixel_scroll_increment /*
5928 *Number of pixels to scroll by per requested line.
5929 If nil then normal line scrolling occurs regardless of line height.
5930 If t then scrolling is done in increments equal to the height of the default face.
5931 */ );
5932 Vwindow_pixel_scroll_increment = Qt;
5933
5558 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines /* 5934 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines /*
5559 *Number of lines of continuity when scrolling by screenfuls. 5935 *Number of lines of continuity when scrolling by screenfuls.
5560 */ ); 5936 */ );
5561 next_screen_context_lines = 2; 5937 next_screen_context_lines = 2;
5562 5938
5567 5943
5568 DEFVAR_INT ("window-min-width", &window_min_width /* 5944 DEFVAR_INT ("window-min-width", &window_min_width /*
5569 *Delete any window less than this wide. 5945 *Delete any window less than this wide.
5570 */ ); 5946 */ );
5571 window_min_width = 10; 5947 window_min_width = 10;
5572
5573 {
5574 int i;
5575
5576 for (i = 0; i < countof (Vwindow_configuration_free_list); i++)
5577 {
5578 Vwindow_configuration_free_list[i] =
5579 make_lcrecord_list (sizeof_window_config_for_n_windows (i + 1),
5580 lrecord_window_configuration);
5581 staticpro (&Vwindow_configuration_free_list[i]);
5582 }
5583 }
5584 } 5948 }
5585 5949
5586 void 5950 void
5587 specifier_vars_of_window (void) 5951 specifier_vars_of_window (void)
5588 { 5952 {
5599 set_specifier_fallback (Vmodeline_shadow_thickness, 5963 set_specifier_fallback (Vmodeline_shadow_thickness,
5600 list1 (Fcons (Qnil, Qzero))); 5964 list1 (Fcons (Qnil, Qzero)));
5601 Fadd_spec_to_specifier (Vmodeline_shadow_thickness, make_int (2), 5965 Fadd_spec_to_specifier (Vmodeline_shadow_thickness, make_int (2),
5602 Qnil, Qnil, Qnil); 5966 Qnil, Qnil, Qnil);
5603 set_specifier_caching (Vmodeline_shadow_thickness, 5967 set_specifier_caching (Vmodeline_shadow_thickness,
5604 slot_offset (struct window, 5968 offsetof (struct window, modeline_shadow_thickness),
5605 modeline_shadow_thickness),
5606 modeline_shadow_thickness_changed, 5969 modeline_shadow_thickness_changed,
5607 0, 0); 5970 0, 0);
5608 5971
5609 DEFVAR_SPECIFIER ("has-modeline-p", &Vhas_modeline_p /* 5972 DEFVAR_SPECIFIER ("has-modeline-p", &Vhas_modeline_p /*
5610 *Whether the modeline should be displayed. 5973 *Whether the modeline should be displayed.
5612 */ ); 5975 */ );
5613 Vhas_modeline_p = Fmake_specifier (Qboolean); 5976 Vhas_modeline_p = Fmake_specifier (Qboolean);
5614 set_specifier_fallback (Vhas_modeline_p, 5977 set_specifier_fallback (Vhas_modeline_p,
5615 list1 (Fcons (Qnil, Qt))); 5978 list1 (Fcons (Qnil, Qt)));
5616 set_specifier_caching (Vhas_modeline_p, 5979 set_specifier_caching (Vhas_modeline_p,
5617 slot_offset (struct window, 5980 offsetof (struct window, has_modeline_p),
5618 has_modeline_p),
5619 /* #### It's strange that we need a special 5981 /* #### It's strange that we need a special
5620 flag to indicate that the shadow-thickness 5982 flag to indicate that the shadow-thickness
5621 has changed, but not one to indicate that 5983 has changed, but not one to indicate that
5622 the modeline has been turned off or on. */ 5984 the modeline has been turned off or on. */
5623 some_window_value_changed, 5985 some_window_value_changed,
5635 */ ); 5997 */ );
5636 Vvertical_divider_always_visible_p = Fmake_specifier (Qboolean); 5998 Vvertical_divider_always_visible_p = Fmake_specifier (Qboolean);
5637 set_specifier_fallback (Vvertical_divider_always_visible_p, 5999 set_specifier_fallback (Vvertical_divider_always_visible_p,
5638 list1 (Fcons (Qnil, Qt))); 6000 list1 (Fcons (Qnil, Qt)));
5639 set_specifier_caching (Vvertical_divider_always_visible_p, 6001 set_specifier_caching (Vvertical_divider_always_visible_p,
5640 slot_offset (struct window, 6002 offsetof (struct window,
5641 vertical_divider_always_visible_p), 6003 vertical_divider_always_visible_p),
5642 vertical_divider_changed_in_window, 6004 vertical_divider_changed_in_window,
5643 0, 0); 6005 0, 0);
5644 6006
5645 DEFVAR_SPECIFIER ("vertical-divider-shadow-thickness", &Vvertical_divider_shadow_thickness /* 6007 DEFVAR_SPECIFIER ("vertical-divider-shadow-thickness", &Vvertical_divider_shadow_thickness /*
5646 *How thick to draw 3D shadows around vertical dividers. 6008 *How thick to draw 3D shadows around vertical dividers.
5650 set_specifier_fallback (Vvertical_divider_shadow_thickness, 6012 set_specifier_fallback (Vvertical_divider_shadow_thickness,
5651 list1 (Fcons (Qnil, Qzero))); 6013 list1 (Fcons (Qnil, Qzero)));
5652 Fadd_spec_to_specifier (Vvertical_divider_shadow_thickness, make_int (2), 6014 Fadd_spec_to_specifier (Vvertical_divider_shadow_thickness, make_int (2),
5653 Qnil, Qnil, Qnil); 6015 Qnil, Qnil, Qnil);
5654 set_specifier_caching (Vvertical_divider_shadow_thickness, 6016 set_specifier_caching (Vvertical_divider_shadow_thickness,
5655 slot_offset (struct window, 6017 offsetof (struct window,
5656 vertical_divider_shadow_thickness), 6018 vertical_divider_shadow_thickness),
5657 vertical_divider_changed_in_window, 6019 vertical_divider_changed_in_window,
5658 0, 0); 6020 0, 0);
5659 DEFVAR_SPECIFIER ("vertical-divider-line-width", &Vvertical_divider_line_width /* 6021 DEFVAR_SPECIFIER ("vertical-divider-line-width", &Vvertical_divider_line_width /*
5660 *The width of the vertical dividers, not including shadows. 6022 *The width of the vertical dividers, not including shadows.
5661 6023
5681 fb = Fcons (Fcons (list1 (Qmswindows), make_int (3)), fb); 6043 fb = Fcons (Fcons (list1 (Qmswindows), make_int (3)), fb);
5682 #endif 6044 #endif
5683 set_specifier_fallback (Vvertical_divider_line_width, fb); 6045 set_specifier_fallback (Vvertical_divider_line_width, fb);
5684 } 6046 }
5685 set_specifier_caching (Vvertical_divider_line_width, 6047 set_specifier_caching (Vvertical_divider_line_width,
5686 slot_offset (struct window, 6048 offsetof (struct window,
5687 vertical_divider_line_width), 6049 vertical_divider_line_width),
5688 vertical_divider_changed_in_window, 6050 vertical_divider_changed_in_window,
5689 0, 0); 6051 0, 0);
5690 6052
5691 DEFVAR_SPECIFIER ("vertical-divider-spacing", &Vvertical_divider_spacing /* 6053 DEFVAR_SPECIFIER ("vertical-divider-spacing", &Vvertical_divider_spacing /*
5692 *How much space to leave around the vertical dividers. 6054 *How much space to leave around the vertical dividers.
5711 fb = Fcons (Fcons (list1 (Qmswindows), Qzero), fb); 6073 fb = Fcons (Fcons (list1 (Qmswindows), Qzero), fb);
5712 #endif 6074 #endif
5713 set_specifier_fallback (Vvertical_divider_spacing, fb); 6075 set_specifier_fallback (Vvertical_divider_spacing, fb);
5714 } 6076 }
5715 set_specifier_caching (Vvertical_divider_spacing, 6077 set_specifier_caching (Vvertical_divider_spacing,
5716 slot_offset (struct window, 6078 offsetof (struct window, vertical_divider_spacing),
5717 vertical_divider_spacing),
5718 vertical_divider_changed_in_window, 6079 vertical_divider_changed_in_window,
5719 0, 0); 6080 0, 0);
5720 } 6081 }