Beispiel #1
0
void
do_line_insertion_deletion_costs (struct frame *frame,
				  const char *ins_line_string,
				  const char *multi_ins_string,
				  const char *del_line_string,
				  const char *multi_del_string,
				  const char *setup_string,
				  const char *cleanup_string,
				  int coefficient)
{
  FRAME_INSERT_COST (frame) =
    xnrealloc (FRAME_INSERT_COST (frame), FRAME_LINES (frame), sizeof (int));
  FRAME_DELETEN_COST (frame) =
    xnrealloc (FRAME_DELETEN_COST (frame), FRAME_LINES (frame), sizeof (int));
  FRAME_INSERTN_COST (frame) =
    xnrealloc (FRAME_INSERTN_COST (frame), FRAME_LINES (frame), sizeof (int));
  FRAME_DELETE_COST (frame) =
    xnrealloc (FRAME_DELETE_COST (frame), FRAME_LINES (frame), sizeof (int));

  ins_del_costs (frame,
		 ins_line_string, multi_ins_string,
		 setup_string, cleanup_string,
		 FRAME_INSERT_COST (frame), FRAME_INSERTN_COST (frame),
		 coefficient);
  ins_del_costs (frame,
		 del_line_string, multi_del_string,
		 setup_string, cleanup_string,
		 FRAME_DELETE_COST (frame), FRAME_DELETEN_COST (frame),
		 coefficient);
}
Beispiel #2
0
static void
set_frame_size (EmacsFrame ew)
{
  /* The widget hierarchy is

	argv[0]			emacsShell	pane	Frame-NAME
	ApplicationShell	EmacsShell	Paned	EmacsFrame

     We accept geometry specs in this order:

	*Frame-NAME.geometry
	*EmacsFrame.geometry
	Emacs.geometry

     Other possibilities for widget hierarchies might be

	argv[0]			frame		pane	Frame-NAME
	ApplicationShell	EmacsShell	Paned	EmacsFrame
     or
	argv[0]			Frame-NAME	pane	Frame-NAME
	ApplicationShell	EmacsShell	Paned	EmacsFrame
     or
	argv[0]			Frame-NAME	pane	emacsTextPane
	ApplicationShell	EmacsFrame	Paned	EmacsTextPane

     With the current setup, the text-display-area is the part which is
     an emacs "frame", since that's the only part managed by emacs proper
     (the menubar and the parent of the menubar and all that sort of thing
     are managed by lwlib.)

     The EmacsShell widget is simply a replacement for the Shell widget
     which is able to deal with using an externally-supplied window instead
     of always creating its own.  It is not actually emacs specific, and
     should possibly have class "Shell" instead of "EmacsShell" to simplify
     the resources.

   */

  /* Hairily merged geometry */
  struct frame *f = ew->emacs_frame.frame;
  int w = FRAME_COLS (f);
  int h = FRAME_LINES (f);
  Widget wmshell = get_wm_shell ((Widget) ew);
  Dimension pixel_width, pixel_height;
  /* Each Emacs shell is now independent and top-level.  */

  if (! XtIsSubclass (wmshell, shellWidgetClass)) emacs_abort ();

  char_to_pixel_size (ew, w, h, &pixel_width, &pixel_height);
  ew->core.width = (frame_resize_pixelwise
		    ? FRAME_PIXEL_WIDTH (f)
		    : pixel_width);
  ew->core.height = (frame_resize_pixelwise
		     ? FRAME_PIXEL_HEIGHT (f)
		     : pixel_height);

  frame_size_history_add
    (f, Qset_frame_size, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
     list2 (make_number (ew->core.width), make_number (ew->core.height)));
}
Beispiel #3
0
/* Clear from cursor to end of screen.  */
static void
w32con_clear_to_end (void)
{
  struct frame * f = PICK_FRAME ();

  w32con_clear_end_of_line (FRAME_COLS (f) - 1);
  w32con_ins_del_lines (cursor_coords.Y, FRAME_LINES (f) - cursor_coords.Y - 1);
}
Beispiel #4
0
static void
line_ins_del (struct frame *frame, int ov1, int pf1, int ovn, int pfn,
              register int *ov, register int *mf)
{
  register int i;
  register int frame_lines = FRAME_LINES (frame);
  register int insert_overhead = ov1 * 10;
  register int next_insert_cost = ovn * 10;

  for (i = frame_lines-1; i >= 0; i--)
    {
      mf[i] = next_insert_cost / 10;
      next_insert_cost += pfn;
      ov[i] = (insert_overhead + next_insert_cost) / 10;
      insert_overhead += pf1;
    }
}
Beispiel #5
0
/* Clear the frame.  */
static void
w32con_clear_frame (struct frame *f)
{
  COORD	     dest;
  int        n;
  DWORD      r;
  CONSOLE_SCREEN_BUFFER_INFO info;

  GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info);

  /* Remember that the screen buffer might be wider than the window.  */
  n = FRAME_LINES (f) * info.dwSize.X;
  dest.X = dest.Y = 0;

  FillConsoleOutputAttribute (cur_screen, char_attr_normal, n, dest, &r);
  FillConsoleOutputCharacter (cur_screen, ' ', n, dest, &r);

  w32con_move_cursor (f, 0, 0);
}
Beispiel #6
0
/* Insert n lines at vpos. if n is negative delete -n lines.  */
static void
w32con_ins_del_lines (int vpos, int n)
{
  int	     i, nb;
  SMALL_RECT scroll;
  COORD	     dest;
  CHAR_INFO  fill;
  struct frame *  f = PICK_FRAME ();

  if (n < 0)
    {
      scroll.Top = vpos - n;
      scroll.Bottom = FRAME_LINES (f);
      dest.Y = vpos;
    }
  else
    {
      scroll.Top = vpos;
      scroll.Bottom = FRAME_LINES (f) - n;
      dest.Y = vpos + n;
    }
  scroll.Left = 0;
  scroll.Right = FRAME_COLS (f);

  dest.X = 0;

  fill.Char.AsciiChar = 0x20;
  fill.Attributes = char_attr_normal;

  ScrollConsoleScreenBuffer (cur_screen, &scroll, NULL, dest, &fill);

  /* Here we have to deal with a w32 console flake: If the scroll
     region looks like abc and we scroll c to a and fill with d we get
     cbd... if we scroll block c one line at a time to a, we get cdd...
     Emacs expects cdd consistently... So we have to deal with that
     here... (this also occurs scrolling the same way in the other
     direction.  */

  if (n > 0)
    {
      if (scroll.Bottom < dest.Y)
        {
	  for (i = scroll.Bottom; i < dest.Y; i++)
            {
	      w32con_move_cursor (i, 0);
	      w32con_clear_end_of_line (FRAME_COLS (f));
            }
        }
    }
  else
    {
      nb = dest.Y + (scroll.Bottom - scroll.Top) + 1;

      if (nb < scroll.Top)
        {
	  for (i = nb; i < scroll.Top; i++)
            {
	      w32con_move_cursor (i, 0);
	      w32con_clear_end_of_line (FRAME_COLS (f));
            }
        }
    }

  cursor_coords.X = 0;
  cursor_coords.Y = vpos;
}
Beispiel #7
0
/* Clear from cursor to end of screen.  */
static void
w32con_clear_to_end (struct frame *f)
{
  w32con_clear_end_of_line (f, FRAME_COLS (f) - 1);
  w32con_ins_del_lines (f, cursor_coords.Y, FRAME_LINES (f) - cursor_coords.Y - 1);
}
Beispiel #8
0
static void
calculate_scrolling (struct frame *frame,
		     /* matrix is of size window_size + 1 on each side.  */
		     struct matrix_elt *matrix,
		     int window_size, int lines_below,
		     int *draw_cost, int *old_hash, int *new_hash,
		     int free_at_end)
{
  register int i, j;
  int frame_lines = FRAME_LINES (frame);
  register struct matrix_elt *p, *p1;
  register int cost, cost1;

  int lines_moved = window_size
    + (FRAME_SCROLL_REGION_OK (frame) ? 0 : lines_below);
  /* first_insert_cost[I] is the cost of doing the first insert-line
     at the i'th line of the lines we are considering,
     where I is origin 1 (as it is below).  */
  int *first_insert_cost
    = &FRAME_INSERT_COST (frame)[frame_lines - 1 - lines_moved];
  int *first_delete_cost
    = &FRAME_DELETE_COST (frame)[frame_lines - 1 - lines_moved];
  int *next_insert_cost
    = &FRAME_INSERTN_COST (frame)[frame_lines - 1 - lines_moved];
  int *next_delete_cost
    = &FRAME_DELETEN_COST (frame)[frame_lines - 1 - lines_moved];

  /* Discourage long scrolls on fast lines.
     Don't scroll nearly a full frame height unless it saves
     at least 1/4 second.  */
  int extra_cost = (int) (baud_rate / (10 * 4 * FRAME_LINES (frame)));

  if (baud_rate <= 0)
    extra_cost = 1;

  /* initialize the top left corner of the matrix */
  matrix->writecost = 0;
  matrix->insertcost = INFINITY;
  matrix->deletecost = INFINITY;
  matrix->insertcount = 0;
  matrix->deletecount = 0;

  /* initialize the left edge of the matrix */
  cost = first_insert_cost[1] - next_insert_cost[1];
  for (i = 1; i <= window_size; i++)
    {
      p = matrix + i * (window_size + 1);
      cost += draw_cost[i] + next_insert_cost[i] + extra_cost;
      p->insertcost = cost;
      p->writecost = INFINITY;
      p->deletecost = INFINITY;
      p->insertcount = i;
      p->deletecount = 0;
    }

  /* initialize the top edge of the matrix */
  cost = first_delete_cost[1] - next_delete_cost[1];
  for (j = 1; j <= window_size; j++)
    {
      cost += next_delete_cost[j];
      matrix[j].deletecost = cost;
      matrix[j].writecost = INFINITY;
      matrix[j].insertcost = INFINITY;
      matrix[j].deletecount = j;
      matrix[j].insertcount = 0;
    }

  /* `i' represents the vpos among new frame contents.
     `j' represents the vpos among the old frame contents.  */
  p = matrix + window_size + 2;	/* matrix [1, 1] */
  for (i = 1; i <= window_size; i++, p++)
    for (j = 1; j <= window_size; j++, p++)
      {
	/* p contains the address of matrix [i, j] */

	/* First calculate the cost assuming we do
	   not insert or delete above this line.
	   That is, if we update through line i-1
	   based on old lines through j-1,
	   and then just change old line j to new line i.  */
	p1 = p - window_size - 2; /* matrix [i-1, j-1] */
	cost = p1->writecost;
	if (cost > p1->insertcost)
	  cost = p1->insertcost;
	if (cost > p1->deletecost)
	  cost = p1->deletecost;
	if (old_hash[j] != new_hash[i])
	  cost += draw_cost[i];
	p->writecost = cost;

	/* Calculate the cost if we do an insert-line
	   before outputting this line.
	   That is, we update through line i-1
	   based on old lines through j,
	   do an insert-line on line i,
	   and then output line i from scratch,
	   leaving old lines starting from j for reuse below.  */
	p1 = p - window_size - 1; /* matrix [i-1, j] */
	/* No need to think about doing a delete followed
	   immediately by an insert.  It cannot be as good
	   as not doing either of them.  */
	if (free_at_end == i)
	  {
	    cost = p1->writecost;
	    cost1 = p1->insertcost;
	  }
	else
	  {
	    cost = p1->writecost + first_insert_cost[i];
	    if ((int) p1->insertcount > i)
	      emacs_abort ();
	    cost1 = p1->insertcost + next_insert_cost[i - p1->insertcount];
	  }
	p->insertcost = min (cost, cost1) + draw_cost[i] + extra_cost;
	p->insertcount = (cost < cost1) ? 1 : p1->insertcount + 1;
	if ((int) p->insertcount > i)
	  emacs_abort ();

	/* Calculate the cost if we do a delete line after
	   outputting this line.
	   That is, we update through line i
	   based on old lines through j-1,
	   and throw away old line j.  */
	p1 = p - 1;		/* matrix [i, j-1] */
	/* No need to think about doing an insert followed
	   immediately by a delete.  */
	if (free_at_end == i)
	  {
	    cost = p1->writecost;
	    cost1 = p1->deletecost;
	  }
	else
	  {
	    cost = p1->writecost + first_delete_cost[i];
	    cost1 = p1->deletecost + next_delete_cost[i];
	  }
	p->deletecost = min (cost, cost1);
	p->deletecount = (cost < cost1) ? 1 : p1->deletecount + 1;
      }
}
Beispiel #9
0
static void
calculate_direct_scrolling (struct frame *frame,
			    /* matrix is of size window_size + 1 on each side.  */
			    struct matrix_elt *matrix,
			    int window_size, int lines_below,
			    int *draw_cost, int *old_draw_cost,
			    int *old_hash, int *new_hash,
			    int free_at_end)
{
  register int i, j;
  int frame_lines = FRAME_LINES (frame);
  register struct matrix_elt *p, *p1;
  register int cost, cost1, delta;

  /* first_insert_cost[-I] is the cost of doing the first insert-line
     at a position I lines above the bottom line in the scroll window. */
  int *first_insert_cost
    = &FRAME_INSERT_COST (frame)[frame_lines - 1];
  int *first_delete_cost
    = &FRAME_DELETE_COST (frame)[frame_lines - 1];
  int *next_insert_cost
    = &FRAME_INSERTN_COST (frame)[frame_lines - 1];
  int *next_delete_cost
    = &FRAME_DELETEN_COST (frame)[frame_lines - 1];

  int scroll_overhead;

  /* Discourage long scrolls on fast lines.
     Don't scroll nearly a full frame height unless it saves
     at least 1/4 second.  */
  int extra_cost = (int) (baud_rate / (10 * 4 * FRAME_LINES (frame)));

  if (baud_rate <= 0)
    extra_cost = 1;

  /* Overhead of setting the scroll window, plus the extra cost
     cost of scrolling by a distance of one.  The extra cost is
     added once for consistency with the cost vectors */
  scroll_overhead
    = FRAME_SCROLL_REGION_COST (frame) + extra_cost;

  /* initialize the top left corner of the matrix */
  matrix->writecost = 0;
  matrix->insertcost = INFINITY;
  matrix->deletecost = INFINITY;
  matrix->writecount = 0;
  matrix->insertcount = 0;
  matrix->deletecount = 0;

  /* initialize the left edge of the matrix */
  cost = 0;
  for (i = 1; i <= window_size; i++)
    {
      p = matrix + i * (window_size + 1);
      cost += draw_cost[i];
      p->insertcost = cost;
      p->writecost = INFINITY;
      p->deletecost = INFINITY;
      p->insertcount = i;
      p->writecount = 0;
      p->deletecount = 0;
    }

  /* initialize the top edge of the matrix */
  for (j = 1; j <= window_size; j++)
    {
      matrix[j].deletecost = 0;
      matrix[j].writecost = INFINITY;
      matrix[j].insertcost = INFINITY;
      matrix[j].deletecount = j;
      matrix[j].writecount = 0;
      matrix[j].insertcount = 0;
    }

  /* `i' represents the vpos among new frame contents.
     `j' represents the vpos among the old frame contents.  */
  p = matrix + window_size + 2;	/* matrix [1, 1] */

  for (i = 1; i <= window_size; i++, p++)
    for (j = 1; j <= window_size; j++, p++)
      {
	/* p contains the address of matrix [i, j] */

	/* First calculate the cost assuming we do
	   not insert or delete above this line.
	   That is, if we update through line i-1
	   based on old lines through j-1,
	   and then just change old line j to new line i.

	   Depending on which choice gives the lower cost,
	   this usually involves either scrolling a single line
	   or extending a sequence of scrolled lines, but
	   when i == j, no scrolling is required. */
	p1 = p - window_size - 2; /* matrix [i-1, j-1] */
	cost = p1->insertcost;
	if (cost > p1->deletecost)
	  cost = p1->deletecost;
	cost1 = p1->writecost;
	if (i == j)
	  {
	    if (cost > cost1)
	      {
		cost = cost1;
		p->writecount = p1->writecount + 1;
	      }
	    else
	      p->writecount = 1;
	    if (old_hash[j] != new_hash[i])
	      {
		cost += draw_cost[i];
	      }
	  }
	else
	  {
	    if (i > j)
	      {
		delta = i - j;

		/* The cost added here for scrolling the first line by
		   a distance N includes the overhead of setting the
		   scroll window, the cost of inserting N lines at a
		   position N lines above the bottom line of the window,
		   and an extra cost which is proportional to N. */
		cost += scroll_overhead + first_insert_cost[-delta] +
		  (delta-1) * (next_insert_cost[-delta] + extra_cost);

		/* In the most general case, the insertion overhead and
		   the multiply factor can grow linearly as the distance
		   from the bottom of the window increases.  The incremental
		   cost of scrolling an additional line depends upon the
		   rate of change of these two parameters.  Each of these
		   growth rates can be determined by a simple difference.
		   To reduce the cumulative effects of rounding error, we
		   vary the position at which the difference is computed. */
		cost1 += first_insert_cost[-j] - first_insert_cost[1-j] +
		  (delta-1) * (next_insert_cost[-j] - next_insert_cost[1-j]);
	      }
	    else
	      {
		delta = j - i;
		cost += scroll_overhead + first_delete_cost[-delta] +
		  (delta-1) * (next_delete_cost[-delta] + extra_cost);
		cost1 += first_delete_cost[-i] - first_delete_cost[1-i] +
		  (delta-1) * ( next_delete_cost[-i] - next_delete_cost[1-i]);
	      }
	    if (cost1 < cost)
	      {
		cost = cost1;
		p->writecount = p1->writecount + 1;
	      }
	    else
	      p->writecount = 1;
	    if (old_hash[j] != new_hash[i])
	      {
		cost += draw_cost[i] + old_draw_cost[j];
	      }
	  }
	p->writecost = cost;

	/* Calculate the cost if we do an insert-line
	   before outputting this line.
	   That is, we update through line i-1
	   based on old lines through j,
	   do an insert-line on line i,
	   and then output line i from scratch,
	   leaving old lines starting from j for reuse below.  */
	p1 = p - window_size - 1; /* matrix [i-1, j] */
	cost = p1->writecost;
	/* If i > j, an insert is allowed after a delete. */
	if (i > j && p1->deletecost < cost)
	  cost = p1->deletecost;
	if (p1->insertcost <= cost)
	  {
	    cost = p1->insertcost;
	    p->insertcount = p1->insertcount + 1;
	  }
	else
	  p->insertcount = 1;
	cost += draw_cost[i];
	p->insertcost = cost;

	/* Calculate the cost if we do a delete line after
	   outputting this line.
	   That is, we update through line i
	   based on old lines through j-1,
	   and throw away old line j.  */
	p1 = p - 1;		/* matrix [i, j-1] */
	cost = p1->writecost;
	/* If i < j, a delete is allowed after an insert. */
	if (i < j && p1->insertcost < cost)
	  cost = p1->insertcost;
	cost1 = p1->deletecost;
	if (p1->deletecost <= cost)
	  {
	    cost = p1->deletecost;
	    p->deletecount = p1->deletecount + 1;
	  }
	else
	  p->deletecount = 1;
	p->deletecost = cost;
      }
}