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