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

📄 eedisp.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
int lcnt;int ccol;{	register int col, i;	register SBBUF *sb;	int c;	char tmp[MAXCHAR*2];	/* MAXCHAR is enough, but *2 just in case */	col = ccol;	sb = (SBBUF *) cur_buf;	if((i = lcnt) > 0)		do {	if((c = sb_getc(sb)) == EOF)				break;			/* Check to see if we've run into an EOL */#if FX_EOLMODE			if(c == CR)			  {	if(eolcrlf(sb))				  {	if((c = sb_getc(sb)) == LF) /* EOL? */					/* Real EOL.  Fail unless point					** is between CR and LF, in which case					** we return 0 (left margin).					*/					    return (i==1 ? 0 : -1);					/* Stray CR, back up & fall thru */					if(c != EOF)						sb_backc(sb);					c = CR;				  }			  } else if (c == LF)			  {	if(!eolcrlf(sb))	/* Real EOL? */					return -1;	/* Yes, fail */				/* If EOL mode is CRLF then hitting a LF				** can only happen for stray LFs (the				** previous check for CR takes care of				** CRLFs, and we never start scanning				** from the middle of a CRLF.				** Drop thru to show stray LF.				*/			  }#else			if(c == LF)				return(-1);#endif /*-FX_EOLMODE*/			col += sctr(c, tmp, col);		  } while(--i);	if(col > scr_wd0)		return(-1);	return(col);}/* D_LUPD - called from command level to completely redisplay a *	specific line on the screen. */d_lupd(w, idx)struct window *w;		/* Window this line belongs to, if known */int idx;{	t_curpos(idx, 0);	t_docleol();		/* Zap physical screen line */	scr[idx]->sl_col = 0;	/* Reflect it on phys screen image */	if(w)			/* Mark window for updating */		w->w_redp |= RD_WINRES;	else redp(RD_WINDS);	/* No window given, assume global */	redp(RD_MOVE);		/* Cursor has moved */}/* Clear a window completely the "quickest possible way" */clear_wind(w)register struct window *w;{	register int i = w->w_pos;	/* Top line of window */	register int bot = i + w->w_ht;	/* Bottom line (plus 1) of window */	for ( ; i < bot; ++i)		d_lupd(w, i);		/* Zap that line */}/* FIX_WIND - Sets up window screen image.  Does not generate any *	terminal output, but completely specifies what the new screen *	image should look like. *	Only the following 4 flags (lumped together in RDS_DOFIX) *	provoke fix_wind to do something: *		RD_MOVE - cursor has moved, must make sure still within *			window, and select new one if not. *		RD_TMOD - Text has been changed somewhere. *		RD_FIXWIN - Something requested that fix_wind fix things. *			Normally this is set when a new w_topldot is set. *		RD_WINRES - Window needs to be completely regenerated. * Results: *	Verifies that the current dot for the window (w_dot) exists. * If it is past the end of buffer, it is reset to EOB, and if this is * the current window, also updates cur_dot.  Otherwise, w_dot is never * adjusted; it is fix_wind's responsibility to make sure that the window * displays w_dot. *	Verifies that current w_topldot setting will result in cursor * (specified by w_dot) appearing within window.  If not, resets w_topldot * to an appropriate value (1/3 of way down from top, unless * moving up in which case 1/3 of way up from bottom). *	Makes sure that sl_boff, sl_len, sl_flg, and sl_cont * are set properly for all lines in window.  SL_MOD is set * for any lines requiring screen updates; these lines * also have sl_nlin and sl_ncol properly set. *	Note that sl_line and sl_col are NOT updated or changed, because * the physical screen has not been altered! * *	Returns 0 if no physical screen updates are needed (other than *		cursor moving and mode line updating). *	Returns 1 if screen updates are needed; RD_UPDWIN is set in w_redp, *		indicating that UPD_WIND should be called. */fix_wind (win)struct window *win;{	register struct window *w;	register int i;	register struct scr_line *s;	chroff cdot, bdelta, updot, sdot, newz;	chroff savdot;	struct buffer *savbuf;	int bot, nlmod, savi, contf, ocontf, randomflg;	int newpct;	if(!(w = win))		return(0);	if(!(w->w_redp&RDS_DOFIX))	/* Anything we need to do? */		return(0);		/* Nope, just ignore */	/* Find current dot for this window, and set up other stuff */	cdot = (w == cur_win) ? cur_dot : w->w_dot;	bot = w->w_pos + w->w_ht;	savbuf = cur_buf;	cur_buf = w->w_buf;	savdot = e_dot();	nlmod = 0;			/* No screen image changes so far */	/* Dot (ie cursor) is before current top?  If so, must move	 * backwards to find a new topldot.  Note also that buffer may have	 * changed so that either cdot or topldot points past EOF.	 */	if(w->w_topldot > cdot)	  {	/* Yes, must search backwards scrht/3 screen lines */		/* from cdot in order to find topldot. */		/* Don't bother updating scr stuff beforehand since we'll		 * have to revise everything anyway and can do it on the fly.		 */		i = (ev_mvpct * w->w_ht) / 100;		goto skipdn;	finddn:	i = ((100 - ev_mvpct) * w->w_ht) / 100;	skipdn:	if(i <= 0) i = 1;	/* Ensure # is reasonable */		else if(i >= w->w_ht) i = w->w_ht-1;		e_go(cdot);		/* Start here (may normalize to EOF)*/		d_backup(i ? i : 1);	/* Try to back up cleverly */		w->w_topldot = e_dot();		randomflg = 0;		/* We have some idea where we are */	fixall:		/* Entry point for later recheck, with randomflg==1 */		newz = e_blen();		if(newz < cdot)		/* Part of buf may have gone away */		  {			/* So normalize dot to EOF */			w->w_dot = cdot = newz;			if(w == cur_win)	/* Special check for fixing */				cur_dot = newz;	/* up cur_dot too! */			goto finddn;	/* and get a new top-of-window loc */		  }	retry:	i = w->w_pos;		contf = 0;		s = 0;		for(; i < bot; i++)		  {	nlmod++;			fix_line(scr[i], s);	/* s = 0 the first time */			s = scr[i];#if FX_SOWIND			if(w->w_flags & W_STANDOUT)				s->sl_flg |= SL_NSO;			else s->sl_flg &= ~SL_NSO;#endif		  }		if(inwinp(w,cdot))	/* Ensure in window */			goto mdone;		if(randomflg)		/* If jumped randomly, */		  {	i = (ev_nwpct * w->w_ht) / 100;			goto skipdn;	/* Try to select new window */		  }		/* We tried to back up and went too far. */		if(cdot < w->w_topldot)	/* Verify place is ahead */		  {	errbarf("fix_wind failed");	/* Didn't back up?? */			goto finddn;		  }		/* Move down one line and try again */		if(w->w_ht > 1)			w->w_topldot = scr[w->w_pos+1]->sl_boff;		else		  {	s = scr[w->w_pos];			w->w_topldot = s->sl_boff + s->sl_len;		  }		e_go(w->w_topldot);		goto retry;	  }	/* At some future point, could separate out processing for	 * RD_WINRES and RD_FIXWIN.  Latter flag implies only w_topldot	 * has changed (new window selected).  Former implies whole	 * buffer has been munged, and everything is completely redone.	 */	if(w->w_redp&(RD_WINRES|RD_FIXWIN))	/* If re-figuring whole window */	  {	e_go(w->w_topldot);	/* Start here, and */		randomflg = 1;		/* set up flag saying random jump */		goto fixall;		/* and go crunch all lines. */	  }	if((w->w_redp&RD_TMOD)==0)	/* If claims no text mods, */	  {	if(inwinp(w,cdot)==0)	/* Just verify cursor loc. */			goto finddn;	/* Sigh.... */		newz = w->w_oldz;	/* Win, set up for exit. */		goto done;	  }	/* Here only when RD_TMOD is set, indicating changes are	 * between range variables.	 */	/* Find upper bound of any mods.  This is a little gross in the	 * speed dept and some faster way should perhaps be devised.	 * In particular the main loop should incrementally keep track of	 * buffer size, and should set a flag RD_TEXT if anything has	 * actually been changed.  Edit routines should have lots of	 * flags available to tell main loop more precisely what they did,	 * so main loop can take care of updating b/emod and stuff.	 */	if((newz = e_blen()) == 0)		goto finddn;		/* Ensure blank window is cleared */	bdelta = newz - w->w_oldz;	if((updot = newz) > w->w_emod)		updot -= w->w_emod;	if(bdelta == 0 && (updot == w->w_bmod))		goto inwinq;	/* Could also check for updot < w_topldot (changes above win)	 * or sl_boff+sl_len < w_bmod  (changes below win) but those	 * cases are probably pretty rare.	 */	/* First find line where changes start */	for(i = w->w_pos; i < bot; i++)	  {	s = scr[i];		if(w->w_bmod <= s->sl_boff)	/* Changes prior to this? */			break;	  }	if(i >= bot)			/* Test last line specially */	  {	if(w->w_bmod > (s->sl_boff + (chroff)s->sl_len))			goto inwinq;	/* Outside window */					/* Last line changed, hack it */	  }	if(i > w->w_pos			/* If we have a prev line */	  && (s->sl_len == 0		/* and we're at EOF, */	    || w->w_bmod != s->sl_boff	/* or not at start of line */	    || scr[i-1]->sl_cont))	/* or prev line is continuation */		s = scr[--i];		/* then it's prev line we want */	/* I has index for screen line changes begin on; S has ptr.	 * This piece of code handles case where buffer has been modified	 * starting at BMOD, and BDELTA chars have been inserted/deleted;	 * range of changes ends at UPDOT.	 */	savi = i;	while(++i < bot)		scr[i]->sl_boff += bdelta;	i = savi;	/* Now start with 1st changed line and start figuring new line	 * lengths.  Stop when hit end, or past updot and boff is correct	 * for start of line.	 */	/* can improve this by jumping out when past emod, and testing for	 * an EOL - then know stuff has to match someplace, so look for that.	 * could then simply update lengths or something?	 */	if(i > w->w_pos)	/* Find # cols already there from prev line*/		contf = scr[i-1]->sl_cont;	else contf = 0;	ocontf = 1;			/* Fake it so always update 1st line*/	e_go(sdot = s->sl_boff);	for(; i < bot; i++)	  {	s = scr[i];		if(updot <= sdot	/* If past changed stuff */		  && sdot == s->sl_boff	/* and locs are lined up */		  && contf == 0		/* and previous line clean */		  && ocontf == 0)	/* (both old and new images) */			break;		/* Then done. */		nlmod++;		ocontf = s->sl_cont;	/* Save old-image contf value */		fix_line(s, (i > w->w_pos) ? scr[i-1] : 0);#if FX_SOWIND		if(w->w_flags & W_STANDOUT)			s->sl_flg |= SL_NSO;		else s->sl_flg &= ~SL_NSO;#endif		sdot = e_dot();		contf = s->sl_cont;	/* Get new-image contf value */	  }	if(inwinp(w,cdot))	/* OK, screen fixed, see if cursor inside */		goto mdone;	goto finddn;	/* Test if still in window and dispatch appropriately */inwinq:	if(inwinp(w,cdot))		goto done;	else goto finddn;	/* Come here when done, after mods made to window.	 * Calculate new %-of-buffer position for window's view, and	 * see if it's changed from current %.	 */mdone:	if(w != cur_win) goto done;	/* If not current window, ignore */	s = scr[bot-1];	if((s->sl_boff + (chroff)s->sl_len) >= newz)		if(w->w_topldot) newpct = 150;	/* BOT */		else newpct = 200;		/* ALL */	else if(w->w_topldot == 0)		newpct = -1;			/* TOP */	else		/* NOTE: This won't work if topldot is huge */		newpct = (w->w_topldot*100)/newz;	/* nn% */	if(newpct != w->w_pct)		/* OK, now compare with old % */	  {	w->w_pct = newpct;	/* Different, must set and */		redp(RD_MODE);		/* invoke redisplay of mode line! */	  }done:	w->w_bmod = -1;		/* To indicate vars not set */	w->w_oldz = newz;	w->w_redp &= ~RDS_DOFIX;	/* Clear flags that invoked us */	if(nlmod)		w->w_redp |= RD_UPDWIN;	/* Say stuff to be updated */	e_go(savdot);	cur_buf = savbuf;	return(nlmod);}/* INWINP - Returns true if given dot is inside given window. */inwinp(win,cdot)struct window *win;chroff cdot;{	register struct scr_line *s;	register struct window *w;	chroff sdot;	w = win;	if(cdot < w->w_topldot)		return(0);	s = scr[(w->w_pos + w->w_ht) - 1];	sdot = s->sl_boff + (chroff)s->sl_len;	if(cdot < sdot)		return(1);		/* Yup, inside window. */	if(cdot > sdot)		return(0);	/* Dot is exactly at end of window, must check further. */	if(s->sl_len		/* If line exists, */	 && ((s->sl_flg&SL_EOL)	/* and ends in LF, */	    || s->sl_cont > 1))	/* or sl_cont > 1, lose. */		return(0);	return(1);		/* Else inside, win. */}/* * UPD_WIND *	If argument 0, assumes cur_win and DOESN'T interrupt if input *	detected. */upd_wind(win)struct window *win;{	register int i, n;	register struct scr_line *s;	struct window *w;	int top, bot, dspf, num, isave, noicost, nodcost, iline, dline;#if FX_SOWIND	int oldso;#endif#if IMAGEN	int origdspf;	char redpmsg[128];#endif /*IMAGEN*/	if((w=win)==0)		w = cur_win;	dspf = w->w_redp;		/* Get update flags for window */#if IMAGEN	origdspf = dspf;#endif /*IMAGEN*/	if(w == cur_win)		/* If updating current window, */		dspf |= rd_type;	/* merge in global flags */	if((dspf &= RDS_WINFLGS) == 0)	/* Well, it might happen sometimes */		goto zdone;	w->w_redp = dspf;	if(dspf&(RD_WINRES|RD_TMOD|RD_MOVE|RD_FIXWIN))	  {	fix_wind(w);		/* May set some flags, so */		dspf = w->w_redp;	/* get them back... */	  }	if((dspf&RD_UPDWIN)==0)		/* Must ask for update! */		goto zdone;#if IMAGEN	if (dbg_redp)	  {	sprintf(redpmsg,			"buffer: %14s, rd_type: %06o, w_redp: %06o, dspf: %06o",			w->w_buf->b_name, rd_type, origdspf, dspf);		barf2(redpmsg);	  }#endif /*IMAGEN*/	/* Assume screen structure set up by FIX_WIND, just go	 * effect change for every line modified.	 */#if FX_SOWIND	oldso = t_dostandout((w->w_flags&W_STANDOUT)? 1:0);#endif	top = w->w_pos;	bot = top + w->w_ht;	for(i = top; i < bot; ++i)	  if((s = scr[i])->sl_flg&SL_MOD)	  {	if(win && tinwait())	/* If OK, stop if any chars typed */		  {	tbufls();			w->w_redp = dspf;#if FX_SOWIND			t_dostandout(oldso);#endif			return(1);	/* Return immediately, say int'd */		  }		if(slineq(s,s))		/* Compare old with new */			goto ldone;	/* Lines equal, no update needed */	#if IMAGEN		/* If hint says redo entirely */

⌨️ 快捷键说明

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