Esempio n. 1
0
void
LoadLayout(struct layout *lay)
{
  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;
  if (!D_forecv)
    MakeDefaultCanvas();
  D_forecv = lay->lay_forecv;
  if (!D_forecv)
    MakeDefaultCanvas();
  DupLayoutCv(&lay->lay_canvas, &D_canvas, 0);
  D_canvas.c_ys = (D_has_hstatus == HSTATUS_FIRSTLINE);
  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;
}
Esempio n. 2
0
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();
}
Esempio n. 3
0
void RemCanvas()
{
	int 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);
	}
	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();
}
Esempio n. 4
0
void FreeCanvas(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);
		LayerCleanupMemory(&cv->c_blank);
		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);
	LayerCleanupMemory(&cv->c_blank);
	free(cv);
}
Esempio n. 5
0
void ResizeCanvas(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;
	debug("ResizeCanvas: %d,%d", xs, ys);
	debug(" %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;
				debug("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;
		debug("corrected to %d\n", focusmin);
	}

	/* pass 1: calculate weight sum */
	for (cv2 = cv, wsum = 0; cv2; cv2 = cv2->c_slnext) {
		debug("  weight %d\n", cv2->c_slweight);
		wsum += cv2->c_slweight;
	}
	debug("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;
		debug("  should %d min %d\n", hh, m);
		if (hh <= m + 1)
			need += m + 1 - hh;
		else
			got += hh - m - 1;
	}
	debug("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;
		debug("  should %d min %d\n", hh, m);
		if (hh <= m + 1) {
			hh = m + 1;
			debug(" -> %d\n", hh);
		} else {
			int hx = need * (hh - m - 1) / got;
			debug(" -> %d - %d = %d\n", hh, hx, hh - hx);
			got -= (hh - m - 1);
			hh -= hx;
			need -= hx;
			debug("   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;
			debug("  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;
	}
}