campo-sirio/include/printer.cpp
guy 96c0a54c9c Corretto calcolo di dots_per_line
git-svn-id: svn://10.65.10.50/trunk@971 c028cbd2-c16b-5b4b-a496-9718f37d4682
1995-02-06 13:36:54 +00:00

1605 lines
35 KiB
C++
Executable File

#include <stdlib.h>
#if XVT_OS==XVT_OS_SCOUNIX
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#else
#include <stdio.h>
#endif
#include <strstream.h>
#include <xvt.h>
#define STYLE_NUM 4
#include <applicat.h>
#include <execp.h>
#include <extcdecl.h>
#include <mask.h>
#include <urldefid.h>
#include <utility.h>
#include <viswin.h>
#include <config.h>
#include <bagn001a.h>
struct PrDesc
{
TTextfile *_txt;
PRINT_RCD *_prcd;
bool _graphics;
int _formlen;
int _charsize;
int _lines_per_inch;
}
PrintWhat;
#define LINES_PER_INCH (6.0)
#if XVT_OS == XVT_OS_WIN
#include <windows.h>
void TPrinter::_get_windows_printer_names (TToken_string & t)
{
char *buf = new char[4096]; // ammazzao'
GetProfileString ("devices", NULL, "", buf, 4096);
for (int i = 0; i < 4095; i++)
{
if (buf[i] == '\0' && buf[i + 1] == '\0')
break;
if (buf[i] == '\0' && buf[i + 1] != '\0')
buf[i] = '|';
}
t = buf;
delete buf;
}
BOOLEAN TPrinter::start_winprint (long data)
{
PrDesc *pd = (PrDesc *) data;
TTextfile& txt = *(pd->_txt);
TPrintwin pw(pd->_prcd, txt, pd->_charsize);
pw.print_background (pd->_graphics);
pw.do_print();
return pw.aborted();
}
#endif
// utils del caz
HIDDEN void read_int (const char *s, int &n, int &cnt)
{
static char nbuf[10];
int j = 0;
while (!isdigit (s[cnt]))
cnt++;
while (isdigit (s[cnt]))
nbuf[j++] = s[cnt++];
nbuf[j] = '\0';
n = atoi (nbuf);
}
#if XVT_OS == XVT_OS_WIN
void TPrinter::set_win_formlen ()
{
long pw, ph, phr, pvr;
xvt_escape (XVT_ESC_GET_PRINTER_INFO, _print_rcd, &ph, &pw, &pvr, &phr);
if (pvr != 0)
{
_formlen = (int) ((ph / pvr) * _lines_per_inch);
_dots_per_line = (int) (pvr / _lines_per_inch);
if (_dots_per_line < 1) _dots_per_line = 1;
_vert_offset = (int) (ph % (long) (_formlen * _dots_per_line));
_horz_offset = 0; // not implemented (font dependent)
}
else
warning_box ("Il driver di stampante non e' valido.\n"
"Non stampare prima di averlo reinstallato");
}
#endif
void TPrinter::parse_background(const char* bg_desc, TArray& background)
{
char op;
int x1, x2, y1, y2;
TToken_string tt (20);
TString txt (80);
TArray pix;
char ch;
int cnt = 0;
while ((ch = bg_desc[cnt++]) != '\0')
{
op = ch;
tt = "";
char bf[2];
bf[1] = '\0';
switch (op)
{
case ' ': // ignore whitespace
case '\t':
case '\n':
continue;
break;
case 'l': // line
case 'b': // box
case 'r': // round box
cnt++;
read_int (bg_desc, x1, cnt);
read_int (bg_desc, y1, cnt);
read_int (bg_desc, x2, cnt);
read_int (bg_desc, y2, cnt);
cnt++;
tt << op;
tt.add (x1 - 1);
tt.add (y1 - 1);
tt.add (x2 - 1);
tt.add (y2 - 1);
break;
case 't': // text
cnt++;
read_int (bg_desc, x1, cnt);
read_int (bg_desc, y1, cnt);
cnt++;
txt = "";
while ((ch = bg_desc[cnt++]) != '}')
txt << ch;
tt << op;
tt.add (x1 - 1);
tt.add (y1 - 1);
tt.add (txt);
break;
case 'P': // set pen style
case 'B': // set brush
case 'W': // set line width
case 'C': // set pen color
tt << op;
bf[0] = bg_desc[cnt++];
tt.add (bf);
break;
default:
yesnofatal_box ("Unknown background opcode: %c", op);
break;
}
pix.add (tt);
}
// now build row descriptions
// colors are listed in printapp:
char curcol = 'n';
char curpen = 'n';
char curpat = 'n';
char curwid = '1';
for (int l = 0; l < _formlen; l++)
{
TString *rwd = (TString *) background.objptr (l);
if (rwd == NULL)
{
background.add (rwd = new TString, l);
if (curcol != 'n')
(*rwd) << 'C' << curcol;
if (curpat != 'n')
(*rwd) << 'B' << curpat;
if (curwid != '1')
(*rwd) << 'W' << curwid;
if (curpen != 'n')
(*rwd) << 'P' << curcol;
}
for (int j = 0; j < pix.items (); j++)
{
TToken_string & tt = (TToken_string &) pix[j];
tt.restart ();
// la stringa contiene l'opcode piu' i parametri in binario,
// incrementati di 1 per evitare lo 0
switch (*(tt.get (0)))
{
case 'b':
x1 = tt.get_int (1) + 1;
y1 = tt.get_int (2) + 1;
x2 = tt.get_int (3) + 1;
y2 = tt.get_int (4) + 1;
if (y1 == l + 1) // at ze biginnin
{
(*rwd) << 'u' << char (x1);
(*rwd) << 'r' << char (x1) << char (x2);
(*rwd) << 'u' << char (x2);
}
else if (y2 == l + 1) // at ze end
{
(*rwd) << 'o' << char (x1);
(*rwd) << 'r' << char (x1) << char (x2);
(*rwd) << 'o' << char (x2);
}
else if (y1 < l + 1 && y2 > l + 1) // in ze middol
{
(*rwd) << 'v' << char (x1);
(*rwd) << 'v' << char (x2);
}
break;
case 'l':
x1 = tt.get_int (1) + 1;
y1 = tt.get_int (2) + 1;
x2 = tt.get_int (3) + 1;
y2 = tt.get_int (4) + 1;
if (y1 == y2 && y1 == l + 1) // orizzontale
{
(*rwd) << 'h' << char (x1) << char (x2);
}
else if (y1 <= l + 1 && y2 >= l + 1) // verticale
{
(*rwd) << 'v' << char (x1);
}
break;
case 't':
x1 = tt.get_int (1) + 1;
y1 = tt.get_int (2) + 1; // al gh'e'
if (y1 == l + 1)
{
}
break;
case 'W':
curwid = *(tt.get (1));
(*rwd) << 'W' << curwid;
break;
case 'P':
curpen = *(tt.get (1));
(*rwd) << 'P' << curpen;
break;
case 'B':
curpat = *(tt.get (1));
(*rwd) << 'B' << curpat;
break;
case 'C':
curcol = *(tt.get (1));
(*rwd) << 'C' << curcol;
break;
}
}
}
}
void TPrinter::setbackground(const char *b)
{
_background.destroy();
_bg_desc = b;
if (b != NULL)
parse_background(_bg_desc, _background);
}
bool printers_on_key(TMask_field & f, KEY key);
// fv support structs for config
bool PrinterDef::read (const char *name, FILE * fd)
{
_printername = name;
_printername.trim ();
TToken_string tmp (64, '=');
TString l (48);
TString r (16);
while (TRUE)
{
const long p = ftell (fd); // Memorizza inizio paragrafo
if (fgets (__tmp_string, 256, fd) == NULL)
return FALSE;
tmp = __tmp_string;
tmp.trim ();
if (tmp == "[End of File]")
return FALSE;
if (tmp[0] == '[')
{
fseek (fd, p, SEEK_SET); // Ritorna ad inizio paragrafo
break;
}
l = tmp.get ();
l.trim ();
r = tmp.get ();
r.trim ();
if (l == "Device name")
{
_devicename = r;
}
else if (l == "Filter name")
{
_filtername = r;
}
else if (l == "Printer type")
{
_printertype = r;
}
else if (l == "Normal")
{
strcpy (_atstr[normalstyle], r);
}
else if (l == "Bold")
{
strcpy (_atstr[boldstyle], r);
}
else if (l == "Italic")
{
strcpy (_atstr[italicstyle], r);
}
else if (l == "Underlined")
{
strcpy (_atstr[underlinedstyle], r);
}
else if (l == "Code")
{
TToken_string code (r);
_names.add (TString (code.get ()));
_codes.add (TString (code.get ()));
}
else if (l == "Form feed")
{
_ffcode = r;
}
else if (l == "Newline")
{
_nlcode = r;
}
else
return error_box ("Riga di configurazione stampante errata:\n%s", (const char *) l);
}
return TRUE;
}
bool PrinterDef::isdefault ()
{
return strcmp(_printername, "Default") == 0;
}
////////// TPRINTROW //////////
TPrintrow::TPrintrow()
{
reset();
}
TPrintrow::TPrintrow(const TPrintrow& pr)
{
_row = pr.row ();
memcpy (_attr, pr._attr, MAXSTR);
memcpy (_cols, pr._cols, MAXSTR);
_currentcolor = 'w';
_currentcolor <<= 8;
_currentcolor += 'n';
_currentstyle = pr._currentstyle;
for (int i = 0; i < MAXSTR; i++)
_cols[i] = _currentcolor;
_lastpos = pr._lastpos;
}
TObject *TPrintrow::dup () const
{
return new TPrintrow (*this);
}
const char *TPrintrow::class_name () const
{
return "Printrow";
}
word TPrintrow::class_id()
const
{
return CLASS_PRINTROW;
}
TPrintrow & TPrintrow::reset ()
{
_row.spaces (sizeof (_attr));
_currentcolor = 'w';
_currentcolor <<= 8;
_currentcolor += 'n';
memset (_attr, normalstyle, sizeof (_attr));
for (int i = 0; i < MAXSTR; i++)
_cols[i] = _currentcolor;
_lastpos = 0;
_currentstyle = normalstyle;
return *this;
}
const char* TPrintrow::row_codified() const
{
// returns the row with @-codes for font style and color
char last_attr = -1;
int last_color = -1;
int last = 0, k = 0, len = -1;
for (int i = 0; i < _row.size(); i++)
if (_row[i] > ' ') len = i;
for (i = 0; i < _row.size(); i++)
{
if (_attr[i] != last_attr)
{
__tmp_string[k++] = '@';
switch (_attr[i])
{
case normalstyle:
__tmp_string[k++] = 'r';
break;
case boldstyle:
__tmp_string[k++] = 'b';
break;
case italicstyle:
__tmp_string[k++] = 'i';
break;
case underlinedstyle:
__tmp_string[k++] = 'u';
break;
}
last_attr = _attr[i];
}
if (_cols[i] != last_color && i <= len)
{
__tmp_string[k++] = '$';
__tmp_string[k++] = '[';
__tmp_string[k++] = (char) (_cols[i] & 0x00ff);
__tmp_string[k++] = ',';
__tmp_string[k++] = (char) (_cols[i] >> 8);
__tmp_string[k++] = ']';
last_color = _cols[i];
}
__tmp_string[k++] = _row[i];
if (_row[i] > ' ') last = k;
}
__tmp_string[last] = '\0';
return __tmp_string;
}
TPrintrow & TPrintrow::put(const char *str, int position, int len)
{
if (len < 1)
len = strlen (str);
if (position < 0)
position = _lastpos;
char bg = 'w', fg = 'n';
for (int i = 0; i < len; i++)
{
char c = str[i];
if (c == '$' && str[i + 1] == '[')
{
++i;
fg = str[++i];
c = str[++i];
if (c == ']')
bg = _currentcolor >> 8;
else if (c == ',')
{
bg = str[++i];
i++;
}
else
{
CHECK (0, "Error in color specification");
}
_currentcolor = (bg << 8) + fg;
}
else if (c == '@')
{
c = str[++i];
switch (toupper (c))
{
case '#':
case '<':
case '>':
// printer MUST handle them
{
const int n = (c == '#') ? 5 : ((c == '>') ? 10 : 8);
_row[position] = '@';
_attr[position++] = _currentstyle;
for (int j = 1; j < n; j++)
{
_row[position] = c;
_attr[position++] = _currentstyle;
}
}
break;
case 'B':
_currentstyle = boldstyle;
break;
case 'I':
_currentstyle = italicstyle;
break;
case 'U':
_currentstyle = underlinedstyle;
break;
case 'R':
_currentstyle = normalstyle;
break;
default:
// should be number followed by skip or jump
if (isdigit (c))
{
// read number
char digbuf[8];
int cnt = 0;
digbuf[cnt++] = c;
while (isdigit (c = str[++i]))
digbuf[cnt++] = c;
digbuf[cnt] = '\0';
int pp = atoi (digbuf);
if (toupper (c) == 'G')
{
if (pp >= MAXSTR)
fatal_box ("printrow reaches position %d", pp);
if (pp > position)
for (int k = position; k < pp; k++)
{
_attr[k] = _currentstyle;
_cols[k] = _currentcolor;
}
position = pp;
}
else if (toupper (c) == 'J')
{
if (pp + position >= MAXSTR)
fatal_box ("printrow reaches position %d", pp + position);
for (int k = 0; k < pp; k++)
{
_attr[k + position] = _currentstyle;
_cols[k + position] = _currentcolor;
}
position += pp;
}
}
else
{
_row[position] = c;
_attr[position++] = _currentstyle;
_cols[position++] = _currentcolor;
}
} // switch
}
else
{
_row[position] = c;
_attr[position] = _currentstyle;
_cols[position++] = _currentcolor;
}
} // for
_lastpos = position;
return *this;
}
////////// TPRINTER //////////
bool printers_on_key (TMask_field & f, KEY key)
{
if (key == K_SPACE)
{
TToken_string pn1 (10), pn2 (20);
const PrinterDef & def = main_app().printer().get_description(atoi(f.get ()));
const char *s;
int j = 0;
while ((s = def.get_codenames (j)) != NULL)
{
pn1.add (format ("%02d", j));
pn2.add (s);
j++;
}
((TList_field &) f.mask ().field (MSK_1_CODES)).replace_items (pn1, pn2);
}
return TRUE;
}
#if XVT_OS == XVT_OS_WIN
bool set_windows_print_device (TMask_field& f, KEY key)
{
static char szDevice[80];
if (key == K_SPACE && f.mask().is_running())
{
if (main_app().printer().get_printrcd() != NULL)
free_print_rcd (main_app().printer().get_printrcd ());
TToken_string & pn = main_app().printer().getprinternames ();
TString pdev (pn.get (atoi (f.get())));
GetProfileString ("devices", pdev, "", szDevice, sizeof (szDevice));
pdev << "," << szDevice;
// scrivi (e semmai lo si risistema poi)
WriteProfileString("windows", "device", pdev);
main_app().printer().set_printrcd(
get_print_rcd(&(main_app().printer ().get_printrcdsize ())));
main_app().printer().set_win_formlen();
}
return TRUE;
}
#endif
TPrinter::TPrinter()
: _date (TODAY), _multiple_link (FALSE), _frozen (FALSE), _isgraphics (TRUE),
_lines_per_inch (6), _ch_size (12), _ncopies(1)
{
_footerhandler = _headerhandler = NULL;
_linkhandler = NULL;
_config = "printer.ini";
_curprn = 0; // first in list if no default is specified
_curcode = 0; // first in list if no default is specified
_formlen = 66;
_frompage = 0;
_topage = 0xffff;
_hwformfeed = FALSE;
_currentpage = 1;
_currentrow = 1;
_fp = NULL;
_headersize = 0;
_footersize = 0;
_isopen = FALSE;
_multiple_copies = main_app().class_id() == CLASS_PRINT_APPLICATION;
// read configuration file
read_configuration (_config);
#if XVT_OS == XVT_OS_WIN
print_begin ();
_print_rcd = get_print_rcd (&_print_rcd_size);
set_win_formlen ();
static char defPrinter[80];
static char szDevice[50];
// get default printer driver
GetProfileString ("windows", "device", ",,,", defPrinter, sizeof(defPrinter));
TString pdev (defPrinter);
GetProfileString ("devices", pdev, "", szDevice, sizeof(szDevice));
pdev << "," << szDevice;
TToken_string dio (pdev, ',');
TToken_string pn2(1024);
// get printer names
_get_windows_printer_names (pn2);
// determine index of current default printer
for (int i = 0; i < pn2.items (); i++)
{
if (TString(dio.get(0)) == TString(pn2.get(i)))
{
_curprn = i;
break;
}
}
TConfig cnf (CONFIG_GENERAL, "Stampa");
_ch_size = cnf.get_int("Size",NULL,-1,12);
_lines_per_inch = cnf.get_int("Lines",NULL,-1,6);
#else
_isgraphics = FALSE;
#endif
}
TToken_string& TPrinter::getprinternames ()
{
// per ora va solo in windows
#if XVT_OS == XVT_OS_WIN
_get_windows_printer_names (_printer_names);
#endif
return _printer_names;
}
void TPrinter::read_configuration(const char *conf)
{
FILE *cnfp = fopen (conf, "r");
if (cnfp == NULL)
fatal_box ("Impossibile aprire il file %s", (const char *) _config);
for (int i = 0; !feof (cnfp); i++)
{
if (fgets (__tmp_string, 256, cnfp) == NULL)
return;
// else
if (strncmp (__tmp_string, "[Default]", 9) != 0)
// fgets(__tmp_string,256,cnfp);
// else
{
if (*__tmp_string == '[')
{
// fatal_box("[ expected in file of printer configuration");
char *u = strchr (__tmp_string, ']');
if (u)
*u = '\0';
u = __tmp_string + 1;
PrinterDef *pp = new PrinterDef;
_printers.add (pp);
if (pp->read (u, cnfp) == FALSE)
break;
}
}
}
fclose (cnfp);
TFilename s ("printer.def");
#if XVT_OS == XVT_OS_SCOUNIX
s << format (".%d", getuid ());
#endif
if (fexist (s))
{
TScanner sc (s);
TToken_string t (sc.line ());
int where_print = t.get_int (1);
t = sc.line ();
_curprn = t.get_int(1);
t = sc.line ();
_printerfile = t.get (1);
t = sc.line ();
_curcode = t.get_int (1);
#if XVT_OS != XVT_OS_WIN
PrinterDef & def = (PrinterDef &) get_description (_curprn);
#endif
switch (where_print)
{
case 0: // stampante
#if XVT_OS == XVT_OS_WIN
_printertype = winprinter;
#else
switch (atoi (def._printertype))
{
case 0:
_printertype = normprinter;
break;
case 1:
_printertype = localprinter;
break;
case 2:
_printertype = spoolprinter;
break;
}
#endif
break;
case 1: // file
_printertype = fileprinter;
break;
case 2: // video
_printertype = screenvis;
_curcode = 0;
break;
}
}
}
TPrinter::~TPrinter ()
{
#if XVT_OS == XVT_OS_WIN
print_end ();
#endif
}
const char* TPrinter::class_name () const
{
return "Printer";
}
word TPrinter::class_id () const
{
return CLASS_PRINTER;
}
TPrintrow *TPrinter::getheaderline (int linetoget)
{
return ((TPrintrow *) _header.objptr (linetoget));
}
TPrintrow *TPrinter::getfooterline (int linetoget)
{
return ((TPrintrow *) _footer.objptr (linetoget));
}
void TPrinter::setheaderline (int linetoset, TPrintrow * line)
{
_header.add (line, linetoset);
if (linetoset >= _headersize)
_headersize = linetoset + 1;
}
void TPrinter::setheaderline (int linetoset, const TPrintrow & line)
{
TPrintrow *p = new TPrintrow (line);
setheaderline (linetoset, p);
}
void TPrinter::setfooterline (int linetoset, TPrintrow* line)
{
_footer.add (line, linetoset);
// if (linetoset >= _footersize) _footersize = linetoset+1;
}
void TPrinter::setfooterline (int linetoset, const TPrintrow& line)
{
TPrintrow *p = new TPrintrow (line);
setfooterline (linetoset, p);
}
void TPrinter::resetheader ()
{
_header.destroy ();
_headersize = 0;
}
void TPrinter::resetfooter ()
{
_footer.destroy ();
// _footersize = 0;
}
bool TPrinter::printrow(TPrintrow* rowtoprint)
{
if (!isopen ())
return FALSE;
if (_currentpage < _frompage || _currentpage > _topage)
return TRUE;
TString rw (rowtoprint == NULL ? "" : (_printertype == screenvis || _printertype == winprinter ||
_printertype == export ?
rowtoprint->row_codified () :
rowtoprint->row ()));
rw.rtrim ();
int lun = rw.len ();
int idx;
if (_printertype != export)
{
for (idx = 0; idx < lun; idx++)
{
if (rw[idx] == '@') // gestione data e n. di pagina
{
switch (rw[idx + 1])
{
case '#':
rw.overwrite (format("%-5u", _currentpage), idx++);
break;
case '>':
rw.overwrite (_date.string (4), idx++);
break;
case '<':
rw.overwrite (_date.string (2), idx++);
break;
default:
break;
}
}
}
}
if (_printertype == screenvis)
{
if (!_vf->frozen ())
_vf->add_line (rw);
else
_frozen = TRUE;
return TRUE;
}
if (_printertype == winprinter || _printertype == export)
{
// add line to txt
if (!_frozen)
_txt.append(rw);
return TRUE;
}
#if XVT_OS != XVT_OS_SCOUNIX
if (_printertype == fileprinter)
{
// add line to txt
if (!_frozen)
_txt.append (rw);
return TRUE;
}
#else
const PrinterDef & pd = get_description (_curprn);
int prvstl = -1;
for (idx = 0; idx < lun; idx++)
{
int cst = rowtoprint->get_style (idx);
if (cst != prvstl)
{
fprintf (_fp, "%s", pd._atstr[normalstyle]);
if (cst != normalstyle)
fprintf (_fp, "%s", pd._atstr[cst]);
}
prvstl = cst;
putc (rw[idx], _fp);
}
if (newline ())
putc (newline (), _fp);
#endif
return TRUE;
}
word TPrinter::rows_left() const
{
word left = _formlen - _currentrow - _footersize + 1;
if (_currentrow < 2)
left -= _headersize;
return left;
}
bool TPrinter::print(TPrintrow& rowtoprint)
{
bool ok = TRUE;
if (!(_printertype == export && !_export_header))
{
if (_currentrow > _formlen - _footersize)
ok = printfooter ();
if (ok && _currentrow == 1)
ok = printheader();
}
if (ok)
{
ok = printrow(&rowtoprint);
_currentrow++;
}
return ok;
}
bool TPrinter::printheader()
{
if (_headerhandler)
_headerhandler (*this);
bool ok = TRUE;
for (int i = 0; i < _headersize && ok; i++)
ok = printrow(getheaderline(i));
_currentrow = _headersize + 1;
return ok;
}
bool TPrinter::printfooter()
{
if (_footerhandler)
_footerhandler (*this);
bool ok = TRUE;
for (int i = 0; i < _footersize && ok; i++)
ok = printrow(getfooterline(i));
#if XVT_OS != XVT_OS_WIN
if (ok)
printformfeed();
#endif
_currentrow = 1;
_currentpage++;
return ok;
}
bool TPrinter::skip(int linestoskip)
{
int jumpline;
CHECK (linestoskip >= 0, "Linestoskip can't be negative");
jumpline = _currentrow + linestoskip;
return jump(jumpline);
}
bool TPrinter::jump(int jumpline)
{
int i = 0;
bool ok = TRUE;
CHECK (jumpline >= 0, "Jumpline can't be negative");
if (jumpline > _formlen - _footersize)
ok = formfeed();
else
for (i = _currentrow; i < jumpline; i++)
if (!printrow())
ok = FALSE;
if (jumpline > _formlen - _footersize)
ok = FALSE;
return ok;
}
bool TPrinter::formfeed()
{
const int lastrow = _formlen - _footersize;
for (; _currentrow <= lastrow; _currentrow++)
printrow();
return printfooter();
}
void TPrinter::reset()
{
resetheader();
resetfooter();
_currentpage = 1;
_currentrow = 1;
}
bool TPrinter::printformfeed()
{
#if XVT_OS != XVT_OS_WIN
const PrinterDef & pd = get_description(_curprn);
if (_printertype != screenvis && _hwformfeed)
fprintf(_fp, "%s",(const char *)pd._ffcode);
#endif
return TRUE;
}
bool TPrinter::open()
{
#if XVT_OS==XVT_OS_SCOUNIX
if (_printertype == spoolprinter)
{
const PrinterDef & def = get_description(_curprn);
int pfd[2];
if (pipe(pfd) == -1)
return error_box ("Impossibile creare processo di stampa " "(pipe)");
int ret = fork();
if (ret == -1)
return error_box("Impossibile creare processo di stampa " "(fork)");
if (ret == 0)
{
if ((::close(0) != -1) && (::dup(pfd[0]) == 0) &&
(::close(pfd[0]) == 0) && (::close(pfd[1]) != -1))
{
char s0[80];
sprintf (s0, "-d%s", (const char *) def._devicename);
if ((def._filtername).not_empty ())
{
char s1[80];
sprintf (s1, "-o %s", (const char *) def._filtername);
char *ws[5] =
{"lpr", "-s", s0, s1, NULL};
execvp (ws[0], ws);
}
else
{
char *ws[4] =
{"lpr", "-s", s0, NULL};
execvp(ws[0], ws);
}
exit(-1);
}
}
if ((::close (pfd[0]) == -1) || ((_fp = fdopen(pfd[1], "w")) == NULL))
return error_box ("Impossibile creare processo di stampa" "(close)");
}
else
#endif
if (_printertype == screenvis)
{
_vf = new TViswin (NULL, "Anteprima di stampa", TRUE, TRUE,
_linksdescr.items () > 0);
_vf->open_modal ();
}
else if (_printertype == winprinter || _printertype == export
#if XVT_OS != XVT_OS_SCOUNIX
|| _printertype == fileprinter
#endif
)
{
// prepare text object for new text
_txt.destroy();
}
#if XVT_OS==XVT_OS_SCOUNIX
else
{
const PrinterDef & def = get_description (_curprn);
TFilename fname (_printerfile);
if (_printertype == normprinter)
fname = def._devicename;
_fp = fopen (fname, "w");
if (_fp == NULL)
return error_box ("Errore di apertura file stampa: '%s'",
(const char *) fname);
TString code (def.get_codes (_curcode));
if (code.not_empty ())
{
const char *s = code;
fputs (esc ((char *) s), _fp);
}
}
#endif
_currentrow = 1;
_currentpage = 1;
return _isopen = TRUE;
}
void TPrinter::set()
{
main_app().disable_menu_item (M_FILE_PG_SETUP);
TMask mask ("bagn001a");
TToken_string pn1 (50), pn2 (100);
int i;
if (_printerfile.empty())
{
_printerfile.tempdir();
#if XVT_OS == XVT_OS_SCOUNIX
_printerfile << '/';
#else
_printerfile << '\\';
#endif
}
TFilename defile("printer.def");
#if XVT_OS == XVT_OS_SCOUNIX
defile << format (".%d", getuid ());
#endif
mask.set_workfile(defile);
mask.set(MSK_1_FILENAME, _printerfile);
mask.set(MSK_1_NPAGES, _ncopies);
#if XVT_OS != XVT_OS_WIN
for (i = 0; i < _printers.items (); i++)
{
pn1.add (i);
pn2.add (((PrinterDef &) _printers[i])._printername);
}
((TList_field &) (mask.field (MSK_1_PRINTERS))).replace_items (pn1, pn2);
mask.hide(MSK_1_SIZE);
mask.hide(MSK_1_LINES);
mask.disable(DLG_SETPRINT);
if (!_multiple_copies) mask.hide(MSK_1_NPAGES);
pn1 = "";
pn2 = "";
for (i = 0; i < ((PrinterDef &)_printers[_curprn])._names.items(); i++)
{
pn1.add(format ("%d", i));
pn2.add((TString &)((PrinterDef &) _printers[_curprn])._names[i]);
}
((TList_field &)(mask.field (MSK_1_CODES))).replace_items(pn1, pn2);
mask.set_handler (MSK_1_PRINTERS, printers_on_key);
if (_printertype == fileprinter)
mask.set (MSK_1_TYPE, "1");
else if (_printertype == screenvis)
mask.set (MSK_1_TYPE, "2");
else
mask.set (MSK_1_TYPE, "0");
mask.set(MSK_1_PRINTERS, format("%d", _curprn));
mask.set(MSK_1_CODES, format("%d", _curcode));
KEY k;
if ((k = mask.run()) == K_ESC)
return;
if (k == K_INS) // premuto REGISTRA
mask.save();
// get user choices
_curprn = atoi(mask.get(MSK_1_PRINTERS));
_ncopies = atoi(mask.get(MSK_1_NPAGES));
PrinterDef& def = (PrinterDef &) get_description (_curprn);
switch (atoi(mask.get (MSK_1_TYPE)))
{
case 0: // stampante
_printertype = normprinter;
_curcode = atoi (mask.get (MSK_1_CODES));
switch (atoi (def._printertype))
{
case 0:
_printertype = normprinter;
break;
case 1:
_printertype = localprinter;
break;
case 2:
_printertype = spoolprinter;
break;
}
break;
case 1: // file
_printertype = fileprinter;
_printerfile = mask.get (MSK_1_FILENAME);
_curcode = atoi (mask.get (MSK_1_CODES));
break;
case 2: // video
_printertype = screenvis;
_curcode = 0;
break;
}
#else
_get_windows_printer_names(pn2);
char old_default[80];
GetProfileString ("windows", "device", ",,,", old_default, sizeof(old_default));
for (i = 0; i < pn2.items (); i++)
pn1.add(i);
((TList_field &) (mask.field (MSK_1_PRINTERS))).replace_items(pn1, pn2);
mask.set(MSK_1_PRINTERS, pn1.get(_curprn));
mask.hide(MSK_1_CODES);
if (!_multiple_copies) mask.hide(MSK_1_NPAGES);
mask.set(MSK_1_ISGRAPHICS, _isgraphics ? "X" : "");
mask.set(MSK_1_SIZE, _ch_size);
mask.set(MSK_1_LINES, _lines_per_inch);
if (_printertype == fileprinter)
mask.set (MSK_1_TYPE, "1");
else if (_printertype == screenvis)
mask.set (MSK_1_TYPE, "2");
else
mask.set (MSK_1_TYPE, "0");
mask.set_handler (MSK_1_PRINTERS, set_windows_print_device);
KEY k;
int oldprn = _curprn;
while ((k = mask.run ()) != K_ESC && k != K_ENTER && k != K_INS)
{
if (k == DLG_SETPRINT)
{
// l'handler setta default di windows a quella nel listbox e ribecca l'rcd
if (_print_rcd != NULL)
{
if (page_setup_dlg(_print_rcd))
{
// see if user has changed printer
// determine index of currently selected printer
// ACTHUNG! Deep hacking of XVT internals! NON PORTABLE!
if (_print_rcd != NULL)
free_print_rcd (_print_rcd);
_print_rcd = get_print_rcd(&_print_rcd_size);
for (i = 0; i < pn2.items(); i++)
if (strcmp((const char *)(_print_rcd + 4), pn2.get(i)) == 0)
{
_curprn = i;
break;
}
mask.set(MSK_1_PRINTERS, pn1.get(_curprn));
set_win_formlen();
}
mask.set_focus();
}
else
beep ();
}
}
_curprn = atoi(mask.get(MSK_1_PRINTERS));
if (k == K_INS)
{
// tutto resta com'e'
mask.save ();
TConfig cnf (CONFIG_GENERAL, "Stampa");
cnf.set("Size", mask.get(MSK_1_SIZE));
cnf.set("Lines",mask.get(MSK_1_LINES));
}
if (k == K_ESC || k == K_ENTER)
{
// riaggiusta stampante default windows come prima
// curprn e rcd sono quelle di prima
main_app().enable_menu_item(M_FILE_PG_SETUP);
WriteProfileString("windows","device", old_default);
}
if (k == K_ESC)
{
if (_print_rcd != NULL)
free_print_rcd (_print_rcd);
_curprn = oldprn;
_print_rcd = get_print_rcd(&_print_rcd_size);
set_win_formlen();
return;
}
_ncopies = atoi (mask.get (MSK_1_NPAGES));
switch (atoi (mask.get (MSK_1_TYPE)))
{
case 0: // stampante
_printertype = winprinter;
break;
case 1: // file
_printertype = fileprinter;
_printerfile = mask.get (MSK_1_FILENAME);
_curcode = atoi (mask.get (MSK_1_CODES));
break;
case 2: // video
_printertype = screenvis;
_curcode = 0;
break;
}
_isgraphics = mask.get_bool (MSK_1_ISGRAPHICS);
_ch_size = atoi (mask.get (MSK_1_SIZE));
_lines_per_inch = atoi (mask.get (MSK_1_LINES));
set_win_formlen ();
#endif
main_app().enable_menu_item (M_FILE_PG_SETUP);
}
void TPrinter::merge_export_file(const char* file, bool header)
{
TTextfile txt(file);
for (long i = 0; i < txt.lines(); i++)
{
TPrintrow* p = new TPrintrow();
p->put(txt.line_formatted(i));
if (header) printrow(p);
else print(*p);
}
}
void TPrinter::close ()
{
const bool isfirstpage = (_currentpage == 1 && _frompage == 0) ||
(_currentpage <= _frompage);
if (isopen() && (!isfirstpage || _currentrow > _headersize) &&
(_printertype != screenvis && _printertype != winprinter
&& _printertype != export))
formfeed();
if (_fp)
{
fclose (_fp);
_fp = NULL;
}
if (_printertype == screenvis)
{
_vf->close_print();
_vf->run ();
if (_vf->is_open ()) _vf->close_modal ();
delete _vf;
freeze (FALSE);
_vf = NULL;
}
else if (_printertype == export)
{
if (!_exportfile.empty() && _txt.lines() > 0L)
{
ofstream txt((const char*)_exportfile);
for (long i = 0; i < _txt.lines(); i++)
{
txt << _txt.line_formatted(i) << '\n';
}
txt.close();
}
}
#if XVT_OS == XVT_OS_WIN
else if (_printertype == winprinter && _txt.lines() > 0L)
{
PrintWhat._prcd = _print_rcd;
PrintWhat._txt = &_txt;
PrintWhat._graphics = _isgraphics;
PrintWhat._charsize = _ch_size;
start_print_thread (start_winprint, (long) (&PrintWhat));
}
else if (_printertype == fileprinter)
{
FILE* fp = fopen(_printerfile, "w");
if (fp == NULL)
{
error_box("Impossibile aprire il file %s", (const char*)_printerfile);
return;
}
for (long i = 0; i < _txt.lines(); i++)
fprintf(fp,"%s\n", _txt.line(i));
fclose(fp);
}
#endif
else if (_printertype == localprinter)
{
#if XVT_OS == XVT_OS_SCOUNIX
TFilename s1 = tmpnam (NULL);
switch (fork ())
{
case -1:
break;
case 0:
execlp ("localprint", "localprint", (const char *) s1, NULL);
default:
wait ((int *) NULL);
}
remove (s1);
#endif
}
_isopen = FALSE;
}
//
// TFile_printer
//
#include <bagn004.h>
#if XVT_OS == XVT_OS_DOS
#define FORMAT_COMMAND "FORMAT"
#else
#define FORMAT_COMMAND "dosformat -fq"
#endif
const long disk_sizes[] =
{360000, 1200000, 720000, 1400000, 2880000};
TFile_printer ::TFile_printer (const char *ffile, const char *label, int len_rec, int num_rec_inizio, int num_rec_fine, int tipo_disco)
{
set_printtype (fileprinter);
_num_rec_testa_coda = num_rec_inizio + num_rec_fine;
_file = ffile;
_label = label;
_len_rec = len_rec;
_volume = 1;
_size = disk_sizes[tipo_disco];
_num_rec_volume = int ((_size / len_rec) - _num_rec_testa_coda);
_nome_file_fissato = TRUE;
_formatta = FALSE;
_label_fissata = TRUE;
}
void TFile_printer::open()
{
}
void TFile_printer::close ()
{
}
bool TFile_printer::genera_dischetti ()
{
int r;
for (int i = 0; i < _tmp_files.items (); i++)
{
// Avvisa l'utente di inserire un dischetto
r = yesno_box ("Inserire il dischetto n. %2d di %2d nel drive %2s",
i + 1, _volume, _drive);
if (!r)
return error_box ("Procedura interrotta!");
// e eventualmente lo formatta
if (_formatta)
{
TString dep (30);
if (_label != NULL)
dep << FORMAT_COMMAND << " " << "/v:" << _label << " " << _drive;
else
dep << FORMAT_COMMAND << " " << _drive;
TExternal_app sys (dep);
sys.run ();
}
// copia il file sul dischetto
fcopy ((const char *) &_tmp_files[i], (const char *) _drive);
}
return TRUE;
}
TFile_printer::~TFile_printer ()
{
}
void TFile_printer::set ()
{
TMask m ("bagn004");
KEY tasto;
int f;
//
//
// --------------------------------------------------------------------
// Qui bisogna inserire la lista dei drive disponibili nella maschera
// Per ora tale lista e' fissa e contiene solo A: e B:
// --------------------------------------------------------------------
//
//
m.set (F_FILE_DESTINAZIONE, _file);
m.set (F_LABEL, _label);
if (_nome_file_fissato)
m.disable (F_FILE_DESTINAZIONE);
if (_label_fissata)
m.disable (F_LABEL);
tasto = m.run ();
if (tasto == K_ENTER)
{
f = atoi(m.get(F_FORMATO_DISCO));
_drive = m.get(F_DRIVE);
_file = m.get(F_FILE_DESTINAZIONE);
_label = m.get(F_LABEL);
_formatta = (bool)(m.get(F_FORMATTA) == "X");
_size = disk_sizes[f];
_num_rec_volume = int ((_size / _len_rec) - _num_rec_testa_coda);
}
}
//
// TFile printer fine
//