summaryrefslogtreecommitdiff
path: root/display.c
diff options
context:
space:
mode:
Diffstat (limited to 'display.c')
-rw-r--r--display.c1583
1 files changed, 1238 insertions, 345 deletions
diff --git a/display.c b/display.c
index 3a47928..68133f0 100644
--- a/display.c
+++ b/display.c
@@ -31,21 +31,41 @@ RCS_ID("$Id: display.c,v 1.16 1994/05/31 12:31:50 mlschroe Exp $ FAU")
#include "config.h"
#include "screen.h"
#include "extern.h"
+#include "braille.h"
-static void CountChars __P((int));
-static void PutChar __P((int));
+static int CountChars __P((int));
+static int PutChar __P((int));
static int BlankResize __P((int, int));
+static int CallRewrite __P((int, int, int, int));
+static void FreeCanvas __P((struct canvas *));
+static void disp_readev_fn __P((struct event *, char *));
+static void disp_writeev_fn __P((struct event *, char *));
+static void disp_status_fn __P((struct event *, char *));
+static void disp_hstatus_fn __P((struct event *, char *));
+static void cv_winid_fn __P((struct event *, char *));
+#ifdef MAPKEYS
+static void disp_map_fn __P((struct event *, char *));
+#endif
+static void WriteLP __P((int, int));
+static void INSERTCHAR __P((int));
+static void RAW_PUTCHAR __P((int));
+extern struct layer *flayer;
extern struct win *windows;
+extern struct LayFuncs WinLf;
extern int use_hardstatus;
-extern int MsgMinWait;
+extern int MsgWait, MsgMinWait;
extern int Z0width, Z1width;
extern char *blank, *null;
extern struct mline mline_blank, mline_null;
extern struct mchar mchar_null, mchar_blank, mchar_so;
+/* XXX shouldn't be here */
+extern char *hstatusstring;
+extern char *captionstring;
+
/*
* tputs needs this to calculate the padding
*/
@@ -68,6 +88,8 @@ int defobuflimit = OBUF_MAX;
#ifdef AUTO_NUKE
int defautonuke = 0;
#endif
+int captionalways;
+int hardstatusemu = HSTATUS_IGNORE;
/*
* Default layer management
@@ -94,23 +116,18 @@ void
DefClearLine(y, xs, xe)
int y, xs, xe;
{
- DisplayLine(&mline_null, &mline_blank, y, xs, xe);
+ LClearLine(flayer, y, xs, xe, (struct mline *)0);
}
/*ARGSUSED*/
int
-DefRewrite(y, xs, xe, doit)
+DefRewrite(y, xs, xe, rend, doit)
int y, xs, xe, doit;
+struct mchar *rend;
{
return EXPENSIVE;
}
-void
-DefSetCursor()
-{
- GotoPos(0, 0);
-}
-
/*ARGSUSED*/
int
DefResize(wi, he)
@@ -122,13 +139,13 @@ int wi, he;
void
DefRestore()
{
- InsertMode(0);
- ChangeScrollRegion(0, D_height - 1);
- KeypadMode(0);
- CursorkeysMode(0);
- CursorVisibility(0);
- SetRendition(&mchar_null);
- SetFlow(FLOW_NOW);
+ LAY_DISPLAYS(flayer, InsertMode(0));
+ /* ChangeScrollRegion(0, D_height - 1); */
+ LKeypadMode(flayer, 0);
+ LCursorkeysMode(flayer, 0);
+ LCursorVisibility(flayer, 0);
+ LSetRendition(flayer, &mchar_null);
+ LSetFlow(flayer, FLOW_NOW);
}
/*
@@ -142,30 +159,25 @@ struct LayFuncs BlankLf =
DefRedisplayLine,
DefClearLine,
DefRewrite,
- DefSetCursor,
BlankResize,
DefRestore
};
-struct layer BlankLayer =
-{
- 0,
- 0,
- &BlankLf,
- 0
-};
-
/*ARGSUSED*/
static int
BlankResize(wi, he)
int wi, he;
{
+ flayer->l_width = wi;
+ flayer->l_height = he;
return 0;
}
/*
- * Generate new display
+ * Generate new display, start with a blank layer.
+ * The termcap arrays are not initialised here.
+ * The new display is placed in the displays list.
*/
struct display *
@@ -175,14 +187,14 @@ int fd, pid;
struct mode *Mode;
{
struct user **u;
+ struct baud_values *b;
if (!*(u = FindUserPtr(uname)) && UserAdd(uname, (char *)0, u))
return 0; /* could not find or add user */
#ifdef MULTI
- if ((display = (struct display *)malloc(sizeof(*display))) == 0)
+ if ((display = (struct display *)calloc(1, sizeof(*display))) == 0)
return 0;
- bzero((char *) display, sizeof(*display));
#else
if (displays)
return 0;
@@ -193,106 +205,102 @@ struct mode *Mode;
D_flow = 1;
D_nonblock = 0;
D_userfd = fd;
+ D_readev.fd = D_writeev.fd = fd;
+ D_readev.type = EV_READ;
+ D_writeev.type = EV_WRITE;
+ D_readev.data = D_writeev.data = (char *)display;
+ D_readev.handler = disp_readev_fn;
+ D_writeev.handler = disp_writeev_fn;
+ evenq(&D_readev);
+ D_writeev.condpos = &D_obuflen;
+ D_writeev.condneg = &D_obuffree;
+ evenq(&D_writeev);
+ D_statusev.type = EV_TIMEOUT;
+ D_statusev.data = (char *)display;
+ D_statusev.handler = disp_status_fn;
+ D_hstatusev.type = EV_TIMEOUT;
+ D_hstatusev.data = (char *)display;
+ D_hstatusev.handler = disp_hstatus_fn;
+#ifdef MAPKEYS
+ D_mapev.type = EV_TIMEOUT;
+ D_mapev.data = (char *)display;
+ D_mapev.handler = disp_map_fn;
+#endif
D_OldMode = *Mode;
Resize_obuf(); /* Allocate memory for buffer */
D_obufmax = defobuflimit;
+ D_obuflenmax = D_obuflen - D_obufmax;
#ifdef AUTO_NUKE
D_auto_nuke = defautonuke;
#endif
D_obufp = D_obuf;
D_printfd = -1;
D_userpid = pid;
-#if defined(POSIX) || defined(TERMIO)
-# ifdef POSIX
- switch (cfgetospeed(&D_OldMode.tio))
+
+#ifdef POSIX
+ if ((b = lookup_baud((int)cfgetospeed(&D_OldMode.tio))))
+ D_dospeed = b->idx;
+#else
+# ifdef TERMIO
+ if ((b = lookup_baud(D_OldMode.tio.c_cflag & CBAUD)))
+ D_dospeed = b->idx;
# else
- switch (D_OldMode.tio.c_cflag & CBAUD)
+ D_dospeed = (short)D_OldMode.m_ttyb.sg_ospeed;
# endif
- {
-#ifdef B0
- case B0: D_dospeed = 0; break;
-#endif
-#ifdef B50
- case B50: D_dospeed = 1; break;
-#endif
-#ifdef B75
- case B75: D_dospeed = 2; break;
-#endif
-#ifdef B110
- case B110: D_dospeed = 3; break;
-#endif
-#ifdef B134
- case B134: D_dospeed = 4; break;
-#endif
-#ifdef B150
- case B150: D_dospeed = 5; break;
#endif
-#ifdef B200
- case B200: D_dospeed = 6; break;
-#endif
-#ifdef B300
- case B300: D_dospeed = 7; break;
-#endif
-#ifdef B600
- case B600: D_dospeed = 8; break;
-#endif
-#ifdef B1200
- case B1200: D_dospeed = 9; break;
-#endif
-#ifdef B1800
- case B1800: D_dospeed = 10; break;
-#endif
-#ifdef B2400
- case B2400: D_dospeed = 11; break;
-#endif
-#ifdef B4800
- case B4800: D_dospeed = 12; break;
-#endif
-#ifdef B9600
- case B9600: D_dospeed = 13; break;
-#endif
-#ifdef EXTA
- case EXTA: D_dospeed = 14; break;
-#endif
-#ifdef EXTB
- case EXTB: D_dospeed = 15; break;
-#endif
-#ifdef B57600
- case B57600: D_dospeed = 16; break;
-#endif
-#ifdef B115200
- case B115200: D_dospeed = 17; break;
-#endif
- default: ;
- }
-#else /* POSIX || TERMIO */
- D_dospeed = (short) D_OldMode.m_ttyb.sg_ospeed;
-#endif /* POSIX || TERMIO */
+
debug1("New displays ospeed = %d\n", D_dospeed);
strncpy(D_usertty, utty, sizeof(D_usertty) - 1);
D_usertty[sizeof(D_usertty) - 1] = 0;
strncpy(D_termname, term, sizeof(D_termname) - 1);
D_termname[sizeof(D_termname) - 1] = 0;
D_user = *u;
- D_lay = &BlankLayer;
- D_layfn = BlankLayer.l_layfn;
+ D_processinput = ProcessInput;
return display;
}
+
void
FreeDisplay()
{
struct win *p;
+ struct canvas *cv, *cvp;
#ifdef MULTI
struct display *d, **dp;
#endif
+#ifdef FONT
FreeTransTable();
+#endif
+ if (D_userfd >= 0)
+ {
+ Flush();
+ SetTTY(D_userfd, &D_OldMode);
+ fcntl(D_userfd, F_SETFL, 0);
+ }
freetty();
if (D_tentry)
free(D_tentry);
D_tentry = 0;
+ if (D_processinputdata)
+ free(D_processinputdata);
+ D_processinputdata = 0;
D_tcinited = 0;
+ evdeq(&D_hstatusev);
+ evdeq(&D_statusev);
+ evdeq(&D_readev);
+ evdeq(&D_writeev);
+#ifdef MAPKEYS
+ evdeq(&D_mapev);
+#endif
+#ifdef HAVE_BRAILLE
+ if (bd.bd_dpy == display)
+ {
+ bd.bd_start_braille = 0;
+ StartBraille();
+ }
+#endif
+
#ifdef MULTI
for (dp = &displays; (d = *dp) ; dp = &d->d_next)
if (d == display)
@@ -303,22 +311,329 @@ FreeDisplay()
if (D_obuf)
free(D_obuf);
*dp = display->d_next;
- free((char *)display);
+ cv = display->d_cvlist;
#else /* MULTI */
ASSERT(display == displays);
ASSERT(display == &TheDisplay);
+ cv = display->d_cvlist;
+ display->d_cvlist = 0;
displays = 0;
#endif /* MULTI */
+
for (p = windows; p; p = p->w_next)
{
- if (p->w_display == display)
- p->w_display = 0;
if (p->w_pdisplay == display)
p->w_pdisplay = 0;
}
+ for (; cv; cv = cvp)
+ {
+ cvp = cv->c_next;
+ FreeCanvas(cv);
+ }
+#ifdef MULTI
+ free((char *)display);
+#endif
display = 0;
}
+int
+MakeDefaultCanvas()
+{
+ struct canvas *cv;
+
+ ASSERT(display);
+ if ((cv = (struct canvas *)calloc(1, sizeof *cv)) == 0)
+ return -1;
+ cv->c_xs = 0;
+ cv->c_xe = D_width - 1;
+ cv->c_ys = 0;
+ cv->c_ye = D_height - 1 - (D_has_hstatus == HSTATUS_LASTLINE) - captionalways;
+ cv->c_xoff = 0;
+ cv->c_yoff = 0;
+ cv->c_next = 0;
+ cv->c_display = display;
+ cv->c_vplist = 0;
+ cv->c_captev.type = EV_TIMEOUT;
+ cv->c_captev.data = (char *)cv;
+ cv->c_captev.handler = cv_winid_fn;
+
+ cv->c_blank.l_cvlist = cv;
+ cv->c_blank.l_width = cv->c_xe - cv->c_xs + 1;
+ cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1;
+ cv->c_blank.l_x = cv->c_blank.l_y = 0;
+ cv->c_blank.l_layfn = &BlankLf;
+ cv->c_blank.l_data = 0;
+ cv->c_blank.l_next = 0;
+ cv->c_blank.l_bottom = &cv->c_blank;
+ cv->c_blank.l_blocking = 0;
+ cv->c_layer = &cv->c_blank;
+ cv->c_lnext = 0;
+
+ D_cvlist = cv;
+ RethinkDisplayViewports();
+ D_forecv = cv; /* default input focus */
+ return 0;
+}
+
+void
+FreeCanvas(cv)
+struct canvas *cv;
+{
+ struct viewport *vp, *nvp;
+ struct win *p;
+
+ p = Layer2Window(cv->c_layer);
+ SetCanvasWindow(cv, 0);
+ if (p)
+ WindowChanged(p, 'u');
+ if (flayer == cv->c_layer)
+ flayer = 0;
+ for (vp = cv->c_vplist; vp; vp = nvp)
+ {
+ vp->v_canvas = 0;
+ nvp = vp->v_next;
+ vp->v_next = 0;
+ free(vp);
+ }
+ evdeq(&cv->c_captev);
+ free(cv);
+}
+
+int
+AddCanvas()
+{
+ int hh, h, i, j;
+ struct canvas *cv, **cvpp;
+
+ for (cv = D_cvlist, j = 0; cv; cv = cv->c_next)
+ j++;
+ j++; /* new canvas */
+ h = D_height - (D_has_hstatus == HSTATUS_LASTLINE);
+ if (h / j <= 1)
+ return -1;
+
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ if (cv == D_forecv)
+ break;
+ ASSERT(cv);
+ cvpp = &cv->c_next;
+
+ if ((cv = (struct canvas *)calloc(1, sizeof *cv)) == 0)
+ return -1;
+
+ cv->c_xs = 0;
+ cv->c_xe = D_width - 1;
+ cv->c_ys = 0;
+ cv->c_ye = D_height - 1;
+ cv->c_xoff = 0;
+ cv->c_yoff = 0;
+ cv->c_display = display;
+ cv->c_vplist = 0;
+ cv->c_captev.type = EV_TIMEOUT;
+ cv->c_captev.data = (char *)cv;
+ cv->c_captev.handler = cv_winid_fn;
+
+ cv->c_blank.l_cvlist = cv;
+ cv->c_blank.l_width = cv->c_xe - cv->c_xs + 1;
+ cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1;
+ cv->c_blank.l_x = cv->c_blank.l_y = 0;
+ cv->c_blank.l_layfn = &BlankLf;
+ cv->c_blank.l_data = 0;
+ cv->c_blank.l_next = 0;
+ cv->c_blank.l_bottom = &cv->c_blank;
+ cv->c_blank.l_blocking = 0;
+ cv->c_layer = &cv->c_blank;
+ cv->c_lnext = 0;
+
+ cv->c_next = *cvpp;
+ *cvpp = cv;
+
+ i = 0;
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ {
+ hh = h / j-- - 1;
+ cv->c_ys = i;
+ cv->c_ye = i + hh - 1;
+ cv->c_yoff = i;
+ i += hh + 1;
+ h -= hh + 1;
+ }
+
+ RethinkDisplayViewports();
+ ResizeLayersToCanvases();
+ return 0;
+}
+
+void
+RemCanvas()
+{
+ int hh, h, i, j;
+ struct canvas *cv, **cvpp;
+ int did = 0;
+
+ h = D_height - (D_has_hstatus == HSTATUS_LASTLINE);
+ for (cv = D_cvlist, j = 0; cv; cv = cv->c_next)
+ j++;
+ if (j == 1)
+ return;
+ i = 0;
+ j--;
+ for (cvpp = &D_cvlist; (cv = *cvpp); cvpp = &cv->c_next)
+ {
+ if (cv == D_forecv && !did)
+ {
+ *cvpp = cv->c_next;
+ FreeCanvas(cv);
+ cv = *cvpp;
+ D_forecv = cv ? cv : D_cvlist;
+ D_fore = Layer2Window(D_forecv->c_layer);
+ flayer = D_forecv->c_layer;
+ if (cv == 0)
+ break;
+ did = 1;
+ }
+ hh = h / j-- - 1;
+ if (!captionalways && i == 0 && j == 0)
+ hh++;
+ cv->c_ys = i;
+ cv->c_ye = i + hh - 1;
+ cv->c_yoff = i;
+ i += hh + 1;
+ h -= hh + 1;
+ }
+ RethinkDisplayViewports();
+ ResizeLayersToCanvases();
+}
+
+void
+OneCanvas()
+{
+ struct canvas *mycv = D_forecv;
+ struct canvas *cv, **cvpp;
+
+ for (cvpp = &D_cvlist; (cv = *cvpp);)
+ {
+ if (cv == mycv)
+ {
+ cv->c_ys = 0;
+ cv->c_ye = D_height - 1 - (D_has_hstatus == HSTATUS_LASTLINE) - captionalways;
+ cv->c_yoff = 0;
+ cvpp = &cv->c_next;
+ }
+ else
+ {
+ *cvpp = cv->c_next;
+ FreeCanvas(cv);
+ }
+ }
+ RethinkDisplayViewports();
+ ResizeLayersToCanvases();
+}
+
+int
+RethinkDisplayViewports()
+{
+ struct canvas *cv;
+ struct viewport *vp, *vpn;
+
+ /* free old viewports */
+ for (cv = display->d_cvlist; cv; cv = cv->c_next)
+ {
+ for (vp = cv->c_vplist; vp; vp = vpn)
+ {
+ vp->v_canvas = 0;
+ vpn = vp->v_next;
+ bzero((char *)vp, sizeof(*vp));
+ free(vp);
+ }
+ cv->c_vplist = 0;
+ }
+ display->d_vpxmin = -1;
+ display->d_vpxmax = -1;
+
+ for (cv = display->d_cvlist; cv; cv = cv->c_next)
+ {
+ if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0)
+ return -1;
+#ifdef HOLE
+ vp->v_canvas = cv;
+ vp->v_xs = cv->c_xs;
+ vp->v_ys = (cv->c_ys + cv->c_ye) / 2;
+ vp->v_xe = cv->c_xe;
+ vp->v_ye = cv->c_ye;
+ vp->v_xoff = cv->c_xoff;
+ vp->v_yoff = cv->c_yoff;
+ vp->v_next = cv->c_vplist;
+ cv->c_vplist = vp;
+
+ if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0)
+ return -1;
+ vp->v_canvas = cv;
+ vp->v_xs = (cv->c_xs + cv->c_xe) / 2;
+ vp->v_ys = (3 * cv->c_ys + cv->c_ye) / 4;
+ vp->v_xe = cv->c_xe;
+ vp->v_ye = (cv->c_ys + cv->c_ye) / 2 - 1;
+ vp->v_xoff = cv->c_xoff;
+ vp->v_yoff = cv->c_yoff;
+ vp->v_next = cv->c_vplist;
+ cv->c_vplist = vp;
+
+ if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0)
+ return -1;
+ vp->v_canvas = cv;
+ vp->v_xs = cv->c_xs;
+ vp->v_ys = (3 * cv->c_ys + cv->c_ye) / 4;
+ vp->v_xe = (3 * cv->c_xs + cv->c_xe) / 4 - 1;
+ vp->v_ye = (cv->c_ys + cv->c_ye) / 2 - 1;
+ vp->v_xoff = cv->c_xoff;
+ vp->v_yoff = cv->c_yoff;
+ vp->v_next = cv->c_vplist;
+ cv->c_vplist = vp;
+
+ if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0)
+ return -1;
+ vp->v_canvas = cv;
+ vp->v_xs = cv->c_xs;
+ vp->v_ys = cv->c_ys;
+ vp->v_xe = cv->c_xe;
+ vp->v_ye = (3 * cv->c_ys + cv->c_ye) / 4 - 1;
+ vp->v_xoff = cv->c_xoff;
+ vp->v_yoff = cv->c_yoff;
+ vp->v_next = cv->c_vplist;
+ cv->c_vplist = vp;
+#else
+ vp->v_canvas = cv;
+ vp->v_xs = cv->c_xs;
+ vp->v_ys = cv->c_ys;
+ vp->v_xe = cv->c_xe;
+ vp->v_ye = cv->c_ye;
+ vp->v_xoff = cv->c_xoff;
+ vp->v_yoff = cv->c_yoff;
+ vp->v_next = cv->c_vplist;
+ cv->c_vplist = vp;
+#endif
+
+ if (cv->c_xs < display->d_vpxmin || display->d_vpxmin == -1)
+ display->d_vpxmin = cv->c_xs;
+ if (cv->c_xe > display->d_vpxmax || display->d_vpxmax == -1)
+ display->d_vpxmax = cv->c_xe;
+ }
+ return 0;
+}
+
+void
+RethinkViewportOffsets(cv)
+struct canvas *cv;
+{
+ struct viewport *vp;
+
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ {
+ vp->v_xoff = cv->c_xoff;
+ vp->v_yoff = cv->c_yoff;
+ }
+}
+
/*
* if the adaptflag is on, we keep the size of this display, else
* we may try to restore our old window sizes.
@@ -336,11 +651,11 @@ int adapt;
if (D_IM && strcmp(D_IM, D_EI))
PutStr(D_EI);
D_insert = 0;
- /* Check for toggle */
#ifdef MAPKEYS
PutStr(D_KS);
PutStr(D_CCS);
#else
+ /* Check for toggle */
if (D_KS && strcmp(D_KS, D_KE))
PutStr(D_KE);
if (D_CCS && strcmp(D_CCS, D_CCE))
@@ -372,16 +687,22 @@ FinitTerm()
if (D_tcinited)
{
ResizeDisplay(D_defwidth, D_defheight);
- DefRestore();
+ InsertMode(0);
+ ChangeScrollRegion(0, D_height - 1);
+ KeypadMode(0);
+ CursorkeysMode(0);
+ CursorVisibility(0);
SetRendition(&mchar_null);
+ SetFlow(FLOW_NOW);
#ifdef MAPKEYS
PutStr(D_KE);
PutStr(D_CCE);
#endif
if (D_hstatus)
- PutStr(D_DS);
+ ShowHStatus((char *)0);
D_x = D_y = -1;
GotoPos(0, D_height - 1);
+ AddChar('\r');
AddChar('\n');
PutStr(D_TE);
}
@@ -389,7 +710,7 @@ FinitTerm()
}
-void
+static void
INSERTCHAR(c)
int c;
{
@@ -444,6 +765,10 @@ int c;
D_lp_missing = 1;
D_rend.image = c;
D_lpchar = D_rend;
+#ifdef KANJI
+ D_lp_mbcs = D_mbcs;
+ D_mbcs = 0;
+#endif
}
/*
@@ -451,20 +776,24 @@ int c;
* NOTE: charset Nr. 0 has a conversion table, but c1, c2, ... don't.
*/
-void
+STATIC void
RAW_PUTCHAR(c)
int c;
{
ASSERT(display);
-#ifdef KANJI
+
+#ifdef FONT
+# ifdef KANJI
if (D_rend.font == KANJI)
{
int t = c;
if (D_mbcs == 0)
{
D_mbcs = c;
+ D_x++;
return;
}
+ D_x--;
if (D_x == D_width - 1)
D_x += D_AM ? 1 : -1;
c = D_mbcs;
@@ -493,11 +822,14 @@ int c;
c |= 0x80;
}
kanjiloop:
-#endif
+# endif
if (D_xtable && D_xtable[(int)(unsigned char)D_rend.font] && D_xtable[(int)(unsigned char)D_rend.font][(int)(unsigned char)c])
AddStr(D_xtable[(int)(unsigned char)D_rend.font][(int)(unsigned char)c]);
else
AddChar(D_rend.font != '0' ? c : D_c0_tab[(int)(unsigned char)c]);
+#else /* FONT */
+ AddChar(c);
+#endif /* FONT */
if (++D_x >= D_width)
{
@@ -520,12 +852,13 @@ int c;
#endif
}
-static void
+static int
PutChar(c)
int c;
{
/* this PutChar for ESC-sequences only (AddChar is a macro) */
AddChar(c);
+ return c;
}
void
@@ -561,7 +894,7 @@ int on;
if (display && on != D_insert && D_IM)
{
D_insert = on;
- if (D_insert)
+ if (on)
PutStr(D_IM);
else
PutStr(D_EI);
@@ -581,7 +914,7 @@ int on;
if (display && D_keypad != on && D_KS)
{
D_keypad = on;
- if (D_keypad)
+ if (on)
PutStr(D_KS);
else
PutStr(D_KE);
@@ -600,7 +933,7 @@ int on;
if (display && D_cursorkeys != on && D_CCS)
{
D_cursorkeys = on;
- if (D_cursorkeys)
+ if (on)
PutStr(D_CCS);
else
PutStr(D_CCE);
@@ -644,11 +977,12 @@ int v;
static int StrCost;
/* ARGSUSED */
-static void
+static int
CountChars(c)
int c;
{
StrCost++;
+ return c;
}
int
@@ -656,14 +990,74 @@ CalcCost(s)
register char *s;
{
ASSERT(display);
- if (!s)
+ if (s)
+ {
+ StrCost = 0;
+ ospeed = D_dospeed;
+ tputs(s, 1, CountChars);
+ return StrCost;
+ }
+ else
return EXPENSIVE;
- StrCost = 0;
- ospeed = D_dospeed;
- tputs(s, 1, CountChars);
- return StrCost;
}
+static int
+CallRewrite(y, xs, xe, doit)
+int y, xs, xe, doit;
+{
+ struct canvas *cv, *cvlist, *cvlnext;
+ struct viewport *vp;
+ struct layer *oldflayer;
+ int cost;
+
+ debug3("CallRewrite %d %d %d\n", y, xs, xe);
+ ASSERT(display);
+ ASSERT(xe >= xs);
+
+ vp = 0;
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ {
+ if (y < cv->c_ys || y > cv->c_ye || xe < cv->c_xs || xs > cv->c_xe)
+ continue;
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ if (y >= vp->v_ys && y <= vp->v_ye && xe >= vp->v_xs && xs <= vp->v_xe)
+ break;
+ if (vp)
+ break;
+ }
+ if (doit)
+ {
+ oldflayer = flayer;
+ flayer = cv->c_layer;
+ cvlist = flayer->l_cvlist;
+ cvlnext = cv->c_lnext;
+ flayer->l_cvlist = cv;
+ cv->c_lnext = 0;
+ Rewrite(y - vp->v_yoff, xs - vp->v_xoff, xe - vp->v_xoff, &D_rend, 1);
+ flayer->l_cvlist = cvlist;
+ cv->c_lnext = cvlnext;
+ flayer = oldflayer;
+ return 0;
+ }
+ if (cv == 0 || cv->c_layer == 0)
+ return EXPENSIVE; /* not found or nothing on it */
+ if (xs < vp->v_xs || xe > vp->v_xe)
+ return EXPENSIVE; /* crosses viewport boundaries */
+ if (y - vp->v_yoff < 0 || y - vp->v_yoff >= cv->c_layer->l_height)
+ return EXPENSIVE; /* line not on layer */
+ if (xs - vp->v_xoff < 0 || xe - vp->v_xoff >= cv->c_layer->l_width)
+ return EXPENSIVE; /* line not on layer */
+ oldflayer = flayer;
+ flayer = cv->c_layer;
+ debug3("Calling Rewrite %d %d %d\n", y - vp->v_yoff, xs - vp->v_xoff, xe - vp->v_xoff);
+ cost = Rewrite(y - vp->v_yoff, xs - vp->v_xoff, xe - vp->v_xoff, &D_rend, 0);
+ flayer = oldflayer;
+ if (D_insert)
+ cost += D_EIcost + D_IMcost;
+ return cost;
+}
+
+
void
GotoPos(x2, y2)
int x2, y2;
@@ -682,16 +1076,20 @@ int x2, y2;
y1 = D_y;
if (x1 == D_width)
- if (D_CLP && D_AM)
- x1 = -1; /* don't know how the terminal treats this */
- else
- x1--;
+ {
+ if (D_CLP && D_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;
+ debug2("GotoPos (%d,%d)", x1, y1);
+ debug2(" -> (%d,%d)\n", x2, y2);
if (!D_MS) /* Safe to move ? */
SetRendition(&mchar_null);
if (y1 < 0 /* don't know the y position */
@@ -731,7 +1129,7 @@ int x2, y2;
xm = M_RI;
}
/* Speedup: dx <= Rewrite() */
- if (dx < costx && (m = Rewrite(y1, x1, x2, 0)) < costx)
+ if (dx < costx && (m = CallRewrite(y1, x1, x2 - 1, 0)) < costx)
{
costx = m;
xm = M_RW;
@@ -754,7 +1152,7 @@ int x2, y2;
costx = 0;
}
/* Speedup: Rewrite() >= x2 */
- if (x2 + D_CRcost < costx && (m = (x2 ? Rewrite(y1, 0, x2, 0) : 0) + D_CRcost) < costx)
+ if (x2 + D_CRcost < costx && (m = (x2 ? CallRewrite(y1, 0, x2 - 1, 0) : 0) + D_CRcost) < costx)
{
costx = m;
xm = M_CR;
@@ -822,7 +1220,7 @@ int x2, y2;
/* FALLTHROUGH */
case M_RW:
if (x1 < x2)
- (void) Rewrite(y1, x1, x2, 1);
+ (void) CallRewrite(y1, x1, x2 - 1, 1);
break;
default:
break;
@@ -864,7 +1262,12 @@ Clear(x1, y1, xs, xe, x2, y2, uselayfn)
int x1, y1, xs, xe, x2, y2, uselayfn;
{
int y, xxe;
+ struct canvas *cv;
+ struct viewport *vp;
+ debug2("Clear %d,%d", x1, y1);
+ debug2(" %d-%d", xs, xe);
+ debug3(" %d,%d uselayfn=%d\n", x2, y2, uselayfn);
ASSERT(display);
if (x1 == D_width)
x1--;
@@ -924,9 +1327,37 @@ int x1, y1, xs, xe, x2, y2, uselayfn;
continue;
}
if (uselayfn)
- ClearLine(y, x1, xxe);
- else
- DisplayLine(&mline_null, &mline_blank, y, x1, xxe);
+ {
+ vp = 0;
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ {
+ if (y < cv->c_ys || y > cv->c_ye || xxe < cv->c_xs || x1 > cv->c_xe)
+ continue;
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ if (y >= vp->v_ys && y <= vp->v_ye && xxe >= vp->v_xs && x1 <= vp->v_xe)
+ break;
+ if (vp)
+ break;
+ }
+ if (cv && cv->c_layer && x1 >= vp->v_xs && xxe <= vp->v_xe &&
+ y - vp->v_yoff >= 0 && y - vp->v_yoff < cv->c_layer->l_height &&
+ xxe - vp->v_xoff >= 0 && x1 - vp->v_xoff < cv->c_layer->l_width)
+ {
+ struct layer *oldflayer = flayer;
+ struct canvas *cvlist, *cvlnext;
+ flayer = cv->c_layer;
+ cvlist = flayer->l_cvlist;
+ cvlnext = cv->c_lnext;
+ flayer->l_cvlist = cv;
+ cv->c_lnext = 0;
+ ClearLine(y - vp->v_yoff, x1 - vp->v_xoff, xxe - vp->v_xoff);
+ flayer->l_cvlist = cvlist;
+ cv->c_lnext = cvlnext;
+ flayer = oldflayer;
+ continue;
+ }
+ }
+ DisplayLine(&mline_null, &mline_blank, y, x1, xxe);
}
}
@@ -940,9 +1371,19 @@ Redisplay(cur_only)
int cur_only;
{
register int i, stop;
+ struct canvas *cv;
ASSERT(display);
- DefRestore();
+
+ /* XXX do em all? */
+ InsertMode(0);
+ ChangeScrollRegion(0, D_height - 1);
+ KeypadMode(0);
+ CursorkeysMode(0);
+ CursorVisibility(0);
+ SetRendition(&mchar_null);
+ SetFlow(FLOW_NOW);
+
ClearDisplay();
stop = D_height;
i = 0;
@@ -952,15 +1393,32 @@ int cur_only;
stop++;
}
else
- RedisplayLine(-1, 0, D_width - 1, 1);
- for (; i < stop; i++)
- RedisplayLine(i, 0, D_width - 1, 1);
- RefreshStatus();
- Restore();
- SetCursor();
+ {
+ debug("Signalling full refresh!\n");
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ {
+ CV_CALL(cv, RedisplayLine(-1, -1, -1, 1));
+ display = cv->c_display; /* just in case! */
+ }
+ }
+ RefreshArea(0, i, D_width - 1, stop - 1, 1);
+ RefreshHStatus();
+
+ CV_CALL(D_forecv, Restore();SetCursor());
+}
+
+void
+RedisplayDisplays(cur_only)
+int cur_only;
+{
+ struct display *olddisplay = display;
+ for (display = displays; display; display = display->d_next)
+ Redisplay(cur_only);
+ display = olddisplay;
}
+/* XXX: use oml! */
void
ScrollH(y, xs, xe, n, oml)
int y, xs, xe, n;
@@ -1028,7 +1486,7 @@ struct mline *oml;
if (D_lp_missing && y == D_bot)
{
if (n > 0)
- FixLP(D_width - 1 - n, y);
+ WriteLP(D_width - 1 - n, y);
D_lp_missing = 0;
}
}
@@ -1051,9 +1509,9 @@ int xs, ys, xe, ye, n;
Clear(xs, ys, xs, xe, xe, ye, 0);
return;
}
- if (xs != 0 || xe != D_width - 1)
+ if (xs > D_vpxmin || xe < D_vpxmax)
{
- Redisplay(0);
+ RefreshArea(xs, ys, xe, ye, 0);
return;
}
@@ -1080,10 +1538,10 @@ int xs, ys, xe, ye, n;
oldtop = D_top;
oldbot = D_bot;
- if (D_bot != ye)
+ if (ys < D_top || D_bot != ye)
ChangeScrollRegion(ys, ye);
- alok = (D_AL || D_CAL || (ye == D_bot && up));
- dlok = (D_DL || D_CDL || (ye == D_bot && !up));
+ alok = (D_AL || D_CAL || (ys >= D_top && ye == D_bot && up));
+ dlok = (D_DL || D_CDL || (ys >= D_top && ye == D_bot && !up));
if (D_top != ys && !(alok && dlok))
ChangeScrollRegion(ys, ye);
@@ -1091,18 +1549,20 @@ int xs, ys, xe, ye, n;
(oldbot != D_bot ||
(oldbot == D_bot && up && D_top == ys && D_bot == ye)))
{
- FixLP(D_width - 1, oldbot);
+ WriteLP(D_width - 1, oldbot);
if (oldbot == D_bot) /* have scrolled */
{
if (--n == 0)
{
+/* XXX
ChangeScrollRegion(oldtop, oldbot);
+*/
return;
}
}
}
- aldlfaster = (n > 1 && ye == D_bot && ((up && D_CDL) || (!up && D_CAL)));
+ aldlfaster = (n > 1 && ys >= D_top && ye == D_bot && ((up && D_CDL) || (!up && D_CAL)));
if (D_UT)
SetRendition(&mchar_null);
@@ -1144,14 +1604,16 @@ int xs, ys, xe, ye, n;
}
else
{
- Redisplay(0);
+ RefreshArea(xs, ys, xe, ye, 0);
return;
}
if (D_lp_missing && missy != D_bot)
- FixLP(D_width - 1, missy);
+ WriteLP(D_width - 1, missy);
+/* XXX
ChangeScrollRegion(oldtop, oldbot);
if (D_lp_missing && missy != D_bot)
- FixLP(D_width - 1, missy);
+ WriteLP(D_width - 1, missy);
+*/
}
void
@@ -1163,11 +1625,11 @@ register int new;
if (!display || (old = D_rend.attr) == new)
return;
#if defined(TERMINFO) && defined(USE_SGR)
- debug1("USE_SGR defined, sa is %s\n", D_SA ? D_SA : "undefined");
if (D_SA)
{
char *tparm();
SetFont(ASCII);
+ ospeed = D_dospeed;
tputs(tparm(D_SA, new & A_SO, new & A_US, new & A_RV, new & A_BL,
new & A_DI, new & A_BD, 0 , 0 ,
0), 1, PutChar);
@@ -1215,6 +1677,7 @@ register int new;
D_atyp = typ;
}
+#ifdef FONT
void
SetFont(new)
int new;
@@ -1248,6 +1711,7 @@ int new;
else
CPutStr(D_CS0, new);
}
+#endif
#ifdef COLOR
void
@@ -1263,7 +1727,7 @@ int new;
f = new & 0xf;
b = (new >> 4) & 0xf;
- if (!D_CAX && ((f == 0 && f != of) || (b == 0 && b != ob)))
+ if (!D_CAX && (D_CAF || D_CAB) && ((f == 0 && f != of) || (b == 0 && b != ob)))
{
int oattr;
@@ -1297,8 +1761,10 @@ struct mchar *mc;
if (D_rend.color != mc->color)
SetColor(mc->color);
#endif
+#ifdef FONT
if (D_rend.font != mc->font)
SetFont(mc->font);
+#endif
}
void
@@ -1314,8 +1780,10 @@ int x;
if (D_rend.color != ml->color[x])
SetColor(ml->color[x]);
#endif
+#ifdef FONT
if (D_rend.font != ml->font[x])
SetFont(ml->font[x]);
+#endif
}
void
@@ -1331,6 +1799,8 @@ char *msg;
if (!D_tcinited)
{
debug("tc not inited, just writing msg\n");
+ if (D_processinputdata)
+ return; /* XXX: better */
AddStr(msg);
AddStr("\r\n");
Flush();
@@ -1346,9 +1816,16 @@ char *msg;
max = D_WS;
if (D_status)
{
+ /* same message? */
+ if (strcmp(msg, D_status_lastmsg) == 0)
+ {
+ debug("same message - increase timeout");
+ SetTimeout(&D_statusev, MsgWait * 1000);
+ return;
+ }
if (!D_status_bell)
{
- ti = time((time_t *) 0) - D_status_time;
+ ti = time((time_t *)0) - D_status_time;
if (ti < MsgMinWait)
sleep(MsgMinWait - ti);
}
@@ -1360,144 +1837,228 @@ char *msg;
else if ((unsigned char)*s >= ' ' && *s != 0177)
*t++ = *s;
*t = '\0';
- if (t > msg)
+ if (t == msg)
+ return;
+ if (t - msg >= D_status_buflen)
{
- 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 || !D_HS)
+ char *buf;
+ if (D_status_lastmsg)
+ buf = realloc(D_status_lastmsg, t - msg + 1);
+ else
+ buf = malloc(t - msg + 1);
+ if (buf)
{
- debug1("using STATLINE %d\n", STATLINE);
- GotoPos(0, STATLINE);
- SetRendition(&mchar_so);
- InsertMode(0);
- AddStr(msg);
- D_x = -1;
+ D_status_lastmsg = buf;
+ D_status_buflen = t - msg + 1;
}
- else
+ }
+ if (t - msg < D_status_buflen)
+ strcpy(D_status_lastmsg, msg);
+ D_status_len = t - msg;
+ D_status_lastx = D_x;
+ D_status_lasty = D_y;
+ if (!use_hardstatus || D_has_hstatus == HSTATUS_IGNORE || D_has_hstatus == HSTATUS_MESSAGE)
+ {
+ if (D_status_delayed != -1 && t - msg < D_status_buflen)
{
- debug("using HS\n");
- SetRendition(&mchar_null);
- InsertMode(0);
- if (D_hstatus)
- PutStr(D_DS);
- CPutStr(D_TS, 0);
- AddStr(msg);
- PutStr(D_FS);
- D_hstatus = 1;
+ D_status_delayed = 1; /* not yet... */
+ D_status = 0;
+ return;
}
- Flush();
- (void) time(&D_status_time);
+ D_status = STATUS_ON_WIN;
+ debug1("using STATLINE %d\n", STATLINE);
+ GotoPos(0, STATLINE);
+ SetRendition(&mchar_so);
+ InsertMode(0);
+ AddStr(msg);
+ if (D_status_len < max)
+ {
+ /* Wayne Davison: add extra space for readability */
+ D_status_len++;
+ SetRendition(&mchar_null);
+ AddChar(' ');
+ if (D_status_len < max)
+ {
+ D_status_len++;
+ AddChar(' ');
+ AddChar('\b');
+ }
+ AddChar('\b');
+ }
+ D_x = -1;
}
+ else
+ {
+ D_status = STATUS_ON_HS;
+ ShowHStatus(msg);
+ }
+ D_status_delayed = 0;
+ Flush();
+ (void) time(&D_status_time);
+ SetTimeout(&D_statusev, MsgWait * 1000);
+ evenq(&D_statusev);
+#ifdef HAVE_BRAILLE
+ RefreshBraille(); /* let user see multiple Msg()s */
+#endif
}
void
RemoveStatus()
{
- struct win *p;
+ struct display *olddisplay;
+ struct layer *oldflayer;
+ int where;
if (!display)
return;
- if (!D_status)
+ if (!(where = 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 || !D_HS)
+ evdeq(&D_statusev);
+ olddisplay = display;
+ oldflayer = flayer;
+ if (where == STATUS_ON_WIN)
{
GotoPos(0, STATLINE);
RefreshLine(STATLINE, 0, D_status_len - 1, 0);
GotoPos(D_status_lastx, D_status_lasty);
}
else
+ RefreshHStatus();
+ flayer = D_forecv->c_layer;
+ if (flayer)
+ SetCursor();
+ display = olddisplay;
+ flayer = oldflayer;
+}
+
+/* refresh the display's hstatus line */
+void
+ShowHStatus(str)
+char *str;
+{
+ int l, i, ox, oy;
+
+ if (D_status == STATUS_ON_WIN && D_has_hstatus == HSTATUS_LASTLINE && STATLINE == D_height-1)
+ return; /* sorry, in use */
+
+ if (D_HS && D_has_hstatus == HSTATUS_HS)
{
- /*
+ if (!D_hstatus && (str == 0 || *str == 0))
+ return;
+ debug("ShowHStatus: using HS\n");
SetRendition(&mchar_null);
+ InsertMode(0);
if (D_hstatus)
- PutStr(D_DS);
- */
- RefreshStatus();
+ PutStr(D_DS);
+ D_hstatus = 0;
+ if (str == 0 || *str == 0)
+ return;
+ CPutStr(D_TS, 0);
+ if (strlen(str) > D_WS)
+ AddStrn(str, D_WS);
+ else
+ AddStr(str);
+ PutStr(D_FS);
+ D_hstatus = 1;
+ }
+ else if (D_has_hstatus == HSTATUS_LASTLINE)
+ {
+ debug("ShowHStatus: using last line\n");
+ ox = D_x;
+ oy = D_y;
+ str = str ? str : "";
+ l = strlen(str);
+ if (l > D_width)
+ l = D_width;
+ GotoPos(0, D_height - 1);
+ SetRendition(captionalways || D_cvlist == 0 || D_cvlist->c_next ? &mchar_null: &mchar_so);
+ for (i = 0; i < l; i++)
+ PUTCHARLP(str[i]);
+ if (!captionalways && D_cvlist && !D_cvlist->c_next)
+ while (l++ < D_width)
+ PUTCHARLP(' ');
+ if (l < D_width)
+ Clear(l, D_height - 1, l, D_width - 1, D_width - 1, D_height - 1, 0);
+ if (ox != -1 && oy != -1)
+ GotoPos(ox, oy);
+ D_hstatus = *str ? 1 : 0;
+ SetRendition(&mchar_null);
+ }
+ else if (str && *str && D_has_hstatus == HSTATUS_MESSAGE)
+ {
+ debug("ShowHStatus: using message\n");
+ Msg(0, "%s", str);
}
- SetCursor();
}
+
/*
- * Refreshes the harstatus of the _window_. Shouldn't be here...
+ * Refreshes the harstatus of the fore window. Shouldn't be here...
*/
-
void
-RefreshStatus()
+RefreshHStatus()
{
char *buf;
- if (D_HS)
+ evdeq(&D_hstatusev);
+ if (D_status == STATUS_ON_HS)
+ return;
+ buf = MakeWinMsgEv(hstatusstring, D_fore, '%', &D_hstatusev);
+ if (buf && *buf)
{
- SetRendition(&mchar_null);
- if (D_hstatus)
- PutStr(D_DS);
- if (D_fore && D_fore->w_hstatus)
- {
- buf = MakeWinMsg(D_fore->w_hstatus, D_fore, '\005');
- CPutStr(D_TS, 0);
- if (strlen(buf) > D_WS)
- AddStrn(buf, D_WS);
- else
- AddStr(buf);
- PutStr(D_FS);
- D_hstatus = 1;
- }
+ ShowHStatus(buf);
+ if (D_has_hstatus != HSTATUS_IGNORE && D_hstatusev.timeout.tv_sec)
+ evenq(&D_hstatusev);
}
- else if (D_fore && D_fore->w_hstatus)
+ else
+ ShowHStatus((char *)0);
+}
+
+/*********************************************************************/
+/*
+ * Here come the routines that refresh an arbitrary part of the screen.
+ */
+
+void
+RefreshArea(xs, ys, xe, ye, isblank)
+int xs, ys, xe, ye, isblank;
+{
+ int y;
+ ASSERT(display);
+ debug2("Refresh Area: %d,%d", xs, ys);
+ debug3(" - %d,%d (isblank=%d)\n", xe, ye, isblank);
+ if (!isblank && xs == 0 && xe == D_width - 1 && ye == D_height - 1 && (ys == 0 || D_CD))
{
- buf = MakeWinMsg(D_fore->w_hstatus, D_fore, '\005');
- Msg(0, "%s", buf);
+ Clear(xs, ys, xs, xe, xe, ye, 0);
+ isblank = 1;
}
+ for (y = ys; y <= ye; y++)
+ RefreshLine(y, xs, xe, isblank);
}
void
RefreshLine(y, from, to, isblank)
int y, from, to, isblank;
{
+ struct viewport *vp, *lvp;
+ struct canvas *cv, *lcv, *cvlist, *cvlnext;
+ struct layer *oldflayer;
+ int xx, yy;
+ char *buf;
+ struct win *p;
+
ASSERT(display);
+
debug2("RefreshLine %d %d", y, from);
debug2(" %d %d\n", to, isblank);
- if (isblank == 0 && D_CE && to == D_width - 1)
+
+ if (D_status == STATUS_ON_WIN && y == STATLINE)
+ return; /* can't refresh status */
+
+ if (isblank == 0 && D_CE && to == D_width - 1 && from < to)
{
GotoPos(from, y);
if (D_UT)
@@ -1505,17 +2066,129 @@ int y, from, to, isblank;
PutStr(D_CE);
isblank = 1;
}
- RedisplayLine(y, from, to, isblank);
+ while (from <= to)
+ {
+ lcv = 0;
+ lvp = 0;
+ for (cv = display->d_cvlist; cv; cv = cv->c_next)
+ {
+ if (y < cv->c_ys || y > cv->c_ye || to < cv->c_xs || from > cv->c_xe)
+ continue;
+ debug2("- canvas hit: %d %d", cv->c_xs, cv->c_ys);
+ debug2(" %d %d\n", cv->c_xe, cv->c_ye);
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ {
+ debug2(" - vp: %d %d", vp->v_xs, vp->v_ys);
+ debug2(" %d %d\n", vp->v_xe, vp->v_ye);
+ /* find leftmost overlapping vp */
+ if (y >= vp->v_ys && y <= vp->v_ye && from <= vp->v_xe && to >= vp->v_xs && (lvp == 0 || lvp->v_xs > vp->v_xs))
+ {
+ lcv = cv;
+ lvp = vp;
+ }
+ }
+ }
+ if (lvp == 0)
+ break;
+ if (from < lvp->v_xs)
+ {
+ if (!isblank)
+ DisplayLine(&mline_null, &mline_blank, y, from, lvp->v_xs - 1);
+ from = lvp->v_xs;
+ }
+
+ /* call RedisplayLine on canvas lcv viewport lvp */
+ yy = y - lvp->v_yoff;
+ xx = to < lvp->v_xe ? to : lvp->v_xe;
+
+ if (lcv->c_layer && yy == lcv->c_layer->l_height)
+ {
+ GotoPos(from, y);
+ SetRendition(&mchar_blank);
+ while (from <= lvp->v_xe && from - lvp->v_xoff < lcv->c_layer->l_width)
+ {
+ PUTCHARLP('-');
+ from++;
+ }
+ if (from >= lvp->v_xe + 1)
+ continue;
+ }
+ if (lcv->c_layer == 0 || yy >= lcv->c_layer->l_height || from - lvp->v_xoff >= lcv->c_layer->l_width)
+ {
+ if (!isblank)
+ DisplayLine(&mline_null, &mline_blank, y, from, lvp->v_xe);
+ from = lvp->v_xe + 1;
+ continue;
+ }
+
+ if (xx - lvp->v_xoff >= lcv->c_layer->l_width)
+ xx = lcv->c_layer->l_width + lvp->v_xoff - 1;
+ oldflayer = flayer;
+ flayer = lcv->c_layer;
+ cvlist = flayer->l_cvlist;
+ cvlnext = lcv->c_lnext;
+ flayer->l_cvlist = lcv;
+ lcv->c_lnext = 0;
+ RedisplayLine(yy, from - lvp->v_xoff, xx - lvp->v_xoff, isblank);
+ flayer->l_cvlist = cvlist;
+ lcv->c_lnext = cvlnext;
+ flayer = oldflayer;
+
+ from = xx + 1;
+ }
+ if (from > to)
+ return; /* all done */
+
+ if (y == D_height - 1 && D_has_hstatus == HSTATUS_LASTLINE)
+ {
+ RefreshHStatus();
+ return;
+ }
+
+ for (cv = display->d_cvlist; cv; cv = cv->c_next)
+ if (y == cv->c_ye + 1)
+ break;
+ if (cv == 0)
+ {
+ if (!isblank)
+ DisplayLine(&mline_null, &mline_blank, y, from, to);
+ return;
+ }
+
+ p = Layer2Window(cv->c_layer);
+ buf = MakeWinMsgEv(captionstring, p, '%', &cv->c_captev);
+ if (cv->c_captev.timeout.tv_sec)
+ evenq(&cv->c_captev);
+ xx = strlen(buf);
+ GotoPos(from, y);
+ SetRendition(&mchar_so);
+ while (from <= to && from < xx)
+ {
+ PUTCHARLP(buf[from]);
+ from++;
+ }
+ while (from++ <= to)
+ PUTCHARLP(' ');
}
-void
-FixLP(x2, y2)
-register int x2, y2;
+/*********************************************************************/
+
+/* clear lp_missing by writing the char on the screen. The
+ * position must be safe.
+ */
+static void
+WriteLP(x2, y2)
+int x2, y2;
{
struct mchar oldrend;
ASSERT(display);
+ ASSERT(D_lp_missing);
oldrend = D_rend;
+#ifdef KANJI
+ if (D_lpchar.font == KANJI && (D_mbcs = D_lp_mbcs) != 0 && x2 > 0)
+ x2--;
+#endif
GotoPos(x2, y2);
SetRendition(&D_lpchar);
PUTCHAR(D_lpchar.image);
@@ -1536,29 +2209,42 @@ int from, to, y;
ASSERT(from >= 0 && from < D_width);
ASSERT(to >= 0 && to < D_width);
if (!D_CLP && y == D_bot && to == D_width - 1)
- if (D_lp_missing || !cmp_mline(oml, ml, to))
- {
- if ((D_IC || D_IM) && from < to)
- {
- to -= 2;
- last2flag = 1;
- D_lp_missing = 0;
- }
- else
- {
- to--;
- delete_lp = (D_CE || D_DC || D_CDC);
- D_lp_missing = !cmp_mchar_mline(&mchar_blank, ml, to);
- copy_mline2mchar(&D_lpchar, ml, to);
- }
- }
- else
- to--;
+ {
+ if (D_lp_missing || !cmp_mline(oml, ml, to))
+ {
+ if ((D_IC || D_IM) && from < to)
+ {
+ to -= 2;
+ last2flag = 1;
+ D_lp_missing = 0;
+ }
+ else
+ {
+ to--;
+ delete_lp = (D_CE || D_DC || D_CDC);
+ D_lp_missing = !cmp_mchar_mline(&mchar_blank, ml, to);
+ copy_mline2mchar(&D_lpchar, ml, to);
+ }
+ }
+ else
+ to--;
+ }
+#ifdef KANJI
+ if (D_mbcs)
+ {
+ /* finish kanji (can happen after a wrap) */
+ SetRenditionMline(ml, from);
+ PUTCHAR(ml->image[from]);
+ from++;
+ }
+#endif
for (x = from; x <= to; x++)
{
+#if 0 /* no longer needed */
if (x || D_x != D_width || D_y != y - 1)
+#endif
{
- if (x < to || x != D_width - 1 || ml->image[x + 1] == ' ')
+ if (x < to || x != D_width - 1 || ml->image[x + 1])
if (cmp_mline(oml, ml, x))
continue;
GotoPos(x, y);
@@ -1567,8 +2253,11 @@ int from, to, y;
if (badkanji(ml->font, x))
{
x--;
+ debug1("DisplayLine badkanji - x now %d\n", x);
GotoPos(x, y);
}
+ if (ml->font[x] == KANJI && x == to)
+ break; /* don't start new kanji */
#endif
SetRenditionMline(ml, x);
PUTCHAR(ml->image[x]);
@@ -1577,8 +2266,11 @@ int from, to, y;
PUTCHAR(ml->image[++x]);
#endif
}
- if (to == D_width - 1 && y < D_height - 1 && ml->image[to + 1] == ' ')
+#if 0 /* not needed any longer */
+ /* compare != 0 because ' ' can happen when clipping occures */
+ if (to == D_width - 1 && y < D_height - 1 && D_x == D_width && ml->image[to + 1])
GotoPos(0, y + 1);
+#endif
if (last2flag)
{
GotoPos(x, y);
@@ -1591,9 +2283,7 @@ int from, to, y;
else if (delete_lp)
{
if (D_UT)
- {
- SetRendition(&mchar_null);
- }
+ SetRendition(&mchar_null);
if (D_DC)
PutStr(D_DC);
else if (D_CDC)
@@ -1604,12 +2294,118 @@ int from, to, y;
}
void
-SetLastPos(x,y)
-int x,y;
+InsChar(c, x, xe, y, oml)
+struct mchar *c;
+int x, xe, y;
+struct mline *oml;
{
- ASSERT(display);
- D_x = x;
+ GotoPos(x, y);
+ if (y == D_bot && !D_CLP)
+ {
+ if (x == D_width - 1)
+ {
+ D_lpchar = *c;
+ return;
+ }
+ if (xe == D_width - 1)
+ D_lp_missing = 0;
+ }
+ if (x == xe)
+ {
+ if (xe != D_width - 1)
+ InsertMode(0);
+ SetRendition(c);
+ RAW_PUTCHAR(c->image);
+ return;
+ }
+ if (!(D_IC || D_CIC || D_IM) || xe != D_width - 1)
+ {
+ RefreshLine(y, x, xe, 0);
+ GotoPos(x + 1, y);
+ /* UpdateLine(oml, y, x, xe); */
+ return;
+ }
+ InsertMode(1);
+ if (!D_insert)
+ {
+ if (D_IC)
+ PutStr(D_IC);
+ else
+ CPutStr(D_CIC, 1);
+ }
+ SetRendition(c);
+ RAW_PUTCHAR(c->image);
+}
+
+void
+WrapChar(c, x, y, xs, ys, xe, ye, ins)
+struct mchar *c;
+int x, y;
+int xs, ys, xe, ye;
+int ins;
+{
+ debug("WrapChar:");
+ debug2(" x %d y %d", x, y);
+ debug2(" Dx %d Dy %d", D_x, D_y);
+ debug2(" xs %d ys %d", xs, ys);
+ debug3(" xe %d ye %d ins %d\n", xe, ye, ins);
+ if (xs != 0 || x != D_width || !D_AM)
+ {
+ if (y == ye)
+ ScrollV(xs, ys, xe, ye, 1);
+ else if (y < D_height - 1)
+ y++;
+ GotoPos(xs, y);
+ if (ins)
+ {
+ InsChar(c, xs, xe, y, 0);
+ return;
+ }
+ SetRendition(c);
+ RAW_PUTCHAR(c->image);
+ return;
+ }
+ if (y == ye) /* we have to scroll */
+ {
+ debug("- scrolling\n");
+ ChangeScrollRegion(ys, ye);
+ if (D_bot != y)
+ {
+ debug("- have to call ScrollV\n");
+ ScrollV(xs, ys, xe, ye, 1);
+ y--;
+ }
+ }
+ else if (y == D_bot)
+ ChangeScrollRegion(ys, ye); /* remove unusable region */
+ if (D_x != D_width || D_y != y)
+ {
+ if (D_CLP && y >= 0) /* don't even try if !LP */
+ RefreshLine(y, D_width - 1, D_width - 1, 0);
+ debug2("- refresh last char -> x,y now %d,%d\n", D_x, D_y);
+ if (D_x != D_width || D_y != y) /* sorry, no bonus */
+ {
+ if (y == ye)
+ ScrollV(xs, ys, xe, ye, 1);
+ GotoPos(xs, y == ye || y == D_height - 1 ? y : y + 1);
+ }
+ }
+ debug("- writeing new char");
+ if (y != ye && y < D_height - 1)
+ y++;
+ if (ins != D_insert)
+ InsertMode(ins);
+ if (ins && !D_insert)
+ {
+ InsChar(c, 0, xe, y, 0);
+ debug2(" -> done with insert (%d,%d)\n", D_x, D_y);
+ return;
+ }
+ SetRendition(c);
D_y = y;
+ D_x = 0;
+ RAW_PUTCHAR(c->image);
+ debug2(" -> done (%d,%d)\n", D_x, D_y);
}
int
@@ -1623,6 +2419,13 @@ int wi, he;
debug("ResizeDisplay: No change\n");
return 0;
}
+ if (D_width != wi && (D_height == he || !D_CWS) && D_CZ0 && (wi == Z0width || wi == Z1width))
+ {
+ debug("ResizeDisplay: using Z0/Z1\n");
+ PutStr(wi == Z0width ? D_CZ0 : D_CZ1);
+ ChangeScreenSize(wi, D_height, 0);
+ return (he == D_height) ? 0 : -1;
+ }
if (D_CWS)
{
debug("ResizeDisplay: using WS\n");
@@ -1630,13 +2433,6 @@ int wi, he;
ChangeScreenSize(wi, he, 0);
return 0;
}
- else if (D_CZ0 && (wi == Z0width || wi == Z1width))
- {
- debug("ResizeDisplay: using Z0/Z1\n");
- PutStr(wi == Z0width ? D_CZ0 : D_CZ1);
- ChangeScreenSize(wi, D_height, 0);
- return (he == D_height) ? 0 : -1;
- }
return -1;
}
@@ -1646,6 +2442,10 @@ int newtop, newbot;
{
if (display == 0)
return;
+ if (newtop == -1)
+ newtop = 0;
+ if (newbot == -1)
+ newbot = D_height - 1;
if (D_CS == 0)
{
D_top = 0;
@@ -1663,73 +2463,6 @@ int newtop, newbot;
/*
- * 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((char *)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((char *)oldlay);
- if (D_fore)
- D_fore->w_lay = D_lay; /* XXX: Is this necessary ? */
- Restore();
- SetCursor();
-}
-
-
-/*
* Output buffering routines
*/
@@ -1740,6 +2473,7 @@ char *str;
register char c;
ASSERT(display);
+
while ((c = *str++))
AddChar(c);
}
@@ -1796,6 +2530,8 @@ Flush()
}
D_obuffree += l;
D_obufp = D_obuf;
+ if (D_nonblock > 1)
+ D_nonblock = 1; /* reenable flow control for WriteString */
if (fcntl(D_userfd, F_SETFL, FNBLOCK))
debug1("Warning: NBLOCK fcntl failed: %d\n", errno);
}
@@ -1813,6 +2549,7 @@ freetty()
free(D_obuf);
D_obuf = 0;
D_obuflen = 0;
+ D_obuflenmax = -D_obufmax;
}
/*
@@ -1843,6 +2580,7 @@ Resize_obuf()
if (!D_obuf)
Panic(0, "Out of memory");
D_obufp = D_obuf + ind;
+ D_obuflenmax = D_obuflen - D_obufmax;
debug1("ResizeObuf: resized to %d\n", D_obuflen);
}
@@ -1879,10 +2617,13 @@ NukePending()
PutStr(D_ME);
else
{
+#ifdef COLOR
+ if (D_CAF)
+ AddStr("\033[m"); /* why is D_ME not set? */
+#endif
PutStr(D_SE);
PutStr(D_UE);
}
- /* FIXME: reset color! */
/* Check for toggle */
if (D_IM && strcmp(D_IM, D_EI))
PutStr(D_EI);
@@ -1933,11 +2674,163 @@ char *f;
int x;
{
int i, j;
- if (f[x] != KANJI)
+
+ f += x;
+ if (*f-- != KANJI)
return 0;
- for (i = j = 0; i < x; i++)
- if (*f++ == KANJI)
- j ^= 1;
+ for (j = 0, i = x - 1; i >= 0; i--, j ^= 1)
+ if (*f-- != KANJI)
+ break;
return j;
}
#endif
+
+static void
+disp_writeev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ int len, size = OUTPUT_BLOCK_SIZE;
+
+ display = (struct display *)data;
+ len = D_obufp - D_obuf;
+ if (len < size)
+ size = len;
+ ASSERT(len >= 0);
+ size = write(D_userfd, D_obuf, size);
+ if (size >= 0)
+ {
+ len -= size;
+ if (len)
+ {
+ bcopy(D_obuf + size, D_obuf, len);
+ debug2("ASYNC: wrote %d - remaining %d\n", size, len);
+ }
+ /* Great, reenable flow control for WriteString now. */
+ if ((D_nonblock > 1) && (len < D_obufmax/2))
+ D_nonblock = 1;
+ D_obufp -= size;
+ D_obuffree += size;
+ }
+ else
+ {
+ if (errno != EINTR)
+# ifdef EWOULDBLOCK
+ if (errno != EWOULDBLOCK)
+# endif
+ Msg(errno, "Error writing output to display");
+ }
+}
+
+static void
+disp_readev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ int size;
+ char buf[IOSIZE];
+ struct canvas *cv;
+
+ display = (struct display *)data;
+
+ /* Hmmmm... a bit ugly... */
+ if (D_forecv)
+ for (cv = D_forecv->c_layer->l_cvlist; cv; cv = cv->c_lnext)
+ {
+ display = cv->c_display;
+ if (D_status == STATUS_ON_WIN)
+ RemoveStatus();
+ }
+
+ display = (struct display *)data;
+ if (D_fore == 0)
+ size = IOSIZE;
+ else
+ {
+#ifdef PSEUDOS
+ if (W_UWP(D_fore))
+ size = sizeof(D_fore->w_pwin->p_inbuf) - D_fore->w_pwin->p_inlen;
+ else
+#endif
+ size = sizeof(D_fore->w_inbuf) - D_fore->w_inlen;
+ }
+
+ if (size > IOSIZE)
+ size = IOSIZE;
+ if (size <= 0)
+ size = 1; /* Always allow one char for command keys */
+
+ size = read(D_userfd, buf, size);
+ if (size < 0)
+ {
+ if (errno == EINTR)
+ return;
+ debug1("Read error: %d - SigHup()ing!\n", errno);
+ SigHup(SIGARG);
+ sleep(1);
+ return;
+ }
+ else if (size == 0)
+ {
+ debug("Found EOF - SigHup()ing!\n");
+ SigHup(SIGARG);
+ sleep(1);
+ return;
+ }
+ (*D_processinput)(buf, size);
+}
+
+static void
+disp_status_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ display = (struct display *)data;
+ if (D_status)
+ RemoveStatus();
+}
+
+static void
+disp_hstatus_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ display = (struct display *)data;
+ RefreshHStatus();
+}
+
+static void
+cv_winid_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ int ox, oy;
+ struct canvas *cv = (struct canvas *)data;
+
+ display = cv->c_display;
+ ox = D_x;
+ oy = D_y;
+ if (cv->c_ye + 1 < D_height)
+ RefreshLine(cv->c_ye + 1, 0, D_width - 1, 0);
+ if (ox != -1 && oy != -1)
+ GotoPos(ox, oy);
+}
+
+#ifdef MAPKEYS
+static void
+disp_map_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ char *p;
+ int l;
+ display = (struct display *)data;
+ debug("Flushing map sequence\n");
+ if (!(l = D_seql))
+ return;
+ p = D_seqp - l;
+ D_seqp = D_kmaps[0].seq;
+ D_seql = 0;
+ ProcessInput2(p, l);
+}
+#endif