diff --git a/include/printer.cpp b/include/printer.cpp index fae5cdbd0..819e94ab5 100755 --- a/include/printer.cpp +++ b/include/printer.cpp @@ -1,1516 +1,1516 @@ -#include -#include - -#if XVT_OS==XVT_OS_SCOUNIX -#include -#include -#include -#else -#include -#endif - -#define STYLE_NUM 4 - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -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 - -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); - _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 () -{ - 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 (); -} - -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 () -{ - // returns the row with @-codes for font style and color - char last_attr = -1; - int last_color = -1; - int k = 0; - _row.rtrim (); - for (int i = 0; i < _row.len (); 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) - { - __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]; - } - // k = k > 255 ? 255 : k; - __tmp_string[k] = '\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 = MainApp()->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) - { - if (MainApp()->printer().get_printrcd() != NULL) - free_print_rcd (MainApp ()->printer().get_printrcd ()); - TToken_string & pn = MainApp()->printer().getprinternames (); - TString pdev (pn.get (atoi (f.get ()))); - GetProfileString ("devices", pdev, "", szDevice, sizeof (szDevice)); - pdev << "," << szDevice; - // WriteProfileString("windows","device", pdev); - // madonna bona - MainApp()->printer().set_printrcd(get_print_rcd (&(MainApp ()->printer ().get_printrcdsize ()))); - MainApp()->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 = MainApp()->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; - } - } - -#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); - - TString 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 ? - rowtoprint->row_codified () : - rowtoprint->row ())); - rw.rtrim (); - - int lun = rw.len (); - int idx; - - 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) - { - // add line to txt - if (!_frozen) - _txt.append (rw); - return TRUE; - } - - 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); - - 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 (_currentrow > _formlen - _footersize) - ok = printfooter (); - - // if (ok && _currentrow <= _headersize) - 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 () -{ - // qui -#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) - { - // prepare text object for new text - _txt.destroy (); - } - 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); - } - } - - _currentrow = 1; - _currentpage = 1; - - return _isopen = TRUE; -} - -void TPrinter::set() -{ - TMask mask ("bagn001a"); - TToken_string pn1 (50), pn2 (100); - int i; - - MainApp()->disable_menu_item (M_FILE_PG_SETUP); - -#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_SETUP); - mask.hide(MSK_1_SIZE); - mask.hide(MSK_1_LINES); - 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)); - mask.set (MSK_1_FILENAME, _printerfile); - mask.set(MSK_1_NPAGES, _ncopies); - - mask.reset (MSK_1_SAVE); - - if (mask.run () == K_ESC) - return; - - if (mask.get (MSK_1_SAVE).not_empty ()) - { - TString s ("printer.def"); -#if XVT_OS == XVT_OS_SCOUNIX - s << format (".%d", getuid ()); -#endif - mask.set_workfile (s); - 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); - - 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); - - mask.set(MSK_1_NPAGES, _ncopies); - - 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); - mask.reset (MSK_1_SAVE); - - KEY k; - int oldprn = _curprn; - - while ((k = mask.run ()) != K_ESC && k != K_ENTER) - { - if (k == MSK_1_SETUP) - { - 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! - 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 (); - } - } - if (k == K_ESC) - { - // rimetti come prima - // WriteProfileString("windows","device", pdev); - if (_print_rcd != NULL) - free_print_rcd (_print_rcd); - _curprn = oldprn; - _print_rcd = get_print_rcd(&_print_rcd_size); - set_win_formlen (); - MainApp()->enable_menu_item(M_FILE_PG_SETUP); - return; - } - - _curprn = atoi(mask.get(MSK_1_PRINTERS)); - - if (mask.get (MSK_1_SAVE).not_empty ()) - { - TString s ("printer.def"); - mask.set_workfile (s); - mask.save (); - } - - _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 - - MainApp ()->enable_menu_item (M_FILE_PG_SETUP); -} - -void TPrinter::close () -{ - if (isopen () && _currentrow > 1 && - (_footersize || (_printertype != screenvis && _printertype != winprinter))) - formfeed (); - - if (_fp) - { - fclose (_fp); - _fp = NULL; - } - - if (_printertype == screenvis) - { - CHECK (_vf, "VF!"); - _vf->close_print (); - _vf->run (); - if (_vf->is_open ()) - _vf->close_modal (); - delete _vf; - freeze (FALSE); - _vf = NULL; - } -#if XVT_OS == XVT_OS_WIN -else if (_printertype == winprinter) -{ - PrintWhat._prcd = _print_rcd; - PrintWhat._txt = &_txt; - PrintWhat._graphics = _isgraphics; - PrintWhat._charsize = _ch_size; - start_print_thread (start_winprint, (long) (&PrintWhat)); -} -#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 - -#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; - - warning_box ("Questa procedura richiede %2d dischetti", - _volume); - - 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 -// +#include +#include + +#if XVT_OS==XVT_OS_SCOUNIX +#include +#include +#include +#else +#include +#endif + +#define STYLE_NUM 4 + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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 + +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); + _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 () +{ + 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 (); +} + +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 () +{ + // returns the row with @-codes for font style and color + char last_attr = -1; + int last_color = -1; + int k = 0; + _row.rtrim (); + for (int i = 0; i < _row.len (); 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) + { + __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]; + } + // k = k > 255 ? 255 : k; + __tmp_string[k] = '\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 = MainApp()->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) + { + if (MainApp()->printer().get_printrcd() != NULL) + free_print_rcd (MainApp ()->printer().get_printrcd ()); + TToken_string & pn = MainApp()->printer().getprinternames (); + TString pdev (pn.get (atoi (f.get ()))); + GetProfileString ("devices", pdev, "", szDevice, sizeof (szDevice)); + pdev << "," << szDevice; + // WriteProfileString("windows","device", pdev); + // madonna bona + MainApp()->printer().set_printrcd(get_print_rcd (&(MainApp ()->printer ().get_printrcdsize ()))); + MainApp()->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 = MainApp()->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; + } + } + +#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); + + TString 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 ? + rowtoprint->row_codified () : + rowtoprint->row ())); + rw.rtrim (); + + int lun = rw.len (); + int idx; + + 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) + { + // add line to txt + if (!_frozen) + _txt.append (rw); + return TRUE; + } + + 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); + + 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 (_currentrow > _formlen - _footersize) + ok = printfooter (); + + // if (ok && _currentrow <= _headersize) + 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 () +{ + // qui +#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) + { + // prepare text object for new text + _txt.destroy (); + } + 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); + } + } + + _currentrow = 1; + _currentpage = 1; + + return _isopen = TRUE; +} + +void TPrinter::set() +{ + TMask mask ("bagn001a"); + TToken_string pn1 (50), pn2 (100); + int i; + + MainApp()->disable_menu_item (M_FILE_PG_SETUP); + +#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_SETUP); + mask.hide(MSK_1_SIZE); + mask.hide(MSK_1_LINES); + 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)); + mask.set (MSK_1_FILENAME, _printerfile); + mask.set(MSK_1_NPAGES, _ncopies); + + mask.reset (MSK_1_SAVE); + + if (mask.run () == K_ESC) + return; + + if (mask.get (MSK_1_SAVE).not_empty ()) + { + TString s ("printer.def"); +#if XVT_OS == XVT_OS_SCOUNIX + s << format (".%d", getuid ()); +#endif + mask.set_workfile (s); + 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); + + 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); + + mask.set(MSK_1_NPAGES, _ncopies); + + 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); + mask.reset (MSK_1_SAVE); + + KEY k; + int oldprn = _curprn; + + while ((k = mask.run ()) != K_ESC && k != K_ENTER) + { + if (k == MSK_1_SETUP) + { + 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! + 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 (); + } + } + if (k == K_ESC) + { + // rimetti come prima + // WriteProfileString("windows","device", pdev); + if (_print_rcd != NULL) + free_print_rcd (_print_rcd); + _curprn = oldprn; + _print_rcd = get_print_rcd(&_print_rcd_size); + set_win_formlen (); + MainApp()->enable_menu_item(M_FILE_PG_SETUP); + return; + } + + _curprn = atoi(mask.get(MSK_1_PRINTERS)); + + if (mask.get (MSK_1_SAVE).not_empty ()) + { + TString s ("printer.def"); + mask.set_workfile (s); + mask.save (); + } + + _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 + + MainApp ()->enable_menu_item (M_FILE_PG_SETUP); +} + +void TPrinter::close () +{ + if (isopen () && _currentrow > 1 && + (_footersize || (_printertype != screenvis && _printertype != winprinter))) + formfeed (); + + if (_fp) + { + fclose (_fp); + _fp = NULL; + } + + if (_printertype == screenvis) + { + CHECK (_vf, "VF!"); + _vf->close_print (); + _vf->run (); + if (_vf->is_open ()) + _vf->close_modal (); + delete _vf; + freeze (FALSE); + _vf = NULL; + } +#if XVT_OS == XVT_OS_WIN +else if (_printertype == winprinter) +{ + PrintWhat._prcd = _print_rcd; + PrintWhat._txt = &_txt; + PrintWhat._graphics = _isgraphics; + PrintWhat._charsize = _ch_size; + start_print_thread (start_winprint, (long) (&PrintWhat)); +} +#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 + +#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; + + warning_box ("Questa procedura richiede %2d dischetti", + _volume); + + 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 +//