Annotation of 43BSDReno/contrib/emacs-18.55/src/window.c, revision 1.1.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.