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