Back to index

tetex-bin  3.0
Defines | Functions | Variables
window.c File Reference
#include "info.h"
#include "nodes.h"
#include "window.h"
#include "display.h"
#include "info-utils.h"
#include "infomap.h"

Go to the source code of this file.

Defines

#define ECHO_AREA_HEIGHT   1
#define echo_area_required   (1 + the_echo_area->height)
#define grow_me_shrinking_next(me, next, diff)
#define grow_me_shrinking_prev(me, prev, diff)
#define shrink_me_growing_next(me, next, diff)
#define shrink_me_growing_prev(me, prev, diff)

Functions

void window_initialize_windows (int width, int height)
void window_new_screen_size (int width, int height)
WINDOWwindow_make_window (NODE *node)
void window_change_window_height (WINDOW *window, int amount)
void window_tile_windows (int style)
void window_toggle_wrap (WINDOW *window)
void window_set_node_of_window (WINDOW *window, NODE *node)
void window_delete_window (WINDOW *window)
void window_mark_chain (WINDOW *chain, int flag)
void window_unmark_chain (WINDOW *chain, int flag)
int character_width (int character, int hpos)
int string_width (char *string, int hpos)
int window_physical_lines (NODE *node)
void calculate_line_starts (WINDOW *window)
void recalculate_line_starts (WINDOW *window)
void window_adjust_pagetop (WINDOW *window)
int window_line_of_point (WINDOW *window)
int window_get_goal_column (WINDOW *window)
int window_get_cursor_column (WINDOW *window)
int window_chars_to_goal (char *line, int goal)
void window_make_modeline (WINDOW *window)
void window_goto_percentage (WINDOW *window, int percent)
void window_get_state (WINDOW *window, SEARCH_STATE *state)
void window_set_state (WINDOW *window, SEARCH_STATE *state)
static void free_echo_area (void)
void window_clear_echo_area (void)
void window_message_in_echo_area (char *format, void *arg1, void *arg2)
void message_in_echo_area (char *format, void *arg1, void *arg2)
void unmessage_in_echo_area (void)
static void message_buffer_resize (int length)
static void build_message_buffer (char *format, void *arg1, void *arg2, void *arg3)
NODEbuild_message_node (char *format, void *arg1, void *arg2)
NODEmessage_buffer_to_node (void)
void initialize_message_buffer (void)
void printf_to_message_buffer (char *format, void *arg1, void *arg2, void *arg3)
int message_buffer_length_this_line (void)
int pad_to (int count, char *string)

Variables

WINDOWthe_screen = NULL
WINDOWthe_echo_area = NULL
WINDOWwindows = NULL
WINDOWactive_window = NULL
VFunctionwindow_deletion_notifier = NULL
int window_scroll_step = 0
static NODEecho_area_node = NULL
static NODE ** old_echo_area_nodes = NULL
static int old_echo_area_nodes_index = 0
static int old_echo_area_nodes_slots = 0
static char * message_buffer = NULL
static int message_buffer_index = 0
static int message_buffer_size = 0

Define Documentation

#define ECHO_AREA_HEIGHT   1

Definition at line 44 of file window.c.

Definition at line 48 of file window.c.

#define grow_me_shrinking_next (   me,
  next,
  diff 
)
Value:
do { \
    me->height += diff; \
    next->height -= diff; \
    next->first_row += diff; \
    window_adjust_pagetop (next); \
  } while (0)

Definition at line 341 of file window.c.

#define grow_me_shrinking_prev (   me,
  prev,
  diff 
)
Value:
do { \
    me->height += diff; \
    prev->height -= diff; \
    me->first_row -=diff; \
    window_adjust_pagetop (prev); \
  } while (0)

Definition at line 349 of file window.c.

#define shrink_me_growing_next (   me,
  next,
  diff 
)
Value:
do { \
    me->height -= diff; \
    next->height += diff; \
    next->first_row -= diff; \
    window_adjust_pagetop (next); \
  } while (0)

Definition at line 357 of file window.c.

#define shrink_me_growing_prev (   me,
  prev,
  diff 
)
Value:
do { \
    me->height -= diff; \
    prev->height += diff; \
    me->first_row += diff; \
    window_adjust_pagetop (prev); \
  } while (0)

Definition at line 365 of file window.c.


Function Documentation

static void build_message_buffer ( char *  format,
void arg1,
void arg2,
void arg3 
) [static]

Definition at line 1327 of file window.c.

{
  register int i, len;
  void *args[3];
  int arg_index = 0;

  args[0] = arg1;
  args[1] = arg2;
  args[2] = arg3;

  len = strlen (format);

  message_buffer_resize (len);

  for (i = 0; format[i]; i++)
    {
      if (format[i] != '%')
        {
          message_buffer[message_buffer_index++] = format[i];
          len--;
        }
      else
        {
          char c;
          char *fmt_start = format + i;
          char *fmt;
          int fmt_len, formatted_len;
         int paramed = 0;

       format_again:
          i++;
          while (format[i] && strchr ("-. +0123456789", format[i]))
            i++;
          c = format[i];

          if (c == '\0')
            abort ();

         if (c == '$') {
           /* position parameter parameter */
           /* better to use bprintf from bfox's metahtml? */
           arg_index = atoi(fmt_start + 1) - 1;
           if (arg_index < 0)
             arg_index = 0;
           if (arg_index >= 2)
             arg_index = 1;
           paramed = 1;
           goto format_again;
         }

          fmt_len = format + i - fmt_start + 1;
          fmt = (char *) xmalloc (fmt_len + 1);
          strncpy (fmt, fmt_start, fmt_len);
          fmt[fmt_len] = '\0';

         if (paramed) {
           /* removed positioned parameter */
           char *p;
           for (p = fmt + 1; *p && *p != '$'; p++) {
             ;
           }
           strcpy(fmt + 1, p + 1);
         }

          /* If we have "%-98s", maybe 98 calls for a longer string.  */
          if (fmt_len > 2)
            {
              int j;

              for (j = fmt_len - 2; j >= 0; j--)
                if (isdigit (fmt[j]) || fmt[j] == '$')
                  break;

              formatted_len = atoi (fmt + j);
            }
          else
            formatted_len = c == 's' ? 0 : 1; /* %s can produce empty string */

          switch (c)
            {
            case '%':           /* Insert a percent sign. */
              message_buffer_resize (len + formatted_len);
              sprintf
                (message_buffer + message_buffer_index, fmt, "%");
              message_buffer_index += formatted_len;
              break;

            case 's':           /* Insert the current arg as a string. */
              {
                char *string;
                int string_len;

                string = (char *)args[arg_index++];
                string_len = strlen (string);

                if (formatted_len > string_len)
                  string_len = formatted_len;
                message_buffer_resize (len + string_len);
                sprintf
                  (message_buffer + message_buffer_index, fmt, string);
                message_buffer_index += string_len;
              }
              break;

            case 'd':           /* Insert the current arg as an integer. */
              {
                long long_val;
                int integer;

                long_val = (long)args[arg_index++];
                integer = (int)long_val;

                message_buffer_resize (len + formatted_len > 32
                                       ? formatted_len : 32);
                sprintf
                  (message_buffer + message_buffer_index, fmt, integer);
                message_buffer_index = strlen (message_buffer);
              }
              break;

            case 'c':           /* Insert the current arg as a character. */
              {
                long long_val;
                int character;

                long_val = (long)args[arg_index++];
                character = (int)long_val;

                message_buffer_resize (len + formatted_len);
                sprintf
                  (message_buffer + message_buffer_index, fmt, character);
                message_buffer_index += formatted_len;
              }
              break;

            default:
              abort ();
            }
          free (fmt);
        }
    }
  message_buffer[message_buffer_index] = '\0';
}

Here is the call graph for this function:

Here is the caller graph for this function:

NODE* build_message_node ( char *  format,
void arg1,
void arg2 
)

Definition at line 1474 of file window.c.

{
  NODE *node;

  message_buffer_index = 0;
  build_message_buffer (format, arg1, arg2, 0);

  node = message_buffer_to_node ();
  return (node);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 787 of file window.c.

{
  register int i, hpos;
  char **line_starts = NULL;
  int line_starts_index = 0, line_starts_slots = 0;
  int bump_index;
  NODE *node;

  window->line_starts = NULL;
  window->line_count = 0;
  node = window->node;

  if (!node)
    return;

  /* Grovel the node starting at the top, and for each line calculate the
     width of the characters appearing in that line.  Add each line start
     to our array. */
  i = 0;
  hpos = 0;
  bump_index = 0;

  while (i < node->nodelen)
    {
      char *line = node->contents + i;
      unsigned int cwidth, c;

      add_pointer_to_array (line, line_starts_index, line_starts,
                            line_starts_slots, 100, char *);
      if (bump_index)
        {
          i++;
          bump_index = 0;
        }

      while (1)
        {
         /* The cast to unsigned char is for 8-bit characters, which
            could be passed as negative integers to character_width
            and wreak havoc on some naive implementations of iscntrl.  */
          c = (unsigned char) node->contents[i];

         /* Support ANSI escape sequences for -R.  */
         if (raw_escapes_p
             && c == '\033'
             && node->contents[i+1] == '['
             && isdigit (node->contents[i+2]))
           {
             if (node->contents[i+3] == 'm')
              {
                i += 3;
                cwidth = 0;
              }
             else if (isdigit (node->contents[i+3])
                     && node->contents[i+4] == 'm')
              {
                i += 4;
                cwidth = 0;
              }
             else
              cwidth = character_width (c, hpos);
           }
         else
           cwidth = character_width (c, hpos);

          /* If this character fits within this line, just do the next one. */
          if ((hpos + cwidth) < (unsigned int) window->width)
            {
              i++;
              hpos += cwidth;
              continue;
            }
          else
            {
              /* If this character would position the cursor at the start of
                 the next printed screen line, then do the next line. */
              if (c == '\n' || c == '\r' || c == '\t')
                {
                  i++;
                  hpos = 0;
                  break;
                }
              else
                {
                  /* This character passes the window width border.  Postion
                     the cursor after the printed character, but remember this
                     line start as where this character is.  A bit tricky. */

                  /* If this window doesn't wrap lines, proceed to the next
                     physical line here. */
                  if (window->flags & W_NoWrap)
                    {
                      hpos = 0;
                      while (i < node->nodelen && node->contents[i] != '\n')
                        i++;

                      if (node->contents[i] == '\n')
                        i++;
                    }
                  else
                    {
                      hpos = the_screen->width - hpos;
                      bump_index++;
                    }
                  break;
                }
            }
        }
    }
  window->line_starts = line_starts;
  window->line_count = line_starts_index;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int character_width ( int  character,
int  hpos 
)

Definition at line 705 of file window.c.

{
  int printable_limit = 127;
  int width = 1;

  if (ISO_Latin_p)
    printable_limit = 255;

  if (character > printable_limit)
    width = 3;
  else if (iscntrl (character))
    {
      switch (character)
        {
        case '\r':
        case '\n':
          width = the_screen->width - hpos;
          break;
        case '\t':
          width = ((hpos + 8) & 0xf8) - hpos;
          break;
        default:
          width = 2;
        }
    }
  else if (character == DEL)
    width = 2;

  return (width);
}

Here is the caller graph for this function:

static void free_echo_area ( void  ) [static]

Definition at line 1234 of file window.c.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1509 of file window.c.

Here is the caller graph for this function:

Definition at line 1524 of file window.c.

{
  register int i;

  if (!message_buffer_index)
    return (0);

  for (i = message_buffer_index; i && message_buffer[i - 1] != '\n'; i--);

  return (string_width (message_buffer + i, 0));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void message_buffer_resize ( int  length) [static]

Definition at line 1309 of file window.c.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1487 of file window.c.

{
  NODE *node;

  node = xmalloc (sizeof (NODE));
  node->filename = NULL;
  node->parent = NULL;
  node->nodename = NULL;
  node->flags = 0;
  node->display_pos =0;

  /* Make sure that this buffer ends with a newline. */
  node->nodelen = 1 + strlen (message_buffer);
  node->contents = xmalloc (1 + node->nodelen);
  strcpy (node->contents, message_buffer);
  node->contents[node->nodelen - 1] = '\n';
  node->contents[node->nodelen] = '\0';
  return (node);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void message_in_echo_area ( char *  format,
void arg1,
void arg2 
)

Definition at line 1277 of file window.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int pad_to ( int  count,
char *  string 
)

Definition at line 1538 of file window.c.

{
  register int i;

  i = strlen (string);

  if (i >= count)
    string[i++] = ' ';
  else
    {
      while (i < count)
        string[i++] = ' ';
    }
  string[i] = '\0';

  return (i);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void printf_to_message_buffer ( char *  format,
void arg1,
void arg2,
void arg3 
)

Definition at line 1516 of file window.c.

{
  build_message_buffer (format, arg1, arg2, arg3);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 902 of file window.c.

{
  maybe_free (window->line_starts);
  calculate_line_starts (window);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int string_width ( char *  string,
int  hpos 
)

Definition at line 739 of file window.c.

{
  register int i, width, this_char_width;

  for (width = 0, i = 0; string[i]; i++)
    {
      /* Support ANSI escape sequences for -R.  */
      if (raw_escapes_p
         && string[i] == '\033'
         && string[i+1] == '['
         && isdigit (string[i+2])
         && (string[i+3] == 'm'
             || (isdigit (string[i+3]) && string[i+4] == 'm')))
       {
         while (string[i] != 'm')
           i++;
         this_char_width = 0;
       }
      else
       this_char_width = character_width (string[i], hpos);
      width += this_char_width;
      hpos += this_char_width;
    }
  return (width);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1290 of file window.c.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 916 of file window.c.

{
  register int line = 0;
  char *contents;

  if (!window->node)
    return;

  contents = window->node->contents;

  /* Find the first printed line start which is after WINDOW->point. */
  for (line = 0; line < window->line_count; line++)
    {
      char *line_start;

      line_start = window->line_starts[line];

      if ((line_start - contents) > window->point)
        break;
    }

  /* The line index preceding the line start which is past point is the
     one containing point. */
  line--;

  /* If this line appears in the current displayable page, do nothing.
     Otherwise, adjust the top of the page to make this line visible. */
  if ((line < window->pagetop) ||
      (line - window->pagetop > (window->height - 1)))
    {
      /* The user-settable variable "scroll-step" is used to attempt
         to make point visible, iff it is non-zero.  If that variable
         is zero, then the line containing point is centered within
         the window. */
      if (window_scroll_step < window->height)
        {
          if ((line < window->pagetop) &&
              ((window->pagetop - window_scroll_step) <= line))
            window->pagetop -= window_scroll_step;
          else if ((line - window->pagetop > (window->height - 1)) &&
                   ((line - (window->pagetop + window_scroll_step)
                     < window->height)))
            window->pagetop += window_scroll_step;
          else
            window->pagetop = line - ((window->height - 1) / 2);
        }
      else
        window->pagetop = line - ((window->height - 1) / 2);

      if (window->pagetop < 0)
        window->pagetop = 0;
      window->flags |= W_UpdateWindow;
    }
}

Here is the caller graph for this function:

void window_change_window_height ( WINDOW window,
int  amount 
)

Definition at line 377 of file window.c.

{
  register WINDOW *win, *prev, *next;

  /* If there is only one window, or if the amount of change is zero,
     return immediately. */
  if (!windows->next || amount == 0)
    return;

  /* Find this window in our chain. */
  for (win = windows; win; win = win->next)
    if (win == window)
      break;

  /* If the window is isolated (i.e., doesn't appear in our window list,
     then quit now. */
  if (!win)
    return;

  /* Change the height of this window by AMOUNT, if that is possible.
     It can be impossible if there isn't enough available room on the
     screen, or if the resultant window would be too small. */

    prev = window->prev;
    next = window->next;

  /* WINDOW decreasing in size? */
  if (amount < 0)
    {
      int abs_amount = -amount; /* It is easier to deal with this way. */

      /* If the resultant window would be too small, stop here. */
      if ((window->height - abs_amount) < WINDOW_MIN_HEIGHT)
        return;

      /* If we have two neighboring windows, choose the smaller one to get
         larger. */
      if (next && prev)
        {
          if (prev->height < next->height)
            shrink_me_growing_prev (window, prev, abs_amount);
          else
            shrink_me_growing_next (window, next, abs_amount);
        }
      else if (next)
        shrink_me_growing_next (window, next, abs_amount);
      else
        shrink_me_growing_prev (window, prev, abs_amount);
    }

  /* WINDOW increasing in size? */
  if (amount > 0)
    {
      int total_avail, next_avail = 0, prev_avail = 0;

      if (next)
        next_avail = next->height - WINDOW_MIN_SIZE;

      if (prev)
        prev_avail = prev->height - WINDOW_MIN_SIZE;

      total_avail = next_avail + prev_avail;

      /* If there isn't enough space available to grow this window, give up. */
      if (amount > total_avail)
        return;

      /* If there aren't two neighboring windows, or if one of the neighbors
         is larger than the other one by at least AMOUNT, grow that one. */
      if ((next && !prev) || ((next_avail - amount) >= prev_avail))
        grow_me_shrinking_next (window, next, amount);
      else if ((prev && !next) || ((prev_avail - amount) >= next_avail))
        grow_me_shrinking_prev (window, prev, amount);
      else
        {
          int change;

          /* This window has two neighbors.  They both must be shrunk in to
             make enough space for WINDOW to grow.  Make them both the same
             size. */
          if (prev_avail > next_avail)
            {
              change = prev_avail - next_avail;
              grow_me_shrinking_prev (window, prev, change);
              amount -= change;
            }
          else
            {
              change = next_avail - prev_avail;
              grow_me_shrinking_next (window, next, change);
              amount -= change;
            }

          /* Both neighbors are the same size.  Split the difference in
             AMOUNT between them. */
          while (amount)
            {
              window->height++;
              amount--;

              /* Odd numbers grow next, even grow prev. */
              if (amount & 1)
                {
                  prev->height--;
                  window->first_row--;
                }
              else
                {
                  next->height--;
                  next->first_row++;
                }
            }
          window_adjust_pagetop (prev);
          window_adjust_pagetop (next);
        }
    }
  if (prev)
    prev->flags |= W_UpdateWindow;

  if (next)
    next->flags |= W_UpdateWindow;

  window->flags |= W_UpdateWindow;
  window_adjust_pagetop (window);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int window_chars_to_goal ( char *  line,
int  goal 
)

Definition at line 1048 of file window.c.

{
  register int i, check = 0, hpos;

  for (hpos = 0, i = 0; line[i] != '\n'; i++)
    {
      /* Support ANSI escape sequences for -R.  */
      if (raw_escapes_p
         && line[i] == '\033'
         && line[i+1] == '['
         && isdigit (line[i+2])
         && (line[i+3] == 'm'
             || (isdigit (line[i+3]) && line[i+4] == 'm')))
       while (line[i] != 'm')
         i++;
      else
       check = hpos + character_width (line[i], hpos);

      if (check > goal)
        break;

      hpos = check;
    }
  return (i);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1249 of file window.c.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 613 of file window.c.

{
  WINDOW *next, *prev, *window_to_fix;

  next = window->next;
  prev = window->prev;

  /* You cannot delete the only window or a permanent window. */
  if ((!next && !prev) || (window->flags & W_WindowIsPerm))
    return;

  if (next)
    next->prev = prev;

  if (!prev)
    windows = next;
  else
    prev->next = next;

  if (window->line_starts)
    free (window->line_starts);

  if (window->modeline)
    free (window->modeline);

  if (window == active_window)
    {
      /* If there isn't a next window, then there must be a previous one,
         since we cannot delete the last window.  If there is a next window,
         prefer to use that as the active window. */
      if (next)
        active_window = next;
      else
        active_window = prev;
    }

  if (next && active_window == next)
    window_to_fix = next;
  else if (prev && active_window == prev)
    window_to_fix = prev;
  else if (next)
    window_to_fix = next;
  else if (prev)
    window_to_fix = prev;
  else
    window_to_fix = windows;
    
  if (window_to_fix->first_row > window->first_row)
    {
      int diff;

      /* Try to adjust the visible part of the node so that as little
         text as possible has to move. */
      diff = window_to_fix->first_row - window->first_row;
      window_to_fix->first_row = window->first_row;

      window_to_fix->pagetop -= diff;
      if (window_to_fix->pagetop < 0)
        window_to_fix->pagetop = 0;
    }

  /* The `+ 1' is to offset the difference between the first_row locations.
     See the code in window_make_window (). */
  window_to_fix->height += window->height + 1;
  window_to_fix->flags |= W_UpdateWindow;

  free (window);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1010 of file window.c.

{
  int i, hpos, end;
  char *line;

  i = window_line_of_point (window);

  if (i < 0)
    return (-1);

  line = window->line_starts[i];
  end = window->point - (line - window->node->contents);

  for (hpos = 0, i = 0; i < end; i++)
    {
      /* Support ANSI escape sequences for -R.  */
      if (raw_escapes_p
         && line[i] == '\033'
         && line[i+1] == '['
         && isdigit (line[i+2]))
       {
         if (line[i+3] == 'm')
           i += 3;
         else if (isdigit (line[i+3]) && line[i+4] == 'm')
           i += 4;
         else
           hpos += character_width (line[i], hpos);
       }
      else
       hpos += character_width (line[i], hpos);
    }

  return (hpos);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 995 of file window.c.

{
  if (!window->node)
    return (-1);

  if (window->goal_column != -1)
    return (window->goal_column);

  /* Okay, do the work.  Find the printed offset of the cursor
     in this window. */
  return (window_get_cursor_column (window));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void window_get_state ( WINDOW window,
SEARCH_STATE state 
)

Definition at line 1209 of file window.c.

{
  state->node = window->node;
  state->pagetop = window->pagetop;
  state->point = window->point;
}

Here is the caller graph for this function:

void window_goto_percentage ( WINDOW window,
int  percent 
)

Definition at line 1190 of file window.c.

{
  int desired_line;

  if (!percent)
    desired_line = 0;
  else
    desired_line =
      (int) ((float)window->line_count * ((float)percent / 100.0));

  window->pagetop = desired_line;
  window->point =
    window->line_starts[window->pagetop] - window->node->contents;
  window->flags |= W_UpdateWindow;
  window_make_modeline (window);
}

Here is the call graph for this function:

void window_initialize_windows ( int  width,
int  height 
)

Definition at line 54 of file window.c.

{
  the_screen = xmalloc (sizeof (WINDOW));
  the_echo_area = xmalloc (sizeof (WINDOW));
  windows = xmalloc (sizeof (WINDOW));
  active_window = windows;

  zero_mem (the_screen, sizeof (WINDOW));
  zero_mem (the_echo_area, sizeof (WINDOW));
  zero_mem (active_window, sizeof (WINDOW));

  /* None of these windows has a goal column yet. */
  the_echo_area->goal_column = -1;
  active_window->goal_column = -1;
  the_screen->goal_column = -1;

  /* The active and echo_area windows are visible.
     The echo_area is permanent.
     The screen is permanent. */
  active_window->flags = W_WindowVisible;
  the_echo_area->flags = W_WindowIsPerm | W_InhibitMode | W_WindowVisible;
  the_screen->flags    = W_WindowIsPerm;

  /* The height of the echo area never changes.  It is statically set right
     here, and it must be at least 1 line for display.  The size of the
     initial window cannot be the same size as the screen, since the screen
     includes the echo area.  So, we make the height of the initial window
     equal to the screen's displayable region minus the height of the echo
     area. */
  the_echo_area->height = ECHO_AREA_HEIGHT;
  active_window->height = the_screen->height - 1 - the_echo_area->height;
  window_new_screen_size (width, height);

  /* The echo area uses a different keymap than normal info windows. */
  the_echo_area->keymap = echo_area_keymap;
  active_window->keymap = info_keymap;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 973 of file window.c.

{
  register int i, start = 0;

  /* Try to optimize.  Check to see if point is past the pagetop for
     this window, and if so, start searching forward from there. */
  if ((window->pagetop > -1 && window->pagetop < window->line_count) &&
      (window->line_starts[window->pagetop] - window->node->contents)
      <= window->point)
    start = window->pagetop;

  for (i = start; i < window->line_count; i++)
    {
      if ((window->line_starts[i] - window->node->contents) > window->point)
        break;
    }

  return (i - 1);
}

Here is the caller graph for this function:

Definition at line 1076 of file window.c.

{
  register int i;
  char *modeline;
  char location_indicator[4];
  int lines_remaining;

  /* Only make modelines for those windows which have one. */
  if (window->flags & W_InhibitMode)
    return;

  /* Find the number of lines actually displayed in this window. */
  lines_remaining = window->line_count - window->pagetop;

  if (window->pagetop == 0)
    {
      if (lines_remaining <= window->height)
        strcpy (location_indicator, "All");
      else
        strcpy (location_indicator, "Top");
    }
  else
    {
      if (lines_remaining <= window->height)
        strcpy (location_indicator, "Bot");
      else
        {
          float pt, lc;
          int percentage;

          pt = (float)window->pagetop;
          lc = (float)window->line_count;

          percentage = 100 * (pt / lc);

          sprintf (location_indicator, "%2d%%", percentage);
        }
    }

  /* Calculate the maximum size of the information to stick in MODELINE. */
  {
    int modeline_len = 0;
    char *parent = NULL, *filename = "*no file*";
    char *nodename = "*no node*";
    const char *update_message = NULL;
    NODE *node = window->node;

    if (node)
      {
        if (node->nodename)
          nodename = node->nodename;

        if (node->parent)
          {
            parent = filename_non_directory (node->parent);
            modeline_len += strlen ("Subfile: ") + strlen (node->filename);
          }

        if (node->filename)
          filename = filename_non_directory (node->filename);

        if (node->flags & N_UpdateTags)
          update_message = _("--*** Tags out of Date ***");
      }

    if (update_message)
      modeline_len += strlen (update_message);
    modeline_len += strlen (filename);
    modeline_len += strlen (nodename);
    modeline_len += 4;          /* strlen (location_indicator). */

    /* 10 for the decimal representation of the number of lines in this
       node, and the remainder of the text that can appear in the line. */
    modeline_len += 10 + strlen (_("-----Info: (), lines ----, "));
    modeline_len += window->width;

    modeline = xmalloc (1 + modeline_len);

    /* Special internal windows have no filename. */
    if (!parent && !*filename)
      sprintf (modeline, _("-%s---Info: %s, %d lines --%s--"),
               (window->flags & W_NoWrap) ? "$" : "-",
               nodename, window->line_count, location_indicator);
    else
      sprintf (modeline, _("-%s%s-Info: (%s)%s, %d lines --%s--"),
               (window->flags & W_NoWrap) ? "$" : "-",
               (node && (node->flags & N_IsCompressed)) ? "zz" : "--",
               parent ? parent : filename,
               nodename, window->line_count, location_indicator);

    if (parent)
      sprintf (modeline + strlen (modeline), _(" Subfile: %s"), filename);

    if (update_message)
      sprintf (modeline + strlen (modeline), "%s", update_message);

    i = strlen (modeline);

    if (i >= window->width)
      modeline[window->width] = '\0';
    else
      {
        while (i < window->width)
          modeline[i++] = '-';
        modeline[i] = '\0';
      }

    strcpy (window->modeline, modeline);
    free (modeline);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 263 of file window.c.

{
  WINDOW *window;

  if (!node)
    node = active_window->node;

  /* If there isn't enough room to make another window, return now. */
  if ((active_window->height / 2) < WINDOW_MIN_SIZE)
    return (NULL);

  /* Make and initialize the new window.
     The fudging about with -1 and +1 is because the following window in the
     chain cannot start at window->height, since that is where the modeline
     for the previous window is displayed.  The inverse adjustment is made
     in window_delete_window (). */
  window = xmalloc (sizeof (WINDOW));
  window->width = the_screen->width;
  window->height = (active_window->height / 2) - 1;
#if defined (SPLIT_BEFORE_ACTIVE)
  window->first_row = active_window->first_row;
#else
  window->first_row = active_window->first_row +
    (active_window->height - window->height);
#endif
  window->keymap = info_keymap;
  window->goal_column = -1;
  window->modeline = xmalloc (1 + window->width);
  window->line_starts = NULL;
  window->flags = W_UpdateWindow | W_WindowVisible;
  window_set_node_of_window (window, node);

  /* Adjust the height of the old active window. */
  active_window->height -= (window->height + 1);
#if defined (SPLIT_BEFORE_ACTIVE)
  active_window->first_row += (window->height + 1);
#endif
  active_window->flags |= W_UpdateWindow;

  /* Readjust the new and old windows so that their modelines and contents
     will be displayed correctly. */
#if defined (NOTDEF)
  /* We don't have to do this for WINDOW since window_set_node_of_window ()
     already did. */
  window_adjust_pagetop (window);
  window_make_modeline (window);
#endif /* NOTDEF */

  /* We do have to readjust the existing active window. */
  window_adjust_pagetop (active_window);
  window_make_modeline (active_window);

#if defined (SPLIT_BEFORE_ACTIVE)
  /* This window is just before the active one.  The active window gets
     bumped down one.  The active window is not changed. */
  window->next = active_window;

  window->prev = active_window->prev;
  active_window->prev = window;

  if (window->prev)
    window->prev->next = window;
  else
    windows = window;
#else
  /* This window is just after the active one.  Which window is active is
     not changed. */
  window->prev = active_window;
  window->next = active_window->next;
  active_window->next = window;
  if (window->next)
    window->next->prev = window;
#endif /* !SPLIT_BEFORE_ACTIVE */
  return (window);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void window_mark_chain ( WINDOW chain,
int  flag 
)

Definition at line 684 of file window.c.

{
  register WINDOW *win;

  for (win = chain; win; win = win->next)
    win->flags |= flag;
}

Here is the caller graph for this function:

void window_message_in_echo_area ( char *  format,
void arg1,
void arg2 
)

Definition at line 1260 of file window.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void window_new_screen_size ( int  width,
int  height 
)

Definition at line 105 of file window.c.

{
  register WINDOW *win;
  int delta_height, delta_each, delta_leftover;
  int numwins;

  /* If no change, do nothing. */
  if (width == the_screen->width && height == the_screen->height)
    return;

  /* If the new window height is too small, make it be zero. */
  if (height < (WINDOW_MIN_SIZE + the_echo_area->height))
    height = 0;
  if (width < 0)
    width = 0;

  /* Find out how many windows will change. */
  for (numwins = 0, win = windows; win; win = win->next, numwins++);

  /* See if some windows will need to be deleted.  This is the case if
     the screen is getting smaller, and the available space divided by
     the number of windows is less than WINDOW_MIN_SIZE.  In that case,
     delete some windows and try again until there is either enough
     space to divy up among the windows, or until there is only one
     window left. */
  while ((height - echo_area_required) / numwins <= WINDOW_MIN_SIZE)
    {
      /* If only one window, make the size of it be zero, and return
         immediately. */
      if (!windows->next)
        {
          windows->height = 0;
          maybe_free (windows->line_starts);
          windows->line_starts = NULL;
          windows->line_count = 0;
          break;
        }

      /* If we have some temporary windows, delete one of them. */
      for (win = windows; win; win = win->next)
        if (win->flags & W_TempWindow)
          break;

      /* Otherwise, delete the first window, and try again. */
      if (!win)
        win = windows;

      if (window_deletion_notifier)
        (*window_deletion_notifier) (win);

      window_delete_window (win);
      numwins--;
    }

  /* The screen has changed height and width. */
  delta_height = height - the_screen->height;   /* This is how much. */
  the_screen->height = height;                  /* This is the new height. */
  the_screen->width = width;                    /* This is the new width. */

  /* Set the start of the echo area. */
  the_echo_area->first_row = height - the_echo_area->height;
  the_echo_area->width = width;

  /* Check to see if the screen can really be changed this way. */
  if ((!windows->next) && ((windows->height == 0) && (delta_height < 0)))
    return;

  /* Divide the change in height among the available windows. */
  delta_each = delta_height / numwins;
  delta_leftover = delta_height - (delta_each * numwins);

  /* Change the height of each window in the chain by delta_each.  Change
     the height of the last window in the chain by delta_each and by the
     leftover amount of change.  Change the width of each window to be
     WIDTH. */
  for (win = windows; win; win = win->next)
    {
      if ((win->width != width) && ((win->flags & W_InhibitMode) == 0))
        {
          win->width = width;
          maybe_free (win->modeline);
          win->modeline = xmalloc (1 + width);
        }

      win->height += delta_each;

      /* If the previous height of this window was zero, it was the only
         window, and it was not visible.  Thus we need to compensate for
         the echo_area. */
      if (win->height == delta_each)
        win->height -= (1 + the_echo_area->height);

      /* If this is not the first window in the chain, then change the
         first row of it.  We cannot just add delta_each to the first row,
         since this window's first row is the sum of the collective increases
         that have gone before it.  So we just add one to the location of the
         previous window's modeline. */
      if (win->prev)
        win->first_row = (win->prev->first_row + win->prev->height) + 1;

      /* The last window in the chain gets the extra space (or shrinkage). */
      if (!win->next)
        win->height += delta_leftover;

      if (win->node)
        recalculate_line_starts (win);

      win->flags |= W_UpdateWindow;
    }

  /* If the screen got smaller, check over the windows just shrunk to
     keep them within bounds.  Some of the windows may have gotten smaller
     than WINDOW_MIN_HEIGHT in which case some of the other windows are
     larger than the available display space in the screen.  Because of our
     intial test above, we know that there is enough space for all of the
     windows. */
  if ((delta_each < 0) && ((windows->height != 0) && windows->next))
    {
      int avail;

      avail = the_screen->height - (numwins + the_echo_area->height);
      win = windows;

      while (win)
        {
          if ((win->height < WINDOW_MIN_HEIGHT) ||
              (win->height > avail))
            {
              WINDOW *lastwin = NULL;

              /* Split the space among the available windows. */
              delta_each = avail / numwins;
              delta_leftover = avail - (delta_each * numwins);

              for (win = windows; win; win = win->next)
                {
                  lastwin = win;
                  if (win->prev)
                    win->first_row =
                      (win->prev->first_row + win->prev->height) + 1;
                  win->height = delta_each;
                }

              /* Give the leftover space (if any) to the last window. */
              lastwin->height += delta_leftover;
              break;
            }
          else
            win= win->next;
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 768 of file window.c.

{
  register int i, lines;
  char *contents;

  if (!node)
    return (0);

  contents = node->contents;
  for (i = 0, lines = 1; i < node->nodelen; i++)
    if (contents[i] == '\n')
      lines++;

  return (lines);
}
void window_set_node_of_window ( WINDOW window,
NODE node 
)

Definition at line 595 of file window.c.

{
  window->node = node;
  window->pagetop = 0;
  window->point = 0;
  recalculate_line_starts (window);
  window->flags |= W_UpdateWindow;
  /* The display_pos member is nonzero if we're displaying an anchor.  */
  window->point = node ? node->display_pos : 0;
  window_adjust_pagetop (window);
  window_make_modeline (window);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void window_set_state ( WINDOW window,
SEARCH_STATE state 
)

Definition at line 1218 of file window.c.

{
  if (window->node != state->node)
    window_set_node_of_window (window, state->node);
  window->pagetop = state->pagetop;
  window->point = state->point;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 508 of file window.c.

{
  WINDOW *win, *last_adjusted;
  int numwins, avail, per_win_height, leftover;
  int do_internals;

  numwins = avail = 0;
  do_internals = (style == TILE_INTERNALS);

  for (win = windows; win; win = win->next)
    if (do_internals || !win->node ||
        (win->node->flags & N_IsInternal) == 0)
      {
        avail += win->height;
        numwins++;
      }

  if (numwins <= 1 || !the_screen->height)
    return;

  /* Find the size for each window.  Divide the size of the usable portion
     of the screen by the number of windows. */
  per_win_height = avail / numwins;
  leftover = avail - (per_win_height * numwins);

  last_adjusted = NULL;
  for (win = windows; win; win = win->next)
    {
      if (do_internals || !win->node ||
          (win->node->flags & N_IsInternal) == 0)
        {
          last_adjusted = win;
          win->height = per_win_height;
        }
    }

  if (last_adjusted)
    last_adjusted->height += leftover;

  /* Readjust the first_row of every window in the chain. */
  for (win = windows; win; win = win->next)
    {
      if (win->prev)
        win->first_row = win->prev->first_row + win->prev->height + 1;

      window_adjust_pagetop (win);
      win->flags |= W_UpdateWindow;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 561 of file window.c.

{
  if (window->flags & W_NoWrap)
    window->flags &= ~W_NoWrap;
  else
    window->flags |= W_NoWrap;

  if (window != the_echo_area)
    {
      char **old_starts;
      int old_lines, old_pagetop;

      old_starts = window->line_starts;
      old_lines = window->line_count;
      old_pagetop = window->pagetop;

      calculate_line_starts (window);

      /* Make sure that point appears within this window. */
      window_adjust_pagetop (window);

      /* If the pagetop hasn't changed maybe we can do some scrolling now
         to speed up the display.  Many of the line starts will be the same,
         so scrolling here is a very good optimization.*/
      if (old_pagetop == window->pagetop)
        display_scroll_line_starts
          (window, old_pagetop, old_starts, old_lines);
      maybe_free (old_starts);
    }
  window->flags |= W_UpdateWindow;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void window_unmark_chain ( WINDOW chain,
int  flag 
)

Definition at line 694 of file window.c.

{
  register WINDOW *win;

  for (win = chain; win; win = win->next)
    win->flags &= ~flag;
}

Variable Documentation

Definition at line 40 of file window.c.

NODE* echo_area_node = NULL [static]

Definition at line 1230 of file window.c.

char* message_buffer = NULL [static]

Definition at line 1302 of file window.c.

int message_buffer_index = 0 [static]

Definition at line 1303 of file window.c.

int message_buffer_size = 0 [static]

Definition at line 1304 of file window.c.

Definition at line 1272 of file window.c.

Definition at line 1273 of file window.c.

Definition at line 1274 of file window.c.

Definition at line 34 of file window.c.

Definition at line 31 of file window.c.

Definition at line 102 of file window.c.

Definition at line 912 of file window.c.

Definition at line 37 of file window.c.