home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1993
- * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- * Copyright (c) 1987 Oliver Laumann
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING); if not, write to the
- * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************
- */
-
- #include "rcs.h"
- RCS_ID("$Id: display.c,v 1.8 1993/07/21 15:43:02 mlschroe Exp $ FAU")
-
-
- #include <sys/types.h>
- #include <fcntl.h>
-
- #include "config.h"
- #include "screen.h"
- #include "extern.h"
-
- static void CountChars __P((int));
- static void PutChar __P((int));
- static int BlankResize __P((int, int));
-
-
- extern char *tgoto __P((char *, int, int));
-
- extern struct win *windows;
-
- extern int use_hardstatus;
- extern int MsgMinWait;
- extern int Z0width, Z1width;
- extern char *blank, *null;
-
- /*
- * tputs needs this to calculate the padding
- */
- #ifndef NEED_OSPEED
- extern
- #endif /* NEED_OSPEED */
- short ospeed;
-
-
- struct display *display, *displays;
-
- #ifndef MULTI
- struct display TheDisplay;
- #endif
-
-
- /*
- * The default values
- */
- int defobuflimit = OBUF_MAX;
- #ifdef AUTO_NUKE
- int defautonuke = 0;
- #endif
-
- /*
- * Default layer management
- */
-
- void
- DefProcess(bufp, lenp)
- char **bufp;
- int *lenp;
- {
- *bufp += *lenp;
- *lenp = 0;
- }
-
- void
- DefRedisplayLine(y, xs, xe, isblank)
- int y, xs, xe, isblank;
- {
- if (isblank == 0 && y >= 0)
- DefClearLine(y, xs, xe);
- }
-
- void
- DefClearLine(y, xs, xe)
- int y, xs, xe;
- {
- DisplayLine(null, null, null, blank, null, null, y, xs, xe);
- }
-
- /*ARGSUSED*/
- int
- DefRewrite(y, xs, xe, doit)
- int y, xs, xe, doit;
- {
- return EXPENSIVE;
- }
-
- void
- DefSetCursor()
- {
- GotoPos(0, 0);
- }
-
- /*ARGSUSED*/
- int
- DefResize(wi, he)
- int wi, he;
- {
- return -1;
- }
-
- void
- DefRestore()
- {
- InsertMode(0);
- ChangeScrollRegion(0, d_height - 1);
- KeypadMode(0);
- CursorkeysMode(0);
- SetAttrFont(0, ASCII);
- SetFlow(FLOW_NOW);
- }
-
- /*
- * Blank layer management
- */
-
- struct LayFuncs BlankLf =
- {
- DefProcess,
- 0,
- DefRedisplayLine,
- DefClearLine,
- DefRewrite,
- DefSetCursor,
- BlankResize,
- DefRestore
- };
-
- struct layer BlankLayer =
- {
- 0,
- 0,
- &BlankLf,
- 0
- };
-
- /*ARGSUSED*/
- static int
- BlankResize(wi, he)
- int wi, he;
- {
- return 0;
- }
-
-
- /*
- * Generate new display
- */
-
- struct display *
- MakeDisplay(uname, utty, term, fd, pid, Mode)
- char *uname, *utty, *term;
- int fd, pid;
- struct mode *Mode;
- {
- struct user **u;
-
- #ifdef MULTI
- if ((display = (struct display *)malloc(sizeof(*display))) == 0)
- return 0;
- bzero((char *) display, sizeof(*display));
- #else
- if (displays)
- return 0;
- display = &TheDisplay;
- #endif
- display->_d_next = displays;
- displays = display;
- d_flow = 1;
- d_userfd = fd;
- d_OldMode = *Mode;
- Resize_obuf(); /* Allocate memory for buffer */
- d_obufmax = defobuflimit;
- #ifdef AUTO_NUKE
- d_auto_nuke = defautonuke;
- #endif
- d_obufp = d_obuf;
- d_userpid = pid;
- #ifdef POSIX
- d_dospeed = (short) cfgetospeed(&d_OldMode.tio);
- #else
- # ifndef TERMIO
- d_dospeed = (short) d_OldMode.m_ttyb.sg_ospeed;
- # endif
- #endif
- debug1("New displays ospeed = %d\n", d_dospeed);
- strcpy(d_usertty, utty);
- strcpy(d_termname, term);
-
- if (!*(u = FindUserPtr(uname)) && UserAdd(uname, NULL, u))
- {
- FreeDisplay();
- return NULL; /* could not find or add user */
- }
- d_user = *u;
- d_lay = &BlankLayer;
- d_layfn = BlankLayer.l_layfn;
- return display;
- }
-
- void
- FreeDisplay()
- {
- #ifdef MULTI
- struct display *d, **dp;
-
- for (dp = &displays; (d = *dp) ; dp = &d->_d_next)
- if (d == display)
- break;
- ASSERT(d);
- if (d_status_lastmsg)
- free(d_status_lastmsg);
- # ifdef COPY_PASTE
- if (d_copybuffer)
- free(d_copybuffer);
- # endif
- if (d_obuf)
- free(d_obuf);
- *dp = display->_d_next;
- free(display);
- #else /* MULTI */
- ASSERT(display == displays);
- ASSERT(display == &TheDisplay);
- displays = 0;
- #endif /* MULTI */
- display = 0;
- }
-
- /*
- * if the adaptflag is on, we keep the size of this display, else
- * we may try to restore our old window sizes.
- */
- void
- InitTerm(adapt)
- int adapt;
- {
- ASSERT(display);
- d_top = d_bot = -1;
- PutStr(TI);
- PutStr(IS);
- /* Check for toggle */
- if (IM && strcmp(IM, EI))
- PutStr(EI);
- d_insert = 0;
- /* Check for toggle */
- if (KS && strcmp(KS, KE))
- PutStr(KE);
- d_keypad = 0;
- if (CCS && strcmp(CCS, CCE))
- PutStr(CCE);
- d_cursorkeys = 0;
- PutStr(CE0);
- d_font = ASCII;
- if (adapt == 0)
- ResizeDisplay(d_defwidth, d_defheight);
- ChangeScrollRegion(0, d_height - 1);
- d_x = d_y = 0;
- Flush();
- ClearDisplay();
- debug1("we %swant to adapt all our windows to the display\n",
- (adapt) ? "" : "don't ");
- /* In case the size was changed by a init sequence */
- CheckScreenSize((adapt) ? 2 : 0);
- }
-
- void
- FinitTerm()
- {
- ASSERT(display);
- ResizeDisplay(d_defwidth, d_defheight);
- DefRestore();
- SetAttrFont(0, ASCII);
- d_x = d_y = -1;
- GotoPos(0, d_height - 1);
- AddChar('\n');
- PutStr(TE);
- Flush();
- }
-
-
- void
- INSERTCHAR(c)
- int c;
- {
- ASSERT(display);
- if (!d_insert && d_x < d_width - 1)
- {
- if (IC || CIC)
- {
- if (IC)
- PutStr(IC);
- else
- CPutStr(CIC, 1);
- RAW_PUTCHAR(c);
- return;
- }
- InsertMode(1);
- if (!d_insert)
- {
- RefreshLine(d_y, d_x, d_width-1, 0);
- return;
- }
- }
- RAW_PUTCHAR(c);
- }
-
- void
- PUTCHAR(c)
- int c;
- {
- ASSERT(display);
- if (d_insert && d_x < d_width - 1)
- InsertMode(0);
- RAW_PUTCHAR(c);
- }
-
- void
- PUTCHARLP(c)
- int c;
- {
- if (d_x < d_width - 1)
- {
- if (d_insert)
- InsertMode(0);
- RAW_PUTCHAR(c);
- return;
- }
- if (CLP || d_y != d_bot)
- {
- RAW_PUTCHAR(c);
- return;
- }
- d_lp_missing = 1;
- d_lp_image = c;
- d_lp_attr = d_attr;
- d_lp_font = d_font;
- }
-
- /*
- * RAW_PUTCHAR() is for all text that will be displayed.
- * NOTE: charset Nr. 0 has a conversion table, but c1, c2, ... don't.
- */
-
- void
- RAW_PUTCHAR(c)
- int c;
- {
- ASSERT(display);
- if (d_font == '0')
- {
- AddChar(d_c0_tab[c]);
- }
- else
- AddChar(c);
- if (++d_x >= d_width)
- {
- if ((AM && !CLP) || d_x > d_width)
- {
- d_x -= d_width;
- if (d_y < d_height-1 && d_y != d_bot)
- d_y++;
- }
- }
- }
-
- static void
- PutChar(c)
- int c;
- {
- /* this PutChar for ESC-sequences only (AddChar is a macro) */
- AddChar(c);
- }
-
- void
- PutStr(s)
- char *s;
- {
- if (display && s)
- {
- ospeed = d_dospeed;
- tputs(s, 1, PutChar);
- }
- }
-
- void
- CPutStr(s, c)
- char *s;
- int c;
- {
- if (display && s)
- {
- ospeed = d_dospeed;
- tputs(tgoto(s, 0, c), 1, PutChar);
- }
- }
-
-
- /* Insert mode is a toggle on some terminals, so we need this hack:
- */
- void
- InsertMode(on)
- int on;
- {
- if (display && on != d_insert && IM)
- {
- d_insert = on;
- if (d_insert)
- PutStr(IM);
- else
- PutStr(EI);
- }
- }
-
- /* ...and maybe d_keypad application mode is a toggle, too:
- */
- void
- KeypadMode(on)
- int on;
- {
- if (display && d_keypad != on && KS)
- {
- d_keypad = on;
- if (d_keypad)
- PutStr(KS);
- else
- PutStr(KE);
- }
- }
-
- void
- CursorkeysMode(on)
- int on;
- {
- if (display && d_cursorkeys != on && CCS)
- {
- d_cursorkeys = on;
- if (d_cursorkeys)
- PutStr(CCS);
- else
- PutStr(CCE);
- }
- }
-
- static int StrCost;
-
- /* ARGSUSED */
- static void
- CountChars(c)
- int c;
- {
- StrCost++;
- }
-
- int
- CalcCost(s)
- register char *s;
- {
- ASSERT(display);
- if (s)
- {
- StrCost = 0;
- ospeed = d_dospeed;
- tputs(s, 1, CountChars);
- return StrCost;
- }
- else
- return EXPENSIVE;
- }
-
- void
- GotoPos(x2, y2)
- int x2, y2;
- {
- register int dy, dx, x1, y1;
- register int costx, costy;
- register int m;
- register char *s;
- int CMcost;
- enum move_t xm = M_NONE, ym = M_NONE;
-
- if (!display)
- return;
-
- x1 = d_x;
- y1 = d_y;
-
- if (x1 == d_width)
- if (CLP && AM)
- x1 = -1; /* don't know how the terminal treats this */
- else
- x1--;
- if (x2 == d_width)
- x2--;
- dx = x2 - x1;
- dy = y2 - y1;
- if (dy == 0 && dx == 0)
- {
- return;
- }
- if (!MS && d_attr) /* Safe to move in SO mode ? */
- SetAttr(0);
- if (y1 < 0 /* don't know the y position */
- || (y2 > d_bot && y1 <= d_bot) /* have to cross border */
- || (y2 < d_top && y1 >= d_top)) /* of scrollregion ? */
- {
- DoCM:
- if (HO && !x2 && !y2)
- PutStr(HO);
- else
- PutStr(tgoto(CM, x2, y2));
- d_x = x2;
- d_y = y2;
- return;
- }
- /* Calculate CMcost */
- if (HO && !x2 && !y2)
- s = HO;
- else
- s = tgoto(CM, x2, y2);
- CMcost = CalcCost(s);
-
- /* Calculate the cost to move the cursor to the right x position */
- costx = EXPENSIVE;
- if (x1 >= 0) /* relativ x positioning only if we know where we are */
- {
- if (dx > 0)
- {
- if (CRI && (dx > 1 || !ND))
- {
- costx = CalcCost(tgoto(CRI, 0, dx));
- xm = M_CRI;
- }
- if ((m = d_NDcost * dx) < costx)
- {
- costx = m;
- xm = M_RI;
- }
- /* Speedup: dx <= Rewrite() */
- if (dx < costx && (m = Rewrite(y1, x1, x2, 0)) < costx)
- {
- costx = m;
- xm = M_RW;
- }
- }
- else if (dx < 0)
- {
- if (CLE && (dx < -1 || !BC))
- {
- costx = CalcCost(tgoto(CLE, 0, -dx));
- xm = M_CLE;
- }
- if ((m = -dx * d_LEcost) < costx)
- {
- costx = m;
- xm = M_LE;
- }
- }
- else
- costx = 0;
- }
- /* Speedup: Rewrite() >= x2 */
- if (x2 + d_CRcost < costx && (m = (x2 ? Rewrite(y1, 0, x2, 0) : 0) + d_CRcost) < costx)
- {
- costx = m;
- xm = M_CR;
- }
-
- /* Check if it is already cheaper to do CM */
- if (costx >= CMcost)
- goto DoCM;
-
- /* Calculate the cost to move the cursor to the right y position */
- costy = EXPENSIVE;
- if (dy > 0)
- {
- if (CDO && dy > 1) /* DO & NL are always != 0 */
- {
- costy = CalcCost(tgoto(CDO, 0, dy));
- ym = M_CDO;
- }
- if ((m = dy * ((x2 == 0) ? d_NLcost : d_DOcost)) < costy)
- {
- costy = m;
- ym = M_DO;
- }
- }
- else if (dy < 0)
- {
- if (CUP && (dy < -1 || !UP))
- {
- costy = CalcCost(tgoto(CUP, 0, -dy));
- ym = M_CUP;
- }
- if ((m = -dy * d_UPcost) < costy)
- {
- costy = m;
- ym = M_UP;
- }
- }
- else
- costy = 0;
-
- /* Finally check if it is cheaper to do CM */
- if (costx + costy >= CMcost)
- goto DoCM;
-
- switch (xm)
- {
- case M_LE:
- while (dx++ < 0)
- PutStr(BC);
- break;
- case M_CLE:
- CPutStr(CLE, -dx);
- break;
- case M_RI:
- while (dx-- > 0)
- PutStr(ND);
- break;
- case M_CRI:
- CPutStr(CRI, dx);
- break;
- case M_CR:
- PutStr(CR);
- d_x = 0;
- x1 = 0;
- /* FALLTHROUGH */
- case M_RW:
- if (x1 < x2)
- (void) Rewrite(y1, x1, x2, 1);
- break;
- default:
- break;
- }
-
- switch (ym)
- {
- case M_UP:
- while (dy++ < 0)
- PutStr(UP);
- break;
- case M_CUP:
- CPutStr(CUP, -dy);
- break;
- case M_DO:
- s = (x2 == 0) ? NL : DO;
- while (dy-- > 0)
- PutStr(s);
- break;
- case M_CDO:
- CPutStr(CDO, dy);
- break;
- default:
- break;
- }
- d_x = x2;
- d_y = y2;
- }
-
- void
- ClearDisplay()
- {
- ASSERT(display);
- Clear(0, 0, d_width - 1, d_height - 1);
- }
-
- void
- Clear(xs, ys, xe, ye)
- int xs, ys, xe, ye;
- {
- int y, xxe;
-
- ASSERT(display);
- if (xs == d_width)
- xs--;
- if (xe == d_width)
- xe--;
- if (d_lp_missing && ys <= d_bot)
- {
- if (ye > d_bot || (ye == d_bot && xe == d_width - 1))
- d_lp_missing = 0;
- }
- if (xe == d_width - 1 && ye == d_height - 1)
- {
- #ifdef AUTO_NUKE
- if (xs == 0 && ys == 0 && d_auto_nuke)
- NukePending();
- #endif
- if (xs == 0 && ys == 0 && CL)
- {
- PutStr(CL);
- d_y = d_x = 0;
- return;
- }
- /*
- * Workaround a hp700/22 terminal bug. Do not use CD where CE
- * is also appropriate.
- */
- if (CD && (ys < ye || !CE))
- {
- GotoPos(xs, ys);
- PutStr(CD);
- return;
- }
- }
- xxe = d_width - 1;
- for (y = ys; y <= ye; y++, xs = 0)
- {
- if (y == ye)
- xxe = xe;
- if (xs == 0 && CB && (xxe != d_width - 1 || (d_x == xxe && d_y == y)))
- {
- GotoPos(xxe, y);
- PutStr(CB);
- continue;
- }
- if (xxe == d_width - 1 && CE)
- {
- GotoPos(xs, y);
- PutStr(CE);
- continue;
- }
- ClearLine(y, xs, xxe);
- }
- }
-
-
- /*
- * if cur_only > 0, we only redisplay current line, as a full refresh is
- * too expensive over a low baud line.
- */
- void
- Redisplay(cur_only)
- int cur_only;
- {
- register int i, stop;
-
- ASSERT(display);
- DefRestore();
- ClearDisplay();
- stop = d_height;
- i = 0;
- if (cur_only > 0 && d_fore)
- {
- i = stop = d_fore->w_y;
- stop++;
- }
- else RedisplayLine(-1, 0, d_width - 1, 1);
- for (; i < stop; i++)
- RedisplayLine(i, 0, d_width - 1, 1);
- Restore();
- SetCursor();
- }
-
-
- void
- ScrollRegion(ys, ye, n)
- int ys, ye, n;
- {
- int i;
- int up;
- int oldtop, oldbot;
- int alok, dlok, aldlfaster;
- int missy = 0;
-
- ASSERT(display);
- if (n == 0)
- return;
- if (ys == 0 && ye == d_height - 1 &&
- (n >= d_height || -n >= d_height))
- {
- ClearDisplay();
- return;
- }
-
- if (d_lp_missing)
- {
- if (d_bot > ye || d_bot < ys)
- missy = d_bot;
- else
- {
- missy = d_bot - n;
- if (missy>ye || missy<ys)
- d_lp_missing = 0;
- }
- }
-
- up = 1;
- if (n < 0)
- {
- up = 0;
- n = -n;
- }
- if (n >= ye-ys+1)
- n = ye-ys+1;
-
- oldtop = d_top;
- oldbot = d_bot;
- if (d_bot != ye)
- ChangeScrollRegion(ys, ye);
- alok = (AL || CAL || (ye == d_bot && up));
- dlok = (DL || CDL || (ye == d_bot && !up));
- if (d_top != ys && !(alok && dlok))
- ChangeScrollRegion(ys, ye);
-
- if (d_lp_missing &&
- (oldbot != d_bot ||
- (oldbot == d_bot && up && d_top == ys && d_bot == ye)))
- {
- FixLP(d_width - 1, oldbot);
- if (oldbot == d_bot) /* have scrolled */
- {
- if (--n == 0)
- {
- ChangeScrollRegion(oldtop, oldbot);
- return;
- }
- }
- }
-
- aldlfaster = (n > 1 && ye == d_bot && ((up && CDL) || (!up && CAL)));
-
- if ((up || SR) && d_top == ys && d_bot == ye && !aldlfaster)
- {
- if (up)
- {
- GotoPos(0, ye);
- while (n-- > 0)
- PutStr(NL); /* was SF, I think NL is faster */
- }
- else
- {
- GotoPos(0, ys);
- while (n-- > 0)
- PutStr(SR);
- }
- }
- else if (alok && dlok)
- {
- if (up || ye != d_bot)
- {
- GotoPos(0, up ? ys : ye+1-n);
- if (CDL && !(n == 1 && DL))
- CPutStr(CDL, n);
- else
- for(i = n; i--; )
- PutStr(DL);
- }
- if (!up || ye != d_bot)
- {
- GotoPos(0, up ? ye+1-n : ys);
- if (CAL && !(n == 1 && AL))
- CPutStr(CAL, n);
- else
- for(i = n; i--; )
- PutStr(AL);
- }
- }
- else
- {
- Redisplay(0);
- return;
- }
- if (d_lp_missing && missy != d_bot)
- FixLP(d_width - 1, missy);
- ChangeScrollRegion(oldtop, oldbot);
- if (d_lp_missing && missy != d_bot)
- FixLP(d_width - 1, missy);
- }
-
- void
- SetAttr(new)
- register int new;
- {
- register int i, old;
-
- if (!display || (old = d_attr) == new)
- return;
- d_attr = new;
- for (i = 1; i <= A_MAX; i <<= 1)
- {
- if ((old & i) && !(new & i))
- {
- PutStr(UE);
- PutStr(SE);
- PutStr(ME);
- if (new & A_DI)
- PutStr(d_attrtab[ATTR_DI]);
- if (new & A_US)
- PutStr(d_attrtab[ATTR_US]);
- if (new & A_BD)
- PutStr(d_attrtab[ATTR_BD]);
- if (new & A_RV)
- PutStr(d_attrtab[ATTR_RV]);
- if (new & A_SO)
- PutStr(d_attrtab[ATTR_SO]);
- if (new & A_BL)
- PutStr(d_attrtab[ATTR_BL]);
- return;
- }
- }
- if ((new & A_DI) && !(old & A_DI))
- PutStr(d_attrtab[ATTR_DI]);
- if ((new & A_US) && !(old & A_US))
- PutStr(d_attrtab[ATTR_US]);
- if ((new & A_BD) && !(old & A_BD))
- PutStr(d_attrtab[ATTR_BD]);
- if ((new & A_RV) && !(old & A_RV))
- PutStr(d_attrtab[ATTR_RV]);
- if ((new & A_SO) && !(old & A_SO))
- PutStr(d_attrtab[ATTR_SO]);
- if ((new & A_BL) && !(old & A_BL))
- PutStr(d_attrtab[ATTR_BL]);
- }
-
- void
- SetFont(new)
- int new;
- {
- if (!display || d_font == new)
- return;
- d_font = new;
- if (new == ASCII)
- PutStr(CE0);
- else
- CPutStr(CS0, new);
- }
-
- void
- SetAttrFont(newattr, newcharset)
- int newattr, newcharset;
- {
- SetAttr(newattr);
- SetFont(newcharset);
- }
-
- void
- MakeStatus(msg)
- char *msg;
- {
- register char *s, *t;
- register int max, ti;
-
- if (!display)
- return;
-
- if (!d_tcinited)
- {
- debug("tc not inited, just writing msg\n");
- AddStr(msg);
- AddStr("\r\n");
- Flush();
- return;
- }
- if (!use_hardstatus || !HS)
- {
- max = d_width;
- if (CLP == 0)
- max--;
- }
- else
- max = WS;
- if (d_status)
- {
- if (!d_status_bell)
- {
- ti = time((time_t *) 0) - d_status_time;
- if (ti < MsgMinWait)
- sleep(MsgMinWait - ti);
- }
- RemoveStatus();
- }
- for (s = t = msg; *s && t - msg < max; ++s)
- if (*s == BELL)
- PutStr(BL);
- else if ((unsigned char)*s >= ' ' && *s != 0177)
- *t++ = *s;
- *t = '\0';
- if (t > msg)
- {
- if (t - msg >= d_status_buflen)
- {
- char *buf;
- if (d_status_lastmsg)
- buf = realloc(d_status_lastmsg, t - msg + 1);
- else
- buf = malloc(t - msg + 1);
- if (buf)
- {
- d_status_lastmsg = buf;
- d_status_buflen = t - msg + 1;
- }
- }
- if (t - msg < d_status_buflen)
- strcpy(d_status_lastmsg, msg);
- d_status = 1;
- d_status_len = t - msg;
- d_status_lastx = d_x;
- d_status_lasty = d_y;
- if (!use_hardstatus || !HS)
- {
- debug1("using STATLINE %d\n", STATLINE);
- GotoPos(0, STATLINE);
- SetAttrFont(A_SO, ASCII);
- InsertMode(0);
- AddStr(msg);
- d_x = -1;
- }
- else
- {
- debug("using HS\n");
- SetAttrFont(0, ASCII);
- InsertMode(0);
- CPutStr(TS, 0);
- AddStr(msg);
- PutStr(FS);
- }
- Flush();
- (void) time(&d_status_time);
- }
- }
-
- void
- RemoveStatus()
- {
- struct win *p;
-
- if (!display)
- return;
- if (!d_status)
- return;
-
- /*
- * UGLY HACK ALERT - this should NOT be in display.c
- * We need to find the window that caused an activity or bell
- * message, to reenable this function there.
- */
- for (p = windows; p; p = p->w_next)
- {
- if (p->w_display != display)
- continue;
- if (p->w_monitor == MON_MSG)
- {
- debug1("RemoveStatus clearing monitor win %d\n", p->w_number);
- p->w_monitor = MON_DONE;
- }
- if (p->w_bell == BELL_MSG)
- {
- debug1("RemoveStatus clearing bell win %d\n", p->w_number);
- p->w_bell = BELL_DONE;
- }
- }
- d_status = 0;
- d_status_bell = 0;
- if (!use_hardstatus || !HS)
- {
- GotoPos(0, STATLINE);
- RefreshLine(STATLINE, 0, d_status_len - 1, 0);
- GotoPos(d_status_lastx, d_status_lasty);
- }
- else
- {
- SetAttrFont(0, ASCII);
- PutStr(DS);
- }
- SetCursor();
- }
-
- void
- RefreshLine(y, from, to, isblank)
- int y, from, to, isblank;
- {
- ASSERT(display);
- debug2("RefreshLine %d %d", y, from);
- debug2(" %d %d\n", to, isblank);
- if (isblank == 0 && CE && to == d_width - 1)
- {
- GotoPos(from, y);
- PutStr(CE);
- isblank = 1;
- }
- RedisplayLine(y, from, to, isblank);
- }
-
- void
- FixLP(x2, y2)
- register int x2, y2;
- {
- int oldattr = d_attr, oldfont = d_font;
-
- ASSERT(display);
- GotoPos(x2, y2);
- SetAttrFont(d_lp_attr, d_lp_font);
- PUTCHAR(d_lp_image);
- d_lp_missing = 0;
- SetAttrFont(oldattr, oldfont);
- }
-
- void
- DisplayLine(os, oa, of, s, as, fs, y, from, to)
- int from, to, y;
- register char *os, *oa, *of, *s, *as, *fs;
- {
- register int x;
- int last2flag = 0, delete_lp = 0;
-
- ASSERT(display);
- ASSERT(y >= 0 && y < d_height);
- ASSERT(from >= 0 && from < d_width);
- ASSERT(to >= 0 && to < d_width);
- if (!CLP && y == d_bot && to == d_width - 1)
- if (d_lp_missing
- || s[to] != os[to] || as[to] != oa[to] || of[to] != fs[to])
- {
- if ((IC || IM) && from < to)
- {
- to -= 2;
- last2flag = 1;
- d_lp_missing = 0;
- }
- else
- {
- to--;
- delete_lp = (CE || DC || CDC);
- d_lp_missing = (s[to] != ' ' || as[to] || fs[to]);
- d_lp_image = s[to];
- d_lp_attr = as[to];
- d_lp_font = fs[to];
- }
- }
- else
- to--;
- for (x = from; x <= to; ++x)
- {
- if (x || d_x != d_width || d_y != y - 1)
- {
- if (x < to || x != d_width - 1 || s[x + 1] == ' ')
- if (s[x] == os[x] && as[x] == oa[x] && of[x] == fs[x])
- continue;
- GotoPos(x, y);
- }
- SetAttr(as[x]);
- SetFont(fs[x]);
- PUTCHAR(s[x]);
- }
- if (to == d_width - 1 && y < d_height - 1 && s[to + 1] == ' ')
- GotoPos(0, y + 1);
- if (last2flag)
- {
- GotoPos(x, y);
- SetAttr(as[x + 1]);
- SetFont(fs[x + 1]);
- PUTCHAR(s[x + 1]);
- GotoPos(x, y);
- SetAttr(as[x]);
- SetFont(fs[x]);
- INSERTCHAR(s[x]);
- }
- else if (delete_lp)
- {
- if (DC)
- PutStr(DC);
- else if (CDC)
- CPutStr(CDC, 1);
- else if (CE)
- PutStr(CE);
- }
- }
-
- void
- SetLastPos(x,y)
- int x,y;
- {
- ASSERT(display);
- d_x = x;
- d_y = y;
- }
-
- int
- ResizeDisplay(wi, he)
- int wi, he;
- {
- ASSERT(display);
- debug2("ResizeDisplay: to (%d,%d).\n", wi, he);
- if (d_width == wi && d_height == he)
- {
- debug("ResizeDisplay: No change\n");
- return 0;
- }
- if (CWS)
- {
- debug("ResizeDisplay: using WS\n");
- PutStr(tgoto(CWS, wi, he));
- ChangeScreenSize(wi, he, 0);
- return 0;
- }
- else if (CZ0 && (wi == Z0width || wi == Z1width))
- {
- debug("ResizeDisplay: using Z0/Z1\n");
- PutStr(wi == Z0width ? CZ0 : CZ1);
- ChangeScreenSize(wi, d_height, 0);
- return (he == d_height) ? 0 : -1;
- }
- return -1;
- }
-
- void
- ChangeScrollRegion(newtop, newbot)
- int newtop, newbot;
- {
- if (display == 0)
- return;
- if (CS == 0)
- {
- d_top = 0;
- d_bot = d_height - 1;
- return;
- }
- if (d_top == newtop && d_bot == newbot)
- return;
- debug2("ChangeScrollRegion: (%d - %d)\n", newtop, newbot);
- PutStr(tgoto(CS, newbot, newtop));
- d_top = newtop;
- d_bot = newbot;
- d_y = d_x = -1; /* Just in case... */
- }
-
-
- /*
- * Layer creation / removal
- */
-
- int
- InitOverlayPage(datasize, lf, block)
- int datasize;
- struct LayFuncs *lf;
- int block;
- {
- char *data;
- struct layer *newlay;
-
- RemoveStatus();
- debug3("Entering new layer display %#x d_fore %#x oldlay %#x\n",
- (unsigned int)display, (unsigned int)d_fore, (unsigned int)d_lay);
- if ((newlay = (struct layer *)malloc(sizeof(struct layer))) == 0)
- {
- Msg(0, "No memory for layer struct");
- return(-1);
- }
- data = 0;
- if (datasize)
- {
- if ((data = malloc(datasize)) == 0)
- {
- free(newlay);
- Msg(0, "No memory for layer data");
- return(-1);
- }
- bzero(data, datasize);
- }
- newlay->l_layfn = lf;
- newlay->l_block = block | d_lay->l_block;
- newlay->l_data = data;
- newlay->l_next = d_lay;
- if (d_fore)
- {
- d_fore->w_lay = newlay; /* XXX: CHECK */
- d_fore->w_active = 0; /* XXX: CHECK */
- }
- d_lay = newlay;
- d_layfn = newlay->l_layfn;
- Restore();
- return(0);
- }
-
- void
- ExitOverlayPage()
- {
- struct layer *oldlay;
-
- debug3("Exiting layer display %#x fore %#x d_lay %#x\n",
- (unsigned int)display, (unsigned int)d_fore, (unsigned int)d_lay);
- oldlay = d_lay;
- if (oldlay->l_data)
- free(oldlay->l_data);
- d_lay = oldlay->l_next;
- d_layfn = d_lay->l_layfn;
- free(oldlay);
- if (d_fore)
- d_fore->w_lay = d_lay; /* XXX: Is this necessary ? */
- Restore();
- SetCursor();
- }
-
-
- /*
- * Output buffering routines
- */
-
- void
- AddStr(str)
- char *str;
- {
- register char c;
-
- ASSERT(display);
- while ((c = *str++))
- AddChar(c);
- }
-
- void
- AddStrn(str, n)
- char *str;
- int n;
- {
- register char c;
-
- ASSERT(display);
- while ((c = *str++) && n-- > 0)
- AddChar(c);
- while (n-- > 0)
- AddChar(' ');
- }
-
- void
- Flush()
- {
- register int l;
- register char *p;
-
- ASSERT(display);
- l = d_obufp - d_obuf;
- debug1("Flush(): %d\n", l);
- ASSERT(l + d_obuffree == d_obuflen);
- if (l == 0)
- return;
- if (d_userfd < 0)
- {
- d_obuffree += l;
- d_obufp = d_obuf;
- return;
- }
- p = d_obuf;
- if (fcntl(d_userfd, F_SETFL, 0))
- debug1("Warning: DELAY fcntl failed: %d\n", errno);
- while (l)
- {
- register int wr;
- wr = write(d_userfd, p, l);
- if (wr <= 0)
- {
- if (errno == EINTR)
- continue;
- debug1("Writing to display: %d\n", errno);
- wr = l;
- }
- d_obuffree += wr;
- p += wr;
- l -= wr;
- }
- d_obuffree += l;
- d_obufp = d_obuf;
- if (fcntl(d_userfd, F_SETFL, FNDELAY))
- debug1("Warning: NDELAY fcntl failed: %d\n", errno);
- }
-
- void
- freetty()
- {
- if (d_userfd >= 0)
- close(d_userfd);
- debug1("did freetty %d\n", d_userfd);
- d_userfd = -1;
- d_obufp = 0;
- d_obuffree = 0;
- if (d_obuf)
- free(d_obuf);
- d_obuf = 0;
- d_obuflen = 0;
- }
-
- /*
- * Asynchronous output routines by
- * Tim MacKenzie (tym@dibbler.cs.monash.edu.au)
- */
-
- void
- Resize_obuf()
- {
- register int ind;
-
- ASSERT(display);
- if (d_obuflen && d_obuf)
- {
- ind = d_obufp - d_obuf;
- d_obuflen += GRAIN;
- d_obuffree += GRAIN;
- d_obuf = realloc(d_obuf, d_obuflen);
- }
- else
- {
- ind = 0;
- d_obuflen = GRAIN;
- d_obuffree = GRAIN;
- d_obuf = malloc(d_obuflen);
- }
- if (!d_obuf)
- Panic(0, "Out of memory");
- d_obufp = d_obuf + ind;
- debug1("ResizeObuf: resized to %d\n", d_obuflen);
- }
-
- #ifdef AUTO_NUKE
- void
- NukePending()
- {/* Nuke pending output in current display, clear screen */
- register int len;
- int oldfont = d_font, oldattr = d_attr, oldtop = d_top, oldbot = d_bot;
- int oldkeypad = d_keypad, oldcursorkeys = d_cursorkeys;
-
- len = d_obufp - d_obuf;
- debug1("NukePending: nuking %d chars\n", len);
-
- /* Throw away any output that we can... */
- # ifdef POSIX
- tcflush(d_userfd, TCOFLUSH);
- # else
- # ifdef TCFLSH
- (void) ioctl(d_userfd, TCFLSH, (char *) 1);
- # endif
- # endif
-
- d_obufp = d_obuf;
- d_obuffree += len;
- d_top = d_bot = -1;
- PutStr(TI);
- PutStr(IS);
- /* Turn off all attributes. (Tim MacKenzie) */
- if (ME)
- PutStr(ME);
- else
- {
- PutStr(SE);
- PutStr(UE);
- }
- /* Check for toggle */
- if (IM && strcmp(IM, EI))
- PutStr(EI);
- d_insert = 0;
- /* Check for toggle */
- if (KS && strcmp(KS, KE))
- PutStr(KE);
- d_keypad = 0;
- if (CCS && strcmp(CCS, CCE))
- PutStr(CCE);
- d_cursorkeys = 0;
- PutStr(CE0);
- d_font = ASCII;
- d_attr = 0;
- ChangeScrollRegion(oldtop, oldbot);
- SetAttrFont(oldattr, oldfont);
- KeypadMode(oldkeypad);
- CursorkeysMode(oldcursorkeys);
- if (CWS)
- {
- debug("ResizeDisplay: using WS\n");
- PutStr(tgoto(CWS, d_width, d_height));
- }
- else if (CZ0 && (d_width == Z0width || d_width == Z1width))
- {
- debug("ResizeDisplay: using Z0/Z1\n");
- PutStr(d_width == Z0width ? CZ0 : CZ1);
- }
- }
- #endif /* AUTO_NUKE */
-