⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dispnew.c.dist

📁 早期freebsd实现
💻 DIST
📖 第 1 页 / 共 3 页
字号:
/* Newly written part of redisplay code.   Copyright (C) 1985, 1986, 1987, 1988, 1990 Free Software Foundation, Inc.This file is part of GNU Emacs.GNU Emacs is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 1, or (at your option)any later version.GNU Emacs is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Emacs; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */#include <signal.h>#include "config.h"#include <stdio.h>#ifdef HAVE_TIMEVAL#ifdef HPUX#include <time.h>#else#include <sys/time.h>#endif#endif#ifdef HAVE_TERMIO#include <termio.h>#ifdef TCOUTQ#undef TIOCOUTQ#define TIOCOUTQ TCOUTQ#include <fcntl.h>#endif /* TCOUTQ defined */#else#ifndef VMS#include <sys/ioctl.h>#endif /* not VMS */#endif /* not HAVE_TERMIO *//* Allow m- file to inhibit use of FIONREAD.  */#ifdef BROKEN_FIONREAD#undef FIONREAD#endif/* We are unable to use interrupts if FIONREAD is not available,   so flush SIGIO so we won't try. */#ifndef FIONREAD#ifdef SIGIO#undef SIGIO#endif#endif#undef NULL#include "termchar.h"#include "termopts.h"#include "cm.h"#include "dispextern.h"#include "lisp.h"#include "buffer.h"#include "window.h"#include "commands.h"#define max(a, b) ((a) > (b) ? (a) : (b))#define min(a, b) ((a) < (b) ? (a) : (b))#ifndef PENDING_OUTPUT_COUNT/* Get number of chars of output now in the buffer of a stdio stream.   This ought to be built in in stdio, but it isn't.   Some s- files override this because their stdio internals differ.  */#ifdef __GNU_LIBRARY__#define	PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bp - (FILE)->__buf)#else#define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base)#endif#endif /* No PENDING_OUTPUT_COUNT *//* Nonzero means do not assume anything about current   contents of actual terminal screen */int screen_garbaged;/* Desired terminal cursor position (to show position of point),   origin zero */int cursor_hpos, cursor_vpos;/* Nonzero means last display completed and cursor is really at   cursor_hpos, cursor_vpos.  Zero means it was preempted. */int display_completed;/* Lisp variable visible-bell; enables use of screen-flash   instead of audible bell.  */int visible_bell;/* Invert the color of the whole screen, at a low level.  */int inverse_video;/* Line speed of the terminal.  */int baud_rate;/* nil or a symbol naming the window system   under which emacs is running   ('x is the only current possibility).  */Lisp_Object Vwindow_system;/* Version number of window system, or nil if no window system.  */Lisp_Object Vwindow_system_version;/* Nonzero means reading single-character input with prompt   so put cursor on minibuffer after the prompt.  */int cursor_in_echo_area;/* Description of actual screen contents.  */ struct matrix *current_screen;/* Description of desired screen contents.  */struct matrix *new_screen;/* Buffer sometimes used to hold partial screen contents.  */struct matrix *temp_screen;/* Stdio stream being used for copy of all terminal output.  */FILE *termscript;/* Structure for info on cursor positioning */struct cm Wcm;int in_display;		/* 1 if in redisplay: can't handle SIGWINCH now.  */int delayed_size_change;  /* 1 means SIGWINCH happened when not safe.  */int delayed_screen_height;  /* Remembered new screen height.  */int delayed_screen_width;   /* Remembered new screen width.  *//* This buffer records the history of display preemption.  */struct preempt{  /* Number of keyboard characters read so far at preempt.  */  int keyboard_char_count;  /* Vertical position at which preemption occurred.  */  int vpos;};#define N_PREEMPTIONS 50/* Circular buffer recording recent display preemptions.  */struct preempt preemptions[N_PREEMPTIONS];/* Index of next element in preemptions.  */int preemption_index;/* Set these variables in the debugger to force a display preemption.  */int debug_preemption_vpos = -1;int debug_preemption_char_count = -1;extern int num_input_chars;/* Free and reallocate current_screen and new_screen.  */struct matrix *make_screen_structure ();remake_screen_structures (){  if (current_screen)    free_screen_structure (current_screen);  if (new_screen)    free_screen_structure (new_screen);  if (temp_screen)    free_screen_structure (temp_screen);  current_screen = make_screen_structure (0);  new_screen = make_screen_structure (0);  temp_screen = make_screen_structure (1);  if (message_buf)    message_buf = (char *) xrealloc (message_buf, screen_width + 1);  else    message_buf = (char *) xmalloc (screen_width + 1);}struct matrix *make_screen_structure (empty)     int empty;{  int i;  struct matrix *new = (struct matrix *) xmalloc (sizeof (struct matrix));  new->height = screen_height;  new->width = screen_width;  new->highlight = (char *) xmalloc (screen_height);  new->enable = (char *) xmalloc (screen_height);  new->contents = (unsigned char **) xmalloc (screen_height * sizeof (char *));  new->used = (int *) xmalloc (screen_height * sizeof (int));  if (empty)    {      /* Make the buffer used by decode_mode_spec.  */      new->total_contents = (unsigned char *) xmalloc (screen_width + 2);      bzero (new->contents, screen_height * sizeof (char *));    }  else    {      /* Add 2 to leave extra bytes at beginning and end of each line.  */       new->total_contents = (unsigned char *) xmalloc (screen_height * (screen_width + 2));      bzero (new->total_contents, screen_height * (screen_width + 2));      for (i = 0; i < screen_height; i++)	new->contents[i] = new->total_contents + i * (screen_width + 2) + 1;    }  bzero (new->enable, screen_height);  return new;}free_screen_structure (matrix)     struct matrix *matrix;{  if (matrix->total_contents)    free (matrix->total_contents);  free (matrix->contents);  free (matrix->highlight);  free (matrix->enable);  free (matrix->used);  free (matrix);}/* Return the hash code of contents of line VPOS of screen-matrix M.  */intline_hash_code (m, vpos)     struct matrix *m;     int vpos;{  register unsigned char *body;  register int h = 0;  /* Give all lighlighted lines the same hash code     so as to encourage scrolling to leave them in place.  */  if (m->highlight[vpos])    return -1;  body = m->contents[vpos];  if (must_write_spaces)    {      while (1)	{	  int c = *body++;	  if (c == 0)	    break;	  h = (((h << 4) + (h >> 24)) & 0x0fffffff) + c - ' ';	}    }  else    {      while (1)	{	  int c = *body++;	  if (c == 0)	    break;	  h = (((h << 4) + (h >> 24)) & 0x0fffffff) + c;	}    }  if (h)    return h;  return 1;}/* Return number of characters in line in M at vpos VPOS,   except don't count leading and trailing spaces   unless the terminal requires those to be explicitly output.  */intline_draw_cost (m, vpos)     struct matrix *m;     int vpos;{  register unsigned char *body;  register int i;  if (must_write_spaces)    return m->used[vpos];  body = m->contents[vpos];  for (i = m->used[vpos]; i > 0 && body[i - 2] == ' '; i--);  i -= count_blanks (body);  return max (i, 0);}/* The functions on this page are the interface from xdisp.c to redisplay. The only other interface into redisplay is through setting cursor_hpos and cursor_vpos (in xdisp.c) and setting screen_garbaged. *//* cancel_line eliminates any request to display a line at position `vpos' */cancel_line (vpos)     int vpos;{  new_screen->enable[vpos] = 0;}clear_screen_records (){  int i;  bzero (current_screen->enable, screen_height);}/* Get ready to display on line `vpos'   and set it up for outputting starting at `hpos' within it.   Return the text string where that line is stored.  */unsigned char *get_display_line (vpos, hpos)     int vpos;     register int hpos;{  if (new_screen->enable[vpos] && new_screen->used[vpos] > hpos)    abort ();  if (! new_screen->enable[vpos])    {      new_screen->used[vpos] = 0;      new_screen->highlight[vpos] = 0;      new_screen->enable[vpos] = 1;    }  if (hpos > new_screen->used[vpos])    {      unsigned char *p = new_screen->contents[vpos] + new_screen->used[vpos];      unsigned char *end = new_screen->contents[vpos] + hpos;      new_screen->used[vpos] = hpos;      while (p != end)	*p++ = ' ';    }  return new_screen->contents[vpos];}/* Scroll lines from vpos `from' up to but not including vpos `end' down by `amount' lines (`amount' may be negative). Returns nonzero if done, zero if terminal cannot scroll them. */intscroll_screen_lines (from, end, amount)     int from, end, amount;{  register int i;  if (!line_ins_del_ok)    return 0;  if (amount == 0)    return 1;  if (amount > 0)    {      set_terminal_window (end + amount);      if (!scroll_region_ok)	ins_del_lines (end, -amount);      ins_del_lines (from, amount);      set_terminal_window (0);      rotate_vector (current_screen->contents + from,		     sizeof (char *) * (end + amount - from),		     amount * sizeof (char *));      safe_bcopy (current_screen->used + from,		  current_screen->used + from + amount,		  (end - from) * sizeof current_screen->used[0]);      safe_bcopy (current_screen->highlight + from,		  current_screen->highlight + from + amount,		  (end - from) * sizeof current_screen->highlight[0]);      safe_bcopy (current_screen->enable + from,		  current_screen->enable + from + amount,		  (end - from) * sizeof current_screen->enable[0]);      /* Mark the lines made empty by scrolling as enabled, empty and	 normal video.  */      bzero (current_screen->used + from,	     amount * sizeof current_screen->used[0]);      bzero (current_screen->highlight + from,	     amount * sizeof current_screen->highlight[0]);      for (i = from; i < from + amount; i++)	{	  current_screen->contents[i][0] = '\0';	  current_screen->enable[i] = 1;	}    }  if (amount < 0)    {      set_terminal_window (end);      ins_del_lines (from + amount, amount);      if (!scroll_region_ok)	ins_del_lines (end + amount, -amount);      set_terminal_window (0);      rotate_vector (current_screen->contents + from + amount,		     sizeof (char *) * (end - from - amount),		     (end - from) * sizeof (char *));      safe_bcopy (current_screen->used + from,		  current_screen->used + from + amount,		  (end - from) * sizeof current_screen->used[0]);      safe_bcopy (current_screen->highlight + from,		  current_screen->highlight + from + amount,		  (end - from) * sizeof current_screen->highlight[0]);      safe_bcopy (current_screen->enable + from,		  current_screen->enable + from + amount,		  (end - from) * sizeof current_screen->enable[0]);      /* Mark the lines made empty by scrolling as enabled, empty and	 normal video.  */      bzero (current_screen->used + end + amount,	     - amount * sizeof current_screen->used[0]);      bzero (current_screen->highlight + end + amount,	     - amount * sizeof current_screen->highlight[0]);      for (i = end + amount; i < end; i++)	{	  current_screen->contents[i][0] = '\0';	  current_screen->enable[i] = 1;	}    }  return 1;}/* Rotate a vector of SIZE bytes, by DISTANCE bytes.   DISTANCE may be negative.  */rotate_vector (vector, size, distance)     char *vector;     int size;     int distance;{  char *temp = (char *) alloca (size);  if (distance < 0)    distance += size;  bcopy (vector, temp + distance, size - distance);  bcopy (vector + size - distance, temp, distance);  bcopy (temp, vector, size);}/* Like bcopy except never gets confused by overlap.  */safe_bcopy (from, to, size)     char *from, *to;     int size;{  register char *endf;  register char *endt;  if (size == 0)    return;  if (from > to)    {      /* If destination is lower in memory, we can go from the beginning.  */      endf = from + size;      while (from != endf)	*to++ = *from++;      return;    }  /* If destination is higher in memory, we can go backwards from the end.  */  endf = from + size;  endt = to + size;  do    *--endt = *--endf;  while (endf != from);}/* After updating a window w that isn't the full screen wide, copy all the columns that w does not occupy from current_screen to new_screen, so that update_screen will not change those columns.  */preserve_other_columns (w)     struct window *w;{  register int vpos;  int start = XFASTINT (w->left);  int end = XFASTINT (w->left) + XFASTINT (w->width);  int bot = XFASTINT (w->top) + XFASTINT (w->height);  for (vpos = XFASTINT (w->top); vpos < bot; vpos++)    {      if (current_screen->enable[vpos] && new_screen->enable[vpos])	{	  if (start > 0)	    {	      int len;	      bcopy (current_screen->contents[vpos],		     new_screen->contents[vpos], start);	      len = min (start, current_screen->used[vpos]);	      if (new_screen->used[vpos] < len)		new_screen->used[vpos] = len;	    }	  if (current_screen->used[vpos] > end	      && new_screen->used[vpos] < current_screen->used[vpos])	    {	      while (new_screen->used[vpos] < end)		new_screen->contents[vpos][new_screen->used[vpos]++] = ' ';	      bcopy (current_screen->contents[vpos] + end,		     new_screen->contents[vpos] + end,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -