/* * updupd: * update the physical screen from the virtual screen * * int force; forced update flag */ int updupd(int force) { struct video *vp1; int i; #if SCROLLCODE if (scrflags & WFKILLS) scrolls(FALSE); if (scrflags & WFINS) scrolls(TRUE); scrflags = 0; #endif for (i = 0; i < term.t_nrow; ++i) { vp1 = vscreen[i]; /* for each line that needs to be updated */ if ((vp1->v_flag & VFCHG) != 0) { #if TYPEAH && ! PKCODE if (force == FALSE && typahead()) return TRUE; #endif #if MEMMAP && ! SCROLLCODE updateline(i, vp1); #else updateline(i, vp1, pscreen[i]); #endif } } return TRUE; }
// Transfer the virtual screen to the physical screen. Force it if "force" is true. Return status. static int pupd_all(bool force) { Video *vp; int i,count; for(i = 0; i < (int) term.t_nrow - 1; ++i) { // Exclude message line. vp = vscreen[i]; // For each line that needs to be updated. if(vp->v_flags & VFCHGD) { #if TYPEAH if(!force) { if(typahead(&count) != SUCCESS) return rc.status; if(count > 0) return rc.status; } #endif if(pupd_line(i,vp,pscreen[i]) != SUCCESS) return rc.status; } } return rc.status; }
int main(int argc, char **argv) { int c = -1; /* command character */ int f; /* default flag */ int n; /* numeric repeat count */ int mflag; /* negative flag on repeat */ struct buffer *bp; /* temp buffer pointer */ int firstfile; /* first file flag */ int carg; /* current arg to scan */ int startflag; /* startup executed flag */ struct buffer *firstbp = NULL; /* ptr to first buffer in cmd line */ int basec; /* c stripped of meta character */ int viewflag; /* are we starting in view mode? */ int gotoflag; /* do we need to goto a line at start? */ int gline = 0; /* if so, what line? */ int searchflag; /* Do we need to search at start? */ int saveflag; /* temp store for lastflag */ int errflag; /* C error processing? */ char bname[NBUFN]; /* buffer name of file to read */ #if CRYPT int cryptflag; /* encrypting on the way in? */ char ekey[NPAT]; /* startup encryption key */ #endif int newc; #if PKCODE & VMS (void) umask(-1); /* Use old protection (this is at wrong place). */ #endif #if PKCODE & BSD sleep(1); /* Time for window manager. */ #endif #if UNIX #ifdef SIGWINCH signal(SIGWINCH, sizesignal); #endif #endif if (argc == 2) { if (strcmp(argv[1], "--help") == 0) { usage(EXIT_FAILURE); } if (strcmp(argv[1], "--version") == 0) { version(); exit(EXIT_SUCCESS); } } /* Initialize the editor. */ vtinit(); /* Display */ edinit("main"); /* Buffers, windows */ varinit(); /* user variables */ viewflag = FALSE; /* view mode defaults off in command line */ gotoflag = FALSE; /* set to off to begin with */ searchflag = FALSE; /* set to off to begin with */ firstfile = TRUE; /* no file to edit yet */ startflag = FALSE; /* startup file not executed yet */ errflag = FALSE; /* not doing C error parsing */ #if CRYPT cryptflag = FALSE; /* no encryption by default */ #endif /* Parse the command line */ for (carg = 1; carg < argc; ++carg) { /* Process Switches */ #if PKCODE if (argv[carg][0] == '+') { gotoflag = TRUE; gline = atoi(&argv[carg][1]); } else #endif if (argv[carg][0] == '-') { switch (argv[carg][1]) { /* Process Startup macroes */ case 'a': /* process error file */ case 'A': errflag = TRUE; break; case 'e': /* -e for Edit file */ case 'E': viewflag = FALSE; break; case 'g': /* -g for initial goto */ case 'G': gotoflag = TRUE; gline = atoi(&argv[carg][2]); break; #if CRYPT case 'k': /* -k<key> for code key */ case 'K': cryptflag = TRUE; strcpy(ekey, &argv[carg][2]); break; #endif #if PKCODE case 'n': /* -n accept null chars */ case 'N': nullflag = TRUE; break; #endif case 'r': /* -r restrictive use */ case 'R': restflag = TRUE; break; case 's': /* -s for initial search string */ case 'S': searchflag = TRUE; strncpy(pat, &argv[carg][2], NPAT); break; case 'v': /* -v for View File */ case 'V': viewflag = TRUE; break; default: /* unknown switch */ /* ignore this for now */ break; } } else if (argv[carg][0] == '@') { /* Process Startup macroes */ if (startup(&argv[carg][1]) == TRUE) /* don't execute emacs.rc */ startflag = TRUE; } else { /* Process an input file */ /* set up a buffer for this file */ makename(bname, argv[carg]); unqname(bname); /* set this to inactive */ bp = bfind(bname, TRUE, 0); strcpy(bp->b_fname, argv[carg]); bp->b_active = FALSE; if (firstfile) { firstbp = bp; firstfile = FALSE; } /* set the modes appropriatly */ if (viewflag) bp->b_mode |= MDVIEW; #if CRYPT if (cryptflag) { bp->b_mode |= MDCRYPT; myencrypt((char *) NULL, 0); myencrypt(ekey, strlen(ekey)); strncpy(bp->b_key, ekey, NPAT); } #endif } } #if UNIX signal(SIGHUP, emergencyexit); signal(SIGTERM, emergencyexit); #endif /* if we are C error parsing... run it! */ if (errflag) { if (startup("error.cmd") == TRUE) startflag = TRUE; } /* if invoked with no other startup files, run the system startup file here */ if (startflag == FALSE) { startup(""); startflag = TRUE; } discmd = TRUE; /* P.K. */ /* if there are any files to read, read the first one! */ bp = bfind("main", FALSE, 0); if (firstfile == FALSE && (gflags & GFREAD)) { swbuffer(firstbp); zotbuf(bp); } else bp->b_mode |= gmode; /* Deal with startup gotos and searches */ if (gotoflag && searchflag) { update(FALSE); mlwrite("(Can not search and goto at the same time!)"); } else if (gotoflag) { if (gotoline(TRUE, gline) == FALSE) { update(FALSE); mlwrite("(Bogus goto argument)"); } } else if (searchflag) { if (forwhunt(FALSE, 0) == FALSE) update(FALSE); } /* Setup to process commands. */ lastflag = 0; /* Fake last flags. */ loop: /* Execute the "command" macro...normally null. */ saveflag = lastflag; /* Preserve lastflag through this. */ execute(META | SPEC | 'C', FALSE, 1); lastflag = saveflag; #if TYPEAH && PKCODE if (typahead()) { newc = getcmd(); update(FALSE); do { fn_t execfunc; if (c == newc && (execfunc = getbind(c)) != NULL && execfunc != insert_newline && execfunc != insert_tab) newc = getcmd(); else break; } while (typahead()); c = newc; } else { update(FALSE); c = getcmd(); } #else /* Fix up the screen */ update(FALSE); /* get the next command from the keyboard */ c = getcmd(); #endif /* if there is something on the command line, clear it */ if (mpresf != FALSE) { mlerase(); update(FALSE); #if CLRMSG if (c == ' ') /* ITS EMACS does this */ goto loop; #endif } f = FALSE; n = 1; /* do META-# processing if needed */ basec = c & ~META; /* strip meta char off if there */ if ((c & META) && ((basec >= '0' && basec <= '9') || basec == '-')) { f = TRUE; /* there is a # arg */ n = 0; /* start with a zero default */ mflag = 1; /* current minus flag */ c = basec; /* strip the META */ while ((c >= '0' && c <= '9') || (c == '-')) { if (c == '-') { /* already hit a minus or digit? */ if ((mflag == -1) || (n != 0)) break; mflag = -1; } else { n = n * 10 + (c - '0'); } if ((n == 0) && (mflag == -1)) /* lonely - */ mlwrite("Arg:"); else mlwrite("Arg: %d", n * mflag); c = getcmd(); /* get the next key */ } n = n * mflag; /* figure in the sign */ } /* do ^U repeat argument processing */ if (c == reptc) { /* ^U, start argument */ f = TRUE; n = 4; /* with argument of 4 */ mflag = 0; /* that can be discarded. */ mlwrite("Arg: 4"); while (((c = getcmd()) >= '0' && c <= '9') || c == reptc || c == '-') { if (c == reptc) if ((n > 0) == ((n * 4) > 0)) n = n * 4; else n = 1; /* * If dash, and start of argument string, set arg. * to -1. Otherwise, insert it. */ else if (c == '-') { if (mflag) break; n = 0; mflag = -1; } /* * If first digit entered, replace previous argument * with digit and set sign. Otherwise, append to arg. */ else { if (!mflag) { n = 0; mflag = 1; } n = 10 * n + c - '0'; } mlwrite("Arg: %d", (mflag >= 0) ? n : (n ? -n : -1)); } /* * Make arguments preceded by a minus sign negative and change * the special argument "^U -" to an effective "^U -1". */ if (mflag == -1) { if (n == 0) n++; n = -n; } } /* and execute the command */ execute(c, f, n); goto loop; }
/* * Make sure that the display is right. This is a three part process. First, * scan through all of the windows looking for dirty ones. Check the framing, * and refresh the screen. Second, make sure that "currow" and "curcol" are * correct for the current window. Third, make the virtual and physical * screens the same. * * int force; force update past type ahead? */ int update(int force) { struct window *wp; #if TYPEAH && ! PKCODE if (force == FALSE && typahead()) return TRUE; #endif #if VISMAC == 0 if (force == FALSE && kbdmode == PLAY) return TRUE; #endif displaying = TRUE; #if SCROLLCODE /* first, propagate mode line changes to all instances of a buffer displayed in more than one window */ wp = wheadp; while (wp != NULL) { if (wp->w_flag & WFMODE) { if (wp->w_bufp->b_nwnd > 1) { /* make sure all previous windows have this */ struct window *owp; owp = wheadp; while (owp != NULL) { if (owp->w_bufp == wp->w_bufp) owp->w_flag |= WFMODE; owp = owp->w_wndp; } } } wp = wp->w_wndp; } #endif /* update any windows that need refreshing */ wp = wheadp; while (wp != NULL) { if (wp->w_flag) { /* if the window has changed, service it */ reframe(wp); /* check the framing */ #if SCROLLCODE if (wp->w_flag & (WFKILLS | WFINS)) { scrflags |= (wp->w_flag & (WFINS | WFKILLS)); wp->w_flag &= ~(WFKILLS | WFINS); } #endif if ((wp->w_flag & ~WFMODE) == WFEDIT) updone(wp); /* update EDITed line */ else if (wp->w_flag & ~WFMOVE) updall(wp); /* update all lines */ #if SCROLLCODE if (scrflags || (wp->w_flag & WFMODE)) #else if (wp->w_flag & WFMODE) #endif modeline(wp); /* update modeline */ wp->w_flag = 0; wp->w_force = 0; } /* on to the next window */ wp = wp->w_wndp; } /* recalc the current hardware cursor location */ updpos(); #if MEMMAP && ! SCROLLCODE /* update the cursor and flush the buffers */ movecursor(currow, curcol - lbound); #endif /* check for lines to de-extend */ upddex(); /* if screen is garbage, re-plot it */ if (sgarbf != FALSE) updgar(); /* update the virtual screen to the physical screen */ updupd(force); /* update the cursor and flush the buffers */ movecursor(currow, curcol - lbound); TTflush(); displaying = FALSE; #if SIGWINCH while (chg_width || chg_height) newscreensize(chg_height, chg_width); #endif return TRUE; }
/* * gtenv() * * char *vname; name of environment variable to retrieve */ char *gtenv(char *vname) { int vnum; /* ordinal number of var refrenced */ /* scan the list, looking for the referenced name */ for (vnum = 0; vnum < ARRAY_SIZE(envars); vnum++) if (strcmp(vname, envars[vnum]) == 0) break; /* return errorm on a bad reference */ if (vnum == ARRAY_SIZE(envars)) #if ENVFUNC { char *ename = getenv(vname); if (ename != NULL) return ename; else return errorm; } #else return errorm; #endif /* otherwise, fetch the appropriate value */ switch (vnum) { case EVFILLCOL: return itoa(fillcol); case EVPAGELEN: return itoa(term.t_nrow + 1); case EVCURCOL: return itoa(getccol(FALSE)); case EVCURLINE: return itoa(getcline()); case EVRAM: return itoa((int) (envram / 1024l)); case EVFLICKER: return ltos(flickcode); case EVCURWIDTH: return itoa(term.t_ncol); case EVCBUFNAME: return curbp->b_bname; case EVCFNAME: return curbp->b_fname; case EVSRES: return sres; case EVDEBUG: return ltos(macbug); case EVSTATUS: return ltos(cmdstatus); case EVPALETTE: return palstr; case EVASAVE: return itoa(gasave); case EVACOUNT: return itoa(gacount); case EVLASTKEY: return itoa(lastkey); case EVCURCHAR: return (curwp->w_dotp->l_used == curwp->w_doto ? itoa('\n') : itoa(lgetc(curwp->w_dotp, curwp->w_doto))); case EVDISCMD: return ltos(discmd); case EVVERSION: return VERSION; case EVPROGNAME: return PROGRAM_NAME_LONG; case EVSEED: return itoa(seed); case EVDISINP: return ltos(disinp); case EVWLINE: return itoa(curwp->w_ntrows); case EVCWLINE: return itoa(getwpos()); case EVTARGET: saveflag = lastflag; return itoa(curgoal); case EVSEARCH: return pat; case EVREPLACE: return rpat; case EVMATCH: return (patmatch == NULL) ? "" : patmatch; case EVKILL: return getkill(); case EVCMODE: return itoa(curbp->b_mode); case EVGMODE: return itoa(gmode); case EVTPAUSE: return itoa(term.t_pause); case EVPENDING: #if TYPEAH return ltos(typahead()); #else return falsem; #endif case EVLWIDTH: return itoa(llength(curwp->w_dotp)); case EVLINE: return getctext(); case EVGFLAGS: return itoa(gflags); case EVRVAL: return itoa(rval); case EVTAB: return itoa(tabmask + 1); case EVOVERLAP: return itoa(overlap); case EVSCROLLCOUNT: return itoa(scrollcount); #if SCROLLCODE case EVSCROLL: return ltos(term.t_scroll != NULL); #else case EVSCROLL: return ltos(0); #endif } exit(-12); /* again, we should never get here */ }
// Make sure that the display is right. This is a four-part process. First, resize the windows in the current screen to match // the current terminal dimensions if needed. Second, scan through all of the screen windows looking for dirty (flagged) ones. // Check the framing and refresh the lines. Third, make sure that "currow" and "curcol" are correct for the current window. // And fourth, make the virtual and physical screens the same. Return status. int update(bool force) { EWindow *winp; int count; #if TYPEAH || !VISMAC // If we are not forcing the update... if(!force) { #if TYPEAH // If there are keystrokes waiting to be processed, skip the update. if(typahead(&count) != SUCCESS || count > 0) return rc.status; #endif #if !VISMAC // If we are replaying a keyboard macro, don't bother keeping updated. if(kmacro.km_state == KMPLAY) return rc.status; #endif } #endif // Current screen dimensions wrong? if(cursp->s_flags) { // ESRESIZE set? EWindow *lastwp,*nextwp; int nrow; // Loop until vertical size of all windows matches terminal rows. do { // Does current screen need to grow vertically? if(term.t_nrow > cursp->s_nrow) { // Yes, go to the last window... winp = wnextis(NULL); // and enlarge it as needed. winp->w_nrows = (cursp->s_nrow = term.t_nrow) - winp->w_toprow - 2; winp->w_flags |= WFHARD | WFMODE; } // Does current screen need to shrink vertically? else if(term.t_nrow < cursp->s_nrow) { // Rebuild the window structure. nextwp = cursp->s_wheadp; lastwp = NULL; nrow = 0; do { winp = nextwp; nextwp = winp->w_nextp; // Get rid of window if it is too low. if(winp->w_toprow >= term.t_nrow - 2) { // Save the "face" parameters. --winp->w_bufp->b_nwind; wftobf(winp,winp->w_bufp); // Update curwp and lastwp if needed. if(winp == curwp) wswitch(wheadp); if(lastwp != NULL) lastwp->w_nextp = NULL; // Free the structure. free((void *) winp); winp = NULL; } else { // Need to change this window size? if(winp->w_toprow + winp->w_nrows - 1 >= term.t_nrow - 2) { winp->w_nrows = term.t_nrow - winp->w_toprow - 2; winp->w_flags |= WFHARD | WFMODE; } nrow += winp->w_nrows + 1; } lastwp = winp; } while(nextwp != NULL); cursp->s_nrow = nrow; } } while(cursp->s_nrow != term.t_nrow); // Update screen controls and mark screen for a redraw. cursp->s_ncol = term.t_ncol; cursp->s_flags = 0; opflags |= OPSCREDRAW; } // Check all windows and update any that need refreshing. winp = wheadp; do { if(winp->w_flags) { // The window has changed in some way: service it. if(wupd_reframe(winp) != SUCCESS) // Check the framing. return rc.status; if((winp->w_flags & ~WFMODE) == WFEDIT) vupd_dotline(winp); // Update EDITed line only. else if(winp->w_flags & ~WFMOVE) vupd_all(winp); // Update all lines. if(winp->w_flags & WFMODE) wupd_modeline(winp,NULL); // Update modeline. winp->w_flags = winp->w_force = 0; } // On to the next window. } while((winp = winp->w_nextp) != NULL); // Recalc the current hardware cursor location. wupd_cursor(); // Check for lines to de-extend. supd_dex(); // If screen is garbage, redraw it. if(opflags & OPSCREDRAW) { if(modetab[MDR_GLOBAL].flags & MDNOUPD) opflags &= ~OPSCREDRAW; else if(supd_redraw() != SUCCESS) return rc.status; } // Update the virtual screen to the physical screen. if(pupd_all(force) != SUCCESS) return rc.status; // Update the cursor position and flush the buffers. if(movecursor(currow,curcol - lbound) != SUCCESS || TTflush() != SUCCESS) return rc.status; #if MMDEBUG & DEBUG_SCRDUMP dumpscreens("Exiting update()"); #endif return rc.status; }