Annotation of 43BSDReno/contrib/emacs-18.55/src/window.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.