summaryrefslogtreecommitdiff
path: root/src/display.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/display.c')
-rw-r--r--src/display.c1429
1 files changed, 245 insertions, 1184 deletions
diff --git a/src/display.c b/src/display.c
index 3e0bdae..5fc5f4b 100644
--- a/src/display.c
+++ b/src/display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008
+/* Copyright (c) 2008, 2009
* Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
* Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
* Micah Cowan (micah@cowan.name)
@@ -37,12 +37,12 @@
#include "screen.h"
#include "extern.h"
#include "braille.h"
+#include "canvas.h"
static int CountChars __P((int));
static int DoAddChar __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 *));
#ifdef linux
@@ -65,8 +65,7 @@ static void RAW_PUTCHAR __P((int));
#ifdef COLOR
static void SetBackColor __P((int));
#endif
-static void FreePerp __P((struct canvas *));
-static struct canvas *AddPerp __P((struct canvas *));
+static void RemoveStatusMinWait __P((void));
extern struct layer *flayer;
@@ -122,6 +121,7 @@ struct display TheDisplay;
*/
int defobuflimit = OBUF_MAX;
int defnonblock = -1;
+int defmousetrack = 0;
#ifdef AUTO_NUKE
int defautonuke = 0;
#endif
@@ -200,7 +200,8 @@ struct LayFuncs BlankLf =
DefClearLine,
DefRewrite,
BlankResize,
- DefRestore
+ DefRestore,
+ 0
};
/*ARGSUSED*/
@@ -313,6 +314,7 @@ struct mode *Mode;
D_termname[sizeof(D_termname) - 1] = 0;
D_user = *u;
D_processinput = ProcessInput;
+ D_mousetrack = defmousetrack;
return display;
}
@@ -333,7 +335,7 @@ FreeDisplay()
#endif
if (D_userfd >= 0)
{
- Flush();
+ Flush(3);
if (!display)
return;
SetTTY(D_userfd, &D_OldMode);
@@ -411,738 +413,17 @@ FreeDisplay()
if (p->w_zdisplay == display)
zmodem_abort(p, 0);
#endif
+ if (D_mousetrack)
+ {
+ D_mousetrack = 0;
+ MouseMode(0);
+ }
#ifdef MULTI
free((char *)display);
#endif
display = 0;
}
-static void
-CanvasInitBlank(cv)
-struct canvas *cv;
-{
- 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;
-}
-
-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;
- debug2("MakeDefaultCanvas 0,0 %d,%d\n", cv->c_xe, cv->c_ye);
- cv->c_xoff = 0;
- cv->c_yoff = 0;
- cv->c_next = 0;
- cv->c_display = display;
- cv->c_vplist = 0;
- cv->c_slnext = 0;
- cv->c_slprev = 0;
- cv->c_slperp = 0;
- cv->c_slweight = 1;
- cv->c_slback = &D_canvas;
- D_canvas.c_slperp = cv;
- D_canvas.c_xs = cv->c_xs;
- D_canvas.c_xe = cv->c_xe;
- D_canvas.c_ys = cv->c_ys;
- D_canvas.c_ye = cv->c_ye;
- cv->c_slorient = SLICE_UNKN;
- cv->c_captev.type = EV_TIMEOUT;
- cv->c_captev.data = (char *)cv;
- cv->c_captev.handler = cv_winid_fn;
-
- CanvasInitBlank(cv);
- cv->c_lnext = 0;
-
- D_cvlist = cv;
- RethinkDisplayViewports();
- D_forecv = cv; /* default input focus */
- return 0;
-}
-
-static struct canvas **
-CreateCanvasChainRec(cv, cvp)
-struct canvas *cv;
-struct canvas **cvp;
-{
- for (; cv; cv = cv->c_slnext)
- {
- if (cv->c_slperp)
- cvp = CreateCanvasChainRec(cv->c_slperp, cvp);
- else
- {
- *cvp = cv;
- cvp = &cv->c_next;
- }
- }
- return cvp;
-}
-
-void
-RecreateCanvasChain()
-{
- struct canvas **cvp;
- cvp = CreateCanvasChainRec(D_canvas.c_slperp, &D_cvlist);
- *cvp = 0;
-}
-
-static void
-FreeCanvas(cv)
-struct canvas *cv;
-{
- struct viewport *vp, *nvp;
- struct canvas **cvp;
- struct win *p;
-
- if (cv->c_slprev)
- cv->c_slprev->c_slnext = cv->c_slnext;
- if (cv->c_slnext)
- cv->c_slnext->c_slprev = cv->c_slprev;
- if (cv->c_slback && cv->c_slback->c_slperp == cv)
- cv->c_slback->c_slperp = cv->c_slnext ? cv->c_slnext : cv->c_slprev;
- if (cv->c_slperp)
- {
- while (cv->c_slperp)
- FreeCanvas(cv->c_slperp);
- free(cv);
- return;
- }
-
- if (display)
- {
- if (D_forecv == cv)
- D_forecv = 0;
- /* remove from canvas chain as SetCanvasWindow might call
- * some layer function */
- for (cvp = &D_cvlist; *cvp ; cvp = &(*cvp)->c_next)
- if (*cvp == cv)
- {
- *cvp = cv->c_next;
- break;
- }
- }
- p = cv->c_layer ? Layer2Window(cv->c_layer) : 0;
- 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
-CountCanvas(cv)
-struct canvas *cv;
-{
- int num = 0;
- for (; cv; cv = cv->c_slnext)
- {
- if (cv->c_slperp)
- {
- struct canvas *cvp;
- int nump = 1, n;
- for (cvp = cv->c_slperp; cvp; cvp = cvp->c_slnext)
- if (cvp->c_slperp)
- {
- n = CountCanvas(cvp->c_slperp);
- if (n > nump)
- nump = n;
- }
- num += nump;
- }
- else
- num++;
- }
- return num;
-}
-
-int
-CountCanvasPerp(cv)
-struct canvas *cv;
-{
- struct canvas *cvp;
- int num = 1, n;
- for (cvp = cv->c_slperp; cvp; cvp = cvp->c_slnext)
- if (cvp->c_slperp)
- {
- n = CountCanvas(cvp->c_slperp);
- if (n > num)
- num = n;
- }
- return num;
-}
-
-void
-EqualizeCanvas(cv, gflag)
-struct canvas *cv;
-int gflag;
-{
- struct canvas *cv2;
- for (; cv; cv = cv->c_slnext)
- {
- if (cv->c_slperp && gflag)
- {
- cv->c_slweight = CountCanvasPerp(cv);
- for (cv2 = cv->c_slperp; cv2; cv2 = cv2->c_slnext)
- if (cv2->c_slperp)
- EqualizeCanvas(cv2->c_slperp, gflag);
- }
- else
- cv->c_slweight = 1;
- }
-}
-
-void
-ResizeCanvas(cv)
-struct canvas *cv;
-{
- struct canvas *cv2, *cvn, *fcv;
- int nh, i, maxi, hh, m, w, wsum;
- int need, got;
- int xs, ys, xe, ye;
- int focusmin = 0;
-
- xs = cv->c_xs;
- ys = cv->c_ys;
- xe = cv->c_xe;
- ye = cv->c_ye;
- cv = cv->c_slperp;
- debug2("ResizeCanvas: %d,%d", xs, ys);
- debug2(" %d,%d\n", xe, ye);
- if (cv == 0)
- return;
- if (cv->c_slorient == SLICE_UNKN)
- {
- ASSERT(!cv->c_slnext && !cv->c_slperp);
- cv->c_xs = xs;
- cv->c_xe = xe;
- cv->c_ys = ys;
- cv->c_ye = ye;
- cv->c_xoff = cv->c_xs;
- cv->c_yoff = cv->c_ys;
- cv->c_blank.l_width = cv->c_xe - cv->c_xs + 1;
- cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1;
- return;
- }
-
- fcv = 0;
- if (focusminwidth || focusminheight)
- {
- debug("searching for focus canvas\n");
- cv2 = D_forecv;
- while (cv2->c_slback)
- {
- if (cv2->c_slback == cv->c_slback)
- {
- fcv = cv2;
- focusmin = cv->c_slorient == SLICE_VERT ? focusminheight : focusminwidth;
- if (focusmin > 0)
- focusmin--;
- else if (focusmin < 0)
- focusmin = cv->c_slorient == SLICE_VERT ? ye - ys + 2 : xe - xs + 2;
- debug1("found, focusmin=%d\n", focusmin);
- }
- cv2 = cv2->c_slback;
- }
- }
- if (focusmin)
- {
- m = CountCanvas(cv) * 2;
- nh = cv->c_slorient == SLICE_VERT ? ye - ys + 2 : xe - xs + 2;
- nh -= m;
- if (nh < 0)
- nh = 0;
- if (focusmin > nh)
- focusmin = nh;
- debug1("corrected to %d\n", focusmin);
- }
-
- /* pass 1: calculate weight sum */
- for (cv2 = cv, wsum = 0; cv2; cv2 = cv2->c_slnext)
- {
- debug1(" weight %d\n", cv2->c_slweight);
- wsum += cv2->c_slweight;
- }
- debug1("wsum = %d\n", wsum);
- if (wsum == 0)
- wsum = 1;
- w = wsum;
-
- /* pass 2: calculate need/excess space */
- nh = cv->c_slorient == SLICE_VERT ? ye - ys + 2 : xe - xs + 2;
- for (cv2 = cv, need = got = 0; cv2; cv2 = cv2->c_slnext)
- {
- m = cv2->c_slperp ? CountCanvasPerp(cv2) * 2 - 1 : 1;
- if (cv2 == fcv)
- m += focusmin;
- hh = cv2->c_slweight ? nh * cv2->c_slweight / w : 0;
- w -= cv2->c_slweight;
- nh -= hh;
- debug2(" should %d min %d\n", hh, m);
- if (hh <= m + 1)
- need += m + 1 - hh;
- else
- got += hh - m - 1;
- }
- debug2("need: %d, got %d\n", need, got);
- if (need > got)
- need = got;
-
- /* pass 3: distribute space */
- nh = cv->c_slorient == SLICE_VERT ? ye - ys + 2 : xe - xs + 2;
- i = cv->c_slorient == SLICE_VERT ? ys : xs;
- maxi = cv->c_slorient == SLICE_VERT ? ye : xe;
- w = wsum;
- for (; cv; cv = cvn)
- {
- cvn = cv->c_slnext;
- if (i > maxi)
- {
- if (cv->c_slprev && !cv->c_slback->c_slback && !cv->c_slprev->c_slperp && !cv->c_slprev->c_slprev)
- {
- cv->c_slprev->c_slorient = SLICE_UNKN;
- if (!captionalways)
- {
- cv->c_slback->c_ye++;
- cv->c_slprev->c_ye++;
- }
- }
- SetCanvasWindow(cv, 0);
- FreeCanvas(cv);
- continue;
- }
- m = cv->c_slperp ? CountCanvasPerp(cv) * 2 - 1 : 1;
- if (cv == fcv)
- m += focusmin;
- hh = cv->c_slweight ? nh * cv->c_slweight / w : 0;
- w -= cv->c_slweight;
- nh -= hh;
- debug2(" should %d min %d\n", hh, m);
- if (hh <= m + 1)
- {
- hh = m + 1;
- debug1(" -> %d\n", hh);
- }
- else
- {
- int hx = need * (hh - m - 1) / got;
- debug3(" -> %d - %d = %d\n", hh, hx, hh - hx);
- got -= (hh - m - 1);
- hh -= hx;
- need -= hx;
- debug2(" now need=%d got=%d\n", need, got);
- }
- ASSERT(hh >= m + 1);
- /* hh is window size plus pation line */
- if (i + hh > maxi + 2)
- {
- hh = maxi + 2 - i;
- debug1(" not enough space, reducing to %d\n", hh);
- }
- if (i + hh == maxi + 1)
- {
- hh++;
- debug(" incrementing as no other canvas will fit\n");
- }
- if (cv->c_slorient == SLICE_VERT)
- {
- cv->c_xs = xs;
- cv->c_xe = xe;
- cv->c_ys = i;
- cv->c_ye = i + hh - 2;
- cv->c_xoff = xs;
- cv->c_yoff = i;
- }
- else
- {
- cv->c_xs = i;
- cv->c_xe = i + hh - 2;
- cv->c_ys = ys;
- cv->c_ye = ye;
- cv->c_xoff = i;
- cv->c_yoff = ys;
- }
- cv->c_xoff = cv->c_xs;
- cv->c_yoff = cv->c_ys;
- cv->c_blank.l_width = cv->c_xe - cv->c_xs + 1;
- cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1;
- if (cv->c_slperp)
- {
- ResizeCanvas(cv);
- if (!cv->c_slperp->c_slnext)
- {
- debug("deleting perp node\n");
- FreePerp(cv->c_slperp);
- FreePerp(cv);
- }
- }
- i += hh;
- }
-}
-
-static struct canvas *
-AddPerp(cv)
-struct canvas *cv;
-{
- struct canvas *pcv;
- debug("Creating new perp node\n");
-
- if ((pcv = (struct canvas *)calloc(1, sizeof *cv)) == 0)
- return 0;
- pcv->c_next = 0;
- pcv->c_display = cv->c_display;
- pcv->c_slnext = cv->c_slnext;
- pcv->c_slprev = cv->c_slprev;
- pcv->c_slperp = cv;
- pcv->c_slback = cv->c_slback;
- if (cv->c_slback && cv->c_slback->c_slperp == cv)
- cv->c_slback->c_slperp = pcv;
- pcv->c_slorient = cv->c_slorient;
- pcv->c_xoff = 0;
- pcv->c_yoff = 0;
- pcv->c_xs = cv->c_xs;
- pcv->c_xe = cv->c_xe;
- pcv->c_ys = cv->c_ys;
- pcv->c_ye = cv->c_ye;
- if (pcv->c_slnext)
- pcv->c_slnext->c_slprev = pcv;
- if (pcv->c_slprev)
- pcv->c_slprev->c_slnext = pcv;
- pcv->c_slweight = cv->c_slweight;
- CanvasInitBlank(pcv);
- cv->c_slweight = 1;
- cv->c_slnext = 0;
- cv->c_slprev = 0;
- cv->c_slperp = 0;
- cv->c_slback = pcv;
- cv->c_slorient = SLICE_UNKN;
- return pcv;
-}
-
-static void
-FreePerp(pcv)
-struct canvas *pcv;
-{
- struct canvas *cv;
-
- if (!pcv->c_slperp)
- return;
- cv = pcv->c_slperp;
- cv->c_slprev = pcv->c_slprev;
- if (cv->c_slprev)
- cv->c_slprev->c_slnext = cv;
- cv->c_slback = pcv->c_slback;
- if (cv->c_slback && cv->c_slback->c_slperp == pcv)
- cv->c_slback->c_slperp = cv;
- cv->c_slorient = pcv->c_slorient;
- cv->c_slweight = pcv->c_slweight;
- while (cv->c_slnext)
- {
- cv = cv->c_slnext;
- cv->c_slorient = pcv->c_slorient;
- cv->c_slback = pcv->c_slback;
- cv->c_slweight = pcv->c_slweight;
- }
- cv->c_slnext = pcv->c_slnext;
- if (cv->c_slnext)
- cv->c_slnext->c_slprev = cv;
- free(pcv);
-}
-
-int
-AddCanvas(orient)
-int orient;
-{
- struct canvas *cv;
- int xs, xe, ys, ye;
- int h, num;
-
- cv = D_forecv;
- debug2("AddCanvas orient %d, forecv is %d\n", orient, cv->c_slorient);
-
- if (cv->c_slorient != SLICE_UNKN && cv->c_slorient != orient)
- if (!AddPerp(cv))
- return -1;
-
- cv = D_forecv;
- xs = cv->c_slback->c_xs;
- xe = cv->c_slback->c_xe;
- ys = cv->c_slback->c_ys;
- ye = cv->c_slback->c_ye;
- if (!captionalways && cv == D_canvas.c_slperp && !cv->c_slnext)
- ye--; /* need space for caption */
- debug2("Adding Canvas to slice %d,%d ", xs, ys);
- debug2("%d,%d\n", xe, ye);
-
- num = CountCanvas(cv->c_slback->c_slperp) + 1;
- debug1("Num = %d\n", num);
- if (orient == SLICE_VERT)
- h = ye - ys + 1;
- else
- h = xe - xs + 1;
-
- h -= 2 * num - 1;
- if (h < 0)
- return -1; /* can't fit in */
-
- if ((cv = (struct canvas *)calloc(1, sizeof *cv)) == 0)
- return -1;
-
- D_forecv->c_slback->c_ye = ye; /* in case we modified it above */
- D_forecv->c_slorient = orient; /* in case it was UNKN */
- cv->c_slnext = D_forecv->c_slnext;
- cv->c_slprev = D_forecv;
- D_forecv->c_slnext = cv;
- if (cv->c_slnext)
- cv->c_slnext->c_slprev = cv;
- cv->c_slorient = orient;
- cv->c_slback = D_forecv->c_slback;
-
- cv->c_xs = xs;
- cv->c_xe = xe;
- cv->c_ys = ys;
- cv->c_ye = ye;
- 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;
-
- CanvasInitBlank(cv);
- cv->c_lnext = 0;
-
- cv->c_next = 0;
-
- cv = cv->c_slback;
- EqualizeCanvas(cv->c_slperp, 0);
- ResizeCanvas(cv);
- RecreateCanvasChain();
- RethinkDisplayViewports();
- ResizeLayersToCanvases();
- return 0;
-}
-
-void
-RemCanvas()
-{
- int xs, xe, ys, ye;
- struct canvas *cv;
-
- debug("RemCanvas\n");
- cv = D_forecv;
- if (cv->c_slorient == SLICE_UNKN)
- return;
- while (cv->c_slprev)
- cv = cv->c_slprev;
- if (!cv->c_slnext)
- return;
- if (!cv->c_slnext->c_slnext && cv->c_slback->c_slback)
- {
- /* two canvases in slice, kill perp node */
- cv = D_forecv;
- debug("deleting perp node\n");
- FreePerp(cv->c_slprev ? cv->c_slprev : cv->c_slnext);
- FreePerp(cv->c_slback);
- }
- xs = cv->c_slback->c_xs;
- xe = cv->c_slback->c_xe;
- ys = cv->c_slback->c_ys;
- ye = cv->c_slback->c_ye;
- /* free canvas */
- cv = D_forecv;
- D_forecv = cv->c_slprev;
- if (!D_forecv)
- D_forecv = cv->c_slnext;
- FreeCanvas(cv);
-
- cv = D_forecv;
- while (D_forecv->c_slperp)
- D_forecv = D_forecv->c_slperp;
-
- /* if only one canvas left, set orient back to unknown */
- if (!cv->c_slnext && !cv->c_slprev && !cv->c_slback->c_slback && !cv->c_slperp)
- {
- cv->c_slorient = SLICE_UNKN;
- if (!captionalways)
- cv->c_slback->c_ye = ++ye; /* caption line no longer needed */
- }
- cv = cv->c_slback;
- EqualizeCanvas(cv->c_slperp, 0);
- ResizeCanvas(cv);
-
- D_fore = Layer2Window(D_forecv->c_layer);
- flayer = D_forecv->c_layer;
-
- RecreateCanvasChain();
- RethinkDisplayViewports();
- ResizeLayersToCanvases();
-}
-
-void
-OneCanvas()
-{
- struct canvas *cv = D_forecv, *ocv = 0;
-
- if (cv->c_slprev)
- {
- ocv = cv->c_slprev;
- cv->c_slprev->c_slnext = cv->c_slnext;
- }
- if (cv->c_slnext)
- {
- ocv = cv->c_slnext;
- cv->c_slnext->c_slprev = cv->c_slprev;
- }
- if (!ocv)
- return;
- if (cv->c_slback && cv->c_slback->c_slperp == cv)
- cv->c_slback->c_slperp = ocv;
- cv->c_slorient = SLICE_UNKN;
- while (D_canvas.c_slperp)
- FreeCanvas(D_canvas.c_slperp);
- cv = D_forecv;
- D_canvas.c_slperp = cv;
- cv->c_slback = &D_canvas;
- cv->c_slnext = 0;
- cv->c_slprev = 0;
- ASSERT(!cv->c_slperp);
- if (!captionalways)
- D_canvas.c_ye++; /* caption line no longer needed */
- ResizeCanvas(&D_canvas);
- RecreateCanvasChain();
- 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.
@@ -1154,8 +435,8 @@ int adapt;
ASSERT(display);
ASSERT(D_tcinited);
D_top = D_bot = -1;
- AddCStr(D_TI);
AddCStr(D_IS);
+ AddCStr(D_TI);
/* Check for toggle */
if (D_IM && strcmp(D_IM, D_EI))
AddCStr(D_EI);
@@ -1181,7 +462,7 @@ int adapt;
ResizeDisplay(D_defwidth, D_defheight);
ChangeScrollRegion(0, D_height - 1);
D_x = D_y = 0;
- Flush();
+ Flush(3);
ClearAll();
debug1("we %swant to adapt all our windows to the display\n",
(adapt) ? "" : "don't ");
@@ -1204,6 +485,8 @@ FinitTerm()
KeypadMode(0);
CursorkeysMode(0);
CursorVisibility(0);
+ if (D_mousetrack)
+ D_mousetrack = 0;
MouseMode(0);
SetRendition(&mchar_null);
SetFlow(FLOW_NOW);
@@ -1222,7 +505,7 @@ FinitTerm()
AddChar('\n');
AddCStr(D_TE);
}
- Flush();
+ Flush(3);
}
@@ -1335,7 +618,15 @@ int c;
AddCStr(D_CE0);
goto addedutf8;
}
- AddUtf8(c);
+ if (c < 0x80)
+ {
+ 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(c);
+ }
+ else
+ AddUtf8(c);
goto addedutf8;
}
# endif
@@ -1521,7 +812,13 @@ void
MouseMode(mode)
int mode;
{
- if (display && D_mouse != mode)
+ if (!display)
+ return;
+
+ if (mode < D_mousetrack)
+ mode = D_mousetrack;
+
+ if (D_mouse != mode)
{
char mousebuf[20];
if (!D_CXT)
@@ -2660,7 +1957,7 @@ char *msg;
return; /* XXX: better */
AddStr(msg);
AddStr("\r\n");
- Flush();
+ Flush(0);
return;
}
if (!use_hardstatus || !D_HS)
@@ -2677,19 +1974,11 @@ char *msg;
if (strcmp(msg, D_status_lastmsg) == 0)
{
debug("same message - increase timeout");
- SetTimeout(&D_statusev, MsgWait);
+ if (!D_status_obufpos)
+ SetTimeout(&D_statusev, MsgWait);
return;
}
- if (!D_status_bell)
- {
- struct timeval now;
- int ti;
- gettimeofday(&now, NULL);
- ti = (now.tv_sec - D_status_time.tv_sec) * 1000 + (now.tv_usec - D_status_time.tv_usec) / 1000;
- if (ti < MsgMinWait)
- DisplaySleep1000(MsgMinWait - ti, 0);
- }
- RemoveStatus();
+ RemoveStatusMinWait();
}
for (s = t = msg; *s && t - msg < max; ++s)
if (*s == BELL)
@@ -2746,15 +2035,15 @@ char *msg;
D_status = STATUS_ON_HS;
ShowHStatus(msg);
}
- Flush();
- if (!display)
- return;
+
+ D_status_obufpos = D_obufp - D_obuf;
+ ASSERT(D_status_obufpos > 0);
+
if (D_status == STATUS_ON_WIN)
{
struct display *olddisplay = display;
struct layer *oldflayer = flayer;
- ASSERT(D_obuffree == D_obuflen);
/* this is copied over from RemoveStatus() */
D_status = 0;
GotoPos(0, STATLINE);
@@ -2765,17 +2054,8 @@ char *msg;
LaySetCursor();
display = olddisplay;
flayer = oldflayer;
- D_status_obuflen = D_obuflen;
- D_status_obuffree = D_obuffree;
- D_obuffree = D_obuflen = 0;
D_status = STATUS_ON_WIN;
}
- gettimeofday(&D_status_time, NULL);
- SetTimeout(&D_statusev, MsgWait);
- evenq(&D_statusev);
-#ifdef HAVE_BRAILLE
- RefreshBraille(); /* let user see multiple Msg()s */
-#endif
}
void
@@ -2798,6 +2078,7 @@ RemoveStatus()
D_status_obuffree = -1;
}
D_status = 0;
+ D_status_obufpos = 0;
D_status_bell = 0;
evdeq(&D_statusev);
olddisplay = display;
@@ -2820,6 +2101,86 @@ RemoveStatus()
flayer = oldflayer;
}
+/* Remove the status but make sure that it is seen for MsgMinWait ms */
+static void
+RemoveStatusMinWait()
+{
+ /* XXX: should flush output first if D_status_obufpos is set */
+ if (!D_status_bell && !D_status_obufpos)
+ {
+ struct timeval now;
+ int ti;
+ gettimeofday(&now, NULL);
+ ti = (now.tv_sec - D_status_time.tv_sec) * 1000 + (now.tv_usec - D_status_time.tv_usec) / 1000;
+ if (ti < MsgMinWait)
+ DisplaySleep1000(MsgMinWait - ti, 0);
+ }
+ RemoveStatus();
+}
+
+#ifdef UTF8
+static int
+strlen_onscreen(unsigned char *c, unsigned char *end)
+{
+ int len = 0;
+ char *s = c;
+ while (*c && (!end || c < end))
+ {
+ int v, dec = 0;
+ do
+ {
+ v = FromUtf8(*c++, &dec);
+ if (v == -2)
+ c--;
+ }
+ while (v < 0 && (!end || c < end));
+ if (!utf8_iscomb(v))
+ {
+ if (utf8_isdouble(v))
+ len++;
+ len++;
+ }
+ }
+
+ return len;
+}
+
+static int
+PrePutWinMsg(s, start, max)
+char *s;
+int start, max;
+{
+ /* Avoid double-encoding problem for a UTF-8 message on a UTF-8 locale.
+ Ideally, this would not be necessary. But fixing it the Right Way will
+ probably take way more time. So this will have to do for now. */
+ if (D_encoding == UTF8)
+ {
+ int chars = strlen_onscreen(s + start, s + max);
+ D_encoding = 0;
+ PutWinMsg(s, start, max);
+ D_encoding = UTF8;
+ D_x -= (max - chars); /* Yak! But this is necessary to count for
+ the fact that not every byte represents a
+ character. */
+ return start + chars;
+ }
+ else
+ {
+ PutWinMsg(s, start, max);
+ return max;
+ }
+}
+#else
+static int
+PrePutWinMsg(s, start, max)
+char *s;
+int start, max;
+{
+ PutWinMsg(s, start, max);
+ return max;
+}
+#endif
+
/* refresh the display's hstatus line */
void
ShowHStatus(str)
@@ -2864,7 +2225,7 @@ char *str;
l = D_width;
GotoPos(0, D_height - 1);
SetRendition(captionalways || D_cvlist == 0 || D_cvlist->c_next ? &mchar_null: &mchar_so);
- PutWinMsg(str, 0, l);
+ l = PrePutWinMsg(str, 0, l);
if (!captionalways && D_cvlist && !D_cvlist->c_next)
while (l++ < D_width)
PUTCHARLP(' ');
@@ -2966,26 +2327,7 @@ int y, from, to, isblank;
return; /* can't refresh status */
}
- /* The following check makes plenty of sense. Unfortunately,
- vte-based terminals (notably gnome-terminal) experience a quirk
- that causes the final line not to update properly when it falls outside
- the scroll region; clearing the line with D_CE avoids the glitch,
- so we'll disable this perfectly sensible shortcut until such a time
- as widespread vte installations lack the glitch.
-
- See http://bugzilla.gnome.org/show_bug.cgi?id=542087 for current
- status of the VTE bug report, and
- https://savannah.gnu.org/bugs/index.php?23699 for the history from
- the Savannah BTS. */
-#if 0
- if (y == D_height - 1 && D_has_hstatus == HSTATUS_LASTLINE)
- {
- RefreshHStatus();
- return;
- }
-#endif
-
- if (isblank == 0 && D_CE && to == D_width - 1 && from < to)
+ if (isblank == 0 && D_CE && to == D_width - 1 && from < to && D_status != STATUS_ON_HS)
{
GotoPos(from, y);
if (D_UT || D_BE)
@@ -2993,6 +2335,13 @@ int y, from, to, isblank;
AddCStr(D_CE);
isblank = 1;
}
+
+ if (y == D_height - 1 && D_has_hstatus == HSTATUS_LASTLINE)
+ {
+ RefreshHStatus();
+ return;
+ }
+
while (from <= to)
{
lcv = 0;
@@ -3011,7 +2360,7 @@ int y, from, to, isblank;
SetRendition(&mchar_so);
if (l > xx - cv->c_xs + 1)
l = xx - cv->c_xs + 1;
- PutWinMsg(buf, from - cv->c_xs, l);
+ l = PrePutWinMsg(buf, from - cv->c_xs, l);
from = cv->c_xs + l;
for (; from <= xx; from++)
PUTCHARLP(' ');
@@ -3181,8 +2530,8 @@ int from, to, y, bce;
void
DisplayLine(oml, ml, y, from, to)
struct mline *oml, *ml;
-int from, to, y;{
-
+int from, to, y;
+{
register int x;
int last2flag = 0, delete_lp = 0;
@@ -3503,12 +2852,19 @@ int newtop, newbot;
}
#ifdef RXVT_OSC
+#define WT_FLAG "2" /* change to "0" to set both title and icon */
+
void
SetXtermOSC(i, s)
int i;
char *s;
{
- static char oscs[] = "1;\000\00020;\00039;\00049;\000";
+ static char *oscs[][2] = {
+ { WT_FLAG ";", "screen" }, /* set window title */
+ { "20;", "" }, /* background */
+ { "39;", "black" }, /* default foreground (black?) */
+ { "49;", "white" } /* default background (white?) */
+ };
ASSERT(display);
if (!D_CXT)
@@ -3517,17 +2873,13 @@ char *s;
s = "";
if (!D_xtermosc[i] && !*s)
return;
- if (i == 0 && !*s)
- s = "screen"; /* always set icon name */
- if (i == 1 && !*s)
- s = ""; /* no background */
- if (i == 2 && !*s)
- s = "black"; /* black text */
- if (i == 3 && !*s)
- s = "white"; /* on white background */
+ if (i == 0 && !D_xtermosc[0])
+ AddStr("\033[22;" WT_FLAG "t"); /* stack titles (xterm patch #251) */
+ if (!*s)
+ s = oscs[i][1];
D_xtermosc[i] = 1;
AddStr("\033]");
- AddStr(oscs + i * 4);
+ AddStr(oscs[i][0]);
AddStr(s);
AddChar(7);
}
@@ -3538,7 +2890,10 @@ ClearAllXtermOSC()
int i;
for (i = 3; i >= 0; i--)
SetXtermOSC(i, 0);
+ if (D_xtermosc[0])
+ AddStr("\033[23;" WT_FLAG "t"); /* unstack titles (xterm patch #251) */
}
+#undef WT_FLAG
#endif
/*
@@ -3588,9 +2943,11 @@ int n;
}
void
-Flush()
+Flush(progress)
+int progress;
{
register int l;
+ int wr;
register char *p;
ASSERT(display);
@@ -3606,29 +2963,57 @@ Flush()
return;
}
p = D_obuf;
- if (fcntl(D_userfd, F_SETFL, 0))
- debug1("Warning: BLOCK fcntl failed: %d\n", errno);
+ if (!progress)
+ {
+ if (fcntl(D_userfd, F_SETFL, 0))
+ debug1("Warning: BLOCK fcntl failed: %d\n", errno);
+ }
while (l)
{
- register int wr;
+ if (progress)
+ {
+ fd_set w;
+ FD_ZERO(&w);
+ FD_SET(D_userfd, &w);
+ struct timeval t;
+ t.tv_sec = progress;
+ t.tv_usec = 0;
+ wr = select(FD_SETSIZE, (fd_set *)0, &w, (fd_set *)0, &t);
+ if (wr == -1)
+ {
+ if (errno == EINTR)
+ continue;
+ debug1("Warning: select failed: %d\n", errno);
+ break;
+ }
+ if (wr == 0)
+ {
+ /* no progress after 3 seconds. sorry. */
+ debug1("Warning: no progress after %d seconds\n", progress);
+ break;
+ }
+ }
wr = write(D_userfd, p, l);
- if (wr <= 0)
+ if (wr <= 0)
{
- if (errno == EINTR)
+ if (errno == EINTR)
continue;
debug1("Writing to display: %d\n", errno);
- wr = l;
+ break;
}
- if (!display)
- return;
D_obuffree += wr;
p += wr;
l -= wr;
}
+ if (l)
+ debug1("Warning: Flush could not write %d bytes\n", l);
D_obuffree += l;
D_obufp = D_obuf;
- if (fcntl(D_userfd, F_SETFL, FNBLOCK))
- debug1("Warning: NBLOCK fcntl failed: %d\n", errno);
+ if (!progress)
+ {
+ if (fcntl(D_userfd, F_SETFL, FNBLOCK))
+ debug1("Warning: NBLOCK fcntl failed: %d\n", errno);
+ }
if (D_blocked == 1)
D_blocked = 0;
D_blocked_fuzz = 0;
@@ -3666,16 +3051,7 @@ Resize_obuf()
if (D_status_obuffree >= 0)
{
ASSERT(D_obuffree == -1);
- if (!D_status_bell)
- {
- struct timeval now;
- int ti;
- gettimeofday(&now, NULL);
- ti = (now.tv_sec - D_status_time.tv_sec) * 1000 + (now.tv_usec - D_status_time.tv_usec) / 1000;
- if (ti < MsgMinWait)
- DisplaySleep1000(MsgMinWait - ti, 0);
- }
- RemoveStatus();
+ RemoveStatusMinWait();
if (--D_obuffree > 0) /* redo AddChar decrement */
return;
}
@@ -3757,8 +3133,8 @@ NukePending()
D_obufp = D_obuf;
D_obuffree += len;
D_top = D_bot = -1;
- AddCStr(D_TI);
AddCStr(D_IS);
+ AddCStr(D_TI);
/* Turn off all attributes. (Tim MacKenzie) */
if (D_ME)
AddCStr(D_ME);
@@ -3843,6 +3219,8 @@ char *data;
len = D_obufp - D_obuf;
if (len < size)
size = len;
+ if (D_status_obufpos && size > D_status_obufpos)
+ size = D_status_obufpos;
ASSERT(len >= 0);
size = write(D_userfd, D_obuf, size);
if (size >= 0)
@@ -3855,6 +3233,30 @@ char *data;
}
D_obufp -= size;
D_obuffree += size;
+ if (D_status_obufpos)
+ {
+ D_status_obufpos -= size;
+ if (!D_status_obufpos)
+ {
+ debug("finished writing the status message\n");
+ /* we're finished displaying the message! */
+ if (D_status == STATUS_ON_WIN)
+ {
+ /* setup continue trigger */
+ D_status_obuflen = D_obuflen;
+ D_status_obuffree = D_obuffree;
+ /* setting obbuffree to 0 will make AddChar call
+ * ResizeObuf */
+ D_obuffree = D_obuflen = 0;
+ }
+ gettimeofday(&D_status_time, NULL);
+ SetTimeout(&D_statusev, MsgWait);
+ evenq(&D_statusev);
+#ifdef HAVE_BRAILLE
+ RefreshBraille(); /* let user see multiple Msg()s */
+#endif
+ }
+ }
if (D_blocked_fuzz)
{
D_blocked_fuzz -= size;
@@ -3882,7 +3284,7 @@ char *data;
Activate(D_fore ? D_fore->w_norefresh : 0);
D_blocked_fuzz = D_obufp - D_obuf;
}
- }
+ }
else
{
#ifdef linux
@@ -4016,15 +3418,29 @@ char *data;
y = bp[4] - 33;
if (x >= D_forecv->c_xs && x <= D_forecv->c_xe && y >= D_forecv->c_ys && y <= D_forecv->c_ye)
{
- x -= D_forecv->c_xoff;
- y -= D_forecv->c_yoff;
- if (x >= 0 && x < D_forecv->c_layer->l_width && y >= 0 && y < D_forecv->c_layer->l_height)
+ if ((D_fore && D_fore->w_mouse) || (D_mousetrack && D_forecv->c_layer->l_mode == 1))
+ {
+ /* Send clicks only if the window is expecting clicks */
+ x -= D_forecv->c_xoff;
+ y -= D_forecv->c_yoff;
+ if (x >= 0 && x < D_forecv->c_layer->l_width && y >= 0 && y < D_forecv->c_layer->l_height)
+ {
+ bp[3] = x + 33;
+ bp[4] = y + 33;
+ i -= 4;
+ bp += 4;
+ continue;
+ }
+ }
+ }
+ else if (D_mousetrack && bp[2] == '#')
+ {
+ /* 'focus' to the clicked region, only on mouse up */
+ struct canvas *cv = FindCanvas(x, y);
+ if (cv)
{
- bp[3] = x + 33;
- bp[4] = y + 33;
- i -= 4;
- bp += 4;
- continue;
+ SetForeCanvas(display, cv);
+ /* XXX: Do we want to reset the input buffer? */
}
}
if (bp[0] == '[')
@@ -4121,29 +3537,6 @@ char *data;
}
}
-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;
- if (D_status == STATUS_ON_WIN)
- {
- SetTimeout(ev, 1);
- evenq(ev);
- return;
- }
- 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)
@@ -4367,7 +3760,7 @@ char **cmdv;
#endif
display = 0;
execvpe(*cmdv, cmdv, NewEnv + 3);
- Panic(errno, *cmdv);
+ Panic(errno, "%s", *cmdv);
default:
break;
}
@@ -4377,338 +3770,6 @@ char **cmdv;
ClearAll();
}
-#endif
-
-struct layout *layouts;
-struct layout *laytab[MAXLAY];
-struct layout *layout_last, layout_last_marker;
-struct layout *layout_attach = &layout_last_marker;
-
-void
-FreeLayoutCv(cv)
-struct canvas *cv;
-{
- struct canvas *cnext, *c = cv;
- for (; cv; cv = cnext)
- {
- if (cv->c_slperp)
- {
- FreeLayoutCv(cv->c_slperp);
- free(cv->c_slperp);
- cv->c_slperp = 0;
- }
- cnext = cv->c_slnext;
- cv->c_slnext = 0;
- if (cv != c)
- free(cv);
- }
-}
-
-static void
-DupLayoutCv(cvf, cvt, save)
-struct canvas *cvf, *cvt;
-int save;
-{
- while(cvf)
- {
- cvt->c_slorient = cvf->c_slorient;
- cvt->c_slweight = cvf->c_slweight;
- if (cvf == D_forecv)
- D_forecv = cvt;
- if (!save)
- {
- cvt->c_display = display;
- if (!cvf->c_slperp)
- {
- cvt->c_captev.type = EV_TIMEOUT;
- cvt->c_captev.data = (char *)cvt;
- cvt->c_captev.handler = cv_winid_fn;
- cvt->c_blank.l_cvlist = 0;
- cvt->c_blank.l_layfn = &BlankLf;
- cvt->c_blank.l_bottom = &cvt->c_blank;
- }
- cvt->c_layer = cvf->c_layer;
- }
- else
- {
- struct win *p = cvf->c_layer ? Layer2Window(cvf->c_layer) : 0;
- cvt->c_layer = p ? &p->w_layer : 0;
- }
- if (cvf->c_slperp)
- {
- cvt->c_slperp = (struct canvas *)calloc(1, sizeof(struct canvas));
- cvt->c_slperp->c_slback = cvt;
- CanvasInitBlank(cvt->c_slperp);
- DupLayoutCv(cvf->c_slperp, cvt->c_slperp, save);
- }
- if (cvf->c_slnext)
- {
- cvt->c_slnext = (struct canvas *)calloc(1, sizeof(struct canvas));
- cvt->c_slnext->c_slprev = cvt;
- cvt->c_slnext->c_slback = cvt->c_slback;
- CanvasInitBlank(cvt->c_slnext);
- }
- cvf = cvf->c_slnext;
- cvt = cvt->c_slnext;
- }
-}
-
-void
-PutWindowCv(cv)
-struct canvas *cv;
-{
- struct win *p;
- for (; cv; cv = cv->c_slnext)
- {
- if (cv->c_slperp)
- {
- PutWindowCv(cv->c_slperp);
- continue;
- }
- p = cv->c_layer ? (struct win *)cv->c_layer->l_data : 0;
- cv->c_layer = 0;
- SetCanvasWindow(cv, p);
- }
-}
-
-struct layout *
-CreateLayout(title, startat)
-char *title;
-int startat;
-{
- struct layout *lay;
- int i;
-
- if (startat >= MAXLAY || startat < 0)
- startat = 0;
- for (i = startat; ;)
- {
- if (!laytab[i])
- break;
- if (++i == MAXLAY)
- i = 0;
- if (i == startat)
- {
- Msg(0, "No more layouts\n");
- return 0;
- }
- }
- lay = (struct layout *)calloc(1, sizeof(*lay));
- lay->lay_title = SaveStr(title);
- lay->lay_autosave = 1;
- lay->lay_number = i;
- laytab[i] = lay;
- lay->lay_next = layouts;
- layouts = lay;
- return lay;
-}
-
-void
-SaveLayout(name, cv)
-char *name;
-struct canvas *cv;
-{
- struct layout *lay;
- struct canvas *fcv;
- for (lay = layouts; lay; lay = lay->lay_next)
- if (!strcmp(lay->lay_title, name))
- break;
- if (lay)
- FreeLayoutCv(&lay->lay_canvas);
- else
- lay = CreateLayout(name, 0);
- if (!lay)
- return;
- fcv = D_forecv;
- DupLayoutCv(cv, &lay->lay_canvas, 1);
- lay->lay_forecv = D_forecv;
- D_forecv = fcv;
- D_layout = lay;
-}
-
-void
-AutosaveLayout(lay)
-struct layout *lay;
-{
- struct canvas *fcv;
- if (!lay || !lay->lay_autosave)
- return;
- FreeLayoutCv(&lay->lay_canvas);
- fcv = D_forecv;
- DupLayoutCv(&D_canvas, &lay->lay_canvas, 1);
- lay->lay_forecv = D_forecv;
- D_forecv = fcv;
-}
-
-struct layout *
-FindLayout(name)
-char *name;
-{
- struct layout *lay;
- char *s;
- int i;
- for (i = 0, s = name; *s >= '0' && *s <= '9'; s++)
- i = i * 10 + (*s - '0');
- if (!*s && s != name && i >= 0 && i < MAXLAY)
- return laytab[i];
- for (lay = layouts; lay; lay = lay->lay_next)
- if (!strcmp(lay->lay_title, name))
- break;
- return lay;
-}
-
-void
-LoadLayout(lay, cv)
-struct layout *lay;
-struct canvas *cv;
-{
- AutosaveLayout(D_layout);
- if (!lay)
- {
- while (D_canvas.c_slperp)
- FreeCanvas(D_canvas.c_slperp);
- MakeDefaultCanvas();
- SetCanvasWindow(D_forecv, 0);
- D_layout = 0;
- return;
- }
- while (D_canvas.c_slperp)
- FreeCanvas(D_canvas.c_slperp);
- D_cvlist = 0;
- D_forecv = lay->lay_forecv;
- DupLayoutCv(&lay->lay_canvas, &D_canvas, 0);
- D_canvas.c_ye = D_height - 1 - ((D_canvas.c_slperp && D_canvas.c_slperp->c_slnext) || captionalways) - (D_has_hstatus == HSTATUS_LASTLINE);
- ResizeCanvas(&D_canvas);
- RecreateCanvasChain();
- RethinkDisplayViewports();
- PutWindowCv(&D_canvas);
- ResizeLayersToCanvases();
- D_layout = lay;
-}
-
-void
-NewLayout(title, startat)
-char *title;
-int startat;
-{
- struct layout *lay;
- struct canvas *fcv;
-
- lay = CreateLayout(title, startat);
- if (!lay)
- return;
- LoadLayout(0, &D_canvas);
- fcv = D_forecv;
- DupLayoutCv(&D_canvas, &lay->lay_canvas, 1);
- lay->lay_forecv = D_forecv;
- D_forecv = fcv;
- D_layout = lay;
- lay->lay_autosave = 1;
-}
-
-static char *
-AddLayoutsInfo(buf, len, where)
-char *buf;
-int len;
-int where;
-{
- char *s, *ss, *t;
- struct layout *p, **pp;
- int l;
-
- s = ss = buf;
- for (pp = laytab; pp < laytab + MAXLAY; pp++)
- {
- if (pp - laytab == where && ss == buf)
- ss = s;
- if ((p = *pp) == 0)
- continue;
- t = p->lay_title;
- l = strlen(t);
- if (l > 20)
- l = 20;
- if (s - buf + l > len - 24)
- break;
- if (s > buf)
- {
- *s++ = ' ';
- *s++ = ' ';
- }
- sprintf(s, "%d", p->lay_number);
- if (p->lay_number == where)
- ss = s;
- s += strlen(s);
- if (display && p == D_layout)
- *s++ = '*';
- *s++ = ' ';
- strncpy(s, t, l);
- s += l;
- }
- *s = 0;
- return ss;
-}
-
-void
-ShowLayouts(where)
-int where;
-{
- char buf[1024];
- char *s, *ss;
+#endif /* BLANKER_PRG */
- if (!display)
- return;
- if (!layouts)
- {
- Msg(0, "No layouts defined\n");
- return;
- }
- if (where == -1 && D_layout)
- where = D_layout->lay_number;
- ss = AddLayoutsInfo(buf, sizeof(buf), where);
- s = buf + strlen(buf);
- if (ss - buf > D_width / 2)
- {
- ss -= D_width / 2;
- if (s - ss < D_width)
- {
- ss = s - D_width;
- if (ss < buf)
- ss = buf;
- }
- }
- else
- ss = buf;
- Msg(0, "%s", ss);
-}
-
-void
-RemoveLayout(lay)
-struct layout *lay;
-{
- struct layout **layp = &layouts;
-
- for (; *layp; layp = &(*layp)->lay_next)
- {
- if (*layp == lay)
- {
- *layp = lay->lay_next;
- break;
- }
- }
- laytab[lay->lay_number] = (struct layout *)0;
-
- if (display && D_layout == lay)
- D_layout = (struct layout *)0;
-
- FreeLayoutCv(&lay->lay_canvas);
-
- if (lay->lay_title)
- free(lay->lay_title);
- free(lay);
-
- if (layouts)
- LoadLayout((display && D_layout) ? D_layout : *layp ? *layp : layouts,
- display ? &D_canvas : (struct canvas *)0);
- Activate(0);
-}