/* BEGIN DOCUMENTATION Name: TCMCREATE.C Created: 7/20/83 DTS Last Update: 04/23/84 Title: Text collection management system slave task. Index: TCM text editor Abstract: Implements "TWINCR" function of TCM to allocate and initialize a rectangular "window" on the screen. Usage: See "TCM.DOC" Parameters: Environment: RSX11M V4.0, DECUS C Compiler See Also: TCM.C, TCMPLI.C, TCMSCRN.C, TCM.DOC Description: Allocates space for tcm window (TWINDCB & buffer) and initializes all parameters in text window control block. Does not call refresh function to display text on screen. Example(s): See "TCM.DOC" Uses: Internal: Window control blocks are a linked list pointed to by "twindroot" and linked via win.twinptr. "malloc" and "mfree" are used to allocate & free memory. Update History: END DOCUMENTATION */ #include #include #include #include "tcmdefs.h" #include "tcmerr.h" #include "tcmpublic.h" #include "tcmedopt.h" /*** (TWINCR) Create Window: allocate & initialize twindcb & buffer ***/ create() { register struct twindcb *wptr; register int siz,i,optn; charpointer bufptr; /* allocate window */ ret.cd = TS_SUC; /* default to good */ bufptr = &temp; /* Point somewhere */ siz = sizeof(temp) - 1; optn = (int) srbuf.opflag; iff (optn & BORDER) != 0 then { srbuf.height -= 2; srbuf.width -= 2; srbuf.row += 1; srbuf.col += 1; } iff (wptr = fndwnd()) != NULL then /* replace existing window */ mfree(wptr->bufstart); /* Free up buffer */ else iff srbuf.height < 1 then ret.cd = TE_BDH; else iff srbuf.width < 2 then ret.cd = TE_BDW; else iff (wptr = malloc(sizeof(struct twindcb))) != NULL then { wptr->twinptr = twinroot; /* Put new window on list */ twinroot = wptr; wptr->fillchr = ' '; /* Default to blank background */ } else ret.cd = TE_IDS; /* Insuff. dynamic storage */ /* Allocate buffer */ iff ret.cd == TS_SUC then { i = ifx srbuf.width <= 0 thenx wptr->width elsex srbuf.width; iff srbuf.max_chars == 0 then srbuf.max_chars = srbuf.virt_lines * (i + 4); /* End of line + extra for esc sequences */ siz = srbuf.max_chars * sizeof(char); iff (bufptr = malloc(siz)) == NULL then { bufptr = &temp; siz = sizeof(temp) - 1; ret.cd = TE_IDS; twinroot = wptr->twinptr; /* Undo window allocation */ mfree(wptr); } else /* Set buffer pointer */ wptr->bufstart = bufptr; } iff (optn & INITEXT) != 0 then { /* Receive data or file name (always) */ count = siz - 2; iff vrecv(&mastsk,bufptr,&count) != IS_SUC then error("Receive data error"); } iff ret.cd == TS_SUC then { /* Initialize control block */ iff (optn & BORDER) != 0 then wptr->border = true; else wptr->border = false; iff srbuf.row > 0 then wptr->row = srbuf.row; iff srbuf.col > 0 then wptr->col = srbuf.col; iff srbuf.height > 0 then wptr->height = srbuf.height; iff srbuf.width > 0 then wptr->width = srbuf.width; iff srbuf.virt_lines > 0 then wptr->virt_lines = srbuf.virt_lines; iff srbuf.fillchr != eos then wptr->fillchr = srbuf.fillchr; strcpy(wptr->name,srbuf.name); wptr->max_chars = srbuf.max_chars; { wptr->bufend = wptr->bufstart + siz; wptr->edline = wptr->bufstart; wptr->column = 1; wptr->scroll = (wptr->height * 2) / 3; wptr->topline = wptr->botline = 1; wptr->edlinnum = 1; wptr->curmax = 2; iff (optn & INITEXT) != 0 then inittext(wptr,count); else { *wptr->bufstart++ = eos; /* Clear buffer */ *wptr->bufstart-- = line[0] = eos; } iff ret.cd == TS_SUC then { iniout(); setout(wptr); } iff ret.cd == TS_SUC then { refresh(); /* Display (clear) window */ rstout(wptr); } else delwind(wptr); } } } /* end create */ /*** Initialize text buffer with default data ***/ inittext(win,txtlen) register struct twindcb *win; int txtlen; { register charpointer s; register int slen,linelen,linecnt,maxlen; charpointer spptr; s = win->bufstart; iff *s++ == '@' then { *(s + txtlen - 1) = eos; /* Mark end of file name */ count = (win->bufend - win->bufstart) - 2; /* Buffer size */ ret.cd = tcmget(s,&(win->file),win->bufstart,&count); txtlen = count - 1; /* Remove last newline */ } iff ret.cd == TS_SUC then { win->curmax = txtlen + 2; /* Change to NULL & mark end */ linecnt = linelen = 1; /* init line count */ spptr = NULL; maxlen = win->width; for (slen = 1,s = win->bufstart; slen <= txtlen; slen++, s++) /* s++ should be s = nxtchr(s); for enhancements */ { iff (*s == '\t') then *s = ' '; /* Change tabs to spaces */ iff (*s == ' ') then spptr = s; iff (*s == '\r') or (*s == '\n') then *s = eos; else iff linelen++ > maxlen then /* Break line if too long */ { iff spptr != NULL then { slen -= (s - spptr); /* Backup up & */ s = spptr; /* break at word if possible */ } *s = eos; } iff *s == eos then { linecnt++; linelen = 1; spptr = NULL; } } *s++ = eos; *s = eos; /* Mark end with extra EOS */ win->botline = linecnt; s = fndlast(--s,win->bufstart); /* Last line in buffer */ } else ret.dsw = $dsw; } /* end inittext */ /*** (TWINDE) Delete window & free up space ***/ windel() { register struct twindcb *win; register struct twindcb *last; ret.cd = TS_SUC; /* default */ last = NULL; /* Set window from name */ for(win = twinroot; win != NULL;win = win->twinptr) { iff streq(win->name,srbuf.name) then loopexit; last = win; } iff win == NULL then /* Name not found */ ret.cd = TE_NSW; else { tcmcls(&(win->file)); /* Close associated file if open */ iff last == NULL then twinroot = win->twinptr; /* remove from list */ else last->twinptr = win->twinptr; delwind(win); /* Free up memory */ } } /* end windel */ /*** Free memory from deleted text window ***/ delwind(wptr) struct twindcb *wptr; { mfree(wptr->bufstart); /* Deallocate buffer memory */ mfree(wptr); /* Deallocate twindcb */ } /* end delwind */