Exemplo n.º 1
0
MENU*
workspace_create(void)
{
    MENU *menu;


    const char *choices[] = {
        "Lpr ",
        "Edita ",
        "Visualizza ",
        "Cerca ",
        "Help " ,
    };
    const char *desc[] = {
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
    };


    menu=menu_create(choices, desc, A_SIZE(choices));
    set_menu_format(menu, 1, A_SIZE(choices));
    set_menu_fore(menu, COLOR_PAIR(1) | A_REVERSE);
    set_menu_back(menu, COLOR_PAIR(1));

    post_menu(menu);

    return menu;

}
Exemplo n.º 2
0
MENUPAN*
menucerca_create(void)
{
    MENU *menu;
    MENUPAN *menupan;


    const char *choices[] = {
        "Cerca per Orario",
        "Cerca per Docente",
        "Cerca per Aula",
        "Cerca per Materia"
    };
    const char *desc[] = {
        "M-o ",
        "M-d ",
        "M-a ",
        NULL
    };


    menu=menu_create(choices, desc, A_SIZE(choices));
    menupan=menu_pan_create(menu, 1, 3*ISIZE+1, 3);
    post_menu(menu);


    return menupan;
}
Exemplo n.º 3
0
MENUPAN*
menuhelp_create(void)
{
    MENU *menu;
    MENUPAN *menupan;


    const char *choices[] = {
        "Help",
        SEP,
        "About",
        NULL,
    };
    const char *desc[] = {
        "M-h",
        DSEP,
        NULL,
    };


    menu=menu_create(choices, desc, A_SIZE(choices));
    menupan=menu_pan_create(menu, 1, 4*ISIZE+1, 4);
    post_menu(menu);


    return menupan;
}
Exemplo n.º 4
0
MENUPAN*
menulpr_create(void)
{
    MENU *menu;
    MENUPAN *menupan;


    const char *choices[] = {
        "Cambia path db",
        SEP,
        "Esci",
    };
    const char *desc[] = {
        "M-p",
        DSEP,
        "M-x",
    };


    menu=menu_create(choices, desc, A_SIZE(choices));
    menupan=menu_pan_create(menu, 1, 1, 0);
    post_menu(menu);


    return menupan;
}
Exemplo n.º 5
0
MENUPAN*
menuedita_create(void)
{
    MENU *menu;
    MENUPAN *menupan;


    const char *choices[] = {
        "Inserisci Record",
        "Edita Record",
        "Elimina Record",
    };
    const char *desc[] = {
        "M-i",
        "M-e",
        "M-c  ",
    };


    menu=menu_create(choices, desc, A_SIZE(choices));
    menupan=menu_pan_create(menu, 1, ISIZE+1, 1);
    post_menu(menu);


    return menupan;
}
Exemplo n.º 6
0
// Read the certificate object
X *ReadSecCertFromObject(SECURE *sec, SEC_OBJ *obj)
{
	UINT size;
	X *x;
	UCHAR value[4096];
	BUF *b;
	CK_ATTRIBUTE get[] =
	{
		{CKA_VALUE,		value,		sizeof(value)},
	};
	// Validate arguments
	if (sec == NULL)
	{
		return false;
	}
	if (sec->SessionCreated == false)
	{
		sec->Error = SEC_ERROR_NO_SESSION;
		return false;
	}
	if (sec->LoginFlag == false && obj->Private)
	{
		sec->Error = SEC_ERROR_NOT_LOGIN;
		return false;
	}
	if (obj->Type != SEC_X)
	{
		sec->Error = SEC_ERROR_BAD_PARAMETER;
		return false;
	}

	// Acquisition
	if (sec->Api->C_GetAttributeValue(
		sec->SessionId, obj->Object, get, sizeof(get) / sizeof(get[0])) != CKR_OK)
	{
		sec->Error = SEC_ERROR_HARDWARE_ERROR;
		return 0;
	}

	size = A_SIZE(get, 0);

	// Conversion
	b = NewBuf();
	WriteBuf(b, value, size);
	SeekBuf(b, 0, 0);

	x = BufToX(b, false);
	if (x == NULL)
	{
		sec->Error = SEC_ERROR_INVALID_CERT;
	}

	FreeBuf(b);

	return x;
}
Exemplo n.º 7
0
// Write the certificate object
bool WriteSecCert(SECURE *sec, bool private_obj, char *name, X *x)
{
	UINT obj_class = CKO_CERTIFICATE;
	CK_BBOOL b_true = true, b_false = false, b_private_obj = private_obj;
	UINT cert_type = CKC_X_509;
	CK_DATE start_date, end_date;
	UCHAR subject[MAX_SIZE];
	UCHAR issuer[MAX_SIZE];
	wchar_t w_subject[MAX_SIZE];
	wchar_t w_issuer[MAX_SIZE];
	UCHAR serial_number[MAX_SIZE];
	UCHAR value[4096];
	UINT ret;
	BUF *b;
	UINT object;
	CK_ATTRIBUTE a[] =
	{
		{CKA_SUBJECT,			subject,		0},			// 0
		{CKA_ISSUER,			issuer,			0},			// 1
		{CKA_SERIAL_NUMBER,		serial_number,	0},			// 2
		{CKA_VALUE,				value,			0},			// 3
		{CKA_CLASS,				&obj_class,		sizeof(obj_class)},
		{CKA_TOKEN,				&b_true,		sizeof(b_true)},
		{CKA_PRIVATE,			&b_private_obj,	sizeof(b_private_obj)},
		{CKA_LABEL,				name,			StrLen(name)},
		{CKA_CERTIFICATE_TYPE,	&cert_type,		sizeof(cert_type)},
#if	0		// Don't use these because some tokens fail
		{CKA_START_DATE,		&start_date,	sizeof(start_date)},
		{CKA_END_DATE,			&end_date,		sizeof(end_date)},
#endif
	};
	// Validate arguments
	if (sec == NULL)
	{
		return false;
	}
	if (name == NULL)
	{
		sec->Error = SEC_ERROR_BAD_PARAMETER;
		return false;
	}
	if (sec->SessionCreated == false)
	{
		sec->Error = SEC_ERROR_NO_SESSION;
		return false;
	}
	if (sec->LoginFlag == false && private_obj)
	{
		sec->Error = SEC_ERROR_NOT_LOGIN;
		return false;
	}

	// Copy the certificate to the buffer
	b = XToBuf(x, false);
	if (b == NULL)
	{
		sec->Error = SEC_ERROR_INVALID_CERT;
		return false;
	}
	if (b->Size > sizeof(value))
	{
		// Size is too large
		FreeBuf(b);
		sec->Error = SEC_ERROR_DATA_TOO_BIG;
		return false;
	}
	Copy(value, b->Buf, b->Size);
	A_SIZE(a, 3) = b->Size;
	FreeBuf(b);

	// Store the Subject and the Issuer by encoding into UTF-8
	GetPrintNameFromName(w_subject, sizeof(w_subject), x->subject_name);
	UniToUtf8(subject, sizeof(subject), w_subject);
	A_SIZE(a, 0) = StrLen(subject);
	if (x->root_cert == false)
	{
		GetPrintNameFromName(w_issuer, sizeof(w_issuer), x->issuer_name);
		UniToUtf8(issuer, sizeof(issuer), w_issuer);
		A_SIZE(a, 1) = StrLen(issuer);
	}

	// Copy the serial number
	Copy(serial_number, x->serial->data, MIN(x->serial->size, sizeof(serial_number)));
	A_SIZE(a, 2) = MIN(x->serial->size, sizeof(serial_number));

	// Expiration date information
	UINT64ToCkDate(&start_date, SystemToLocal64(x->notBefore));
	UINT64ToCkDate(&end_date, SystemToLocal64(x->notAfter));

	// Workaround for Gemalto PKCS#11 API. It rejects a private certificate.
	if(sec->Dev->Id == 18 || sec->Dev->Id == 19)
	{
		b_private_obj = false;
	}

	// Remove objects which have the same name
	if (CheckSecObject(sec, name, SEC_X))
	{
		DeleteSecCert(sec, name);
	}

	// Creating
	if ((ret = sec->Api->C_CreateObject(sec->SessionId, a, sizeof(a) / sizeof(a[0]), &object)) != CKR_OK)
	{
		// Failure
		sec->Error = SEC_ERROR_HARDWARE_ERROR;
		Debug("Error: 0x%02x\n", ret);
		return false;
	}

	// Clear Cache
	EraseEnumSecObjectCache(sec);

	return true;
}
Exemplo n.º 8
0
// Write the private key object
bool WriteSecKey(SECURE *sec, bool private_obj, char *name, K *k)
{
	UINT key_type = CKK_RSA;
	CK_BBOOL b_true = true, b_false = false, b_private_obj = private_obj;
	UINT obj_class = CKO_PRIVATE_KEY;
	UINT object;
	UINT ret;
	BUF *b;
	RSA *rsa;
	UCHAR modules[MAX_SIZE], pub[MAX_SIZE], pri[MAX_SIZE], prime1[MAX_SIZE], prime2[MAX_SIZE];
	UCHAR exp1[MAX_SIZE], exp2[MAX_SIZE], coeff[MAX_SIZE];
	CK_ATTRIBUTE a[] =
	{
		{CKA_MODULUS,			modules,		0},		// 0
		{CKA_PUBLIC_EXPONENT,	pub,			0},		// 1
		{CKA_PRIVATE_EXPONENT,	pri,			0},		// 2
		{CKA_PRIME_1,			prime1,			0},		// 3
		{CKA_PRIME_2,			prime2,			0},		// 4
		{CKA_EXPONENT_1,		exp1,			0},		// 5
		{CKA_EXPONENT_2,		exp2,			0},		// 6
		{CKA_COEFFICIENT,		coeff,			0},		// 7

		{CKA_CLASS,				&obj_class,		sizeof(obj_class)},
		{CKA_TOKEN,				&b_true,		sizeof(b_true)},
		{CKA_PRIVATE,			&b_private_obj,	sizeof(b_private_obj)},
		{CKA_LABEL,				name,			StrLen(name)},
		{CKA_KEY_TYPE,			&key_type,		sizeof(key_type)},
		{CKA_DERIVE,			&b_false,		sizeof(b_false)},
		{CKA_SUBJECT,			name,			StrLen(name)},
		{CKA_SENSITIVE,			&b_true,		sizeof(b_true)},
		{CKA_DECRYPT,			&b_true,		sizeof(b_true)},
		{CKA_SIGN,				&b_true,		sizeof(b_true)},
		{CKA_SIGN_RECOVER,		&b_false,		sizeof(b_false)},
		{CKA_EXTRACTABLE,		&b_false,		sizeof(b_false)},
		{CKA_MODIFIABLE,		&b_false,		sizeof(b_false)},
	};

	// Validate arguments
	if (sec == NULL)
	{
		return false;
	}
	if (name == NULL || k == NULL || k->private_key == false)
	{
		sec->Error = SEC_ERROR_BAD_PARAMETER;
		return false;
	}
	if (sec->SessionCreated == false)
	{
		sec->Error = SEC_ERROR_NO_SESSION;
		return false;
	}
	if (sec->LoginFlag == false && private_obj)
	{
		sec->Error = SEC_ERROR_NOT_LOGIN;
		return false;
	}

	// Numeric data generation
	rsa = k->pkey->pkey.rsa;
	if (rsa == NULL)
	{
		sec->Error = SEC_ERROR_BAD_PARAMETER;
		return false;
	}
	b = BigNumToBuf(rsa->n);
	ReadBuf(b, modules, sizeof(modules));
	A_SIZE(a, 0) = b->Size;
	FreeBuf(b);

	b = BigNumToBuf(rsa->e);
	ReadBuf(b, pub, sizeof(pub));
	A_SIZE(a, 1) = b->Size;
	FreeBuf(b);

	b = BigNumToBuf(rsa->d);
	ReadBuf(b, pri, sizeof(pri));
	A_SIZE(a, 2) = b->Size;
	FreeBuf(b);

	b = BigNumToBuf(rsa->p);
	ReadBuf(b, prime1, sizeof(prime1));
	A_SIZE(a, 3) = b->Size;
	FreeBuf(b);

	b = BigNumToBuf(rsa->q);
	ReadBuf(b, prime2, sizeof(prime2));
	A_SIZE(a, 4) = b->Size;
	FreeBuf(b);

	b = BigNumToBuf(rsa->dmp1);
	ReadBuf(b, exp1, sizeof(exp1));
	A_SIZE(a, 5) = b->Size;
	FreeBuf(b);

	b = BigNumToBuf(rsa->dmq1);
	ReadBuf(b, exp2, sizeof(exp2));
	A_SIZE(a, 6) = b->Size;
	FreeBuf(b);

	b = BigNumToBuf(rsa->iqmp);
	ReadBuf(b, coeff, sizeof(coeff));
	A_SIZE(a, 7) = b->Size;
	FreeBuf(b);

	// Delete the old key if it exists
	if (CheckSecObject(sec, name, SEC_K))
	{
		DeleteSecKey(sec, name);
	}

	// Creating
	if ((ret = sec->Api->C_CreateObject(sec->SessionId, a, sizeof(a) / sizeof(a[0]), &object)) != CKR_OK)
	{
		// Failure
		sec->Error = SEC_ERROR_HARDWARE_ERROR;
		Debug("ret: 0x%x\n", ret);
		return false;
	}

	// Clear Cache
	EraseEnumSecObjectCache(sec);

	return true;
}
Exemplo n.º 9
0
bool
PovDemoProc::SetupTmp()
{
	cnumtmp c_tmp;
	char pc[PATH_MAX];
	auto_std_FILE f;

	int fd = gettmpfd(pc, A_SIZE(pc));
	if ( fd < 0 ) {
		errmsg = _("internal error [SetupTmp() 00]");
		::perror("PovDemoProc::SetupTmp() 00");
		return false;
	}
	otmp = ch2wxs(pc);
	::close(fd);
	wxString outf(otmp + wxT(".png"));
	// we expect that (otmp + ".png") does not exist
#ifdef __UNIX__
	fd = symlink(wxs2fn(otmp), wxs2fn(outf));
#else
	fd = open(wxs2fn(outf), O_RDWR|O_CREAT|O_EXCL, 0600);
#endif
	if ( fd < 0 ) {
		errmsg = _("internal error [SetupTmp() 05]");
		::perror("PovDemoProc::SetupTmp() 05");
		::remove(wxs2fn(otmp));
		return false;
	}
#ifndef __UNIX__
	::close(fd);
#endif

	fd = gettmpfd(pc, A_SIZE(pc));
	f.assign(::fdopen(fd, "r+"));
	if ( ! f ) {
		errmsg = _("internal error [SetupTmp() 10]");
		::perror("PovDemoProc::SetupTmp() 10");
		::remove(wxs2fn(otmp));
		::remove(wxs2fn(outf));
		if ( fd >= 0 ) {
			::remove(pc);
			::close(fd);
		}
		return false;
	}
	itmp = ch2wxs(pc);

	can.ExportFILE(f, itmp.AfterLast(SEPC), true);
	int e0 = ::ferror(f);
	int e1 = ::fclose(f.release());
	if ( e0 || e1 ) {
		errmsg = _("internal error [SetupTmp() 20]");
		::perror("PovDemoProc::SetupTmp() 20");
		::remove(wxs2fn(otmp));
		::remove(wxs2fn(outf));
		::remove(wxs2fn(itmp));
		return false;
	}

	fd = gettmpfd(pc, A_SIZE(pc));
	f.assign(::fdopen(fd, "r+"));
	if ( ! f ) {
		errmsg = _("internal error [SetupTmp() 30]");
		::perror("PovDemoProc::SetupTmp() 30");
		::remove(wxs2fn(otmp));
		::remove(wxs2fn(outf));
		::remove(wxs2fn(itmp));
		if ( fd >= 0 ) {
			::remove(pc);
			::close(fd);
		}
		return false;
	}
	itmp2 = ch2wxs(pc);

	writepov(f);
	e0 = ::ferror(f);
	e1 = ::fclose(f.release());
	if ( e0 || e1 ) {
		errmsg = _("internal error [SetupTmp() 40]");
		::perror("PovDemoProc::SetupTmp() 40");
		::remove(wxs2fn(otmp));
		::remove(wxs2fn(outf));
		::remove(wxs2fn(itmp));
		::remove(wxs2fn(itmp2));
		return false;
	}

	wxString pexec;
	if ( ! GetPovExecutable(pexec) ) {
		errmsg =
		_("POV-Ray not found or not executable -- check preferences");
		::remove(wxs2fn(otmp));
		::remove(wxs2fn(outf));
		::remove(wxs2fn(itmp));
		::remove(wxs2fn(itmp2));
		return false;
	}

	wxString opts = GetPovOpts();

#ifdef __UNIX__
	cmd.Printf(wxT("%s %s +FN +I%s +O%s")
		, fmtcst(pexec), fmtcst(opts), fmtcst(itmp2), fmtcst(outf));

	// Added 10-2012 -- the Unix Povray X preview window under
	// new (last few years) compositing/window managers (e.g.
    // KDE, compiz, etc) has unwanted transparency, at least
    // with typical default visual 'TrueColor' -- a workaround
    // that has been reliable (for me) is to give '-visual DirectColor',
    // but I don't know if it is OK as a default.
    // Update: change to add the arg by default, use of envvar
    // is to refrain from using the arg.
    //
    // Update 2013/11/20: POVRay 3.7 released a few days ago, and
    // the Unix build uses SDL (might be an option) which does not
    // accept the this argument, so the default is made false, and
    // and envar added to make the the arg available -- and for fun
    // the old code is left in place so that the user may use
    // both envars and turn on and then off for no good reason.
    bool use_directcolor = false;
    if ( const char* p = std::getenv("POVRAY_USE_DIRECTCOLOR") ) {
        wxString s(ch2wxs(p));
        if ( s == wxT("1")
            || ! s.CmpNoCase(wxT("yes"))
            || ! s.CmpNoCase(wxT("true"))
            || ! s.CmpNoCase(wxT("on"))
            ) {
			use_directcolor = true;
        }
    }
    if ( const char* p = std::getenv("POVRAY_NO_DIRECTCOLOR") ) {
        wxString s(ch2wxs(p));
        if ( s == wxT("1")
            || ! s.CmpNoCase(wxT("yes"))
            || ! s.CmpNoCase(wxT("true"))
            || ! s.CmpNoCase(wxT("on"))
            ) {
			use_directcolor = false;
        }
    }
	if ( use_directcolor ) {
		cmd += wxT(" -visual DirectColor");
	}

#	ifndef _PATH_BSHELL
#	define _PATH_BSHELL "/bin/sh"
#	endif

#	if 0 // decide: should povray messages go to /dev/null, or not?
	cmd = ch2wxs(_PATH_BSHELL " -c 'exec ") + cmd
        + ch2wxs(" < /dev/null > /dev/null 2>&1'");
#	else
	cmd = ch2wxs(_PATH_BSHELL " -c 'exec ") + cmd
        + ch2wxs(" < /dev/null'");
#	endif

#else // __UNIX__

	cmd.Printf(wxT("%s +FN +I%s +O%s /NR %s")
		, fmtcst(pexec), fmtcst(itmp2), fmtcst(outf), fmtcst(opts));

#endif // __UNIX__

	return true;
}
Exemplo n.º 10
0
bool
PovDemoProc::writepov(FILE* f)
{
	const char* clrs [] = {
		"<1,0,0>", "<0,1,0>", "<0,0,1>",
		"<1,1,0>", "<1,0,1>", "<0,1,1>",
		"<0.667,0,0>", "<0,0.667,0>", "<0,0,0.667>",
		"<0.667,0.667,0>", "<0.667,0,0.667>", "<0,0.667,0.667>",
		"<0.333,0,0>", "<0,0.333,0>", "<0,0,0.333>",
		"<0.333,0.333,0>", "<0.333,0,0.333>", "<0,0.333,0.333>"
	};
	const char fst [] =
		"#version 3.5;\n"
		"global_settings { assumed_gamma 1.0 }\n"
		"#include \"colors.inc\"\n"
		"#declare aspect = image_width / image_height;\n\n"
		"#if ( aspect > 1.0 )\n"
		"#declare szadj = 1.0 / aspect;\n"
		"#else\n"
		"#declare szadj = aspect;\n"
		"#end\n\n"
		"light_source { <20, 20, -20>\n"
		"  color White\n}\n\n"
		;
	const char stf [] =
		"#include \"%s\"\n\n"
		"camera {\n"
		"  location <0, 0, %f>\n"
		"  look_at <0, 0, 0>\n"
		"  right x * aspect\n"
		"  angle %f\n"
		"}\n\n"
		"#declare testo = union {\n"
		;
	const char uo [] = "  object { %s\n%s    rotate x * %d\n  }\n";
	const char tx [] = "    texture { pigment { color rgb %s } }\n";
	const char ob [] =
		"object { testo\n"
		"  translate <%f, 0, %f>\n"
		"  scale (1 / %f) * szadj\n"
		"  rotate x * 90\n"
		"}\n\n";
	int clr = 0, n = 0, outcnt = 0;
	wxString t(itmp), tn, tt, ts = wxT("");
	const double cam_pos_adj = 0.25; // trial & error adjustment
	const double cam_angle = 45.0; // this may become configurable

	cnumtmp c_tmp; // ensures real number formatting is in "C" locale

	std::fputs(fst, f);

	t.Replace(wxT("."), wxT("_"), true);
	t = wxT("I_") + t.AfterLast(SEPC);

	std::list<SplineBase*>::iterator i = l.begin();
	//wxStringList decl; // gone as of wx 2.9
	std::set<wxString>  decl;
	wxPoint pmin, pmax;
	double Lx = DBL_MAX, Ly = DBL_MAX;
	double Mx = DBL_MIN, My = DBL_MIN, viewmax = 0.0;
	while ( i != l.end() ) {
		SplineBase* p = *i++;
		
		if ( ! p->POkay() ) {
			continue;
		}
		if ( p->Getobjt() == SplineBase::undef ) {
			continue;
		}

		outcnt++;
		// for whole min and max
		double mnx, mny, mxx, mxy;
		p->CBox(mnx, mny, mxx, mxy);
		// because lathes rotate about 0 . . .
		if ( p->Getobjt() == SplineBase::lathe ) {
			viewmax = std::max(viewmax, std::abs(mxx));
		} else {
			double sw = p->Getsweepmax();
			viewmax = std::max(viewmax, sw);
		}
		Lx = std::min(Lx, mnx);
		Ly = std::min(Ly, mny);
		Mx = std::max(Mx, mxx);
		My = std::max(My, mxy);

		// object attributes
		wxString ts;
		ts = p->GetTexture(); ts.Trim(true); ts.Trim(false);
		if ( SplineBase::NotStringFieldEmpty(ts)
			&& (decl.find(ts) == decl.end()) ) { // !decl.Member(ts) ) {
			std::fprintf(f
			, "#declare %s = texture { pigment { color rgb %s } }\n"
			, wxs2ch(ts), clrs[clr++]);
			if ( clr == A_SIZE(clrs) ) clr = 0;
			decl.insert(ts); // decl.Add(ts);
		}
		ts = p->GetInterior(); ts.Trim(true); ts.Trim(false);
		if ( SplineBase::NotStringFieldEmpty(ts)
			&& (decl.find(ts) == decl.end()) ) { // !decl.Member(ts) ) {
			std::fprintf(f, "#declare %s = interior { ior 1 }\n"
				, wxs2ch(ts));
			decl.insert(ts); // decl.Add(ts);
		}
		ts = p->GetTransform(); ts.Trim(true); ts.Trim(false);
		if ( SplineBase::NotStringFieldEmpty(ts)
			&& (decl.find(ts) == decl.end()) ) { // !decl.Member(ts) ) {
			std::fprintf(f, "#declare %s = transform { rotate x*0 }\n"
				, wxs2ch(ts));
			decl.insert(ts); // decl.Add(ts);
		}
	}

	// write any good objects lately?
	if ( outcnt < 1 ) {
		return false;
	}

    double zp, scale;
    scale = std::max(std::abs(My-Ly), std::abs(Mx-Lx));

    // camera z-position, from two data: camera field angle, and
    // extent of field to be visible (x|y) which will have its
    // center at origin.  Since camera is centered and perpendicular,
    // angle/2 is opposite extent/2 which is one side of the 90 degree
    // angle of a right triangle:
    // (the two data are cam_angle:angle, and scale:visible extent)
    // -- take sine of angle and find radius, which is the hypotenuse:
    zp = std::abs(std::sin(cam_angle / 2.0 / (M_PI * 2.0)));
    zp = (scale / 2.0) / zp; // sin(theta)==y/r ergo r==y/sin(theta)
    // -- zp now holds radius|hypotenuse, so follow Pythagorus to the
    //    remaining side, which is negated for the camera z-position:
    zp = -std::sqrt(zp * zp - std::pow(scale / 2.0, int(2)));
    // -- zp now holds the *simplistic* camera z-position; it does not
    //    account for objects with significant -z extent.  To use maths
    //    to make an adjustment would require more processing of the
    //    calculated curve-points to find the most-deeply-clipped, but
    //    simple fudging will be good enough.  The greatest extent of
    //    all lathes or greatest sweep of prisms is subtracted from
    //    camera z-pos; it will help in some cases, but will merely
    //    reduce the size of the image if the point is near x,y center.
    zp -= viewmax;
    // -- finally, apply the render's scale factor
    zp /= scale;

    // print, and allow a bit of trial & error adjustment camera z-pos
	std::fprintf(f, stf, wxs2ch(itmp), zp - cam_pos_adj, cam_angle);

	//decl.erase(decl.begin(), decl.end()); // decl.Clear();
	clear(decl);
	i = l.begin();
	while ( i != l.end() ) {
		SplineBase* p = *i++;
		int rtt = 0;

		if ( ! p->POkay() ) {
			continue;
		}
		
		tn = p->GetObNam();
		if ( tn == SplineBase::DefaultName ) {
			tn << n;
		}
		n++;

		// continue on undef _after_ checking name
		// and inc'ing n, because objects were exported this way
		if ( p->Getobjt() == SplineBase::undef ) {
			continue;
		}
#if 0 // working on this: see A_Canvas::ExportFile()
		int nn = 0;
		wxString ttn(tn);
		while ( decl.find(ttn) != decl.end() ) {
			ttn = tn;
			ttn << ++nn;
		}
		tn = ttn;
		decl.insert(tn);	
#endif // 0

		tt = wxT("");
		if ( SplineBase::StringFieldEmpty(p->GetTexture()) ) {
			tt.Printf(ch2wxs(tx), ch2wxs(clrs[clr++]).c_str());
			if ( clr == A_SIZE(clrs) ) clr = 0;
		}

        // want to see lathes from side view
        if ( p->Getobjt() == SplineBase::lathe ) {
            rtt = 90;
        }

		std::fprintf(f, uo, wxs2ch(tn), wxs2ch(tt), rtt);
	}
	std::fputs("}\n\n", f);

	std::fprintf(f, ob, -(Mx-Lx)/2.0-Lx, -(My-Ly)/2.0-Ly, scale);

	std::fputs(
		"plane { <0,0,-1>, 0 translate z*50\n"
		"  texture { pigment { color White } }\n"
		"  hollow\n"
		"}\n\n",
		f
	);

	return true;
}