Mercurial > emacs
annotate src/window.c @ 1016:817b0ce337d7
* window.c (Fset_window_configuration): Removed #if 0'd code which
assumes that minibuf_window is on the same frame as the window
configuration. Removed special case for windows whose prevs
point to themselves.
* window.c (Fset_window_configuration): Rename the argument from
ARG to CONFIGURATION, so it matches the docstring. The
make-docfile program cares.
* window.c [MULTI_FRAME] (syms_of_window): Don't staticpro
minibuf_window; the frame list will take care of it.
* window.c (window_loop): This used to keep track of the first
window processed and wait until we came back around to it. Sadly,
this doesn't work if that window gets deleted. So instead, use
Fprevious_window to find the last window to process, and loop
until we've done that one.
* window.c [not MULTI_FRAME] (init_window_once): Don't forget to
set the `mini_p' flag on the new minibuffer window to t.
* window.c (Fwindow_at): Don't check the type of the frame
argument.
* window.c [not MULTI_FRAME] (window_loop): Set frame to zero,
instead of trying to decode it.
* window.c (init_window_once): Initialize minibuf_window before
FRAME_ROOT_WINDOW, so the latter actually points to something.
author | Jim Blandy <jimb@redhat.com> |
---|---|
date | Wed, 19 Aug 1992 06:40:02 +0000 |
parents | eb19dfaec9c4 |
children | 25046e48ce9a |
rev | line source |
---|---|
265 | 1 /* Window creation, deletion and examination for GNU Emacs. |
2 Does not include redisplay. | |
708 | 3 Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc. |
265 | 4 |
5 This file is part of GNU Emacs. | |
6 | |
7 GNU Emacs is free software; you can redistribute it and/or modify | |
8 it under the terms of the GNU General Public License as published by | |
708 | 9 the Free Software Foundation; either version 2, or (at your option) |
265 | 10 any later version. |
11 | |
12 GNU Emacs is distributed in the hope that it will be useful, | |
13 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 GNU General Public License for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with GNU Emacs; see the file COPYING. If not, write to | |
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
20 | |
21 #include "config.h" | |
22 #include "lisp.h" | |
23 #include "buffer.h" | |
769 | 24 #include "frame.h" |
265 | 25 #include "window.h" |
26 #include "commands.h" | |
27 #include "indent.h" | |
28 #include "termchar.h" | |
29 #include "disptab.h" | |
522 | 30 #include "keyboard.h" |
265 | 31 |
32 Lisp_Object Qwindowp; | |
33 | |
34 Lisp_Object Fnext_window (), Fdelete_window (), Fselect_window (); | |
35 Lisp_Object Fset_window_buffer (), Fsplit_window (), Frecenter (); | |
36 | |
37 static void delete_all_subwindows (); | |
38 static struct window *decode_window(); | |
39 | |
40 /* This is the window in which the terminal's cursor should | |
41 be left when nothing is being done with it. This must | |
42 always be a leaf window, and its buffer is selected by | |
43 the top level editing loop at the end of each command. | |
44 | |
45 This value is always the same as | |
769 | 46 FRAME_SELECTED_WINDOW (selected_frame). */ |
265 | 47 |
48 Lisp_Object selected_window; | |
49 | |
769 | 50 /* The minibuffer window of the selected frame. |
265 | 51 Note that you cannot test for minibufferness of an arbitrary window |
52 by comparing against this; but you can test for minibufferness of | |
53 the selected window. */ | |
54 Lisp_Object minibuf_window; | |
55 | |
56 /* Non-nil means it is the window for C-M-v to scroll | |
57 when the minibuffer is selected. */ | |
58 Lisp_Object Vminibuf_scroll_window; | |
59 | |
60 /* Non-nil means this is the buffer whose window C-M-v should scroll. */ | |
61 Lisp_Object Vother_window_scroll_buffer; | |
62 | |
63 /* Window that the mouse is over (nil if no mouse support). */ | |
64 Lisp_Object Vmouse_window; | |
65 | |
66 /* Last mouse click data structure (nil if no mouse support). */ | |
67 Lisp_Object Vmouse_event; | |
68 | |
69 /* Non-nil means it's function to call to display temp buffers. */ | |
70 Lisp_Object Vtemp_buffer_show_function; | |
71 | |
72 /* If a window gets smaller than either of these, it is removed. */ | |
73 int window_min_height; | |
74 int window_min_width; | |
75 | |
76 /* Nonzero implies Fdisplay_buffer should create windows. */ | |
77 int pop_up_windows; | |
78 | |
769 | 79 /* Nonzero implies make new frames for Fdisplay_buffer. */ |
80 int pop_up_frames; | |
265 | 81 |
82 /* Non-nil means use this function instead of default */ | |
769 | 83 Lisp_Object Vpop_up_frame_function; |
265 | 84 |
85 /* Function to call to handle Fdisplay_buffer. */ | |
86 Lisp_Object Vdisplay_buffer_function; | |
87 | |
88 /* Fdisplay_buffer always splits the largest window | |
89 if that window is more than this high. */ | |
90 int split_height_threshold; | |
91 | |
92 /* Number of lines of continuity in scrolling by screenfuls. */ | |
93 int next_screen_context_lines; | |
94 | |
95 /* Incremented for each window created. */ | |
96 static int sequence_number; | |
97 | |
98 #define min(a, b) ((a) < (b) ? (a) : (b)) | |
99 | |
100 DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0, | |
101 "Returns t if OBJ is a window.") | |
102 (obj) | |
103 Lisp_Object obj; | |
104 { | |
105 return XTYPE (obj) == Lisp_Window ? Qt : Qnil; | |
106 } | |
107 | |
108 Lisp_Object | |
109 make_window () | |
110 { | |
111 register Lisp_Object val; | |
112 register struct window *p; | |
113 | |
114 /* Add sizeof (Lisp_Object) here because sizeof (struct Lisp_Vector) | |
115 includes the first element. */ | |
116 val = Fmake_vector ( | |
117 make_number ((sizeof (struct window) - sizeof (struct Lisp_Vector) | |
118 + sizeof (Lisp_Object)) | |
119 / sizeof (Lisp_Object)), | |
120 Qnil); | |
121 XSETTYPE (val, Lisp_Window); | |
122 p = XWINDOW (val); | |
123 XFASTINT (p->sequence_number) = ++sequence_number; | |
124 XFASTINT (p->left) = XFASTINT (p->top) | |
125 = XFASTINT (p->height) = XFASTINT (p->width) | |
126 = XFASTINT (p->hscroll) = 0; | |
127 XFASTINT (p->last_point_x) = XFASTINT (p->last_point_y) = 0; | |
128 p->start = Fmake_marker (); | |
129 p->pointm = Fmake_marker (); | |
130 XFASTINT (p->use_time) = 0; | |
769 | 131 p->frame = Qnil; |
265 | 132 p->display_table = Qnil; |
133 p->dedicated = Qnil; | |
134 return val; | |
135 } | |
136 | |
137 DEFUN ("selected-window", Fselected_window, Sselected_window, 0, 0, 0, | |
138 "Return the window that the cursor now appears in and commands apply to.") | |
139 () | |
140 { | |
141 return selected_window; | |
142 } | |
143 | |
144 DEFUN ("minibuffer-window", Fminibuffer_window, Sminibuffer_window, 0, 0, 0, | |
145 "Return the window used now for minibuffers.") | |
146 () | |
147 { | |
769 | 148 #ifdef MULTI_FRAME |
149 choose_minibuf_frame (); | |
150 #endif /* MULTI_FRAME */ | |
265 | 151 return minibuf_window; |
152 } | |
153 | |
154 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, Swindow_minibuffer_p, 1, 1, 0, | |
155 "Returns non-nil if WINDOW is a minibuffer window.") | |
156 (window) | |
157 Lisp_Object window; | |
158 { | |
159 struct window *w = decode_window (window); | |
160 return (MINI_WINDOW_P (w) ? Qt : Qnil); | |
161 } | |
162 | |
163 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p, | |
164 Spos_visible_in_window_p, 0, 2, 0, | |
769 | 165 "Return t if position POS is currently on the frame in WINDOW.\n\ |
265 | 166 Returns nil if that position is scrolled vertically out of view.\n\ |
167 POS defaults to point; WINDOW, to the selected window.") | |
168 (pos, window) | |
169 Lisp_Object pos, window; | |
170 { | |
171 register struct window *w; | |
172 register int top; | |
173 register int height; | |
174 register int posint; | |
175 register struct buffer *buf; | |
176 struct position posval; | |
177 | |
485 | 178 if (NILP (pos)) |
265 | 179 posint = point; |
180 else | |
181 { | |
182 CHECK_NUMBER_COERCE_MARKER (pos, 0); | |
183 posint = XINT (pos); | |
184 } | |
185 | |
485 | 186 if (NILP (window)) |
265 | 187 window = selected_window; |
188 else | |
189 CHECK_WINDOW (window, 1); | |
190 w = XWINDOW (window); | |
191 top = marker_position (w->start); | |
192 | |
193 if (posint < top) | |
194 return Qnil; | |
195 | |
196 height = XFASTINT (w->height) - ! MINI_WINDOW_P (w); | |
197 | |
198 buf = XBUFFER (w->buffer); | |
199 if (XFASTINT (w->last_modified) >= BUF_MODIFF (buf)) | |
200 { | |
769 | 201 /* If frame is up to date, |
265 | 202 use the info recorded about how much text fit on it. */ |
203 if (posint < BUF_Z (buf) - XFASTINT (w->window_end_pos) | |
204 || (XFASTINT (w->window_end_vpos) < height)) | |
205 return Qt; | |
206 return Qnil; | |
207 } | |
208 else | |
209 { | |
210 if (posint > BUF_Z (buf)) | |
211 return Qnil; | |
212 | |
213 /* If that info is not correct, calculate afresh */ | |
214 posval = *compute_motion (top, 0, 0, posint, height, 0, | |
215 XFASTINT (w->width) - 1 | |
216 - (XFASTINT (w->width) + XFASTINT (w->left) | |
769 | 217 != FRAME_WIDTH (XFRAME (w->frame))), |
265 | 218 XINT (w->hscroll), 0); |
219 | |
220 return posval.vpos < height ? Qt : Qnil; | |
221 } | |
222 } | |
223 | |
224 static struct window * | |
225 decode_window (window) | |
226 register Lisp_Object window; | |
227 { | |
485 | 228 if (NILP (window)) |
265 | 229 return XWINDOW (selected_window); |
230 | |
231 CHECK_WINDOW (window, 0); | |
232 return XWINDOW (window); | |
233 } | |
234 | |
235 DEFUN ("window-buffer", Fwindow_buffer, Swindow_buffer, 0, 1, 0, | |
236 "Return the buffer that WINDOW is displaying.") | |
237 (window) | |
238 Lisp_Object window; | |
239 { | |
240 return decode_window (window)->buffer; | |
241 } | |
242 | |
243 DEFUN ("window-height", Fwindow_height, Swindow_height, 0, 1, 0, | |
244 "Return the number of lines in WINDOW (including its mode line).") | |
245 (window) | |
246 Lisp_Object window; | |
247 { | |
248 return decode_window (window)->height; | |
249 } | |
250 | |
251 DEFUN ("window-width", Fwindow_width, Swindow_width, 0, 1, 0, | |
252 "Return the number of columns in WINDOW.") | |
253 (window) | |
254 Lisp_Object window; | |
255 { | |
256 register struct window *w = decode_window (window); | |
257 register int width = w->width; | |
258 | |
259 /* If this window does not end at the right margin, | |
260 must deduct one column for the border */ | |
769 | 261 if ((width + w->left) == FRAME_WIDTH (XFRAME (WINDOW_FRAME (w)))) |
265 | 262 return width; |
263 return width - 1; | |
264 } | |
265 | |
266 DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0, | |
267 "Return the number of columns by which WINDOW is scrolled from left margin.") | |
268 (window) | |
269 Lisp_Object window; | |
270 { | |
271 return decode_window (window)->hscroll; | |
272 } | |
273 | |
274 DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0, | |
275 "Set number of columns WINDOW is scrolled from left margin to NCOL.\n\ | |
276 NCOL should be zero or positive.") | |
277 (window, ncol) | |
278 register Lisp_Object window, ncol; | |
279 { | |
280 register struct window *w; | |
281 | |
282 CHECK_NUMBER (ncol, 1); | |
283 if (XINT (ncol) < 0) XFASTINT (ncol) = 0; | |
284 if (XFASTINT (ncol) >= (1 << (SHORTBITS - 1))) | |
285 args_out_of_range (ncol, Qnil); | |
286 w = decode_window (window); | |
287 if (w->hscroll != ncol) | |
288 clip_changed = 1; /* Prevent redisplay shortcuts */ | |
289 w->hscroll = ncol; | |
290 return ncol; | |
291 } | |
292 | |
293 DEFUN ("window-edges", Fwindow_edges, Swindow_edges, 0, 1, 0, | |
294 "Return a list of the edge coordinates of WINDOW.\n\ | |
769 | 295 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.\n\ |
265 | 296 RIGHT is one more than the rightmost column used by WINDOW,\n\ |
297 and BOTTOM is one more than the bottommost row used by WINDOW\n\ | |
298 and its mode-line.") | |
299 (window) | |
300 Lisp_Object window; | |
301 { | |
302 register struct window *w = decode_window (window); | |
303 | |
304 return Fcons (w->left, Fcons (w->top, | |
305 Fcons (make_number (XFASTINT (w->left) + XFASTINT (w->width)), | |
306 Fcons (make_number (XFASTINT (w->top) | |
307 + XFASTINT (w->height)), | |
308 Qnil)))); | |
309 } | |
310 | |
432 | 311 /* Test if the character at column *x, row *y is within window *w. |
312 If it is not, return 0; | |
313 if it is in the window's text area, | |
314 set *x and *y to its location relative to the upper left corner | |
315 of the window, and | |
316 return 1; | |
317 if it is on the window's modeline, return 2; | |
318 if it is on the border between the window and its right sibling, | |
319 return 3. */ | |
320 static int | |
321 coordinates_in_window (w, x, y) | |
322 register struct window *w; | |
323 register int *x, *y; | |
324 { | |
325 register int left = XINT (w->left); | |
326 register int width = XINT (w->width); | |
327 register int window_height = XINT (w->height); | |
328 register int top = XFASTINT (w->top); | |
329 | |
330 if ( *x < left || *x >= left + width | |
331 || *y < top || *y >= top + window_height) | |
332 return 0; | |
333 | |
334 /* Is the character is the mode line? */ | |
335 if (*y == top + window_height - 1 | |
336 && window_height > 1) /* 1 line => minibuffer */ | |
337 return 2; | |
338 | |
339 /* Is the character in the right border? */ | |
340 if (*x == left + width - 1 | |
769 | 341 && left + width != FRAME_WIDTH (XFRAME (w->frame))) |
432 | 342 return 3; |
343 | |
344 *x -= left; | |
345 *y -= top; | |
346 return 1; | |
347 } | |
348 | |
349 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p, | |
350 Scoordinates_in_window_p, 2, 2, 0, | |
351 "Return non-nil if COORDINATES are in WINDOW.\n\ | |
708 | 352 COORDINATES is a cons of the form (X . Y), X and Y being distances\n\ |
769 | 353 measured in characters from the upper-left corner of the frame.\n\ |
708 | 354 (0 . 0) denotes the character in the upper left corner of the\n\ |
769 | 355 frame.\n\ |
432 | 356 If COORDINATES are in the text portion of WINDOW,\n\ |
357 the coordinates relative to the window are returned.\n\ | |
732 | 358 If they are in the mode line of WINDOW, `mode-line' is returned.\n\ |
432 | 359 If they are on the border between WINDOW and its right sibling,\n\ |
732 | 360 `vertical-line' is returned.") |
432 | 361 (coordinates, window) |
362 register Lisp_Object coordinates, window; | |
363 { | |
364 int x, y; | |
365 | |
366 CHECK_WINDOW (window, 0); | |
367 CHECK_CONS (coordinates, 1); | |
368 x = XINT (Fcar (coordinates)); | |
369 y = XINT (Fcdr (coordinates)); | |
370 | |
371 switch (coordinates_in_window (XWINDOW (window), &x, &y)) | |
372 { | |
373 case 0: /* NOT in window at all. */ | |
374 return Qnil; | |
375 | |
376 case 1: /* In text part of window. */ | |
377 return Fcons (x, y); | |
378 | |
379 case 2: /* In mode line of window. */ | |
380 return Qmode_line; | |
381 | |
382 case 3: /* On right border of window. */ | |
732 | 383 return Qvertical_line; |
432 | 384 |
385 default: | |
386 abort (); | |
387 } | |
388 } | |
389 | |
265 | 390 /* Find the window containing column x, row y, and return it as a |
432 | 391 Lisp_Object. If x, y is on the window's modeline, set *part |
392 to 1; if it is on the separating line between the window and its | |
393 right sibling, set it to 2; otherwise set it to 0. If there is no | |
394 window under x, y return nil and leave *part unmodified. */ | |
265 | 395 Lisp_Object |
769 | 396 window_from_coordinates (frame, x, y, part) |
397 FRAME_PTR frame; | |
265 | 398 int x, y; |
432 | 399 int *part; |
265 | 400 { |
401 register Lisp_Object tem, first; | |
402 | |
769 | 403 tem = first = FRAME_SELECTED_WINDOW (frame); |
265 | 404 |
432 | 405 do |
265 | 406 { |
407 int found = coordinates_in_window (XWINDOW (tem), &x, &y); | |
408 | |
409 if (found) | |
410 { | |
432 | 411 *part = found - 1; |
265 | 412 return tem; |
413 } | |
414 | |
432 | 415 tem = Fnext_window (tem, Qt, Qlambda); |
265 | 416 } |
432 | 417 while (! EQ (tem, first)); |
418 | |
419 return Qnil; | |
265 | 420 } |
421 | |
681
026f978690be
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
555
diff
changeset
|
422 DEFUN ("window-at", Fwindow_at, Swindow_at, 2, 3, 0, |
769 | 423 "Return window containing row ROW, column COLUMN on FRAME.\n\ |
424 If omitted, FRAME defaults to the currently selected frame.\n\ | |
425 The top left corner of the frame is considered to be row 0,\n\ | |
548 | 426 column 0.") |
769 | 427 (row, column, frame) |
428 Lisp_Object row, column, frame; | |
265 | 429 { |
430 int part; | |
431 | |
983
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
432 #ifdef MULTI_FRAME |
769 | 433 if (NILP (frame)) |
434 XSET (frame, Lisp_Frame, selected_frame); | |
432 | 435 else |
769 | 436 CHECK_LIVE_FRAME (frame, 2); |
983
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
437 #endif |
548 | 438 CHECK_NUMBER (row, 0); |
439 CHECK_NUMBER (column, 1); | |
265 | 440 |
769 | 441 return window_from_coordinates (XFRAME (frame), |
548 | 442 XINT (row), XINT (column), |
265 | 443 &part); |
444 } | |
445 | |
446 DEFUN ("window-point", Fwindow_point, Swindow_point, 0, 1, 0, | |
447 "Return current value of point in WINDOW.\n\ | |
448 For a nonselected window, this is the value point would have\n\ | |
449 if that window were selected.\n\ | |
450 \n\ | |
451 Note that, when WINDOW is the selected window and its buffer\n\ | |
452 is also currently selected, the value returned is the same as (point).\n\ | |
453 It would be more strictly correct to return the `top-level' value\n\ | |
454 of point, outside of any save-excursion forms.\n\ | |
455 But that is hard to define.") | |
456 (window) | |
457 Lisp_Object window; | |
458 { | |
459 register struct window *w = decode_window (window); | |
460 | |
461 if (w == XWINDOW (selected_window) | |
462 && current_buffer == XBUFFER (w->buffer)) | |
463 return Fpoint (); | |
464 return Fmarker_position (w->pointm); | |
465 } | |
466 | |
467 DEFUN ("window-start", Fwindow_start, Swindow_start, 0, 1, 0, | |
468 "Return position at which display currently starts in WINDOW.") | |
469 (window) | |
470 Lisp_Object window; | |
471 { | |
472 return Fmarker_position (decode_window (window)->start); | |
473 } | |
474 | |
475 DEFUN ("window-end", Fwindow_end, Swindow_end, 0, 1, 0, | |
476 "Return position at which display currently ends in WINDOW.") | |
477 (window) | |
478 Lisp_Object window; | |
479 { | |
480 Lisp_Object value; | |
481 struct window *w = decode_window (window); | |
482 | |
483 XSET (value, Lisp_Int, | |
484 BUF_Z (current_buffer) - XFASTINT (w->window_end_pos)); | |
485 | |
486 return value; | |
487 } | |
488 | |
489 DEFUN ("set-window-point", Fset_window_point, Sset_window_point, 2, 2, 0, | |
490 "Make point value in WINDOW be at position POS in WINDOW's buffer.") | |
491 (window, pos) | |
492 Lisp_Object window, pos; | |
493 { | |
494 register struct window *w = decode_window (window); | |
495 | |
496 CHECK_NUMBER_COERCE_MARKER (pos, 1); | |
497 if (w == XWINDOW (selected_window)) | |
498 Fgoto_char (pos); | |
499 else | |
500 set_marker_restricted (w->pointm, pos, w->buffer); | |
501 | |
502 return pos; | |
503 } | |
504 | |
505 DEFUN ("set-window-start", Fset_window_start, Sset_window_start, 2, 3, 0, | |
506 "Make display in WINDOW start at position POS in WINDOW's buffer.\n\ | |
507 Optional third arg NOFORCE non-nil inhibits next redisplay\n\ | |
508 from overriding motion of point in order to display at this exact start.") | |
509 (window, pos, noforce) | |
510 Lisp_Object window, pos, noforce; | |
511 { | |
512 register struct window *w = decode_window (window); | |
513 | |
514 CHECK_NUMBER_COERCE_MARKER (pos, 1); | |
515 set_marker_restricted (w->start, pos, w->buffer); | |
516 /* this is not right, but much easier than doing what is right. */ | |
517 w->start_at_line_beg = Qnil; | |
485 | 518 if (NILP (noforce)) |
265 | 519 w->force_start = Qt; |
520 w->update_mode_line = Qt; | |
521 XFASTINT (w->last_modified) = 0; | |
338 | 522 if (!EQ (window, selected_window)) |
523 windows_or_buffers_changed++; | |
265 | 524 return pos; |
525 } | |
526 | |
527 DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p, | |
528 1, 1, 0, | |
529 "Return WINDOW's dedicated object, usually t or nil.\n\ | |
530 See also `set-window-buffer-dedicated'.") | |
531 (window) | |
532 Lisp_Object window; | |
533 { | |
534 return decode_window (window)->dedicated; | |
535 } | |
536 | |
722
0a2391511b46
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
708
diff
changeset
|
537 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p, |
0a2391511b46
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
708
diff
changeset
|
538 Sset_window_dedicated_p, 2, 2, 0, |
0a2391511b46
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
708
diff
changeset
|
539 "Control whether WINDOW is dedicated to the buffer it displays.\n\ |
0a2391511b46
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
708
diff
changeset
|
540 If it is dedicated, Emacs will not automatically change\n\ |
0a2391511b46
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
708
diff
changeset
|
541 which buffer appears in it.\n\ |
0a2391511b46
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
708
diff
changeset
|
542 The second argument is the new value for the dedication flag;\n\ |
0a2391511b46
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
708
diff
changeset
|
543 non-nil means yes.") |
265 | 544 (window, arg) |
545 Lisp_Object window, arg; | |
546 { | |
547 register struct window *w = decode_window (window); | |
548 | |
485 | 549 if (NILP (arg)) |
265 | 550 w->dedicated = Qnil; |
551 else | |
722
0a2391511b46
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
708
diff
changeset
|
552 w->dedicated = Qt; |
265 | 553 |
554 return w->dedicated; | |
555 } | |
556 | |
557 DEFUN ("window-display-table", Fwindow_display_table, Swindow_display_table, | |
558 0, 1, 0, | |
559 "Return the display-table that WINDOW is using.") | |
560 (window) | |
561 Lisp_Object window; | |
562 { | |
563 return decode_window (window)->display_table; | |
564 } | |
565 | |
566 /* Get the display table for use currently on window W. | |
567 This is either W's display table or W's buffer's display table. | |
568 Ignore the specified tables if they are not valid; | |
569 if no valid table is specified, return 0. */ | |
570 | |
571 struct Lisp_Vector * | |
572 window_display_table (w) | |
573 struct window *w; | |
574 { | |
575 Lisp_Object tem; | |
576 tem = w->display_table; | |
577 if (XTYPE (tem) == Lisp_Vector && XVECTOR (tem)->size == DISP_TABLE_SIZE) | |
578 return XVECTOR (tem); | |
579 tem = XBUFFER (w->buffer)->display_table; | |
580 if (XTYPE (tem) == Lisp_Vector && XVECTOR (tem)->size == DISP_TABLE_SIZE) | |
581 return XVECTOR (tem); | |
582 tem = Vstandard_display_table; | |
583 if (XTYPE (tem) == Lisp_Vector && XVECTOR (tem)->size == DISP_TABLE_SIZE) | |
584 return XVECTOR (tem); | |
585 return 0; | |
586 } | |
587 | |
555 | 588 DEFUN ("set-window-display-table", Fset_window_display_table, Sset_window_display_table, 2, 2, 0, |
265 | 589 "Set WINDOW's display-table to TABLE.") |
590 (window, table) | |
591 register Lisp_Object window, table; | |
592 { | |
593 register struct window *w; | |
594 register Lisp_Object z; /* Return value. */ | |
595 | |
596 w = decode_window (window); | |
597 w->display_table = table; | |
598 return table; | |
599 } | |
600 | |
601 /* Record info on buffer window w is displaying | |
602 when it is about to cease to display that buffer. */ | |
603 static | |
604 unshow_buffer (w) | |
605 register struct window *w; | |
606 { | |
607 Lisp_Object buf = w->buffer; | |
608 | |
609 if (XBUFFER (buf) != XMARKER (w->pointm)->buffer) | |
610 abort (); | |
611 | |
612 if (w == XWINDOW (selected_window) | |
613 || ! EQ (buf, XWINDOW (selected_window)->buffer)) | |
614 /* Do this except when the selected window's buffer | |
615 is being removed from some other window. */ | |
616 XBUFFER (buf)->last_window_start = marker_position (w->start); | |
617 | |
618 /* Point in the selected window's buffer | |
619 is actually stored in that buffer, and the window's pointm isn't used. | |
620 So don't clobber point in that buffer. */ | |
621 if (! EQ (buf, XWINDOW (selected_window)->buffer)) | |
622 BUF_PT (XBUFFER (buf)) | |
623 = clip_to_bounds (BUF_BEGV (XBUFFER (buf)), | |
624 marker_position (w->pointm), | |
625 BUF_ZV (XBUFFER (buf))); | |
626 } | |
627 | |
628 /* Put replacement into the window structure in place of old. */ | |
629 static | |
630 replace_window (old, replacement) | |
631 Lisp_Object old, replacement; | |
632 { | |
633 register Lisp_Object tem; | |
634 register struct window *o = XWINDOW (old), *p = XWINDOW (replacement); | |
635 | |
769 | 636 /* If OLD is its frame's root_window, then replacement is the new |
637 root_window for that frame. */ | |
265 | 638 |
769 | 639 if (old == FRAME_ROOT_WINDOW (XFRAME (o->frame))) |
640 FRAME_ROOT_WINDOW (XFRAME (o->frame)) = replacement; | |
265 | 641 |
642 p->left = o->left; | |
643 p->top = o->top; | |
644 p->width = o->width; | |
645 p->height = o->height; | |
646 | |
647 p->next = tem = o->next; | |
485 | 648 if (!NILP (tem)) |
265 | 649 XWINDOW (tem)->prev = replacement; |
650 | |
651 p->prev = tem = o->prev; | |
485 | 652 if (!NILP (tem)) |
265 | 653 XWINDOW (tem)->next = replacement; |
654 | |
655 p->parent = tem = o->parent; | |
485 | 656 if (!NILP (tem)) |
265 | 657 { |
658 if (EQ (XWINDOW (tem)->vchild, old)) | |
659 XWINDOW (tem)->vchild = replacement; | |
660 if (EQ (XWINDOW (tem)->hchild, old)) | |
661 XWINDOW (tem)->hchild = replacement; | |
662 } | |
663 | |
664 /*** Here, if replacement is a vertical combination | |
665 and so is its new parent, we should make replacement's | |
666 children be children of that parent instead. ***/ | |
667 } | |
668 | |
669 DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "", | |
670 "Remove WINDOW from the display. Default is selected window.") | |
671 (window) | |
672 register Lisp_Object window; | |
673 { | |
674 register Lisp_Object tem, parent, sib; | |
675 register struct window *p; | |
676 register struct window *par; | |
677 | |
485 | 678 if (NILP (window)) |
265 | 679 window = selected_window; |
680 else | |
681 CHECK_WINDOW (window, 0); | |
682 | |
683 p = XWINDOW (window); | |
684 parent = p->parent; | |
485 | 685 if (NILP (parent)) |
265 | 686 error ("Attempt to delete minibuffer or sole ordinary window"); |
687 par = XWINDOW (parent); | |
688 | |
689 windows_or_buffers_changed++; | |
690 | |
691 if (EQ (window, selected_window)) | |
692 Fselect_window (Fnext_window (window, Qnil, Qnil)); | |
693 | |
694 tem = p->buffer; | |
695 /* tem is null for dummy parent windows | |
696 (which have inferiors but not any contents themselves) */ | |
485 | 697 if (!NILP (tem)) |
265 | 698 { |
699 unshow_buffer (p); | |
700 unchain_marker (p->pointm); | |
701 unchain_marker (p->start); | |
702 p->buffer = Qnil; | |
703 } | |
704 | |
705 tem = p->next; | |
485 | 706 if (!NILP (tem)) |
265 | 707 XWINDOW (tem)->prev = p->prev; |
708 | |
709 tem = p->prev; | |
485 | 710 if (!NILP (tem)) |
265 | 711 XWINDOW (tem)->next = p->next; |
712 | |
713 if (EQ (window, par->hchild)) | |
714 par->hchild = p->next; | |
715 if (EQ (window, par->vchild)) | |
716 par->vchild = p->next; | |
717 | |
718 /* Find one of our siblings to give our space to. */ | |
719 sib = p->prev; | |
485 | 720 if (NILP (sib)) |
265 | 721 { |
722 /* If p gives its space to its next sibling, that sibling needs | |
723 to have its top/left side pulled back to where p's is. | |
724 set_window_{height,width} will re-position the sibling's | |
725 children. */ | |
726 sib = p->next; | |
727 XFASTINT (XWINDOW (sib)->top) = p->top; | |
728 XFASTINT (XWINDOW (sib)->left) = p->left; | |
729 } | |
730 | |
731 /* Stretch that sibling. */ | |
485 | 732 if (!NILP (par->vchild)) |
265 | 733 set_window_height (sib, |
734 XFASTINT (XWINDOW (sib)->height) + XFASTINT (p->height), | |
735 1); | |
485 | 736 if (!NILP (par->hchild)) |
265 | 737 set_window_width (sib, |
738 XFASTINT (XWINDOW (sib)->width) + XFASTINT (p->width), | |
739 1); | |
740 | |
741 /* If parent now has only one child, | |
742 put the child into the parent's place. */ | |
743 | |
744 tem = par->hchild; | |
485 | 745 if (NILP (tem)) |
265 | 746 tem = par->vchild; |
485 | 747 if (NILP (XWINDOW (tem)->next)) |
265 | 748 replace_window (parent, tem); |
749 return Qnil; | |
750 } | |
751 | |
432 | 752 |
769 | 753 extern Lisp_Object next_frame (), prev_frame (); |
432 | 754 |
755 DEFUN ("next-window", Fnext_window, Snext_window, 0, 3, 0, | |
756 "Return next window after WINDOW in canonical ordering of windows.\n\ | |
757 If omitted, WINDOW defaults to the selected window.\n\ | |
758 \n\ | |
759 Optional second arg MINIBUF t means count the minibuffer window even\n\ | |
760 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\ | |
761 it is active. MINIBUF neither t nor nil means not to count the\n\ | |
762 minibuffer even if it is active.\n\ | |
763 \n\ | |
769 | 764 Several frames may share a single minibuffer; if the minibuffer\n\ |
765 counts, all windows on all frames that share that minibuffer count\n\ | |
432 | 766 too. This means that next-window may be used to iterate through the\n\ |
769 | 767 set of windows even when the minibuffer is on another frame. If the\n\ |
768 minibuffer does not count, only windows from WINDOW's frame count.\n\ | |
432 | 769 \n\ |
769 | 770 Optional third arg ALL-FRAMES t means include windows on all frames.\n\ |
771 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\ | |
772 above. If neither nil nor t, restrict to WINDOW's frame.") | |
773 (window, minibuf, all_frames) | |
774 register Lisp_Object window, minibuf, all_frames; | |
265 | 775 { |
432 | 776 register Lisp_Object tem; |
777 Lisp_Object start_window; | |
265 | 778 |
485 | 779 if (NILP (window)) |
432 | 780 window = selected_window; |
781 else | |
782 CHECK_WINDOW (window, 0); | |
783 | |
784 start_window = window; | |
785 | |
786 /* minibuf == nil may or may not include minibuffers. | |
787 Decide if it does. */ | |
485 | 788 if (NILP (minibuf)) |
432 | 789 minibuf = (minibuf_level ? Qt : Qlambda); |
790 | |
769 | 791 /* all_frames == nil doesn't specify which frames to include. |
792 Decide which frames it includes. */ | |
793 if (NILP (all_frames)) | |
794 all_frames = (EQ (minibuf, Qt) | |
795 ? (FRAME_MINIBUF_WINDOW | |
796 (XFRAME | |
797 (WINDOW_FRAME | |
432 | 798 (XWINDOW (window))))) |
799 : Qnil); | |
769 | 800 else if (! EQ (all_frames, Qt)) |
801 all_frames = Qnil; | |
432 | 802 |
265 | 803 /* Do this loop at least once, to get the next window, and perhaps |
804 again, if we hit the minibuffer and that is not acceptable. */ | |
805 do | |
806 { | |
807 /* Find a window that actually has a next one. This loop | |
808 climbs up the tree. */ | |
485 | 809 while (tem = XWINDOW (window)->next, NILP (tem)) |
810 if (tem = XWINDOW (window)->parent, !NILP (tem)) | |
265 | 811 window = tem; |
432 | 812 else |
265 | 813 { |
769 | 814 /* We've reached the end of this frame. |
815 Which other frames are acceptable? */ | |
816 tem = WINDOW_FRAME (XWINDOW (window)); | |
817 #ifdef MULTI_FRAME | |
818 if (! NILP (all_frames)) | |
819 tem = next_frame (tem, all_frames); | |
432 | 820 #endif |
769 | 821 tem = FRAME_ROOT_WINDOW (XFRAME (tem)); |
432 | 822 |
265 | 823 break; |
824 } | |
825 | |
826 window = tem; | |
432 | 827 |
265 | 828 /* If we're in a combination window, find its first child and |
829 recurse on that. Otherwise, we've found the window we want. */ | |
830 while (1) | |
831 { | |
485 | 832 if (!NILP (XWINDOW (window)->hchild)) |
265 | 833 window = XWINDOW (window)->hchild; |
485 | 834 else if (!NILP (XWINDOW (window)->vchild)) |
265 | 835 window = XWINDOW (window)->vchild; |
836 else break; | |
837 } | |
838 } | |
432 | 839 /* Which windows are acceptible? |
840 Exit the loop and accept this window if | |
265 | 841 this isn't a minibuffer window, or |
432 | 842 we're accepting minibuffer windows, or |
843 we've come all the way around and we're back at the original window. */ | |
265 | 844 while (MINI_WINDOW_P (XWINDOW (window)) |
432 | 845 && ! EQ (minibuf, Qt) |
846 && window != start_window); | |
265 | 847 |
848 return window; | |
849 } | |
850 | |
432 | 851 DEFUN ("previous-window", Fprevious_window, Sprevious_window, 0, 3, 0, |
852 "Return the window preceeding WINDOW in canonical ordering of windows.\n\ | |
853 If omitted, WINDOW defaults to the selected window.\n\ | |
854 \n\ | |
855 Optional second arg MINIBUF t means count the minibuffer window even\n\ | |
856 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\ | |
857 it is active. MINIBUF neither t nor nil means not to count the\n\ | |
858 minibuffer even if it is active.\n\ | |
859 \n\ | |
769 | 860 Several frames may share a single minibuffer; if the minibuffer\n\ |
861 counts, all windows on all frames that share that minibuffer count\n\ | |
432 | 862 too. This means that previous-window may be used to iterate through\n\ |
769 | 863 the set of windows even when the minibuffer is on another frame. If\n\ |
864 the minibuffer does not count, only windows from WINDOW's frame\n\ | |
432 | 865 count.\n\ |
866 \n\ | |
769 | 867 Optional third arg ALL-FRAMES t means include windows on all frames.\n\ |
868 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\ | |
869 above. If neither nil nor t, restrict to WINDOW's frame.") | |
870 (window, minibuf, all_frames) | |
871 register Lisp_Object window, minibuf, all_frames; | |
265 | 872 { |
873 register Lisp_Object tem; | |
432 | 874 Lisp_Object start_window; |
265 | 875 |
485 | 876 if (NILP (window)) |
265 | 877 window = selected_window; |
878 else | |
879 CHECK_WINDOW (window, 0); | |
880 | |
432 | 881 start_window = window; |
265 | 882 |
432 | 883 /* minibuf == nil may or may not include minibuffers. |
884 Decide if it does. */ | |
485 | 885 if (NILP (minibuf)) |
432 | 886 minibuf = (minibuf_level ? Qt : Qlambda); |
265 | 887 |
769 | 888 /* all_frames == nil doesn't specify which frames to include. |
889 Decide which frames it includes. */ | |
890 if (NILP (all_frames)) | |
891 all_frames = (EQ (minibuf, Qt) | |
892 ? (FRAME_MINIBUF_WINDOW | |
893 (XFRAME | |
894 (WINDOW_FRAME | |
432 | 895 (XWINDOW (window))))) |
896 : Qnil); | |
769 | 897 else if (! EQ (all_frames, Qt)) |
898 all_frames = Qnil; | |
265 | 899 |
900 /* Do this loop at least once, to get the previous window, and perhaps | |
901 again, if we hit the minibuffer and that is not acceptable. */ | |
902 do | |
903 { | |
904 /* Find a window that actually has a previous one. This loop | |
905 climbs up the tree. */ | |
485 | 906 while (tem = XWINDOW (window)->prev, NILP (tem)) |
907 if (tem = XWINDOW (window)->parent, !NILP (tem)) | |
265 | 908 window = tem; |
432 | 909 else |
265 | 910 { |
769 | 911 /* We have found the top window on the frame. |
912 Which frames are acceptable? */ | |
913 tem = WINDOW_FRAME (XWINDOW (window)); | |
914 #ifdef MULTI_FRAME | |
915 if (! NILP (all_frames)) | |
916 tem = next_frame (tem, all_frames); | |
265 | 917 #endif |
769 | 918 tem = FRAME_ROOT_WINDOW (XFRAME (tem)); |
432 | 919 |
265 | 920 break; |
921 } | |
922 | |
923 window = tem; | |
924 /* If we're in a combination window, find its last child and | |
925 recurse on that. Otherwise, we've found the window we want. */ | |
926 while (1) | |
927 { | |
485 | 928 if (!NILP (XWINDOW (window)->hchild)) |
265 | 929 window = XWINDOW (window)->hchild; |
485 | 930 else if (!NILP (XWINDOW (window)->vchild)) |
265 | 931 window = XWINDOW (window)->vchild; |
932 else break; | |
485 | 933 while (tem = XWINDOW (window)->next, !NILP (tem)) |
265 | 934 window = tem; |
935 } | |
936 } | |
432 | 937 /* Which windows are acceptable? |
938 Exit the loop and accept this window if | |
265 | 939 this isn't a minibuffer window, or |
432 | 940 we're accepting minibuffer windows, or |
941 we've come all the way around and we're back at the original window. */ | |
265 | 942 while (MINI_WINDOW_P (XWINDOW (window)) |
432 | 943 && !EQ (minibuf, Qt) |
944 && window != start_window); | |
265 | 945 |
946 return window; | |
947 } | |
948 | |
338 | 949 DEFUN ("other-window", Fother_window, Sother_window, 1, 2, "p", |
769 | 950 "Select the ARG'th different window on this frame.\n\ |
951 All windows on current frame are arranged in a cyclic order.\n\ | |
265 | 952 This command selects the window ARG steps away in that order.\n\ |
953 A negative ARG moves in the opposite order. If the optional second\n\ | |
769 | 954 argument ALL_FRAMES is non-nil, cycle through all frames.") |
955 (n, all_frames) | |
956 register Lisp_Object n, all_frames; | |
265 | 957 { |
958 register int i; | |
959 register Lisp_Object w; | |
960 | |
961 CHECK_NUMBER (n, 0); | |
962 w = selected_window; | |
963 i = XINT (n); | |
964 | |
965 while (i > 0) | |
966 { | |
769 | 967 w = Fnext_window (w, Qnil, all_frames); |
265 | 968 i--; |
969 } | |
970 while (i < 0) | |
971 { | |
769 | 972 w = Fprevious_window (w, Qnil, all_frames); |
265 | 973 i++; |
974 } | |
975 Fselect_window (w); | |
976 return Qnil; | |
977 } | |
978 | |
979 /* Look at all windows, performing an operation specified by TYPE | |
980 with argument OBJ. | |
769 | 981 If FRAMES is Qt, look at all frames, if Qnil, look at just the selected |
982 frame. If FRAMES is a frame, just look at windows on that frame. | |
265 | 983 If MINI is non-zero, perform the operation on minibuffer windows too. |
984 */ | |
985 | |
986 enum window_loop | |
987 { | |
988 WINDOW_LOOP_UNUSED, | |
989 GET_BUFFER_WINDOW, /* Arg is buffer */ | |
990 GET_LRU_WINDOW, /* Arg is t for full-width windows only */ | |
991 DELETE_OTHER_WINDOWS, /* Arg is window not to delete */ | |
992 DELETE_BUFFER_WINDOWS, /* Arg is buffer */ | |
993 GET_LARGEST_WINDOW, | |
994 UNSHOW_BUFFER, /* Arg is buffer */ | |
995 }; | |
996 | |
997 static Lisp_Object | |
769 | 998 window_loop (type, obj, mini, frames) |
265 | 999 enum window_loop type; |
769 | 1000 register Lisp_Object obj, frames; |
265 | 1001 int mini; |
1002 { | |
1003 register Lisp_Object w; | |
1004 register Lisp_Object best_window; | |
1005 register Lisp_Object next_window; | |
983
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1006 register Lisp_Object last_window; |
769 | 1007 FRAME_PTR frame; |
265 | 1008 |
983
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1009 #ifdef MULTI_FRAME |
769 | 1010 /* If we're only looping through windows on a particular frame, |
1011 frame points to that frame. If we're looping through windows | |
1012 on all frames, frame is 0. */ | |
1013 if (FRAMEP (frames)) | |
1014 frame = XFRAME (frames); | |
1015 else if (NILP (frames)) | |
1016 frame = selected_frame; | |
265 | 1017 else |
769 | 1018 frame = 0; |
983
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1019 #else |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1020 frame = 0; |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1021 #endif |
265 | 1022 |
1023 /* Pick a window to start with. */ | |
1024 if (XTYPE (obj) == Lisp_Window) | |
983
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1025 w = obj; |
769 | 1026 else if (frame) |
983
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1027 w = FRAME_SELECTED_WINDOW (frame); |
265 | 1028 else |
983
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1029 w = FRAME_SELECTED_WINDOW (selected_frame); |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1030 |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1031 /* Figure out the last window we're going to mess with. Since |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1032 Fnext_window, given the same options, is guaranteed to go in a |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1033 ring, we can just use Fprevious_window to find the last one. |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1034 |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1035 We can't just wait until we hit the first window again, because |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1036 it might be deleted. */ |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1037 |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1038 #ifdef MULTI_FRAME |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1039 if (frame) |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1040 last_window = Fprevious_window (w, (mini ? Qt : Qnil), Qlambda); |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1041 else |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1042 #endif /* MULTI_FRAME */ |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1043 /* We know frame is 0, so we're looping through all frames. |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1044 Or we know this isn't a MULTI_FRAME Emacs, so who cares? */ |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1045 last_window = Fprevious_window (w, mini ? Qt : Qnil, Qt); |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1046 |
265 | 1047 best_window = Qnil; |
983
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1048 for (;;) |
265 | 1049 { |
1050 /* Pick the next window now, since some operations will delete | |
1051 the current window. */ | |
769 | 1052 #ifdef MULTI_FRAME |
1053 if (frame) | |
432 | 1054 next_window = Fnext_window (w, (mini ? Qt : Qnil), Qlambda); |
265 | 1055 else |
983
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1056 #endif /* MULTI_FRAME */ |
769 | 1057 /* We know frame is 0, so we're looping through all frames. |
1058 Or we know this isn't a MULTI_FRAME Emacs, so who cares? */ | |
265 | 1059 next_window = Fnext_window (w, mini ? Qt : Qnil, Qt); |
1060 | |
1061 if (!MINI_WINDOW_P (XWINDOW (w)) | |
1062 || (mini && minibuf_level > 0)) | |
1063 switch (type) | |
1064 { | |
1065 case GET_BUFFER_WINDOW: | |
1066 #if 0 | |
769 | 1067 /* Ignore invisible and iconified frames. */ |
1068 if (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (w)))) | |
1069 || FRAME_ICONIFIED_P (XFRAME (WINDOW_FRAME (XWINDOW (w))))) | |
265 | 1070 break; |
1071 #endif | |
1072 if (XBUFFER (XWINDOW (w)->buffer) == XBUFFER (obj)) | |
1073 return w; | |
1074 break; | |
1075 | |
1076 case GET_LRU_WINDOW: | |
1077 /* t as arg means consider only full-width windows */ | |
732 | 1078 if (!NILP (obj) && XFASTINT (XWINDOW (w)->width) |
769 | 1079 != FRAME_WIDTH (frame)) |
265 | 1080 break; |
1081 #if 0 | |
769 | 1082 /* Ignore invisible and iconified frames. */ |
1083 if (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (w)))) | |
1084 || FRAME_ICONIFIED_P (XFRAME (WINDOW_FRAME (XWINDOW (w))))) | |
265 | 1085 break; |
1086 #endif | |
1087 /* Ignore dedicated windows and minibuffers. */ | |
1088 if (MINI_WINDOW_P (XWINDOW (w)) | |
485 | 1089 || !NILP (XWINDOW (w)->dedicated)) |
265 | 1090 break; |
485 | 1091 if (NILP (best_window) |
265 | 1092 || (XFASTINT (XWINDOW (best_window)->use_time) |
1093 > XFASTINT (XWINDOW (w)->use_time))) | |
1094 best_window = w; | |
1095 break; | |
1096 | |
1097 case DELETE_OTHER_WINDOWS: | |
1098 if (XWINDOW (w) != XWINDOW (obj)) | |
1099 Fdelete_window (w); | |
1100 break; | |
1101 | |
1102 case DELETE_BUFFER_WINDOWS: | |
1103 if (EQ (XWINDOW (w)->buffer, obj)) | |
1104 { | |
1105 /* If we're deleting the buffer displayed in the only window | |
769 | 1106 on the frame, find a new buffer to display there. */ |
485 | 1107 if (NILP (XWINDOW (w)->parent)) |
265 | 1108 { |
1109 Lisp_Object new_buffer = Fother_buffer (obj); | |
485 | 1110 if (NILP (new_buffer)) |
265 | 1111 new_buffer |
1112 = Fget_buffer_create (build_string ("*scratch*")); | |
1113 Fset_window_buffer (w, new_buffer); | |
1114 Fset_buffer (XWINDOW (w)->buffer); | |
1115 } | |
1116 else | |
1117 Fdelete_window (w); | |
1118 } | |
1119 break; | |
1120 | |
1121 case GET_LARGEST_WINDOW: | |
1122 #if 0 | |
769 | 1123 /* Ignore invisible and iconified frames. */ |
1124 if (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (w)))) | |
1125 || FRAME_ICONIFIED_P (XFRAME (WINDOW_FRAME (XWINDOW (w))))) | |
265 | 1126 break; |
1127 #endif | |
1128 /* Ignore dedicated windows and minibuffers. */ | |
1129 if (MINI_WINDOW_P (XWINDOW (w)) | |
485 | 1130 || !NILP (XWINDOW (w)->dedicated)) |
265 | 1131 break; |
1132 { | |
1133 struct window *best_window_ptr = XWINDOW (best_window); | |
1134 struct window *w_ptr = XWINDOW (w); | |
485 | 1135 if (NILP (best_window) || |
265 | 1136 (XFASTINT (w_ptr->height) * XFASTINT (w_ptr->width)) |
1137 > (XFASTINT (best_window_ptr->height) | |
1138 * XFASTINT (best_window_ptr->width))) | |
1139 best_window = w; | |
1140 } | |
1141 break; | |
1142 | |
1143 case UNSHOW_BUFFER: | |
1144 if (EQ (XWINDOW (w)->buffer, obj)) | |
1145 { | |
1146 /* Find another buffer to show in this window. */ | |
1147 Lisp_Object another_buffer = Fother_buffer (obj); | |
485 | 1148 if (NILP (another_buffer)) |
265 | 1149 another_buffer |
1150 = Fget_buffer_create (build_string ("*scratch*")); | |
1151 Fset_window_buffer (w, another_buffer); | |
1152 if (EQ (w, selected_window)) | |
1153 Fset_buffer (XWINDOW (w)->buffer); | |
1154 } | |
1155 break; | |
1156 } | |
983
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1157 |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1158 if (EQ (w, last_window)) |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1159 break; |
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
1160 |
265 | 1161 w = next_window; |
1162 } | |
1163 | |
1164 return best_window; | |
1165 } | |
1166 | |
1167 DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 1, 0, | |
1168 "Return the window least recently selected or used for display.\n\ | |
769 | 1169 If optional argument FRAMES is t, search all frames. If FRAME is a\n\ |
1170 frame, search only that frame.\n") | |
1171 (frames) | |
1172 Lisp_Object frames; | |
265 | 1173 { |
1174 register Lisp_Object w; | |
1175 /* First try for a window that is full-width */ | |
769 | 1176 w = window_loop (GET_LRU_WINDOW, Qt, 0, frames); |
485 | 1177 if (!NILP (w) && !EQ (w, selected_window)) |
265 | 1178 return w; |
1179 /* If none of them, try the rest */ | |
769 | 1180 return window_loop (GET_LRU_WINDOW, Qnil, 0, frames); |
265 | 1181 } |
1182 | |
1183 DEFUN ("get-largest-window", Fget_largest_window, Sget_largest_window, 0, 1, 0, | |
1184 "Return the largest window in area.\n\ | |
769 | 1185 If optional argument FRAMES is t, search all frames. If FRAME is a\n\ |
1186 frame, search only that frame.\n") | |
1187 (frame) | |
1188 Lisp_Object frame; | |
265 | 1189 { |
1190 return window_loop (GET_LARGEST_WINDOW, Qnil, 0, | |
769 | 1191 frame); |
265 | 1192 } |
1193 | |
1194 DEFUN ("get-buffer-window", Fget_buffer_window, Sget_buffer_window, 1, 2, 0, | |
1195 "Return a window currently displaying BUFFER, or nil if none.\n\ | |
769 | 1196 If optional argument FRAMES is t, search all frames. If FRAME is a\n\ |
1197 frame, search only that frame.\n") | |
1198 (buffer, frame) | |
1199 Lisp_Object buffer, frame; | |
265 | 1200 { |
1201 buffer = Fget_buffer (buffer); | |
1202 if (XTYPE (buffer) == Lisp_Buffer) | |
769 | 1203 return window_loop (GET_BUFFER_WINDOW, buffer, 1, frame); |
265 | 1204 else |
1205 return Qnil; | |
1206 } | |
1207 | |
1208 DEFUN ("delete-other-windows", Fdelete_other_windows, Sdelete_other_windows, | |
1209 0, 1, "", | |
769 | 1210 "Make WINDOW (or the selected window) fill its frame.\n\ |
1211 Only the frame WINDOW is on is affected.") | |
265 | 1212 (window) |
1213 Lisp_Object window; | |
1214 { | |
1215 struct window *w; | |
1216 int opoint = point; | |
1217 struct buffer *obuf = current_buffer; | |
1218 int top; | |
1219 | |
485 | 1220 if (NILP (window)) |
265 | 1221 window = selected_window; |
1222 else | |
1223 CHECK_WINDOW (window, 0); | |
1224 | |
1225 w = XWINDOW (window); | |
1226 top = XFASTINT (w->top); | |
1227 | |
769 | 1228 window_loop (DELETE_OTHER_WINDOWS, window, 0, WINDOW_FRAME(w)); |
265 | 1229 |
1230 Fset_buffer (w->buffer); | |
1231 SET_PT (marker_position (w->start)); | |
1232 Frecenter (make_number (top)); | |
1233 | |
1234 set_buffer_internal (obuf); | |
1235 SET_PT (opoint); | |
1236 return Qnil; | |
1237 } | |
1238 | |
1239 DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on, | |
1240 1, 1, "bDelete windows on (buffer): ", | |
1241 "Delete all windows showing BUFFER.") | |
1242 (buffer) | |
1243 Lisp_Object buffer; | |
1244 { | |
485 | 1245 if (!NILP (buffer)) |
265 | 1246 { |
1247 buffer = Fget_buffer (buffer); | |
1248 CHECK_BUFFER (buffer, 0); | |
1249 window_loop (DELETE_BUFFER_WINDOWS, buffer, 0, Qt); | |
1250 } | |
1251 return Qnil; | |
1252 } | |
1253 | |
1254 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows, | |
1255 Sreplace_buffer_in_windows, | |
1256 1, 1, "bReplace buffer in windows: ", | |
1257 "Replace BUFFER with some other buffer in all windows showing it.") | |
1258 (buffer) | |
1259 Lisp_Object buffer; | |
1260 { | |
485 | 1261 if (!NILP (buffer)) |
265 | 1262 { |
1263 buffer = Fget_buffer (buffer); | |
1264 CHECK_BUFFER (buffer, 0); | |
1265 window_loop (UNSHOW_BUFFER, buffer, 0, Qt); | |
1266 } | |
1267 return Qnil; | |
1268 } | |
1269 | |
1270 /* Set the height of WINDOW and all its inferiors. */ | |
972
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1271 |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1272 /* The smallest acceptable dimensions for a window. Anything smaller |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1273 might crash Emacs. */ |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1274 #define MIN_SAFE_WINDOW_WIDTH (2) |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1275 #define MIN_SAFE_WINDOW_HEIGHT (2) |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1276 |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1277 /* Make sure that window_min_height and window_min_width are |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1278 not too small; if they are, set them to safe minima. */ |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1279 |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1280 static void |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1281 check_min_window_sizes () |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1282 { |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1283 /* Smaller values might permit a crash. */ |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1284 if (window_min_width < MIN_SAFE_WINDOW_WIDTH) |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1285 window_min_width = MIN_SAFE_WINDOW_WIDTH; |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1286 if (window_min_height < MIN_SAFE_WINDOW_HEIGHT) |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1287 window_min_height = MIN_SAFE_WINDOW_HEIGHT; |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1288 } |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1289 |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1290 /* If *ROWS or *COLS are too small a size for FRAME, set them to the |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1291 minimum allowable size. */ |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1292 extern void |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1293 check_frame_size (frame, rows, cols) |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1294 FRAME_PTR frame; |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1295 int *rows, *cols; |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1296 { |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1297 /* For height, we have to see whether the frame has a minibuffer, and |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1298 whether it wants a mode line. */ |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1299 int min_height = |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1300 ((FRAME_MINIBUF_ONLY_P (frame) |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1301 || ! FRAME_HAS_MINIBUF_P (frame)) |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1302 ? MIN_SAFE_WINDOW_HEIGHT |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1303 : 2 * MIN_SAFE_WINDOW_HEIGHT - 1); |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1304 |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1305 if (*rows < min_height) |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1306 *rows = min_height; |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1307 if (*cols < MIN_SAFE_WINDOW_WIDTH) |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1308 *cols = MIN_SAFE_WINDOW_WIDTH; |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1309 } |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1310 |
265 | 1311 /* Normally the window is deleted if it gets too small. |
1312 nodelete nonzero means do not do this. | |
1313 (The caller should check later and do so if appropriate) */ | |
1314 | |
1315 set_window_height (window, height, nodelete) | |
1316 Lisp_Object window; | |
1317 int height; | |
1318 int nodelete; | |
1319 { | |
1320 register struct window *w = XWINDOW (window); | |
1321 register struct window *c; | |
1322 int oheight = XFASTINT (w->height); | |
1323 int top, pos, lastbot, opos, lastobot; | |
1324 Lisp_Object child; | |
1325 | |
972
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1326 check_min_window_sizes (); |
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1327 |
265 | 1328 if (!nodelete |
485 | 1329 && ! NILP (w->parent) |
265 | 1330 && height < window_min_height) |
1331 { | |
1332 Fdelete_window (window); | |
1333 return; | |
1334 } | |
1335 | |
1336 XFASTINT (w->last_modified) = 0; | |
1337 windows_or_buffers_changed++; | |
1338 XFASTINT (w->height) = height; | |
485 | 1339 if (!NILP (w->hchild)) |
265 | 1340 { |
485 | 1341 for (child = w->hchild; !NILP (child); child = XWINDOW (child)->next) |
265 | 1342 { |
1343 XWINDOW (child)->top = w->top; | |
1344 set_window_height (child, height, nodelete); | |
1345 } | |
1346 } | |
485 | 1347 else if (!NILP (w->vchild)) |
265 | 1348 { |
1349 lastbot = top = XFASTINT (w->top); | |
1350 lastobot = 0; | |
485 | 1351 for (child = w->vchild; !NILP (child); child = c->next) |
265 | 1352 { |
1353 c = XWINDOW (child); | |
1354 | |
1355 opos = lastobot + XFASTINT (c->height); | |
1356 | |
1357 XFASTINT (c->top) = lastbot; | |
1358 | |
1359 pos = (((opos * height) << 1) + oheight) / (oheight << 1); | |
1360 | |
1361 /* Avoid confusion: inhibit deletion of child if becomes too small */ | |
1362 set_window_height (child, pos + top - lastbot, 1); | |
1363 | |
1364 /* Now advance child to next window, | |
1365 and set lastbot if child was not just deleted. */ | |
1366 lastbot = pos + top; | |
1367 lastobot = opos; | |
1368 } | |
1369 /* Now delete any children that became too small. */ | |
1370 if (!nodelete) | |
485 | 1371 for (child = w->vchild; !NILP (child); child = XWINDOW (child)->next) |
265 | 1372 { |
1373 set_window_height (child, XINT (XWINDOW (child)->height), 0); | |
1374 } | |
1375 } | |
1376 } | |
1377 | |
1378 /* Recursively set width of WINDOW and its inferiors. */ | |
1379 | |
1380 set_window_width (window, width, nodelete) | |
1381 Lisp_Object window; | |
1382 int width; | |
1383 int nodelete; | |
1384 { | |
1385 register struct window *w = XWINDOW (window); | |
1386 register struct window *c; | |
1387 int owidth = XFASTINT (w->width); | |
1388 int left, pos, lastright, opos, lastoright; | |
1389 Lisp_Object child; | |
1390 | |
1391 if (!nodelete && width < window_min_width) | |
1392 { | |
1393 Fdelete_window (window); | |
1394 return; | |
1395 } | |
1396 | |
1397 XFASTINT (w->last_modified) = 0; | |
1398 windows_or_buffers_changed++; | |
1399 XFASTINT (w->width) = width; | |
485 | 1400 if (!NILP (w->vchild)) |
265 | 1401 { |
485 | 1402 for (child = w->vchild; !NILP (child); child = XWINDOW (child)->next) |
265 | 1403 { |
1404 XWINDOW (child)->left = w->left; | |
1405 set_window_width (child, width, nodelete); | |
1406 } | |
1407 } | |
485 | 1408 else if (!NILP (w->hchild)) |
265 | 1409 { |
1410 lastright = left = XFASTINT (w->left); | |
1411 lastoright = 0; | |
485 | 1412 for (child = w->hchild; !NILP (child); child = c->next) |
265 | 1413 { |
1414 c = XWINDOW (child); | |
1415 | |
1416 opos = lastoright + XFASTINT (c->width); | |
1417 | |
1418 XFASTINT (c->left) = lastright; | |
1419 | |
1420 pos = (((opos * width) << 1) + owidth) / (owidth << 1); | |
1421 | |
1422 /* Inhibit deletion for becoming too small */ | |
1423 set_window_width (child, pos + left - lastright, 1); | |
1424 | |
1425 /* Now advance child to next window, | |
1426 and set lastright if child was not just deleted. */ | |
1427 lastright = pos + left, lastoright = opos; | |
1428 } | |
1429 /* Delete children that became too small */ | |
1430 if (!nodelete) | |
485 | 1431 for (child = w->hchild; !NILP (child); child = XWINDOW (child)->next) |
265 | 1432 { |
1433 set_window_width (child, XINT (XWINDOW (child)->width), 0); | |
1434 } | |
1435 } | |
1436 } | |
1437 | |
362 | 1438 int window_select_count; |
265 | 1439 |
1440 DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 2, 0, | |
1441 "Make WINDOW display BUFFER as its contents.\n\ | |
1442 BUFFER can be a buffer or buffer name.") | |
1443 (window, buffer) | |
1444 register Lisp_Object window, buffer; | |
1445 { | |
1446 register Lisp_Object tem; | |
1447 register struct window *w = decode_window (window); | |
1448 | |
1449 buffer = Fget_buffer (buffer); | |
1450 CHECK_BUFFER (buffer, 1); | |
1451 | |
485 | 1452 if (NILP (XBUFFER (buffer)->name)) |
265 | 1453 error ("Attempt to display deleted buffer"); |
1454 | |
1455 tem = w->buffer; | |
485 | 1456 if (NILP (tem)) |
265 | 1457 error ("Window is deleted"); |
1458 else if (! EQ (tem, Qt)) /* w->buffer is t when the window | |
1459 is first being set up. */ | |
1460 { | |
485 | 1461 if (!NILP (w->dedicated) && !EQ (tem, buffer)) |
265 | 1462 error ("Window is dedicated to %s\n", tem); |
1463 | |
1464 unshow_buffer (w); | |
1465 } | |
1466 | |
1467 w->buffer = buffer; | |
1468 Fset_marker (w->pointm, | |
1469 make_number (BUF_PT (XBUFFER (buffer))), | |
1470 buffer); | |
1471 set_marker_restricted (w->start, | |
1472 make_number (XBUFFER (buffer)->last_window_start), | |
1473 buffer); | |
1474 w->start_at_line_beg = Qnil; | |
1475 XFASTINT (w->last_modified) = 0; | |
1476 windows_or_buffers_changed++; | |
1477 if (EQ (window, selected_window)) | |
1478 Fset_buffer (buffer); | |
1479 | |
1480 return Qnil; | |
1481 } | |
1482 | |
1483 DEFUN ("select-window", Fselect_window, Sselect_window, 1, 1, 0, | |
1484 "Select WINDOW. Most editing will apply to WINDOW's buffer.\n\ | |
1485 The main editor command loop selects the buffer of the selected window\n\ | |
1486 before each command.") | |
1487 (window) | |
1488 register Lisp_Object window; | |
1489 { | |
1490 register struct window *w; | |
1491 register struct window *ow = XWINDOW (selected_window); | |
1492 | |
1493 CHECK_WINDOW (window, 0); | |
1494 | |
1495 w = XWINDOW (window); | |
1496 | |
485 | 1497 if (NILP (w->buffer)) |
265 | 1498 error ("Trying to select deleted window or non-leaf window"); |
1499 | |
1500 XFASTINT (w->use_time) = ++window_select_count; | |
1501 if (EQ (window, selected_window)) | |
1502 return window; | |
1503 | |
1504 Fset_marker (ow->pointm, make_number (BUF_PT (XBUFFER (ow->buffer))), | |
1505 ow->buffer); | |
1506 | |
1507 selected_window = window; | |
769 | 1508 #ifdef MULTI_FRAME |
1509 if (XFRAME (WINDOW_FRAME (w)) != selected_frame) | |
265 | 1510 { |
769 | 1511 XFRAME (WINDOW_FRAME (w))->selected_window = window; |
1512 Fselect_frame (WINDOW_FRAME (w), Qnil); | |
265 | 1513 } |
1514 else | |
769 | 1515 selected_frame->selected_window = window; |
265 | 1516 #endif |
1517 | |
1518 record_buffer (w->buffer); | |
1519 Fset_buffer (w->buffer); | |
1520 | |
1521 /* Go to the point recorded in the window. | |
1522 This is important when the buffer is in more | |
1523 than one window. It also matters when | |
1524 redisplay_window has altered point after scrolling, | |
1525 because it makes the change only in the window. */ | |
1526 { | |
1527 register int new_point = marker_position (w->pointm); | |
1528 if (new_point < BEGV) | |
1529 SET_PT (BEGV); | |
1530 if (new_point > ZV) | |
1531 SET_PT (ZV); | |
1532 else | |
1533 SET_PT (new_point); | |
1534 } | |
1535 | |
1536 windows_or_buffers_changed++; | |
1537 return window; | |
1538 } | |
1539 | |
735 | 1540 DEFUN ("display-buffer", Fdisplay_buffer, Sdisplay_buffer, 1, 2, |
1541 "BDisplay buffer:\nP", | |
265 | 1542 "Make BUFFER appear in some window but don't select it.\n\ |
1543 BUFFER can be a buffer or a buffer name.\n\ | |
1544 If BUFFER is shown already in some window, just use that one,\n\ | |
1545 unless the window is the selected window and the optional second\n\ | |
1546 argument NOT_THIS_WINDOW is non-nil.\n\ | |
1547 Returns the window displaying BUFFER.") | |
1548 (buffer, not_this_window) | |
1549 register Lisp_Object buffer, not_this_window; | |
1550 { | |
1551 register Lisp_Object window; | |
1552 | |
1553 buffer = Fget_buffer (buffer); | |
1554 CHECK_BUFFER (buffer, 0); | |
1555 | |
485 | 1556 if (!NILP (Vdisplay_buffer_function)) |
265 | 1557 return call2 (Vdisplay_buffer_function, buffer, not_this_window); |
1558 | |
485 | 1559 if (NILP (not_this_window) |
265 | 1560 && XBUFFER (XWINDOW (selected_window)->buffer) == XBUFFER (buffer)) |
1561 return selected_window; | |
1562 | |
1563 window = Fget_buffer_window (buffer, Qnil); | |
485 | 1564 if (!NILP (window) |
1565 && (NILP (not_this_window) || !EQ (window, selected_window))) | |
265 | 1566 return window; |
1567 | |
769 | 1568 #ifdef MULTI_FRAME |
1569 /* If there are no frames open that have more than a minibuffer, | |
1570 we need to create a new frame. */ | |
1571 if (pop_up_frames || last_nonminibuf_frame == 0) | |
265 | 1572 { |
1573 window | |
769 | 1574 = Fframe_selected_window (call0 (Vpop_up_frame_function)); |
265 | 1575 Fset_window_buffer (window, buffer); |
1576 #if 0 | |
769 | 1577 Fselect_frame (XWINDOW (window)->frame, Qnil); |
265 | 1578 #endif |
1579 return window; | |
1580 } | |
769 | 1581 #endif /* MULTI_FRAME */ |
265 | 1582 |
358 | 1583 if (pop_up_windows |
769 | 1584 #ifdef MULTI_FRAME |
1585 || FRAME_MINIBUF_ONLY_P (selected_frame) | |
358 | 1586 #endif |
1587 ) | |
1588 { | |
769 | 1589 Lisp_Object frames = Qnil; |
358 | 1590 |
769 | 1591 #ifdef MULTI_FRAME |
1592 if (FRAME_MINIBUF_ONLY_P (selected_frame)) | |
1593 XSET (frames, Lisp_Frame, last_nonminibuf_frame); | |
265 | 1594 #endif |
1595 /* Don't try to create a window if would get an error */ | |
1596 if (split_height_threshold < window_min_height << 1) | |
1597 split_height_threshold = window_min_height << 1; | |
1598 | |
769 | 1599 window = Fget_largest_window (frames); |
265 | 1600 |
485 | 1601 if (!NILP (window) |
265 | 1602 && window_height (window) >= split_height_threshold |
1603 && | |
1604 (XFASTINT (XWINDOW (window)->width) | |
769 | 1605 == FRAME_WIDTH (XFRAME (WINDOW_FRAME (XWINDOW (window)))))) |
265 | 1606 window = Fsplit_window (window, Qnil, Qnil); |
1607 else | |
1608 { | |
769 | 1609 window = Fget_lru_window (frames); |
265 | 1610 if ((EQ (window, selected_window) |
1611 || EQ (XWINDOW (window)->parent, Qnil)) | |
1612 && window_height (window) >= window_min_height << 1) | |
1613 window = Fsplit_window (window, Qnil, Qnil); | |
1614 } | |
1615 } | |
1616 else | |
1617 window = Fget_lru_window (Qnil); | |
1618 | |
1619 Fset_window_buffer (window, buffer); | |
1620 return window; | |
1621 } | |
1622 | |
1623 void | |
1624 temp_output_buffer_show (buf) | |
1625 register Lisp_Object buf; | |
1626 { | |
1627 register struct buffer *old = current_buffer; | |
1628 register Lisp_Object window; | |
1629 register struct window *w; | |
1630 | |
1631 Fset_buffer (buf); | |
1632 XBUFFER (buf)->save_modified = MODIFF; | |
1633 BEGV = BEG; | |
1634 ZV = Z; | |
1635 SET_PT (BEG); | |
1636 clip_changed = 1; | |
1637 set_buffer_internal (old); | |
1638 | |
1639 if (!EQ (Vtemp_buffer_show_function, Qnil)) | |
1640 call1 (Vtemp_buffer_show_function, buf); | |
1641 else | |
1642 { | |
1643 window = Fdisplay_buffer (buf, Qnil); | |
1644 | |
769 | 1645 #ifdef MULTI_FRAME |
1646 if (XFRAME (XWINDOW (window)->frame) != selected_frame) | |
1647 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window))); | |
1648 #endif /* MULTI_FRAME */ | |
265 | 1649 Vminibuf_scroll_window = window; |
1650 w = XWINDOW (window); | |
1651 XFASTINT (w->hscroll) = 0; | |
1652 set_marker_restricted (w->start, make_number (1), buf); | |
1653 set_marker_restricted (w->pointm, make_number (1), buf); | |
1654 } | |
1655 } | |
1656 | |
1657 static | |
1658 make_dummy_parent (window) | |
1659 Lisp_Object window; | |
1660 { | |
1661 register Lisp_Object old, new; | |
1662 register struct window *o, *p; | |
1663 | |
1664 old = window; | |
1665 XSETTYPE (old, Lisp_Vector); | |
1666 new = Fcopy_sequence (old); | |
1667 XSETTYPE (new, Lisp_Window); | |
1668 | |
1669 o = XWINDOW (old); | |
1670 p = XWINDOW (new); | |
1671 XFASTINT (p->sequence_number) = ++sequence_number; | |
1672 | |
1673 /* Put new into window structure in place of window */ | |
1674 replace_window (window, new); | |
1675 | |
1676 o->next = Qnil; | |
1677 o->prev = Qnil; | |
1678 o->vchild = Qnil; | |
1679 o->hchild = Qnil; | |
1680 o->parent = new; | |
1681 | |
1682 p->start = Qnil; | |
1683 p->pointm = Qnil; | |
1684 p->buffer = Qnil; | |
1685 } | |
1686 | |
1687 DEFUN ("split-window", Fsplit_window, Ssplit_window, 0, 3, "", | |
1688 "Split WINDOW, putting SIZE lines in the first of the pair.\n\ | |
1689 WINDOW defaults to selected one and SIZE to half its size.\n\ | |
1690 If optional third arg HOR-FLAG is non-nil, split side by side\n\ | |
1691 and put SIZE columns in the first of the pair.") | |
1692 (window, chsize, horflag) | |
1693 Lisp_Object window, chsize, horflag; | |
1694 { | |
1695 register Lisp_Object new; | |
1696 register struct window *o, *p; | |
1697 register int size; | |
1698 | |
485 | 1699 if (NILP (window)) |
265 | 1700 window = selected_window; |
1701 else | |
1702 CHECK_WINDOW (window, 0); | |
1703 | |
1704 o = XWINDOW (window); | |
1705 | |
485 | 1706 if (NILP (chsize)) |
265 | 1707 { |
485 | 1708 if (!NILP (horflag)) |
265 | 1709 /* Round odd size up, since this is for the left-hand window, |
1710 and it will lose a column for the separators. */ | |
1711 size = ((XFASTINT (o->width) + 1) & -2) >> 1; | |
1712 else | |
1713 size = XFASTINT (o->height) >> 1; | |
1714 } | |
1715 else | |
1716 { | |
1717 CHECK_NUMBER (chsize, 1); | |
1718 size = XINT (chsize); | |
1719 } | |
1720 | |
1721 if (MINI_WINDOW_P (o)) | |
1722 error ("Attempt to split minibuffer window"); | |
769 | 1723 else if (FRAME_NO_SPLIT_P (XFRAME (WINDOW_FRAME (o)))) |
1724 error ("Attempt to split unsplittable frame"); | |
265 | 1725 |
972
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1726 check_min_window_sizes (); |
265 | 1727 |
485 | 1728 if (NILP (horflag)) |
265 | 1729 { |
1730 if (size < window_min_height | |
1731 || size + window_min_height > XFASTINT (o->height)) | |
1732 args_out_of_range_3 (window, chsize, horflag); | |
485 | 1733 if (NILP (o->parent) |
1734 || NILP (XWINDOW (o->parent)->vchild)) | |
265 | 1735 { |
1736 make_dummy_parent (window); | |
1737 new = o->parent; | |
1738 XWINDOW (new)->vchild = window; | |
1739 } | |
1740 } | |
1741 else | |
1742 { | |
1743 if (size < window_min_width | |
1744 || size + window_min_width > XFASTINT (o->width)) | |
1745 args_out_of_range_3 (window, chsize, horflag); | |
485 | 1746 if (NILP (o->parent) |
1747 || NILP (XWINDOW (o->parent)->hchild)) | |
265 | 1748 { |
1749 make_dummy_parent (window); | |
1750 new = o->parent; | |
1751 XWINDOW (new)->hchild = window; | |
1752 } | |
1753 } | |
1754 | |
1755 /* Now we know that window's parent is a vertical combination | |
1756 if we are dividing vertically, or a horizontal combination | |
1757 if we are making side-by-side windows */ | |
1758 | |
1759 windows_or_buffers_changed++; | |
1760 new = make_window (); | |
1761 p = XWINDOW (new); | |
1762 | |
769 | 1763 p->frame = o->frame; |
265 | 1764 p->next = o->next; |
485 | 1765 if (!NILP (p->next)) |
265 | 1766 XWINDOW (p->next)->prev = new; |
1767 p->prev = window; | |
1768 o->next = new; | |
1769 p->parent = o->parent; | |
1770 p->buffer = Qt; | |
1771 | |
1772 Fset_window_buffer (new, o->buffer); | |
1773 | |
769 | 1774 /* Apportion the available frame space among the two new windows */ |
265 | 1775 |
485 | 1776 if (!NILP (horflag)) |
265 | 1777 { |
1778 p->height = o->height; | |
1779 p->top = o->top; | |
1780 XFASTINT (p->width) = XFASTINT (o->width) - size; | |
1781 XFASTINT (o->width) = size; | |
1782 XFASTINT (p->left) = XFASTINT (o->left) + size; | |
1783 } | |
1784 else | |
1785 { | |
1786 p->left = o->left; | |
1787 p->width = o->width; | |
1788 XFASTINT (p->height) = XFASTINT (o->height) - size; | |
1789 XFASTINT (o->height) = size; | |
1790 XFASTINT (p->top) = XFASTINT (o->top) + size; | |
1791 } | |
1792 | |
1793 return new; | |
1794 } | |
1795 | |
1796 DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p", | |
1797 "Make current window ARG lines bigger.\n\ | |
1798 From program, optional second arg non-nil means grow sideways ARG columns.") | |
1799 (n, side) | |
1800 register Lisp_Object n, side; | |
1801 { | |
1802 CHECK_NUMBER (n, 0); | |
485 | 1803 change_window_height (XINT (n), !NILP (side)); |
265 | 1804 return Qnil; |
1805 } | |
1806 | |
1807 DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p", | |
1808 "Make current window ARG lines smaller.\n\ | |
1809 From program, optional second arg non-nil means shrink sideways ARG columns.") | |
1810 (n, side) | |
1811 register Lisp_Object n, side; | |
1812 { | |
1813 CHECK_NUMBER (n, 0); | |
485 | 1814 change_window_height (-XINT (n), !NILP (side)); |
265 | 1815 return Qnil; |
1816 } | |
1817 | |
1818 int | |
1819 window_height (window) | |
1820 Lisp_Object window; | |
1821 { | |
1822 register struct window *p = XWINDOW (window); | |
1823 return XFASTINT (p->height); | |
1824 } | |
1825 | |
1826 int | |
1827 window_width (window) | |
1828 Lisp_Object window; | |
1829 { | |
1830 register struct window *p = XWINDOW (window); | |
1831 return XFASTINT (p->width); | |
1832 } | |
1833 | |
1834 #define MINSIZE(w) \ | |
1835 (widthflag ? window_min_width : window_min_height) | |
1836 | |
1837 #define CURBEG(w) \ | |
1838 *(widthflag ? (int *) &(w)->left : (int *) &(w)->top) | |
1839 | |
1840 #define CURSIZE(w) \ | |
1841 *(widthflag ? (int *) &(w)->width : (int *) &(w)->height) | |
1842 | |
1843 /* Unlike set_window_height, this function | |
1844 also changes the heights of the siblings so as to | |
1845 keep everything consistent. */ | |
1846 | |
1847 change_window_height (delta, widthflag) | |
1848 register int delta; | |
1849 int widthflag; | |
1850 { | |
1851 register Lisp_Object parent; | |
1852 Lisp_Object window; | |
1853 register struct window *p; | |
1854 int *sizep; | |
1855 int (*sizefun) () = widthflag ? window_width : window_height; | |
1856 register int (*setsizefun) () = (widthflag | |
1857 ? set_window_width | |
1858 : set_window_height); | |
1859 | |
972
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
1860 check_min_window_sizes (); |
265 | 1861 |
1862 window = selected_window; | |
1863 while (1) | |
1864 { | |
1865 p = XWINDOW (window); | |
1866 parent = p->parent; | |
485 | 1867 if (NILP (parent)) |
265 | 1868 { |
1869 if (widthflag) | |
1870 error ("No other window to side of this one"); | |
1871 break; | |
1872 } | |
485 | 1873 if (widthflag ? !NILP (XWINDOW (parent)->hchild) |
1874 : !NILP (XWINDOW (parent)->vchild)) | |
265 | 1875 break; |
1876 window = parent; | |
1877 } | |
1878 | |
1879 sizep = &CURSIZE (p); | |
1880 | |
1881 if (*sizep + delta < MINSIZE (p) | |
485 | 1882 && !NILP (XWINDOW (window)->parent)) |
265 | 1883 { |
1884 Fdelete_window (window); | |
1885 return; | |
1886 } | |
1887 | |
1888 { | |
1889 register int maxdelta; | |
1890 | |
485 | 1891 maxdelta = (!NILP (parent) ? (*sizefun) (parent) - *sizep |
1892 : !NILP (p->next) ? (*sizefun) (p->next) - MINSIZE (p->next) | |
1893 : !NILP (p->prev) ? (*sizefun) (p->prev) - MINSIZE (p->prev) | |
769 | 1894 /* This is a frame with only one window, a minibuffer-only |
1895 or a minibufferless frame. */ | |
432 | 1896 : (delta = 0)); |
265 | 1897 |
1898 if (delta > maxdelta) | |
1899 /* This case traps trying to make the minibuffer | |
769 | 1900 the full frame, or make the only window aside from the |
1901 minibuffer the full frame. */ | |
265 | 1902 delta = maxdelta; |
432 | 1903 |
1904 if (delta == 0) | |
1905 return; | |
265 | 1906 } |
1907 | |
485 | 1908 if (!NILP (p->next) && |
265 | 1909 (*sizefun) (p->next) - delta >= MINSIZE (p->next)) |
1910 { | |
1911 (*setsizefun) (p->next, (*sizefun) (p->next) - delta, 0); | |
1912 (*setsizefun) (window, *sizep + delta, 0); | |
1913 CURBEG (XWINDOW (p->next)) += delta; | |
1914 /* This does not change size of p->next, | |
1915 but it propagates the new top edge to its children */ | |
1916 (*setsizefun) (p->next, (*sizefun) (p->next), 0); | |
1917 } | |
485 | 1918 else if (!NILP (p->prev) && |
265 | 1919 (*sizefun) (p->prev) - delta >= MINSIZE (p->prev)) |
1920 { | |
1921 (*setsizefun) (p->prev, (*sizefun) (p->prev) - delta, 0); | |
1922 CURBEG (p) -= delta; | |
1923 (*setsizefun) (window, *sizep + delta, 0); | |
1924 } | |
1925 else | |
1926 { | |
1927 register int delta1; | |
1928 register int opht = (*sizefun) (parent); | |
1929 | |
1930 /* If trying to grow this window to or beyond size of the parent, | |
1931 make delta1 so big that, on shrinking back down, | |
1932 all the siblings end up with less than one line and are deleted. */ | |
1933 if (opht <= *sizep + delta) | |
1934 delta1 = opht * opht * 2; | |
1935 /* Otherwise, make delta1 just right so that if we add delta1 | |
1936 lines to this window and to the parent, and then shrink | |
1937 the parent back to its original size, the new proportional | |
1938 size of this window will increase by delta. */ | |
1939 else | |
1940 delta1 = (delta * opht * 100) / ((opht - *sizep - delta) * 100); | |
1941 | |
1942 /* Add delta1 lines or columns to this window, and to the parent, | |
1943 keeping things consistent while not affecting siblings. */ | |
1944 CURSIZE (XWINDOW (parent)) = opht + delta1; | |
1945 (*setsizefun) (window, *sizep + delta1, 0); | |
1946 | |
1947 /* Squeeze out delta1 lines or columns from our parent, | |
1948 shriking this window and siblings proportionately. | |
1949 This brings parent back to correct size. | |
1950 Delta1 was calculated so this makes this window the desired size, | |
1951 taking it all out of the siblings. */ | |
1952 (*setsizefun) (parent, opht, 0); | |
1953 } | |
1954 | |
1955 XFASTINT (p->last_modified) = 0; | |
1956 } | |
1957 #undef MINSIZE | |
1958 #undef CURBEG | |
1959 #undef CURSIZE | |
1960 | |
1961 | |
1962 /* Return number of lines of text (not counting mode line) in W. */ | |
1963 | |
1964 int | |
1965 window_internal_height (w) | |
1966 struct window *w; | |
1967 { | |
1968 int ht = XFASTINT (w->height); | |
1969 | |
1970 if (MINI_WINDOW_P (w)) | |
1971 return ht; | |
1972 | |
485 | 1973 if (!NILP (w->parent) || !NILP (w->vchild) || !NILP (w->hchild) |
1974 || !NILP (w->next) || !NILP (w->prev) | |
769 | 1975 || FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (w)))) |
265 | 1976 return ht - 1; |
1977 | |
1978 return ht; | |
1979 } | |
1980 | |
1981 /* Scroll contents of window WINDOW up N lines. */ | |
1982 | |
1983 void | |
522 | 1984 window_scroll (window, n, noerror) |
265 | 1985 Lisp_Object window; |
1986 int n; | |
522 | 1987 int noerror; |
265 | 1988 { |
1989 register struct window *w = XWINDOW (window); | |
1990 register int opoint = point; | |
1991 register int pos; | |
1992 register int ht = window_internal_height (w); | |
1993 register Lisp_Object tem; | |
1994 int lose; | |
1995 Lisp_Object bolp, nmoved; | |
1996 | |
1997 XFASTINT (tem) = point; | |
1998 tem = Fpos_visible_in_window_p (tem, window); | |
1999 | |
485 | 2000 if (NILP (tem)) |
265 | 2001 { |
2002 Fvertical_motion (make_number (- ht / 2)); | |
2003 XFASTINT (tem) = point; | |
2004 Fset_marker (w->start, tem, w->buffer); | |
2005 w->force_start = Qt; | |
2006 } | |
2007 | |
2008 SET_PT (marker_position (w->start)); | |
2009 lose = n < 0 && point == BEGV; | |
2010 Fvertical_motion (make_number (n)); | |
2011 pos = point; | |
2012 bolp = Fbolp (); | |
2013 SET_PT (opoint); | |
2014 | |
2015 if (lose) | |
522 | 2016 { |
2017 if (noerror) | |
2018 return; | |
2019 else | |
2020 Fsignal (Qbeginning_of_buffer, Qnil); | |
2021 } | |
265 | 2022 |
2023 if (pos < ZV) | |
2024 { | |
2025 set_marker_restricted (w->start, make_number (pos), w->buffer); | |
2026 w->start_at_line_beg = bolp; | |
2027 w->update_mode_line = Qt; | |
2028 XFASTINT (w->last_modified) = 0; | |
2029 if (pos > opoint) | |
2030 SET_PT (pos); | |
2031 if (n < 0) | |
2032 { | |
2033 SET_PT (pos); | |
2034 tem = Fvertical_motion (make_number (ht)); | |
2035 if (point > opoint || XFASTINT (tem) < ht) | |
2036 SET_PT (opoint); | |
2037 else | |
2038 Fvertical_motion (make_number (-1)); | |
2039 } | |
2040 } | |
2041 else | |
522 | 2042 { |
2043 if (noerror) | |
2044 return; | |
2045 else | |
2046 Fsignal (Qend_of_buffer, Qnil); | |
2047 } | |
265 | 2048 } |
2049 | |
2050 /* This is the guts of Fscroll_up and Fscroll_down. */ | |
2051 | |
2052 static void | |
2053 scroll_command (n, direction) | |
2054 register Lisp_Object n; | |
2055 int direction; | |
2056 { | |
2057 register int defalt; | |
2058 int count = specpdl_ptr - specpdl; | |
2059 | |
548 | 2060 /* If selected window's buffer isn't current, make it current for the moment. |
2061 But don't screw up if window_scroll gets an error. */ | |
265 | 2062 if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer) |
548 | 2063 { |
2064 record_unwind_protect (save_excursion_restore, save_excursion_save ()); | |
2065 Fset_buffer (XWINDOW (selected_window)->buffer); | |
2066 } | |
265 | 2067 |
2068 defalt = (window_internal_height (XWINDOW (selected_window)) | |
2069 - next_screen_context_lines); | |
2070 defalt = direction * (defalt < 1 ? 1 : defalt); | |
2071 | |
485 | 2072 if (NILP (n)) |
522 | 2073 window_scroll (selected_window, defalt, 0); |
265 | 2074 else if (EQ (n, Qminus)) |
522 | 2075 window_scroll (selected_window, - defalt, 0); |
265 | 2076 else |
2077 { | |
2078 n = Fprefix_numeric_value (n); | |
522 | 2079 window_scroll (selected_window, XINT (n) * direction, 0); |
265 | 2080 } |
548 | 2081 |
2082 unbind_to (count, Qnil); | |
265 | 2083 } |
2084 | |
2085 DEFUN ("scroll-up", Fscroll_up, Sscroll_up, 0, 1, "P", | |
2086 "Scroll text of current window upward ARG lines; or near full screen if no ARG.\n\ | |
2087 A near full screen is `next-screen-context-lines' less than a full screen.\n\ | |
2088 When calling from a program, supply a number as argument or nil.") | |
2089 (n) | |
2090 Lisp_Object n; | |
2091 { | |
2092 scroll_command (n, 1); | |
2093 return Qnil; | |
2094 } | |
2095 | |
2096 DEFUN ("scroll-down", Fscroll_down, Sscroll_down, 0, 1, "P", | |
2097 "Scroll text of current window downward ARG lines; or near full screen if no ARG.\n\ | |
2098 A near full screen is `next-screen-context-lines' less than a full screen.\n\ | |
2099 When calling from a program, supply a number as argument or nil.") | |
2100 (n) | |
2101 Lisp_Object n; | |
2102 { | |
2103 scroll_command (n, -1); | |
2104 return Qnil; | |
2105 } | |
2106 | |
2107 DEFUN ("scroll-other-window", Fscroll_other_window, Sscroll_other_window, 0, 1, "P", | |
2108 "Scroll text of next window upward ARG lines; or near full screen if no ARG.\n\ | |
2109 The next window is the one below the current one; or the one at the top\n\ | |
2110 if the current one is at the bottom.\n\ | |
2111 When calling from a program, supply a number as argument or nil.\n\ | |
2112 \n\ | |
2113 If in the minibuffer, `minibuf-scroll-window' if non-nil\n\ | |
2114 specifies the window to scroll.\n\ | |
2115 If `other-window-scroll-buffer' is non-nil, scroll the window\n\ | |
2116 showing that buffer, popping the buffer up if necessary.") | |
2117 (n) | |
2118 register Lisp_Object n; | |
2119 { | |
2120 register Lisp_Object window; | |
2121 register int ht; | |
2122 register struct window *w; | |
2123 register int count = specpdl_ptr - specpdl; | |
2124 | |
2125 if (MINI_WINDOW_P (XWINDOW (selected_window)) | |
485 | 2126 && !NILP (Vminibuf_scroll_window)) |
265 | 2127 window = Vminibuf_scroll_window; |
2128 /* If buffer is specified, scroll that buffer. */ | |
485 | 2129 else if (!NILP (Vother_window_scroll_buffer)) |
265 | 2130 { |
2131 window = Fget_buffer_window (Vother_window_scroll_buffer, Qnil); | |
485 | 2132 if (NILP (window)) |
265 | 2133 window = Fdisplay_buffer (Vother_window_scroll_buffer, Qt); |
2134 } | |
2135 else | |
2136 /* Nothing specified; pick a neighboring window. */ | |
2137 window = Fnext_window (selected_window, Qnil, Qt); | |
2138 CHECK_WINDOW (window, 0); | |
2139 | |
2140 if (EQ (window, selected_window)) | |
2141 error ("There is no other window"); | |
2142 | |
2143 w = XWINDOW (window); | |
2144 ht = window_internal_height (w); | |
2145 | |
2146 /* Don't screw up if window_scroll gets an error. */ | |
2147 record_unwind_protect (save_excursion_restore, save_excursion_save ()); | |
2148 | |
2149 Fset_buffer (w->buffer); | |
2150 SET_PT (marker_position (w->pointm)); | |
2151 | |
485 | 2152 if (NILP (n)) |
522 | 2153 window_scroll (window, ht - next_screen_context_lines, 1); |
265 | 2154 else if (EQ (n, Qminus)) |
522 | 2155 window_scroll (window, next_screen_context_lines - ht, 1); |
265 | 2156 else |
2157 { | |
2158 if (XTYPE (n) == Lisp_Cons) | |
2159 n = Fcar (n); | |
2160 CHECK_NUMBER (n, 0); | |
522 | 2161 window_scroll (window, XINT (n), 1); |
265 | 2162 } |
2163 | |
2164 Fset_marker (w->pointm, make_number (point), Qnil); | |
2165 unbind_to (count); | |
2166 | |
2167 return Qnil; | |
2168 } | |
2169 | |
2170 DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 1, 1, "P", | |
2171 "Scroll selected window display ARG columns left.\n\ | |
2172 Default for ARG is window width minus 2.") | |
2173 (arg) | |
2174 register Lisp_Object arg; | |
2175 { | |
2176 | |
485 | 2177 if (NILP (arg)) |
265 | 2178 XFASTINT (arg) = XFASTINT (XWINDOW (selected_window)->width) - 2; |
2179 else | |
2180 arg = Fprefix_numeric_value (arg); | |
2181 | |
2182 return | |
2183 Fset_window_hscroll (selected_window, | |
2184 make_number (XINT (XWINDOW (selected_window)->hscroll) | |
2185 + XINT (arg))); | |
2186 } | |
2187 | |
2188 DEFUN ("scroll-right", Fscroll_right, Sscroll_right, 1, 1, "P", | |
2189 "Scroll selected window display ARG columns right.\n\ | |
2190 Default for ARG is window width minus 2.") | |
2191 (arg) | |
2192 register Lisp_Object arg; | |
2193 { | |
485 | 2194 if (NILP (arg)) |
265 | 2195 XFASTINT (arg) = XFASTINT (XWINDOW (selected_window)->width) - 2; |
2196 else | |
2197 arg = Fprefix_numeric_value (arg); | |
2198 | |
2199 return | |
2200 Fset_window_hscroll (selected_window, | |
2201 make_number (XINT (XWINDOW (selected_window)->hscroll) | |
2202 - XINT (arg))); | |
2203 } | |
2204 | |
2205 DEFUN ("recenter", Frecenter, Srecenter, 0, 1, "P", | |
769 | 2206 "Center point in window and redisplay frame. With ARG, put point on line ARG.\n\ |
265 | 2207 The desired position of point is always relative to the current window.\n\ |
769 | 2208 Just C-u as prefix means put point in the center of the window.\n\ |
2209 No arg (i.e., it is nil) erases the entire frame and then\n\ | |
2210 redraws with point in the center of the current window.") | |
265 | 2211 (n) |
2212 register Lisp_Object n; | |
2213 { | |
2214 register struct window *w = XWINDOW (selected_window); | |
2215 register int ht = window_internal_height (w); | |
2216 register int opoint = point; | |
2217 | |
485 | 2218 if (NILP (n)) |
265 | 2219 { |
769 | 2220 extern int frame_garbaged; |
265 | 2221 |
769 | 2222 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w))); |
265 | 2223 XFASTINT (n) = ht / 2; |
2224 } | |
2225 else if (XTYPE (n) == Lisp_Cons) /* Just C-u. */ | |
2226 { | |
2227 XFASTINT (n) = ht / 2; | |
2228 } | |
2229 else | |
2230 { | |
2231 n = Fprefix_numeric_value (n); | |
2232 CHECK_NUMBER (n, 0); | |
2233 } | |
2234 | |
2235 if (XINT (n) < 0) | |
2236 XSETINT (n, XINT (n) + ht); | |
2237 | |
2238 XSETINT (n, - XINT (n)); | |
2239 | |
2240 Fvertical_motion (n); | |
2241 Fset_marker (w->start, make_number (point), w->buffer); | |
2242 w->start_at_line_beg = Fbolp (); | |
2243 | |
2244 SET_PT (opoint); | |
2245 w->force_start = Qt; | |
2246 | |
2247 return Qnil; | |
2248 } | |
2249 | |
2250 DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line, | |
2251 1, 1, "P", | |
2252 "Position point relative to window.\n\ | |
2253 With no argument, position text at center of window.\n\ | |
769 | 2254 An argument specifies frame line; zero means top of window,\n\ |
265 | 2255 negative means relative to bottom of window.") |
2256 (arg) | |
2257 register Lisp_Object arg; | |
2258 { | |
2259 register struct window *w = XWINDOW (selected_window); | |
2260 register int height = window_internal_height (w); | |
2261 register int start; | |
2262 | |
485 | 2263 if (NILP (arg)) |
265 | 2264 XFASTINT (arg) = height / 2; |
2265 else | |
2266 { | |
2267 arg = Fprefix_numeric_value (arg); | |
2268 if (XINT (arg) < 0) | |
2269 XSETINT (arg, XINT (arg) + height); | |
2270 } | |
2271 | |
2272 start = marker_position (w->start); | |
2273 if (start < BEGV || start > ZV) | |
2274 { | |
2275 Fvertical_motion (make_number (- height / 2)); | |
2276 Fset_marker (w->start, make_number (point), w->buffer); | |
2277 w->start_at_line_beg = Fbolp (); | |
2278 w->force_start = Qt; | |
2279 } | |
2280 else | |
2281 SET_PT (start); | |
2282 | |
2283 return Fvertical_motion (arg); | |
2284 } | |
2285 | |
2286 struct save_window_data | |
2287 { | |
2288 int size_from_Lisp_Vector_struct; | |
2289 struct Lisp_Vector *next_from_Lisp_Vector_struct; | |
769 | 2290 Lisp_Object frame_width, frame_height; |
265 | 2291 Lisp_Object current_window; |
2292 Lisp_Object current_buffer; | |
2293 Lisp_Object minibuf_scroll_window; | |
2294 Lisp_Object root_window; | |
2295 /* A vector, interpreted as a struct saved_window */ | |
2296 Lisp_Object saved_windows; | |
2297 }; | |
2298 #define SAVE_WINDOW_DATA_SIZE 7 /* Arg to Fmake_vector */ | |
2299 | |
2300 /* This is saved as a Lisp_Vector */ | |
2301 struct saved_window | |
2302 { | |
2303 /* these first two must agree with struct Lisp_Vector in lisp.h */ | |
2304 int size_from_Lisp_Vector_struct; | |
2305 struct Lisp_Vector *next_from_Lisp_Vector_struct; | |
2306 | |
2307 Lisp_Object window; | |
2308 Lisp_Object buffer, start, pointm, mark; | |
2309 Lisp_Object left, top, width, height, hscroll; | |
2310 Lisp_Object parent, prev; | |
2311 Lisp_Object start_at_line_beg; | |
2312 Lisp_Object display_table; | |
2313 }; | |
2314 #define SAVED_WINDOW_VECTOR_SIZE 14 /* Arg to Fmake_vector */ | |
2315 | |
2316 #define SAVED_WINDOW_N(swv,n) \ | |
2317 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)]))) | |
2318 | |
2319 DEFUN ("window-configuration-p", Fwindow_configuration_p, Swindow_configuration_p, 1, 1, 0, | |
2320 "T if OBJECT is a window-configration object.") | |
2321 (obj) | |
2322 Lisp_Object obj; | |
2323 { | |
2324 if (XTYPE (obj) == Lisp_Window_Configuration) | |
2325 return Qt; | |
2326 return Qnil; | |
2327 } | |
2328 | |
2329 | |
2330 DEFUN ("set-window-configuration", | |
2331 Fset_window_configuration, Sset_window_configuration, | |
2332 1, 1, 0, | |
2333 "Set the configuration of windows and buffers as specified by CONFIGURATION.\n\ | |
2334 CONFIGURATION must be a value previously returned\n\ | |
2335 by `current-window-configuration' (which see).") | |
1016
817b0ce337d7
* window.c (Fset_window_configuration): Removed #if 0'd code which
Jim Blandy <jimb@redhat.com>
parents:
983
diff
changeset
|
2336 (configuration) |
817b0ce337d7
* window.c (Fset_window_configuration): Removed #if 0'd code which
Jim Blandy <jimb@redhat.com>
parents:
983
diff
changeset
|
2337 Lisp_Object configuration; |
265 | 2338 { |
2339 register struct window *w; | |
2340 register struct save_window_data *data; | |
2341 struct Lisp_Vector *saved_windows; | |
2342 register struct saved_window *p; | |
2343 register Lisp_Object tem; | |
2344 Lisp_Object new_current_buffer; | |
2345 int k; | |
769 | 2346 FRAME_PTR f; |
265 | 2347 |
1016
817b0ce337d7
* window.c (Fset_window_configuration): Removed #if 0'd code which
Jim Blandy <jimb@redhat.com>
parents:
983
diff
changeset
|
2348 while (XTYPE (configuration) != Lisp_Window_Configuration) |
265 | 2349 { |
1016
817b0ce337d7
* window.c (Fset_window_configuration): Removed #if 0'd code which
Jim Blandy <jimb@redhat.com>
parents:
983
diff
changeset
|
2350 configuration = wrong_type_argument (intern ("window-configuration-p"), |
817b0ce337d7
* window.c (Fset_window_configuration): Removed #if 0'd code which
Jim Blandy <jimb@redhat.com>
parents:
983
diff
changeset
|
2351 configuration); |
265 | 2352 } |
2353 | |
1016
817b0ce337d7
* window.c (Fset_window_configuration): Removed #if 0'd code which
Jim Blandy <jimb@redhat.com>
parents:
983
diff
changeset
|
2354 data = (struct save_window_data *) XVECTOR (configuration); |
265 | 2355 saved_windows = XVECTOR (data->saved_windows); |
2356 | |
769 | 2357 f = XFRAME (XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame); |
265 | 2358 |
769 | 2359 if (XFASTINT (data->frame_height) != FRAME_HEIGHT (f) |
2360 || XFASTINT (data->frame_width) != FRAME_WIDTH (f)) | |
265 | 2361 { |
2362 /* Presumably something clever could be done. | |
2363 However, it doesn't seem worth the effort */ | |
769 | 2364 error ("Frame size %dx%d in saved window configuration mismatches frame.", |
2365 XFASTINT (data->frame_height), | |
2366 XFASTINT (data->frame_width)); | |
265 | 2367 } |
2368 | |
2369 windows_or_buffers_changed++; | |
2370 new_current_buffer = data->current_buffer; | |
485 | 2371 if (NILP (XBUFFER (new_current_buffer)->name)) |
265 | 2372 new_current_buffer = Qnil; |
2373 | |
769 | 2374 /* Mark all windows now on frame as "deleted". |
265 | 2375 Restoring the new configuration "undeletes" any that are in it. */ |
769 | 2376 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f))); |
265 | 2377 |
2378 for (k = 0; k < saved_windows->size; k++) | |
2379 { | |
2380 p = SAVED_WINDOW_N (saved_windows, k); | |
2381 w = XWINDOW (p->window); | |
2382 w->next = Qnil; | |
2383 | |
485 | 2384 if (!NILP (p->parent)) |
265 | 2385 w->parent = SAVED_WINDOW_N (saved_windows, XFASTINT (p->parent))->window; |
2386 else | |
2387 w->parent = Qnil; | |
2388 | |
485 | 2389 if (!NILP (p->prev)) |
265 | 2390 { |
2391 w->prev = SAVED_WINDOW_N (saved_windows, XFASTINT (p->prev))->window; | |
1016
817b0ce337d7
* window.c (Fset_window_configuration): Removed #if 0'd code which
Jim Blandy <jimb@redhat.com>
parents:
983
diff
changeset
|
2392 XWINDOW (w->prev)->next = p->window; |
265 | 2393 } |
2394 else | |
2395 { | |
2396 w->prev = Qnil; | |
485 | 2397 if (!NILP (w->parent)) |
265 | 2398 { |
2399 if (EQ (p->width, XWINDOW (w->parent)->width)) | |
2400 { | |
2401 XWINDOW (w->parent)->vchild = p->window; | |
2402 XWINDOW (w->parent)->hchild = Qnil; | |
2403 } | |
2404 else | |
2405 { | |
2406 XWINDOW (w->parent)->hchild = p->window; | |
2407 XWINDOW (w->parent)->vchild = Qnil; | |
2408 } | |
2409 } | |
2410 } | |
2411 w->left = p->left; | |
2412 w->top = p->top; | |
2413 w->width = p->width; | |
2414 w->height = p->height; | |
2415 w->hscroll = p->hscroll; | |
2416 w->display_table = p->display_table; | |
2417 XFASTINT (w->last_modified) = 0; | |
2418 | |
2419 /* Reinstall the saved buffer and pointers into it. */ | |
485 | 2420 if (NILP (p->buffer)) |
265 | 2421 w->buffer = p->buffer; |
2422 else | |
2423 { | |
485 | 2424 if (!NILP (XBUFFER (p->buffer)->name)) |
265 | 2425 /* If saved buffer is alive, install it. */ |
2426 { | |
2427 w->buffer = p->buffer; | |
2428 w->start_at_line_beg = p->start_at_line_beg; | |
2429 set_marker_restricted (w->start, Fmarker_position (p->start), w->buffer); | |
2430 set_marker_restricted (w->pointm, Fmarker_position (p->pointm), w->buffer); | |
2431 Fset_marker (XBUFFER (w->buffer)->mark, | |
2432 Fmarker_position (p->mark), w->buffer); | |
2433 | |
2434 if (!EQ (p->buffer, new_current_buffer) && | |
2435 XBUFFER (p->buffer) == current_buffer) | |
2436 Fgoto_char (w->pointm); | |
2437 } | |
485 | 2438 else if (NILP (XBUFFER (w->buffer)->name)) |
265 | 2439 /* Else if window's old buffer is dead too, get a live one. */ |
2440 { | |
2441 w->buffer = Fcdr (Fcar (Vbuffer_alist)); | |
2442 /* This will set the markers to beginning of visible range. */ | |
2443 set_marker_restricted (w->start, make_number (0), w->buffer); | |
2444 set_marker_restricted (w->pointm, make_number (0), w->buffer); | |
2445 w->start_at_line_beg = Qt; | |
2446 } | |
2447 else | |
2448 /* Keeping window's old buffer; make sure the markers are real. */ | |
2449 /* Else if window's old buffer is dead too, get a live one. */ | |
2450 { | |
2451 /* Set window markers at start of visible range. */ | |
2452 if (XMARKER (w->start)->buffer == 0) | |
2453 set_marker_restricted (w->start, make_number (0), w->buffer); | |
2454 if (XMARKER (w->pointm)->buffer == 0) | |
2455 set_marker_restricted (w->pointm, | |
2456 make_number (BUF_PT (XBUFFER (w->buffer))), | |
2457 w->buffer); | |
2458 w->start_at_line_beg = Qt; | |
2459 } | |
2460 } | |
2461 } | |
2462 | |
769 | 2463 FRAME_ROOT_WINDOW (f) = data->root_window; |
265 | 2464 |
769 | 2465 #ifdef MULTI_FRAME |
972
f47d221cbfe6
* window.c (MIN_SAFE_WINDOW_HEIGHT, MIN_SAFE_WINDOW_WIDTH): Macros
Jim Blandy <jimb@redhat.com>
parents:
780
diff
changeset
|
2466 if (f != selected_frame && ! FRAME_TERMCAP_P (f)) |
769 | 2467 Fselect_frame (WINDOW_FRAME (XWINDOW (data->root_window)), Qnil); |
265 | 2468 #endif |
2469 | |
769 | 2470 if (f == selected_frame) |
265 | 2471 { |
2472 Fselect_window (data->current_window); | |
485 | 2473 if (!NILP (new_current_buffer)) |
265 | 2474 Fset_buffer (new_current_buffer); |
2475 else | |
2476 Fset_buffer (XWINDOW (selected_window)->buffer); | |
2477 } | |
2478 | |
2479 Vminibuf_scroll_window = data->minibuf_scroll_window; | |
2480 return (Qnil); | |
2481 } | |
2482 | |
769 | 2483 /* Mark all windows now on frame as deleted |
265 | 2484 by setting their buffers to nil. */ |
2485 | |
2486 static void | |
2487 delete_all_subwindows (w) | |
2488 register struct window *w; | |
2489 { | |
2490 register int count = 1; | |
2491 w->buffer = Qnil; | |
485 | 2492 if (!NILP (w->next)) |
265 | 2493 delete_all_subwindows (XWINDOW (w->next)); |
485 | 2494 if (!NILP (w->vchild)) |
265 | 2495 delete_all_subwindows (XWINDOW (w->vchild)); |
485 | 2496 if (!NILP (w->hchild)) |
265 | 2497 delete_all_subwindows (XWINDOW (w->hchild)); |
2498 } | |
2499 | |
2500 static int | |
2501 count_windows (window) | |
2502 register struct window *window; | |
2503 { | |
2504 register int count = 1; | |
485 | 2505 if (!NILP (window->next)) |
265 | 2506 count += count_windows (XWINDOW (window->next)); |
485 | 2507 if (!NILP (window->vchild)) |
265 | 2508 count += count_windows (XWINDOW (window->vchild)); |
485 | 2509 if (!NILP (window->hchild)) |
265 | 2510 count += count_windows (XWINDOW (window->hchild)); |
2511 return count; | |
2512 } | |
2513 | |
2514 static int | |
2515 save_window_save (window, vector, i) | |
2516 Lisp_Object window; | |
2517 struct Lisp_Vector *vector; | |
2518 int i; | |
2519 { | |
2520 register struct saved_window *p; | |
2521 register struct window *w; | |
2522 register Lisp_Object tem; | |
2523 | |
485 | 2524 for (;!NILP (window); window = w->next) |
265 | 2525 { |
2526 p = SAVED_WINDOW_N (vector, i); | |
2527 w = XWINDOW (window); | |
2528 | |
2529 XFASTINT (w->temslot) = i++; | |
2530 p->window = window; | |
2531 p->buffer = w->buffer; | |
2532 p->left = w->left; | |
2533 p->top = w->top; | |
2534 p->width = w->width; | |
2535 p->height = w->height; | |
2536 p->hscroll = w->hscroll; | |
2537 p->display_table = w->display_table; | |
485 | 2538 if (!NILP (w->buffer)) |
265 | 2539 { |
2540 /* Save w's value of point in the window configuration. | |
2541 If w is the selected window, then get the value of point | |
2542 from the buffer; pointm is garbage in the selected window. */ | |
2543 if (EQ (window, selected_window)) | |
2544 { | |
2545 p->pointm = Fmake_marker (); | |
2546 Fset_marker (p->pointm, BUF_PT (XBUFFER (w->buffer)), | |
2547 w->buffer); | |
2548 } | |
2549 else | |
2550 p->pointm = Fcopy_marker (w->pointm); | |
2551 | |
2552 p->start = Fcopy_marker (w->start); | |
2553 p->start_at_line_beg = w->start_at_line_beg; | |
2554 | |
2555 tem = XBUFFER (w->buffer)->mark; | |
2556 p->mark = Fcopy_marker (tem); | |
2557 } | |
2558 else | |
2559 { | |
2560 p->pointm = Qnil; | |
2561 p->start = Qnil; | |
2562 p->mark = Qnil; | |
2563 p->start_at_line_beg = Qnil; | |
2564 } | |
2565 | |
485 | 2566 if (NILP (w->parent)) |
265 | 2567 p->parent = Qnil; |
2568 else | |
2569 p->parent = XWINDOW (w->parent)->temslot; | |
2570 | |
485 | 2571 if (NILP (w->prev)) |
265 | 2572 p->prev = Qnil; |
2573 else | |
2574 p->prev = XWINDOW (w->prev)->temslot; | |
2575 | |
485 | 2576 if (!NILP (w->vchild)) |
265 | 2577 i = save_window_save (w->vchild, vector, i); |
485 | 2578 if (!NILP (w->hchild)) |
265 | 2579 i = save_window_save (w->hchild, vector, i); |
2580 } | |
2581 | |
2582 return i; | |
2583 } | |
2584 | |
2585 DEFUN ("current-window-configuration", | |
358 | 2586 Fcurrent_window_configuration, Scurrent_window_configuration, 0, 1, 0, |
769 | 2587 "Return an object representing the current window configuration of FRAME.\n\ |
2588 If FRAME is nil or omitted, use the selected frame.\n\ | |
265 | 2589 This describes the number of windows, their sizes and current buffers,\n\ |
2590 and for each displayed buffer, where display starts, and the positions of\n\ | |
2591 point and mark. An exception is made for point in the current buffer:\n\ | |
2592 its value is -not- saved.") | |
769 | 2593 (frame) |
2594 Lisp_Object frame; | |
265 | 2595 { |
2596 register Lisp_Object tem; | |
2597 register int n_windows; | |
2598 register struct save_window_data *data; | |
2599 register int i; | |
769 | 2600 FRAME_PTR f; |
265 | 2601 |
769 | 2602 if (NILP (frame)) |
2603 f = selected_frame; | |
358 | 2604 else |
2605 { | |
769 | 2606 CHECK_LIVE_FRAME (frame, 0); |
2607 f = XFRAME (frame); | |
358 | 2608 } |
2609 | |
769 | 2610 n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f))); |
265 | 2611 data = (struct save_window_data *) |
2612 XVECTOR (Fmake_vector (make_number (SAVE_WINDOW_DATA_SIZE), | |
2613 Qnil)); | |
769 | 2614 XFASTINT (data->frame_width) = FRAME_WIDTH (f); |
2615 XFASTINT (data->frame_height) = FRAME_HEIGHT (f); | |
2616 data->current_window = FRAME_SELECTED_WINDOW (f); | |
265 | 2617 XSET (data->current_buffer, Lisp_Buffer, current_buffer); |
2618 data->minibuf_scroll_window = Vminibuf_scroll_window; | |
769 | 2619 data->root_window = FRAME_ROOT_WINDOW (f); |
265 | 2620 tem = Fmake_vector (make_number (n_windows), Qnil); |
2621 data->saved_windows = tem; | |
2622 for (i = 0; i < n_windows; i++) | |
2623 XVECTOR (tem)->contents[i] | |
2624 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE), Qnil); | |
769 | 2625 save_window_save (FRAME_ROOT_WINDOW (f), |
265 | 2626 XVECTOR (tem), 0); |
2627 XSET (tem, Lisp_Window_Configuration, data); | |
2628 return (tem); | |
2629 } | |
2630 | |
2631 DEFUN ("save-window-excursion", Fsave_window_excursion, Ssave_window_excursion, | |
2632 0, UNEVALLED, 0, | |
2633 "Execute body, preserving window sizes and contents.\n\ | |
2634 Restores which buffer appears in which window, where display starts,\n\ | |
2635 as well as the current buffer.\n\ | |
2636 Does not restore the value of point in current buffer.") | |
2637 (args) | |
2638 Lisp_Object args; | |
2639 { | |
2640 register Lisp_Object val; | |
2641 register int count = specpdl_ptr - specpdl; | |
2642 | |
2643 record_unwind_protect (Fset_window_configuration, | |
358 | 2644 Fcurrent_window_configuration (Qnil)); |
265 | 2645 val = Fprogn (args); |
2646 return unbind_to (count, val); | |
2647 } | |
2648 | |
2649 init_window_once () | |
2650 { | |
769 | 2651 #ifdef MULTI_FRAME |
2652 selected_frame = make_terminal_frame (); | |
2653 minibuf_window = selected_frame->minibuffer_window; | |
2654 selected_window = selected_frame->selected_window; | |
2655 last_nonminibuf_frame = selected_frame; | |
2656 #else /* not MULTI_FRAME */ | |
265 | 2657 extern Lisp_Object get_minibuffer (); |
2658 | |
983
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
2659 minibuf_window = make_window (); |
769 | 2660 FRAME_ROOT_WINDOW (selected_frame) = make_window (); |
265 | 2661 |
769 | 2662 XWINDOW (FRAME_ROOT_WINDOW (selected_frame))->next = minibuf_window; |
2663 XWINDOW (minibuf_window)->prev = FRAME_ROOT_WINDOW (selected_frame); | |
983
eb19dfaec9c4
* window.c (window_loop): This used to keep track of the first
Jim Blandy <jimb@redhat.com>
parents:
972
diff
changeset
|
2664 XWINDOW (minibuf_window)->mini_p = Qt; |
265 | 2665 |
2666 /* These values 9 and 10 are arbitrary, | |
2667 just so that there is "something there." | |
2668 Correct values are put in in init_xdisp */ | |
2669 | |
769 | 2670 XFASTINT (XWINDOW (FRAME_ROOT_WINDOW (selected_frame))->width) = 10; |
265 | 2671 XFASTINT (XWINDOW (minibuf_window)->width) = 10; |
2672 | |
769 | 2673 XFASTINT (XWINDOW (FRAME_ROOT_WINDOW (selected_frame))->height) = 9; |
265 | 2674 XFASTINT (XWINDOW (minibuf_window)->top) = 9; |
2675 XFASTINT (XWINDOW (minibuf_window)->height) = 1; | |
2676 | |
2677 /* Prevent error in Fset_window_buffer. */ | |
769 | 2678 XWINDOW (FRAME_ROOT_WINDOW (selected_frame))->buffer = Qt; |
265 | 2679 XWINDOW (minibuf_window)->buffer = Qt; |
2680 | |
2681 /* Now set them up for real. */ | |
769 | 2682 Fset_window_buffer (FRAME_ROOT_WINDOW (selected_frame), |
732 | 2683 Fcurrent_buffer ()); |
265 | 2684 Fset_window_buffer (minibuf_window, get_minibuffer (0)); |
2685 | |
769 | 2686 selected_window = FRAME_ROOT_WINDOW (selected_frame); |
362 | 2687 /* Make sure this window seems more recently used than |
2688 a newly-created, never-selected window. Increment | |
2689 window_select_count so the first selection ever will get | |
2690 something newer than this. */ | |
2691 XFASTINT (XWINDOW (selected_window)->use_time) = ++window_select_count; | |
769 | 2692 #endif /* not MULTI_FRAME */ |
265 | 2693 } |
2694 | |
2695 syms_of_window () | |
2696 { | |
2697 Qwindowp = intern ("windowp"); | |
2698 staticpro (&Qwindowp); | |
2699 | |
1016
817b0ce337d7
* window.c (Fset_window_configuration): Removed #if 0'd code which
Jim Blandy <jimb@redhat.com>
parents:
983
diff
changeset
|
2700 #ifndef MULTI_FRAME |
265 | 2701 /* Make sure all windows get marked */ |
2702 staticpro (&minibuf_window); | |
1016
817b0ce337d7
* window.c (Fset_window_configuration): Removed #if 0'd code which
Jim Blandy <jimb@redhat.com>
parents:
983
diff
changeset
|
2703 #endif |
265 | 2704 |
2705 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function, | |
2706 "Non-nil means call as function to display a help buffer.\n\ | |
2707 Used by `with-output-to-temp-buffer'."); | |
2708 Vtemp_buffer_show_function = Qnil; | |
2709 | |
2710 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function, | |
2711 "If non-nil, function to call to handle `display-buffer'.\n\ | |
2712 It will receive two args, the buffer and a flag which if non-nil means\n\ | |
2713 that the currently selected window is not acceptable.\n\ | |
2714 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\ | |
2715 work using this function."); | |
2716 Vdisplay_buffer_function = Qnil; | |
2717 | |
2718 DEFVAR_LISP ("mouse-window", &Vmouse_window, | |
2719 "Window that the last mouse click occurred on."); | |
2720 Vmouse_window = Qnil; | |
2721 | |
2722 DEFVAR_LISP ("mouse-event", &Vmouse_event, | |
2723 "The last mouse-event object. A list of four elements:\n\ | |
769 | 2724 ((X-POS Y-POS) WINDOW FRAME-PART KEYSEQ).\n\ |
265 | 2725 KEYSEQ is a string, the key sequence to be looked up in the mouse maps.\n\ |
2726 WINDOW is the window that the click applies do.\n\ | |
769 | 2727 If FRAME-PART is non-nil, the event was on a scrollbar;\n\ |
265 | 2728 then Y-POS is really the total length of the scrollbar, while X-POS is\n\ |
2729 the relative position of the scrollbar's value within that total length.\n\ | |
769 | 2730 FRAME-PART is one of the following symbols:\n\ |
265 | 2731 `vertical-scrollbar', `vertical-slider',\n\ |
2732 `vertical-thumbup', `vertical-thumbdown',\n\ | |
2733 `horizontal-scrollbar', `horizontal-slider',\n\ | |
2734 `horizontal-thumbleft', `horizontal-thumbright'"); | |
2735 Vmouse_event = Qnil; | |
2736 | |
2737 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window, | |
2738 "Non-nil means it is the window that C-M-v in minibuffer should scroll."); | |
2739 Vminibuf_scroll_window = Qnil; | |
2740 | |
2741 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer, | |
2742 "If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window."); | |
2743 Vother_window_scroll_buffer = Qnil; | |
2744 | |
769 | 2745 #ifdef MULTI_FRAME |
2746 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames, | |
780 | 2747 "*Non-nil means `display-buffer' should make a separate frame."); |
769 | 2748 pop_up_frames = 0; |
265 | 2749 |
769 | 2750 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function, |
2751 "*If non-nil, function to call to handle automatic new frame creation.\n\ | |
2752 It is called with no arguments and should return a newly created frame.\n\ | |
265 | 2753 \n\ |
769 | 2754 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'\n\ |
2755 where `pop-up-frame-alist' would hold the default frame parameters."); | |
2756 Vpop_up_frame_function = Qnil; | |
265 | 2757 #endif |
2758 | |
2759 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows, | |
2760 "*Non-nil means display-buffer should make new windows."); | |
2761 pop_up_windows = 1; | |
2762 | |
2763 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines, | |
2764 "*Number of lines of continuity when scrolling by screenfuls."); | |
2765 next_screen_context_lines = 2; | |
2766 | |
2767 DEFVAR_INT ("split-height-threshold", &split_height_threshold, | |
2768 "*display-buffer would prefer to split the largest window if this large.\n\ | |
2769 If there is only one window, it is split regardless of this value."); | |
2770 split_height_threshold = 500; | |
2771 | |
2772 DEFVAR_INT ("window-min-height", &window_min_height, | |
2773 "*Delete any window less than this tall (including its mode line)."); | |
2774 window_min_height = 4; | |
2775 | |
2776 DEFVAR_INT ("window-min-width", &window_min_width, | |
2777 "*Delete any window less than this wide."); | |
2778 window_min_width = 10; | |
2779 | |
2780 defsubr (&Sselected_window); | |
2781 defsubr (&Sminibuffer_window); | |
2782 defsubr (&Swindow_minibuffer_p); | |
2783 defsubr (&Swindowp); | |
2784 defsubr (&Spos_visible_in_window_p); | |
2785 defsubr (&Swindow_buffer); | |
2786 defsubr (&Swindow_height); | |
2787 defsubr (&Swindow_width); | |
2788 defsubr (&Swindow_hscroll); | |
2789 defsubr (&Sset_window_hscroll); | |
2790 defsubr (&Swindow_edges); | |
432 | 2791 defsubr (&Scoordinates_in_window_p); |
2792 defsubr (&Swindow_at); | |
265 | 2793 defsubr (&Swindow_point); |
2794 defsubr (&Swindow_start); | |
2795 defsubr (&Swindow_end); | |
2796 defsubr (&Sset_window_point); | |
2797 defsubr (&Sset_window_start); | |
2798 defsubr (&Swindow_dedicated_p); | |
722
0a2391511b46
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
708
diff
changeset
|
2799 defsubr (&Sset_window_dedicated_p); |
265 | 2800 defsubr (&Swindow_display_table); |
2801 defsubr (&Sset_window_display_table); | |
2802 defsubr (&Snext_window); | |
2803 defsubr (&Sprevious_window); | |
2804 defsubr (&Sother_window); | |
2805 defsubr (&Sget_lru_window); | |
2806 defsubr (&Sget_largest_window); | |
2807 defsubr (&Sget_buffer_window); | |
2808 defsubr (&Sdelete_other_windows); | |
2809 defsubr (&Sdelete_windows_on); | |
2810 defsubr (&Sreplace_buffer_in_windows); | |
2811 defsubr (&Sdelete_window); | |
2812 defsubr (&Sset_window_buffer); | |
2813 defsubr (&Sselect_window); | |
2814 defsubr (&Sdisplay_buffer); | |
2815 defsubr (&Ssplit_window); | |
2816 defsubr (&Senlarge_window); | |
2817 defsubr (&Sshrink_window); | |
2818 defsubr (&Sscroll_up); | |
2819 defsubr (&Sscroll_down); | |
2820 defsubr (&Sscroll_left); | |
2821 defsubr (&Sscroll_right); | |
2822 defsubr (&Sscroll_other_window); | |
2823 defsubr (&Srecenter); | |
2824 defsubr (&Smove_to_window_line); | |
2825 defsubr (&Swindow_configuration_p); | |
2826 defsubr (&Sset_window_configuration); | |
2827 defsubr (&Scurrent_window_configuration); | |
2828 defsubr (&Ssave_window_excursion); | |
2829 } | |
2830 | |
2831 keys_of_window () | |
2832 { | |
2833 initial_define_key (control_x_map, '1', "delete-other-windows"); | |
2834 initial_define_key (control_x_map, '2', "split-window"); | |
2835 initial_define_key (control_x_map, '0', "delete-window"); | |
2836 initial_define_key (control_x_map, 'o', "other-window"); | |
2837 initial_define_key (control_x_map, '^', "enlarge-window"); | |
2838 initial_define_key (control_x_map, '<', "scroll-left"); | |
2839 initial_define_key (control_x_map, '>', "scroll-right"); | |
2840 | |
2841 initial_define_key (global_map, Ctl ('V'), "scroll-up"); | |
2842 initial_define_key (meta_map, Ctl ('V'), "scroll-other-window"); | |
2843 initial_define_key (meta_map, 'v', "scroll-down"); | |
2844 | |
2845 initial_define_key (global_map, Ctl('L'), "recenter"); | |
2846 initial_define_key (meta_map, 'r', "move-to-window-line"); | |
2847 } |