diff options
author | Axel Beckert <abe@deuxchevaux.org> | 2011-09-03 14:05:23 +0200 |
---|---|---|
committer | Axel Beckert <abe@deuxchevaux.org> | 2011-09-03 14:05:23 +0200 |
commit | bdf45bc45637eefdbdee913465729f9d31d6c255 (patch) | |
tree | 9b6538c483ad6c2b38177068d5c5730397c9f292 /layer.c | |
parent | 14a4b00c9ef680b78469333291270e4c276f100d (diff) | |
download | screen-bdf45bc45637eefdbdee913465729f9d31d6c255.tar.gz |
Imported Upstream version 3.9.5upstream/3.9.5
Diffstat (limited to 'layer.c')
-rw-r--r-- | layer.c | 938 |
1 files changed, 938 insertions, 0 deletions
@@ -0,0 +1,938 @@ +/* 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., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + **************************************************************** + */ + +#include "rcs.h" +RCS_ID("$Id: search.c,v 1.2 1994/05/31 12:32:57 mlschroe Exp $ FAU") + +#include <sys/types.h> + +#include "config.h" +#include "screen.h" +#include "mark.h" +#include "extern.h" +#include "braille.h" + +extern struct display *display, *displays; + +extern struct mline mline_blank; +extern struct mline mline_null; +extern struct mchar mchar_null; +extern struct mchar mchar_blank; + +extern struct layer *flayer; /* sigh */ +extern struct LayFuncs WinLf; +extern struct LayFuncs BlankLf; + + +static struct mline *mloff __P((struct mline *, int)); + +/* + * Layer subsystem. + * + * ...here is all the clipping code... beware! + * + * XXX: add some speedup code! + * + */ + +static struct mline * +mloff(ml, off) +struct mline *ml; +int off; +{ + static struct mline mml; + + if (ml == 0) + return 0; + mml.image = ml->image + off; + mml.attr = ml->attr + off; +#ifdef FONT + mml.font = ml->font + off; +#endif +#ifdef COLOR + mml.color = ml->color + off; +#endif + return &mml; +} + +void +LGotoPos(l, x, y) +struct layer *l; +int x, y; +{ + struct canvas *cv; + struct viewport *vp; + int x2, y2; + +#ifdef HAVE_BRAILLE + if (bd.bd_refreshing) + return; +#endif + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + { + display = cv->c_display; + if (cv != D_forecv) + continue; + x2 = x + cv->c_xoff; + y2 = y + cv->c_yoff; + debug2("---LGotoPos %d %d\n", x2, y2); + if (x2 < cv->c_xs) + x2 = cv->c_xs; + if (y2 < cv->c_ys) + y2 = cv->c_ys; + if (x2 > cv->c_xe) + x2 = cv->c_xe; + if (y2 > cv->c_ye) + y2 = cv->c_ye; + for (vp = cv->c_vplist; vp; vp = vp->v_next) + { + if (x2 < vp->v_xs || x2 > vp->v_xe) + continue; + if (y2 < vp->v_ys || y2 > vp->v_ye) + continue; + GotoPos(x2, y2); + break; + } + } +} + +void +LScrollH(l, n, y, xs, xe, ol) +struct layer *l; +int n, y, xs, xe; +struct mline *ol; +{ + struct canvas *cv; + struct viewport *vp; + int y2, xs2, xe2; + + if (n == 0) + return; + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + for (vp = cv->c_vplist; vp; vp = vp->v_next) + { + y2 = y + vp->v_yoff; + if (y2 < vp->v_ys || y2 > vp->v_ye) + continue; + xs2 = xs + vp->v_xoff; + xe2 = xe + vp->v_xoff; + if (xs2 < vp->v_xs) + xs2 = vp->v_xs; + if (xe2 > vp->v_xe) + xe2 = vp->v_xe; + if (xs2 > xe2) + continue; + display = cv->c_display; + ScrollH(y2, xs2, xe2, n, ol ? mloff(ol, -vp->v_xoff) : 0); + if (xe2 - xs2 == xe - xs) + continue; + if (n > 0) + { + xs2 = xe2 + 1 - n; + xe2 = xe + vp->v_xoff - n; + } + else + { + xe2 = xs2 - 1 - n; + xs2 = xs + vp->v_xoff - n; + } + if (xs2 < vp->v_xs) + xs2 = vp->v_xs; + if (xe2 > vp->v_xe) + xe2 = vp->v_xe; + if (xs2 <= xe2) + RefreshArea(xs2, y2, xe2, y2, 1); + } +} + +void +LScrollV(l, n, ys, ye) +struct layer *l; +int n; +int ys, ye; +{ + struct canvas *cv; + struct viewport *vp; + int ys2, ye2, xs2, xe2; + if (n == 0) + return; + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + for (vp = cv->c_vplist; vp; vp = vp->v_next) + { + xs2 = vp->v_xoff; + xe2 = l->l_width - 1 + vp->v_xoff; + ys2 = ys + vp->v_yoff; + ye2 = ye + vp->v_yoff; + if (xs2 < vp->v_xs) + xs2 = vp->v_xs; + if (xe2 > vp->v_xe) + xe2 = vp->v_xe; + if (ys2 < vp->v_ys) + ys2 = vp->v_ys; + if (ye2 > vp->v_ye) + ye2 = vp->v_ye; + if (ys2 > ye2 || xs2 > xe2) + continue; + display = cv->c_display; +#if 0 + ScrollV(xs2, ys2, xe2, ye2, n); +#else + ScrollV(vp->v_xs, ys2, vp->v_xe, ye2, n); +#endif + debug2("LScrollV: %d %d", ys, ye); + debug2(" -> %d %d\n", ys2, ye2); + if (ye2 - ys2 == ye - ys) + continue; + if (n > 0) + { + ys2 = ye2 + 1 - n; + ye2 = ye + vp->v_yoff - n; + } + else + { + ye2 = ys2 - 1 - n; + ys2 = ys + vp->v_yoff - n; + } + debug2("LScrollV: - %d %d\n", ys2, ye2); + if (ys2 < vp->v_ys) + ys2 = vp->v_ys; + if (ye2 > vp->v_ye) + ye2 = vp->v_ye; + debug2("LScrollV: - %d %d\n", ys2, ye2); + if (ys2 <= ye2) + RefreshArea(xs2, ys2, xe2, ye2, 1); + } +} + +void +LInsChar(l, c, x, y, ol) +struct layer *l; +struct mchar *c; +int x, y; +struct mline *ol; +{ + struct canvas *cv; + struct viewport *vp; + int xs2, xe2, y2, f; + struct mchar *c2, cc; + + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + for (vp = cv->c_vplist; vp; vp = vp->v_next) + { + y2 = y + vp->v_yoff; + if (y2 < vp->v_ys || y2 > vp->v_ye) + continue; + xs2 = x + vp->v_xoff; + xe2 = l->l_width - 1 + vp->v_xoff; + c2 = c; + f = 0; + if (xs2 < vp->v_xs) + { + xs2 = vp->v_xs; + c2 = &mchar_blank; + if (ol) + { + int i; + i = xs2 - vp->v_xoff - 1; + if (i >= 0 && i < l->l_width) + { + copy_mline2mchar(&cc, ol, i); + c2 = &cc; + } + } + else + f = 1; + } + if (xe2 > vp->v_xe) + xe2 = vp->v_xe; + if (xs2 > xe2) + continue; + display = cv->c_display; + InsChar(c2, xs2, xe2, y2, mloff(ol, -vp->v_xoff)); + if (f) + RefreshArea(xs2, y2, xs2, y2, 1); + } +} + +void +LPutChar(l, c, x, y) +struct layer *l; +struct mchar *c; +int x, y; +{ + struct canvas *cv; + struct viewport *vp; + int x2, y2; +#ifdef HAVE_BRAILLE + if (bd.bd_refreshing) + { + BPutChar(l, c, x, y); + return; + } +#endif + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + for (vp = cv->c_vplist; vp; vp = vp->v_next) + { + y2 = y + vp->v_yoff; + if (y2 < vp->v_ys || y2 > vp->v_ye) + continue; + x2 = x + vp->v_xoff; + if (x2 < vp->v_xs || x2 > vp->v_xe) + continue; + display = cv->c_display; + GotoPos(x2, y2); + SetRendition(c); + PUTCHARLP(c->image); + if (D_AM && !D_CLP && x2 == D_width - 1) + GotoPos(x2, y2); + } +} + +void +LPutStr(l, s, n, r, x, y) +struct layer *l; +char *s; +int n; +struct mchar *r; +int x, y; +{ + struct canvas *cv; + struct viewport *vp; + char *s2; + int xs2, xe2, y2; + + if (x + n > l->l_width) + n = l->l_width - x; +#ifdef HAVE_BRAILLE + if (bd.bd_refreshing) + { + BPutStr(l, s, n, r, x, y); + return; + } +#endif + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + for (vp = cv->c_vplist; vp; vp = vp->v_next) + { + y2 = y + vp->v_yoff; + if (y2 < vp->v_ys || y2 > vp->v_ye) + continue; + xs2 = x + vp->v_xoff; + xe2 = xs2 + n - 1; + if (xs2 < vp->v_xs) + xs2 = vp->v_xs; + if (xe2 > vp->v_xe) + xe2 = vp->v_xe; + if (xs2 > xe2) + continue; + display = cv->c_display; + GotoPos(xs2, y2); + SetRendition(r); + s2 = s + xs2 - x - vp->v_xoff; + while (xs2++ <= xe2) + PUTCHARLP(*s2++); + } +} + +void +LClearLine(l, y, xs, xe, ol) +struct layer *l; +int xs, xe; +struct mline *ol; +{ + struct canvas *cv; + struct viewport *vp; + int y2, xs2, xe2; + + /* check for magic margin condition */ + if (xs >= l->l_width) + xs = l->l_width - 1; + if (xe >= l->l_width) + xe = l->l_width - 1; + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + for (vp = cv->c_vplist; vp; vp = vp->v_next) + { + xs2 = xs + vp->v_xoff; + xe2 = xe + vp->v_xoff; + y2 = y + vp->v_yoff; + if (y2 < vp->v_ys || y2 > vp->v_ye) + continue; + if (xs2 < vp->v_xs) + xs2 = vp->v_xs; + if (xe2 > vp->v_xe) + xe2 = vp->v_xe; + if (xs2 > xe2) + continue; + display = cv->c_display; + DisplayLine(ol ? mloff(ol, -vp->v_xoff) : &mline_null, &mline_blank, y2, xs2, xe2); + } +} + +void +LClear(l, xs, ys, xe, ye, uself) +struct layer *l; +int xs, ys, xe, ye; +int uself; +{ + struct canvas *cv; + struct viewport *vp; + int xs2, ys2, xe2, ye2; +#ifdef HAVE_BRAILLE + if (bd.bd_refreshing) + return; +#endif + /* check for magic margin condition */ + if (xs >= l->l_width) + xs = l->l_width - 1; + if (xe >= l->l_width) + xe = l->l_width - 1; + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + for (vp = cv->c_vplist; vp; vp = vp->v_next) + { + xs2 = xs + vp->v_xoff; + xe2 = xe + vp->v_xoff; + ys2 = ys + vp->v_yoff; + ye2 = ye + vp->v_yoff; + if (xs2 < vp->v_xs) + xs2 = vp->v_xs; + if (xe2 > vp->v_xe) + xe2 = vp->v_xe; + if (xs2 > vp->v_xe) + ys2++; + if (xe2 < vp->v_xs) + ye2--; + if (ys2 < vp->v_ys) + ys2 = vp->v_ys; + if (ye2 > vp->v_ye) + ye2 = vp->v_ye; + if (ys2 > ye2) + continue; +#if 0 + xcs = vp->v_xoff; + xce = l->l_width - 1 + vp->v_xoff; + if (xcs < vp->v_xs) + xcs = vp->v_xs; + if (xce > vp->v_xe) + xce = vp->v_xe; + if (xcs > xce) + continue; + if (ys2 != ys + vp->v_yoff) + xs2 = xcs; + if (ye2 != ye + vp->v_yoff) + xe2 = xce; + display = cv->c_display; + Clear(xs2, ys2, xcs, xce, xe2, ye2, uself); +#else + if (xs == 0 || ys2 != ys + vp->v_yoff) + xs2 = vp->v_xs; + if (xe == l->l_width - 1 || ye2 != ye + vp->v_yoff) + xe2 = vp->v_xe; + display = cv->c_display; + Clear(xs2, ys2, vp->v_xs, vp->v_xe, xe2, ye2, uself); +#endif + } +} + +void +LCDisplayLine(l, ml, y, xs, xe, isblank) +struct layer *l; +struct mline *ml; +int y, xs, xe; +int isblank; +{ + struct canvas *cv; + struct viewport *vp; + int xs2, xe2, y2; +#ifdef HAVE_BRAILLE + if (bd.bd_refreshing) + { + BCDisplayLine(l, ml, y, xs, xe, isblank); + return; + } +#endif + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + for (vp = cv->c_vplist; vp; vp = vp->v_next) + { + xs2 = xs + vp->v_xoff; + xe2 = xe + vp->v_xoff; + y2 = y + vp->v_yoff; + if (y2 < vp->v_ys || y2 > vp->v_ye) + continue; + if (xs2 < vp->v_xs) + xs2 = vp->v_xs; + if (xe2 > vp->v_xe) + xe2 = vp->v_xe; + if (xs2 > xe2) + continue; + display = cv->c_display; + debug3("LCDisplayLine: DisplayLine %d, %d-%d", y2, xs2, xe2); + debug1(" mloff = %d\n", -vp->v_xoff); + DisplayLine(isblank ? &mline_blank : &mline_null, mloff(ml, -vp->v_xoff), y2, xs2, xe2); + } +} + +void +LSetRendition(l, r) +struct layer *l; +struct mchar *r; +{ + struct canvas *cv; + struct viewport *vp; + + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + for (vp = cv->c_vplist; vp; vp = vp->v_next) + { + display = cv->c_display; + SetRendition(r); + } +} + +void +LWrapChar(l, c, y, top, bot, ins) +struct layer *l; +struct mchar *c; +int y, top, bot; +int ins; +{ + struct canvas *cv, *cvlist, *cvlnext; + struct viewport *vp, *evp, **vpp; + int yy, y2, yy2, top2, bot2; + + if (y != bot) + { + /* simple case: no scrolling */ + + /* cursor after wrapping */ + yy = y == l->l_height - 1 ? y : y + 1; + + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + { + display = cv->c_display; + /* find the viewport of the wrapped character */ + for (vp = cv->c_vplist; vp; vp = vp->v_next) + { + y2 = y + vp->v_yoff; + yy2 = yy + vp->v_yoff; + if (yy2 >= vp->v_ys && yy2 <= vp->v_ye && vp->v_xoff >= vp->v_xs && vp->v_xoff <= vp->v_xe) + break; + } + if (vp == 0) + continue; /* nothing to do, character not visible */ + /* find the viewport of the character at the end of the line*/ + for (evp = cv->c_vplist; evp; evp = evp->v_next) + if (y2 >= evp->v_ys && y2 <= evp->v_ye && evp->v_xoff + l->l_width - 1 >= evp->v_xs && evp->v_xoff + l->l_width - 1 <= evp->v_xe) + break; /* gotcha! */ + if (evp == 0 || (ins && vp->v_xoff + l->l_width - 1 > vp->v_ye)) + { + /* no wrapping possible */ + debug("LWrap: can't wrap!\n"); + cvlist = l->l_cvlist; + cvlnext = cv->c_lnext; + l->l_cvlist = cv; + cv->c_lnext = 0; + if (ins) + LInsChar(l, c, 0, yy, 0); + else + LPutChar(l, c, 0, yy); + l->l_cvlist = cvlist; + cv->c_lnext = cvlnext; + } + else + WrapChar(c, vp->v_xoff + l->l_width, y2, vp->v_xoff, -1, vp->v_xoff + l->l_width - 1, -1, ins); + } + } + else + { + /* hard case: scroll up*/ + + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + { + display = cv->c_display; + /* search for wrap viewport */ + for (vpp = &cv->c_vplist; (vp = *vpp); vpp = &vp->v_next) + { + yy2 = bot + vp->v_yoff; + if (yy2 >= vp->v_ys && yy2 <= vp->v_ye && vp->v_xoff >= vp->v_xs && vp->v_xoff + l->l_width - 1 <= vp->v_xe) + break; + } + + if (vp) + { + /* great, can use Wrap on the vp */ + /* temporarily remove vp from cvlist */ + *vpp = vp->v_next; + } + if (cv->c_vplist) + { + /* scroll all viewports != vp */ + cvlist = l->l_cvlist; + cvlnext = cv->c_lnext; + l->l_cvlist = cv; + cv->c_lnext = 0; + LScrollV(l, 1, top, bot); + if (!vp) + { + if (ins) + LInsChar(l, c, 0, bot, 0); + else + LPutChar(l, c, 0, bot); + } + l->l_cvlist = cvlist; + cv->c_lnext = cvlnext; + } + if (vp) + { + /* add vp back to cvlist */ + *vpp = vp; + top2 = top + vp->v_yoff; + bot2 = bot + vp->v_yoff; + if (top2 < vp->v_ys) + top2 = vp->v_ys; + WrapChar(c, vp->v_xoff + l->l_width, bot2, vp->v_xoff, top2, vp->v_xoff + l->l_width - 1, bot2, ins); + } + } + } +} + + +void +LCursorVisibility(l, vis) +struct layer *l; +int vis; +{ + struct canvas *cv; + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + { + display = cv->c_display; + if (cv != D_forecv) + continue; + CursorVisibility(vis); + } +} + +void +LSetFlow(l, flow) +struct layer *l; +int flow; +{ + struct canvas *cv; + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + { + display = cv->c_display; + if (cv != D_forecv) + continue; + SetFlow(flow); + } +} + +void +LKeypadMode(l, on) +struct layer *l; +int on; +{ + struct canvas *cv; + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + { + display = cv->c_display; + if (cv != D_forecv) + continue; + KeypadMode(on); + } +} + +void +LCursorkeysMode(l, on) +struct layer *l; +int on; +{ + struct canvas *cv; + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + { + display = cv->c_display; + if (cv != D_forecv) + continue; + CursorkeysMode(on); + } +} + + +/*******************************************************************/ + +void +ClearLayer(l, uself) +struct layer *l; +int uself; +{ + LClear(l, 0, 0, l->l_width - 1, l->l_height - 1, uself); +} + +void +RedisplayLayer(l, isblank) +struct layer *l; +int isblank; +{ + struct layer *oldflayer; + int y; + + debug1("RedisplayLayer isblank=%d\n", isblank); + oldflayer = flayer; + flayer = l; + if (!isblank) + LClear(l, 0, 0, l->l_width - 1, l->l_height - 1, 0); + /* signal full refresh */ + RedisplayLine(-1, -1, -1, 1); + for (y = 0; y < l->l_height; y++) + RedisplayLine(y, 0, l->l_width - 1, 1); + flayer = oldflayer; +} + + +void +KillLayerChain(lay) +struct layer *lay; +{ + struct canvas *cv, *ncv; + struct layer *l, *oldflayer; + + oldflayer = flayer; + debug1("KillLayerChain %#x\n", lay); + for (l = lay; l; l = l->l_next) + { + if (l->l_layfn == &WinLf || l->l_layfn == &BlankLf) + break; + debug1("- killing %#x\n", l); + if (oldflayer == l) + oldflayer = 0; + for (cv = l->l_cvlist; cv; cv = ncv) + { + ncv = cv->c_lnext; + cv->c_layer = 0; + cv->c_lnext = 0; + } + } + flayer = lay; + while (flayer != l) + ExitOverlayPage(); + flayer = oldflayer; +} + + +/*******************************************************************/ +/*******************************************************************/ + +/* + * Layer creation / removal + */ + +int +InitOverlayPage(datasize, lf, block) +int datasize; +struct LayFuncs *lf; +int block; +{ + char *data; + struct layer *newlay; + struct canvas *cv, *cvp, **cvpp; + struct win *p; + + ASSERT(flayer); + + cv = 0; + if (display && D_forecv->c_layer == flayer) + cv = D_forecv; /* work only on this cv! */ + + if ((newlay = (struct layer *)calloc(1, sizeof(struct layer))) == 0) + { + Msg(0, "No memory for layer struct"); + return -1; + } + debug2("Entering new layer on top of %#x: %#x\n", (unsigned int)flayer, newlay); + data = 0; + if (datasize) + { + if ((data = malloc(datasize)) == 0) + { + free((char *)newlay); + Msg(0, "No memory for layer data"); + return -1; + } + bzero(data, datasize); + } + + p = Layer2Window(flayer); + + if (p && (p->w_savelayer == flayer || (block && flayer->l_next == 0))) + { + if (p->w_savelayer && p->w_savelayer != flayer && p->w_savelayer->l_cvlist == 0) + KillLayerChain(p->w_savelayer); + p->w_savelayer = newlay; + } + + if (cv && flayer->l_next == 0 && !block) + { + struct display *olddisplay = display; + display = cv->c_display; + RemoveStatus(); + display = olddisplay; + + /* new branch -> just get canvas vps */ + for (cvpp = &flayer->l_cvlist; (cvp = *cvpp); cvpp = &cvp->c_lnext) + if (cvp == cv) + break; + ASSERT(cvp); + *cvpp = cv->c_lnext; + newlay->l_cvlist = cv; + cv->c_lnext = 0; + cv->c_layer = newlay; + } + else + { + LAY_DISPLAYS(flayer, RemoveStatus()); + if (block) + debug("layer is blocking\n"); + if (block && flayer->l_layfn == &WinLf) + { + debug("...and is first, so window gets blocked\n"); + ASSERT(p->w_blocked == 0); + p->w_blocked++; + newlay->l_blocking = 1; + } + /* change all canvases */ + newlay->l_cvlist = flayer->l_cvlist; + for (cvp = newlay->l_cvlist; cvp; cvp = cvp->c_lnext) + cvp->c_layer = newlay; + flayer->l_cvlist = 0; + } + newlay->l_width = flayer->l_width; + newlay->l_height = flayer->l_height; + newlay->l_layfn = lf; + newlay->l_data = data; + newlay->l_next = flayer; + newlay->l_bottom = flayer->l_bottom; + flayer = newlay; + Restore(); + return 0; +} + +void +ExitOverlayPage() +{ + struct layer *oldlay; + struct win *p; + int doredisplay = 0; + struct canvas *cv, *ocv; + + ASSERT(flayer); + debug1("Exiting layer %#x\n", (unsigned int)flayer); + oldlay = flayer; + if (oldlay->l_data) + free(oldlay->l_data); + + p = Layer2Window(flayer); + + flayer = oldlay->l_next; + if (flayer->l_layfn == &WinLf) + { + if (oldlay->l_blocking) + { + ASSERT(p->w_blocked > 0); + p->w_blocked--; + debug1("layer was blocking, -> w_blocked now %d\n", p->w_blocked); + } + /* don't warp dead layers: check cvlist */ + if (p->w_blocked && p->w_savelayer && p->w_savelayer != flayer && oldlay->l_cvlist) + { + debug("warping to top of blocking chain!\n"); + /* warp ourself into savelayer */ + flayer = p->w_savelayer; + doredisplay = 1; + } + } + if (p && p->w_savelayer == oldlay) + p->w_savelayer = flayer; +#ifdef COPY_PASTE + if (p && oldlay == p->w_paster.pa_pastelayer) + p->w_paster.pa_pastelayer = 0; +#endif + + /* add all canvases back into next layer's canvas list */ + for (ocv = 0, cv = oldlay->l_cvlist; cv; cv = cv->c_lnext) + { + cv->c_layer = flayer; + ocv = cv; + } + if (ocv) + { + cv = flayer->l_cvlist; + ocv->c_lnext = 0; + flayer->l_cvlist = oldlay->l_cvlist; + /* redisplay only the warped cvs */ + if (doredisplay) + RedisplayLayer(flayer, 0); + ocv->c_lnext = cv; + } + oldlay->l_cvlist = 0; + free((char *)oldlay); + Restore(); + SetCursor(); +} + +void +/*VARARGS2*/ +#if defined(USEVARARGS) && defined(__STDC__) +LMsg(int err, char *fmt, VA_DOTS) +#else +LMsg(err, fmt, VA_DOTS) +int err; +char *fmt; +VA_DECL +#endif +{ + VA_LIST(ap) + char buf[MAXPATHLEN*2]; + char *p = buf; + struct canvas *cv; + + VA_START(ap, fmt); + fmt = DoNLS(fmt); + (void)vsnprintf(p, sizeof(buf) - 100, fmt, VA_ARGS(ap)); + VA_END(ap); + if (err) + { + p += strlen(p); + *p++ = ':'; + *p++ = ' '; + strncpy(p, strerror(err), buf + sizeof(buf) - p - 1); + buf[sizeof(buf) - 1] = 0; + } + debug2("LMsg('%s') (%#x);\n", buf, (unsigned int)flayer); + for (display = displays; display; display = display->d_next) + { + for (cv = D_cvlist; cv; cv = cv->c_next) + if (cv->c_layer == flayer) + break; + if (cv == 0) + continue; + MakeStatus(buf); + } +} + |