Mercurial > hg > xemacs-beta
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 } |