|
|
1.1 ! root 1: /* Window creation, deletion and examination for GNU Emacs. ! 2: Does not include redisplay. ! 3: Copyright (C) 1985, 1986, 1987, 1990 Free Software Foundation, Inc. ! 4: ! 5: This file is part of GNU Emacs. ! 6: ! 7: GNU Emacs is free software; you can redistribute it and/or modify ! 8: it under the terms of the GNU General Public License as published by ! 9: the Free Software Foundation; either version 1, or (at your option) ! 10: any later version. ! 11: ! 12: GNU Emacs is distributed in the hope that it will be useful, ! 13: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: GNU General Public License for more details. ! 16: ! 17: You should have received a copy of the GNU General Public License ! 18: along with GNU Emacs; see the file COPYING. If not, write to ! 19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 20: ! 21: ! 22: #include "config.h" ! 23: #include "lisp.h" ! 24: #include "buffer.h" ! 25: #include "window.h" ! 26: #include "commands.h" ! 27: #include "indent.h" ! 28: #include "termchar.h" ! 29: ! 30: Lisp_Object Qwindowp; ! 31: ! 32: Lisp_Object Fnext_window (), Fdelete_window (), Fselect_window (); ! 33: Lisp_Object Fset_window_buffer (), Fsplit_window (), Frecenter (); ! 34: ! 35: static void replace_window (), unshow_buffer (); ! 36: static int save_window_save (); ! 37: ! 38: extern int minibuf_prompt_width; ! 39: ! 40: /* This is the window which displays the minibuffer. ! 41: It is always the same window. */ ! 42: ! 43: Lisp_Object minibuf_window; ! 44: ! 45: /* This is the window in which the terminal's cursor should ! 46: be left when nothing is being done with it. This must ! 47: always be a leaf window, and its buffer is selected by ! 48: the top level editing loop at the end of each command. */ ! 49: ! 50: Lisp_Object selected_window; ! 51: ! 52: /* Non-nil means it is the window for C-M-v to scroll ! 53: when the minibuffer is selected. */ ! 54: ! 55: Lisp_Object Vminibuf_scroll_window; ! 56: ! 57: /* Non-nil means it's function to call to display temp buffers. */ ! 58: ! 59: Lisp_Object Vtemp_buffer_show_hook; ! 60: ! 61: /* If a window gets smaller than either of these, it is removed. */ ! 62: ! 63: int window_min_height; ! 64: int window_min_width; ! 65: ! 66: /* Nonzero implies pop_to_buffer should create windows. */ ! 67: ! 68: int pop_up_windows; ! 69: ! 70: /* display-buffer always splits the largest window ! 71: if that window is more than this high */ ! 72: ! 73: int split_height_threshold; ! 74: ! 75: /* Number of lines of continuity in scrolling by screenfuls. */ ! 76: ! 77: int next_screen_context_lines; ! 78: ! 79: /* Incremented for each window created. */ ! 80: ! 81: static int sequence_number; ! 82: ! 83: DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0, ! 84: "Returns t if OBJ is a window.") ! 85: (obj) ! 86: Lisp_Object obj; ! 87: { ! 88: return XTYPE (obj) == Lisp_Window ? Qt : Qnil; ! 89: } ! 90: ! 91: static Lisp_Object ! 92: make_window () ! 93: { ! 94: register Lisp_Object val; ! 95: register struct window *p; ! 96: ! 97: /* Add sizeof (Lisp_Object) here because sizeof (struct Lisp_Vector) ! 98: includes the first element. */ ! 99: val = Fmake_vector ( ! 100: make_number ((sizeof (struct window) - sizeof (struct Lisp_Vector) ! 101: + sizeof (Lisp_Object)) ! 102: / sizeof (Lisp_Object)), ! 103: Qnil); ! 104: XSETTYPE (val, Lisp_Window); ! 105: p = XWINDOW (val); ! 106: XFASTINT (p->sequence_number) = ++sequence_number; ! 107: XFASTINT (p->left) = XFASTINT (p->top) ! 108: = XFASTINT (p->height) = XFASTINT (p->width) ! 109: = XFASTINT (p->hscroll) = 0; ! 110: XFASTINT (p->last_point_x) = XFASTINT (p->last_point_y) = 0; ! 111: p->start = Fmake_marker (); ! 112: p->pointm = Fmake_marker (); ! 113: XFASTINT (p->use_time) = 0; ! 114: return val; ! 115: } ! 116: ! 117: DEFUN ("selected-window", Fselected_window, Sselected_window, 0, 0, 0, ! 118: "Return the window that the cursor now appears in and commands apply to.") ! 119: () ! 120: { ! 121: return selected_window; ! 122: } ! 123: ! 124: DEFUN ("minibuffer-window", Fminibuffer_window, Sminibuffer_window, 0, 0, 0, ! 125: "Return the window used for minibuffers.") ! 126: () ! 127: { ! 128: return minibuf_window; ! 129: } ! 130: ! 131: DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p, ! 132: Spos_visible_in_window_p, 0, 2, 0, ! 133: "Return t if position POS is currently on the screen in WINDOW.\n\ ! 134: Returns nil if that position is scrolled vertically out of view.\n\ ! 135: POS defaults to point; WINDOW, to the selected window.") ! 136: (pos, window) ! 137: Lisp_Object pos, window; ! 138: { ! 139: register struct window *w; ! 140: register int top; ! 141: register int height; ! 142: register int posint; ! 143: register struct buffer *buf; ! 144: struct position posval; ! 145: ! 146: if (NULL (pos)) ! 147: posint = point; ! 148: else ! 149: { ! 150: CHECK_NUMBER_COERCE_MARKER (pos, 0); ! 151: posint = XINT (pos); ! 152: } ! 153: ! 154: if (NULL (window)) ! 155: window = selected_window; ! 156: else ! 157: CHECK_WINDOW (window, 1); ! 158: w = XWINDOW (window); ! 159: top = marker_position (w->start); ! 160: ! 161: if (posint < top) ! 162: return Qnil; ! 163: ! 164: height = XFASTINT (w->height) - !EQ (window, minibuf_window); ! 165: ! 166: buf = XBUFFER (w->buffer); ! 167: if (XFASTINT (w->last_modified) >= BUF_MODIFF (buf)) ! 168: { ! 169: /* If screen is up to date, ! 170: use the info recorded about how much text fit on it. */ ! 171: if (posint < BUF_Z (buf) - XFASTINT (w->window_end_pos) ! 172: || (XFASTINT (w->window_end_vpos) < height)) ! 173: return Qt; ! 174: return Qnil; ! 175: } ! 176: else ! 177: { ! 178: if (posint > BUF_Z (buf)) ! 179: return Qnil; ! 180: /* If that info is not correct, calculate afresh */ ! 181: posval = *compute_motion (top, 0, 0, ! 182: posint, height, 0, ! 183: XFASTINT (w->width) - 1 ! 184: - (XFASTINT (w->width) + XFASTINT (w->left) != XFASTINT (XWINDOW (minibuf_window)->width)), ! 185: ! 186: XINT (w->hscroll), 0); ! 187: return posval.vpos < height ? Qt : Qnil; ! 188: } ! 189: } ! 190: ! 191: static struct window * ! 192: decode_window (window) ! 193: register Lisp_Object window; ! 194: { ! 195: if (NULL (window)) ! 196: return XWINDOW (selected_window); ! 197: ! 198: CHECK_WINDOW (window, 0); ! 199: return XWINDOW (window); ! 200: } ! 201: ! 202: DEFUN ("window-buffer", Fwindow_buffer, Swindow_buffer, 0, 1, 0, ! 203: "Return the buffer that WINDOW is displaying.") ! 204: (window) ! 205: Lisp_Object window; ! 206: { ! 207: return decode_window (window)->buffer; ! 208: } ! 209: ! 210: DEFUN ("window-height", Fwindow_height, Swindow_height, 0, 1, 0, ! 211: "Return the number of lines in WINDOW (including its mode line).") ! 212: (window) ! 213: Lisp_Object window; ! 214: { ! 215: return decode_window (window)->height; ! 216: } ! 217: ! 218: DEFUN ("window-width", Fwindow_width, Swindow_width, 0, 1, 0, ! 219: "Return the number of columns in WINDOW.") ! 220: (window) ! 221: Lisp_Object window; ! 222: { ! 223: register int w = decode_window (window)->width; ! 224: /* If this window does not end at the right margin, ! 225: must deduct one column for the border */ ! 226: if (w + decode_window (window)->left == screen_width) ! 227: return w; ! 228: return w - 1; ! 229: } ! 230: ! 231: DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0, ! 232: "Return the number of columns by which WINDOW is scrolled from left margin.") ! 233: (window) ! 234: Lisp_Object window; ! 235: { ! 236: return decode_window (window)->hscroll; ! 237: } ! 238: ! 239: DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0, ! 240: "Set number of columns WINDOW is scrolled from left margin to NCOL.\n\ ! 241: NCOL should be zero or positive.") ! 242: (window, ncol) ! 243: register Lisp_Object window, ncol; ! 244: { ! 245: register struct window *w; ! 246: ! 247: CHECK_NUMBER (ncol, 1); ! 248: if (XINT (ncol) < 0) XFASTINT (ncol) = 0; ! 249: if (XFASTINT (ncol) >= (1 << (SHORTBITS - 1))) ! 250: args_out_of_range (ncol, Qnil); ! 251: w = decode_window (window); ! 252: if (w->hscroll != ncol) ! 253: clip_changed = 1; /* Prevent redisplay shortcuts */ ! 254: w->hscroll = ncol; ! 255: return ncol; ! 256: } ! 257: ! 258: DEFUN ("window-edges", Fwindow_edges, Swindow_edges, 0, 1, 0, ! 259: "Return a list of the edge coordinates of WINDOW.\n\ ! 260: \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of screen.\n\ ! 261: RIGHT is one more than the rightmost column used by WINDOW,\n\ ! 262: and BOTTOM is one more than the bottommost row used by WINDOW\n\ ! 263: and its mode-line.") ! 264: (window) ! 265: Lisp_Object window; ! 266: { ! 267: register struct window *w = decode_window (window); ! 268: ! 269: return Fcons (w->left, Fcons (w->top, ! 270: Fcons (make_number (XFASTINT (w->left) + XFASTINT (w->width)), ! 271: Fcons (make_number (XFASTINT (w->top) ! 272: + XFASTINT (w->height)), ! 273: Qnil)))); ! 274: } ! 275: ! 276: DEFUN ("window-point", Fwindow_point, Swindow_point, 0, 1, 0, ! 277: "Return current value of point in WINDOW.\n\ ! 278: For a nonselected window, this is the value point would have\n\ ! 279: if that window were selected.\n\ ! 280: \n\ ! 281: Note that, when WINDOW is the selected window and its buffer\n\ ! 282: is also currently selected, the value returned is the same as (point).\n\ ! 283: It would be more strictly correct to return the `top-level' value\n\ ! 284: of point, outside of any save-excursion forms.\n\ ! 285: But that is hard to define.") ! 286: (window) ! 287: Lisp_Object window; ! 288: { ! 289: register struct window *w = decode_window (window); ! 290: ! 291: if (w == XWINDOW (selected_window) ! 292: && current_buffer == XBUFFER (w->buffer)) ! 293: return Fpoint (); ! 294: return Fmarker_position (w->pointm); ! 295: } ! 296: ! 297: DEFUN ("window-start", Fwindow_start, Swindow_start, 0, 1, 0, ! 298: "Return position at which display currently starts in WINDOW.") ! 299: (window) ! 300: Lisp_Object window; ! 301: { ! 302: return Fmarker_position (decode_window (window)->start); ! 303: } ! 304: ! 305: DEFUN ("set-window-point", Fset_window_point, Sset_window_point, 2, 2, 0, ! 306: "Make point value in WINDOW be at position POS in WINDOW's buffer.") ! 307: (window, pos) ! 308: Lisp_Object window, pos; ! 309: { ! 310: register struct window *w = decode_window (window); ! 311: ! 312: CHECK_NUMBER_COERCE_MARKER (pos, 1); ! 313: if (w == XWINDOW (selected_window)) ! 314: Fgoto_char (pos); ! 315: else ! 316: set_marker_restricted (w->pointm, pos, w->buffer); ! 317: return pos; ! 318: } ! 319: ! 320: DEFUN ("set-window-start", Fset_window_start, Sset_window_start, 2, 3, 0, ! 321: "Make display in WINDOW start at position POS in WINDOW's buffer.\n\ ! 322: Optional third arg NOFORCE non-nil inhibits next redisplay\n\ ! 323: from overriding motion of point in order to display at this exact start.") ! 324: (window, pos, noforce) ! 325: Lisp_Object window, pos, noforce; ! 326: { ! 327: register struct window *w = decode_window (window); ! 328: ! 329: CHECK_NUMBER_COERCE_MARKER (pos, 1); ! 330: set_marker_restricted (w->start, pos, w->buffer); ! 331: /* this is not right, but much easier than doing what is right. */ ! 332: w->start_at_line_beg = Qnil; ! 333: if (NULL (noforce)) ! 334: w->force_start = Qt; ! 335: w->update_mode_line = Qt; ! 336: XFASTINT (w->last_modified) = 0; ! 337: return pos; ! 338: } ! 339: ! 340: DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "", ! 341: "Remove WINDOW from the display. Default is selected window.") ! 342: (window) ! 343: register Lisp_Object window; ! 344: { ! 345: int osize; ! 346: register Lisp_Object tem, parent; ! 347: register struct window *p; ! 348: register struct window *par; ! 349: ! 350: if (NULL (window)) ! 351: window = selected_window; ! 352: else ! 353: CHECK_WINDOW (window, 0); ! 354: ! 355: p = XWINDOW (window); ! 356: parent = p->parent; ! 357: if (NULL (parent)) ! 358: error ("Attempt to delete minibuffer or sole ordinary window"); ! 359: par=XWINDOW (parent); ! 360: ! 361: windows_or_buffers_changed++; ! 362: ! 363: if (EQ (window, selected_window)) ! 364: Fselect_window (Fnext_window (window, Qnil)); ! 365: ! 366: tem = p->buffer; ! 367: /* tem is null for dummy parent windows ! 368: (which have inferiors but not any contents themselves) */ ! 369: if (!NULL (tem)) ! 370: { ! 371: unshow_buffer (p); ! 372: unchain_marker (p->pointm); ! 373: unchain_marker (p->start); ! 374: } ! 375: ! 376: tem = p->next; ! 377: if (!NULL (tem)) ! 378: XWINDOW (tem)->prev = p->prev; ! 379: ! 380: tem = p->prev; ! 381: if (!NULL (tem)) ! 382: XWINDOW (tem)->next = p->next; ! 383: ! 384: if (EQ (window, par->hchild)) ! 385: par->hchild = p->next; ! 386: if (EQ (window, par->vchild)) ! 387: par->vchild = p->next; ! 388: ! 389: /* Stretch the siblings to use all the available space */ ! 390: if (!NULL (par->vchild)) ! 391: { ! 392: /* It's a vertical combination */ ! 393: osize = XFASTINT (par->height); ! 394: XFASTINT (par->height) ! 395: -= XFASTINT (p->height); ! 396: set_window_height (parent, osize, 1); ! 397: } ! 398: if (!NULL (par->hchild)) ! 399: { ! 400: /* It's a horizontal combination */ ! 401: osize = XFASTINT (par->width); ! 402: XFASTINT (par->width) ! 403: -= XFASTINT (p->width); ! 404: set_window_width (parent, osize, 1); ! 405: } ! 406: ! 407: /* If parent now has only one child, ! 408: put the child into the parent's place. */ ! 409: ! 410: tem = par->hchild; ! 411: if (NULL (tem)) ! 412: tem = par->vchild; ! 413: if (NULL (XWINDOW (tem)->next)) ! 414: replace_window (parent, tem); ! 415: return Qnil; ! 416: } ! 417: ! 418: /* Put replacement into the window structure in place of old. */ ! 419: static void ! 420: replace_window (old, replacement) ! 421: Lisp_Object old, replacement; ! 422: { ! 423: register Lisp_Object tem; ! 424: register struct window *o = XWINDOW (old), *p = XWINDOW (replacement); ! 425: ! 426: p->left = o->left; ! 427: p->top = o->top; ! 428: p->width = o->width; ! 429: p->height = o->height; ! 430: ! 431: p->next = tem = o->next; ! 432: if (!NULL (tem)) ! 433: XWINDOW (tem)->prev = replacement; ! 434: ! 435: p->prev = tem = o->prev; ! 436: if (!NULL (tem)) ! 437: XWINDOW (tem)->next = replacement; ! 438: ! 439: p->parent = tem = o->parent; ! 440: if (!NULL (tem)) ! 441: { ! 442: if (EQ (XWINDOW (tem)->vchild, old)) ! 443: XWINDOW (tem)->vchild = replacement; ! 444: if (EQ (XWINDOW (tem)->hchild, old)) ! 445: XWINDOW (tem)->hchild = replacement; ! 446: } ! 447: ! 448: /*** Here, if replacement is a vertical combination ! 449: and so is its new parent, we should make replacement's ! 450: children be children of that parent instead. ***/ ! 451: } ! 452: ! 453: DEFUN ("next-window", Fnext_window, Snext_window, 0, 2, 0, ! 454: "Return next window after WINDOW in canonical ordering of windows.\n\ ! 455: Optional second arg MINIBUF t means count the minibuffer window\n\ ! 456: even if not active. If MINIBUF is neither t nor nil it means\n\ ! 457: not to count the minibuffer even if it is active.") ! 458: (window, mini) ! 459: register Lisp_Object window, mini; ! 460: { ! 461: register Lisp_Object tem; ! 462: if (NULL (window)) ! 463: window = selected_window; ! 464: else ! 465: CHECK_WINDOW (window, 0); ! 466: do ! 467: { ! 468: while (tem = XWINDOW (window)->next, NULL (tem)) ! 469: if (tem = XWINDOW (window)->parent, !NULL (tem)) ! 470: window = tem; ! 471: else /* window must be minibuf_window now */ ! 472: { ! 473: tem = XWINDOW (window)->prev; ! 474: break; ! 475: } ! 476: window = tem; ! 477: while (1) ! 478: { ! 479: if (!NULL (XWINDOW (window)->hchild)) ! 480: window = XWINDOW (window)->hchild; ! 481: else if (!NULL (XWINDOW (window)->vchild)) ! 482: window = XWINDOW (window)->vchild; ! 483: else break; ! 484: } ! 485: } ! 486: while (EQ (window, minibuf_window) && !EQ (mini, Qt) ! 487: && (!NULL (mini) || minibuf_level == 0)); ! 488: return window; ! 489: } ! 490: ! 491: DEFUN ("previous-window", Fprevious_window, Sprevious_window, 0, 1, 0, ! 492: "Return previous window before WINDOW in canonical ordering of windows.") ! 493: (window) ! 494: register Lisp_Object window; ! 495: { ! 496: register Lisp_Object tem; ! 497: if (NULL (window)) ! 498: window = selected_window; ! 499: else ! 500: CHECK_WINDOW (window, 0); ! 501: do /* at least once, and until not the minibuffer */ ! 502: { ! 503: while (tem = XWINDOW (window)->prev, NULL (tem)) ! 504: if (tem = XWINDOW (window)->parent, !NULL (tem)) ! 505: window = tem; ! 506: else /* window must be the root window now */ ! 507: { ! 508: tem = minibuf_window; ! 509: break; ! 510: } ! 511: window = tem; ! 512: while (1) ! 513: { ! 514: if (!NULL (XWINDOW (window)->hchild)) ! 515: window = XWINDOW (window)->hchild; ! 516: else if (!NULL (XWINDOW (window)->vchild)) ! 517: window = XWINDOW (window)->vchild; ! 518: else break; ! 519: while (tem = XWINDOW (window)->next, !NULL (tem)) ! 520: window = tem; ! 521: } ! 522: } ! 523: while (EQ (window, minibuf_window) && minibuf_level == 0); ! 524: return window; ! 525: } ! 526: ! 527: DEFUN ("other-window", Fother_window, Sother_window, 1, 1, "p", ! 528: "Select the ARG'th different window.") ! 529: (n) ! 530: register Lisp_Object n; ! 531: { ! 532: register int i; ! 533: register Lisp_Object w; ! 534: ! 535: CHECK_NUMBER (n, 0); ! 536: w = selected_window; ! 537: i = XINT (n); ! 538: ! 539: while (i > 0) ! 540: { ! 541: w = Fnext_window (w, Qnil); ! 542: i--; ! 543: } ! 544: while (i < 0) ! 545: { ! 546: w = Fprevious_window (w); ! 547: i++; ! 548: } ! 549: Fselect_window (w); ! 550: return Qnil; ! 551: } ! 552: ! 553: static Lisp_Object ! 554: window_loop (type, obj) ! 555: int type; ! 556: register Lisp_Object obj; ! 557: { ! 558: register Lisp_Object w, tem, ret_w; ! 559: Lisp_Object w1, start_w; ! 560: register struct window *p, *q; ! 561: ! 562: w = minibuf_window; ! 563: ret_w = Qnil; ! 564: while (1) ! 565: { ! 566: p = XWINDOW (w); ! 567: w1 = Fnext_window (w, Qt); ! 568: if (!EQ (w, minibuf_window)) ! 569: switch (type) ! 570: { ! 571: case 1: ! 572: if (XBUFFER (p->buffer) == XBUFFER (obj)) ! 573: return w; ! 574: break; ! 575: ! 576: case 2: ! 577: /* t as arg means consider only full-width windows */ ! 578: if (!NULL (obj) && XFASTINT (p->width) != screen_width) ! 579: break; ! 580: if (NULL (ret_w) || ! 581: XFASTINT (XWINDOW (ret_w)->use_time) > XFASTINT (p->use_time)) ! 582: ret_w = w; ! 583: break; ! 584: ! 585: case 3: ! 586: if (p != XWINDOW (obj)) ! 587: Fdelete_window (w); ! 588: break; ! 589: ! 590: case 4: ! 591: if (EQ (p->buffer, obj)) ! 592: { ! 593: if (NULL (p->parent)) ! 594: { ! 595: tem = Fother_buffer (obj); ! 596: if (NULL (tem)) ! 597: tem = Fget_buffer_create (build_string ("*scratch*")); ! 598: Fset_window_buffer (w, tem); ! 599: Fset_buffer (p->buffer); ! 600: } ! 601: else ! 602: Fdelete_window (w); ! 603: } ! 604: break; ! 605: ! 606: case 5: ! 607: q = XWINDOW (ret_w); ! 608: if (NULL (ret_w) || ! 609: (XFASTINT (p->height) * XFASTINT (p->width)) ! 610: > ! 611: (XFASTINT (q->height) * XFASTINT (q->width))) ! 612: ret_w = w; ! 613: break; ! 614: ! 615: case 6: ! 616: if (EQ (p->buffer, obj)) ! 617: { ! 618: tem = Fother_buffer (obj); ! 619: if (NULL (tem)) ! 620: tem = Fget_buffer_create (build_string ("*scratch*")); ! 621: Fset_window_buffer (w, tem); ! 622: } ! 623: break; ! 624: } ! 625: w = w1; ! 626: if (EQ (w, minibuf_window)) ! 627: return ret_w; ! 628: } ! 629: } ! 630: ! 631: DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 0, 0, ! 632: "Return the window least recently selected or used for display.") ! 633: () ! 634: { ! 635: register Lisp_Object w; ! 636: /* First try for a window that is full-width */ ! 637: w = window_loop (2, Qt); ! 638: if (!NULL (w) && !EQ (w, selected_window)) ! 639: return w; ! 640: /* If none of them, try the rest */ ! 641: return window_loop (2, Qnil); ! 642: } ! 643: ! 644: DEFUN ("get-largest-window", Fget_largest_window, Sget_largest_window, 0, 0, 0, ! 645: "Return the largest window in area.") ! 646: () ! 647: { ! 648: return window_loop (5, Qnil); ! 649: } ! 650: ! 651: DEFUN ("get-buffer-window", Fget_buffer_window, Sget_buffer_window, 1, 1, 0, ! 652: "Return a window currently displaying BUFFER, or nil if none.") ! 653: (buffer) ! 654: Lisp_Object buffer; ! 655: { ! 656: buffer = Fget_buffer (buffer); ! 657: if (XTYPE (buffer) == Lisp_Buffer) ! 658: return window_loop (1, buffer); ! 659: else return Qnil; ! 660: } ! 661: ! 662: DEFUN ("delete-other-windows", Fdelete_other_windows, Sdelete_other_windows, ! 663: 0, 1, "", ! 664: "Make WINDOW (or the selected window) fill the screen.") ! 665: (w) ! 666: Lisp_Object w; ! 667: { ! 668: window_loop (3, !NULL (w) ? w : selected_window); ! 669: return Qnil; ! 670: } ! 671: ! 672: DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on, ! 673: 1, 1, "bDelete windows on (buffer): ", ! 674: "Delete all windows showing BUFFER.") ! 675: (buffer) ! 676: Lisp_Object buffer; ! 677: { ! 678: if (!NULL (buffer)) ! 679: { ! 680: buffer = Fget_buffer (buffer); ! 681: CHECK_BUFFER (buffer, 0); ! 682: window_loop (4, buffer); ! 683: } ! 684: return Qnil; ! 685: } ! 686: ! 687: DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows, ! 688: Sreplace_buffer_in_windows, ! 689: 1, 1, "bReplace buffer in windows: ", ! 690: "Replace BUFFER with some other buffer in all windows showing it.") ! 691: (buffer) ! 692: Lisp_Object buffer; ! 693: { ! 694: if (!NULL (buffer)) ! 695: { ! 696: buffer = Fget_buffer (buffer); ! 697: CHECK_BUFFER (buffer, 0); ! 698: window_loop (6, buffer); ! 699: } ! 700: return Qnil; ! 701: } ! 702: ! 703: /* Set the height of WINDOW and all its inferiors. */ ! 704: /* Normally the window is deleted if it gets too small. ! 705: nodelete nonzero means do not do this. ! 706: (The caller should check later and do so if appropriate) */ ! 707: ! 708: set_window_height (window, height, nodelete) ! 709: Lisp_Object window; ! 710: int height; ! 711: int nodelete; ! 712: { ! 713: register struct window *w = XWINDOW (window); ! 714: register struct window *c; ! 715: int oheight = XFASTINT (w->height); ! 716: int top, pos, lastbot, opos, lastobot; ! 717: Lisp_Object child; ! 718: ! 719: if (window_min_height < 2) ! 720: window_min_height = 2; ! 721: ! 722: if (!nodelete ! 723: && ! NULL (w->parent) ! 724: && height < (EQ(window, minibuf_window) ? 1 : window_min_height)) ! 725: { ! 726: Fdelete_window (window); ! 727: return; ! 728: } ! 729: ! 730: XFASTINT (w->last_modified) = 0; ! 731: windows_or_buffers_changed++; ! 732: XFASTINT (w->height) = height; ! 733: if (!NULL (w->hchild)) ! 734: { ! 735: for (child = w->hchild; !NULL (child); child = XWINDOW (child)->next) ! 736: { ! 737: XWINDOW (child)->top = w->top; ! 738: set_window_height (child, height, nodelete); ! 739: } ! 740: } ! 741: else if (!NULL (w->vchild)) ! 742: { ! 743: lastbot = top = XFASTINT (w->top); ! 744: lastobot = 0; ! 745: for (child = w->vchild; !NULL (child); child = c->next) ! 746: { ! 747: c = XWINDOW (child); ! 748: ! 749: opos = lastobot + XFASTINT (c->height); ! 750: ! 751: XFASTINT (c->top) = lastbot; ! 752: ! 753: pos = (((opos * height) << 1) + oheight) / (oheight << 1); ! 754: ! 755: /* Avoid confusion: inhibit deletion of child if becomes too small */ ! 756: set_window_height (child, pos + top - lastbot, 1); ! 757: ! 758: /* Now advance child to next window, ! 759: and set lastbot if child was not just deleted. */ ! 760: lastbot = pos + top, lastobot = opos; ! 761: } ! 762: /* Now delete any children that became too small. */ ! 763: if (!nodelete) ! 764: for (child = w->vchild; !NULL (child); child = XWINDOW (child)->next) ! 765: { ! 766: set_window_height (child, XINT (XWINDOW (child)->height), 0); ! 767: } ! 768: } ! 769: } ! 770: ! 771: /* Recursively set width of WINDOW and its inferiors. */ ! 772: ! 773: set_window_width (window, width, nodelete) ! 774: Lisp_Object window; ! 775: int width; ! 776: int nodelete; ! 777: { ! 778: register struct window *w = XWINDOW (window); ! 779: register struct window *c; ! 780: int owidth = XFASTINT (w->width); ! 781: int left, pos, lastright, opos, lastoright; ! 782: Lisp_Object child; ! 783: ! 784: if (!nodelete ! 785: && ! NULL (w->parent) ! 786: && width < window_min_width) ! 787: { ! 788: Fdelete_window (window); ! 789: return; ! 790: } ! 791: ! 792: XFASTINT (w->last_modified) = 0; ! 793: windows_or_buffers_changed++; ! 794: XFASTINT (w->width) = width; ! 795: if (!NULL (w->vchild)) ! 796: { ! 797: for (child = w->vchild; !NULL (child); child = XWINDOW (child)->next) ! 798: { ! 799: XWINDOW (child)->left = w->left; ! 800: set_window_width (child, width, nodelete); ! 801: } ! 802: } ! 803: else if (!NULL (w->hchild)) ! 804: { ! 805: lastright = left = XFASTINT (w->left); ! 806: lastoright = 0; ! 807: for (child = w->hchild; !NULL (child); child = c->next) ! 808: { ! 809: c = XWINDOW (child); ! 810: ! 811: opos = lastoright + XFASTINT (c->width); ! 812: ! 813: XFASTINT (c->left) = lastright; ! 814: ! 815: pos = (((opos * width) << 1) + owidth) / (owidth << 1); ! 816: ! 817: /* Inhibit deletion for becoming too small */ ! 818: set_window_width (child, pos + left - lastright, 1); ! 819: ! 820: /* Now advance child to next window, ! 821: and set lastright if child was not just deleted. */ ! 822: lastright = pos + left, lastoright = opos; ! 823: } ! 824: /* Delete children that became too small */ ! 825: if (!nodelete) ! 826: for (child = w->hchild; !NULL (child); child = XWINDOW (child)->next) ! 827: { ! 828: set_window_width (child, XINT (XWINDOW (child)->width), 0); ! 829: } ! 830: } ! 831: } ! 832: ! 833: static int window_select_count; ! 834: ! 835: DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 2, 0, ! 836: "Make WINDOW display BUFFER as its contents.\n\ ! 837: BUFFER can be a buffer or buffer name.") ! 838: (window, buffer) ! 839: register Lisp_Object window, buffer; ! 840: { ! 841: register Lisp_Object tem; ! 842: register struct window *w = decode_window (window); ! 843: ! 844: buffer = Fget_buffer (buffer); ! 845: CHECK_BUFFER (buffer, 1); ! 846: ! 847: if (NULL (XBUFFER (buffer)->name)) ! 848: error ("Attempt to display deleted buffer"); ! 849: ! 850: tem = w->buffer; ! 851: if (!NULL (tem)) ! 852: unshow_buffer (w); ! 853: ! 854: w->buffer = buffer; ! 855: Fset_marker (w->pointm, ! 856: make_number (BUF_PT (XBUFFER (buffer))), ! 857: buffer); ! 858: set_marker_restricted (w->start, ! 859: make_number (XBUFFER (buffer)->last_window_start), ! 860: buffer); ! 861: w->start_at_line_beg = Qnil; ! 862: XFASTINT (w->last_modified) = 0; ! 863: windows_or_buffers_changed++; ! 864: if (EQ (window, selected_window)) ! 865: Fset_buffer (buffer); ! 866: ! 867: return Qnil; ! 868: } ! 869: ! 870: /* Record info on buffer window w is displaying ! 871: when it is about to cease to display that buffer. */ ! 872: static void ! 873: unshow_buffer (w) ! 874: register struct window *w; ! 875: { ! 876: register Lisp_Object buf; ! 877: buf = w->buffer; ! 878: ! 879: if (XBUFFER (buf) != XMARKER (w->pointm)->buffer) ! 880: abort (); ! 881: ! 882: if (w == XWINDOW (selected_window) ! 883: || ! EQ (buf, XWINDOW (selected_window)->buffer)) ! 884: /* Do this except when the selected window's buffer ! 885: is being removed from some other window. */ ! 886: XBUFFER (buf)->last_window_start = marker_position (w->start); ! 887: ! 888: /* Point in the selected window's buffer ! 889: is actually stored in that buffer, and the window's pointm isn't used. ! 890: So don't clobber point in that buffer. */ ! 891: if (! EQ (buf, XWINDOW (selected_window)->buffer)) ! 892: BUF_PT (XBUFFER (buf)) ! 893: = clip_to_bounds (BUF_BEGV (XBUFFER (buf)), ! 894: marker_position (w->pointm), ! 895: BUF_ZV (XBUFFER (buf))); ! 896: } ! 897: ! 898: DEFUN ("select-window", Fselect_window, Sselect_window, 1, 1, 0, ! 899: "Select WINDOW. Most editing will apply to WINDOW's buffer.\n\ ! 900: That buffer is made current right away.\n\n\ ! 901: The main editor command loop, before each command,\n\ ! 902: selects the buffer of the selected window.") ! 903: (window) ! 904: register Lisp_Object window; ! 905: { ! 906: register struct window *w; ! 907: register struct window *ow = XWINDOW (selected_window); ! 908: ! 909: CHECK_WINDOW (window, 0); ! 910: ! 911: w = XWINDOW (window); ! 912: ! 913: if (NULL (w->buffer)) ! 914: error ("Trying to select window with no buffer"); ! 915: ! 916: XFASTINT (w->use_time) = ++window_select_count; ! 917: if (EQ (window, selected_window)) ! 918: return window; ! 919: ! 920: Fset_marker (ow->pointm, make_number (BUF_PT (XBUFFER (ow->buffer))), ! 921: ow->buffer); ! 922: ! 923: selected_window = window; ! 924: ! 925: record_buffer (w->buffer); ! 926: Fset_buffer (w->buffer); ! 927: ! 928: /* Go to the point recorded in the window. ! 929: This is important when the buffer is in more ! 930: than one window. It also matters when ! 931: redisplay_window has altered point after scrolling, ! 932: because it makes the change only in the window. */ ! 933: SET_PT (marker_position (w->pointm)); ! 934: if (point < BEGV) ! 935: point = BEGV; ! 936: if (point > ZV) ! 937: point = ZV; ! 938: ! 939: windows_or_buffers_changed++; ! 940: ! 941: return window; ! 942: } ! 943: ! 944: DEFUN ("display-buffer", Fdisplay_buffer, Sdisplay_buffer, 1, 2, 0, ! 945: "Make BUFFER appear in some window but don't select it.\n\ ! 946: BUFFER can be a buffer or a buffer name.\n\ ! 947: If BUFFER is shown already in some window, just uses that one,\n\ ! 948: unless the window is the selected window and NOTTHISWINDOW is non-nil.\n\ ! 949: Returns the window displaying BUFFER.") ! 950: (buffer, notthiswindow) ! 951: register Lisp_Object buffer, notthiswindow; ! 952: { ! 953: register Lisp_Object window; ! 954: ! 955: buffer = Fget_buffer (buffer); ! 956: CHECK_BUFFER (buffer, 0); ! 957: ! 958: if (NULL (notthiswindow) ! 959: && XBUFFER (XWINDOW (selected_window)->buffer) == XBUFFER (buffer)) ! 960: return selected_window; ! 961: ! 962: window = Fget_buffer_window (buffer); ! 963: if (!NULL (window) ! 964: && (NULL (notthiswindow) || !EQ (window, selected_window))) ! 965: return window; ! 966: ! 967: if (pop_up_windows) ! 968: { ! 969: /* Don't try to create a window if would get an error */ ! 970: if (window_min_height < 2) ! 971: window_min_height = 2; ! 972: if (split_height_threshold < window_min_height << 1) ! 973: split_height_threshold = window_min_height << 1; ! 974: ! 975: window = Fget_largest_window (); ! 976: if (window_height (window) >= split_height_threshold ! 977: && ! 978: XFASTINT (XWINDOW (window)->width) == screen_width) ! 979: window = Fsplit_window (window, Qnil, Qnil); ! 980: else ! 981: { ! 982: window = Fget_lru_window (); ! 983: if ((EQ (window, selected_window) ! 984: || (EQ (selected_window, minibuf_window) ! 985: && EQ (window, XWINDOW (minibuf_window)->prev))) ! 986: && window_height (window) >= window_min_height << 1) ! 987: window = Fsplit_window (window, Qnil, Qnil); ! 988: } ! 989: } ! 990: else ! 991: window = Fget_lru_window (); ! 992: ! 993: Fset_window_buffer (window, buffer); ! 994: return window; ! 995: } ! 996: ! 997: temp_output_buffer_show (buf) ! 998: register Lisp_Object buf; ! 999: { ! 1000: register struct buffer *old = current_buffer; ! 1001: register Lisp_Object window; ! 1002: register struct window *w; ! 1003: ! 1004: Fset_buffer (buf); ! 1005: XBUFFER (buf)->save_modified = MODIFF; ! 1006: BEGV = BEG; ! 1007: ZV = Z; ! 1008: SET_PT (BEG); ! 1009: clip_changed = 1; ! 1010: set_buffer_internal (old); ! 1011: ! 1012: if (!EQ (Vtemp_buffer_show_hook, Qnil)) ! 1013: call1 (Vtemp_buffer_show_hook, buf); ! 1014: else ! 1015: { ! 1016: window = Fdisplay_buffer (buf, Qnil); ! 1017: Vminibuf_scroll_window = window; ! 1018: w = XWINDOW (window); ! 1019: XFASTINT (w->hscroll) = 0; ! 1020: set_marker_restricted (w->start, make_number (1), buf); ! 1021: set_marker_restricted (w->pointm, make_number (1), buf); ! 1022: } ! 1023: } ! 1024: ! 1025: static ! 1026: make_dummy_parent (window) ! 1027: Lisp_Object window; ! 1028: { ! 1029: register Lisp_Object old, new; ! 1030: register struct window *o, *p; ! 1031: ! 1032: old = window; ! 1033: XSETTYPE (old, Lisp_Vector); ! 1034: new = Fcopy_sequence (old); ! 1035: XSETTYPE (new, Lisp_Window); ! 1036: ! 1037: o = XWINDOW (old); ! 1038: p = XWINDOW (new); ! 1039: XFASTINT (p->sequence_number) = ++sequence_number; ! 1040: ! 1041: /* Put new into window structure in place of window */ ! 1042: replace_window (window, new); ! 1043: ! 1044: o->next = Qnil; ! 1045: o->prev = Qnil; ! 1046: o->vchild = Qnil; ! 1047: o->hchild = Qnil; ! 1048: o->parent = new; ! 1049: ! 1050: p->start = Qnil; ! 1051: p->pointm = Qnil; ! 1052: p->buffer = Qnil; ! 1053: } ! 1054: ! 1055: DEFUN ("split-window", Fsplit_window, Ssplit_window, 0, 3, "", ! 1056: "Split WINDOW, putting SIZE lines in the first of the pair.\n\ ! 1057: WINDOW defaults to selected one and SIZE to half its size.\n\ ! 1058: If optional third arg HOR-FLAG is non-nil, split side by side\n\ ! 1059: and put SIZE columns in the first of the pair.") ! 1060: (window, chsize, horflag) ! 1061: Lisp_Object window, chsize, horflag; ! 1062: { ! 1063: register Lisp_Object new; ! 1064: register struct window *o, *p; ! 1065: register int size; ! 1066: ! 1067: if (NULL (window)) ! 1068: window = selected_window; ! 1069: else ! 1070: CHECK_WINDOW (window, 0); ! 1071: ! 1072: o = XWINDOW (window); ! 1073: ! 1074: if (NULL (chsize)) ! 1075: { ! 1076: if (!NULL (horflag)) ! 1077: /* Add 1 so we round up rather than down. ! 1078: This puts an excess column into the left-hand window, ! 1079: which is the one that certainly contains a border line. */ ! 1080: size = (1 + XFASTINT (o->width)) >> 1; ! 1081: else ! 1082: size = XFASTINT (o->height) >> 1; ! 1083: } ! 1084: else ! 1085: { ! 1086: CHECK_NUMBER (chsize, 1); ! 1087: size = XINT (chsize); ! 1088: } ! 1089: ! 1090: if (EQ (window, minibuf_window)) ! 1091: error ("Attempt to split minibuffer window"); ! 1092: ! 1093: if (NULL (horflag)) ! 1094: { ! 1095: if (window_min_height < 2) ! 1096: window_min_height = 2; ! 1097: ! 1098: if (size < window_min_height || ! 1099: size + window_min_height > XFASTINT (o->height)) ! 1100: args_out_of_range_3 (window, chsize, horflag); ! 1101: if (NULL (o->parent) || ! 1102: NULL (XWINDOW (o->parent)->vchild)) ! 1103: { ! 1104: make_dummy_parent (window); ! 1105: new = o->parent; ! 1106: XWINDOW (new)->vchild = window; ! 1107: } ! 1108: } ! 1109: else ! 1110: { ! 1111: if (size < window_min_width || ! 1112: size + window_min_width > XFASTINT (o->width)) ! 1113: args_out_of_range_3 (window, chsize, horflag); ! 1114: if (NULL (o->parent) || ! 1115: NULL (XWINDOW (o->parent)->hchild)) ! 1116: { ! 1117: make_dummy_parent (window); ! 1118: new = o->parent; ! 1119: XWINDOW (new)->hchild = window; ! 1120: } ! 1121: } ! 1122: ! 1123: /* Now we know that window's parent is a vertical combination ! 1124: if we are dividing vertically, or a horizontal combination ! 1125: if we are making side-by-side windows */ ! 1126: ! 1127: windows_or_buffers_changed++; ! 1128: new = make_window (); ! 1129: p = XWINDOW (new); ! 1130: ! 1131: p->next = o->next; ! 1132: if (!NULL (p->next)) ! 1133: XWINDOW (p->next)->prev = new; ! 1134: p->prev = window; ! 1135: o->next = new; ! 1136: p->parent = o->parent; ! 1137: ! 1138: Fset_window_buffer (new, o->buffer); ! 1139: ! 1140: /* Apportion the available screen space among the two new windows */ ! 1141: ! 1142: if (!NULL (horflag)) ! 1143: { ! 1144: p->height = o->height; ! 1145: p->top = o->top; ! 1146: XFASTINT (p->width) = XFASTINT (o->width) - size; ! 1147: XFASTINT (o->width) = size; ! 1148: XFASTINT (p->left) = XFASTINT (o->left) + size; ! 1149: } ! 1150: else ! 1151: { ! 1152: p->left = o->left; ! 1153: p->width = o->width; ! 1154: XFASTINT (p->height) = XFASTINT (o->height) - size; ! 1155: XFASTINT (o->height) = size; ! 1156: XFASTINT (p->top) = XFASTINT (o->top) + size; ! 1157: } ! 1158: ! 1159: return new; ! 1160: } ! 1161: ! 1162: DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p", ! 1163: "Make current window ARG lines bigger.\n\ ! 1164: From program, optional second arg non-nil means grow sideways ARG columns.") ! 1165: (n, side) ! 1166: register Lisp_Object n, side; ! 1167: { ! 1168: CHECK_NUMBER (n, 0); ! 1169: change_window_height (XINT (n), !NULL (side)); ! 1170: return Qnil; ! 1171: } ! 1172: ! 1173: DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p", ! 1174: "Make current window ARG lines smaller.\n\ ! 1175: From program, optional second arg non-nil means shrink sideways ARG columns.") ! 1176: (n, side) ! 1177: register Lisp_Object n, side; ! 1178: { ! 1179: CHECK_NUMBER (n, 0); ! 1180: change_window_height (-XINT (n), !NULL (side)); ! 1181: return Qnil; ! 1182: } ! 1183: ! 1184: int ! 1185: window_height (window) ! 1186: Lisp_Object window; ! 1187: { ! 1188: register struct window *p = XWINDOW (window); ! 1189: return XFASTINT (p->height); ! 1190: } ! 1191: ! 1192: int ! 1193: window_width (window) ! 1194: Lisp_Object window; ! 1195: { ! 1196: register struct window *p = XWINDOW (window); ! 1197: return XFASTINT (p->width); ! 1198: } ! 1199: ! 1200: #define MINSIZE(window) \ ! 1201: (widthflag ? window_min_width \ ! 1202: : (EQ (window, minibuf_window) ? 1 : window_min_height)) ! 1203: ! 1204: #define CURBEG(w) \ ! 1205: *(widthflag ? (int *) &w->left : (int *) &w->top) ! 1206: ! 1207: #define CURSIZE(w) \ ! 1208: *(widthflag ? (int *) &w->width : (int *) &w->height) ! 1209: ! 1210: /* Unlike set_window_height, this function ! 1211: also changes the heights of the siblings so as to ! 1212: keep everything consistent. */ ! 1213: ! 1214: change_window_height (delta, widthflag) ! 1215: register int delta; ! 1216: int widthflag; ! 1217: { ! 1218: register Lisp_Object parent; ! 1219: Lisp_Object window; ! 1220: register struct window *p; ! 1221: int *sizep; ! 1222: int (*sizefun) () = widthflag ? window_width : window_height; ! 1223: register int (*setsizefun) () = widthflag ? set_window_width : set_window_height; ! 1224: ! 1225: if (window_min_height < 2) ! 1226: window_min_height = 2; ! 1227: ! 1228: window = selected_window; ! 1229: while (1) ! 1230: { ! 1231: p = XWINDOW (window); ! 1232: parent = p->parent; ! 1233: if (NULL (parent)) ! 1234: { ! 1235: if (widthflag) ! 1236: error ("No other window to side of this one"); ! 1237: break; ! 1238: } ! 1239: if (widthflag ? !NULL (XWINDOW (parent)->hchild) ! 1240: : !NULL (XWINDOW (parent)->vchild)) ! 1241: break; ! 1242: window = parent; ! 1243: } ! 1244: ! 1245: sizep = &CURSIZE (p); ! 1246: ! 1247: if (*sizep + delta < MINSIZE (window)) ! 1248: { ! 1249: Fdelete_window (window); ! 1250: return; ! 1251: } ! 1252: ! 1253: { ! 1254: register int maxdelta; ! 1255: register Lisp_Object tem; ! 1256: ! 1257: maxdelta = (!NULL (parent) ? (*sizefun) (parent) - *sizep ! 1258: : (tem = (!NULL (p->next) ? p->next : p->prev), ! 1259: (*sizefun) (tem) - MINSIZE (tem))); ! 1260: ! 1261: if (delta > maxdelta) ! 1262: /* This case traps trying to make the minibuffer ! 1263: the full screen, or make the only window aside from the ! 1264: minibuffer the full screen. */ ! 1265: delta = maxdelta; ! 1266: } ! 1267: ! 1268: if (!NULL (p->next) && ! 1269: (*sizefun) (p->next) - delta >= MINSIZE (p->next)) ! 1270: { ! 1271: (*setsizefun) (p->next, (*sizefun) (p->next) - delta, 0); ! 1272: (*setsizefun) (window, *sizep + delta, 0); ! 1273: CURBEG (XWINDOW (p->next)) += delta; ! 1274: /* This does not change size of p->next, ! 1275: but it propagates the new top edge to its children */ ! 1276: (*setsizefun) (p->next, (*sizefun) (p->next), 0); ! 1277: } ! 1278: else if (!NULL (p->prev) && ! 1279: (*sizefun) (p->prev) - delta >= MINSIZE (p->prev)) ! 1280: { ! 1281: (*setsizefun) (p->prev, (*sizefun) (p->prev) - delta, 0); ! 1282: CURBEG (p) -= delta; ! 1283: (*setsizefun) (window, *sizep + delta, 0); ! 1284: } ! 1285: else ! 1286: { ! 1287: register int delta1; ! 1288: register int opht = (*sizefun) (parent); ! 1289: ! 1290: /* If trying to grow this window to or beyond size of the parent, ! 1291: make delta1 so big that, on shrinking back down, ! 1292: all the siblings end up with less than one line and are deleted. */ ! 1293: if (opht <= *sizep + delta) ! 1294: delta1 = opht * opht * 2; ! 1295: /* Otherwise, make delta1 just right so that if we add delta1 ! 1296: lines to this window and to the parent, and then shrink ! 1297: the parent back to its original size, the new proportional ! 1298: size of this window will increase by delta. */ ! 1299: else ! 1300: delta1 = (delta * opht * 100) / ((opht - *sizep - delta) * 100); ! 1301: ! 1302: /* Add delta1 lines or columns to this window, and to the parent, ! 1303: keeping things consistent while not affecting siblings. */ ! 1304: CURSIZE (XWINDOW (parent)) = opht + delta1; ! 1305: (*setsizefun) (window, *sizep + delta1, 0); ! 1306: ! 1307: /* Squeeze out delta1 lines or columns from our parent, ! 1308: shriking this window and siblings proportionately. ! 1309: This brings parent back to correct size. ! 1310: Delta1 was calculated so this makes this window the desired size, ! 1311: taking it all out of the siblings. */ ! 1312: (*setsizefun) (parent, opht, 0); ! 1313: } ! 1314: ! 1315: XFASTINT (p->last_modified) = 0; ! 1316: } ! 1317: #undef MINSIZE ! 1318: #undef CURBEG ! 1319: #undef CURSIZE ! 1320: ! 1321: ! 1322: /* Scroll window WINDOW (a Lisp object) by N lines. ! 1323: If NOERROR is 0, signal an error if that can't be done. ! 1324: If NOERROR is nonzero, return Qnil if successful ! 1325: and an error name otherwise. */ ! 1326: ! 1327: static Lisp_Object ! 1328: window_scroll (window, n, noerror) ! 1329: Lisp_Object window; ! 1330: int n; ! 1331: int noerror; ! 1332: { ! 1333: register struct window *w = XWINDOW (window); ! 1334: register int opoint = point; ! 1335: register int ht, pos; ! 1336: register Lisp_Object tem; ! 1337: int lose; ! 1338: Lisp_Object bolp; ! 1339: ! 1340: ht = XFASTINT (w->height) - !EQ (window, minibuf_window); ! 1341: ! 1342: XFASTINT (tem) = point; ! 1343: tem = Fpos_visible_in_window_p (tem, window); ! 1344: ! 1345: if (NULL (tem)) ! 1346: { ! 1347: Fvertical_motion (make_number (- ht / 2)); ! 1348: XFASTINT (tem) = point; ! 1349: Fset_marker (w->start, tem, w->buffer); ! 1350: w->force_start = Qt; ! 1351: } ! 1352: ! 1353: SET_PT (marker_position (w->start)); ! 1354: lose = n < 0 && point == BEGV; ! 1355: Fvertical_motion (make_number (n)); ! 1356: pos = point; ! 1357: bolp = Fbolp (); ! 1358: SET_PT (opoint); ! 1359: ! 1360: if (lose) ! 1361: { ! 1362: if (noerror) ! 1363: return Qbeginning_of_buffer; ! 1364: Fsignal (Qbeginning_of_buffer, Qnil); ! 1365: } ! 1366: ! 1367: if (pos < ZV) ! 1368: { ! 1369: set_marker_restricted (w->start, make_number (pos), w->buffer); ! 1370: w->start_at_line_beg = bolp; ! 1371: w->update_mode_line = Qt; ! 1372: XFASTINT (w->last_modified) = 0; ! 1373: if (pos > opoint) ! 1374: SET_PT (pos); ! 1375: if (n < 0) ! 1376: { ! 1377: SET_PT (pos); ! 1378: tem = Fvertical_motion (make_number (ht)); ! 1379: if (point > opoint || XFASTINT (tem) < ht) ! 1380: SET_PT (opoint); ! 1381: else ! 1382: Fvertical_motion (make_number (-1)); ! 1383: } ! 1384: return Qnil; ! 1385: } ! 1386: else ! 1387: { ! 1388: if (!noerror) ! 1389: Fsignal (Qend_of_buffer, Qnil); ! 1390: return Qend_of_buffer; ! 1391: } ! 1392: } ! 1393: ! 1394: scroll_command (n, direction) ! 1395: register Lisp_Object n; ! 1396: int direction; ! 1397: { ! 1398: register int defalt = (window_height (selected_window) - 1 ! 1399: - next_screen_context_lines); ! 1400: ! 1401: if (defalt < 1) ! 1402: defalt = 1; ! 1403: defalt *= direction; ! 1404: ! 1405: if (NULL (n)) ! 1406: window_scroll (selected_window, defalt, 0); ! 1407: else if (EQ (n, Qminus)) ! 1408: window_scroll (selected_window, - defalt, 0); ! 1409: else ! 1410: { ! 1411: n = Fprefix_numeric_value (n); ! 1412: window_scroll (selected_window, XINT (n) * direction, 0); ! 1413: } ! 1414: } ! 1415: ! 1416: DEFUN ("scroll-up", Fscroll_up, Sscroll_up, 0, 1, "P", ! 1417: "Scroll text of current window upward ARG lines; or near full screen if no ARG.\n\ ! 1418: When calling from a program, supply a number as argument or nil.") ! 1419: (n) ! 1420: Lisp_Object n; ! 1421: { ! 1422: scroll_command (n, 1); ! 1423: return Qnil; ! 1424: } ! 1425: ! 1426: DEFUN ("scroll-down", Fscroll_down, Sscroll_down, 0, 1, "P", ! 1427: "Scroll text of current window downward ARG lines; or near full screen if no ARG.\n\ ! 1428: When calling from a program, supply a number as argument or nil.") ! 1429: (n) ! 1430: Lisp_Object n; ! 1431: { ! 1432: scroll_command (n, -1); ! 1433: return Qnil; ! 1434: } ! 1435: ! 1436: DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 1, 1, "P", ! 1437: "Scroll selected window display ARG columns left.\n\ ! 1438: Default for ARG is window width minus 2.") ! 1439: (arg) ! 1440: register Lisp_Object arg; ! 1441: { ! 1442: if (NULL (arg)) ! 1443: XFASTINT (arg) = XFASTINT (XWINDOW (selected_window)->width) - 2; ! 1444: else ! 1445: arg = Fprefix_numeric_value (arg); ! 1446: ! 1447: return Fset_window_hscroll (selected_window, ! 1448: make_number (XINT (XWINDOW (selected_window)->hscroll) ! 1449: + XINT (arg))); ! 1450: } ! 1451: ! 1452: DEFUN ("scroll-right", Fscroll_right, Sscroll_right, 1, 1, "P", ! 1453: "Scroll selected window display ARG columns right.\n\ ! 1454: Default for ARG is window width minus 2.") ! 1455: (arg) ! 1456: register Lisp_Object arg; ! 1457: { ! 1458: if (NULL (arg)) ! 1459: XFASTINT (arg) = XFASTINT (XWINDOW (selected_window)->width) - 2; ! 1460: else ! 1461: arg = Fprefix_numeric_value (arg); ! 1462: ! 1463: return Fset_window_hscroll (selected_window, ! 1464: make_number (XINT (XWINDOW (selected_window)->hscroll) ! 1465: - XINT (arg))); ! 1466: } ! 1467: ! 1468: DEFUN ("scroll-other-window", Fscroll_other_window, Sscroll_other_window, 0, 1, "P", ! 1469: "Scroll text of next window upward ARG lines; or near full screen if no ARG.\n\ ! 1470: The next window is the one below the current one; or the one at the top\n\ ! 1471: if the current one is at the bottom.\n\ ! 1472: When calling from a program, supply a number as argument or nil.") ! 1473: (n) ! 1474: register Lisp_Object n; ! 1475: { ! 1476: register Lisp_Object window; ! 1477: struct buffer *old = current_buffer; ! 1478: register int ht; ! 1479: register int opoint = point; ! 1480: register struct window *w; ! 1481: Lisp_Object result; ! 1482: ! 1483: if (EQ (selected_window, minibuf_window) ! 1484: && !NULL (Vminibuf_scroll_window)) ! 1485: window = Vminibuf_scroll_window; ! 1486: else ! 1487: window = Fnext_window (selected_window, Qnil); ! 1488: CHECK_WINDOW (window, 0); ! 1489: ht = window_height (window) - 1; ! 1490: ! 1491: if (EQ (window, selected_window)) ! 1492: error ("There is no other window"); ! 1493: ! 1494: w = XWINDOW (window); ! 1495: Fset_buffer (w->buffer); ! 1496: SET_PT (marker_position (w->pointm)); ! 1497: ! 1498: if (NULL (n)) ! 1499: result = window_scroll (window, ht - next_screen_context_lines, 1); ! 1500: else if (EQ (n, Qminus)) ! 1501: result = window_scroll (window, next_screen_context_lines - ht, 1); ! 1502: else ! 1503: { ! 1504: if (XTYPE (n) == Lisp_Cons) ! 1505: n = Fcar (n); ! 1506: CHECK_NUMBER (n, 0); ! 1507: result = window_scroll (window, XINT (n), 1); ! 1508: } ! 1509: ! 1510: Fset_marker (w->pointm, make_number (point), Qnil); ! 1511: set_buffer_internal (old); ! 1512: SET_PT (opoint); ! 1513: if (!EQ (result, Qnil)) ! 1514: Fsignal (result, Qnil); ! 1515: return Qnil; ! 1516: } ! 1517: ! 1518: DEFUN ("recenter", Frecenter, Srecenter, 0, 1, "P", ! 1519: "Center point in window and redisplay screen. With ARG, put point on line ARG.\n\ ! 1520: The desired position of point is always relative to the current window.\n\ ! 1521: Just C-u as prefix means put point in the center of the screen.\n\ ! 1522: No arg (i.e., it is nil) erases the entire screen and then\n\ ! 1523: redraws with point in the center.") ! 1524: (n) ! 1525: register Lisp_Object n; ! 1526: { ! 1527: register int ht = window_height (selected_window) ! 1528: - !EQ (selected_window, minibuf_window); ! 1529: register struct window *w = XWINDOW (selected_window); ! 1530: register int opoint = point; ! 1531: ! 1532: if (NULL (n)) ! 1533: { ! 1534: extern int screen_garbaged; ! 1535: screen_garbaged++; ! 1536: XFASTINT (n) = ht / 2; ! 1537: } ! 1538: else if (XTYPE (n) == Lisp_Cons) /* Just C-u. */ ! 1539: { ! 1540: XFASTINT (n) = ht / 2; ! 1541: } ! 1542: else ! 1543: { ! 1544: n = Fprefix_numeric_value (n); ! 1545: CHECK_NUMBER (n, 0); ! 1546: } ! 1547: ! 1548: if (XINT (n) < 0) ! 1549: XSETINT (n, XINT (n) + ht); ! 1550: ! 1551: XSETINT (n, - XINT (n)); ! 1552: ! 1553: Fvertical_motion (n); ! 1554: Fset_marker (w->start, make_number (point), w->buffer); ! 1555: w->start_at_line_beg = Fbolp (); ! 1556: ! 1557: SET_PT (opoint); ! 1558: w->force_start = Qt; ! 1559: ! 1560: return Qnil; ! 1561: } ! 1562: ! 1563: DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line, ! 1564: 1, 1, "P", ! 1565: "Position point relative to window.\n\ ! 1566: With no argument, position at text at center of window.\n\ ! 1567: An argument specifies screen line; zero means top of window,\n\ ! 1568: negative means relative to bottom of window.") ! 1569: (arg) ! 1570: register Lisp_Object arg; ! 1571: { ! 1572: register struct window *w = XWINDOW (selected_window); ! 1573: register int height = XFASTINT (w->height); ! 1574: register int start; ! 1575: ! 1576: if (!EQ (selected_window, minibuf_window)) height--; ! 1577: ! 1578: if (NULL (arg)) ! 1579: XFASTINT (arg) = height / 2; ! 1580: else ! 1581: { ! 1582: arg = Fprefix_numeric_value (arg); ! 1583: if (XINT (arg) < 0) ! 1584: XSETINT (arg, XINT (arg) + height); ! 1585: } ! 1586: ! 1587: start = marker_position (w->start); ! 1588: if (start < BEGV || start > ZV) ! 1589: { ! 1590: Fvertical_motion (make_number (- height / 2)); ! 1591: Fset_marker (w->start, make_number (point), w->buffer); ! 1592: w->start_at_line_beg = Fbolp (); ! 1593: w->force_start = Qt; ! 1594: } ! 1595: else ! 1596: SET_PT (start); ! 1597: ! 1598: return Fvertical_motion (arg); ! 1599: } ! 1600: ! 1601: struct save_window_data ! 1602: { ! 1603: int size_from_Lisp_Vector_struct; ! 1604: struct Lisp_Vector *next_from_Lisp_Vector_struct; ! 1605: Lisp_Object screen_width, screen_height; ! 1606: Lisp_Object current_window; ! 1607: Lisp_Object current_buffer; ! 1608: Lisp_Object minibuf_scroll_window; ! 1609: /* A vector, interpreted as a struct saved_window */ ! 1610: Lisp_Object saved_windows; ! 1611: }; ! 1612: #define SAVE_WINDOW_DATA_SIZE 6 /* Arg to Fmake_vector */ ! 1613: ! 1614: /* This is saved as a Lisp_Vector */ ! 1615: struct saved_window ! 1616: { ! 1617: /* these first two must agree with struct Lisp_Vector in lisp.h */ ! 1618: int size_from_Lisp_Vector_struct; ! 1619: struct Lisp_Vector *next_from_Lisp_Vector_struct; ! 1620: ! 1621: Lisp_Object window; ! 1622: Lisp_Object buffer, start, pointm, mark; ! 1623: Lisp_Object left, top, width, height, hscroll; ! 1624: Lisp_Object parent, prev; ! 1625: Lisp_Object start_at_line_beg; ! 1626: }; ! 1627: #define SAVED_WINDOW_VECTOR_SIZE 13 /* Arg to Fmake_vector */ ! 1628: ! 1629: #define SAVED_WINDOW_N(swv,n) \ ! 1630: ((struct saved_window *) (XVECTOR ((swv)->contents[(n)]))) ! 1631: ! 1632: DEFUN ("set-window-configuration", ! 1633: Fset_window_configuration, Sset_window_configuration, ! 1634: 1, 1, 0, ! 1635: "Restore the configuration of Emacs' windows and buffers to\n\ ! 1636: the state specified by CONFIGURATION. CONFIGURATION must be a value\n\ ! 1637: retrned by current-window-configuration -- see the documentation of that\n\ ! 1638: function for more information.") ! 1639: (arg) ! 1640: Lisp_Object arg; ! 1641: { ! 1642: register struct window *w; ! 1643: register struct save_window_data *data; ! 1644: struct Lisp_Vector *saved_windows; ! 1645: register struct saved_window *p; ! 1646: register Lisp_Object tem; ! 1647: Lisp_Object new_current_buffer; ! 1648: int k; ! 1649: ! 1650: /* Save screen height here so we can go back to it at the end. */ ! 1651: int previous_screen_height = screen_height; ! 1652: int previous_screen_width = screen_width; ! 1653: int screen_size_change = 0; ! 1654: ! 1655: while (XTYPE (arg) != Lisp_Window_Configuration) ! 1656: { ! 1657: /* the function window-configuration-p isn't actually defined ! 1658: at present --- is there a need for it? */ ! 1659: arg = wrong_type_argument (intern ("window-configuration-p"), arg); ! 1660: } ! 1661: ! 1662: data = (struct save_window_data *) XVECTOR (arg); ! 1663: saved_windows = XVECTOR (data->saved_windows); ! 1664: ! 1665: /* Set the screen height to the value it had at save time. */ ! 1666: if (XFASTINT (data->screen_height) != screen_height ! 1667: || XFASTINT (data->screen_width) != screen_width) ! 1668: { ! 1669: change_screen_size (data->screen_height, data->screen_width, 0, 0, 0); ! 1670: screen_size_change = 1; ! 1671: } ! 1672: ! 1673: windows_or_buffers_changed++; ! 1674: new_current_buffer = data->current_buffer; ! 1675: if (NULL (XBUFFER (new_current_buffer)->name)) ! 1676: new_current_buffer = Qnil; ! 1677: ! 1678: for (k = 0; k < saved_windows->size; k++) ! 1679: { ! 1680: p = SAVED_WINDOW_N (saved_windows, k); ! 1681: w = XWINDOW (p->window); ! 1682: w->next = Qnil; ! 1683: ! 1684: if (!NULL (p->parent)) ! 1685: w->parent = SAVED_WINDOW_N (saved_windows, XFASTINT (p->parent))->window; ! 1686: else ! 1687: w->parent = Qnil; ! 1688: ! 1689: if (!NULL (p->prev)) ! 1690: { ! 1691: w->prev = SAVED_WINDOW_N (saved_windows, XFASTINT (p->prev))->window; ! 1692: XWINDOW (w->prev)->next = p->window; ! 1693: } ! 1694: else ! 1695: { ! 1696: w->prev = Qnil; ! 1697: if (!NULL (w->parent)) ! 1698: { ! 1699: if (EQ (p->width, XWINDOW (w->parent)->width)) ! 1700: { ! 1701: XWINDOW (w->parent)->vchild = p->window; ! 1702: XWINDOW (w->parent)->hchild = Qnil; ! 1703: } ! 1704: else ! 1705: { ! 1706: XWINDOW (w->parent)->hchild = p->window; ! 1707: XWINDOW (w->parent)->vchild = Qnil; ! 1708: } ! 1709: } ! 1710: } ! 1711: w->left = p->left; ! 1712: w->top = p->top; ! 1713: w->width = p->width; ! 1714: w->height = p->height; ! 1715: w->hscroll = p->hscroll; ! 1716: XFASTINT (w->last_modified) = 0; ! 1717: ! 1718: /* Reinstall the saved buffer and pointers into it. */ ! 1719: if (NULL (p->buffer)) ! 1720: w->buffer = p->buffer; ! 1721: else ! 1722: { ! 1723: if (!NULL (XBUFFER (p->buffer)->name)) ! 1724: /* If saved buffer is alive, install it. */ ! 1725: { ! 1726: w->buffer = p->buffer; ! 1727: w->start_at_line_beg = p->start_at_line_beg; ! 1728: set_marker_restricted (w->start, ! 1729: Fmarker_position (p->start), w->buffer); ! 1730: set_marker_restricted (w->pointm, ! 1731: Fmarker_position (p->pointm), w->buffer); ! 1732: Fset_marker (XBUFFER (w->buffer)->mark, ! 1733: Fmarker_position (p->mark), w->buffer); ! 1734: ! 1735: if (!EQ (p->buffer, new_current_buffer) && ! 1736: XBUFFER (p->buffer) == current_buffer) ! 1737: Fgoto_char (w->pointm); ! 1738: } ! 1739: else if (NULL (XBUFFER (w->buffer)->name)) ! 1740: /* Else if window's old buffer is dead too, get a live one. */ ! 1741: { ! 1742: w->buffer = Fcdr (Fcar (Vbuffer_alist)); ! 1743: /* Set window markers at start of buffer. ! 1744: Rely on set_marker_restricted to put them ! 1745: within the restriction. */ ! 1746: set_marker_restricted (w->start, make_number (0), w->buffer); ! 1747: set_marker_restricted (w->pointm, make_number (0), w->buffer); ! 1748: w->start_at_line_beg = Qt; ! 1749: } ! 1750: else ! 1751: /* Keeping window's old buffer; make sure the markers are real. */ ! 1752: /* Else if window's old buffer is dead too, get a live one. */ ! 1753: { ! 1754: /* Set window markers at start of buffer. ! 1755: Rely on set_marker_restricted to put them within the restriction. */ ! 1756: if (XMARKER (w->start)->buffer == 0) ! 1757: set_marker_restricted (w->start, make_number (0), w->buffer); ! 1758: if (XMARKER (w->pointm)->buffer == 0) ! 1759: set_marker_restricted (w->pointm, ! 1760: make_number (BUF_PT (XBUFFER (w->buffer))), ! 1761: w->buffer); ! 1762: w->start_at_line_beg = Qt; ! 1763: } ! 1764: } ! 1765: } ! 1766: ! 1767: /* Set the screen height to the value it had before this function. */ ! 1768: if (screen_size_change) ! 1769: change_screen_size (previous_screen_height, previous_screen_width, 0, 0, 0); ! 1770: ! 1771: Fselect_window (data->current_window); ! 1772: if (!NULL (new_current_buffer)) ! 1773: Fset_buffer (new_current_buffer); ! 1774: else ! 1775: Fset_buffer (XWINDOW (selected_window)->buffer); ! 1776: Vminibuf_scroll_window = data->minibuf_scroll_window; ! 1777: return (Qnil); ! 1778: } ! 1779: ! 1780: ! 1781: static int ! 1782: count_windows (window) ! 1783: register struct window *window; ! 1784: { ! 1785: register int count = 1; ! 1786: if (!NULL (window->next)) ! 1787: count += count_windows (XWINDOW (window->next)); ! 1788: if (!NULL (window->vchild)) ! 1789: count += count_windows (XWINDOW (window->vchild)); ! 1790: if (!NULL (window->hchild)) ! 1791: count += count_windows (XWINDOW (window->hchild)); ! 1792: return count; ! 1793: } ! 1794: ! 1795: DEFUN ("current-window-configuration", ! 1796: Fcurrent_window_configuration, Scurrent_window_configuration, 0, 0, 0, ! 1797: "Return an object representing Emacs' current window configuration,\n\ ! 1798: namely the number of windows, their sizes and current buffers, and for\n\ ! 1799: each displayed buffer, where display starts, and the positions of\n\ ! 1800: point and mark. An exception is made for point in (current-buffer) --\n\ ! 1801: its value is -not- saved.") ! 1802: () ! 1803: { ! 1804: register Lisp_Object tem; ! 1805: register int n_windows; ! 1806: register struct save_window_data *data; ! 1807: register int i; ! 1808: ! 1809: n_windows = count_windows (XWINDOW (XWINDOW (minibuf_window)->prev)); ! 1810: data = (struct save_window_data *) ! 1811: XVECTOR (Fmake_vector (make_number (SAVE_WINDOW_DATA_SIZE), ! 1812: Qnil)); ! 1813: XFASTINT (data->screen_width) = screen_width; ! 1814: XFASTINT (data->screen_height) = screen_height; ! 1815: data->current_window = selected_window; ! 1816: XSET (data->current_buffer, Lisp_Buffer, current_buffer); ! 1817: data->minibuf_scroll_window = Vminibuf_scroll_window; ! 1818: tem = Fmake_vector (make_number (n_windows), Qnil); ! 1819: data->saved_windows = tem; ! 1820: for (i = 0; i < n_windows; i++) ! 1821: XVECTOR (tem)->contents[i] ! 1822: = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE), Qnil); ! 1823: save_window_save (XWINDOW (minibuf_window)->prev, ! 1824: XVECTOR (tem), ! 1825: 0, n_windows); ! 1826: XSET (tem, Lisp_Window_Configuration, data); ! 1827: return (tem); ! 1828: } ! 1829: ! 1830: static int ! 1831: save_window_save (window, vector, i, maxwindow) ! 1832: Lisp_Object window; ! 1833: struct Lisp_Vector *vector; ! 1834: int i; ! 1835: int maxwindow; ! 1836: { ! 1837: register struct saved_window *p; ! 1838: register struct window *w; ! 1839: register Lisp_Object tem; ! 1840: ! 1841: for (;!NULL (window); window = w->next) ! 1842: { ! 1843: /* If you get a crash here, you may be seeing a very weird bug. ! 1844: When it happened to me, it seems that count_windows returned ! 1845: a value that was too small--only two, when there were two ! 1846: visible windows, a parent, and the minibuffer (inactive). ! 1847: If this starts happening for you, please run under a debugger ! 1848: with a breakpoint at the abort, so that you can at least try calling ! 1849: count_windows again to see if it will lose again. ! 1850: If it does, you can find the bug. */ ! 1851: if (i == maxwindow) ! 1852: abort (); ! 1853: ! 1854: p = SAVED_WINDOW_N (vector, i); ! 1855: w = XWINDOW (window); ! 1856: ! 1857: XFASTINT (w->temslot) = i++; ! 1858: ! 1859: p->window = window; ! 1860: p->buffer = w->buffer; ! 1861: p->left = w->left; ! 1862: p->top = w->top; ! 1863: p->width = w->width; ! 1864: p->height = w->height; ! 1865: p->hscroll = w->hscroll; ! 1866: if (!NULL (w->buffer)) ! 1867: { ! 1868: /* Save w's value of point in the window configuration. ! 1869: If w is the selected window, then get the value of point ! 1870: from the buffer; pointm is garbage in the selected window. */ ! 1871: if (EQ (window, selected_window)) ! 1872: { ! 1873: p->pointm = Fmake_marker (); ! 1874: Fset_marker (p->pointm, BUF_PT (XBUFFER (w->buffer)), ! 1875: w->buffer); ! 1876: } ! 1877: else ! 1878: p->pointm = Fcopy_marker (w->pointm); ! 1879: ! 1880: p->start = Fcopy_marker (w->start); ! 1881: p->start_at_line_beg = w->start_at_line_beg; ! 1882: ! 1883: tem = XBUFFER (w->buffer)->mark; ! 1884: p->mark = Fcopy_marker (tem); ! 1885: } ! 1886: else ! 1887: { ! 1888: p->pointm = Qnil; ! 1889: p->start = Qnil; ! 1890: p->mark = Qnil; ! 1891: p->start_at_line_beg = Qnil; ! 1892: } ! 1893: ! 1894: if (NULL (w->parent)) ! 1895: p->parent = Qnil; ! 1896: else ! 1897: p->parent = XWINDOW (w->parent)->temslot; ! 1898: ! 1899: if (NULL (w->prev)) ! 1900: p->prev = Qnil; ! 1901: else ! 1902: p->prev = XWINDOW (w->prev)->temslot; ! 1903: ! 1904: if (!NULL (w->vchild)) ! 1905: i = save_window_save (w->vchild, vector, i, maxwindow); ! 1906: if (!NULL (w->hchild)) ! 1907: i = save_window_save (w->hchild, vector, i, maxwindow); ! 1908: } ! 1909: ! 1910: return i; ! 1911: } ! 1912: ! 1913: DEFUN ("save-window-excursion", Fsave_window_excursion, Ssave_window_excursion, ! 1914: 0, UNEVALLED, 0, ! 1915: "Execute body, preserving window sizes and contents.\n\ ! 1916: Restores which buffer appears in which window, where display starts,\n\ ! 1917: as well as the current buffer.\n\ ! 1918: Does not restore the value of point in current buffer.") ! 1919: (args) ! 1920: Lisp_Object args; ! 1921: { ! 1922: register Lisp_Object val; ! 1923: register int count = specpdl_ptr - specpdl; ! 1924: ! 1925: record_unwind_protect (Fset_window_configuration, ! 1926: Fcurrent_window_configuration ()); ! 1927: val = Fprogn (args); ! 1928: unbind_to (count); ! 1929: return val; ! 1930: } ! 1931: ! 1932: init_window_once () ! 1933: { ! 1934: extern Lisp_Object get_minibuffer (); ! 1935: register Lisp_Object root_window; ! 1936: ! 1937: root_window = make_window (); ! 1938: minibuf_window = make_window (); ! 1939: ! 1940: XWINDOW (root_window)->next = minibuf_window; ! 1941: XWINDOW (minibuf_window)->prev = root_window; ! 1942: ! 1943: /* These values 9 and 10 are arbitrary, ! 1944: just so that there is "something there." ! 1945: Correct values are put in in init_xdisp */ ! 1946: ! 1947: XFASTINT (XWINDOW (root_window)->width) = 10; ! 1948: XFASTINT (XWINDOW (minibuf_window)->width) = 10; ! 1949: ! 1950: XFASTINT (XWINDOW (root_window)->height) = 9; ! 1951: XFASTINT (XWINDOW (minibuf_window)->top) = 9; ! 1952: XFASTINT (XWINDOW (minibuf_window)->height) = 1; ! 1953: ! 1954: Fset_window_buffer (root_window, Fcurrent_buffer ()); ! 1955: Fset_window_buffer (minibuf_window, get_minibuffer (0)); ! 1956: ! 1957: selected_window = root_window; ! 1958: /* Make sure this window seems more recently used than ! 1959: a newly-created, never-selected window. */ ! 1960: XFASTINT (XWINDOW (selected_window)->use_time) = ++window_select_count; ! 1961: } ! 1962: ! 1963: syms_of_window () ! 1964: { ! 1965: Qwindowp = intern ("windowp"); ! 1966: staticpro (&Qwindowp); ! 1967: ! 1968: /* Make sure all windows get marked */ ! 1969: staticpro (&minibuf_window); ! 1970: ! 1971: DEFVAR_INT ("minibuffer-prompt-width", &minibuf_prompt_width, ! 1972: "Width of the prompt appearing at the start of the minibuffer window.\n\ ! 1973: The value is meaningless when the minibuffer is not visible."); ! 1974: ! 1975: DEFVAR_LISP ("temp-buffer-show-hook", &Vtemp_buffer_show_hook, ! 1976: "Non-nil means call as function to display a help buffer.\n\ ! 1977: Used by with-output-to-temp-buffer."); ! 1978: Vtemp_buffer_show_hook = Qnil; ! 1979: ! 1980: DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window, ! 1981: "Non-nil means it is the window that C-M-v in minibuffer should scroll."); ! 1982: Vminibuf_scroll_window = Qnil; ! 1983: ! 1984: DEFVAR_BOOL ("pop-up-windows", &pop_up_windows, ! 1985: "*Non-nil means display-buffer should make new windows."); ! 1986: pop_up_windows = 1; ! 1987: ! 1988: DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines, ! 1989: "*Number of lines of continuity when scrolling by screenfuls."); ! 1990: next_screen_context_lines = 2; ! 1991: ! 1992: DEFVAR_INT ("split-height-threshold", &split_height_threshold, ! 1993: "*display-buffer would prefer to split the largest window if this large.\n\ ! 1994: If there is only one window, it is split regardless of this value."); ! 1995: split_height_threshold = 500; ! 1996: ! 1997: DEFVAR_INT ("window-min-height", &window_min_height, ! 1998: "*Delete any window less than this tall (including its mode line)."); ! 1999: window_min_height = 4; ! 2000: ! 2001: DEFVAR_INT ("window-min-width", &window_min_width, ! 2002: "*Delete any window less than this wide."); ! 2003: window_min_width = 10; ! 2004: ! 2005: defsubr (&Sselected_window); ! 2006: defsubr (&Sminibuffer_window); ! 2007: defsubr (&Swindowp); ! 2008: defsubr (&Spos_visible_in_window_p); ! 2009: defsubr (&Swindow_buffer); ! 2010: defsubr (&Swindow_height); ! 2011: defsubr (&Swindow_width); ! 2012: defsubr (&Swindow_hscroll); ! 2013: defsubr (&Sset_window_hscroll); ! 2014: defsubr (&Swindow_edges); ! 2015: defsubr (&Swindow_point); ! 2016: defsubr (&Swindow_start); ! 2017: defsubr (&Sset_window_point); ! 2018: defsubr (&Sset_window_start); ! 2019: defsubr (&Snext_window); ! 2020: defsubr (&Sprevious_window); ! 2021: defsubr (&Sother_window); ! 2022: defsubr (&Sget_lru_window); ! 2023: defsubr (&Sget_largest_window); ! 2024: defsubr (&Sget_buffer_window); ! 2025: defsubr (&Sdelete_other_windows); ! 2026: defsubr (&Sdelete_windows_on); ! 2027: defsubr (&Sreplace_buffer_in_windows); ! 2028: defsubr (&Sdelete_window); ! 2029: defsubr (&Sset_window_buffer); ! 2030: defsubr (&Sselect_window); ! 2031: defsubr (&Sdisplay_buffer); ! 2032: defsubr (&Ssplit_window); ! 2033: defsubr (&Senlarge_window); ! 2034: defsubr (&Sshrink_window); ! 2035: defsubr (&Sscroll_up); ! 2036: defsubr (&Sscroll_down); ! 2037: defsubr (&Sscroll_left); ! 2038: defsubr (&Sscroll_right); ! 2039: defsubr (&Sscroll_other_window); ! 2040: defsubr (&Srecenter); ! 2041: defsubr (&Smove_to_window_line); ! 2042: defsubr (&Sset_window_configuration); ! 2043: defsubr (&Scurrent_window_configuration); ! 2044: defsubr (&Ssave_window_excursion); ! 2045: } ! 2046: ! 2047: keys_of_window () ! 2048: { ! 2049: ndefkey (Vctl_x_map, '1', "delete-other-windows"); ! 2050: ndefkey (Vctl_x_map, '2', "split-window"); ! 2051: ndefkey (Vctl_x_map, '0', "delete-window"); ! 2052: ndefkey (Vctl_x_map, 'o', "other-window"); ! 2053: ndefkey (Vctl_x_map, '^', "enlarge-window"); ! 2054: ndefkey (Vctl_x_map, '<', "scroll-left"); ! 2055: ndefkey (Vctl_x_map, '>', "scroll-right"); ! 2056: ! 2057: ndefkey (Vglobal_map, Ctl ('V'), "scroll-up"); ! 2058: ndefkey (Vesc_map, Ctl ('V'), "scroll-other-window"); ! 2059: ndefkey (Vesc_map, 'v', "scroll-down"); ! 2060: ! 2061: ndefkey (Vglobal_map, Ctl('L'), "recenter"); ! 2062: ndefkey (Vesc_map, 'r', "move-to-window-line"); ! 2063: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.