Mercurial > hg > xemacs-beta
annotate src/window.c @ 5636:07256dcc0c8b
Add missing foreback specifier values to the GUI Element face.
They were missing for an unexplicable reason in my initial patch, leading to
nil color instances in the whole hierarchy of widget faces.
-------------------- ChangeLog entries follow: --------------------
src/ChangeLog addition:
2012-01-03 Didier Verna <didier@xemacs.org>
* faces.c (complex_vars_of_faces): Add missing foreback specifier
values to the GUI Element face.
author | Didier Verna <didier@lrde.epita.fr> |
---|---|
date | Tue, 03 Jan 2012 11:25:06 +0100 |
parents | 3fde0e346ad7 |
children | a1808d52a34a |
rev | line source |
---|---|
428 | 1 /* Window creation, deletion and examination for XEmacs. |
2 Copyright (C) 1985-1987, 1992-1995 Free Software Foundation, Inc. | |
3 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. | |
5043 | 4 Copyright (C) 1995, 1996, 2002, 2010 Ben Wing. |
428 | 5 Copyright (C) 1996 Chuck Thompson. |
6 | |
7 This file is part of XEmacs. | |
8 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5217
diff
changeset
|
9 XEmacs is free software: you can redistribute it and/or modify it |
428 | 10 under the terms of the GNU General Public License as published by the |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5217
diff
changeset
|
11 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5217
diff
changeset
|
12 option) any later version. |
428 | 13 |
14 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5217
diff
changeset
|
20 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 21 |
22 /* Synched up with: FSF 19.30. */ | |
23 /* Beginning to diverge significantly. */ | |
24 | |
853 | 25 /* Authorship: |
26 | |
27 Based on code from pre-release FSF 19, c. 1991. | |
28 Significantly reworked by Chuck Thompson, 1993-1996. | |
29 window mirror stuff added by Chuck Thompson c. 1993. | |
30 various cleanup by Ben Wing c. 1995 (window slots, window init code, | |
31 memory usage, synch. up to FSF 19.30, other). | |
32 Unknown work by Andy Piper. | |
33 new window-width/height fns. by Ben Wing, Mar 2000. */ | |
34 | |
428 | 35 /* This file has been Mule-ized. */ |
36 | |
37 #include <config.h> | |
38 #include "lisp.h" | |
39 | |
40 #include "buffer.h" | |
800 | 41 #include "commands.h" |
872 | 42 #include "device-impl.h" |
800 | 43 #include "elhash.h" |
428 | 44 #include "faces.h" |
872 | 45 #include "frame-impl.h" |
800 | 46 #include "glyphs.h" |
47 #include "gutter.h" | |
5176
8b2f75cecb89
rename objects* (.c, .h and .el files) to fontcolor*
Ben Wing <ben@xemacs.org>
parents:
5052
diff
changeset
|
48 #include "fontcolor.h" |
428 | 49 #include "redisplay.h" |
872 | 50 #include "window-impl.h" |
428 | 51 |
1149 | 52 Lisp_Object Qwindowp, Qwindow_live_p; |
428 | 53 Lisp_Object Qdisplay_buffer; |
54 | |
55 #ifdef MEMORY_USAGE_STATS | |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
56 Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qredisplay_structs; |
428 | 57 #ifdef HAVE_SCROLLBARS |
58 Lisp_Object Qscrollbar_instances; | |
59 #endif | |
60 #endif | |
61 | |
1979 | 62 extern int allow_deletion_of_last_visible_frame; |
63 | |
428 | 64 EXFUN (Fnext_window, 4); |
65 | |
66 static int window_pixel_width_to_char_width (struct window *w, | |
67 int pixel_width, | |
68 int include_margins_p); | |
69 static int window_char_width_to_pixel_width (struct window *w, | |
70 int char_width, | |
71 int include_margins_p); | |
72 static int window_pixel_height_to_char_height (struct window *w, | |
73 int pixel_height, | |
74 int include_gutters_p); | |
75 static int window_char_height_to_pixel_height (struct window *w, | |
76 int char_height, | |
77 int include_gutters_p); | |
444 | 78 static void change_window_height (Lisp_Object window, int delta, |
79 Lisp_Object horizontalp, int inpixels); | |
428 | 80 |
81 /* Thickness of shadow border around 3d modelines. */ | |
82 Lisp_Object Vmodeline_shadow_thickness; | |
83 | |
84 /* Whether vertical dividers are draggable and displayed */ | |
85 Lisp_Object Vvertical_divider_always_visible_p; | |
86 | |
87 /* Whether a modeline should be displayed. */ | |
88 Lisp_Object Vhas_modeline_p; | |
89 | |
90 /* Thickness of shadow border around vertical dividers. */ | |
91 Lisp_Object Vvertical_divider_shadow_thickness; | |
92 | |
93 /* Divider surface width (not counting 3-d borders) */ | |
94 Lisp_Object Vvertical_divider_line_width; | |
95 | |
442 | 96 /* Spacing between outer edge of divider border and window edge */ |
428 | 97 Lisp_Object Vvertical_divider_spacing; |
98 | |
99 /* How much to scroll by per-line. */ | |
100 Lisp_Object Vwindow_pixel_scroll_increment; | |
101 | |
102 /* Scroll if point lands on the bottom line and that line is partially | |
103 clipped. */ | |
104 int scroll_on_clipped_lines; | |
105 | |
106 /* The minibuffer window of the selected frame. | |
107 Note that you cannot test for minibufferness of an arbitrary window | |
108 by comparing against this; but you can test for minibufferness of | |
109 the selected window. */ | |
110 Lisp_Object minibuf_window; | |
111 | |
112 /* Non-nil means it is the window for C-M-v to scroll | |
113 when the minibuffer is selected. */ | |
114 Lisp_Object Vminibuffer_scroll_window; | |
115 | |
116 /* Non-nil means this is the buffer whose window C-M-v should scroll. */ | |
117 Lisp_Object Vother_window_scroll_buffer; | |
118 | |
119 /* Non-nil means it's the function to call to display temp buffers. */ | |
120 Lisp_Object Vtemp_buffer_show_function; | |
121 | |
122 /* If a window gets smaller than either of these, it is removed. */ | |
458 | 123 Fixnum window_min_height; |
124 Fixnum window_min_width; | |
428 | 125 |
126 /* Number of lines of continuity in scrolling by screenfuls. */ | |
458 | 127 Fixnum next_screen_context_lines; |
428 | 128 |
1149 | 129 Lisp_Object Qcurrent_window_configuration, Qset_window_configuration; |
428 | 130 |
707 | 131 Lisp_Object Qtruncate_partial_width_windows; |
132 | |
428 | 133 #define SET_LAST_MODIFIED(w, cache_too) \ |
134 do { \ | |
135 (w)->last_modified[CURRENT_DISP] = Qzero; \ | |
136 (w)->last_modified[DESIRED_DISP] = Qzero; \ | |
137 (w)->last_modified[CMOTION_DISP] = Qzero; \ | |
138 if (cache_too) \ | |
139 (w)->line_cache_last_updated = Qzero; \ | |
140 } while (0) | |
141 | |
142 #define SET_LAST_FACECHANGE(w) \ | |
143 do { \ | |
144 (w)->last_facechange[CURRENT_DISP] = Qzero; \ | |
145 (w)->last_facechange[DESIRED_DISP] = Qzero; \ | |
146 (w)->last_facechange[CMOTION_DISP] = Qzero; \ | |
147 } while (0) | |
148 | |
149 | |
1204 | 150 |
151 static const struct memory_description int_description_1[] = { | |
152 { XD_END } | |
153 }; | |
154 | |
155 static const struct sized_memory_description int_description = { | |
156 sizeof (int), | |
157 int_description_1 | |
158 }; | |
159 | |
160 static const struct memory_description int_dynarr_description_1[] = { | |
161 XD_DYNARR_DESC (int_dynarr, &int_description), | |
162 { XD_END } | |
163 }; | |
164 | |
165 static const struct sized_memory_description int_dynarr_description = { | |
166 sizeof (int_dynarr), | |
167 int_dynarr_description_1 | |
168 }; | |
169 | |
170 static const struct memory_description face_cachel_description_1[] = { | |
2367 | 171 { XD_BLOCK_PTR, offsetof (face_cachel, merged_faces), |
2551 | 172 1, { &int_dynarr_description } }, |
1204 | 173 { XD_LISP_OBJECT, offsetof (face_cachel, face) }, |
174 { XD_LISP_OBJECT, offsetof (face_cachel, foreground) }, | |
175 { XD_LISP_OBJECT, offsetof (face_cachel, background) }, | |
176 { XD_LISP_OBJECT_ARRAY, offsetof (face_cachel, font), NUM_LEADING_BYTES }, | |
177 { XD_LISP_OBJECT, offsetof (face_cachel, display_table) }, | |
178 { XD_LISP_OBJECT, offsetof (face_cachel, background_pixmap) }, | |
179 { XD_END } | |
180 }; | |
181 | |
3092 | 182 #ifdef NEW_GC |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
183 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("face-cachel", face_cachel, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
184 0, face_cachel_description_1, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
185 Lisp_Face_Cachel); |
3092 | 186 #endif /* NEW_GC */ |
187 | |
1204 | 188 static const struct sized_memory_description face_cachel_description = { |
189 sizeof (face_cachel), | |
190 face_cachel_description_1 | |
191 }; | |
192 | |
193 static const struct memory_description face_cachel_dynarr_description_1[] = { | |
3092 | 194 #ifdef NEW_GC |
195 XD_LISP_DYNARR_DESC (face_cachel_dynarr, &face_cachel_description), | |
196 #else /* not NEW_GC */ | |
1204 | 197 XD_DYNARR_DESC (face_cachel_dynarr, &face_cachel_description), |
3092 | 198 #endif /* not NEW_GC */ |
1204 | 199 { XD_END } |
200 }; | |
201 | |
3092 | 202 #ifdef NEW_GC |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
203 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("face-cachel-dynarr", face_cachel_dynarr, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
204 0, face_cachel_dynarr_description_1, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
205 face_cachel_dynarr); |
3092 | 206 #else /* not NEW_GC */ |
1204 | 207 static const struct sized_memory_description face_cachel_dynarr_description = { |
208 sizeof (face_cachel_dynarr), | |
209 face_cachel_dynarr_description_1 | |
210 }; | |
3092 | 211 #endif /* not NEW_GC */ |
1204 | 212 |
213 static const struct memory_description glyph_cachel_description_1[] = { | |
214 { XD_LISP_OBJECT, offsetof (glyph_cachel, glyph) }, | |
215 { XD_END } | |
216 }; | |
217 | |
3092 | 218 #ifdef NEW_GC |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
219 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("glyph-cachel", glyph_cachel, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
220 0, glyph_cachel_description_1, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
221 Lisp_Glyph_Cachel); |
3092 | 222 #endif /* NEW_GC */ |
223 | |
1204 | 224 static const struct sized_memory_description glyph_cachel_description = { |
225 sizeof (glyph_cachel), | |
226 glyph_cachel_description_1 | |
227 }; | |
228 | |
229 static const struct memory_description glyph_cachel_dynarr_description_1[] = { | |
3092 | 230 #ifdef NEW_GC |
231 XD_LISP_DYNARR_DESC (glyph_cachel_dynarr, &glyph_cachel_description), | |
232 #else /* not NEW_GC */ | |
1204 | 233 XD_DYNARR_DESC (glyph_cachel_dynarr, &glyph_cachel_description), |
3092 | 234 #endif /* not NEW_GC */ |
1204 | 235 { XD_END } |
236 }; | |
237 | |
3092 | 238 #ifdef NEW_GC |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
239 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("glyph-cachel-dynarr", |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
240 glyph_cachel_dynarr, 0, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
241 glyph_cachel_dynarr_description_1, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
242 glyph_cachel_dynarr); |
3092 | 243 #else /* not NEW_GC */ |
1204 | 244 static const struct sized_memory_description glyph_cachel_dynarr_description = { |
245 sizeof (glyph_cachel_dynarr), | |
246 glyph_cachel_dynarr_description_1 | |
247 }; | |
3092 | 248 #endif /* not NEW_GC */ |
1204 | 249 |
250 static const struct memory_description line_start_cache_description_1[] = { | |
251 { XD_END } | |
252 }; | |
253 | |
254 static const struct sized_memory_description line_start_cache_description = { | |
255 sizeof (line_start_cache), | |
256 line_start_cache_description_1 | |
257 }; | |
258 | |
259 static const struct memory_description line_start_cache_dynarr_description_1[] = { | |
260 XD_DYNARR_DESC (line_start_cache_dynarr, &line_start_cache_description), | |
261 { XD_END } | |
262 }; | |
263 | |
264 static const struct sized_memory_description line_start_cache_dynarr_description = { | |
265 sizeof (line_start_cache_dynarr), | |
266 line_start_cache_dynarr_description_1 | |
267 }; | |
268 | |
269 static const struct memory_description window_description [] = { | |
270 #define WINDOW_SLOT(slot) { XD_LISP_OBJECT, offsetof (struct window, slot) }, | |
271 #define WINDOW_SLOT_ARRAY(slot, size) \ | |
272 { XD_LISP_OBJECT_ARRAY, offsetof (struct window, slot), size }, | |
273 #include "winslots.h" | |
274 | |
3092 | 275 #ifdef NEW_GC |
276 { XD_LISP_OBJECT, offsetof (struct window, face_cachels) }, | |
277 { XD_LISP_OBJECT, offsetof (struct window, glyph_cachels) }, | |
278 #else /* not NEW_GC */ | |
2367 | 279 { XD_BLOCK_PTR, offsetof (struct window, face_cachels), |
2551 | 280 1, { &face_cachel_dynarr_description } }, |
2367 | 281 { XD_BLOCK_PTR, offsetof (struct window, glyph_cachels), |
2551 | 282 1, { &glyph_cachel_dynarr_description } }, |
3092 | 283 #endif /* not NEW_GC */ |
2367 | 284 { XD_BLOCK_PTR, offsetof (struct window, line_start_cache), |
2775 | 285 1, { &line_start_cache_dynarr_description }, XD_FLAG_NO_KKCC }, |
1204 | 286 { XD_END } |
287 }; | |
428 | 288 |
289 static Lisp_Object | |
290 mark_window (Lisp_Object obj) | |
291 { | |
292 struct window *window = XWINDOW (obj); | |
293 | |
294 mark_face_cachels (window->face_cachels); | |
295 mark_glyph_cachels (window->glyph_cachels); | |
296 | |
617 | 297 #define WINDOW_SLOT(slot) mark_object (window->slot); |
428 | 298 #include "winslots.h" |
299 | |
300 return Qnil; | |
301 } | |
302 | |
303 static void | |
2286 | 304 print_window (Lisp_Object obj, Lisp_Object printcharfun, |
305 int UNUSED (escapeflag)) | |
428 | 306 { |
4846 | 307 Lisp_Object buf; |
308 | |
428 | 309 if (print_readably) |
5142
f965e31a35f0
reduce lcrecord headers to 2 words, rename printing_unreadable_object
Ben Wing <ben@xemacs.org>
parents:
5128
diff
changeset
|
310 printing_unreadable_lisp_object (obj, 0); |
428 | 311 |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
312 write_ascstring (printcharfun, "#<window"); |
4846 | 313 buf = XWINDOW_BUFFER (obj); |
314 if (EQ (buf, Qt)) | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
315 write_ascstring (printcharfun, " during creation"); |
4846 | 316 else if (!NILP (buf)) |
428 | 317 { |
4846 | 318 |
319 Lisp_Object name = XBUFFER (buf)->name; | |
800 | 320 write_fmt_string_lisp (printcharfun, " on %S", 1, name); |
428 | 321 } |
5146
88bd4f3ef8e4
make lrecord UID's have a separate UID space for each object, resurrect debug SOE code in extents.c
Ben Wing <ben@xemacs.org>
parents:
5142
diff
changeset
|
322 write_fmt_string (printcharfun, " 0x%x>", LISP_OBJECT_UID (obj)); |
428 | 323 } |
324 | |
325 static void | |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5126
diff
changeset
|
326 finalize_window (Lisp_Object obj) |
428 | 327 { |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5126
diff
changeset
|
328 struct window *w = XWINDOW (obj); |
428 | 329 |
330 if (w->line_start_cache) | |
331 { | |
332 Dynarr_free (w->line_start_cache); | |
333 w->line_start_cache = 0; | |
334 } | |
335 | |
336 if (w->face_cachels) | |
337 { | |
338 int i; | |
339 | |
340 for (i = 0; i < Dynarr_length (w->face_cachels); i++) | |
341 { | |
342 struct face_cachel *cachel = Dynarr_atp (w->face_cachels, i); | |
343 if (cachel->merged_faces) | |
344 { | |
345 Dynarr_free (cachel->merged_faces); | |
346 cachel->merged_faces = 0; | |
347 } | |
348 } | |
349 Dynarr_free (w->face_cachels); | |
350 w->face_cachels = 0; | |
351 } | |
352 | |
353 if (w->glyph_cachels) | |
354 { | |
355 Dynarr_free (w->glyph_cachels); | |
356 w->glyph_cachels = 0; | |
357 } | |
358 } | |
359 | |
844 | 360 /* These caches map buffers to markers. They are key-weak so that entries |
361 remain around as long as the buffers do. */ | |
362 | |
363 static Lisp_Object | |
364 make_saved_buffer_point_cache (void) | |
365 { | |
5191
71ee43b8a74d
Add #'equalp as a hash test by default; add #'define-hash-table-test, GNU API
Aidan Kehoe <kehoea@parhasard.net>
parents:
5178
diff
changeset
|
366 return make_lisp_hash_table (20, HASH_TABLE_KEY_WEAK, Qeq); |
844 | 367 } |
368 | |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
369 DEFINE_NODUMP_LISP_OBJECT ("window", window, |
5124
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5120
diff
changeset
|
370 mark_window, print_window, finalize_window, |
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5120
diff
changeset
|
371 0, 0, window_description, struct window); |
428 | 372 |
373 #define INIT_DISP_VARIABLE(field, initialization) \ | |
374 p->field[CURRENT_DISP] = initialization; \ | |
375 p->field[DESIRED_DISP] = initialization; \ | |
376 p->field[CMOTION_DISP] = initialization; | |
377 | |
378 /* We have an implicit assertion that the first two elements (default | |
379 and modeline faces) are always present in the face_element_cache. | |
380 Normally redisplay ensures this. However, it is possible for a | |
381 window to get created and functions which reference these values | |
382 called before redisplay works with the window for the first time. | |
383 All callers of allocate_window should therefore call | |
384 reset_face_cachels on the created window. We can't do it | |
385 here because the window must have its frame pointer set or | |
5587
3fde0e346ad7
Prevent assert at frame.c, l. 6311 by initializing glyph cachels.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
5581
diff
changeset
|
386 reset_face_cachels will fail. |
3fde0e346ad7
Prevent assert at frame.c, l. 6311 by initializing glyph cachels.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
5581
diff
changeset
|
387 A similar requirement holds for reset_glyph_cachels. We *could* do |
3fde0e346ad7
Prevent assert at frame.c, l. 6311 by initializing glyph cachels.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
5581
diff
changeset
|
388 that here (there's no reference to the frame pointer in that function), |
3fde0e346ad7
Prevent assert at frame.c, l. 6311 by initializing glyph cachels.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
5581
diff
changeset
|
389 but we may as well have the same discipline. */ |
428 | 390 Lisp_Object |
391 allocate_window (void) | |
392 { | |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5126
diff
changeset
|
393 Lisp_Object obj = ALLOC_NORMAL_LISP_OBJECT (window); |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3078
diff
changeset
|
394 struct window *p = XWINDOW (obj); |
617 | 395 |
396 #define WINDOW_SLOT(slot) p->slot = Qnil; | |
397 #include "winslots.h" | |
398 | |
428 | 399 INIT_DISP_VARIABLE (start, Fmake_marker ()); |
400 INIT_DISP_VARIABLE (pointm, Fmake_marker ()); | |
401 p->sb_point = Fmake_marker (); | |
844 | 402 p->saved_point_cache = make_saved_buffer_point_cache (); |
403 p->saved_last_window_start_cache = make_saved_buffer_point_cache (); | |
428 | 404 p->use_time = Qzero; |
405 INIT_DISP_VARIABLE (last_modified, Qzero); | |
406 INIT_DISP_VARIABLE (last_point, Fmake_marker ()); | |
407 INIT_DISP_VARIABLE (last_start, Fmake_marker ()); | |
408 INIT_DISP_VARIABLE (last_facechange, Qzero); | |
3092 | 409 #ifdef NEW_GC |
410 p->face_cachels = Dynarr_lisp_new (face_cachel, | |
411 &lrecord_face_cachel_dynarr, | |
412 &lrecord_face_cachel); | |
413 p->glyph_cachels = Dynarr_lisp_new (glyph_cachel, | |
414 &lrecord_glyph_cachel_dynarr, | |
415 &lrecord_glyph_cachel); | |
416 #else /* not NEW_GC */ | |
428 | 417 p->face_cachels = Dynarr_new (face_cachel); |
418 p->glyph_cachels = Dynarr_new (glyph_cachel); | |
3092 | 419 #endif /* not NEW_GC */ |
428 | 420 p->line_start_cache = Dynarr_new (line_start_cache); |
450 | 421 p->subwindow_instance_cache = make_image_instance_cache_hash_table (); |
422 | |
428 | 423 p->line_cache_last_updated = Qzero; |
442 | 424 |
428 | 425 p->windows_changed = 1; |
426 p->shadow_thickness_changed = 1; | |
427 | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3078
diff
changeset
|
428 return obj; |
428 | 429 } |
430 #undef INIT_DISP_VARIABLE | |
431 | |
617 | 432 /************************************************************************/ |
433 /* Window mirror structure */ | |
434 /************************************************************************/ | |
435 | |
428 | 436 /* |
437 * The redisplay structures used to be stored with each window. While | |
438 * they are logically something associated with frames they can't be | |
439 * stored there with a redisplay which handles variable height lines. | |
440 * Lines in horizontally split windows might not line up. So they get | |
441 * stored with the windows. | |
442 * | |
443 * The problem with this is window configurations. When restoring a | |
444 * window configuration it now becomes problematic to do an | |
445 * incremental redisplay. The solution is to store the redisplay | |
446 * structures with the frame as they should be but laid out in the | |
447 * same manner as the window structure. Thus is born the window | |
448 * mirror. | |
449 * | |
450 * It also becomes a convenient place to stick scrollbar instances | |
451 * since they extrapolate out to having the same problem described for | |
452 * the display structures. | |
453 */ | |
454 | |
617 | 455 /* NOTE: The window-mirror structure formerly was not a Lisp object, and |
456 marking was handled specially. I've gotten recurring crashes, however, | |
457 using the mouse wheel under Windows, where either the window mirror | |
458 accessed through a scrollbar instance, or the frame pointed to by that | |
459 window mirror, gets garbaged. Things are tricky under windows because | |
460 the scrollbar instances are stored in HWND-specific data. Furthermore, | |
461 we have scrollbar-instance caches to complicate things. Both of these | |
462 make it very difficult (for me at least, not being intimately familiar | |
463 with the redisplay code) to track exactly when and where a particular | |
464 window mirror or scrollbar instance has pointers to it, or whether a | |
465 window mirror might have a dead frame or buffer in it (i.e. not | |
466 necessarily gc-protected by being on a global list). By far the safest | |
467 thing, then, is to make both structures Lisp objects and not explicitly | |
468 xfree() them. This should make no practical difference in memory usage | |
469 because neither structure is created very often (only when windows are | |
470 created or deleted). --ben */ | |
471 | |
1204 | 472 static const struct memory_description window_mirror_description [] = { |
473 { XD_LISP_OBJECT, offsetof (struct window_mirror, frame) }, | |
474 { XD_LISP_OBJECT, offsetof (struct window_mirror, next) }, | |
475 { XD_LISP_OBJECT, offsetof (struct window_mirror, hchild) }, | |
476 { XD_LISP_OBJECT, offsetof (struct window_mirror, vchild) }, | |
477 | |
2367 | 478 { XD_BLOCK_PTR, offsetof (struct window_mirror, current_display_lines), |
2551 | 479 1, { &display_line_dynarr_description } }, |
2367 | 480 { XD_BLOCK_PTR, offsetof (struct window_mirror, desired_display_lines), |
2551 | 481 1, { &display_line_dynarr_description } }, |
1204 | 482 |
483 { XD_LISP_OBJECT, offsetof (struct window_mirror, buffer) }, | |
484 | |
485 #ifdef HAVE_SCROLLBARS | |
486 { XD_LISP_OBJECT, offsetof (struct window_mirror, | |
487 scrollbar_vertical_instance) }, | |
488 { XD_LISP_OBJECT, offsetof (struct window_mirror, | |
489 scrollbar_horizontal_instance) }, | |
490 #endif /* HAVE_SCROLLBARS */ | |
491 | |
934 | 492 { XD_END } |
493 }; | |
494 | |
617 | 495 static Lisp_Object |
496 mark_window_mirror (Lisp_Object obj) | |
497 { | |
498 struct window_mirror *mir = XWINDOW_MIRROR (obj); | |
499 | |
500 if (mir->current_display_lines) | |
501 mark_redisplay_structs (mir->current_display_lines); | |
502 if (mir->desired_display_lines) | |
503 mark_redisplay_structs (mir->desired_display_lines); | |
504 | |
505 if (mir->hchild) | |
506 mark_object (wrap_window_mirror (mir->hchild)); | |
507 if (mir->vchild) | |
508 mark_object (wrap_window_mirror (mir->vchild)); | |
509 | |
510 if (mir->frame) | |
511 mark_object (wrap_frame (mir->frame)); | |
512 if (mir->buffer) | |
513 mark_object (wrap_buffer (mir->buffer)); | |
514 | |
515 #ifdef HAVE_SCROLLBARS | |
516 if (mir->scrollbar_vertical_instance) | |
517 mark_object (wrap_scrollbar_instance (mir->scrollbar_vertical_instance)); | |
518 if (mir->scrollbar_horizontal_instance) | |
519 mark_object (wrap_scrollbar_instance (mir->scrollbar_horizontal_instance)); | |
520 #endif /* HAVE_SCROLLBARS */ | |
521 if (mir->next) | |
522 return wrap_window_mirror (mir->next); | |
523 else | |
524 return Qnil; | |
525 } | |
526 | |
5124
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5120
diff
changeset
|
527 DEFINE_NODUMP_INTERNAL_LISP_OBJECT ("window-mirror", window_mirror, |
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5120
diff
changeset
|
528 mark_window_mirror, |
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5120
diff
changeset
|
529 window_mirror_description, |
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5120
diff
changeset
|
530 struct window_mirror); |
617 | 531 |
428 | 532 /* Create a new window mirror structure and associated redisplay |
533 structs. */ | |
534 static struct window_mirror * | |
535 new_window_mirror (struct frame *f) | |
536 { | |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5126
diff
changeset
|
537 Lisp_Object obj = ALLOC_NORMAL_LISP_OBJECT (window_mirror); |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3078
diff
changeset
|
538 struct window_mirror *t = XWINDOW_MIRROR (obj); |
428 | 539 |
540 t->frame = f; | |
541 t->current_display_lines = Dynarr_new (display_line); | |
542 t->desired_display_lines = Dynarr_new (display_line); | |
543 | |
544 return t; | |
545 } | |
546 | |
547 /* Synchronize the mirror structure with a given window structure. | |
548 This is normally called from update_frame_window_mirror with a | |
549 starting window of f->root_window. */ | |
550 static struct window_mirror * | |
551 update_mirror_internal (Lisp_Object win, struct window_mirror *mir) | |
552 { | |
553 if (NILP (win)) | |
554 { | |
555 if (mir) | |
556 { | |
557 free_window_mirror (mir); | |
558 mir = NULL; | |
559 } | |
560 return mir; | |
561 } | |
562 else | |
563 if (!mir) | |
564 mir = new_window_mirror (XFRAME (XWINDOW (win)->frame)); | |
565 | |
1204 | 566 mir->next = update_mirror_internal (XWINDOW (win)->next, mir->next); |
428 | 567 mir->hchild = update_mirror_internal (XWINDOW (win)->hchild, mir->hchild); |
568 mir->vchild = update_mirror_internal (XWINDOW (win)->vchild, mir->vchild); | |
569 | |
570 /* | |
571 * If the redisplay structs are not empty and the mirror has | |
572 * children, then this mirror structure was formerly being used for | |
573 * display but is no longer. Reset its current display structs so | |
574 * that redisplay doesn't accidentally think they are accurate if it | |
575 * is later used for display purposes once again. Also, mark the | |
576 * scrollbar instance as not active. | |
577 */ | |
578 if (mir->vchild || mir->hchild) | |
579 { | |
580 /* The redisplay structures are big. Leaving them around in | |
581 non-leaf windows can add up to a lot of wasted space. So | |
582 don't do it. */ | |
583 free_display_structs (mir); | |
584 mir->current_display_lines = Dynarr_new (display_line); | |
585 mir->desired_display_lines = Dynarr_new (display_line); | |
586 | |
587 #ifdef HAVE_SCROLLBARS | |
588 update_window_scrollbars (XWINDOW (win), mir, 0, 0); | |
589 #endif | |
590 mir->buffer = NULL; | |
591 } | |
592 | |
593 return mir; | |
594 } | |
595 | |
596 /* Given a window mirror, determine which real window it contains the | |
597 redisplay structures for. */ | |
598 static Lisp_Object | |
599 real_window_internal (Lisp_Object win, struct window_mirror *rmir, | |
600 struct window_mirror *mir) | |
601 { | |
602 for (; !NILP (win) && rmir ; win = XWINDOW (win)->next, rmir = rmir->next) | |
603 { | |
604 if (mir == rmir) | |
605 return win; | |
606 if (!NILP (XWINDOW (win)->vchild)) | |
607 { | |
608 Lisp_Object retval = | |
609 real_window_internal (XWINDOW (win)->vchild, rmir->vchild, mir); | |
610 if (!NILP (retval)) | |
611 return retval; | |
612 } | |
613 if (!NILP (XWINDOW (win)->hchild)) | |
614 { | |
615 Lisp_Object retval = | |
616 real_window_internal (XWINDOW (win)->hchild, rmir->hchild, mir); | |
617 if (!NILP (retval)) | |
618 return retval; | |
619 } | |
620 } | |
621 | |
622 return Qnil; | |
623 } | |
624 | |
625 /* Given a real window, find the mirror structure which contains its | |
626 redisplay structures. */ | |
627 static struct window_mirror * | |
628 find_window_mirror_internal (Lisp_Object win, struct window_mirror *rmir, | |
629 struct window *w) | |
630 { | |
5171
8cd17b2131a1
fix further crash in window-mirror finding
Ben Wing <ben@xemacs.org>
parents:
5170
diff
changeset
|
631 for (; !NILP (win) && rmir; win = XWINDOW (win)->next, rmir = rmir->next) |
428 | 632 { |
633 if (w == XWINDOW (win)) | |
634 return rmir; | |
635 | |
636 if (!NILP (XWINDOW (win)->vchild)) | |
637 { | |
638 struct window_mirror *retval = | |
639 find_window_mirror_internal (XWINDOW (win)->vchild, | |
640 rmir->vchild, w); | |
641 if (retval) return retval; | |
642 } | |
643 | |
644 if (!NILP (XWINDOW (win)->hchild)) | |
645 { | |
646 struct window_mirror *retval = | |
647 find_window_mirror_internal (XWINDOW (win)->hchild, | |
648 rmir->hchild, w); | |
649 if (retval) return retval; | |
650 } | |
651 } | |
652 | |
653 return 0; | |
654 } | |
655 | |
656 /* Update the mirror structure for the given frame. */ | |
657 void | |
658 update_frame_window_mirror (struct frame *f) | |
659 { | |
617 | 660 f->root_mirror = |
661 wrap_window_mirror (update_mirror_internal | |
662 (f->root_window, | |
663 NILP (f->root_mirror) ? 0 : | |
664 XWINDOW_MIRROR (f->root_mirror))); | |
428 | 665 f->mirror_dirty = 0; |
666 } | |
667 | |
668 /* Free a given mirror structure along with all of its children as | |
669 well as their associated display structures. */ | |
670 void | |
671 free_window_mirror (struct window_mirror *mir) | |
672 { | |
673 while (mir) | |
674 { | |
675 if (mir->hchild) free_window_mirror (mir->hchild); | |
676 if (mir->vchild) free_window_mirror (mir->vchild); | |
677 #ifdef HAVE_SCROLLBARS | |
678 release_window_mirror_scrollbars (mir); | |
679 #endif | |
680 free_display_structs (mir); | |
681 mir = mir->next; | |
5142
f965e31a35f0
reduce lcrecord headers to 2 words, rename printing_unreadable_object
Ben Wing <ben@xemacs.org>
parents:
5128
diff
changeset
|
682 /* not worth calling free_normal_lisp_object() -- window mirrors |
617 | 683 are not created that frequently and it's dangerous. we don't |
684 know for sure that there aren't other pointers around -- e.g. | |
685 in a scrollbar instance. */ | |
428 | 686 } |
687 } | |
688 | |
689 /* Given a mirror structure, return the window it mirrors. Calls | |
690 real_window_internal to do most of the work. */ | |
691 Lisp_Object | |
692 real_window (struct window_mirror *mir, int no_abort) | |
693 { | |
617 | 694 Lisp_Object retval = |
695 real_window_internal (mir->frame->root_window, | |
696 XWINDOW_MIRROR (mir->frame->root_mirror), mir); | |
5050
6f2158fa75ed
Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
697 assert (!NILP (retval) || no_abort); |
428 | 698 |
699 return retval; | |
700 } | |
701 | |
702 /* Given a real window, return its mirror structure. Calls | |
703 find_window_mirror_internal to do all of the work. */ | |
704 struct window_mirror * | |
705 find_window_mirror (struct window *w) | |
706 { | |
707 struct frame *f = XFRAME (w->frame); | |
708 if (f->mirror_dirty) | |
709 update_frame_window_mirror (f); | |
617 | 710 return find_window_mirror_internal (f->root_window, |
711 XWINDOW_MIRROR (f->root_mirror), w); | |
428 | 712 } |
713 | |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
714 /* Given a real window, return its mirror structure, if it exists. |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
715 Don't do any updating. */ |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
716 static struct window_mirror * |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
717 find_window_mirror_maybe (struct window *w) |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
718 { |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
719 struct frame *f = XFRAME (w->frame); |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
720 if (!WINDOW_MIRRORP (f->root_mirror)) |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
721 return 0; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
722 return find_window_mirror_internal (f->root_window, |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
723 XWINDOW_MIRROR (f->root_mirror), w); |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
724 } |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
725 |
428 | 726 /***************************************************************************** |
727 find_window_by_pixel_pos | |
728 | |
729 Given a pixel position relative to a frame, find the window at that | |
730 position. | |
731 ****************************************************************************/ | |
732 struct window * | |
733 find_window_by_pixel_pos (int pix_x, int pix_y, Lisp_Object win) | |
734 { | |
735 if (NILP (win)) | |
736 return 0; | |
737 | |
738 for (; !NILP (win); win = XWINDOW (win)->next) | |
739 { | |
740 struct window *w; | |
741 | |
742 if (!NILP (XWINDOW (win)->vchild)) | |
743 { | |
744 w = find_window_by_pixel_pos (pix_x, pix_y, XWINDOW (win)->vchild); | |
745 if (w) return w; | |
746 } | |
747 if (!NILP (XWINDOW (win)->hchild)) | |
748 { | |
749 w = find_window_by_pixel_pos (pix_x, pix_y, XWINDOW (win)->hchild); | |
750 if (w) return w; | |
751 } | |
752 w = XWINDOW (win); | |
753 if (pix_x >= WINDOW_LEFT (w) | |
754 && pix_x <= WINDOW_RIGHT (w) | |
755 && pix_y >= WINDOW_TOP (w) | |
756 && pix_y <= WINDOW_BOTTOM (w)) | |
757 return w; | |
758 } | |
759 return NULL; | |
760 } | |
761 | |
762 /* Return a pointer to the display structures for the given window. */ | |
763 display_line_dynarr * | |
764 window_display_lines (struct window *w, int which) | |
765 { | |
766 struct window_mirror *t; | |
767 | |
768 t = find_window_mirror (w); | |
5050
6f2158fa75ed
Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
769 assert (t); |
428 | 770 |
771 if (which == CURRENT_DISP) | |
772 return t->current_display_lines; | |
773 else if (which == DESIRED_DISP) | |
774 return t->desired_display_lines; | |
775 else if (which == CMOTION_DISP) | |
776 /* The CMOTION_DISP display lines are global. */ | |
777 return cmotion_display_lines; | |
778 else | |
2500 | 779 ABORT (); |
428 | 780 |
781 return 0; /* shut up compiler */ | |
782 } | |
783 | |
784 struct buffer * | |
785 window_display_buffer (struct window *w) | |
786 { | |
787 struct window_mirror *t; | |
788 | |
789 t = find_window_mirror (w); | |
5050
6f2158fa75ed
Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
790 assert (t); |
428 | 791 |
792 return t->buffer; | |
793 } | |
794 | |
795 void | |
796 set_window_display_buffer (struct window *w, struct buffer *b) | |
797 { | |
798 struct window_mirror *t; | |
799 | |
800 t = find_window_mirror (w); | |
5050
6f2158fa75ed
Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
801 assert (t); |
428 | 802 |
803 t->buffer = b; | |
804 } | |
805 | |
806 | |
807 /* Determining a window's position based solely on its pixel | |
808 positioning doesn't work. Instead, we do it the intelligent way, | |
809 by checking its positioning in the window hierarchy. */ | |
810 int | |
811 window_is_leftmost (struct window *w) | |
812 { | |
813 Lisp_Object parent, current_ancestor, window; | |
814 | |
793 | 815 window = wrap_window (w); |
428 | 816 |
817 parent = XWINDOW (window)->parent; | |
818 current_ancestor = window; | |
819 | |
820 while (!NILP (parent)) | |
821 { | |
822 if (!NILP (XWINDOW (parent)->hchild) && | |
823 !EQ (XWINDOW (parent)->hchild, current_ancestor)) | |
824 return 0; | |
825 | |
826 current_ancestor = parent; | |
827 parent = XWINDOW (parent)->parent; | |
828 } | |
829 | |
830 return 1; | |
831 } | |
832 | |
833 int | |
834 window_is_rightmost (struct window *w) | |
835 { | |
836 Lisp_Object parent, current_ancestor, window; | |
837 | |
793 | 838 window = wrap_window (w); |
428 | 839 |
840 parent = XWINDOW (window)->parent; | |
841 current_ancestor = window; | |
842 | |
843 while (!NILP (parent)) | |
844 { | |
845 if (!NILP (XWINDOW (parent)->hchild) | |
846 && !NILP (XWINDOW (current_ancestor)->next)) | |
847 return 0; | |
848 | |
849 current_ancestor = parent; | |
850 parent = XWINDOW (parent)->parent; | |
851 } | |
852 | |
853 return 1; | |
854 } | |
855 | |
856 static int | |
857 window_full_width_p (struct window *w) | |
858 { | |
859 return window_is_leftmost (w) && window_is_rightmost (w); | |
860 } | |
861 | |
862 int | |
863 window_is_highest (struct window *w) | |
864 { | |
865 Lisp_Object parent, current_ancestor, window; | |
866 | |
793 | 867 window = wrap_window (w); |
428 | 868 |
869 parent = XWINDOW (window)->parent; | |
870 current_ancestor = window; | |
871 | |
872 while (!NILP (parent)) | |
873 { | |
874 if (!NILP (XWINDOW (parent)->vchild) && | |
875 !EQ (XWINDOW (parent)->vchild, current_ancestor)) | |
876 return 0; | |
877 | |
878 current_ancestor = parent; | |
879 parent = XWINDOW (parent)->parent; | |
880 } | |
881 | |
882 /* This is really to catch the minibuffer but we make it generic in | |
883 case we ever change things around to let the minibuffer be on top. */ | |
884 if (NILP (XWINDOW (current_ancestor)->prev)) | |
885 return 1; | |
886 else | |
887 return 0; | |
888 } | |
889 | |
890 int | |
891 window_is_lowest (struct window *w) | |
892 { | |
893 Lisp_Object parent, current_ancestor, window; | |
894 | |
793 | 895 window = wrap_window (w); |
428 | 896 |
897 parent = XWINDOW (window)->parent; | |
898 current_ancestor = window; | |
899 | |
900 while (!NILP (parent)) | |
901 { | |
902 if (!NILP (XWINDOW (parent)->vchild) | |
903 && !NILP (XWINDOW (current_ancestor)->next)) | |
904 return 0; | |
905 | |
906 current_ancestor = parent; | |
907 parent = XWINDOW (parent)->parent; | |
908 } | |
909 | |
910 return 1; | |
911 } | |
912 | |
913 #if 0 /* not currently used */ | |
914 | |
915 static int | |
916 window_full_height_p (struct window *w) | |
917 { | |
918 return window_is_highest (w) && window_is_lowest (w); | |
919 } | |
920 | |
921 #endif | |
922 | |
923 int | |
924 window_truncation_on (struct window *w) | |
925 { | |
926 /* Minibuffer windows are never truncated. | |
440 | 927 #### is this the right way ? */ |
428 | 928 if (MINI_WINDOW_P (w)) |
929 return 0; | |
930 | |
931 /* Horizontally scrolled windows are truncated. */ | |
932 if (w->hscroll) | |
933 return 1; | |
934 | |
935 /* If truncate_partial_width_windows is true and the window is not | |
936 the full width of the frame it is truncated. */ | |
707 | 937 if (!NILP (symbol_value_in_buffer (Qtruncate_partial_width_windows, |
938 w->buffer)) | |
428 | 939 && !(window_is_leftmost (w) && window_is_rightmost (w))) |
940 return 1; | |
941 | |
942 /* If the window's buffer's value of truncate_lines is non-nil, then | |
943 the window is truncated. */ | |
944 if (!NILP (XBUFFER (w->buffer)->truncate_lines)) | |
945 return 1; | |
946 | |
947 return 0; | |
948 } | |
949 | |
950 DEFUN ("window-truncated-p", Fwindow_truncated_p, 0, 1, 0, /* | |
442 | 951 Returns non-nil if text in the window is truncated. |
428 | 952 */ |
953 (window)) | |
954 { | |
955 struct window *w = decode_window (window); | |
956 | |
957 return window_truncation_on (w) ? Qt : Qnil; | |
958 } | |
959 | |
960 | |
961 static int | |
962 have_undivided_common_edge (struct window *w_right, void *closure) | |
963 { | |
964 struct window *w_left = (struct window *) closure; | |
965 return (WINDOW_RIGHT (w_left) == WINDOW_LEFT (w_right) | |
966 && WINDOW_TOP (w_left) < WINDOW_BOTTOM (w_right) | |
967 && WINDOW_TOP (w_right) < WINDOW_BOTTOM (w_left) | |
968 #ifdef HAVE_SCROLLBARS | |
969 && (NILP (w_right->scrollbar_on_left_p) | |
970 || NILP (w_right->vertical_scrollbar_visible_p) | |
971 || ZEROP (w_right->scrollbar_width)) | |
972 #endif | |
973 ); | |
974 } | |
975 | |
976 static int | |
977 window_needs_vertical_divider_1 (struct window *w) | |
978 { | |
979 /* Never if we're on the right */ | |
980 if (window_is_rightmost (w)) | |
981 return 0; | |
982 | |
983 /* Always if draggable */ | |
984 if (!NILP (w->vertical_divider_always_visible_p)) | |
985 return 1; | |
986 | |
987 #ifdef HAVE_SCROLLBARS | |
988 /* Our right scrollbar is enough to separate us at the right */ | |
989 if (NILP (w->scrollbar_on_left_p) | |
990 && !NILP (w->vertical_scrollbar_visible_p) | |
991 && !ZEROP (w->scrollbar_width)) | |
992 return 0; | |
993 #endif | |
994 | |
995 /* Ok. to determine whether we need a divider on the left, we must | |
996 check that our right neighbor windows have scrollbars on their | |
997 left sides. We must check all such windows which have common | |
998 left edge with our window's right edge. */ | |
999 return map_windows (XFRAME (WINDOW_FRAME (w)), | |
1000 have_undivided_common_edge, (void*)w); | |
1001 } | |
1002 | |
1003 int | |
1004 window_needs_vertical_divider (struct window *w) | |
1005 { | |
1006 if (!w->need_vertical_divider_valid_p) | |
1007 { | |
1008 w->need_vertical_divider_p = | |
1009 window_needs_vertical_divider_1 (w); | |
1010 w->need_vertical_divider_valid_p = 1; | |
1011 } | |
1012 return w->need_vertical_divider_p; | |
1013 } | |
1014 | |
1015 /* Called from invalidate_vertical_divider_cache_in_frame */ | |
1016 int | |
1017 invalidate_vertical_divider_cache_in_window (struct window *w, | |
2286 | 1018 void *UNUSED (unused)) |
428 | 1019 { |
1020 w->need_vertical_divider_valid_p = 0; | |
1021 return 0; | |
1022 } | |
1023 | |
1024 /* Calculate width of vertical divider, including its shadows | |
1025 and spacing. The returned value is effectively the distance | |
1026 between adjacent window edges. This function does not check | |
1027 whether a window needs a vertical divider, so the returned | |
1028 value is a "theoretical" one */ | |
1029 int | |
1030 window_divider_width (struct window *w) | |
1031 { | |
1032 /* the shadow thickness can be negative. This means that the divider | |
1033 will have a depressed look */ | |
1034 | |
1035 if (FRAME_WIN_P (XFRAME (WINDOW_FRAME (w)))) | |
1036 return | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1037 XFIXNUM (w->vertical_divider_line_width) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1038 + 2 * XFIXNUM (w->vertical_divider_spacing) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1039 + 2 * abs (XFIXNUM (w->vertical_divider_shadow_thickness)); |
428 | 1040 else |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1041 return XFIXNUM (w->vertical_divider_line_width) == 0 ? 0 : 1; |
428 | 1042 } |
1043 | |
1044 int | |
4932 | 1045 window_scrollbar_width (struct window * USED_IF_SCROLLBARS (w)) |
428 | 1046 { |
1047 #ifdef HAVE_SCROLLBARS | |
1048 if (!WINDOW_WIN_P (w) | |
1049 || MINI_WINDOW_P (w) | |
1050 || NILP (w->buffer) | |
1051 || NILP (w->vertical_scrollbar_visible_p)) | |
1052 /* #### when does NILP (w->buffer) happen? */ | |
1053 return 0; | |
1054 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1055 return XFIXNUM (w->scrollbar_width); |
428 | 1056 #else |
1057 return 0; | |
1058 #endif /* HAVE_SCROLLBARS */ | |
1059 } | |
1060 | |
1061 /* Horizontal scrollbars are only active on windows with truncation | |
1062 turned on. */ | |
1063 int | |
4932 | 1064 window_scrollbar_height (struct window * USED_IF_SCROLLBARS (w)) |
428 | 1065 { |
1066 #ifdef HAVE_SCROLLBARS | |
1067 if (!WINDOW_WIN_P (w) | |
1068 || MINI_WINDOW_P (w) | |
1069 || NILP (w->buffer) | |
1070 || NILP (w->horizontal_scrollbar_visible_p) | |
1071 || !window_truncation_on (w)) | |
1072 return 0; | |
1073 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1074 return XFIXNUM (w->scrollbar_height); |
428 | 1075 #else |
1076 return 0; | |
1077 #endif /* HAVE_SCROLLBARS */ | |
1078 } | |
1079 | |
1080 int | |
1081 window_modeline_height (struct window *w) | |
1082 { | |
1083 struct frame *f = XFRAME (w->frame); | |
1084 int modeline_height; | |
1085 | |
1086 if (MINI_WINDOW_P (w) || NILP (w->buffer)) | |
1087 { | |
1088 modeline_height = 0; | |
1089 } | |
1090 else if (!WINDOW_HAS_MODELINE_P (w)) | |
1091 { | |
1092 if (window_scrollbar_height (w)) | |
1093 modeline_height = 0; | |
1094 else | |
1095 { | |
1096 modeline_height = FRAMEMETH (f, divider_height, ()); | |
1097 | |
1098 if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f)) | |
1099 modeline_height += (2 * MODELINE_SHADOW_THICKNESS (w)); | |
1100 } | |
1101 } | |
1102 else | |
1103 { | |
1104 if (noninteractive) | |
1105 modeline_height = 0; | |
1106 else | |
1107 { | |
1108 display_line_dynarr *dla; | |
1109 | |
1110 /* We don't force a regeneration of the modeline here. | |
1111 Instead it is now a precondition that any function calling | |
1112 this should make sure that one of these structures is | |
1113 up-to-date. In practice this only affects two internal | |
1114 redisplay functions, regenerate_window and | |
1115 regenerate_window_point_center. */ | |
1116 /* We check DESIRED_DISP because if it is valid it is more | |
1117 up-to-date than CURRENT_DISP. For calls to this outside | |
1118 of redisplay it doesn't matter which structure we check | |
1119 since there is a redisplay condition that these | |
1120 structures be identical outside of redisplay. */ | |
1121 dla = window_display_lines (w, DESIRED_DISP); | |
4967 | 1122 if (dla && Dynarr_length (dla) && Dynarr_begin (dla)->modeline) |
1123 modeline_height = (Dynarr_begin (dla)->ascent + | |
1124 Dynarr_begin (dla)->descent); | |
428 | 1125 else |
1126 { | |
1127 dla = window_display_lines (w, CURRENT_DISP); | |
4967 | 1128 if (dla && Dynarr_length (dla) && Dynarr_begin (dla)->modeline) |
1129 modeline_height = (Dynarr_begin (dla)->ascent + | |
1130 Dynarr_begin (dla)->descent); | |
428 | 1131 else |
1132 /* This should be an abort except I'm not yet 100% | |
1133 confident that it won't ever get hit (though I | |
1134 haven't been able to trigger it). It is extremely | |
1135 unlikely to cause any noticeable problem and even if | |
1136 it does it will be a minor display glitch. */ | |
1137 /* #### Bullshit alert. It does get hit and it causes | |
1138 noticeable glitches. real_current_modeline_height | |
1139 is a kludge to fix this for 19.14. */ | |
1140 modeline_height = real_current_modeline_height (w); | |
1141 } | |
1142 | |
1143 if (!EQ (Qzero, w->modeline_shadow_thickness) && FRAME_WIN_P (f)) | |
1144 modeline_height += (2 * MODELINE_SHADOW_THICKNESS (w)); | |
1145 } | |
1146 } | |
1147 | |
1148 return modeline_height; | |
1149 } | |
1150 | |
1151 /***************************************************************************** | |
1152 margin_width_internal | |
1153 | |
1154 For a given window, return the width in pixels of the specified margin. | |
1155 ****************************************************************************/ | |
1156 static int | |
1157 margin_width_internal (struct window *w, int left_margin) | |
1158 { | |
1159 int window_cwidth = window_char_width (w, 1); | |
1160 int margin_cwidth; | |
1161 int font_width; | |
1162 Lisp_Object window; | |
1163 | |
1164 /* We might be getting called on a non-leaf. */ | |
1165 if (NILP (w->buffer)) | |
1166 return 0; | |
1167 | |
1168 /* The minibuffer never has margins. */ | |
1169 if (MINI_WINDOW_P (w)) | |
1170 return 0; | |
1171 | |
793 | 1172 window = wrap_window (w); |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1173 margin_cwidth = (left_margin ? XFIXNUM (w->left_margin_width) : |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1174 XFIXNUM (w->right_margin_width)); |
428 | 1175 |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
1176 default_face_width_and_height (window, &font_width, 0); |
428 | 1177 |
1178 /* The left margin takes precedence over the right margin so we | |
1179 subtract its width from the space available for the right | |
1180 margin. */ | |
1181 if (!left_margin) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1182 window_cwidth -= XFIXNUM (w->left_margin_width); |
428 | 1183 |
1184 /* The margin cannot be wider than the window is. We allow the | |
1185 value to be bigger since it is possible for the user to enlarge | |
1186 the window such that the left margin value would no longer be too | |
1187 big, but we won't return a value that is larger. */ | |
1188 if (margin_cwidth > window_cwidth) | |
1189 margin_cwidth = window_cwidth; | |
1190 | |
1191 /* At the user level the margin is always specified in characters. | |
1192 Internally however it is manipulated in terms of pixels. */ | |
1193 return margin_cwidth * font_width; | |
1194 } | |
1195 | |
1196 int | |
1197 window_left_margin_width (struct window *w) | |
1198 { | |
1199 return margin_width_internal (w, 1); | |
1200 } | |
1201 | |
1202 int | |
1203 window_right_margin_width (struct window *w) | |
1204 { | |
1205 return margin_width_internal (w, 0); | |
1206 } | |
1207 | |
1208 /***************************************************************************** | |
1209 Window Gutters | |
1210 | |
1211 The gutters of a window are those areas in the boundary defined by | |
1212 w->pixel_top, w->pixel_left, w->pixel_height and w->pixel_width which | |
1213 do not contain text. Items which may be in the gutters include | |
1214 scrollbars, toolbars and modelines. The margin areas are not | |
1215 included. This is an exception made because redisplay special cases | |
1216 the handling of those areas in many places in such a way that | |
1217 including them in the gutter area would make life difficult. | |
1218 | |
1219 The size functions refer to height for the bottom and top gutters and | |
1220 width for the left and right gutters. The starting position | |
1221 functions refer to the Y coord for bottom and top gutters and the X | |
1222 coord for left and right gutters. All starting positions are | |
1223 relative to the frame, not the window. | |
1224 ****************************************************************************/ | |
1225 | |
442 | 1226 static int |
1227 window_top_window_gutter_height (struct window *w) | |
1228 { | |
428 | 1229 if (!NILP (w->hchild) || !NILP (w->vchild)) |
1230 return 0; | |
1231 | |
1232 #ifdef HAVE_SCROLLBARS | |
1233 if (!NILP (w->scrollbar_on_top_p)) | |
442 | 1234 return window_scrollbar_height (w); |
428 | 1235 else |
1236 #endif | |
442 | 1237 return 0; |
428 | 1238 } |
1239 | |
1240 int | |
442 | 1241 window_top_gutter_height (struct window *w) |
1242 { | |
1243 return window_top_window_gutter_height (w); | |
1244 } | |
1245 | |
1246 static int | |
1247 window_bottom_window_gutter_height (struct window *w) | |
1248 { | |
1249 int gutter; | |
428 | 1250 |
1251 if (!NILP (w->hchild) || !NILP (w->vchild)) | |
1252 return 0; | |
1253 | |
442 | 1254 gutter = window_modeline_height (w); |
428 | 1255 |
1256 #ifdef HAVE_SCROLLBARS | |
1257 if (NILP (w->scrollbar_on_top_p)) | |
1258 return window_scrollbar_height (w) + gutter; | |
1259 else | |
1260 #endif | |
1261 return gutter; | |
1262 } | |
1263 | |
1264 int | |
442 | 1265 window_bottom_gutter_height (struct window *w) |
1266 { | |
1267 return window_bottom_window_gutter_height (w); | |
1268 } | |
1269 | |
1270 static int | |
4932 | 1271 window_left_window_gutter_width (struct window *w, |
1272 int USED_IF_SCROLLBARS (modeline)) | |
442 | 1273 { |
428 | 1274 if (!NILP (w->hchild) || !NILP (w->vchild)) |
1275 return 0; | |
1276 | |
1277 #ifdef HAVE_SCROLLBARS | |
1278 if (!modeline && !NILP (w->scrollbar_on_left_p)) | |
442 | 1279 return window_scrollbar_width (w); |
428 | 1280 #endif |
1281 | |
442 | 1282 return 0; |
428 | 1283 } |
1284 | |
1285 int | |
442 | 1286 window_left_gutter_width (struct window *w, int modeline) |
1287 { | |
1288 return window_left_window_gutter_width (w, modeline); | |
1289 } | |
1290 | |
1291 static int | |
4932 | 1292 window_right_window_gutter_width (struct window *w, |
1293 int USED_IF_SCROLLBARS (modeline)) | |
442 | 1294 { |
1295 int gutter = 0; | |
428 | 1296 |
1297 if (!NILP (w->hchild) || !NILP (w->vchild)) | |
1298 return 0; | |
1299 | |
1300 #ifdef HAVE_SCROLLBARS | |
1301 if (!modeline && NILP (w->scrollbar_on_left_p)) | |
1302 gutter += window_scrollbar_width (w); | |
1303 #endif | |
1304 | |
1305 if (window_needs_vertical_divider (w)) | |
1306 gutter += window_divider_width (w); | |
1307 | |
1308 return gutter; | |
1309 } | |
1310 | |
442 | 1311 int |
1312 window_right_gutter_width (struct window *w, int modeline) | |
1313 { | |
1314 return window_right_window_gutter_width (w, modeline); | |
1315 } | |
1316 | |
1317 static int | |
1318 window_pixel_height (struct window* w) | |
1319 { | |
1320 return WINDOW_HEIGHT (w); | |
1321 } | |
1322 | |
428 | 1323 |
1324 DEFUN ("windowp", Fwindowp, 1, 1, 0, /* | |
444 | 1325 Return t if OBJECT is a window. |
428 | 1326 */ |
444 | 1327 (object)) |
1328 { | |
1329 return WINDOWP (object) ? Qt : Qnil; | |
428 | 1330 } |
1331 | |
1332 DEFUN ("window-live-p", Fwindow_live_p, 1, 1, 0, /* | |
444 | 1333 Return t if OBJECT is a window which is currently visible. |
428 | 1334 */ |
444 | 1335 (object)) |
1336 { | |
1337 return WINDOWP (object) && WINDOW_LIVE_P (XWINDOW (object)) | |
1338 ? Qt : Qnil; | |
428 | 1339 } |
1340 | |
1341 DEFUN ("selected-window", Fselected_window, 0, 1, 0, /* | |
1342 Return the window that the cursor now appears in and commands apply to. | |
1343 If the optional argument CON-DEV-OR-FRAME is specified and is a frame, return | |
1344 the selected window used by that frame. If CON-DEV-OR-FRAME is a device, | |
1345 then the selected frame on that device will be used. If CON-DEV-OR-FRAME | |
1346 is a console, the selected frame on that console's selected device will | |
1347 be used. Otherwise, the selected frame is used. | |
1348 */ | |
1349 (con_dev_or_frame)) | |
1350 { | |
1351 if (NILP (con_dev_or_frame) && NILP (Fselected_device (Qnil))) | |
1352 return Qnil; /* happens at startup */ | |
1353 | |
1354 { | |
1355 struct frame *f = decode_frame_or_selected (con_dev_or_frame); | |
1356 return FRAME_SELECTED_WINDOW (f); | |
1357 } | |
1358 } | |
1359 | |
1360 DEFUN ("last-nonminibuf-window", Flast_nonminibuf_window, 0, 1, 0, /* | |
1361 Return the last selected window that is not a minibuffer window. | |
1362 If the optional argument CON-DEV-OR-FRAME is specified and is a frame, | |
1363 return the last non-minibuffer window used by that frame. If | |
1364 CON-DEV-OR-FRAME is a device, then the selected frame on that device | |
1365 will be used. If CON-DEV-OR-FRAME is a console, the selected frame on | |
1366 that console's selected device will be used. Otherwise, the selected | |
1367 frame is used. | |
1368 */ | |
1369 (con_dev_or_frame)) | |
1370 { | |
1371 if (NILP (con_dev_or_frame) && NILP (Fselected_device (Qnil))) | |
1372 return Qnil; /* happens at startup */ | |
1373 | |
1374 { | |
1375 struct frame *f = decode_frame_or_selected (con_dev_or_frame); | |
1376 return FRAME_LAST_NONMINIBUF_WINDOW (f); | |
1377 } | |
1378 } | |
1379 | |
1380 DEFUN ("minibuffer-window", Fminibuffer_window, 0, 1, 0, /* | |
1381 Return the window used now for minibuffers. | |
1382 If the optional argument CON-DEV-OR-FRAME is specified and is a frame, return | |
1383 the minibuffer window used by that frame. If CON-DEV-OR-FRAME is a device, | |
1384 then the selected frame on that device will be used. If CON-DEV-OR-FRAME | |
1385 is a console, the selected frame on that console's selected device will | |
1386 be used. Otherwise, the selected frame is used. | |
1387 */ | |
1388 (con_dev_or_frame)) | |
1389 { | |
1390 return FRAME_MINIBUF_WINDOW (decode_frame_or_selected (con_dev_or_frame)); | |
1391 } | |
1392 | |
438 | 1393 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, 0, 1, 0, /* |
428 | 1394 Return non-nil if WINDOW is a minibuffer window. |
1395 */ | |
1396 (window)) | |
1397 { | |
1398 return MINI_WINDOW_P (decode_window (window)) ? Qt : Qnil; | |
1399 } | |
1400 | |
1401 DEFUN ("window-first-hchild", Fwindow_first_hchild, 1, 1, 0, /* | |
1402 Return the first horizontal child of WINDOW, or nil. | |
1403 */ | |
1404 (window)) | |
1405 { | |
1406 return decode_window (window)->hchild; | |
1407 } | |
1408 | |
1409 DEFUN ("window-first-vchild", Fwindow_first_vchild, 1, 1, 0, /* | |
1410 Return the first vertical child of WINDOW, or nil. | |
1411 */ | |
1412 (window)) | |
1413 { | |
1414 return decode_window (window)->vchild; | |
1415 } | |
1416 | |
1417 DEFUN ("window-next-child", Fwindow_next_child, 1, 1, 0, /* | |
1418 Return the next window on the same level as WINDOW, or nil. | |
1419 */ | |
1420 (window)) | |
1421 { | |
1422 return decode_window (window)->next; | |
1423 } | |
1424 | |
1425 DEFUN ("window-previous-child", Fwindow_previous_child, 1, 1, 0, /* | |
1426 Return the previous window on the same level as WINDOW, or nil. | |
1427 */ | |
1428 (window)) | |
1429 { | |
1430 return decode_window (window)->prev; | |
1431 } | |
1432 | |
1433 DEFUN ("window-parent", Fwindow_parent, 1, 1, 0, /* | |
1434 Return the parent of WINDOW, or nil. | |
1435 */ | |
1436 (window)) | |
1437 { | |
1438 return decode_window (window)->parent; | |
1439 } | |
1440 | |
1441 DEFUN ("window-lowest-p", Fwindow_lowest_p, 1, 1, 0, /* | |
1442 Return non-nil if WINDOW is along the bottom of its frame. | |
1443 */ | |
1444 (window)) | |
1445 { | |
1446 return window_is_lowest (decode_window (window)) ? Qt : Qnil; | |
1447 } | |
1448 | |
1449 DEFUN ("window-highest-p", Fwindow_highest_p, 1, 1, 0, /* | |
1450 Return non-nil if WINDOW is along the top of its frame. | |
1451 */ | |
1452 (window)) | |
1453 { | |
1454 return window_is_highest (decode_window (window)) ? Qt : Qnil; | |
1455 } | |
1456 | |
1457 DEFUN ("window-leftmost-p", Fwindow_leftmost_p, 1, 1, 0, /* | |
1458 Return non-nil if WINDOW is along the left edge of its frame. | |
1459 */ | |
1460 (window)) | |
1461 { | |
1462 return window_is_leftmost (decode_window (window)) ? Qt : Qnil; | |
1463 } | |
1464 | |
1465 DEFUN ("window-rightmost-p", Fwindow_rightmost_p, 1, 1, 0, /* | |
1466 Return non-nil if WINDOW is along the right edge of its frame. | |
1467 */ | |
1468 (window)) | |
1469 { | |
1470 return window_is_rightmost (decode_window (window)) ? Qt : Qnil; | |
1471 } | |
1472 | |
1708 | 1473 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p, 0, 3, 0, /* |
1474 Returns t if position POS is currently on the frame in WINDOW. | |
428 | 1475 Returns nil if that position is scrolled vertically out of view. |
1708 | 1476 If a character is only partially visible, nil is returned, unless the |
1477 optional argument PARTIALLY is non-nil. | |
428 | 1478 POS defaults to point in WINDOW's buffer; WINDOW, to the selected window. |
1479 */ | |
1708 | 1480 (pos, window, partially)) |
428 | 1481 { |
1482 struct window *w = decode_window (window); | |
665 | 1483 Charbpos top = marker_position (w->start[CURRENT_DISP]); |
1484 Charbpos posint; | |
428 | 1485 struct buffer *buf = XBUFFER (w->buffer); |
1486 | |
1487 if (NILP (pos)) | |
1488 posint = BUF_PT (buf); | |
1489 else | |
1490 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1491 CHECK_FIXNUM_COERCE_MARKER (pos); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1492 posint = XFIXNUM (pos); |
428 | 1493 } |
1494 | |
1495 if (posint < top || posint > BUF_ZV (buf)) | |
1496 return Qnil; | |
1497 | |
1498 /* w->start can be out of range. If it is, do something reasonable. */ | |
1499 if (top < BUF_BEGV (buf) || top > BUF_ZV (buf)) | |
1500 return Qnil; | |
1501 | |
1708 | 1502 return point_would_be_visible (w, top, posint, !NILP (partially)) |
1503 ? Qt : Qnil; | |
428 | 1504 } |
1505 | |
1506 | |
1507 struct window * | |
1508 decode_window (Lisp_Object window) | |
1509 { | |
1510 if (NILP (window)) | |
1511 return XWINDOW (Fselected_window (Qnil)); | |
1512 | |
1513 CHECK_LIVE_WINDOW (window); | |
1514 return XWINDOW (window); | |
1515 } | |
1516 | |
872 | 1517 int |
1518 window_live_p (struct window *w) | |
1519 { | |
1520 return WINDOW_LIVE_P (w); | |
1521 } | |
1522 | |
1523 Lisp_Object | |
1524 window_frame (struct window *w) | |
1525 { | |
1526 return WINDOW_FRAME (w); | |
1527 } | |
1528 | |
1529 Lisp_Object | |
1530 window_buffer (struct window *w) | |
1531 { | |
1532 return WINDOW_BUFFER (w); | |
1533 } | |
1534 | |
428 | 1535 DEFUN ("window-buffer", Fwindow_buffer, 0, 1, 0, /* |
1536 Return the buffer that WINDOW is displaying. | |
1537 */ | |
1538 (window)) | |
1539 { | |
1540 return decode_window (window)->buffer; | |
1541 } | |
1542 | |
1543 DEFUN ("window-frame", Fwindow_frame, 0, 1, 0, /* | |
1544 Return the frame that window WINDOW is on. | |
1545 */ | |
1546 (window)) | |
1547 { | |
1548 return decode_window (window)->frame; | |
1549 } | |
1550 | |
1551 DEFUN ("window-height", Fwindow_height, 0, 1, 0, /* | |
1552 Return the number of default lines in WINDOW. | |
1553 This actually works by dividing the window's pixel height (including | |
1554 the modeline and horizontal scrollbar, if any) by the height of the | |
1555 default font; therefore, the number of displayed lines will probably | |
1556 be different. | |
1557 Use `window-height' to get consistent results in geometry calculations. | |
1558 Use `window-displayed-height' to get the actual number of lines | |
1559 currently displayed in a window. | |
442 | 1560 |
1561 The names are somewhat confusing; here's a table to help out: | |
1562 | |
1563 width height | |
1564 ------------------------------------------------------------------------- | |
1565 w/o gutters | |
1566 (rows/columns) window-width window-text-area-height | |
1567 (pixels) window-text-area-pixel-width window-text-area-pixel-height | |
1568 | |
1569 with gutters | |
1570 (rows/columns) window-full-width window-height | |
1571 (pixels) window-pixel-width window-pixel-height | |
1572 | |
1573 actually displayed | |
1574 (rows/columns) ---- window-displayed-height | |
1575 (pixels) ---- window-displayed-text-pixel-height | |
428 | 1576 */ |
1577 (window)) | |
1578 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1579 return make_fixnum (window_char_height (decode_window (window), 1)); |
428 | 1580 } |
1581 | |
1582 DEFUN ("window-displayed-height", Fwindow_displayed_height, 0, 1, 0, /* | |
1583 Return the number of lines currently displayed in WINDOW. | |
1584 This counts the actual number of lines displayed in WINDOW | |
1585 \(as opposed to `window-height'). The modeline and horizontal | |
1586 scrollbar do not count as lines. If there is some blank space | |
1587 between the end of the buffer and the end of the window, this | |
1588 function pretends that there are lines of text in the default | |
1589 font there. | |
1590 */ | |
1591 (window)) | |
1592 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1593 return make_fixnum (window_displayed_height (decode_window (window))); |
428 | 1594 } |
1595 | |
1596 DEFUN ("window-pixel-height", Fwindow_pixel_height, 0, 1, 0, /* | |
1597 Return the height of WINDOW in pixels. Defaults to current window. | |
1598 This includes the window's modeline and horizontal scrollbar (if any). | |
1599 */ | |
1600 (window)) | |
1601 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1602 return make_fixnum (window_pixel_height (decode_window (window))); |
442 | 1603 } |
1604 | |
1605 DEFUN ("window-text-area-height", Fwindow_text_area_height, 0, 1, 0, /* | |
1606 Return the number of default lines in the text area of WINDOW. | |
1607 This actually works by dividing the window's text area pixel height (i.e. | |
1608 excluding the modeline and horizontal scrollbar, if any) by the height of the | |
1609 default font; therefore, the number of displayed lines will probably | |
1610 be different. | |
1611 See also `window-height' and `window-displayed-height'. | |
1612 */ | |
1613 (window)) | |
1614 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1615 return make_fixnum (window_char_height (decode_window (window), 0)); |
428 | 1616 } |
1617 | |
1618 DEFUN ("window-text-area-pixel-height", | |
1619 Fwindow_text_area_pixel_height, 0, 1, 0, /* | |
1620 Return the height in pixels of the text-displaying portion of WINDOW. | |
1621 Unlike `window-pixel-height', the space occupied by the modeline and | |
1622 horizontal scrollbar, if any, is not counted. | |
1623 */ | |
1624 (window)) | |
1625 { | |
1626 struct window *w = decode_window (window); | |
1627 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1628 return make_fixnum (WINDOW_TEXT_HEIGHT (w)); |
428 | 1629 } |
1630 | |
1631 DEFUN ("window-displayed-text-pixel-height", | |
1632 Fwindow_displayed_text_pixel_height, 0, 2, 0, /* | |
1633 Return the height in pixels of the text displayed in WINDOW. | |
1634 Unlike `window-text-area-pixel-height', any blank space below the | |
1635 end of the buffer is not included. If optional argument NOCLIPPED | |
1636 is non-nil, do not include space occupied by clipped lines. | |
1637 */ | |
1638 (window, noclipped)) | |
1639 { | |
1640 struct window *w; | |
665 | 1641 Charbpos start, eobuf; |
428 | 1642 int defheight; |
1643 int hlimit, height, prev_height = -1; | |
1644 int line; | |
1645 int elt, nelt, i; | |
1646 int needed; | |
1647 line_start_cache_dynarr *cache; | |
1648 | |
1649 if (NILP (window)) | |
1650 window = Fselected_window (Qnil); | |
1651 | |
1652 CHECK_LIVE_WINDOW (window); | |
1653 w = XWINDOW (window); | |
1654 | |
1655 start = marker_position (w->start[CURRENT_DISP]); | |
1656 hlimit = WINDOW_TEXT_HEIGHT (w); | |
1657 eobuf = BUF_ZV (XBUFFER (w->buffer)); | |
1658 | |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
1659 default_face_width_and_height (window, NULL, &defheight); |
428 | 1660 |
1661 /* guess lines needed in line start cache + a few extra */ | |
1662 needed = (hlimit + defheight-1) / defheight + 3; | |
1663 | |
1664 while (1) { | |
1665 elt = point_in_line_start_cache (w, start, needed); | |
1666 assert (elt >= 0); /* in the cache */ | |
1667 | |
1668 cache = w->line_start_cache; | |
1669 nelt = Dynarr_length (cache); | |
1670 | |
1671 height = 0; | |
1672 for (i = elt; i < nelt; i++) { | |
1673 line = Dynarr_atp (cache, i)->height; | |
1674 | |
1675 if (height + line > hlimit) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1676 return make_fixnum (!NILP (noclipped) ? height : hlimit); |
428 | 1677 |
1678 height += line; | |
1679 | |
1680 if (height == hlimit || Dynarr_atp (cache, i)->end >= eobuf) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1681 return make_fixnum (height); |
428 | 1682 } |
1683 | |
1684 /* get here => need more cache lines. try again. */ | |
1685 assert(height > prev_height); /* progress? */ | |
1686 prev_height = height; | |
1687 | |
1688 needed += ((hlimit - height)*(nelt - elt) + height-1)/height + 3; | |
1689 } | |
1690 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1691 RETURN_NOT_REACHED(make_fixnum (0)); /* shut up compiler */ |
428 | 1692 } |
1693 | |
1694 DEFUN ("window-width", Fwindow_width, 0, 1, 0, /* | |
1695 Return the number of display columns in WINDOW. | |
442 | 1696 This is the width that is usable columns available for text in WINDOW, |
1697 and does not include vertical scrollbars, dividers, or the like. See also | |
1698 `window-full-width' and `window-height'. | |
428 | 1699 */ |
1700 (window)) | |
1701 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1702 return make_fixnum (window_char_width (decode_window (window), 0)); |
428 | 1703 } |
1704 | |
442 | 1705 DEFUN ("window-full-width", Fwindow_full_width, 0, 1, 0, /* |
1706 Return the total number of columns in WINDOW. | |
1707 This is like `window-width' but includes vertical scrollbars, dividers, | |
1708 etc. | |
1709 */ | |
1710 (window)) | |
1711 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1712 return make_fixnum (window_char_width (decode_window (window), 1)); |
442 | 1713 } |
1714 | |
428 | 1715 DEFUN ("window-pixel-width", Fwindow_pixel_width, 0, 1, 0, /* |
1716 Return the width of WINDOW in pixels. Defaults to current window. | |
1717 */ | |
1718 (window)) | |
1719 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1720 return make_fixnum (decode_window (window)->pixel_width); |
428 | 1721 } |
1722 | |
1723 DEFUN ("window-text-area-pixel-width", | |
1724 Fwindow_text_area_pixel_width, 0, 1, 0, /* | |
1725 Return the width in pixels of the text-displaying portion of WINDOW. | |
1726 Unlike `window-pixel-width', the space occupied by the vertical | |
1727 scrollbar or divider, if any, is not counted. | |
1728 */ | |
1729 (window)) | |
1730 { | |
1731 struct window *w = decode_window (window); | |
1732 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1733 return make_fixnum (WINDOW_TEXT_WIDTH (w)); |
428 | 1734 } |
1735 | |
1736 DEFUN ("window-hscroll", Fwindow_hscroll, 0, 1, 0, /* | |
1737 Return the number of columns by which WINDOW is scrolled from left margin. | |
1738 */ | |
1739 (window)) | |
1740 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1741 return make_fixnum (decode_window (window)->hscroll); |
428 | 1742 } |
1743 | |
1744 DEFUN ("modeline-hscroll", Fmodeline_hscroll, 0, 1, 0, /* | |
442 | 1745 Return the horizontal scrolling amount of WINDOW's modeline. |
438 | 1746 If the window has no modeline, return nil. |
428 | 1747 */ |
1748 (window)) | |
1749 { | |
1750 struct window *w = decode_window (window); | |
1751 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1752 return (WINDOW_HAS_MODELINE_P (w)) ? make_fixnum ((int) w->modeline_hscroll) : |
438 | 1753 Qnil; |
428 | 1754 } |
1755 | |
1756 DEFUN ("set-modeline-hscroll", Fset_modeline_hscroll, 2, 2, 0, /* | |
442 | 1757 Set the horizontal scrolling amount of WINDOW's modeline to NCOL. |
438 | 1758 If NCOL is negative, it will silently be forced to 0. |
1759 If the window has no modeline, return nil. Otherwise, return the actual | |
1760 value that was set. | |
428 | 1761 */ |
1762 (window, ncol)) | |
1763 { | |
1764 struct window *w = decode_window (window); | |
1765 | |
1766 if (WINDOW_HAS_MODELINE_P (w)) | |
1767 { | |
438 | 1768 Charcount ncols; |
1769 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1770 CHECK_FIXNUM (ncol); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1771 ncols = (XFIXNUM (ncol) <= 0) ? 0 : (Charcount) XFIXNUM (ncol); |
438 | 1772 if (ncols != w->modeline_hscroll) |
1773 { | |
1774 MARK_MODELINE_CHANGED; | |
1775 w->modeline_hscroll = ncols; | |
1776 } | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1777 return make_fixnum ((int) ncols); |
428 | 1778 } |
438 | 1779 |
428 | 1780 return Qnil; |
1781 } | |
1782 | |
1783 DEFUN ("set-window-hscroll", Fset_window_hscroll, 2, 2, 0, /* | |
1784 Set number of columns WINDOW is scrolled from left margin to NCOL. | |
1785 NCOL should be zero or positive. | |
1786 */ | |
1787 (window, ncol)) | |
1788 { | |
1789 struct window *w; | |
1790 int ncols; | |
1791 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1792 CHECK_FIXNUM (ncol); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1793 ncols = XFIXNUM (ncol); |
428 | 1794 if (ncols < 0) ncols = 0; |
1795 w = decode_window (window); | |
1796 if (w->hscroll != ncols) | |
1797 MARK_CLIP_CHANGED; /* FSF marks differently but we aren't FSF. */ | |
1798 w->hscroll = ncols; | |
1799 return ncol; | |
1800 } | |
1801 | |
1802 DEFUN ("window-pixel-edges", Fwindow_pixel_edges, 0, 1, 0, /* | |
1803 Return a list of the pixel edge coordinates of WINDOW. | |
444 | 1804 The returned list is of the form (LEFT TOP RIGHT BOTTOM), |
1805 all relative to 0, 0 at the top left corner of WINDOW's frame. | |
1806 The frame toolbars, menubars and gutters are considered to be outside | |
1807 of this area, while the scrollbars are considered to be inside. | |
428 | 1808 */ |
1809 (window)) | |
1810 { | |
1811 struct window *w = decode_window (window); | |
1812 struct frame *f = XFRAME (w->frame); | |
1813 | |
5090 | 1814 int left = w->pixel_left - FRAME_PANED_LEFT_EDGE (f); |
1815 int top = w->pixel_top - FRAME_PANED_TOP_EDGE (f); | |
428 | 1816 |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1817 return list4 (make_fixnum (left), |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1818 make_fixnum (top), |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1819 make_fixnum (left + w->pixel_width), |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1820 make_fixnum (top + w->pixel_height)); |
428 | 1821 } |
1822 | |
1823 DEFUN ("window-text-area-pixel-edges", | |
1824 Fwindow_text_area_pixel_edges, 0, 1, 0, /* | |
1825 Return a list of the pixel edge coordinates of the text area of WINDOW. | |
444 | 1826 The returned list is of the form (LEFT TOP RIGHT BOTTOM), |
1827 all relative to 0, 0 at the top left corner of the total area allocated | |
1828 to the window, which includes the scrollbars. | |
428 | 1829 */ |
1830 (window)) | |
1831 { | |
1832 struct window *w = decode_window (window); | |
1833 | |
1834 int left = window_left_gutter_width (w, /* modeline = */ 0); | |
1835 int top = window_top_gutter_height (w); | |
1836 int right = WINDOW_WIDTH (w) - window_right_gutter_width (w, 0); | |
1837 int bottom = WINDOW_HEIGHT (w) - window_bottom_gutter_height (w); | |
1838 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1839 return list4 (make_fixnum (left), |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1840 make_fixnum (top), |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1841 make_fixnum (right), |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1842 make_fixnum (bottom)); |
428 | 1843 } |
1844 | |
1845 DEFUN ("window-point", Fwindow_point, 0, 1, 0, /* | |
1846 Return current value of point in WINDOW. | |
442 | 1847 For a non-selected window, this is the value point would have |
428 | 1848 if that window were selected. |
1849 | |
1850 Note that, when WINDOW is the selected window and its buffer | |
1851 is also currently selected, the value returned is the same as (point). | |
1852 It would be more strictly correct to return the `top-level' value | |
1853 of point, outside of any save-excursion forms. | |
444 | 1854 But that value is hard to find. |
428 | 1855 */ |
1856 (window)) | |
1857 { | |
1858 struct window *w = decode_window (window); | |
1859 | |
1860 /* The special check for current buffer is necessary for this | |
1861 function to work as defined when called within an excursion. */ | |
1862 if (w == XWINDOW (Fselected_window (XFRAME (w->frame)->device)) | |
1863 && current_buffer == XBUFFER (w->buffer)) | |
1864 return Fpoint (Qnil); | |
1865 return Fmarker_position (w->pointm[CURRENT_DISP]); | |
1866 } | |
1867 | |
1868 DEFUN ("window-start", Fwindow_start, 0, 1, 0, /* | |
1869 Return position at which display currently starts in WINDOW. | |
1870 This is updated by redisplay or by calling `set-window-start'. | |
1871 */ | |
1872 (window)) | |
1873 { | |
1874 return Fmarker_position (decode_window (window)->start[CURRENT_DISP]); | |
1875 } | |
1876 | |
1877 DEFUN ("window-end", Fwindow_end, 0, 2, 0, /* | |
1878 Return position at which display currently ends in WINDOW. | |
1879 This is updated by redisplay, when it runs to completion. | |
444 | 1880 Simply changing the buffer text or setting `window-start' does not |
1881 update this value. WINDOW defaults to the selected window. | |
1882 | |
1883 If optional arg GUARANTEE is non-nil, the return value is guaranteed | |
1884 to be the same value as this function would return at the end of the | |
1885 next full redisplay assuming nothing else changes in the meantime. | |
1886 This function is potentially much slower with this flag set. | |
428 | 1887 */ |
1888 (window, guarantee)) | |
1889 { | |
1890 struct window *w = decode_window (window); | |
1891 | |
1892 if (NILP (guarantee)) | |
1893 { | |
1894 Lisp_Object buf; | |
1895 buf = w->buffer; | |
1896 CHECK_BUFFER (buf); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1897 return make_fixnum (BUF_Z (XBUFFER (buf)) - w->window_end_pos[CURRENT_DISP]); |
428 | 1898 } |
1899 else | |
1900 { | |
665 | 1901 Charbpos startp = marker_position (w->start[CURRENT_DISP]); |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1902 return make_fixnum (end_of_last_line (w, startp)); |
428 | 1903 } |
1904 } | |
1905 | |
442 | 1906 DEFUN ("window-last-line-visible-height", Fwindow_last_line_visible_height, 0, 1, 0, /* |
1907 Return pixel height of visible part of last window line if it is clipped. | |
1908 If the last line is not clipped, return nil. | |
1909 */ | |
1910 (window)) | |
1911 { | |
1912 struct window *w = decode_window (window); | |
1913 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP); | |
1914 int num_lines = Dynarr_length (dla); | |
1915 struct display_line *dl; | |
1916 | |
1917 /* No lines - no clipped lines */ | |
4967 | 1918 if (num_lines == 0 || (num_lines == 1 && Dynarr_begin (dla)->modeline)) |
442 | 1919 return Qnil; |
1920 | |
1921 dl = Dynarr_atp (dla, num_lines - 1); | |
1922 if (dl->clip == 0) | |
1923 return Qnil; | |
1924 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1925 return make_fixnum (dl->ascent + dl->descent - dl->clip); |
442 | 1926 } |
1927 | |
428 | 1928 DEFUN ("set-window-point", Fset_window_point, 2, 2, 0, /* |
1929 Make point value in WINDOW be at position POS in WINDOW's buffer. | |
1161 | 1930 If WINDOW is the selected window, and window's buffer is the current |
1931 buffer, this actually changes the buffer's point instead of the window's | |
1932 point. (The equivalence of the selected window's point with its buffer's | |
1933 point is maintained throughout XEmacs. However, enforcing the additional | |
1934 restriction on the current buffer is "bug compatible" with FSF and is | |
1935 perhaps more logical.) | |
428 | 1936 */ |
1937 (window, pos)) | |
1938 { | |
1939 struct window *w = decode_window (window); | |
1940 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1941 CHECK_FIXNUM_COERCE_MARKER (pos); |
1161 | 1942 |
844 | 1943 /* Don't dereference selected-window because there may not |
1944 be one -- e.g. at startup */ | |
1161 | 1945 if (EQ (wrap_window (w), Fselected_window (Qnil)) |
1946 && EQ (w->buffer, Fcurrent_buffer ())) | |
1947 Fgoto_char (pos, Qnil); | |
428 | 1948 else |
1949 set_marker_restricted (w->pointm[CURRENT_DISP], pos, w->buffer); | |
1950 | |
1951 MARK_POINT_CHANGED; | |
1952 return pos; | |
1953 } | |
1954 | |
1955 DEFUN ("set-window-start", Fset_window_start, 2, 3, 0, /* | |
1956 Make display in WINDOW start at position POS in WINDOW's buffer. | |
1957 Optional third arg NOFORCE non-nil inhibits next redisplay | |
1958 from overriding motion of point in order to display at this exact start. | |
1959 */ | |
1960 (window, pos, noforce)) | |
1961 { | |
1962 struct window *w = decode_window (window); | |
1963 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
1964 CHECK_FIXNUM_COERCE_MARKER (pos); |
428 | 1965 set_marker_restricted (w->start[CURRENT_DISP], pos, w->buffer); |
1966 /* this is not right, but much easier than doing what is right. */ | |
1967 /* w->start_at_line_beg = 0; */ | |
1968 /* WTF is the above supposed to mean? GE */ | |
1969 w->start_at_line_beg = beginning_of_line_p (XBUFFER (w->buffer), | |
1970 marker_position (w->start[CURRENT_DISP])); | |
1971 if (NILP (noforce)) | |
1972 w->force_start = 1; | |
1973 w->redo_modeline = 1; | |
1974 SET_LAST_MODIFIED (w, 0); | |
1975 SET_LAST_FACECHANGE (w); | |
1976 | |
1977 MARK_WINDOWS_CHANGED (w); | |
1978 | |
1979 return pos; | |
1980 } | |
1981 | |
1982 DEFUN ("window-dedicated-p", Fwindow_dedicated_p, 1, 1, 0, /* | |
1983 Return WINDOW's dedicated object, usually t or nil. | |
1984 See also `set-window-dedicated-p'. | |
1985 */ | |
1986 (window)) | |
1987 { | |
1988 return decode_window (window)->dedicated; | |
1989 } | |
1990 | |
1991 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p, 2, 2, 0, /* | |
1992 Control whether WINDOW is dedicated to the buffer it displays. | |
1993 If it is dedicated, Emacs will not automatically change | |
1994 which buffer appears in it. | |
1995 The second argument is the new value for the dedication flag; | |
1996 non-nil means yes. | |
1997 */ | |
1998 (window, arg)) | |
1999 { | |
2000 struct window *w = decode_window (window); | |
2001 | |
2002 w->dedicated = NILP (arg) ? Qnil : Qt; | |
2003 | |
2004 return w->dedicated; | |
2005 } | |
2006 | |
2007 /* FSFmacs has window-display-table here. We have display table as a | |
2008 specifier. */ | |
2009 | |
2010 | |
2011 /* Record info on buffer window w is displaying | |
2012 when it is about to cease to display that buffer. */ | |
2013 static void | |
2014 unshow_buffer (struct window *w) | |
2015 { | |
2016 Lisp_Object buf = w->buffer; | |
844 | 2017 struct buffer *b = XBUFFER (buf); |
2018 | |
5050
6f2158fa75ed
Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
2019 assert (b == XMARKER (w->pointm[CURRENT_DISP])->buffer); |
428 | 2020 |
2021 /* FSF disables this check, so I'll do it too. I hope it won't | |
2022 break things. --ben */ | |
2023 #if 0 | |
2024 if (w == XWINDOW (Fselected_window (Qnil)) | |
2025 || ! EQ (buf, XWINDOW (Fselected_window (Qnil))->buffer)) | |
2026 /* Do this except when the selected window's buffer | |
2027 is being removed from some other window. */ | |
2028 #endif | |
2029 /* last_window_start records the start position that this buffer | |
2030 had in the last window to be disconnected from it. | |
2031 Now that this statement is unconditional, | |
2032 it is possible for the buffer to be displayed in the | |
2033 selected window, while last_window_start reflects another | |
2034 window which was recently showing the same buffer. | |
2035 Some people might say that might be a good thing. Let's see. */ | |
2036 XBUFFER (buf)->last_window_start = | |
2037 marker_position (w->start[CURRENT_DISP]); | |
2038 | |
2039 /* Point in the selected window's buffer | |
2040 is actually stored in that buffer, and the window's pointm isn't used. | |
2041 So don't clobber point in that buffer. */ | |
2042 if (! EQ (buf, XWINDOW (Fselected_window (Qnil))->buffer)) | |
844 | 2043 BUF_SET_PT (b, |
2044 charbpos_clip_to_bounds | |
2045 (BUF_BEGV (b), | |
2046 marker_position (w->pointm[CURRENT_DISP]), | |
2047 BUF_ZV (b))); | |
2048 | |
2049 { | |
2050 Lisp_Object marker = Fgethash (buf, w->saved_point_cache, Qnil); | |
2051 int selected = EQ (wrap_window (w), Fselected_window (Qnil)); | |
2052 | |
2053 if (NILP (marker)) | |
2054 { | |
2055 marker = Fmake_marker (); | |
2056 Fputhash (buf, marker, w->saved_point_cache); | |
2057 } | |
2058 Fset_marker (marker, | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2059 selected ? make_fixnum (BUF_PT (b)) : w->pointm[CURRENT_DISP], |
844 | 2060 buf); |
2061 | |
2062 marker = Fgethash (buf, w->saved_last_window_start_cache, Qnil); | |
2063 | |
2064 if (NILP (marker)) | |
2065 { | |
2066 marker = Fmake_marker (); | |
2067 Fputhash (buf, marker, w->saved_last_window_start_cache); | |
2068 } | |
2069 Fset_marker (marker, w->start[CURRENT_DISP], buf); | |
2070 } | |
428 | 2071 } |
2072 | |
2073 /* Put REPLACEMENT into the window structure in place of OLD. */ | |
2074 static void | |
2075 replace_window (Lisp_Object old, Lisp_Object replacement) | |
2076 { | |
2077 Lisp_Object tem; | |
2078 struct window *o = XWINDOW (old), *p = XWINDOW (replacement); | |
2079 | |
2080 /* If OLD is its frame's root_window, then replacement is the new | |
2081 root_window for that frame. */ | |
2082 | |
2083 if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame)))) | |
2084 FRAME_ROOT_WINDOW (XFRAME (o->frame)) = replacement; | |
2085 | |
2086 WINDOW_LEFT (p) = WINDOW_LEFT (o); | |
2087 WINDOW_TOP (p) = WINDOW_TOP (o); | |
2088 WINDOW_WIDTH (p) = WINDOW_WIDTH (o); | |
2089 WINDOW_HEIGHT (p) = WINDOW_HEIGHT (o); | |
2090 | |
2091 p->next = tem = o->next; | |
2092 if (!NILP (tem)) | |
2093 XWINDOW (tem)->prev = replacement; | |
2094 | |
2095 p->prev = tem = o->prev; | |
2096 if (!NILP (tem)) | |
2097 XWINDOW (tem)->next = replacement; | |
2098 | |
2099 p->parent = tem = o->parent; | |
2100 if (!NILP (tem)) | |
2101 { | |
2102 if (EQ (XWINDOW (tem)->vchild, old)) | |
2103 XWINDOW (tem)->vchild = replacement; | |
2104 if (EQ (XWINDOW (tem)->hchild, old)) | |
2105 XWINDOW (tem)->hchild = replacement; | |
2106 } | |
2107 | |
2108 /* #### Here, if replacement is a vertical combination | |
2109 and so is its new parent, we should make replacement's | |
2110 children be children of that parent instead. */ | |
442 | 2111 |
2112 ERROR_CHECK_SUBWINDOW_CACHE (p); | |
2113 } | |
2114 | |
2115 static void | |
2116 window_unmap_subwindows (struct window* w) | |
2117 { | |
2118 assert (!NILP (w->subwindow_instance_cache)); | |
2119 elisp_maphash (unmap_subwindow_instance_cache_mapper, | |
2120 w->subwindow_instance_cache, (void*)1); | |
428 | 2121 } |
2122 | |
2123 /* we're deleting W; set the structure of W to indicate this. */ | |
2124 | |
2125 static void | |
2126 mark_window_as_deleted (struct window *w) | |
2127 { | |
442 | 2128 /* The window instance cache is going away now, so need to get the |
2129 cachels reset by redisplay. */ | |
2130 MARK_FRAME_SUBWINDOWS_CHANGED (XFRAME (WINDOW_FRAME (w))); | |
2131 | |
2132 /* The cache is going away. If we leave unmapping to | |
2133 reset_subwindow_cachels then we get in a situation where the | |
2134 domain (the window) has been deleted but we still need access to | |
2135 its attributes in order to unmap windows properly. Since the | |
2136 subwindows are going to get GC'd anyway as a result of the domain | |
2137 going away, it is safer to just unmap them all while we know the | |
2138 domain is still valid. */ | |
2139 ERROR_CHECK_SUBWINDOW_CACHE (w); | |
2140 window_unmap_subwindows (w); | |
2141 | |
617 | 2142 /* Free the extra data structures attached to windows immediately so |
2143 they don't sit around consuming excess space. They will be | |
2144 reinitialized by the window-configuration code as necessary. */ | |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5126
diff
changeset
|
2145 finalize_window (wrap_window (w)); |
617 | 2146 |
1149 | 2147 /* Nobody should be accessing anything in this object any more, |
618 | 2148 and making them Qnil allows for better GC'ing in case a pointer |
2149 to the dead window continues to hang around. Zero all other | |
2150 structs in case someone tries to access something through them. | |
2151 | |
2152 (So, in point of fact, we zero out all of the "saved" slots, | |
2153 which are obviously restored from the window config, plus the | |
2154 slots which were already zeroed.) | |
617 | 2155 |
2156 As an example of why setting the values to Qnil is good, here | |
2157 is an old comment: | |
2158 | |
2159 In the loop | |
428 | 2160 (while t (split-window) (delete-window)) |
2161 we end up with a tree of deleted windows which are all connected | |
2162 through the `next' slot. This might not seem so bad, as they're | |
2163 deleted, and will presumably be GCed - but if even *one* of those | |
2164 windows is still being pointed to, by the user, or by a window | |
1149 | 2165 configuration, then *all* of those windows stick around. */ |
617 | 2166 |
618 | 2167 #define WINDOW_SLOT(slot) |
2168 #define WINDOW_SAVED_SLOT(slot, compare) w->slot = Qnil; | |
617 | 2169 #include "winslots.h" |
428 | 2170 |
618 | 2171 w->next = Qnil; |
2172 w->prev = Qnil; | |
2173 w->hchild = Qnil; | |
2174 w->vchild = Qnil; | |
2175 w->parent = Qnil; | |
2176 w->subwindow_instance_cache = Qnil; | |
2177 | |
428 | 2178 w->dead = 1; |
853 | 2179 note_object_deleted (wrap_window (w)); |
428 | 2180 } |
2181 | |
1207 | 2182 /* Check if window contains pwindow. */ |
2183 | |
2184 static int | |
2185 contains_window (Lisp_Object window, Lisp_Object pwindow) | |
2186 { | |
2187 while (!NILP (pwindow)) | |
2188 { | |
2189 if (EQ (window, pwindow)) | |
2190 return 1; | |
2191 pwindow = XWINDOW (pwindow)->parent; | |
2192 } | |
2193 return 0; | |
2194 } | |
2195 | |
428 | 2196 DEFUN ("delete-window", Fdelete_window, 0, 2, "", /* |
2197 Remove WINDOW from the display. Default is selected window. | |
444 | 2198 If window is the only one on its frame, the frame is deleted as well. |
428 | 2199 Normally, you cannot delete the last non-minibuffer-only frame (you must |
2200 use `save-buffers-kill-emacs' or `kill-emacs'). However, if optional | |
2201 second argument FORCE is non-nil, you can delete the last frame. (This | |
2202 will automatically call `save-buffers-kill-emacs'.) | |
2203 */ | |
2204 (window, force)) | |
2205 { | |
2206 /* This function can GC if this is the only window in the frame */ | |
2207 struct window *w; | |
2208 Lisp_Object parent; | |
2209 struct window *par; | |
2210 Lisp_Object frame; | |
2211 struct frame *f; | |
2212 struct device *d; | |
2213 | |
2214 /* Note: this function is called by other C code on non-leaf | |
2215 windows. */ | |
2216 | |
2217 /* Do the equivalent of decode_window() but don't error out on | |
2218 deleted window; it's OK to delete an already-deleted window. */ | |
2219 if (NILP (window)) | |
2220 window = Fselected_window (Qnil); | |
2221 else | |
2222 CHECK_WINDOW (window); | |
442 | 2223 |
428 | 2224 w = XWINDOW (window); |
2225 | |
2226 /* It's okay to delete an already-deleted window. */ | |
2227 if (! WINDOW_LIVE_P (w)) | |
2228 return Qnil; | |
2229 | |
853 | 2230 check_allowed_operation (OPERATION_DELETE_OBJECT, window, Qnil); |
2231 | |
428 | 2232 frame = WINDOW_FRAME (w); |
2233 f = XFRAME (frame); | |
2234 d = XDEVICE (FRAME_DEVICE (f)); | |
2235 | |
2236 if (TOP_LEVEL_WINDOW_P (w)) | |
2237 { | |
2238 if (NILP (memq_no_quit (frame, DEVICE_FRAME_LIST (d)))) | |
2239 /* this frame isn't fully initialized yet; don't blow up. */ | |
2240 return Qnil; | |
2241 | |
2242 if (MINI_WINDOW_P (XWINDOW (window))) | |
563 | 2243 signal_error (Qinvalid_operation, "Attempt to delete the minibuffer window", Qunbound); |
428 | 2244 |
2245 /* It has been suggested that it's a good thing for C-x 0 to have this | |
2246 behavior, but not such a good idea for #'delete-window to have it. | |
2247 Maybe C-x 0 should be bound to something else, or maybe frame | |
2248 deletion should only happen when this is called interactively. | |
2249 */ | |
2250 delete_frame_internal (f, !NILP (force), 0, 0); | |
2251 return Qnil; | |
2252 } | |
2253 | |
2254 /* At this point, we know the window has a parent. */ | |
2255 parent = w->parent; | |
2256 par = XWINDOW (parent); | |
2257 | |
2258 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f); | |
430 | 2259 /* It's quite likely that deleting a window will result in |
2260 subwindows needing to be deleted also (since they are cached | |
2261 per-window). So we mark them as changed, so that the cachels will | |
2262 get reset by redisplay and thus deleted subwindows can get | |
2263 GC'd. */ | |
2264 MARK_FRAME_SUBWINDOWS_CHANGED (f); | |
428 | 2265 |
2266 /* Are we trying to delete any frame's selected window? | |
2267 Note that we could be dealing with a non-leaf window | |
2268 where the selected window is one of our children. | |
2269 So, we check by scanning all the ancestors of the | |
2270 frame's selected window and comparing each one with | |
2271 WINDOW. */ | |
1207 | 2272 if (contains_window (window, FRAME_SELECTED_WINDOW (f))) |
2273 { | |
2274 Lisp_Object alternative; | |
2275 alternative = Fnext_window (window, Qlambda, Qnil, Qnil); | |
2276 | |
2277 /* #### */ | |
2278 /* If we're about to delete the selected window on the | |
2279 selected frame, then we should use Fselect_window to select | |
2280 the new window. On the other hand, if we're about to | |
2281 delete the selected window on any other frame, we shouldn't do | |
2282 anything but set the frame's selected_window slot. */ | |
2283 if (EQ (frame, Fselected_frame (Qnil))) | |
2284 Fselect_window (alternative, Qnil); | |
2285 else | |
2286 set_frame_selected_window (f, alternative); | |
2287 } | |
2288 | |
2289 /* Some display parameters (gutter display specifically) depend on | |
2290 FRAME_LAST_NONMINIBUF (f) to be set to a live window. Ensure that. */ | |
2291 if (contains_window (window, FRAME_LAST_NONMINIBUF_WINDOW (f))) | |
2292 f->last_nonminibuf_window = Fnext_window (window, Qlambda, Qnil, Qnil); | |
428 | 2293 |
2294 /* w->buffer is nil in a non-leaf window; in this case, | |
2295 get rid of the markers we maintain that point into that buffer. */ | |
2296 if (!NILP (w->buffer)) | |
2297 { | |
2298 unshow_buffer (w); | |
2299 unchain_marker (w->pointm[CURRENT_DISP]); | |
2300 unchain_marker (w->pointm[DESIRED_DISP]); | |
2301 unchain_marker (w->pointm[CMOTION_DISP]); | |
2302 unchain_marker (w->start[CURRENT_DISP]); | |
2303 unchain_marker (w->start[DESIRED_DISP]); | |
2304 unchain_marker (w->start[CMOTION_DISP]); | |
2305 unchain_marker (w->sb_point); | |
1149 | 2306 w->buffer = Qnil; |
428 | 2307 } |
2308 | |
2309 /* close up the hole in the sibling list */ | |
2310 if (!NILP (w->next)) | |
2311 XWINDOW (w->next)->prev = w->prev; | |
2312 if (!NILP (w->prev)) | |
2313 XWINDOW (w->prev)->next = w->next; | |
2314 if (EQ (window, par->hchild)) | |
2315 par->hchild = w->next; | |
2316 if (EQ (window, par->vchild)) | |
2317 par->vchild = w->next; | |
2318 | |
2319 /* Find one of our siblings to give our space to. */ | |
2320 { | |
2321 Lisp_Object sib = w->prev; | |
2322 if (NILP (sib)) | |
2323 { | |
2324 /* If w gives its space to its next sibling, that sibling needs | |
2325 to have its top/left side pulled back to where w's is. | |
2326 set_window_{height,width} will re-position the sibling's | |
2327 children. */ | |
2328 sib = w->next; | |
2329 WINDOW_TOP (XWINDOW (sib)) = WINDOW_TOP (w); | |
2330 WINDOW_LEFT (XWINDOW (sib)) = WINDOW_LEFT (w); | |
2331 } | |
2332 | |
2333 /* Stretch that sibling. */ | |
2334 if (!NILP (par->vchild)) | |
2335 set_window_pixheight | |
2336 (sib, (WINDOW_HEIGHT (XWINDOW (sib)) + WINDOW_HEIGHT (w)), 1); | |
2337 if (!NILP (par->hchild)) | |
2338 set_window_pixwidth | |
2339 (sib, (WINDOW_WIDTH (XWINDOW (sib)) + WINDOW_WIDTH (w)), 1); | |
2340 } | |
2341 | |
2342 /* If parent now has only one child, | |
2343 put the child into the parent's place. */ | |
2344 { | |
2345 Lisp_Object parchild = par->hchild; | |
2346 if (NILP (parchild)) | |
2347 parchild = par->vchild; | |
2348 if (NILP (XWINDOW (parchild)->next)) | |
2349 { | |
2350 replace_window (parent, parchild); | |
2351 mark_window_as_deleted (XWINDOW (parent)); | |
2352 } | |
2353 } | |
2354 | |
2355 /* Since we may be deleting combination windows, we must make sure that | |
2356 not only W but all its children have been marked as deleted. */ | |
2357 if (!NILP (w->hchild)) | |
2358 delete_all_subwindows (XWINDOW (w->hchild)); | |
2359 else if (!NILP (w->vchild)) | |
2360 delete_all_subwindows (XWINDOW (w->vchild)); | |
2361 | |
1752 | 2362 /* Warning: mark_window_as_deleted calls window_unmap_subwindows and |
2363 therefore redisplay, so it requires the mirror structure to be | |
2364 correct. We must dirty the mirror before it is called. */ | |
2365 f->mirror_dirty = 1; | |
2366 | |
428 | 2367 mark_window_as_deleted (w); |
2368 | |
2369 return Qnil; | |
2370 } | |
2371 | |
2372 | |
2373 DEFUN ("next-window", Fnext_window, 0, 4, 0, /* | |
442 | 2374 Return the next window after WINDOW in the canonical ordering of windows. |
428 | 2375 If omitted, WINDOW defaults to the selected window. |
2376 | |
2377 Optional second arg MINIBUF t means count the minibuffer window even | |
2378 if not active. MINIBUF nil or omitted means count the minibuffer iff | |
2379 it is active. MINIBUF neither t nor nil means not to count the | |
2380 minibuffer even if it is active. | |
2381 | |
2382 Several frames may share a single minibuffer; if the minibuffer | |
2383 counts, all windows on all frames that share that minibuffer count | |
2384 too. Therefore, `next-window' can be used to iterate through the | |
2385 set of windows even when the minibuffer is on another frame. If the | |
2386 minibuffer does not count, only windows from WINDOW's frame count. | |
2387 | |
444 | 2388 By default, only the windows in the selected frame are considered. |
2389 The optional argument WHICH-FRAMES changes this behavior: | |
2390 WHICH-FRAMES = `visible' means search windows on all visible frames. | |
448 | 2391 WHICH-FRAMES = 0 means search windows on all visible and iconified frames. |
444 | 2392 WHICH-FRAMES = t means search windows on all frames including invisible frames. |
2393 WHICH-FRAMES = a frame means search only windows on that frame. | |
2394 Anything else means restrict to the selected frame. | |
2395 | |
2396 The optional fourth argument WHICH-DEVICES further clarifies on which | |
2397 devices to search for frames as specified by WHICH-FRAMES. This value | |
2398 is only meaningful if WHICH-FRAMES is non-nil. | |
2399 If nil or omitted, search all devices on the selected console. | |
2400 If a device, only search that device. | |
2401 If a console, search all devices on that console. | |
2402 If a device type, search all devices of that type. | |
2403 If `window-system', search all window-system devices. | |
2404 Any other non-nil value means search all devices. | |
2405 | |
2406 If you use consistent values for MINIBUF, WHICH-FRAMES, and WHICH-DEVICES, | |
2407 you can use `next-window' to iterate through the entire cycle of | |
2408 acceptable windows, eventually ending up back at the window you started with. | |
428 | 2409 `previous-window' traverses the same cycle, in the reverse order. |
2410 */ | |
444 | 2411 (window, minibuf, which_frames, which_devices)) |
428 | 2412 { |
2413 Lisp_Object tem; | |
2414 Lisp_Object start_window; | |
2415 | |
2416 if (NILP (window)) | |
2417 window = Fselected_window (Qnil); | |
2418 else | |
2419 CHECK_LIVE_WINDOW (window); | |
2420 | |
2421 start_window = window; | |
2422 | |
2423 /* minibuf == nil may or may not include minibuffers. | |
2424 Decide if it does. */ | |
2425 if (NILP (minibuf)) | |
2426 minibuf = (minibuf_level ? minibuf_window : Qlambda); | |
2427 else if (! EQ (minibuf, Qt)) | |
2428 minibuf = Qlambda; | |
442 | 2429 /* Now `minibuf' is one of: |
2430 t => count all minibuffer windows | |
2431 lambda => count none of them | |
428 | 2432 or a specific minibuffer window (the active one) to count. */ |
2433 | |
444 | 2434 /* which_frames == nil doesn't specify which frames to include. */ |
2435 if (NILP (which_frames)) | |
2436 which_frames = (! EQ (minibuf, Qlambda) | |
428 | 2437 ? (FRAME_MINIBUF_WINDOW |
2438 (XFRAME | |
2439 (WINDOW_FRAME | |
2440 (XWINDOW (window))))) | |
2441 : Qnil); | |
444 | 2442 else if (EQ (which_frames, Qvisible)) |
428 | 2443 ; |
444 | 2444 else if (ZEROP (which_frames)) |
428 | 2445 ; |
444 | 2446 else if (FRAMEP (which_frames) && ! EQ (which_frames, Fwindow_frame (window))) |
2447 /* If which_frames is a frame and window arg isn't on that frame, just | |
428 | 2448 return the first window on the frame. */ |
444 | 2449 return frame_first_window (XFRAME (which_frames)); |
2450 else if (! EQ (which_frames, Qt)) | |
2451 which_frames = Qnil; | |
2452 /* Now `which_frames' is one of: | |
442 | 2453 t => search all frames |
2454 nil => search just the current frame | |
2455 visible => search just visible frames | |
2456 0 => search visible and iconified frames | |
2457 a window => search the frame that window belongs to. */ | |
428 | 2458 |
2459 /* Do this loop at least once, to get the next window, and perhaps | |
2460 again, if we hit the minibuffer and that is not acceptable. */ | |
2461 do | |
2462 { | |
2463 /* Find a window that actually has a next one. This loop | |
2464 climbs up the tree. */ | |
2465 while (tem = XWINDOW (window)->next, NILP (tem)) | |
2466 if (tem = XWINDOW (window)->parent, !NILP (tem)) | |
2467 window = tem; | |
2468 else /* window must be minibuffer window now */ | |
2469 { | |
2470 /* We've reached the end of this frame. | |
2471 Which other frames are acceptable? */ | |
2472 tem = WINDOW_FRAME (XWINDOW (window)); | |
2473 | |
444 | 2474 if (! NILP (which_frames)) |
428 | 2475 { |
442 | 2476 Lisp_Object tem1 = tem; |
444 | 2477 tem = next_frame (tem, which_frames, which_devices); |
442 | 2478 |
428 | 2479 /* In the case where the minibuffer is active, |
2480 and we include its frame as well as the selected one, | |
2481 next_frame may get stuck in that frame. | |
2482 If that happens, go back to the selected frame | |
2483 so we can complete the cycle. */ | |
2484 if (EQ (tem, tem1)) | |
793 | 2485 tem = wrap_frame (selected_frame ()); |
428 | 2486 } |
2487 | |
2488 tem = FRAME_ROOT_WINDOW (XFRAME (tem)); | |
2489 break; | |
2490 } | |
2491 | |
2492 window = tem; | |
2493 | |
2494 /* If we're in a combination window, find its first child and | |
2495 recurse on that. Otherwise, we've found the window we want. */ | |
2496 while (1) | |
2497 { | |
2498 if (!NILP (XWINDOW (window)->hchild)) | |
2499 window = XWINDOW (window)->hchild; | |
2500 else if (!NILP (XWINDOW (window)->vchild)) | |
2501 window = XWINDOW (window)->vchild; | |
2502 else break; | |
2503 } | |
2504 } | |
2505 /* Which windows are acceptable? | |
2506 Exit the loop and accept this window if | |
2507 this isn't a minibuffer window, | |
2508 or we're accepting all minibuffer windows, | |
2509 or this is the active minibuffer and we are accepting that one, or | |
2510 we've come all the way around and we're back at the original window. */ | |
2511 while (MINI_WINDOW_P (XWINDOW (window)) | |
2512 && ! EQ (minibuf, Qt) | |
2513 && ! EQ (minibuf, window) | |
2514 && ! EQ (window, start_window)); | |
2515 | |
2516 return window; | |
2517 } | |
2518 | |
2519 DEFUN ("previous-window", Fprevious_window, 0, 4, 0, /* | |
442 | 2520 Return the window preceding WINDOW in the canonical ordering of windows. |
428 | 2521 If omitted, WINDOW defaults to the selected window. |
2522 | |
2523 Optional second arg MINIBUF t means count the minibuffer window even | |
2524 if not active. MINIBUF nil or omitted means count the minibuffer iff | |
2525 it is active. MINIBUF neither t nor nil means not to count the | |
2526 minibuffer even if it is active. | |
2527 | |
2528 Several frames may share a single minibuffer; if the minibuffer | |
2529 counts, all windows on all frames that share that minibuffer count | |
2530 too. Therefore, `previous-window' can be used to iterate through | |
2531 the set of windows even when the minibuffer is on another frame. If | |
442 | 2532 the minibuffer does not count, only windows from WINDOW's frame count. |
2533 | |
444 | 2534 By default, only the windows in the selected frame are considered. |
2535 The optional argument WHICH-FRAMES changes this behavior: | |
2536 WHICH-FRAMES = `visible' means search windows on all visible frames. | |
448 | 2537 WHICH-FRAMES = 0 means search windows on all visible and iconified frames. |
444 | 2538 WHICH-FRAMES = t means search windows on all frames including invisible frames. |
2539 WHICH-FRAMES = a frame means search only windows on that frame. | |
2540 Anything else means restrict to the selected frame. | |
2541 | |
2542 The optional fourth argument WHICH-DEVICES further clarifies on which | |
2543 devices to search for frames as specified by WHICH-FRAMES. This value | |
2544 is only meaningful if WHICH-FRAMES is non-nil. | |
2545 If nil or omitted, search all devices on the selected console. | |
2546 If a device, only search that device. | |
2547 If a console, search all devices on that console. | |
2548 If a device type, search all devices of that type. | |
2549 If `window-system', search all window-system devices. | |
2550 Any other non-nil value means search all devices. | |
2551 | |
2552 If you use consistent values for MINIBUF, WHICH-FRAMES, and WHICH-DEVICES, | |
2553 you can use `previous-window' to iterate through the entire cycle of | |
2554 acceptable windows, eventually ending up back at the window you started with. | |
428 | 2555 `next-window' traverses the same cycle, in the reverse order. |
2556 */ | |
444 | 2557 (window, minibuf, which_frames, devices)) |
428 | 2558 { |
2559 Lisp_Object tem; | |
2560 Lisp_Object start_window; | |
2561 | |
2562 if (NILP (window)) | |
2563 window = Fselected_window (Qnil); | |
2564 else | |
2565 CHECK_LIVE_WINDOW (window); | |
2566 | |
2567 start_window = window; | |
2568 | |
2569 /* minibuf == nil may or may not include minibuffers. | |
2570 Decide if it does. */ | |
2571 if (NILP (minibuf)) | |
2572 minibuf = (minibuf_level ? minibuf_window : Qlambda); | |
2573 else if (! EQ (minibuf, Qt)) | |
2574 minibuf = Qlambda; | |
442 | 2575 /* Now `minibuf' is one of: |
2576 t => count all minibuffer windows | |
2577 lambda => count none of them | |
428 | 2578 or a specific minibuffer window (the active one) to count. */ |
2579 | |
444 | 2580 /* which_frames == nil doesn't specify which frames to include. |
428 | 2581 Decide which frames it includes. */ |
444 | 2582 if (NILP (which_frames)) |
2583 which_frames = (! EQ (minibuf, Qlambda) | |
428 | 2584 ? (FRAME_MINIBUF_WINDOW |
2585 (XFRAME | |
2586 (WINDOW_FRAME | |
2587 (XWINDOW (window))))) | |
2588 : Qnil); | |
444 | 2589 else if (EQ (which_frames, Qvisible)) |
428 | 2590 ; |
444 | 2591 else if (ZEROP (which_frames)) |
428 | 2592 ; |
444 | 2593 else if (FRAMEP (which_frames) && ! EQ (which_frames, Fwindow_frame (window))) |
2594 /* If which_frames is a frame and window arg isn't on that frame, just | |
428 | 2595 return the first window on the frame. */ |
444 | 2596 return frame_first_window (XFRAME (which_frames)); |
2597 else if (! EQ (which_frames, Qt)) | |
2598 which_frames = Qnil; | |
2599 /* Now `which_frames' is one of: | |
442 | 2600 t => search all frames |
2601 nil => search just the current frame | |
2602 visible => search just visible frames | |
2603 0 => search visible and iconified frames | |
2604 a window => search the frame that window belongs to. */ | |
428 | 2605 |
2606 /* Do this loop at least once, to get the next window, and perhaps | |
2607 again, if we hit the minibuffer and that is not acceptable. */ | |
2608 do | |
2609 { | |
2610 /* Find a window that actually has a next one. This loop | |
2611 climbs up the tree. */ | |
2612 while (tem = XWINDOW (window)->prev, NILP (tem)) | |
2613 if (tem = XWINDOW (window)->parent, !NILP (tem)) | |
2614 window = tem; | |
2615 else /* window must be minibuffer window now */ | |
2616 { | |
2617 /* We have found the top window on the frame. | |
2618 Which frames are acceptable? */ | |
2619 tem = WINDOW_FRAME (XWINDOW (window)); | |
2620 | |
444 | 2621 if (! NILP (which_frames)) |
442 | 2622 /* It's actually important that we use previous_frame here, |
428 | 2623 rather than next_frame. All the windows acceptable |
2624 according to the given parameters should form a ring; | |
2625 Fnext_window and Fprevious_window should go back and | |
2626 forth around the ring. If we use next_frame here, | |
2627 then Fnext_window and Fprevious_window take different | |
2628 paths through the set of acceptable windows. | |
2629 window_loop assumes that these `ring' requirement are | |
2630 met. */ | |
2631 { | |
442 | 2632 Lisp_Object tem1 = tem; |
444 | 2633 tem = previous_frame (tem, which_frames, devices); |
428 | 2634 /* In the case where the minibuffer is active, |
2635 and we include its frame as well as the selected one, | |
2636 next_frame may get stuck in that frame. | |
2637 If that happens, go back to the selected frame | |
2638 so we can complete the cycle. */ | |
2639 if (EQ (tem, tem1)) | |
793 | 2640 tem = wrap_frame (selected_frame ()); |
428 | 2641 } |
2642 | |
2643 /* If this frame has a minibuffer, find that window first, | |
2644 because it is conceptually the last window in that frame. */ | |
2645 if (FRAME_HAS_MINIBUF_P (XFRAME (tem))) | |
2646 tem = FRAME_MINIBUF_WINDOW (XFRAME (tem)); | |
2647 else | |
2648 tem = FRAME_ROOT_WINDOW (XFRAME (tem)); | |
2649 | |
2650 break; | |
2651 } | |
2652 | |
2653 window = tem; | |
2654 | |
2655 /* If we're in a combination window, find its first child and | |
2656 recurse on that. Otherwise, we've found the window we want. */ | |
2657 while (1) | |
2658 { | |
2659 if (!NILP (XWINDOW (window)->hchild)) | |
2660 window = XWINDOW (window)->hchild; | |
2661 else if (!NILP (XWINDOW (window)->vchild)) | |
2662 window = XWINDOW (window)->vchild; | |
2663 else break; | |
2664 while (tem = XWINDOW (window)->next, !NILP (tem)) | |
2665 window = tem; | |
2666 } | |
2667 } | |
2668 /* Which windows are acceptable? | |
2669 Exit the loop and accept this window if | |
2670 this isn't a minibuffer window, | |
2671 or we're accepting all minibuffer windows, | |
2672 or this is the active minibuffer and we are accepting that one, or | |
2673 we've come all the way around and we're back at the original window. */ | |
2674 while (MINI_WINDOW_P (XWINDOW (window)) | |
2675 && ! EQ (minibuf, Qt) | |
2676 && ! EQ (minibuf, window) | |
2677 && ! EQ (window, start_window)); | |
2678 | |
2679 return window; | |
2680 } | |
2681 | |
2682 DEFUN ("next-vertical-window", Fnext_vertical_window, 0, 1, 0, /* | |
2683 Return the next window which is vertically after WINDOW. | |
2684 */ | |
2685 (window)) | |
2686 { | |
2687 Lisp_Object root; | |
2688 struct window *w = decode_window (window); | |
793 | 2689 window = wrap_window (w); |
428 | 2690 |
2691 if (MINI_WINDOW_P (XWINDOW (window))) | |
2692 return Qnil; | |
2693 | |
2694 root = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (XWINDOW (window)))); | |
2695 | |
2696 if (EQ (window, root)) | |
2697 { | |
2698 while (1) | |
2699 if (!NILP (XWINDOW (window)->hchild)) | |
2700 window = XWINDOW (window)->hchild; | |
2701 else if (!NILP (XWINDOW (window)->vchild)) | |
2702 window = XWINDOW (window)->vchild; | |
2703 else | |
2704 return window; | |
2705 } | |
2706 | |
2707 do | |
2708 { | |
2709 if (!NILP (XWINDOW (window)->parent) && | |
2710 !NILP (XWINDOW (XWINDOW (window)->parent)->vchild)) | |
2711 { | |
2712 if (!NILP (XWINDOW (window)->next)) | |
2713 return XWINDOW (window)->next; | |
2714 else | |
2715 window = XWINDOW (window)->parent; | |
2716 } | |
2717 else | |
2718 window = XWINDOW (window)->parent; | |
2719 } | |
2720 while (!EQ (window, root)); | |
2721 | |
2722 while (1) | |
2723 if (!NILP (XWINDOW (window)->hchild)) | |
2724 window = XWINDOW (window)->hchild; | |
2725 else if (!NILP (XWINDOW (window)->vchild)) | |
2726 window = XWINDOW (window)->vchild; | |
2727 else | |
2728 return window; | |
2729 } | |
2730 | |
2731 DEFUN ("other-window", Fother_window, 1, 3, "p", /* | |
444 | 2732 Select the COUNT'th different window on this frame. |
428 | 2733 All windows on current frame are arranged in a cyclic order. |
444 | 2734 This command selects the window COUNT steps away in that order. |
2735 A negative COUNT moves in the opposite order. | |
2736 | |
2737 By default, only the windows in the selected frame are considered. | |
2738 The optional argument WHICH-FRAMES changes this behavior: | |
2739 WHICH-FRAMES = `visible' means search windows on all visible frames. | |
448 | 2740 WHICH-FRAMES = 0 means search windows on all visible and iconified frames. |
444 | 2741 WHICH-FRAMES = t means search windows on all frames including invisible frames. |
2742 WHICH-FRAMES = a frame means search only windows on that frame. | |
2743 Anything else means restrict to the selected frame. | |
2744 | |
2745 The optional argument WHICH-DEVICES further clarifies on which devices | |
2746 to search for frames as specified by WHICH-FRAMES. This value is only | |
2747 meaningful if WHICH-FRAMES is non-nil. | |
2748 If nil or omitted, search all devices on the selected console. | |
2749 If a device, only search that device. | |
2750 If a console, search all devices on that console. | |
2751 If a device type, search all devices of that type. | |
2752 If `window-system', search all window-system devices. | |
2753 Any other non-nil value means search all devices. | |
428 | 2754 */ |
444 | 2755 (count, which_frames, which_devices)) |
428 | 2756 { |
2757 int i; | |
2758 Lisp_Object w; | |
2759 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2760 CHECK_FIXNUM (count); |
428 | 2761 w = Fselected_window (Qnil); |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2762 i = XFIXNUM (count); |
428 | 2763 |
2764 while (i > 0) | |
2765 { | |
444 | 2766 w = Fnext_window (w, Qnil, which_frames, which_devices); |
428 | 2767 i--; |
2768 } | |
2769 while (i < 0) | |
2770 { | |
444 | 2771 w = Fprevious_window (w, Qnil, which_frames, which_devices); |
428 | 2772 i++; |
2773 } | |
2774 Fselect_window (w, Qnil); | |
2775 return Qnil; | |
2776 } | |
2777 | |
2778 | |
2779 /* Look at all windows, performing an operation specified by TYPE | |
2780 with argument OBJ. | |
2781 | |
2782 If FRAMES is Qt, look at all frames, if Qnil, look at just the selected | |
2783 frame. If FRAMES is a frame, just look at windows on that frame. | |
2784 If MINI is non-zero, perform the operation on minibuffer windows too. | |
2785 */ | |
2786 | |
2787 enum window_loop | |
2788 { | |
2789 WINDOW_LOOP_UNUSED, | |
2790 GET_BUFFER_WINDOW, /* Arg is buffer */ | |
2791 GET_LRU_WINDOW, /* Arg is t for full-width windows only */ | |
2792 DELETE_OTHER_WINDOWS, /* Arg is window not to delete */ | |
2793 DELETE_BUFFER_WINDOWS, /* Arg is buffer */ | |
2794 GET_LARGEST_WINDOW, | |
2795 GET_BUFFER_WINDOW_COUNT, /* Arg is buffer */ | |
2796 GET_BUFFER_MRU_WINDOW /* Arg is buffer */ | |
2797 }; | |
2798 | |
2799 static Lisp_Object | |
2800 window_loop (enum window_loop type, | |
2801 Lisp_Object obj, | |
2802 int mini, | |
444 | 2803 Lisp_Object which_frames, |
428 | 2804 int dedicated_too, |
444 | 2805 Lisp_Object which_devices) |
428 | 2806 { |
448 | 2807 /* This function can GC if type == DELETE_BUFFER_WINDOWS */ |
428 | 2808 Lisp_Object w; |
2809 Lisp_Object best_window = Qnil; | |
2810 Lisp_Object next_window; | |
2811 Lisp_Object last_window; | |
2812 struct frame *frame; | |
2813 Lisp_Object frame_arg = Qt; | |
2814 int count = 0; /* for GET_BUFFER_WINDOW_COUNT */ | |
2815 /* #### I think the change of "precomputing" last_window and next_window | |
2816 * #### catch the lossage this is meant(?) to punt on... | |
2817 */ | |
2818 int lose_lose = 0; | |
2819 Lisp_Object devcons, concons; | |
2820 | |
2821 /* If we're only looping through windows on a particular frame, | |
2822 FRAME points to that frame. If we're looping through windows | |
2823 on all frames, FRAME is 0. */ | |
444 | 2824 if (FRAMEP (which_frames)) |
2825 frame = XFRAME (which_frames); | |
2826 else if (NILP (which_frames)) | |
428 | 2827 frame = selected_frame (); |
2828 else | |
2829 frame = 0; | |
442 | 2830 |
2831 /* FRAME_ARG is Qlambda to stick to one frame, | |
2832 Qvisible to consider all visible frames, | |
2833 or Qt otherwise. */ | |
428 | 2834 if (frame) |
2835 frame_arg = Qlambda; | |
444 | 2836 else if (ZEROP (which_frames)) |
2837 frame_arg = which_frames; | |
2838 else if (EQ (which_frames, Qvisible)) | |
2839 frame_arg = which_frames; | |
428 | 2840 |
2841 DEVICE_LOOP_NO_BREAK (devcons, concons) | |
2842 { | |
2843 Lisp_Object device = XCAR (devcons); | |
2844 Lisp_Object the_frame; | |
2845 | |
2846 if (frame) | |
793 | 2847 the_frame = wrap_frame (frame); |
428 | 2848 else |
2849 the_frame = DEVICE_SELECTED_FRAME (XDEVICE (device)); | |
2850 | |
2851 if (NILP (the_frame)) | |
2852 continue; | |
2853 | |
444 | 2854 if (!device_matches_device_spec (device, |
2855 NILP (which_devices) ? | |
2856 FRAME_CONSOLE (XFRAME (the_frame)) : | |
2857 which_devices)) | |
428 | 2858 continue; |
2859 | |
2860 /* Pick a window to start with. */ | |
2861 if (WINDOWP (obj)) | |
2862 w = obj; | |
2863 else | |
2864 w = FRAME_SELECTED_WINDOW (XFRAME (the_frame)); | |
2865 | |
2866 /* Figure out the last window we're going to mess with. Since | |
2867 Fnext_window, given the same options, is guaranteed to go in a | |
2868 ring, we can just use Fprevious_window to find the last one. | |
2869 | |
2870 We can't just wait until we hit the first window again, | |
2871 because it might be deleted. */ | |
2872 | |
707 | 2873 last_window = Fprevious_window (w, mini ? Qt : Qnil, frame_arg, device); |
428 | 2874 |
2875 best_window = Qnil; | |
2876 for (;;) | |
2877 { | |
2878 struct window *p = XWINDOW (w); | |
2879 | |
2880 /* Pick the next window now, since some operations will delete | |
2881 the current window. */ | |
442 | 2882 next_window = Fnext_window (w, mini ? Qt : Qnil, frame_arg, device); |
428 | 2883 |
2884 /* #### Still needed ?? */ | |
2885 /* Given the outstanding quality of the rest of this code, | |
2886 I feel no shame about putting this piece of shit in. */ | |
2887 if (++lose_lose >= 500) | |
707 | 2888 { |
2500 | 2889 /* Call to ABORT() added by Darryl Okahata (16 Nov. 2001), |
707 | 2890 at Ben's request, to catch any remaining bugs. |
2891 | |
2892 If you find that XEmacs is aborting here, and you | |
2893 need to be up and running ASAP, it should be safe to | |
2500 | 2894 comment out the following ABORT(), as long as you |
707 | 2895 leave the "break;" alone. */ |
2500 | 2896 ABORT(); |
707 | 2897 break; /* <--- KEEP THIS HERE! Do not delete! */ |
2898 } | |
428 | 2899 |
2900 /* Note that we do not pay attention here to whether | |
2901 the frame is visible, since Fnext_window skips non-visible frames | |
2902 if that is desired, under the control of frame_arg. */ | |
2903 if (! MINI_WINDOW_P (p) | |
2904 || (mini && minibuf_level > 0)) | |
2905 switch (type) | |
2906 { | |
2907 case GET_BUFFER_WINDOW: | |
2908 { | |
2909 if (XBUFFER (p->buffer) == XBUFFER (obj)) | |
2910 return w; | |
2911 break; | |
2912 } | |
2913 | |
2914 case GET_BUFFER_WINDOW_COUNT: | |
2915 { | |
2916 if (XBUFFER (p->buffer) == XBUFFER (obj)) | |
2917 count++; | |
2918 break; | |
2919 } | |
2920 | |
2921 case GET_LRU_WINDOW: | |
2922 { | |
2923 /* t as arg means consider only full-width windows */ | |
2924 if (!NILP (obj) | |
2925 && !window_full_width_p (p)) | |
2926 break; | |
2927 /* Ignore dedicated windows and minibuffers. */ | |
2928 if (MINI_WINDOW_P (p) | |
2929 || (dedicated_too ? 0 : !NILP (p->dedicated))) | |
2930 break; | |
2931 if (NILP (best_window) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2932 || (XFIXNUM (XWINDOW (best_window)->use_time) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2933 > XFIXNUM (p->use_time))) |
428 | 2934 best_window = w; |
2935 break; | |
2936 } | |
2937 | |
2938 case GET_BUFFER_MRU_WINDOW: | |
2939 { | |
2940 /* #### what about the first check in GET_LRU_WINDOW? */ | |
2941 /* Ignore dedicated windows and minibuffers. */ | |
2942 if (MINI_WINDOW_P (p) | |
2943 || (dedicated_too ? 0 : !NILP (p->dedicated))) | |
2944 break; | |
2945 | |
2946 if (XBUFFER (p->buffer) == XBUFFER (obj)) | |
2947 { | |
2948 if (NILP (best_window) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2949 || (XFIXNUM (XWINDOW (best_window)->use_time) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
2950 < XFIXNUM (p->use_time))) |
428 | 2951 best_window = w; |
2952 } | |
2953 break; | |
2954 } | |
2955 | |
2956 case DELETE_OTHER_WINDOWS: | |
2957 { | |
2958 /* Don't delete the last window on a frame; this can | |
2959 happen when the minibuffer is selected, and would | |
2960 cause the frame to be deleted. */ | |
2961 if (p != XWINDOW (obj) && !TOP_LEVEL_WINDOW_P (XWINDOW (w))) | |
2962 Fdelete_window (w, Qnil); | |
2963 break; | |
2964 } | |
2965 | |
2966 case DELETE_BUFFER_WINDOWS: | |
2967 { | |
2968 if (EQ (p->buffer, obj)) | |
2969 { | |
2970 struct frame *f = XFRAME (WINDOW_FRAME (p)); | |
2971 | |
2972 /* If this window is dedicated, and in a frame | |
2973 of its own, kill the frame. */ | |
2974 if (EQ (w, FRAME_ROOT_WINDOW (f)) | |
2975 && !NILP (p->dedicated) | |
1979 | 2976 && (allow_deletion_of_last_visible_frame |
2977 || other_visible_frames (f))) | |
428 | 2978 { |
2979 /* Skip the other windows on this frame. | |
2980 There might be one, the minibuffer! */ | |
2981 if (! EQ (w, last_window)) | |
2982 while (f == XFRAME (WINDOW_FRAME | |
2983 (XWINDOW (next_window)))) | |
2984 { | |
2985 /* As we go, check for the end of the | |
2986 loop. We mustn't start going | |
2987 around a second time. */ | |
2988 if (EQ (next_window, last_window)) | |
2989 { | |
2990 last_window = w; | |
2991 break; | |
2992 } | |
2993 next_window = Fnext_window (next_window, | |
2994 mini ? Qt : Qnil, | |
2995 frame_arg, Qt); | |
2996 } | |
2997 /* Now we can safely delete the frame. */ | |
2998 Fdelete_frame (WINDOW_FRAME (p), Qnil); | |
2999 } | |
3000 else | |
3001 /* If we're deleting the buffer displayed in | |
3002 the only window on the frame, find a new | |
3003 buffer to display there. */ | |
3004 if (NILP (p->parent)) | |
3005 { | |
3006 Lisp_Object new_buffer; | |
3007 new_buffer = Fother_buffer (obj, Qnil, Qnil); | |
3008 if (NILP (new_buffer)) | |
3009 new_buffer = Fget_buffer_create (QSscratch); | |
440 | 3010 Fset_window_buffer (w, new_buffer, Qnil); |
428 | 3011 if (EQ (w, Fselected_window (Qnil))) |
3012 Fset_buffer (p->buffer); | |
3013 } | |
3014 else | |
3015 Fdelete_window (w, Qnil); | |
3016 } | |
3017 break; | |
3018 } | |
3019 | |
3020 case GET_LARGEST_WINDOW: | |
3021 { | |
3022 /* Ignore dedicated windows and minibuffers. */ | |
3023 if (MINI_WINDOW_P (p) | |
3024 || (dedicated_too ? 0 : !NILP (p->dedicated))) | |
3025 break; | |
3026 { | |
3027 /* write the check as follows to avoid tripping | |
3028 error_check_window() --ben */ | |
3029 struct window *b = NILP (best_window) ? 0 : | |
3030 XWINDOW (best_window); | |
3031 if (NILP (best_window) | |
3032 || ((WINDOW_HEIGHT (p) * WINDOW_WIDTH (p)) | |
3033 > (WINDOW_HEIGHT (b) * WINDOW_WIDTH (b)))) | |
3034 best_window = w; | |
3035 } | |
3036 break; | |
3037 } | |
3038 | |
3039 default: | |
2500 | 3040 ABORT (); |
428 | 3041 } |
3042 | |
3043 if (EQ (w, last_window)) | |
3044 break; | |
3045 | |
3046 w = next_window; | |
3047 } | |
3048 } | |
3049 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3050 return type == GET_BUFFER_WINDOW_COUNT ? make_fixnum (count) : best_window; |
428 | 3051 } |
3052 | |
3053 #if 0 /* not currently used */ | |
3054 | |
3055 int | |
3056 buffer_window_count (struct buffer *b, struct frame *f) | |
3057 { | |
3058 Lisp_Object buffer, frame; | |
3059 | |
793 | 3060 frame = wrap_frame (f); |
3061 buffer = wrap_buffer (b); | |
428 | 3062 |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3063 return XFIXNUM (window_loop (GET_BUFFER_WINDOW_COUNT, buffer, 0, frame, 1, |
428 | 3064 Qnil)); |
3065 } | |
3066 | |
3067 int | |
3068 buffer_window_mru (struct window *w) | |
3069 { | |
3070 Lisp_Object window = | |
3071 window_loop (GET_BUFFER_MRU_WINDOW, w->buffer, 0, w->frame, 1, Qnil); | |
3072 | |
3073 if (NILP (window)) | |
3074 return 0; | |
3075 else if (XWINDOW (window) == w) | |
3076 return 1; | |
3077 else | |
3078 return 0; | |
3079 } | |
3080 | |
3081 #endif | |
3082 | |
3083 | |
3084 DEFUN ("get-lru-window", Fget_lru_window, 0, 2, 0, /* | |
3085 Return the window least recently selected or used for display. | |
444 | 3086 |
3087 By default, only the windows in the selected frame are considered. | |
3088 The optional argument WHICH-FRAMES changes this behavior: | |
3089 If optional argument WHICH-FRAMES is `visible', search all visible frames. | |
3090 If WHICH-FRAMES is 0, search all visible and iconified frames. | |
3091 If WHICH-FRAMES is t, search all frames. | |
3092 If WHICH-FRAMES is nil, search only the selected frame. | |
3093 If WHICH-FRAMES is a frame, search only that frame. | |
3094 | |
3095 The optional argument WHICH-DEVICES further clarifies on which devices | |
3096 to search for frames as specified by WHICH-FRAMES. This value is only | |
3097 meaningful if WHICH-FRAMES is non-nil. | |
3098 If nil or omitted, search all devices on the selected console. | |
3099 If a device, only search that device. | |
3100 If a console, search all devices on that console. | |
3101 If a device type, search all devices of that type. | |
3102 If `window-system', search all devices on window-system consoles. | |
3103 Any other non-nil value means search all devices. | |
428 | 3104 */ |
444 | 3105 (which_frames, which_devices)) |
428 | 3106 { |
3107 Lisp_Object w; | |
3108 /* First try for a non-dedicated window that is full-width */ | |
444 | 3109 w = window_loop (GET_LRU_WINDOW, Qt, 0, which_frames, 0, which_devices); |
428 | 3110 if (!NILP (w) && !EQ (w, Fselected_window (Qnil))) |
3111 return w; | |
3112 | |
3113 /* Then try for any non-dedicated window */ | |
444 | 3114 w = window_loop (GET_LRU_WINDOW, Qnil, 0, which_frames, 0, which_devices); |
428 | 3115 if (!NILP (w) && !EQ (w, Fselected_window (Qnil))) |
3116 return w; | |
3117 | |
3118 #if 0 | |
3119 /* FSFmacs never returns a dedicated window here. If we do, | |
3120 it makes `display-buffer' not work right. #### All of this | |
3121 shit is so disgusting and awful that it needs to be rethought | |
3122 from scratch. */ | |
3123 /* then try for a dedicated window that is full-width */ | |
444 | 3124 w = window_loop (GET_LRU_WINDOW, Qt, 0, which_frames, 1, which_devices); |
428 | 3125 if (!NILP (w) && !EQ (w, Fselected_window (Qnil))) |
3126 return w; | |
3127 | |
3128 /* If none of them, then all windows, dedicated or not. */ | |
444 | 3129 w = window_loop (GET_LRU_WINDOW, Qnil, 0, which_frames, 1, which_devices); |
428 | 3130 |
3131 /* At this point we damn well better have found something. */ | |
5050
6f2158fa75ed
Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3132 assert (!NILP (w)); |
428 | 3133 #endif |
3134 | |
3135 return w; | |
3136 } | |
3137 | |
3138 DEFUN ("get-largest-window", Fget_largest_window, 0, 2, 0, /* | |
3139 Return the window largest in area. | |
444 | 3140 |
3141 By default, only the windows in the selected frame are considered. | |
3142 The optional argument WHICH-FRAMES changes this behavior: | |
3143 If optional argument WHICH-FRAMES is `visible', search all visible frames. | |
3144 If WHICH-FRAMES is 0, search all visible and iconified frames. | |
3145 If WHICH-FRAMES is t, search all frames. | |
3146 If WHICH-FRAMES is nil, search only the selected frame. | |
3147 If WHICH-FRAMES is a frame, search only that frame. | |
3148 | |
3149 The optional argument WHICH-DEVICES further clarifies on which devices | |
3150 to search for frames as specified by WHICH-FRAMES. This value is only | |
3151 meaningful if WHICH-FRAMES is non-nil. | |
3152 If nil or omitted, search all devices on the selected console. | |
3153 If a device, only search that device. | |
3154 If a console, search all devices on that console. | |
3155 If a device type, search all devices of that type. | |
3156 If `window-system', search all devices on window-system consoles. | |
3157 Any other non-nil value means search all devices. | |
428 | 3158 */ |
444 | 3159 (which_frames, which_devices)) |
428 | 3160 { |
3161 /* Don't search dedicated windows because FSFmacs doesn't. | |
3162 This stuff is all black magic so don't try to apply common | |
3163 sense to it. */ | |
444 | 3164 return window_loop (GET_LARGEST_WINDOW, Qnil, 0, |
3165 which_frames, 0, which_devices); | |
428 | 3166 } |
3167 | |
3168 DEFUN ("get-buffer-window", Fget_buffer_window, 1, 3, 0, /* | |
3169 Return a window currently displaying BUFFER, or nil if none. | |
444 | 3170 |
3171 By default, only the windows in the selected frame are considered. | |
3172 The optional argument WHICH-FRAMES changes this behavior: | |
3173 If optional argument WHICH-FRAMES is `visible', search all visible frames. | |
3174 If WHICH-FRAMES is 0, search all visible and iconified frames. | |
3175 If WHICH-FRAMES is t, search all frames. | |
3176 If WHICH-FRAMES is nil, search only the selected frame. | |
3177 If WHICH-FRAMES is a frame, search only that frame. | |
3178 | |
3179 The optional argument WHICH-DEVICES further clarifies on which devices | |
3180 to search for frames as specified by WHICH-FRAMES. This value is only | |
3181 meaningful if WHICH-FRAMES is non-nil. | |
3182 If nil or omitted, search all devices on the selected console. | |
3183 If a device, only search that device. | |
3184 If a console, search all devices on that console. | |
3185 If a device type, search all devices of that type. | |
3186 If `window-system', search all devices on window-system consoles. | |
3187 Any other non-nil value means search all devices. | |
428 | 3188 */ |
444 | 3189 (buffer, which_frames, which_devices)) |
428 | 3190 { |
3191 buffer = Fget_buffer (buffer); | |
3192 if (BUFFERP (buffer)) | |
3193 /* Search dedicated windows too. (Doesn't matter here anyway.) */ | |
444 | 3194 return window_loop (GET_BUFFER_WINDOW, buffer, 1, |
3195 which_frames, 1, which_devices); | |
428 | 3196 else |
3197 return Qnil; | |
3198 } | |
3199 | |
3200 /* These functions used to be `buffer-left-margin-pixel-width', etc. | |
3201 but there is no sensible way to implement those functions, since | |
3202 you can't in general derive a window from a buffer. */ | |
3203 | |
3204 DEFUN ("window-left-margin-pixel-width", Fwindow_left_margin_pixel_width, | |
3205 0, 1, 0, /* | |
3206 Return the width in pixels of the left outside margin of window WINDOW. | |
3207 If WINDOW is nil, the selected window is assumed. | |
3208 */ | |
3209 (window)) | |
3210 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3211 return make_fixnum (window_left_margin_width (decode_window (window))); |
428 | 3212 } |
3213 | |
3214 DEFUN ("window-right-margin-pixel-width", Fwindow_right_margin_pixel_width, | |
3215 0, 1, 0, /* | |
3216 Return the width in pixels of the right outside margin of window WINDOW. | |
3217 If WINDOW is nil, the selected window is assumed. | |
3218 */ | |
3219 (window)) | |
3220 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3221 return make_fixnum (window_right_margin_width (decode_window (window))); |
428 | 3222 } |
3223 | |
3224 DEFUN ("delete-other-windows", Fdelete_other_windows, 0, 1, "", /* | |
3225 Make WINDOW (or the selected window) fill its frame. | |
3226 Only the frame WINDOW is on is affected. | |
3227 This function tries to reduce display jumps | |
3228 by keeping the text previously visible in WINDOW | |
3229 in the same place on the frame. Doing this depends on | |
3230 the value of (window-start WINDOW), so if calling this function | |
3231 in a program gives strange scrolling, make sure the window-start | |
3232 value is reasonable when this function is called. | |
3233 */ | |
3234 (window)) | |
3235 { | |
3236 struct window *w = decode_window (window); | |
1207 | 3237 struct buffer *b; |
665 | 3238 Charbpos start_pos; |
428 | 3239 int old_top = WINDOW_TOP (w); |
3240 | |
1207 | 3241 if (NILP (WINDOW_BUFFER (w))) |
3242 invalid_operation ("Can't delete other windows of combination", window); | |
3243 | |
793 | 3244 window = wrap_window (w); |
1207 | 3245 b = XBUFFER (WINDOW_BUFFER (w)); |
428 | 3246 |
3247 if (MINI_WINDOW_P (w) && old_top > 0) | |
563 | 3248 invalid_operation ("Can't expand minibuffer to full frame", Qunbound); |
428 | 3249 |
3250 /* Ignore dedicated windows. */ | |
3251 window_loop (DELETE_OTHER_WINDOWS, window, 0, w->frame, 0, Qnil); | |
3252 | |
3253 start_pos = marker_position (w->start[CURRENT_DISP]); | |
3254 | |
3255 /* Try to minimize scrolling, by setting the window start to the | |
3256 point which will cause the text at the old window start to be at | |
3257 the same place on the frame. But don't try to do this if the | |
3258 window start is outside the visible portion (as might happen when | |
3259 the display is not current, due to typeahead). */ | |
3260 if (start_pos >= BUF_BEGV (b) && start_pos <= BUF_ZV (b) | |
3261 && !MINI_WINDOW_P (w)) | |
3262 { | |
665 | 3263 Charbpos new_start = start_with_line_at_pixpos (w, start_pos, old_top); |
428 | 3264 |
3265 if (new_start >= BUF_BEGV (b) && new_start <= BUF_ZV (b)) | |
3266 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3267 Fset_marker (w->start[CURRENT_DISP], make_fixnum (new_start), |
428 | 3268 w->buffer); |
3269 w->start_at_line_beg = beginning_of_line_p (b, new_start); | |
3270 } | |
3271 /* We need to do this, so that the window-scroll-functions | |
3272 get called. */ | |
3273 w->force_start = 1; | |
3274 } | |
3275 | |
3276 return Qnil; | |
3277 } | |
3278 | |
3279 DEFUN ("delete-windows-on", Fdelete_windows_on, 1, 3, | |
3280 "bDelete windows on (buffer): ", /* | |
3281 Delete all windows showing BUFFER. | |
444 | 3282 |
3283 Optional second argument WHICH-FRAMES controls which frames are affected. | |
428 | 3284 If nil or omitted, delete all windows showing BUFFER in any frame. |
3285 If t, delete only windows showing BUFFER in the selected frame. | |
3286 If `visible', delete all windows showing BUFFER in any visible frame. | |
3287 If a frame, delete only windows showing BUFFER in that frame. | |
444 | 3288 Warning: WHICH-FRAMES has the same meaning as with `next-window', |
3289 except that the meanings of nil and t are reversed. | |
3290 | |
3291 The optional third argument WHICH-DEVICES further clarifies on which | |
3292 devices to search for frames as specified by WHICH-FRAMES. This value | |
3293 is only meaningful if WHICH-FRAMES is not t. | |
3294 If nil or omitted, search only the selected console. | |
3295 If a device, only search that device. | |
3296 If a console, search all devices on that console. | |
3297 If a device type, search all devices of that type. | |
3298 If `window-system', search all devices on a window system. | |
3299 Any other non-nil value means search all devices. | |
428 | 3300 */ |
444 | 3301 (buffer, which_frames, which_devices)) |
428 | 3302 { |
3303 /* This function can GC */ | |
444 | 3304 buffer = Fget_buffer (buffer); |
3305 CHECK_BUFFER (buffer); | |
3306 | |
3307 /* WHICH-FRAMES values t and nil mean the opposite of what | |
3308 window_loop expects. */ | |
3309 if (EQ (which_frames, Qnil)) | |
3310 which_frames = Qt; | |
3311 else if (EQ (which_frames, Qt)) | |
3312 which_frames = Qnil; | |
3313 | |
3314 /* Ignore dedicated windows. */ | |
3315 window_loop (DELETE_BUFFER_WINDOWS, buffer, 0, | |
3316 which_frames, 0, which_devices); | |
428 | 3317 return Qnil; |
3318 } | |
3319 | |
448 | 3320 static Lisp_Object |
3321 list_windows (struct window *w, Lisp_Object value) | |
3322 { | |
3323 for (;;) | |
3324 { | |
3325 if (!NILP (w->hchild)) | |
3326 value = list_windows (XWINDOW (w->hchild), value); | |
3327 else if (!NILP (w->vchild)) | |
3328 value = list_windows (XWINDOW (w->vchild), value); | |
3329 else | |
3330 { | |
793 | 3331 Lisp_Object window = wrap_window (w); |
3332 | |
448 | 3333 value = Fcons (window, value); |
3334 } | |
3335 if (NILP (w->next)) | |
3336 break; | |
3337 w = XWINDOW (w->next); | |
3338 } | |
3339 return value; | |
3340 } | |
3341 | |
3342 static Lisp_Object | |
3343 list_all_windows (Lisp_Object frame_spec, Lisp_Object device_spec) | |
3344 { | |
3345 Lisp_Object devcons, concons; | |
3346 Lisp_Object retval = Qnil; | |
3347 | |
3348 DEVICE_LOOP_NO_BREAK (devcons, concons) | |
3349 { | |
3350 Lisp_Object frame_list, the_window; | |
3351 Lisp_Object device, tail; | |
3352 | |
3353 device = XCAR (devcons); | |
3354 frame_list = DEVICE_FRAME_LIST (XDEVICE (device)); | |
3355 | |
3356 LIST_LOOP (tail, frame_list) | |
3357 { | |
3358 if ((NILP (frame_spec) | |
3359 && !EQ (XCAR (tail), DEVICE_SELECTED_FRAME (XDEVICE (device)))) | |
3360 || (EQ (frame_spec, Qvisible) | |
3361 && !FRAME_VISIBLE_P (XFRAME (XCAR (tail)))) | |
3362 || (FRAMEP (frame_spec) | |
3363 && !EQ (frame_spec, XCAR (tail))) | |
3364 || (!NILP (frame_spec) | |
3365 && !device_matches_device_spec (device, | |
3366 NILP (device_spec) ? | |
3367 Vselected_console : | |
3368 device_spec))) | |
3369 continue; | |
3370 the_window = FRAME_ROOT_WINDOW (XFRAME (XCAR (tail))); | |
3371 retval = list_windows (XWINDOW (the_window), retval); | |
3372 } | |
3373 } | |
3374 return Fnreverse (retval); | |
3375 } | |
3376 | |
444 | 3377 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows, 1, 3, |
428 | 3378 "bReplace buffer in windows: ", /* |
3379 Replace BUFFER with some other buffer in all windows showing it. | |
444 | 3380 |
3381 Optional second argument WHICH-FRAMES controls which frames are affected. | |
3382 If nil or omitted, all frames are affected. | |
3383 If t, only the selected frame is affected. | |
3384 If `visible', all visible frames are affected. | |
3385 If a frame, only that frame is affected. | |
3386 Warning: WHICH-FRAMES has the same meaning as with `next-window', | |
3387 except that the meanings of nil and t are reversed. | |
3388 | |
3389 The optional third argument WHICH-DEVICES further clarifies on which | |
3390 devices to search for frames as specified by WHICH-FRAMES. This value | |
3391 is only meaningful if WHICH-FRAMES is not t. | |
3392 If nil or omitted, search only the selected console. | |
3393 If a device, only search that device. | |
3394 If a console, search all devices on that console. | |
3395 If a device type, search all devices of that type. | |
3396 If `window-system', search all devices on a window system. | |
3397 Any other non-nil value means search all devices. | |
428 | 3398 */ |
444 | 3399 (buffer, which_frames, which_devices)) |
428 | 3400 { |
3401 /* This function can GC */ | |
448 | 3402 Lisp_Object window_list; |
3403 Lisp_Object tail; | |
3404 struct gcpro gcpro1, gcpro2; | |
3405 | |
444 | 3406 if (EQ (which_frames, Qnil)) |
3407 which_frames = Qt; | |
3408 else if (EQ (which_frames, Qt)) | |
3409 which_frames = Qnil; | |
448 | 3410 window_list = list_all_windows (which_frames, which_devices); |
3411 | |
3412 buffer = Fget_buffer (buffer); | |
3413 CHECK_BUFFER (buffer); | |
3414 | |
3415 GCPRO2 (window_list, buffer); | |
3416 LIST_LOOP (tail, window_list) | |
3417 { | |
3418 Lisp_Object window = XCAR (tail); | |
3419 if (!MINI_WINDOW_P (XWINDOW (window)) | |
3420 && EQ (XWINDOW (window)->buffer, buffer)) | |
3421 { | |
3422 Lisp_Object another_buffer = Fother_buffer (buffer, Qnil, Qnil); | |
3423 Lisp_Object frame = WINDOW_FRAME (XWINDOW (window)); | |
3424 if (NILP (another_buffer)) | |
3425 another_buffer = Fget_buffer_create (QSscratch); | |
3426 if (!NILP (XWINDOW (window)->dedicated) | |
3427 && EQ (window, | |
3428 FRAME_ROOT_WINDOW (XFRAME (frame))) | |
1979 | 3429 && (allow_deletion_of_last_visible_frame |
3430 || other_visible_frames (XFRAME (frame)))) | |
448 | 3431 { |
3432 delete_frame_internal (XFRAME (frame), 0, 0, 0); /* GC */ | |
3433 } | |
3434 else | |
3435 { | |
3436 Fset_window_buffer (window, another_buffer, Qnil); | |
3437 if (EQ (window, Fselected_window (Qnil))) | |
3438 Fset_buffer (XWINDOW (window)->buffer); | |
3439 } | |
3440 } | |
3441 } | |
3442 UNGCPRO; | |
428 | 3443 return Qnil; |
3444 } | |
3445 | |
3446 /* The smallest acceptable dimensions for a window. Anything smaller | |
3447 might crash Emacs. */ | |
3448 #define MIN_SAFE_WINDOW_WIDTH (2) | |
3449 #define MIN_SAFE_WINDOW_HEIGHT (2) | |
3450 | |
3451 /* Make sure that window_min_height and window_min_width are | |
3452 not too small; if they are, set them to safe minima. */ | |
3453 | |
3454 static void | |
3455 check_min_window_sizes (void) | |
3456 { | |
3457 /* Smaller values might permit a crash. */ | |
3458 if (window_min_width < MIN_SAFE_WINDOW_WIDTH) | |
3459 window_min_width = MIN_SAFE_WINDOW_WIDTH; | |
3460 if (window_min_height < MIN_SAFE_WINDOW_HEIGHT) | |
3461 window_min_height = MIN_SAFE_WINDOW_HEIGHT; | |
3462 } | |
3463 | |
440 | 3464 static int |
3465 frame_min_height (struct frame *frame) | |
3466 { | |
3467 /* For height, we have to see whether the frame has a minibuffer, and | |
3468 whether it wants a modeline. */ | |
3469 return (FRAME_MINIBUF_ONLY_P (frame) ? MIN_SAFE_WINDOW_HEIGHT - 1 | |
3470 : (! FRAME_HAS_MINIBUF_P (frame)) ? MIN_SAFE_WINDOW_HEIGHT | |
3471 : 2 * MIN_SAFE_WINDOW_HEIGHT - 1); | |
3472 } | |
3473 | |
3474 /* Return non-zero if both frame sizes are less than or equal to | |
3475 minimal allowed values. ROWS and COLS are in characters */ | |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
3476 static int |
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
3477 frame_size_valid_p (struct frame *frame, int cols, int rows) |
440 | 3478 { |
3479 return (rows >= frame_min_height (frame) | |
3480 && cols >= MIN_SAFE_WINDOW_WIDTH); | |
3481 } | |
3482 | |
3483 /* Return non-zero if both frame sizes are less than or equal to | |
3484 minimal allowed values. WIDTH and HEIGHT are in pixels */ | |
3485 int | |
3486 frame_pixsize_valid_p (struct frame *frame, int width, int height) | |
3487 { | |
3488 int rows, cols; | |
5043 | 3489 pixel_to_char_size (frame, width, height, &cols, &rows); |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
3490 return frame_size_valid_p (frame, cols, rows); |
440 | 3491 } |
3492 | |
428 | 3493 /* If *ROWS or *COLS are too small a size for FRAME, set them to the |
3494 minimum allowable size. */ | |
3495 void | |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
3496 check_frame_size (struct frame *frame, int *cols, int *rows) |
428 | 3497 { |
440 | 3498 int min_height = frame_min_height (frame); |
5043 | 3499 int min_pixwidth, min_pixheight; |
3500 int min_geomwidth, min_geomheight; | |
3501 | |
3502 /* There is no char_to_frame_unit_size(). This can be done with | |
3503 frame_conversion_internal(), but that's currently static, and we can | |
3504 do it fine with two steps, as follows. */ | |
3505 char_to_pixel_size (frame, MIN_SAFE_WINDOW_WIDTH, min_height, | |
3506 &min_pixwidth, &min_pixheight); | |
3507 pixel_to_frame_unit_size (frame, min_pixwidth, min_pixheight, | |
3508 &min_geomwidth, &min_geomheight); | |
3509 if (*rows < min_geomheight) | |
3510 *rows = min_geomheight; | |
3511 if (*cols < min_geomwidth) | |
3512 *cols = min_geomwidth; | |
428 | 3513 } |
3514 | |
3515 /* Normally the window is deleted if it gets too small. | |
3516 nodelete nonzero means do not do this. | |
3517 (The caller should check later and do so if appropriate) */ | |
3518 static void | |
3519 set_window_pixsize (Lisp_Object window, int new_pixsize, int nodelete, | |
3520 int set_height) | |
3521 { | |
3522 struct window *w = XWINDOW (window); | |
3523 struct frame *f = XFRAME (w->frame); | |
3524 struct window *c; | |
3525 int old_pixsize = (set_height ? WINDOW_HEIGHT (w) : WINDOW_WIDTH (w)); | |
3526 Lisp_Object child, minor_kid, major_kid; | |
3527 int minsize; | |
3528 int line_size; | |
3529 int defheight, defwidth; | |
3530 | |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
3531 default_face_width_and_height (window, &defwidth, &defheight); |
428 | 3532 line_size = (set_height ? defheight : defwidth); |
3533 | |
3534 check_min_window_sizes (); | |
3535 | |
3536 minsize = (set_height ? window_min_height : window_min_width); | |
3537 minsize *= line_size; | |
3538 | |
3539 if (!nodelete | |
3540 && !TOP_LEVEL_WINDOW_P (w) | |
4375
74e0e1131e01
Update window-size computation.
Mike Sperber <sperber@deinprogramm.de>
parents:
3707
diff
changeset
|
3541 && (new_pixsize + window_modeline_height (w)) < minsize) |
428 | 3542 { |
3543 Fdelete_window (window, Qnil); | |
3544 return; | |
3545 } | |
3546 | |
3547 SET_LAST_MODIFIED (w, 0); | |
3548 SET_LAST_FACECHANGE (w); | |
3549 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f); /* multiple windows affected */ | |
3550 if (set_height) | |
3551 { | |
3552 WINDOW_HEIGHT (w) = new_pixsize; | |
3553 major_kid = w->vchild; | |
3554 minor_kid = w->hchild; | |
3555 } | |
3556 else | |
3557 { | |
3558 WINDOW_WIDTH (w) = new_pixsize; | |
3559 major_kid = w->hchild; | |
3560 minor_kid = w->vchild; | |
3561 } | |
3562 | |
3563 if (!NILP (minor_kid)) | |
3564 { | |
3565 for (child = minor_kid; !NILP (child); child = XWINDOW (child)->next) | |
3566 { | |
3567 if (set_height) | |
3568 WINDOW_TOP (XWINDOW (child)) = WINDOW_TOP (w); | |
3569 else | |
3570 WINDOW_LEFT (XWINDOW (child)) = WINDOW_LEFT (w); | |
3571 | |
3572 set_window_pixsize (child, new_pixsize, nodelete, set_height); | |
3573 } | |
3574 } | |
3575 else if (!NILP (major_kid)) | |
3576 { | |
3577 int last_pos, last_old_pos, pos, old_pos, first; | |
3578 int pixel_adj_left = new_pixsize - old_pixsize; | |
3579 int div_val = old_pixsize << 1; | |
3580 | |
3581 /* | |
3582 * Previously we bailed out here if there was no size change. | |
3583 * (pixel_adj_left == 0) But this broke toolbar updates. If a | |
3584 * toolbar appears or disappears, windows may not change size, | |
3585 * but their top and left coordinates need to be updated. | |
3586 * | |
3587 * So we don't bail until after the loop below. | |
3588 */ | |
3589 | |
3590 last_pos = first = (set_height ? WINDOW_TOP (w) : WINDOW_LEFT (w)); | |
3591 last_old_pos = 0; | |
3592 | |
3593 for (child = major_kid; !NILP (child); child = c->next) | |
3594 { | |
3595 c = XWINDOW (child); | |
3596 | |
3597 if (set_height) | |
3598 { | |
3599 old_pos = last_old_pos + WINDOW_HEIGHT (c); | |
3600 WINDOW_TOP (c) = last_pos; | |
3601 } | |
3602 else | |
3603 { | |
3604 old_pos = last_old_pos + WINDOW_WIDTH (c); | |
3605 WINDOW_LEFT (c) = last_pos; | |
3606 } | |
3607 | |
3608 pos = (((old_pos * new_pixsize) << 1) + old_pixsize) / div_val; | |
3609 /* All but the last window should have a height which is | |
3610 a multiple of the default line height. */ | |
3611 if (!NILP (c->next)) | |
4446
c32b3d10c56b
Fix problem with `resize-minibuffer-mode'.
Mike Sperber <sperber@deinprogramm.de>
parents:
4375
diff
changeset
|
3612 { |
c32b3d10c56b
Fix problem with `resize-minibuffer-mode'.
Mike Sperber <sperber@deinprogramm.de>
parents:
4375
diff
changeset
|
3613 /* |
c32b3d10c56b
Fix problem with `resize-minibuffer-mode'.
Mike Sperber <sperber@deinprogramm.de>
parents:
4375
diff
changeset
|
3614 * Round up when we're shrinking, down when we're growing |
c32b3d10c56b
Fix problem with `resize-minibuffer-mode'.
Mike Sperber <sperber@deinprogramm.de>
parents:
4375
diff
changeset
|
3615 * to make sure that pairs of grow / shrink meant to |
c32b3d10c56b
Fix problem with `resize-minibuffer-mode'.
Mike Sperber <sperber@deinprogramm.de>
parents:
4375
diff
changeset
|
3616 * cancel out actually do cancel out. |
c32b3d10c56b
Fix problem with `resize-minibuffer-mode'.
Mike Sperber <sperber@deinprogramm.de>
parents:
4375
diff
changeset
|
3617 */ |
c32b3d10c56b
Fix problem with `resize-minibuffer-mode'.
Mike Sperber <sperber@deinprogramm.de>
parents:
4375
diff
changeset
|
3618 if (pixel_adj_left < 0) |
c32b3d10c56b
Fix problem with `resize-minibuffer-mode'.
Mike Sperber <sperber@deinprogramm.de>
parents:
4375
diff
changeset
|
3619 pos = ((pos + line_size -1) / line_size) * line_size; |
c32b3d10c56b
Fix problem with `resize-minibuffer-mode'.
Mike Sperber <sperber@deinprogramm.de>
parents:
4375
diff
changeset
|
3620 else |
c32b3d10c56b
Fix problem with `resize-minibuffer-mode'.
Mike Sperber <sperber@deinprogramm.de>
parents:
4375
diff
changeset
|
3621 pos = (pos / line_size) * line_size; |
c32b3d10c56b
Fix problem with `resize-minibuffer-mode'.
Mike Sperber <sperber@deinprogramm.de>
parents:
4375
diff
changeset
|
3622 } |
428 | 3623 |
3624 /* Avoid confusion: don't delete child if it becomes too small */ | |
3625 set_window_pixsize (child, pos + first - last_pos, 1, set_height); | |
3626 | |
3627 last_pos = pos + first; | |
3628 last_old_pos = old_pos; | |
3629 } | |
3630 | |
3631 /* Sometimes we may get called with our old size. In that case | |
3632 we don't need to do anything else. */ | |
3633 if (!pixel_adj_left) | |
3634 return; | |
3635 | |
3636 /* Now delete any children that became too small. */ | |
3637 if (!nodelete) | |
3638 for (child = major_kid; !NILP (child); child = XWINDOW (child)->next) | |
3639 { | |
3640 if (set_height) | |
3641 set_window_pixheight (child, WINDOW_HEIGHT (XWINDOW (child)), 0); | |
3642 else | |
3643 set_window_pixwidth (child, WINDOW_WIDTH (XWINDOW (child)), 0); | |
3644 } | |
3645 } | |
3646 } | |
3647 | |
3648 /* Set the height of WINDOW and all its inferiors. */ | |
3649 void | |
3650 set_window_pixheight (Lisp_Object window, int new_pixheight, int nodelete) | |
3651 { | |
3652 set_window_pixsize (window, new_pixheight, nodelete, 1); | |
3653 } | |
3654 | |
3655 /* Recursively set width of WINDOW and its inferiors. */ | |
3656 void | |
3657 set_window_pixwidth (Lisp_Object window, int new_pixwidth, int nodelete) | |
3658 { | |
3659 set_window_pixsize (window, new_pixwidth, nodelete, 0); | |
3660 } | |
3661 | |
3662 | |
3663 static int window_select_count; | |
3664 | |
440 | 3665 DEFUN ("set-window-buffer", Fset_window_buffer, 2, 3, 0, /* |
428 | 3666 Make WINDOW display BUFFER as its contents. |
3667 BUFFER can be a buffer or buffer name. | |
440 | 3668 |
442 | 3669 With non-nil optional argument NORECORD, do not modify the |
440 | 3670 global or per-frame buffer ordering. |
428 | 3671 */ |
440 | 3672 (window, buffer, norecord)) |
428 | 3673 { |
3674 Lisp_Object tem; | |
3675 struct window *w = decode_window (window); | |
448 | 3676 int old_buffer_local_face_property = 0; |
428 | 3677 |
3678 buffer = Fget_buffer (buffer); | |
3679 CHECK_BUFFER (buffer); | |
3680 | |
3681 if (!BUFFER_LIVE_P (XBUFFER (buffer))) | |
563 | 3682 invalid_operation ("Attempt to display deleted buffer", Qunbound); |
428 | 3683 |
3684 tem = w->buffer; | |
3685 if (NILP (tem)) | |
563 | 3686 invalid_operation ("Window is deleted", Qunbound); |
428 | 3687 else if (EQ (tem, buffer)) |
3688 return Qnil; | |
3689 else if (! EQ (tem, Qt)) /* w->buffer is t when the window | |
3690 is first being set up. */ | |
3691 { | |
3692 if (!NILP (w->dedicated) && !EQ (tem, buffer)) | |
563 | 3693 signal_error (Qinvalid_operation, "Window is dedicated to buffer", tem); |
428 | 3694 |
448 | 3695 old_buffer_local_face_property = |
3696 XBUFFER (w->buffer)->buffer_local_face_property; | |
428 | 3697 unshow_buffer (w); |
3698 } | |
3699 | |
3700 w->buffer = buffer; | |
3701 w->window_end_pos[CURRENT_DISP] = 0; | |
3702 w->hscroll = 0; | |
3703 w->modeline_hscroll = 0; | |
844 | 3704 #if 0 /* pre point caches */ |
428 | 3705 Fset_marker (w->pointm[CURRENT_DISP], |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3706 make_fixnum (BUF_PT (XBUFFER (buffer))), |
428 | 3707 buffer); |
3708 set_marker_restricted (w->start[CURRENT_DISP], | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3709 make_fixnum (XBUFFER (buffer)->last_window_start), |
428 | 3710 buffer); |
844 | 3711 #else |
3712 { | |
3713 Lisp_Object marker = Fgethash (buffer, w->saved_point_cache, Qnil); | |
3714 Lisp_Object newpoint = | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3715 !NILP (marker) ? make_fixnum (marker_position (marker)) : |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3716 make_fixnum (BUF_PT (XBUFFER (buffer))); |
844 | 3717 /* Previously, we had in here set-window-point, which did one of the |
3718 following two, but not both. However, that could result in pointm | |
3719 being in a different buffer from the window's buffer! Probably | |
3720 not a travesty since it always occurred when the window was | |
3721 selected, meaning its value of point was ignored in favor of the | |
3722 buffer's; but it tripped an assert() in unshow_buffer(). */ | |
3723 set_marker_restricted (w->pointm[CURRENT_DISP], newpoint, buffer); | |
3724 if (EQ (wrap_window (w), Fselected_window (Qnil))) | |
3725 Fgoto_char (newpoint, buffer); /* this will automatically clip to | |
3726 accessible */ | |
3727 marker = Fgethash (buffer, w->saved_last_window_start_cache, Qnil); | |
3728 set_marker_restricted (w->start[CURRENT_DISP], | |
3729 !NILP (marker) ? | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3730 make_fixnum (marker_position (marker)) : |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3731 make_fixnum (XBUFFER (buffer)->last_window_start), |
844 | 3732 buffer); |
3733 } | |
3734 #endif | |
3735 | |
428 | 3736 Fset_marker (w->sb_point, w->start[CURRENT_DISP], buffer); |
3737 /* set start_at_line_beg correctly. GE */ | |
844 | 3738 w->start_at_line_beg = |
3739 beginning_of_line_p (XBUFFER (buffer), | |
3740 marker_position (w->start[CURRENT_DISP])); | |
3741 w->force_start = 0; /* XEmacs fix */ | |
428 | 3742 SET_LAST_MODIFIED (w, 1); |
3743 SET_LAST_FACECHANGE (w); | |
3744 MARK_WINDOWS_CHANGED (w); | |
448 | 3745 { |
3746 int new_buffer_local_face_property = | |
3747 XBUFFER (w->buffer)->buffer_local_face_property; | |
3748 | |
3749 if (new_buffer_local_face_property | |
3750 || new_buffer_local_face_property != old_buffer_local_face_property) | |
3751 MARK_WINDOW_FACES_CHANGED (w); | |
3752 } | |
428 | 3753 recompute_all_cached_specifiers_in_window (w); |
3754 if (EQ (window, Fselected_window (Qnil))) | |
3755 { | |
440 | 3756 if (NILP (norecord)) |
3757 Frecord_buffer (buffer); | |
3758 | |
428 | 3759 Fset_buffer (buffer); |
3760 } | |
5214
0b4d355771bd
Import buffer-display-count, buffer-display-time; thank you, Jeff Sparkes.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
3761 if (NILP (XBUFFER (buffer)->display_count)) |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3762 XBUFFER (buffer)->display_count = make_fixnum (1); |
5214
0b4d355771bd
Import buffer-display-count, buffer-display-time; thank you, Jeff Sparkes.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
3763 else |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3764 XBUFFER (buffer)->display_count = make_fixnum (1 + XFIXNUM (XBUFFER (buffer)->display_count)); |
5214
0b4d355771bd
Import buffer-display-count, buffer-display-time; thank you, Jeff Sparkes.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5191
diff
changeset
|
3765 XBUFFER (buffer)->display_time = Fcurrent_time(); |
428 | 3766 return Qnil; |
3767 } | |
3768 | |
3769 DEFUN ("select-window", Fselect_window, 1, 2, 0, /* | |
3770 Select WINDOW. Most editing will apply to WINDOW's buffer. | |
3771 The main editor command loop selects the buffer of the selected window | |
3772 before each command. | |
3773 | |
442 | 3774 With non-nil optional argument NORECORD, do not modify the |
428 | 3775 global or per-frame buffer ordering. |
3776 */ | |
3777 (window, norecord)) | |
3778 { | |
3779 struct window *w; | |
3780 Lisp_Object old_selected_window = Fselected_window (Qnil); | |
3781 | |
3782 CHECK_LIVE_WINDOW (window); | |
3783 w = XWINDOW (window); | |
3784 | |
3785 /* we have already caught dead-window errors */ | |
3786 if (!NILP (w->hchild) || !NILP (w->vchild)) | |
563 | 3787 invalid_operation ("Trying to select non-leaf window", Qunbound); |
428 | 3788 |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3789 w->use_time = make_fixnum (++window_select_count); |
442 | 3790 |
428 | 3791 if (EQ (window, old_selected_window)) |
3792 return window; | |
3793 | |
3794 /* deselect the old window, if it exists (it might not exist if | |
3795 the selected device has no frames, which occurs at startup) */ | |
3796 if (!NILP (old_selected_window)) | |
3797 { | |
3798 struct window *ow = XWINDOW (old_selected_window); | |
3799 | |
3800 Fset_marker (ow->pointm[CURRENT_DISP], | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3801 make_fixnum (BUF_PT (XBUFFER (ow->buffer))), |
428 | 3802 ow->buffer); |
3803 | |
3804 MARK_WINDOWS_CHANGED (ow); | |
3805 } | |
3806 | |
3807 /* now select the window's frame */ | |
3808 set_frame_selected_window (XFRAME (WINDOW_FRAME (w)), window); | |
3809 | |
3810 select_frame_1 (WINDOW_FRAME (w)); | |
3811 | |
3812 /* also select the window's buffer */ | |
3813 if (NILP (norecord)) | |
3814 Frecord_buffer (w->buffer); | |
3815 Fset_buffer (w->buffer); | |
3816 | |
3817 /* Go to the point recorded in the window. | |
3818 This is important when the buffer is in more | |
3819 than one window. It also matters when | |
3820 redisplay_window has altered point after scrolling, | |
3821 because it makes the change only in the window. */ | |
3822 { | |
665 | 3823 Charbpos new_point = marker_position (w->pointm[CURRENT_DISP]); |
428 | 3824 if (new_point < BUF_BEGV (current_buffer)) |
3825 new_point = BUF_BEGV (current_buffer); | |
3826 else if (new_point > BUF_ZV (current_buffer)) | |
3827 new_point = BUF_ZV (current_buffer); | |
3828 | |
3829 BUF_SET_PT (current_buffer, new_point); | |
3830 } | |
3831 | |
3832 MARK_WINDOWS_CHANGED (w); | |
3833 | |
3834 return window; | |
3835 } | |
3836 | |
3837 Lisp_Object | |
3838 display_buffer (Lisp_Object buffer, Lisp_Object not_this_window_p, | |
3839 Lisp_Object override_frame) | |
3840 { | |
3841 return call3 (Qdisplay_buffer, buffer, not_this_window_p, override_frame); | |
3842 } | |
3843 | |
3844 void | |
3845 temp_output_buffer_show (Lisp_Object buf, Lisp_Object same_frame) | |
3846 { | |
3847 /* This function can GC */ | |
3848 Lisp_Object window; | |
3849 struct window *w; | |
3850 struct buffer *b = XBUFFER (buf); | |
3851 | |
3852 BUF_SAVE_MODIFF (XBUFFER (buf)) = BUF_MODIFF (b); | |
3853 widen_buffer (b, 0); | |
3854 BUF_SET_PT (b, BUF_BEG (b)); | |
3855 | |
3856 if (!NILP (Vtemp_buffer_show_function)) | |
3857 call1 (Vtemp_buffer_show_function, buf); | |
3858 else | |
3859 { | |
3860 window = display_buffer (buf, Qnil, same_frame); | |
3861 | |
3862 if (!EQ (XWINDOW (window)->frame, Fselected_frame (Qnil))) | |
3863 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window))); | |
3864 | |
3865 Vminibuffer_scroll_window = window; | |
3866 w = XWINDOW (window); | |
3867 w->hscroll = 0; | |
3868 w->modeline_hscroll = 0; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3869 set_marker_restricted (w->start[CURRENT_DISP], make_fixnum (1), buf); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3870 set_marker_restricted (w->pointm[CURRENT_DISP], make_fixnum (1), buf); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3871 set_marker_restricted (w->sb_point, make_fixnum (1), buf); |
428 | 3872 } |
3873 } | |
3874 | |
3875 static void | |
3876 make_dummy_parent (Lisp_Object window) | |
3877 { | |
3878 struct window *o = XWINDOW (window); | |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5126
diff
changeset
|
3879 Lisp_Object obj = ALLOC_NORMAL_LISP_OBJECT (window); |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3078
diff
changeset
|
3880 struct window *p = XWINDOW (obj); |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3078
diff
changeset
|
3881 |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5126
diff
changeset
|
3882 copy_lisp_object (obj, window); |
428 | 3883 |
3884 /* Don't copy the pointers to the line start cache or the face | |
3885 instances. */ | |
3886 p->line_start_cache = Dynarr_new (line_start_cache); | |
3092 | 3887 #ifdef NEW_GC |
3888 p->face_cachels = Dynarr_lisp_new (face_cachel, | |
3889 &lrecord_face_cachel_dynarr, | |
3890 &lrecord_face_cachel); | |
3891 p->glyph_cachels = Dynarr_lisp_new (glyph_cachel, | |
3892 &lrecord_glyph_cachel_dynarr, | |
3893 &lrecord_glyph_cachel); | |
3894 #else /* not NEW_GC */ | |
428 | 3895 p->face_cachels = Dynarr_new (face_cachel); |
3896 p->glyph_cachels = Dynarr_new (glyph_cachel); | |
3092 | 3897 #endif /* not NEW_GC */ |
442 | 3898 p->subwindow_instance_cache = |
450 | 3899 make_image_instance_cache_hash_table (); |
428 | 3900 |
3901 /* Put new into window structure in place of window */ | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3078
diff
changeset
|
3902 replace_window (window, obj); |
428 | 3903 |
3904 o->next = Qnil; | |
3905 o->prev = Qnil; | |
3906 o->vchild = Qnil; | |
3907 o->hchild = Qnil; | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3078
diff
changeset
|
3908 o->parent = obj; |
428 | 3909 |
3910 p->start[CURRENT_DISP] = Qnil; | |
3911 p->start[DESIRED_DISP] = Qnil; | |
3912 p->start[CMOTION_DISP] = Qnil; | |
3913 p->pointm[CURRENT_DISP] = Qnil; | |
3914 p->pointm[DESIRED_DISP] = Qnil; | |
3915 p->pointm[CMOTION_DISP] = Qnil; | |
3916 p->sb_point = Qnil; | |
844 | 3917 p->saved_point_cache = make_saved_buffer_point_cache (); |
3918 p->saved_last_window_start_cache = make_saved_buffer_point_cache (); | |
428 | 3919 p->buffer = Qnil; |
3920 } | |
3921 | |
3922 DEFUN ("split-window", Fsplit_window, 0, 3, "", /* | |
3923 Split WINDOW, putting SIZE lines in the first of the pair. | |
444 | 3924 WINDOW defaults to the selected one and SIZE to half its size. |
707 | 3925 If optional third arg HORFLAG is non-nil, split side by side and put |
3926 SIZE columns in the first of the pair. The newly created window is | |
3927 returned. | |
428 | 3928 */ |
444 | 3929 (window, size, horflag)) |
428 | 3930 { |
3025 | 3931 Lisp_Object new_; |
428 | 3932 struct window *o, *p; |
3933 struct frame *f; | |
444 | 3934 int csize; |
428 | 3935 int psize; |
3936 | |
3937 if (NILP (window)) | |
3938 window = Fselected_window (Qnil); | |
3939 else | |
3940 CHECK_LIVE_WINDOW (window); | |
3941 | |
3942 o = XWINDOW (window); | |
3943 f = XFRAME (WINDOW_FRAME (o)); | |
3944 | |
444 | 3945 if (NILP (size)) |
428 | 3946 { |
3947 if (!NILP (horflag)) | |
3948 /* In the new scheme, we are symmetric with respect to separators | |
3949 so there is no need to do weird things here. */ | |
3950 { | |
956 | 3951 psize = (WINDOW_WIDTH (o) + window_divider_width (o)) >> 1; |
444 | 3952 csize = window_pixel_width_to_char_width (o, psize, 0); |
428 | 3953 } |
3954 else | |
3955 { | |
3956 psize = WINDOW_HEIGHT (o) >> 1; | |
444 | 3957 csize = window_pixel_height_to_char_height (o, psize, 1); |
428 | 3958 } |
3959 } | |
3960 else | |
3961 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3962 CHECK_FIXNUM (size); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3963 csize = XFIXNUM (size); |
428 | 3964 if (!NILP (horflag)) |
444 | 3965 psize = window_char_width_to_pixel_width (o, csize, 0); |
428 | 3966 else |
444 | 3967 psize = window_char_height_to_pixel_height (o, csize, 1); |
428 | 3968 } |
3969 | |
3970 if (MINI_WINDOW_P (o)) | |
563 | 3971 invalid_operation ("Attempt to split minibuffer window", Qunbound); |
428 | 3972 else if (FRAME_NO_SPLIT_P (XFRAME (WINDOW_FRAME (o)))) |
563 | 3973 invalid_operation ("Attempt to split unsplittable frame", Qunbound); |
428 | 3974 |
3975 check_min_window_sizes (); | |
3976 | |
3977 if (NILP (horflag)) | |
3978 { | |
444 | 3979 if (csize < window_min_height) |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3980 signal_error (Qinvalid_operation, "Window height too small (after splitting)", make_fixnum (csize)); |
444 | 3981 if (csize + window_min_height > window_char_height (o, 1)) |
563 | 3982 signal_error (Qinvalid_operation, "Window height too small (after splitting)", |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
3983 make_fixnum (window_char_height (o, 1) - csize)); |
428 | 3984 if (NILP (o->parent) |
3985 || NILP (XWINDOW (o->parent)->vchild)) | |
3986 { | |
3987 make_dummy_parent (window); | |
448 | 3988 #if 0 |
3989 /* #### I can't understand why you have to reset face | |
3990 cachels here. This can cause crash so let's disable it | |
3991 and see the difference. See redisplay-tests.el --yh */ | |
428 | 3992 reset_face_cachels (XWINDOW (window)); |
448 | 3993 #endif |
3025 | 3994 new_ = o->parent; |
3995 XWINDOW (new_)->vchild = window; | |
428 | 3996 XFRAME (o->frame)->mirror_dirty = 1; |
3997 } | |
3998 } | |
3999 else | |
4000 { | |
444 | 4001 if (csize < window_min_width) |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4002 signal_error (Qinvalid_operation, "Window width too small (after splitting)", make_fixnum (csize)); |
444 | 4003 if (csize + window_min_width > window_char_width (o, 0)) |
563 | 4004 signal_error (Qinvalid_operation, "Window width too small (after splitting)", |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4005 make_fixnum (window_char_width (o, 0) - csize)); |
428 | 4006 if (NILP (o->parent) |
4007 || NILP (XWINDOW (o->parent)->hchild)) | |
4008 { | |
4009 make_dummy_parent (window); | |
448 | 4010 #if 0 |
4011 /* #### See above. */ | |
428 | 4012 reset_face_cachels (XWINDOW (window)); |
448 | 4013 #endif |
3025 | 4014 new_ = o->parent; |
4015 XWINDOW (new_)->hchild = window; | |
428 | 4016 XFRAME (o->frame)->mirror_dirty = 1; |
4017 } | |
4018 } | |
4019 | |
4020 /* Now we know that window's parent is a vertical combination | |
4021 if we are dividing vertically, or a horizontal combination | |
4022 if we are making side-by-side windows */ | |
4023 | |
4024 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f); | |
3025 | 4025 new_ = allocate_window (); |
4026 p = XWINDOW (new_); | |
428 | 4027 |
4028 p->frame = o->frame; | |
4029 p->next = o->next; | |
4030 if (!NILP (p->next)) | |
3025 | 4031 XWINDOW (p->next)->prev = new_; |
428 | 4032 p->prev = window; |
3025 | 4033 o->next = new_; |
428 | 4034 p->parent = o->parent; |
4035 p->buffer = Qt; | |
4036 | |
4037 reset_face_cachels (p); | |
4038 reset_glyph_cachels (p); | |
4039 | |
4040 | |
4041 /* Apportion the available frame space among the two new windows */ | |
4042 | |
4043 if (!NILP (horflag)) | |
4044 { | |
4045 WINDOW_HEIGHT (p) = WINDOW_HEIGHT (o); | |
4046 WINDOW_TOP (p) = WINDOW_TOP (o); | |
4047 WINDOW_WIDTH (p) = WINDOW_WIDTH (o) - psize; | |
4048 WINDOW_WIDTH (o) = psize; | |
4049 WINDOW_LEFT (p) = WINDOW_LEFT (o) + psize; | |
4050 } | |
4051 else | |
4052 { | |
4053 WINDOW_LEFT (p) = WINDOW_LEFT (o); | |
4054 WINDOW_WIDTH (p) = WINDOW_WIDTH (o); | |
4055 WINDOW_HEIGHT (p) = WINDOW_HEIGHT (o) - psize; | |
4056 WINDOW_HEIGHT (o) = psize; | |
4057 WINDOW_TOP (p) = WINDOW_TOP (o) + psize; | |
4058 } | |
4059 | |
4060 XFRAME (p->frame)->mirror_dirty = 1; | |
853 | 4061 |
3025 | 4062 note_object_created (new_); |
853 | 4063 |
428 | 4064 /* do this last (after the window is completely initialized and |
4065 the mirror-dirty flag is set) so that specifier recomputation | |
4066 caused as a result of this will work properly and not abort. */ | |
3025 | 4067 Fset_window_buffer (new_, o->buffer, Qt); |
4068 return new_; | |
428 | 4069 } |
4070 | |
4071 | |
4072 DEFUN ("enlarge-window", Fenlarge_window, 1, 3, "_p", /* | |
444 | 4073 Make the selected window COUNT lines taller. |
4074 From program, optional second arg HORIZONTALP non-nil means grow | |
4075 sideways COUNT columns, and optional third arg WINDOW specifies the | |
4076 window to change instead of the selected window. | |
428 | 4077 */ |
444 | 4078 (count, horizontalp, window)) |
4079 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4080 CHECK_FIXNUM (count); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4081 change_window_height (window, XFIXNUM (count), horizontalp, /* inpixels */ 0); |
428 | 4082 return Qnil; |
4083 } | |
4084 | |
4085 DEFUN ("enlarge-window-pixels", Fenlarge_window_pixels, 1, 3, "_p", /* | |
444 | 4086 Make the selected window COUNT pixels taller. |
4087 From program, optional second arg HORIZONTALP non-nil means grow | |
4088 sideways COUNT pixels, and optional third arg WINDOW specifies the | |
4089 window to change instead of the selected window. | |
428 | 4090 */ |
444 | 4091 (count, horizontalp, window)) |
4092 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4093 CHECK_FIXNUM (count); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4094 change_window_height (window, XFIXNUM (count), horizontalp, /* inpixels */ 1); |
428 | 4095 return Qnil; |
4096 } | |
4097 | |
4098 DEFUN ("shrink-window", Fshrink_window, 1, 3, "_p", /* | |
444 | 4099 Make the selected window COUNT lines shorter. |
4100 From program, optional second arg HORIZONTALP non-nil means shrink | |
4101 sideways COUNT columns, and optional third arg WINDOW specifies the | |
4102 window to change instead of the selected window. | |
428 | 4103 */ |
444 | 4104 (count, horizontalp, window)) |
4105 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4106 CHECK_FIXNUM (count); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4107 change_window_height (window, -XFIXNUM (count), horizontalp, /* inpixels */ 0); |
428 | 4108 return Qnil; |
4109 } | |
4110 | |
4111 DEFUN ("shrink-window-pixels", Fshrink_window_pixels, 1, 3, "_p", /* | |
444 | 4112 Make the selected window COUNT pixels smaller. |
4113 From program, optional second arg HORIZONTALP non-nil means shrink | |
4114 sideways COUNT pixels, and optional third arg WINDOW specifies the | |
4115 window to change instead of the selected window. | |
428 | 4116 */ |
444 | 4117 (count, horizontalp, window)) |
4118 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4119 CHECK_FIXNUM (count); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4120 change_window_height (window, -XFIXNUM (count), horizontalp, /* inpixels */ 1); |
428 | 4121 return Qnil; |
4122 } | |
4123 | |
4124 static int | |
4125 window_pixel_height_to_char_height (struct window *w, int pixel_height, | |
4126 int include_gutters_p) | |
4127 { | |
4128 int avail_height; | |
4129 int defheight, defwidth; | |
3687 | 4130 int char_height = 0; |
793 | 4131 Lisp_Object window = wrap_window (w); |
4132 | |
428 | 4133 |
4134 avail_height = (pixel_height - | |
4135 (include_gutters_p ? 0 : | |
442 | 4136 window_top_window_gutter_height (w) + |
4137 window_bottom_window_gutter_height (w))); | |
428 | 4138 |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
4139 default_face_width_and_height (window, &defwidth, &defheight); |
428 | 4140 |
3687 | 4141 if (defheight) |
4142 char_height = avail_height / defheight; | |
428 | 4143 |
4144 /* It's the calling function's responsibility to check these values | |
4145 and make sure they're not out of range. | |
4146 | |
4147 #### We need to go through the calling functions and actually | |
4148 do this. */ | |
4149 return max (0, char_height); | |
4150 } | |
4151 | |
4152 static int | |
4153 window_char_height_to_pixel_height (struct window *w, int char_height, | |
4154 int include_gutters_p) | |
4155 { | |
4156 int avail_height; | |
4157 int defheight, defwidth; | |
4158 int pixel_height; | |
4159 | |
793 | 4160 Lisp_Object window = wrap_window (w); |
4161 | |
428 | 4162 |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
4163 default_face_width_and_height (window, &defwidth, &defheight); |
428 | 4164 |
4165 avail_height = char_height * defheight; | |
4166 pixel_height = (avail_height + | |
4167 (include_gutters_p ? 0 : | |
442 | 4168 window_top_window_gutter_height (w) + |
4169 window_bottom_window_gutter_height (w))); | |
428 | 4170 |
4171 /* It's the calling function's responsibility to check these values | |
4172 and make sure they're not out of range. | |
4173 | |
4174 #### We need to go through the calling functions and actually | |
4175 do this. */ | |
4176 return max (0, pixel_height); | |
4177 } | |
4178 | |
4179 /* Return number of default lines of text can fit in the window W. | |
4180 If INCLUDE_GUTTERS_P is 1, include "gutter" space (modeline plus | |
4181 horizontal scrollbar) in the space that is used for the calculation. | |
442 | 4182 This doesn't include space used by the frame gutters. |
428 | 4183 */ |
4184 int | |
4185 window_char_height (struct window *w, int include_gutters_p) | |
4186 { | |
442 | 4187 return window_pixel_height_to_char_height (w, window_pixel_height (w), |
428 | 4188 include_gutters_p); |
4189 } | |
4190 | |
4191 /* | |
4192 * Return number of lines currently displayed in window w. If | |
4193 * end-of-buffer is displayed then the area below end-of-buffer is assume | |
4194 * to be blank lines of default height. | |
4195 * Does not include the modeline. | |
4196 */ | |
4197 int | |
4198 window_displayed_height (struct window *w) | |
4199 { | |
4200 struct buffer *b = XBUFFER (w->buffer); | |
4201 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP); | |
4202 int num_lines; | |
4203 Charcount end_pos = (BUF_Z (b) - w->window_end_pos[CURRENT_DISP] > BUF_ZV (b) | |
4204 ? -1 | |
4205 : w->window_end_pos[CURRENT_DISP]); | |
4206 | |
4207 if (!Dynarr_length (dla)) | |
4208 return window_char_height (w, 0); | |
4209 | |
4210 num_lines = Dynarr_length (dla); | |
4211 | |
4212 /* #### Document and assert somewhere that w->window_end_pos == -1 | |
4213 indicates that end-of-buffer is being displayed. */ | |
4214 if (end_pos == -1) | |
4215 { | |
4967 | 4216 struct display_line *dl = Dynarr_begin (dla); |
428 | 4217 int ypos1 = dl->ypos + dl->descent; |
4218 int ypos2 = WINDOW_TEXT_BOTTOM (w); | |
4219 Lisp_Object window; | |
4220 int defheight, defwidth; | |
4221 | |
793 | 4222 window = wrap_window (w); |
428 | 4223 |
4224 if (dl->modeline) | |
4225 { | |
4226 num_lines--; | |
4227 | |
4228 if (Dynarr_length (dla) == 1) | |
4229 ypos1 = WINDOW_TEXT_TOP (w); | |
4230 else | |
4231 { | |
4232 dl = Dynarr_atp (dla, Dynarr_length (dla) - 1); | |
4233 /* If this line is clipped then we know that there is no | |
4234 blank room between eob and the modeline. If we are | |
4235 scrolling on clipped lines just know off the clipped | |
4236 line and return .*/ | |
4237 if (scroll_on_clipped_lines && dl->clip) | |
4238 return num_lines - 1; | |
4239 ypos1 = dl->ypos + dl->descent - dl->clip; | |
4240 } | |
4241 } | |
4242 | |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
4243 default_face_width_and_height (window, &defwidth, &defheight); |
428 | 4244 /* #### This probably needs to know about the clipping area once a |
4245 final definition is decided on. */ | |
3707 | 4246 if (defheight) |
4247 num_lines += ((ypos2 - ypos1) / defheight); | |
428 | 4248 } |
4249 else | |
4250 { | |
4967 | 4251 if (num_lines > 1 && Dynarr_begin (dla)->modeline) |
428 | 4252 num_lines--; |
4253 | |
4254 if (scroll_on_clipped_lines | |
4255 && Dynarr_atp (dla, Dynarr_length (dla) - 1)->clip) | |
4256 num_lines--; | |
4257 } | |
4258 | |
4259 return num_lines; | |
4260 } | |
4261 | |
4262 static int | |
4263 window_pixel_width (Lisp_Object window) | |
4264 { | |
4265 return WINDOW_WIDTH (XWINDOW (window)); | |
4266 } | |
4267 | |
442 | 4268 /* Calculate the pixel of a window, optionally including margin space |
4269 but no vertical gutters. */ | |
428 | 4270 static int |
4271 window_pixel_width_to_char_width (struct window *w, int pixel_width, | |
4272 int include_margins_p) | |
4273 { | |
4274 int avail_width; | |
3676 | 4275 int char_width = 0; |
428 | 4276 int defheight, defwidth; |
793 | 4277 Lisp_Object window = wrap_window (w); |
4278 | |
428 | 4279 |
4280 avail_width = (pixel_width - | |
4281 window_left_gutter_width (w, 0) - | |
4282 window_right_gutter_width (w, 0) - | |
4283 (include_margins_p ? 0 : window_left_margin_width (w)) - | |
4284 (include_margins_p ? 0 : window_right_margin_width (w))); | |
4285 | |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
4286 default_face_width_and_height (window, &defwidth, &defheight); |
428 | 4287 |
3676 | 4288 if (defwidth) |
4289 char_width = (avail_width / defwidth); | |
428 | 4290 |
4291 /* It's the calling function's responsibility to check these values | |
4292 and make sure they're not out of range. | |
4293 | |
4294 #### We need to go through the calling functions and actually | |
4295 do this. */ | |
4296 return max (0, char_width); | |
4297 } | |
4298 | |
4299 static int | |
4300 window_char_width_to_pixel_width (struct window *w, int char_width, | |
4301 int include_margins_p) | |
4302 { | |
4303 int avail_width; | |
4304 int pixel_width; | |
4305 int defheight, defwidth; | |
793 | 4306 Lisp_Object window = wrap_window (w); |
4307 | |
428 | 4308 |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
4309 default_face_width_and_height (window, &defwidth, &defheight); |
428 | 4310 |
4311 avail_width = char_width * defwidth; | |
4312 pixel_width = (avail_width + | |
442 | 4313 window_left_window_gutter_width (w, 0) + |
4314 window_right_window_gutter_width (w, 0) + | |
428 | 4315 (include_margins_p ? 0 : window_left_margin_width (w)) + |
4316 (include_margins_p ? 0 : window_right_margin_width (w))); | |
4317 | |
4318 /* It's the calling function's responsibility to check these values | |
4319 and make sure they're not out of range. | |
4320 | |
4321 #### We need to go through the calling functions and actually | |
4322 do this. */ | |
4323 return max (0, pixel_width); | |
4324 } | |
4325 | |
4326 /* This returns the usable space which doesn't include space needed by | |
4327 scrollbars or divider lines. */ | |
4328 int | |
4329 window_char_width (struct window *w, int include_margins_p) | |
4330 { | |
4331 return window_pixel_width_to_char_width (w, WINDOW_WIDTH (w), | |
4332 include_margins_p); | |
4333 } | |
4334 | |
4335 #define MINSIZE(w) \ | |
4336 (widthflag \ | |
4337 ? window_min_width * defwidth \ | |
4338 : (defheight * (MINI_WINDOW_P (XWINDOW (w)) ? 1 : window_min_height))) | |
4339 | |
4340 #define CURBEG(w) \ | |
4341 *(widthflag ? (int *) &WINDOW_LEFT (w) : (int *) &WINDOW_TOP (w)) | |
4342 | |
4343 #define CURSIZE(w) \ | |
4344 *(widthflag ? (int *) &WINDOW_WIDTH (w) : (int *) &WINDOW_HEIGHT (w)) | |
4345 | |
4346 #define CURCHARSIZE(w) \ | |
4347 (widthflag ? window_char_width (w, 0) : window_char_height (w, 1)) | |
4348 | |
4349 #define MINCHARSIZE(window) \ | |
4350 (widthflag ? window_min_width : MINI_WINDOW_P (XWINDOW (window)) \ | |
4351 ? 1 : window_min_height) | |
4352 | |
442 | 4353 static int |
4354 window_pixheight (Lisp_Object w) | |
4355 { | |
4356 return window_pixel_height (XWINDOW (w)); | |
4357 } | |
4358 | |
428 | 4359 /* Unlike set_window_pixheight, this function |
4360 also changes the heights of the siblings so as to | |
4361 keep everything consistent. */ | |
4362 | |
4363 static void | |
444 | 4364 change_window_height (Lisp_Object window, int delta, Lisp_Object horizontalp, |
428 | 4365 int inpixels) |
4366 { | |
444 | 4367 struct window *win = decode_window (window); |
4368 int widthflag = !NILP (horizontalp); | |
428 | 4369 Lisp_Object parent; |
4370 struct window *w; | |
4371 struct frame *f; | |
4372 int *sizep; | |
4373 int (*sizefun) (Lisp_Object) = (widthflag | |
4374 ? window_pixel_width | |
442 | 4375 : window_pixheight); |
428 | 4376 void (*setsizefun) (Lisp_Object, int, int) = (widthflag |
4377 ? set_window_pixwidth | |
4378 : set_window_pixheight); | |
4379 int dim; | |
4380 int defheight, defwidth; | |
4381 | |
4382 if (delta == 0) | |
4383 return; | |
4384 | |
4385 check_min_window_sizes (); | |
4386 | |
793 | 4387 window = wrap_window (win); |
428 | 4388 f = XFRAME (win->frame); |
4389 if (EQ (window, FRAME_ROOT_WINDOW (f))) | |
563 | 4390 invalid_operation ("Won't change only window", Qunbound); |
428 | 4391 |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
4392 default_face_width_and_height (window, &defwidth, &defheight); |
428 | 4393 |
4394 while (1) | |
4395 { | |
4396 w = XWINDOW (window); | |
4397 parent = w->parent; | |
4398 if (NILP (parent)) | |
4399 { | |
4400 if (widthflag) | |
3078 | 4401 { |
4402 int new_pixsize; | |
4403 sizep = &CURSIZE (w); | |
3466 | 4404 dim = CURCHARSIZE (w); |
3078 | 4405 new_pixsize = inpixels?(*sizep + delta):(dim+delta); |
4406 set_window_pixsize (window, new_pixsize, 0, 0); | |
4407 return; | |
4408 } | |
428 | 4409 break; |
4410 } | |
4411 if (widthflag | |
4412 ? !NILP (XWINDOW (parent)->hchild) | |
4413 : !NILP (XWINDOW (parent)->vchild)) | |
4414 break; | |
4415 window = parent; | |
4416 } | |
4417 | |
4418 sizep = &CURSIZE (w); | |
4419 dim = CURCHARSIZE (w); | |
4420 | |
4421 if ((inpixels && (*sizep + delta) < MINSIZE (window)) || | |
4422 (!inpixels && (dim + delta) < MINCHARSIZE (window))) | |
4423 { | |
4424 if (MINI_WINDOW_P (XWINDOW (window))) | |
4425 return; | |
4426 else if (!NILP (parent)) | |
4427 { | |
4428 Fdelete_window (window, Qnil); | |
4429 return; | |
4430 } | |
4431 } | |
4432 | |
4433 if (!inpixels) | |
4434 delta *= (widthflag ? defwidth : defheight); | |
4435 | |
4436 { | |
4437 int maxdelta; | |
4438 | |
4439 maxdelta = ((!NILP (parent)) | |
4440 ? (*sizefun) (parent) - *sizep | |
4441 : ((!NILP (w->next)) | |
4442 ? (*sizefun) (w->next) - MINSIZE (w->next) | |
4443 : ((!NILP (w->prev)) | |
4444 ? (*sizefun) (w->prev) - MINSIZE (w->prev) | |
4445 /* This is a frame with only one window, | |
4446 a minibuffer-only or a minibufferless frame. */ | |
4447 : (delta = 0)))); | |
4448 | |
4449 if (delta > maxdelta) | |
4450 /* This case traps trying to make the minibuffer | |
4451 the full frame, or make the only window aside from the | |
4452 minibuffer the full frame. */ | |
4453 delta = maxdelta; | |
4454 | |
4455 if (delta == 0) | |
4456 return; | |
4457 | |
4458 #if 0 /* FSFmacs */ | |
4459 /* #### Chuck: is this correct? */ | |
4460 if (*sizep + delta < MINSIZE (window)) | |
4461 { | |
4462 Fdelete_window (window); | |
4463 return; | |
4464 } | |
4465 #endif | |
4466 } | |
4467 | |
4468 if (!NILP (w->next) && | |
4469 (*sizefun) (w->next) - delta >= (int) MINSIZE (w->next)) | |
4470 { | |
4471 CURBEG (XWINDOW (w->next)) += delta; | |
4472 (*setsizefun) (w->next, (*sizefun) (w->next) - delta, 0); | |
4473 (*setsizefun) (window, *sizep + delta, 0); | |
4474 } | |
4475 else if (!NILP (w->prev) && | |
4476 (*sizefun) (w->prev) - delta >= (int) MINSIZE (w->prev)) | |
4477 { | |
4478 (*setsizefun) (w->prev, (*sizefun) (w->prev) - delta, 0); | |
4479 CURBEG (w) -= delta; | |
4480 (*setsizefun) (window, *sizep + delta, 0); | |
4481 } | |
4482 else | |
4483 { | |
4484 int delta1; | |
4485 int opht = (*sizefun) (parent); | |
4486 | |
4487 /* If trying to grow this window to or beyond size of the parent, | |
4488 make delta1 so big that, on shrinking back down, | |
4489 all the siblings end up with less than one line and are deleted. */ | |
4490 if (opht <= *sizep + delta) | |
4491 delta1 = opht * opht * 2; | |
4492 /* Otherwise, make delta1 just right so that if we add delta1 | |
4493 lines to this window and to the parent, and then shrink | |
4494 the parent back to its original size, the new proportional | |
4495 size of this window will increase by delta. */ | |
4496 else | |
4497 delta1 = (delta * opht * 100) / ((opht - *sizep - delta) * 100); | |
4498 | |
4499 /* Add delta1 lines or columns to this window, and to the parent, | |
4500 keeping things consistent while not affecting siblings. */ | |
4501 CURSIZE (XWINDOW (parent)) = opht + delta1; | |
4502 (*setsizefun) (window, *sizep + delta1, 0); | |
4503 | |
4504 /* Squeeze out delta1 lines or columns from our parent, | |
4505 shrinking this window and siblings proportionately. | |
4506 This brings parent back to correct size. | |
4507 Delta1 was calculated so this makes this window the desired size, | |
4508 taking it all out of the siblings. */ | |
4509 (*setsizefun) (parent, opht, 0); | |
4510 } | |
4511 | |
4512 SET_LAST_MODIFIED (w, 0); | |
4513 SET_LAST_FACECHANGE (w); | |
4514 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f); | |
4515 /* overkill maybe, but better to be correct */ | |
4516 MARK_FRAME_GUTTERS_CHANGED (f); | |
4517 } | |
4518 #undef MINSIZE | |
4519 #undef CURBEG | |
4520 #undef CURSIZE | |
4521 #undef CURCHARSIZE | |
4522 #undef MINCHARSIZE | |
4523 | |
4524 | |
4525 | |
444 | 4526 /* Scroll contents of window WINDOW up COUNT lines. |
4527 If COUNT < (top line height / average line height) then we just adjust | |
4528 the top clip. */ | |
428 | 4529 void |
444 | 4530 window_scroll (Lisp_Object window, Lisp_Object count, int direction, |
578 | 4531 Error_Behavior errb) |
428 | 4532 { |
4533 struct window *w = XWINDOW (window); | |
4534 struct buffer *b = XBUFFER (w->buffer); | |
4535 int selected = EQ (window, Fselected_window (Qnil)); | |
4536 int value = 0; | |
4537 Lisp_Object point, tem; | |
4538 display_line_dynarr *dla; | |
4539 int fheight, fwidth, modeline = 0; | |
4540 struct display_line* dl; | |
4541 | |
4542 if (selected) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4543 point = make_fixnum (BUF_PT (b)); |
428 | 4544 else |
4545 { | |
665 | 4546 Charbpos pos = marker_position (w->pointm[CURRENT_DISP]); |
428 | 4547 |
4548 if (pos < BUF_BEGV (b)) | |
4549 pos = BUF_BEGV (b); | |
4550 else if (pos > BUF_ZV (b)) | |
4551 pos = BUF_ZV (b); | |
4552 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4553 point = make_fixnum (pos); |
428 | 4554 } |
4555 | |
4556 /* Always set force_start so that redisplay_window will run | |
4557 the window-scroll-functions. */ | |
4558 w->force_start = 1; | |
4559 | |
4560 /* #### When the fuck does this happen? I'm so glad that history has | |
4561 completely documented the behavior of the scrolling functions under | |
4562 all circumstances. */ | |
1708 | 4563 tem = Fpos_visible_in_window_p (point, window, Qnil); |
428 | 4564 if (NILP (tem)) |
4565 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4566 Fvertical_motion (make_fixnum (-window_char_height (w, 0) / 2), |
428 | 4567 window, Qnil); |
4568 Fset_marker (w->start[CURRENT_DISP], point, w->buffer); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4569 w->start_at_line_beg = beginning_of_line_p (b, XFIXNUM (point)); |
428 | 4570 WINDOW_TEXT_TOP_CLIP (w) = 0; |
4571 MARK_WINDOWS_CHANGED (w); | |
4572 } | |
4573 | |
444 | 4574 if (!NILP (count)) |
428 | 4575 { |
444 | 4576 if (EQ (count, Qminus)) |
428 | 4577 direction *= -1; |
4578 else | |
4579 { | |
444 | 4580 count = Fprefix_numeric_value (count); |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4581 value = XFIXNUM (count) * direction; |
428 | 4582 |
4583 if (!value) | |
4584 return; /* someone just made a pointless call */ | |
4585 } | |
4586 } | |
4587 | |
4588 /* If the user didn't specify how far to scroll then we have to figure it | |
4589 out by ourselves. */ | |
444 | 4590 if (NILP (count) || EQ (count, Qminus)) |
428 | 4591 { |
4592 /* Going forwards is easy. If that is what we are doing then just | |
4593 set value and the section which handles the user specifying a | |
4594 positive value will work. */ | |
4595 if (direction == 1) | |
4596 { | |
4597 value = window_displayed_height (w) - next_screen_context_lines; | |
4598 value = (value < 1 ? 1 : value); | |
4599 } | |
4600 | |
4601 /* Going backwards is hard. We can't use the same loop used if the | |
4602 user specified a negative value because we care about | |
4603 next_screen_context_lines. In a variable height world you don't | |
4604 know how many lines above you can actually be displayed and still | |
4605 have the context lines appear. So we leave value set to 0 and add | |
4606 a separate section to deal with this. */ | |
4607 | |
4608 } | |
4609 | |
4610 if (direction == 1 && !value) | |
4611 { | |
4612 return; | |
4613 } | |
4614 | |
4615 /* Determine parameters to test for partial line scrolling with. */ | |
4616 dla = window_display_lines (w, CURRENT_DISP); | |
4617 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4618 if (FIXNUMP (Vwindow_pixel_scroll_increment)) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4619 fheight = XFIXNUM (Vwindow_pixel_scroll_increment); |
440 | 4620 else if (!NILP (Vwindow_pixel_scroll_increment)) |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
4621 default_face_width_and_height (window, &fwidth, &fheight); |
438 | 4622 |
428 | 4623 if (Dynarr_length (dla) >= 1) |
4967 | 4624 modeline = Dynarr_begin (dla)->modeline; |
428 | 4625 |
4626 dl = Dynarr_atp (dla, modeline); | |
438 | 4627 |
428 | 4628 if (value > 0) |
4629 { | |
4630 /* Go for partial display line scrolling. This just means bumping | |
4631 the clip by a reasonable amount and redisplaying, everything else | |
4632 remains unchanged. */ | |
4633 if (!NILP (Vwindow_pixel_scroll_increment) | |
4634 && | |
4635 Dynarr_length (dla) >= (1 + modeline) | |
4636 && | |
458 | 4637 (dl->ascent - dl->top_clip) > fheight * value) |
428 | 4638 { |
4639 WINDOW_TEXT_TOP_CLIP (w) += value * fheight; | |
4640 MARK_WINDOWS_CHANGED (w); | |
4641 } | |
4642 else | |
4643 { | |
4644 int vtarget; | |
665 | 4645 Charbpos startp, old_start; |
438 | 4646 |
428 | 4647 if (WINDOW_TEXT_TOP_CLIP (w)) |
4648 { | |
4649 WINDOW_TEXT_TOP_CLIP (w) = 0; | |
4650 MARK_WINDOWS_CHANGED (w); | |
4651 } | |
4652 | |
4653 old_start = marker_position (w->start[CURRENT_DISP]); | |
4654 startp = vmotion (w, old_start, value, &vtarget); | |
438 | 4655 |
428 | 4656 if (vtarget < value && |
4657 (w->window_end_pos[CURRENT_DISP] == -1 | |
4658 || (BUF_Z (b) - w->window_end_pos[CURRENT_DISP] > BUF_ZV (b)))) | |
4659 { | |
563 | 4660 maybe_signal_error_1 (Qend_of_buffer, Qnil, Qwindow, errb); |
428 | 4661 return; |
4662 } | |
4663 else | |
4664 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4665 set_marker_restricted (w->start[CURRENT_DISP], make_fixnum (startp), |
428 | 4666 w->buffer); |
4667 w->force_start = 1; | |
4668 w->start_at_line_beg = beginning_of_line_p (b, startp); | |
4669 MARK_WINDOWS_CHANGED (w); | |
438 | 4670 |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4671 if (!point_would_be_visible (w, startp, XFIXNUM (point), 0)) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4672 Fset_window_point (wrap_window (w), make_fixnum (startp)); |
428 | 4673 } |
4674 } | |
4675 } | |
4676 else if (value < 0) | |
4677 { | |
4678 /* Go for partial display line scrolling. This just means bumping | |
4679 the clip by a reasonable amount and redisplaying, everything else | |
4680 remains unchanged. */ | |
4681 if (!NILP (Vwindow_pixel_scroll_increment) | |
4682 && | |
4683 Dynarr_length (dla) >= (1 + modeline) | |
4684 && | |
4685 (dl->ascent - dl->top_clip) - fheight * value < | |
4686 (dl->ascent + dl->descent - dl->clip) | |
4687 && | |
4688 WINDOW_TEXT_TOP_CLIP (w) + value * fheight > 0) | |
4689 { | |
4690 WINDOW_TEXT_TOP_CLIP (w) += value * fheight; | |
4691 MARK_WINDOWS_CHANGED (w); | |
4692 } | |
4693 else | |
4694 { | |
4695 int vtarget; | |
665 | 4696 Charbpos startp, old_start; |
438 | 4697 |
428 | 4698 if (WINDOW_TEXT_TOP_CLIP (w)) |
4699 { | |
4700 WINDOW_TEXT_TOP_CLIP (w) = 0; | |
4701 MARK_WINDOWS_CHANGED (w); | |
4702 } | |
438 | 4703 |
428 | 4704 old_start = marker_position (w->start[CURRENT_DISP]); |
4705 startp = vmotion (w, old_start, value, &vtarget); | |
438 | 4706 |
428 | 4707 if (vtarget > value |
4708 && marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b)) | |
4709 { | |
563 | 4710 maybe_signal_error_1 (Qbeginning_of_buffer, Qnil, Qwindow, errb); |
428 | 4711 return; |
4712 } | |
4713 else | |
4714 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4715 set_marker_restricted (w->start[CURRENT_DISP], make_fixnum (startp), |
428 | 4716 w->buffer); |
4717 w->force_start = 1; | |
4718 w->start_at_line_beg = beginning_of_line_p (b, startp); | |
4719 MARK_WINDOWS_CHANGED (w); | |
438 | 4720 |
440 | 4721 /* #### Scroll back by less than a line. This code was |
4722 originally for scrolling over large pixmaps and it | |
4723 loses when a line being *exposed* at the top of the | |
4724 window is bigger than the current one. However, for | |
4725 pixel based scrolling in general we can guess that | |
4726 the line we are going to display is probably the same | |
4727 size as the one we are on. In that instance we can | |
4728 have a reasonable stab at a suitable top clip. Fixing | |
4729 this properly is hard (and probably slow) as we would | |
4730 have to call redisplay to figure out the exposed line | |
4731 size. */ | |
4732 if (!NILP (Vwindow_pixel_scroll_increment) | |
4733 && Dynarr_length (dla) >= (1 + modeline) | |
4734 && dl->ascent + fheight * value > 0) | |
4735 { | |
4736 WINDOW_TEXT_TOP_CLIP (w) = (dl->ascent + fheight * value); | |
4737 } | |
4738 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4739 if (!point_would_be_visible (w, startp, XFIXNUM (point), 0)) |
428 | 4740 { |
665 | 4741 Charbpos new_point; |
438 | 4742 |
428 | 4743 if (MINI_WINDOW_P (w)) |
4744 new_point = startp; | |
4745 else | |
4746 new_point = start_of_last_line (w, startp); | |
438 | 4747 |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4748 Fset_window_point (wrap_window (w), make_fixnum (new_point)); |
428 | 4749 } |
4750 } | |
4751 } | |
4752 } | |
4753 else /* value == 0 && direction == -1 */ | |
4754 { | |
4755 if (WINDOW_TEXT_TOP_CLIP (w)) | |
4756 { | |
4757 WINDOW_TEXT_TOP_CLIP (w) = 0; | |
4758 MARK_WINDOWS_CHANGED (w); | |
4759 } | |
4760 if (marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b)) | |
4761 { | |
563 | 4762 maybe_signal_error_1 (Qbeginning_of_buffer, Qnil, Qwindow, errb); |
428 | 4763 return; |
4764 } | |
4765 else | |
4766 { | |
4767 int vtarget; | |
4768 int movement = next_screen_context_lines - 1; | |
665 | 4769 Charbpos old_startp = marker_position (w->start[CURRENT_DISP]); |
4770 Charbpos bottom = vmotion (w, old_startp, movement, &vtarget); | |
4771 Charbpos startp = | |
428 | 4772 start_with_point_on_display_line (w, bottom, |
4773 -1 - (movement - vtarget)); | |
4774 | |
4775 if (startp >= old_startp) | |
4776 startp = vmotion (w, old_startp, -1, NULL); | |
4777 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4778 set_marker_restricted (w->start[CURRENT_DISP], make_fixnum (startp), |
428 | 4779 w->buffer); |
4780 w->force_start = 1; | |
4781 w->start_at_line_beg = beginning_of_line_p (b, startp); | |
4782 MARK_WINDOWS_CHANGED (w); | |
4783 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4784 if (!point_would_be_visible (w, startp, XFIXNUM (point), 0)) |
428 | 4785 { |
665 | 4786 Charbpos new_point = start_of_last_line (w, startp); |
428 | 4787 |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4788 Fset_window_point (wrap_window (w), make_fixnum (new_point)); |
428 | 4789 } |
4790 } | |
4791 } | |
4792 } | |
4793 | |
4794 DEFUN ("scroll-up", Fscroll_up, 0, 1, "_P", /* | |
444 | 4795 Scroll text of current window up COUNT lines; or near full screen if no arg. |
428 | 4796 A near full screen is `next-screen-context-lines' less than a full screen. |
444 | 4797 Negative COUNT means scroll downward. |
428 | 4798 When calling from a program, supply an integer as argument or nil. |
4799 On attempt to scroll past end of buffer, `end-of-buffer' is signaled. | |
4800 On attempt to scroll past beginning of buffer, `beginning-of-buffer' is | |
4801 signaled. | |
462 | 4802 |
4803 The characters that are moved over may be added to the current selection | |
4804 \(i.e. active region) if the Shift key is held down, a motion key is used | |
4805 to invoke this command, and `shifted-motion-keys-select-region' is t; see | |
4806 the documentation for this variable for more details. | |
428 | 4807 */ |
444 | 4808 (count)) |
4809 { | |
4810 window_scroll (Fselected_window (Qnil), count, 1, ERROR_ME); | |
428 | 4811 return Qnil; |
4812 } | |
4813 | |
4814 DEFUN ("scroll-down", Fscroll_down, 0, 1, "_P", /* | |
444 | 4815 Scroll text of current window down COUNT lines; or near full screen if no arg. |
428 | 4816 A near full screen is `next-screen-context-lines' less than a full screen. |
444 | 4817 Negative COUNT means scroll upward. |
428 | 4818 When calling from a program, supply a number as argument or nil. |
4819 On attempt to scroll past end of buffer, `end-of-buffer' is signaled. | |
4820 On attempt to scroll past beginning of buffer, `beginning-of-buffer' is | |
4821 signaled. | |
462 | 4822 |
4823 The characters that are moved over may be added to the current selection | |
4824 \(i.e. active region) if the Shift key is held down, a motion key is used | |
4825 to invoke this command, and `shifted-motion-keys-select-region' is t; see | |
4826 the documentation for this variable for more details. | |
428 | 4827 */ |
444 | 4828 (count)) |
4829 { | |
4830 window_scroll (Fselected_window (Qnil), count, -1, ERROR_ME); | |
428 | 4831 return Qnil; |
4832 } | |
4833 | |
4834 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling, 0, 0, 0, /* | |
4835 Return the other window for "other window scroll" commands. | |
4836 If in the minibuffer, `minibuffer-scroll-window' if non-nil | |
4837 specifies the window. | |
4838 If `other-window-scroll-buffer' is non-nil, a window | |
4839 showing that buffer is used. | |
4840 */ | |
4841 ()) | |
4842 { | |
4843 Lisp_Object window; | |
4844 Lisp_Object selected_window = Fselected_window (Qnil); | |
4845 | |
4846 if (MINI_WINDOW_P (XWINDOW (selected_window)) | |
4847 && !NILP (Vminibuffer_scroll_window)) | |
4848 window = Vminibuffer_scroll_window; | |
4849 /* If buffer is specified, scroll that buffer. */ | |
4850 else if (!NILP (Vother_window_scroll_buffer)) | |
4851 { | |
4852 window = Fget_buffer_window (Vother_window_scroll_buffer, Qnil, Qnil); | |
4853 if (NILP (window)) | |
4854 window = display_buffer (Vother_window_scroll_buffer, Qt, Qnil); | |
4855 } | |
4856 else | |
4857 { | |
4858 /* Nothing specified; look for a neighboring window on the same | |
4859 frame. */ | |
4860 window = Fnext_window (selected_window, Qnil, Qnil, Qnil); | |
4861 | |
4862 if (EQ (window, selected_window)) | |
4863 /* That didn't get us anywhere; look for a window on another | |
4864 visible frame. */ | |
4865 do | |
4866 window = Fnext_window (window, Qnil, Qt, Qnil); | |
4867 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window)))) | |
4868 && ! EQ (window, selected_window)); | |
4869 } | |
4870 | |
4871 CHECK_LIVE_WINDOW (window); | |
4872 | |
4873 if (EQ (window, selected_window)) | |
563 | 4874 invalid_operation ("There is no other window", Qunbound); |
428 | 4875 |
4876 return window; | |
4877 } | |
4878 | |
4879 DEFUN ("scroll-other-window", Fscroll_other_window, 0, 1, "_P", /* | |
444 | 4880 Scroll next window upward COUNT lines; or near full frame if no arg. |
428 | 4881 The next window is the one below the current one; or the one at the top |
444 | 4882 if the current one is at the bottom. Negative COUNT means scroll downward. |
428 | 4883 When calling from a program, supply a number as argument or nil. |
4884 | |
4885 If in the minibuffer, `minibuffer-scroll-window' if non-nil | |
4886 specifies the window to scroll. | |
4887 If `other-window-scroll-buffer' is non-nil, scroll the window | |
4888 showing that buffer, popping the buffer up if necessary. | |
4889 */ | |
444 | 4890 (count)) |
4891 { | |
4892 window_scroll (Fother_window_for_scrolling (), count, 1, ERROR_ME); | |
428 | 4893 return Qnil; |
4894 } | |
4895 | |
4896 DEFUN ("scroll-left", Fscroll_left, 0, 1, "_P", /* | |
444 | 4897 Scroll selected window display COUNT columns left. |
4898 Default for COUNT is window width minus 2. | |
462 | 4899 |
4900 The characters that are moved over may be added to the current selection | |
4901 \(i.e. active region) if the Shift key is held down, a motion key is used | |
4902 to invoke this command, and `shifted-motion-keys-select-region' is t; see | |
4903 the documentation for this variable for more details. | |
428 | 4904 */ |
444 | 4905 (count)) |
428 | 4906 { |
4907 Lisp_Object window = Fselected_window (Qnil); | |
4908 struct window *w = XWINDOW (window); | |
444 | 4909 int n = (NILP (count) ? |
4910 window_char_width (w, 0) - 2 : | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4911 XFIXNUM (Fprefix_numeric_value (count))); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4912 |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4913 return Fset_window_hscroll (window, make_fixnum (w->hscroll + n)); |
428 | 4914 } |
4915 | |
4916 DEFUN ("scroll-right", Fscroll_right, 0, 1, "_P", /* | |
444 | 4917 Scroll selected window display COUNT columns right. |
4918 Default for COUNT is window width minus 2. | |
462 | 4919 |
4920 The characters that are moved over may be added to the current selection | |
4921 \(i.e. active region) if the Shift key is held down, a motion key is used | |
4922 to invoke this command, and `shifted-motion-keys-select-region' is t; see | |
4923 the documentation for this variable for more details. | |
428 | 4924 */ |
444 | 4925 (count)) |
428 | 4926 { |
4927 Lisp_Object window = Fselected_window (Qnil); | |
4928 struct window *w = XWINDOW (window); | |
444 | 4929 int n = (NILP (count) ? |
4930 window_char_width (w, 0) - 2 : | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4931 XFIXNUM (Fprefix_numeric_value (count))); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4932 |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4933 return Fset_window_hscroll (window, make_fixnum (w->hscroll - n)); |
428 | 4934 } |
4935 | |
4936 DEFUN ("center-to-window-line", Fcenter_to_window_line, 0, 2, "_P", /* | |
4937 Center point in WINDOW. With N, put point on line N. | |
4938 The desired position of point is always relative to the window. | |
4939 If WINDOW is nil, the selected window is used. | |
4940 */ | |
4941 (n, window)) | |
4942 { | |
4943 struct window *w = decode_window (window); | |
4944 struct buffer *b = XBUFFER (w->buffer); | |
665 | 4945 Charbpos opoint = BUF_PT (b); |
4946 Charbpos startp; | |
428 | 4947 |
4948 if (NILP (n)) | |
4949 startp = start_with_line_at_pixpos (w, opoint, window_half_pixpos (w)); | |
4950 else | |
4951 { | |
4952 n = Fprefix_numeric_value (n); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4953 CHECK_FIXNUM (n); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4954 startp = start_with_point_on_display_line (w, opoint, XFIXNUM (n)); |
428 | 4955 } |
4956 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4957 Fset_marker (w->start[CURRENT_DISP], make_fixnum (startp), w->buffer); |
428 | 4958 |
4959 w->start_at_line_beg = beginning_of_line_p (b, startp); | |
4960 w->force_start = 1; | |
4961 MARK_WINDOWS_CHANGED (w); | |
4962 return Qnil; | |
4963 } | |
4964 | |
4965 DEFUN ("move-to-window-line", Fmove_to_window_line, 1, 2, "_P", /* | |
4966 Position point relative to WINDOW. | |
4967 With no argument, position text at center of window. | |
4968 An argument specifies window line; zero means top of window, | |
4969 negative means relative to bottom of window. | |
4970 If WINDOW is nil, the selected window is used. | |
4971 */ | |
4972 (arg, window)) | |
4973 { | |
4974 struct window *w; | |
4975 struct buffer *b; | |
4976 int height; | |
665 | 4977 Charbpos start, new_point; |
428 | 4978 int selected; |
4979 | |
4980 /* Don't use decode_window() because we need the new value of | |
4981 WINDOW. */ | |
4982 if (NILP (window)) | |
4983 window = Fselected_window (Qnil); | |
4984 else | |
4985 CHECK_LIVE_WINDOW (window); | |
4986 w = XWINDOW (window); | |
4987 b = XBUFFER (w->buffer); | |
4988 | |
4989 height = window_displayed_height (w); | |
4990 selected = EQ (window, Fselected_window (w->frame)); | |
4991 | |
4992 if (NILP (arg)) | |
4993 { | |
4994 int retval; | |
4995 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4996 if (XFIXNUM (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
4997 && XFIXNUM (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b)) |
428 | 4998 { |
4999 new_point = point_at_center (w, CURRENT_DISP, 0, 0); | |
5000 | |
844 | 5001 /* #### Here we are checking the selected window of the frame |
5002 instead of the selected window period. Elsewhere we check | |
5003 the selected window of the device. What a mess! */ | |
428 | 5004 if (selected) |
5005 BUF_SET_PT (b, new_point); | |
5006 else | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5007 Fset_window_point (window, make_fixnum (new_point)); |
428 | 5008 |
5009 retval = line_at_center (w, CURRENT_DISP, 0, 0); | |
5010 } | |
5011 else | |
5012 { | |
5013 start = marker_position (w->start[CURRENT_DISP]); | |
5014 if (start < BUF_BEGV (b)) | |
5015 start = BUF_BEGV (b); | |
5016 else if (start > BUF_ZV (b)) | |
5017 start = BUF_ZV (b); | |
5018 | |
5019 if (selected) | |
5020 new_point = BUF_PT (b); | |
5021 else | |
5022 new_point = marker_position (w->pointm[CURRENT_DISP]); | |
5023 | |
5024 new_point = point_at_center (w, CMOTION_DISP, start, BUF_PT (b)); | |
5025 | |
5026 if (selected) | |
5027 BUF_SET_PT (b, new_point); | |
5028 else | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5029 Fset_window_point (window, make_fixnum (new_point)); |
428 | 5030 |
5031 retval = line_at_center (w, CMOTION_DISP, start, BUF_PT (b)); | |
5032 } | |
5033 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5034 return make_fixnum (retval); |
428 | 5035 } |
5036 else | |
5037 { | |
5038 /* #### Is this going to work right when at eob? */ | |
5039 arg = Fprefix_numeric_value (arg); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5040 if (XFIXNUM (arg) < 0) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5041 arg = make_fixnum (XFIXNUM (arg) + height); |
428 | 5042 } |
5043 | |
5044 start = marker_position (w->start[CURRENT_DISP]); | |
5045 if (start < BUF_BEGV (b) || start > BUF_ZV (b)) | |
5046 { | |
5047 if (selected) | |
5048 new_point = BUF_PT (b); | |
5049 else | |
5050 new_point = marker_position (w->pointm[CURRENT_DISP]); | |
5051 | |
5052 new_point = vmotion (XWINDOW (window), new_point, -height / 2, 0); | |
5053 | |
5054 if (selected) | |
5055 BUF_SET_PT (b, new_point); | |
5056 else | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5057 Fset_window_point (window, make_fixnum (new_point)); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5058 |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5059 Fset_marker (w->start[CURRENT_DISP], make_fixnum (new_point), |
428 | 5060 w->buffer); |
5061 w->start_at_line_beg = beginning_of_line_p (b, new_point); | |
5062 w->force_start = 1; | |
5063 } | |
5064 else | |
5065 { | |
5066 if (selected) | |
5067 BUF_SET_PT (b, start); | |
5068 else | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5069 Fset_window_point (window, make_fixnum (start)); |
428 | 5070 } |
5071 | |
5072 if (selected) | |
5073 return Fvertical_motion (arg, window, Qnil); | |
5074 else | |
5075 { | |
5076 int vpos; | |
5077 new_point = vmotion (XWINDOW (window), | |
5078 marker_position (w->pointm[CURRENT_DISP]), | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5079 XFIXNUM (arg), &vpos); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5080 Fset_window_point (window, make_fixnum (new_point)); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5081 return make_fixnum (vpos); |
428 | 5082 } |
5083 } | |
5084 | |
5085 | |
5086 static int | |
5087 map_windows_1 (Lisp_Object window, | |
5088 int (*mapfun) (struct window *w, void *closure), | |
5089 void *closure) | |
5090 { | |
5091 for (; !NILP (window); window = XWINDOW (window)->next) | |
5092 { | |
5093 int retval; | |
5094 struct window *w = XWINDOW (window); | |
5095 | |
5096 if (!NILP (w->vchild)) | |
5097 retval = map_windows_1 (w->vchild, mapfun, closure); | |
5098 else if (!NILP (w->hchild)) | |
5099 retval = map_windows_1 (w->hchild, mapfun, closure); | |
5100 else | |
5101 retval = (mapfun) (w, closure); | |
5102 | |
5103 if (retval) | |
5104 return retval; | |
5105 } | |
5106 | |
5107 return 0; | |
5108 } | |
5109 | |
5110 /* Map MAPFUN over the windows in F. CLOSURE is passed to each | |
5111 invocation of MAPFUN. If any invocation of MAPFUN returns | |
5112 non-zero, the mapping is halted. Otherwise, map_windows() maps | |
5113 over all windows in F. | |
5114 | |
800 | 5115 If F is null, map over all frames on all devices and consoles. |
5116 | |
428 | 5117 If MAPFUN creates or deletes windows, the behavior is undefined. */ |
5118 | |
5119 int | |
5120 map_windows (struct frame *f, int (*mapfun) (struct window *w, void *closure), | |
5121 void *closure) | |
5122 { | |
5123 if (f) | |
5124 return map_windows_1 (FRAME_ROOT_WINDOW (f), mapfun, closure); | |
5125 else | |
5126 { | |
5127 Lisp_Object frmcons, devcons, concons; | |
5128 | |
5129 FRAME_LOOP_NO_BREAK(frmcons, devcons, concons) | |
5130 { | |
5131 int v = map_windows_1 (FRAME_ROOT_WINDOW (XFRAME (XCAR (frmcons))), | |
5132 mapfun, closure); | |
5133 if (v) | |
5134 return v; | |
5135 } | |
5136 } | |
5137 | |
5138 return 0; | |
5139 } | |
5140 | |
5141 | |
5142 static void | |
2286 | 5143 modeline_shadow_thickness_changed (Lisp_Object UNUSED (specifier), |
5144 struct window *w, | |
5145 Lisp_Object UNUSED (oldval)) | |
428 | 5146 { |
5147 w->shadow_thickness_changed = 1; | |
5148 MARK_WINDOWS_CHANGED (w); | |
5149 } | |
5150 | |
5151 static void | |
2286 | 5152 vertical_divider_changed_in_window (Lisp_Object UNUSED (specifier), |
428 | 5153 struct window *w, |
2286 | 5154 Lisp_Object UNUSED (oldval)) |
428 | 5155 { |
5156 MARK_WINDOWS_CHANGED (w); | |
5157 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (XFRAME (WINDOW_FRAME (w))); | |
5158 } | |
5159 | |
5160 /* also used in scrollbar.c */ | |
5161 void | |
2286 | 5162 some_window_value_changed (Lisp_Object UNUSED (specifier), |
5163 struct window *w, | |
5164 Lisp_Object UNUSED (oldval)) | |
428 | 5165 { |
5166 MARK_WINDOWS_CHANGED (w); | |
5167 } | |
5168 | |
5169 #ifdef MEMORY_USAGE_STATS | |
5170 | |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5171 struct window_mirror_stats |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5172 { |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5173 struct usage_stats u; |
5384
3889ef128488
Fix misspelled words, and some grammar, across the entire source tree.
Jerry James <james@xemacs.org>
parents:
5217
diff
changeset
|
5174 /* Ancillary non-lisp */ |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5175 Bytecount redisplay_structs; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5176 #ifdef HAVE_SCROLLBARS |
5384
3889ef128488
Fix misspelled words, and some grammar, across the entire source tree.
Jerry James <james@xemacs.org>
parents:
5217
diff
changeset
|
5177 /* Ancillary Lisp */ |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5178 Bytecount scrollbar; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5179 #endif |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5180 }; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5181 |
428 | 5182 struct window_stats |
5183 { | |
5157
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5184 struct usage_stats u; |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5185 /* Ancillary non-Lisp */ |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5186 Bytecount line_start; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5187 /* The next two: ancillary non-Lisp under old-GC, ancillary Lisp under |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5188 NEW_GC */ |
5157
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5189 Bytecount face; |
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5190 Bytecount glyph; |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5191 /* The next two are copied out of the window mirror, which is an ancillary |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5192 Lisp structure; the first is non-Lisp, the second Lisp, but from our |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5193 perspective, they are both counted as Lisp */ |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5194 Bytecount redisplay_structs; |
428 | 5195 #ifdef HAVE_SCROLLBARS |
5157
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5196 Bytecount scrollbar; |
428 | 5197 #endif |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5198 /* Remaining memory associated with window mirror (ancillary Lisp) */ |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5199 Bytecount window_mirror; |
428 | 5200 }; |
5201 | |
5202 static void | |
5203 compute_window_mirror_usage (struct window_mirror *mir, | |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5204 struct window_mirror_stats *stats) |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5205 { |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5206 stats->redisplay_structs = |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5207 compute_display_line_dynarr_usage (mir->current_display_lines, &stats->u) |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5208 + |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5209 compute_display_line_dynarr_usage (mir->desired_display_lines, &stats->u); |
428 | 5210 #ifdef HAVE_SCROLLBARS |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5211 stats->scrollbar = |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5212 compute_all_scrollbar_instance_usage (mir->scrollbar_vertical_instance) + |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5213 compute_all_scrollbar_instance_usage (mir->scrollbar_horizontal_instance); |
428 | 5214 #endif /* HAVE_SCROLLBARS */ |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5215 } |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5216 |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5217 |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5218 static void |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5219 window_mirror_memory_usage (Lisp_Object window_mirror, |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5220 struct generic_usage_stats *gustats) |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5221 { |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5222 struct window_mirror_stats *stats = (struct window_mirror_stats *) gustats; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5223 |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5224 compute_window_mirror_usage (XWINDOW_MIRROR (window_mirror), stats); |
428 | 5225 } |
5226 | |
5227 static void | |
5228 compute_window_usage (struct window *w, struct window_stats *stats, | |
5157
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5229 struct usage_stats *ustats) |
428 | 5230 { |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5231 stats->line_start = |
5157
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5232 compute_line_start_cache_dynarr_usage (w->line_start_cache, ustats); |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5233 stats->face = compute_face_cachel_usage (w->face_cachels, |
5217
c0f518284a68
Unbreak `show-memory-usage' for NEW_GC.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5214
diff
changeset
|
5234 ustats); |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5235 stats->glyph = compute_glyph_cachel_usage (w->glyph_cachels, |
5217
c0f518284a68
Unbreak `show-memory-usage' for NEW_GC.
Marcus Crestani <crestani@informatik.uni-tuebingen.de>
parents:
5214
diff
changeset
|
5236 ustats); |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5237 { |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5238 struct window_mirror *wm; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5239 |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5240 wm = find_window_mirror_maybe (w); |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5241 if (wm) |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5242 { |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5243 struct generic_usage_stats gustats; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5244 struct window_mirror_stats *wmstats; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5245 Bytecount total; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5246 total = lisp_object_memory_usage_full (wrap_window_mirror (wm), |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5247 NULL, NULL, NULL, &gustats); |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5248 wmstats = (struct window_mirror_stats *) &gustats; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5249 stats->redisplay_structs = wmstats->redisplay_structs; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5250 total -= stats->redisplay_structs; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5251 #ifdef HAVE_SCROLLBARS |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5252 stats->scrollbar = wmstats->scrollbar; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5253 total -= stats->scrollbar; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5254 #endif |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5255 stats->window_mirror = total; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5256 } |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5257 } |
428 | 5258 } |
5259 | |
5157
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5260 static void |
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5261 window_memory_usage (Lisp_Object window, struct generic_usage_stats *gustats) |
428 | 5262 { |
5157
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5263 struct window_stats *stats = (struct window_stats *) gustats; |
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5264 |
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5265 compute_window_usage (XWINDOW (window), stats, &stats->u); |
428 | 5266 } |
5267 | |
5268 #endif /* MEMORY_USAGE_STATS */ | |
5157
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5269 |
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5270 |
428 | 5271 |
5272 /* Mark all subwindows of a window as deleted. The argument | |
5273 W is actually the subwindow tree of the window in question. */ | |
5274 | |
5275 void | |
5276 delete_all_subwindows (struct window *w) | |
5277 { | |
5278 if (!NILP (w->next)) delete_all_subwindows (XWINDOW (w->next)); | |
5279 if (!NILP (w->vchild)) delete_all_subwindows (XWINDOW (w->vchild)); | |
5280 if (!NILP (w->hchild)) delete_all_subwindows (XWINDOW (w->hchild)); | |
5281 | |
5282 mark_window_as_deleted (w); | |
5283 } | |
5284 | |
1149 | 5285 |
2289 | 5286 static int |
5287 get_current_pixel_pos (Lisp_Object window, Lisp_Object pos, | |
5288 struct window **w, | |
5289 struct rune **rb, struct display_line **dl) | |
428 | 5290 { |
2289 | 5291 display_line_dynarr *dla; |
5292 struct display_block *db = NULL; | |
5293 int x, y; | |
5294 | |
5295 *rb = NULL; | |
5296 *dl = NULL; | |
5297 *w = decode_window (window); | |
5298 dla = window_display_lines (*w, CURRENT_DISP); | |
5299 x = (*w)->last_point_x[CURRENT_DISP]; | |
5300 y = (*w)->last_point_y[CURRENT_DISP]; | |
5301 if (MINI_WINDOW_P (*w)) | |
5302 return 0; | |
428 | 5303 |
5304 if (y<0 || x<0 || y >= Dynarr_length (dla) || !NILP (pos)) | |
5305 { | |
5306 int first_line, i; | |
665 | 5307 Charbpos point; |
428 | 5308 |
5309 if (NILP (pos)) | |
5310 pos = Fwindow_point (window); | |
438 | 5311 |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5312 CHECK_FIXNUM (pos); |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5313 point = XFIXNUM (pos); |
428 | 5314 |
4967 | 5315 if (Dynarr_length (dla) && Dynarr_begin (dla)->modeline) |
428 | 5316 first_line = 1; |
5317 else | |
5318 first_line = 0; | |
5319 | |
5320 for (i = first_line; i < Dynarr_length (dla); i++) | |
5321 { | |
2289 | 5322 *dl = Dynarr_atp (dla, i); |
428 | 5323 /* find the vertical location first */ |
2289 | 5324 if (point >= (*dl)->charpos && point <= (*dl)->end_charpos) |
428 | 5325 { |
2289 | 5326 db = get_display_block_from_line (*dl, TEXT); |
428 | 5327 for (i = 0; i < Dynarr_length (db->runes); i++) |
5328 { | |
2289 | 5329 *rb = Dynarr_atp (db->runes, i); |
2290 | 5330 if (point <= (*rb)->charpos) |
826 | 5331 goto found_charpos; |
428 | 5332 } |
2289 | 5333 return 0; |
428 | 5334 } |
5335 } | |
2289 | 5336 return 0; |
826 | 5337 found_charpos: |
428 | 5338 ; |
5339 } | |
5340 else | |
5341 { | |
442 | 5342 /* optimized case */ |
2289 | 5343 *dl = Dynarr_atp (dla, y); |
5344 db = get_display_block_from_line (*dl, TEXT); | |
428 | 5345 |
5346 if (x >= Dynarr_length (db->runes)) | |
2289 | 5347 return 0; |
5348 | |
5349 *rb = Dynarr_atp (db->runes, x); | |
428 | 5350 } |
5351 | |
2289 | 5352 return 1; |
5353 } | |
5354 | |
5355 DEFUN ("current-pixel-column", Fcurrent_pixel_column, 0, 2, 0, /* | |
5356 Return the horizontal pixel position of point POS in window. | |
5357 Beginning of line is column 0. If WINDOW is nil, the current window | |
5358 is assumed. If POS is nil, point is assumed. Note that POS must be | |
5359 visible for a non-nil result to be returned. This is calculated using | |
5360 the redisplay display tables; because of this, the returned value will | |
5361 only be correct if the redisplay tables are up-to-date. Use | |
5362 \"(sit-for 0)\" to insure that they are; however, if WINDOW is part of | |
5363 a new frame, use the following instead: | |
5364 (while (not (frame-visible-p frame)) (sleep-for .5)) | |
5365 */ | |
5366 (window, pos)) | |
5367 { | |
5368 struct window* w; | |
5369 struct display_line *dl; | |
5370 struct rune* rb; | |
5371 | |
5372 if (!get_current_pixel_pos(window, pos, &w, &rb, &dl)) | |
5373 return Qnil; | |
5374 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5375 return make_fixnum (rb->xpos - WINDOW_LEFT (w)); |
428 | 5376 } |
5377 | |
2289 | 5378 DEFUN ("current-pixel-row", Fcurrent_pixel_row, 0, 2, 0, /* |
5379 Return the vertical pixel position of point POS in window. Top of | |
5380 window is row 0. If WINDOW is nil, the current window is assumed. If | |
5381 POS is nil, point is assumed. Note that POS must be visible for a | |
5382 non-nil result to be returned. This is calculated using the redisplay | |
5383 display tables; because of this, the returned value will only be | |
5384 correct if the redisplay tables are up-to-date. Use \"(sit-for 0)\" | |
5385 to insure that they are; however, if WINDOW is part of a new frame, | |
5386 use the following instead: | |
5387 (while (not (frame-visible-p frame)) (sleep-for .5)) | |
5388 */ | |
5389 (window, pos)) | |
5390 { | |
5391 struct window* w; | |
5392 struct display_line *dl; | |
5393 struct rune* rb; | |
5394 | |
5395 if (!get_current_pixel_pos(window, pos, &w, &rb, &dl)) | |
5396 return Qnil; | |
5397 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5398 return make_fixnum (dl->ypos - dl->ascent - WINDOW_TOP (w)); |
2289 | 5399 } |
5400 | |
428 | 5401 |
5402 #ifdef DEBUG_XEMACS | |
5403 /* This is short and simple in elisp, but... it was written to debug | |
5404 problems purely on the C side. That is where we need to call it so | |
5405 here it is. */ | |
5406 static void | |
5407 debug_print_window (Lisp_Object window, int level) | |
5408 { | |
5409 int i; | |
5410 Lisp_Object child = Fwindow_first_vchild (window); | |
5411 | |
5412 if (NILP (child)) | |
5413 child = Fwindow_first_hchild (window); | |
5414 | |
5415 for (i = level; i > 0; i--) | |
442 | 5416 stderr_out ("\t"); |
5417 | |
5418 stderr_out ("#<window"); | |
428 | 5419 { |
5420 Lisp_Object buffer = XWINDOW (window)->buffer; | |
5421 if (!NILP (buffer) && BUFFERP (buffer)) | |
442 | 5422 stderr_out (" on %s", XSTRING_DATA (XBUFFER (buffer)->name)); |
428 | 5423 } |
5146
88bd4f3ef8e4
make lrecord UID's have a separate UID space for each object, resurrect debug SOE code in extents.c
Ben Wing <ben@xemacs.org>
parents:
5142
diff
changeset
|
5424 stderr_out (" 0x%x>", LISP_OBJECT_UID (window)); |
428 | 5425 |
5426 while (!NILP (child)) | |
5427 { | |
5428 debug_print_window (child, level + 1); | |
5429 child = Fwindow_next_child (child); | |
5430 } | |
5431 } | |
5432 | |
5433 void debug_print_windows (struct frame *f); | |
5434 void | |
5435 debug_print_windows (struct frame *f) | |
5436 { | |
5437 debug_print_window (f->root_window, 0); | |
5438 putc ('\n', stderr); | |
5439 } | |
5440 #endif /* DEBUG_XEMACS */ | |
5441 | |
5442 | |
5443 /************************************************************************/ | |
5444 /* initialization */ | |
5445 /************************************************************************/ | |
5446 | |
5447 void | |
5157
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5448 window_objects_create (void) |
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5449 { |
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5450 #ifdef MEMORY_USAGE_STATS |
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5451 OBJECT_HAS_METHOD (window, memory_usage); |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5452 OBJECT_HAS_METHOD (window_mirror, memory_usage); |
5157
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5453 #endif |
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5454 } |
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5455 |
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5456 void |
428 | 5457 syms_of_window (void) |
5458 { | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3078
diff
changeset
|
5459 INIT_LISP_OBJECT (window); |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3078
diff
changeset
|
5460 INIT_LISP_OBJECT (window_mirror); |
3092 | 5461 #ifdef NEW_GC |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
5462 INIT_LISP_OBJECT (face_cachel); |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
5463 INIT_LISP_OBJECT (face_cachel_dynarr); |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
5464 INIT_LISP_OBJECT (glyph_cachel); |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
5465 INIT_LISP_OBJECT (glyph_cachel_dynarr); |
3092 | 5466 #endif /* NEW_GC */ |
442 | 5467 |
563 | 5468 DEFSYMBOL (Qwindowp); |
5469 DEFSYMBOL (Qwindow_live_p); | |
5470 DEFSYMBOL (Qdisplay_buffer); | |
428 | 5471 |
5472 #ifdef MEMORY_USAGE_STATS | |
563 | 5473 DEFSYMBOL (Qface_cache); |
5474 DEFSYMBOL (Qglyph_cache); | |
5475 DEFSYMBOL (Qline_start_cache); | |
428 | 5476 #ifdef HAVE_SCROLLBARS |
563 | 5477 DEFSYMBOL (Qscrollbar_instances); |
428 | 5478 #endif |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5479 DEFSYMBOL (Qredisplay_structs); |
428 | 5480 #endif |
5481 | |
707 | 5482 DEFSYMBOL (Qtruncate_partial_width_windows); |
1149 | 5483 DEFSYMBOL (Qcurrent_window_configuration); |
5484 DEFSYMBOL (Qset_window_configuration); | |
707 | 5485 |
428 | 5486 DEFSUBR (Fselected_window); |
5487 DEFSUBR (Flast_nonminibuf_window); | |
5488 DEFSUBR (Fminibuffer_window); | |
5489 DEFSUBR (Fwindow_minibuffer_p); | |
5490 DEFSUBR (Fwindowp); | |
5491 DEFSUBR (Fwindow_live_p); | |
5492 DEFSUBR (Fwindow_first_hchild); | |
5493 DEFSUBR (Fwindow_first_vchild); | |
5494 DEFSUBR (Fwindow_next_child); | |
5495 DEFSUBR (Fwindow_previous_child); | |
5496 DEFSUBR (Fwindow_parent); | |
5497 DEFSUBR (Fwindow_lowest_p); | |
5498 DEFSUBR (Fwindow_truncated_p); | |
5499 DEFSUBR (Fwindow_highest_p); | |
5500 DEFSUBR (Fwindow_leftmost_p); | |
5501 DEFSUBR (Fwindow_rightmost_p); | |
5502 DEFSUBR (Fpos_visible_in_window_p); | |
5503 DEFSUBR (Fwindow_buffer); | |
5504 DEFSUBR (Fwindow_frame); | |
5505 DEFSUBR (Fwindow_height); | |
5506 DEFSUBR (Fwindow_displayed_height); | |
5507 DEFSUBR (Fwindow_width); | |
442 | 5508 DEFSUBR (Fwindow_full_width); |
428 | 5509 DEFSUBR (Fwindow_pixel_height); |
5510 DEFSUBR (Fwindow_pixel_width); | |
442 | 5511 DEFSUBR (Fwindow_text_area_height); |
428 | 5512 DEFSUBR (Fwindow_text_area_pixel_height); |
5513 DEFSUBR (Fwindow_displayed_text_pixel_height); | |
5514 DEFSUBR (Fwindow_text_area_pixel_width); | |
5515 DEFSUBR (Fwindow_hscroll); | |
438 | 5516 DEFSUBR (Fset_window_hscroll); |
428 | 5517 DEFSUBR (Fmodeline_hscroll); |
5518 DEFSUBR (Fset_modeline_hscroll); | |
5519 DEFSUBR (Fwindow_pixel_edges); | |
5520 DEFSUBR (Fwindow_text_area_pixel_edges); | |
5521 DEFSUBR (Fwindow_point); | |
5522 DEFSUBR (Fwindow_start); | |
5523 DEFSUBR (Fwindow_end); | |
442 | 5524 DEFSUBR (Fwindow_last_line_visible_height); |
428 | 5525 DEFSUBR (Fset_window_point); |
5526 DEFSUBR (Fset_window_start); | |
5527 DEFSUBR (Fwindow_dedicated_p); | |
5528 DEFSUBR (Fset_window_dedicated_p); | |
5529 DEFSUBR (Fnext_window); | |
5530 DEFSUBR (Fprevious_window); | |
5531 DEFSUBR (Fnext_vertical_window); | |
5532 DEFSUBR (Fother_window); | |
5533 DEFSUBR (Fget_lru_window); | |
5534 DEFSUBR (Fget_largest_window); | |
5535 DEFSUBR (Fget_buffer_window); | |
5536 DEFSUBR (Fwindow_left_margin_pixel_width); | |
5537 DEFSUBR (Fwindow_right_margin_pixel_width); | |
5538 DEFSUBR (Fdelete_other_windows); | |
5539 DEFSUBR (Fdelete_windows_on); | |
5540 DEFSUBR (Freplace_buffer_in_windows); | |
5541 DEFSUBR (Fdelete_window); | |
5542 DEFSUBR (Fset_window_buffer); | |
5543 DEFSUBR (Fselect_window); | |
5544 DEFSUBR (Fsplit_window); | |
5545 DEFSUBR (Fenlarge_window); | |
5546 DEFSUBR (Fenlarge_window_pixels); | |
5547 DEFSUBR (Fshrink_window); | |
5548 DEFSUBR (Fshrink_window_pixels); | |
5549 DEFSUBR (Fscroll_up); | |
5550 DEFSUBR (Fscroll_down); | |
5551 DEFSUBR (Fscroll_left); | |
5552 DEFSUBR (Fscroll_right); | |
5553 DEFSUBR (Fother_window_for_scrolling); | |
5554 DEFSUBR (Fscroll_other_window); | |
5555 DEFSUBR (Fcenter_to_window_line); | |
5556 DEFSUBR (Fmove_to_window_line); | |
5557 DEFSUBR (Fcurrent_pixel_column); | |
2289 | 5558 DEFSUBR (Fcurrent_pixel_row); |
428 | 5559 } |
5560 | |
5561 void | |
5562 reinit_vars_of_window (void) | |
5563 { | |
5564 /* Make sure all windows get marked */ | |
5565 minibuf_window = Qnil; | |
5566 staticpro_nodump (&minibuf_window); | |
5567 } | |
5568 | |
5569 void | |
5570 vars_of_window (void) | |
5571 { | |
5157
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5572 #ifdef MEMORY_USAGE_STATS |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5573 Lisp_Object l; |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5574 |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5575 l = listu (Qline_start_cache, |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5576 #ifdef NEW_GC |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5577 Qt, |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5578 #endif |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5579 Qface_cache, Qglyph_cache, |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5580 #ifndef NEW_GC |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5581 Qt, |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5582 #endif |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5583 Qredisplay_structs, |
5164
8bf9e67e06ec
Fix broken compile of window.c under Visual Studio 6.
Vin Shelton <acs@xemacs.org>
parents:
5157
diff
changeset
|
5584 #ifdef HAVE_SCROLLBARS |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5585 Qscrollbar_instances, |
5157
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5586 #endif |
5170
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5587 intern ("window-mirror"), |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5588 Qunbound); |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5589 |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5590 OBJECT_HAS_PROPERTY (window, memusage_stats_list, l); |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5591 |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5592 l = listu (Qredisplay_structs, |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5593 #ifdef HAVE_SCROLLBARS |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5594 Qt, Qscrollbar_instances, |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5595 #endif |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5596 Qunbound); |
5ddbab03b0e6
various fixes to memory-usage stats
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
5597 OBJECT_HAS_PROPERTY (window_mirror, memusage_stats_list, l); |
5157
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5598 #endif /* MEMORY_USAGE_STATS */ |
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
5599 |
428 | 5600 DEFVAR_BOOL ("scroll-on-clipped-lines", &scroll_on_clipped_lines /* |
5601 *Non-nil means to scroll if point lands on a line which is clipped. | |
5602 */ ); | |
5603 scroll_on_clipped_lines = 1; | |
5604 | |
5605 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function /* | |
5606 Non-nil means call as function to display a help buffer. | |
5607 The function is called with one argument, the buffer to be displayed. | |
5608 Used by `with-output-to-temp-buffer'. | |
5609 If this function is used, then it must do the entire job of showing | |
5610 the buffer; `temp-buffer-show-hook' is not run unless this function runs it. | |
442 | 5611 \(`temp-buffer-show-hook' is obsolete. Do not use in new code.) |
428 | 5612 */ ); |
5613 Vtemp_buffer_show_function = Qnil; | |
5614 | |
5615 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuffer_scroll_window /* | |
5616 Non-nil means it is the window that \\<minibuffer-local-map>\\[scroll-other-window] in minibuffer should scroll. | |
5617 */ ); | |
5618 Vminibuffer_scroll_window = Qnil; | |
5619 | |
5620 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer /* | |
5621 If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. | |
5622 */ ); | |
5623 Vother_window_scroll_buffer = Qnil; | |
5624 | |
5625 DEFVAR_LISP ("window-pixel-scroll-increment", &Vwindow_pixel_scroll_increment /* | |
5626 *Number of pixels to scroll by per requested line. | |
5627 If nil then normal line scrolling occurs regardless of line height. | |
5628 If t then scrolling is done in increments equal to the height of the default face. | |
5629 */ ); | |
5630 Vwindow_pixel_scroll_increment = Qt; | |
5631 | |
5632 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines /* | |
5633 *Number of lines of continuity when scrolling by screenfuls. | |
5634 */ ); | |
5635 next_screen_context_lines = 2; | |
5636 | |
5637 DEFVAR_INT ("window-min-height", &window_min_height /* | |
5638 *Delete any window less than this tall (including its modeline). | |
5639 */ ); | |
5640 window_min_height = 4; | |
5641 | |
5642 DEFVAR_INT ("window-min-width", &window_min_width /* | |
5643 *Delete any window less than this wide. | |
5644 */ ); | |
5645 window_min_width = 10; | |
5646 } | |
5647 | |
5648 void | |
5649 specifier_vars_of_window (void) | |
5650 { | |
5651 DEFVAR_SPECIFIER ("modeline-shadow-thickness", &Vmodeline_shadow_thickness /* | |
5652 *How thick to draw 3D shadows around modelines. | |
5653 If this is set to 0, modelines will be the traditional 2D. Sizes above | |
5654 10 will be accepted but the maximum thickness that will be drawn is 10. | |
5655 This is a specifier; use `set-specifier' to change it. | |
5656 */ ); | |
5657 Vmodeline_shadow_thickness = Fmake_specifier (Qinteger); | |
5658 /* The initial value for modeline-shadow-thickness is 2, but if the | |
5659 user removes all specifications we provide a fallback value of 0, | |
5660 which is probably what was expected. */ | |
5661 set_specifier_fallback (Vmodeline_shadow_thickness, | |
5662 list1 (Fcons (Qnil, Qzero))); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5663 Fadd_spec_to_specifier (Vmodeline_shadow_thickness, make_fixnum (2), |
428 | 5664 Qnil, Qnil, Qnil); |
5665 set_specifier_caching (Vmodeline_shadow_thickness, | |
438 | 5666 offsetof (struct window, modeline_shadow_thickness), |
428 | 5667 modeline_shadow_thickness_changed, |
444 | 5668 0, 0, 0); |
428 | 5669 |
5670 DEFVAR_SPECIFIER ("has-modeline-p", &Vhas_modeline_p /* | |
5671 *Whether the modeline should be displayed. | |
5672 This is a specifier; use `set-specifier' to change it. | |
5673 */ ); | |
5674 Vhas_modeline_p = Fmake_specifier (Qboolean); | |
5675 set_specifier_fallback (Vhas_modeline_p, | |
5676 list1 (Fcons (Qnil, Qt))); | |
5677 set_specifier_caching (Vhas_modeline_p, | |
438 | 5678 offsetof (struct window, has_modeline_p), |
428 | 5679 /* #### It's strange that we need a special |
5680 flag to indicate that the shadow-thickness | |
5681 has changed, but not one to indicate that | |
5682 the modeline has been turned off or on. */ | |
5683 some_window_value_changed, | |
444 | 5684 0, 0, 0); |
428 | 5685 |
5686 DEFVAR_SPECIFIER ("vertical-divider-always-visible-p", | |
5687 &Vvertical_divider_always_visible_p /* | |
5688 *Should XEmacs always display vertical dividers between windows. | |
5689 | |
5690 When this is non-nil, vertical dividers are always shown, and are | |
5691 draggable. When it is nil, vertical dividers are shown only when | |
5692 there are no scrollbars in between windows, and are not draggable. | |
5693 | |
5694 This is a specifier; use `set-specifier' to change it. | |
5695 */ ); | |
5696 Vvertical_divider_always_visible_p = Fmake_specifier (Qboolean); | |
5697 set_specifier_fallback (Vvertical_divider_always_visible_p, | |
5698 list1 (Fcons (Qnil, Qt))); | |
5699 set_specifier_caching (Vvertical_divider_always_visible_p, | |
438 | 5700 offsetof (struct window, |
5701 vertical_divider_always_visible_p), | |
428 | 5702 vertical_divider_changed_in_window, |
444 | 5703 0, 0, 0); |
428 | 5704 |
5705 DEFVAR_SPECIFIER ("vertical-divider-shadow-thickness", &Vvertical_divider_shadow_thickness /* | |
5706 *How thick to draw 3D shadows around vertical dividers. | |
5707 This is a specifier; use `set-specifier' to change it. | |
5708 */ ); | |
5709 Vvertical_divider_shadow_thickness = Fmake_specifier (Qinteger); | |
5710 set_specifier_fallback (Vvertical_divider_shadow_thickness, | |
5711 list1 (Fcons (Qnil, Qzero))); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5712 Fadd_spec_to_specifier (Vvertical_divider_shadow_thickness, make_fixnum (2), |
428 | 5713 Qnil, Qnil, Qnil); |
5714 set_specifier_caching (Vvertical_divider_shadow_thickness, | |
438 | 5715 offsetof (struct window, |
5716 vertical_divider_shadow_thickness), | |
428 | 5717 vertical_divider_changed_in_window, |
444 | 5718 0, 0, 0); |
428 | 5719 DEFVAR_SPECIFIER ("vertical-divider-line-width", &Vvertical_divider_line_width /* |
5720 *The width of the vertical dividers, not including shadows. | |
5721 | |
5722 For TTY windows, divider line is always one character wide. When | |
5723 instance of this specifier is zero in a TTY window, no divider is | |
5724 drawn at all between windows. When non-zero, a one character wide | |
5725 divider is displayed. | |
5726 | |
5727 This is a specifier; use `set-specifier' to change it. | |
5728 */ ); | |
5729 | |
5730 Vvertical_divider_line_width = Fmake_specifier (Qnatnum); | |
5731 { | |
5732 Lisp_Object fb = Qnil; | |
5733 #ifdef HAVE_TTY | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5734 fb = Fcons (Fcons (list1 (Qtty), make_fixnum (1)), fb); |
428 | 5735 #endif |
462 | 5736 #ifdef HAVE_GTK |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5737 fb = Fcons (Fcons (list1 (Qgtk), make_fixnum (3)), fb); |
462 | 5738 #endif |
428 | 5739 #ifdef HAVE_X_WINDOWS |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5740 fb = Fcons (Fcons (list1 (Qx), make_fixnum (3)), fb); |
428 | 5741 #endif |
5742 #ifdef HAVE_MS_WINDOWS | |
5743 /* #### This should be made magic and made to obey system settings */ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5744 fb = Fcons (Fcons (list1 (Qmswindows), make_fixnum (3)), fb); |
428 | 5745 #endif |
5746 set_specifier_fallback (Vvertical_divider_line_width, fb); | |
5747 } | |
5748 set_specifier_caching (Vvertical_divider_line_width, | |
438 | 5749 offsetof (struct window, |
5750 vertical_divider_line_width), | |
428 | 5751 vertical_divider_changed_in_window, |
444 | 5752 0, 0, 0); |
428 | 5753 |
5754 DEFVAR_SPECIFIER ("vertical-divider-spacing", &Vvertical_divider_spacing /* | |
5755 *How much space to leave around the vertical dividers. | |
5756 | |
5757 In TTY windows, spacing is always zero, and the value of this | |
5758 specifier is ignored. | |
5759 | |
5760 This is a specifier; use `set-specifier' to change it. | |
5761 */ ); | |
5762 Vvertical_divider_spacing = Fmake_specifier (Qnatnum); | |
5763 { | |
5764 Lisp_Object fb = Qnil; | |
5765 #ifdef HAVE_TTY | |
5766 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb); | |
5767 #endif | |
5768 #ifdef HAVE_X_WINDOWS | |
5769 /* #### 3D dividers look great on MS Windows with spacing = 0. | |
5770 Should not the same value be the fallback under X? - kkm */ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5474
diff
changeset
|
5771 fb = Fcons (Fcons (list1 (Qx), make_fixnum (2)), fb); |
428 | 5772 #endif |
462 | 5773 #ifdef HAVE_GTK |
5774 fb = Fcons (Fcons (list1 (Qgtk), Qzero), fb); | |
5775 #endif | |
428 | 5776 #ifdef HAVE_MS_WINDOWS |
5777 fb = Fcons (Fcons (list1 (Qmswindows), Qzero), fb); | |
5778 #endif | |
5779 set_specifier_fallback (Vvertical_divider_spacing, fb); | |
5780 } | |
5781 set_specifier_caching (Vvertical_divider_spacing, | |
438 | 5782 offsetof (struct window, vertical_divider_spacing), |
428 | 5783 vertical_divider_changed_in_window, |
444 | 5784 0, 0, 0); |
5785 } |