/* BEGIN DOCUMENTATION Name: TCMEDIT.C Created: 07/20/83 DTS. Last Update: 05/21/84 Title: Text collection management edit subroutine. Index: Abstract: Implements "TCOLL" function of TCM system Usage: Parameters: Environment: DECUS C, RSX11M V4.0 See Also: TCM.C, TCMTABLES.C, TCMEDFUNC.C, TCM.DOC Description: Uses window buffer returned by fndwnd() to do editing in. Loops adding characters & word - wrapping if nec. until buffer is full or user presses a done editing key. Example(s): Uses: Internal: Update History: 01/19/84 DTS - Changed use of srbuf fields including srbuf.opflag from single character to bit encoded character. END DOCUMENTATION */ #include #include #include #include "tcmdefs.h" #include "tcmerr.h" #include "tcmpublic.h" #include "tcmedopt.h" /* External globals */ extern int timeout; /* Defined in TCMINPUT module */ extern int linevir; /* Defined in TCMSCRN module */ /* #define debug 0 */ /* Forward references */ extern padlin(); /*** Edit window on screen (TCOLL) ***/ edit() { register struct twindcb *win; register int c; register char *nxt; boolean funcall; funcpointer edfun; /*** Initialize editing session ***/ iff (win = fndwnd()) == NULL then /* Set window from name */ { ret.cd = TE_NSW; return; } /* exit edit if not found */ curwin = win; c = (int) srbuf.opflag; coldisp = ifx (c & STATLIN) != 0 thenx true elsex false; rdonly = ifx (c & READOLY) != 0 thenx true elsex false; iff (c & INSRT) != 0 then insert = true; win->column = ifx srbuf.col > 0 thenx srbuf.col elsex win->width; c = ifx (srbuf.row > 0) and (srbuf.row < win->botline) thenx srbuf.row elsex win->botline; win->edline = fndlin(win->bufstart,win->bufend,c); iff (win->topline > c) or (win->topline + win->height <= c) then /* on screen */ win->topline = ifx (c -= win->height) > 0 thenx (c+1) elsex 1; c = virlen(win->edline) + 1; iff win->column > c then win->column = c; errlvl = srbuf.virt_lines; timeout = srbuf.max_chars; attach(TLUN); /* Attach terminal (TI:) for input */ setout(win); /* Init screen output */ setscroll(top,bot); eddone = funcall = false; nxt = getlin(win->edline); /* Init edit line */ rdastinit(TLUN,RDFLAG); /* Init read ast routine, input from TI: */ /* Loop while editing window */ /* Process all input before refreshing screen */ repeat { ret.cd = TS_SUC; refresh(); /* Refresh screen if changed */ rfstat(); wtse(RDFLAG); /* Wait for next input */ while((c = inchar()) != EOF) { iff lin[vtlin].fircol == tempmsg then lin[vtlin].fircol = newlin; ret.term = c; /* Return last character */ iff c == NULL then { doo nothing; } else iff c >= 127 then { funcall = true; /* process function key */ edfun = edfunc[c-127]; nxt = (*edfun)(nxt); } else iff ! (rdonly) then { /* Add character to line */ iff funcall != false then { /*** commented out, not yet implemented nxt = insenhan(nxt); * insert enhancements * ***/ funcall = false; /* Once per line only */ } rfline(bufcol,nxt-line,nxt-line); /* Mark char on screen */ iff nxt >= &line[lin[0].len] then /* pad with spaces */ padlin(nxt); iff insert then /* make room for character */ { iff addchr() then moveup(nxt,nxt+1, &line[lin[0].len]-nxt); rfline(bufcol+1,nxt-line,lin[0].len - 1); /* Redisplay to end */ } else iff nxt == &line[lin[0].len-1] then addchr(); /* Increment line length */ iff ret.cd == TS_SUC then { bufcol++; *nxt++ = c; } /* not full, add char */ iff bufcol > (win->width + 1) then nxt = wdwrap(win); /* Type past end, word wrap */ else iff linevir > win->width then nxt = inewln(nxt); /* Insert overflow, insert new line */ iff linevir > win->width then /* Must have filled buffer */ nxt = deleft(nxt); /* Undo character insert */ } else tcmerr(TS_IKY); } } untill(eddone)); /* Terminate editing session */ savlin(win); /* Save current line */ win->edlinnum = ret.bline = bufline; /* Return line & column to caller */ ret.bcol = bufcol; scerln(vtlin,1); #ifdef debug sprintf(&temp,"Line = %d, Column = %d, Terminator = %d.",ret.bline,ret.bcol,ret.term); scout(vtlin,1,temp); scout(curline,curcol,NULL); #endif rstout(win); /* Clear output buffer */ curwin = NULL; errlvl = 0; /* Restored for other routines */ detach(TLUN); /* Detach terminal */ } /* end edit */ /*** Wrap last word on line to next line ***/ /* Returns pointer to end of new line */ /* Changes curline, bufline, & bufcol globals */ charpointer wdwrap(win) register struct twindcb *win; { register charpointer cptr; register int c,i; for(c=0,cptr=line,i=-1; c < lin[0].len; c++) iff *cptr++ == ' ' then i = c; cptr -= 2; /* Last char on line */ iff i < 0 then /* Word too long for line */ { tcmerr(TS_WTL); subchr(); bufcol--; /* Delete added character */ *cptr = eos; return(cptr); } iff !addlin() then { subchr(); bufcol--; /* buffer full, delete char */ *cptr = eos; return(cptr); } line[i] = '\r'; /* mark end of first line */ savlin(win); /* Move line & partial word into buffer */ iff i > lin[curline].len then i = lin[curline].len; /* (Should not happen!) Must be in current line */ cptr = win->edline + i; *cptr = eos; /* Break line in two */ lin[curline].len = strlen(win->edline) + 1; lin[curline].laschr = win->width; lin[curline].fircol = bufcol; lin[curline].firchr = lin[curline].len - 1; win->edline = ++cptr; iff curline < bot then { curline++; /* Advance to new line */ inslin(); /* Insert line on screen */ } else { win->topline++; scrlup(); /* scroll current window up */ } bufline++; bufcol = virlen(win->edline) + 1; /* Doesn't count enhanced chars */ return(getlin(win->edline)); /* Restore 2nd half as new line */ } /* end wdwrap */ /*** PADLIN: When beyond end, Pad current line with spaces, extend to pointer ***/ padlin(nxt) register charpointer nxt; { register charpointer lnend; rfline(linevir+1,lin[0].len-1,lin[0].len); /* Show new spaces on screen */ lnend = &line[lin[0].len]; lnend--; while((nxt > lnend) and addchr()) /* pad with spaces */ *lnend++ = ' '; line[lin[0].len - 1] = eos; /* Mark end of line */ } /* end padlin */