/* BEGIN DOCUMENTATION Name: TCMTINS.C Created: 05/11/84 DTS Last Update: 05/18/84 Title: Text collection management text insert function. Index: TCM text editor Abstract: Implements "TXTINS" function of TCM to add text to an existing "window" on the screen. Usage: See "TCM.DOC" Parameters: srbuf.row & srbuf.col has position to insert text. Environment: RSX11M V4.0, DECUS C Compiler See Also: TCM.C, TCMPTXTIN.C, TCMCREATE.C, TCM.DOC Description: Inserts text at given cursor location into named text window. Calls function to re-display text on screen. Example(s): See "TCM.DOC" Uses: Internal: Makes room for maximum amount of text at current cursor location receives text or file name from remote task & then closes text buffer. Update History: END DOCUMENTATION */ /* #define debug 0 */ #include #include #include #include "tcmdefs.h" #include "tcmerr.h" #include "tcmpublic.h" #include "tcmedopt.h" /* Forward reference */ extern boolean wrapline(); /*** (TXTINS) Text Insertion: Add text to window buffer ***/ txtins() { register struct twindcb *win; register int emptyspc,cnt; charpointer bufptr,oldstart,oldend; int oldbot,oldmax,spacecnt; static int ccount; iff (win = fndwnd()) == NULL then { ccount = 0; bufptr = line; /* Point somewhere */ ret.cd = TE_NSW; } else { ret.cd = TS_SUC; /* Default to successful */ oldstart = win->bufstart; /* Save current window buffer state */ oldend = win->bufend; oldbot = win->botline; oldmax = win->curmax; cnt = ifx (srbuf.row > 0) thenx srbuf.row elsex win->edlinnum; iff cnt > oldbot then cnt = oldbot; iff win->edlinnum != cnt then { win->edline = fndlin(oldstart,oldend,cnt); /* Point to selected line */ win->edlinnum = cnt; } win->column = ifx (srbuf.col > 0) and (srbuf.col < win->width) thenx srbuf.col elsex win->width - 1; cnt = virlen(win->edline) + 1; spacecnt = ifx win->column > cnt thenx win->column - cnt elsex 0; /* Count of pad chars */ bufptr = virchr(win->edline,win->column - spacecnt); /* Point to insert location */ emptyspc = oldend - oldstart; ccount = emptyspc = (emptyspc - oldmax); /* Room available in buffer */ iff (emptyspc > 1) and (bufptr < (oldstart + oldmax)) then { cnt = bufptr - oldstart; cnt = oldmax - cnt; /* Char count from bufptr to end */ moveup(bufptr,bufptr+emptyspc,cnt); /* Make room in contiguous buffer */ while ((spacecnt-- > 0) and (emptyspc > 0)) { *bufptr++ = ' '; /* Pad line with spaces */ emptyspc--; oldmax++; } ccount = emptyspc; /* Space still open */ } else { bufptr = oldstart + oldmax; /* End of text in buffer */ emptyspc = ifx oldend > bufptr thenx oldend - bufptr elsex 0; cnt = 0; /* No char move */ } } iff vrecv(&mastsk,bufptr,&ccount) != IS_SUC then /* Always receive */ error("TXTINS: RCV error"); iff ret.cd == TS_SUC then { win->bufend = bufptr + emptyspc; win->botline = 1; iff *bufptr == '@' then win->bufstart = bufptr; else { win->bufstart = win->edline; /* Set buffer to opened area */ ccount += (int) (bufptr - win->edline); /* put current line in buffer */ oldmax -= (int) (bufptr - win->edline); /* don't chars count twice */ bufptr = win->edline; } inittext(win,ccount); /* Initialize new text in buffer */ #ifdef debug sprintf(temp,"New text = '%s' empty = %d, new = %d, moved chars = %d",bufptr,emptyspc,ccount,cnt); scout(vtlin,1,temp); scout(0,0,NULL); lin[vtlin].fircol = tempmsg; #endif ccount = win->curmax - 2; /* number of new characters */ iff (oldmax + ccount) > win->max_chars then tcmerr(TS_BFP); /* Buffer full */ else iff (win->botline + oldbot - 1) > win->virt_lines then tcmerr(TS_MCP); iff (ret.cd == TS_SUC) then /* Count new text */ { iff wrapline(&(win->edline),win->width) then /* Test for line wrap */ win->botline++; win->edline = fndlin(win->edline,win->bufend,win->botline); ret.bcol = win->column = virlen(win->edline) + 1; iff cnt > 0 then movedn(win->bufend, bufptr+ccount, cnt); /* Close buffer */ win->edlinnum += (win->botline - 1); /* End of insert */ bufptr = win->edline; iff wrapline(&bufptr,win->width) then /* Test for line wrap */ win->botline++; win->botline += (oldbot - 1); win->curmax = oldmax + ccount; } else /* restore entire buffer, undo insert */ { win->botline = oldbot; win->curmax = oldmax; ret.bcol = win->column; iff cnt > 0 then movedn(win->bufend,bufptr,cnt); } ret.bline = win->edlinnum; win->bufstart = oldstart; /* Restore buffer pointers */ win->bufend = oldend; } iff ret.cd == TS_SUC then /* add iniout() ? */ { lin[curline].fircol = newlin; setout(win); } iff ret.cd == TS_SUC then { lin[curline].fircol = newlin; /* Redisplay current line */ refresh(); /* Display window changes */ rstout(win); } } /* end txtins */ /*** WRAPLINE: Break line at last space, or right column ***/ boolean /* Return true if line wrapped, else false */ wrapline(lptr,lwid) register charpointer *lptr; /* Line pointer, set to 2nd half if line wrapped */ int lwid; /* Maximum allowed width */ { register charpointer p,sp; iff virlen(*lptr) > lwid then { /* Break line */ sp = virchr(*lptr,lwid); for (p = sp; p > *lptr; p--) { iff *p == ' ' then /* At last space */ {sp = p; break;} } *sp++ = eos; *lptr = sp; return(true); } else return(false); } /* end wrapline */