3519953bf6
Files correlati : ba1.exe Ricompilazione Demo : [ ] Commento : AO20116 Da WIN XP/2000: se entro nella gestione degli utenti e faccio "FINE" mi restituisce un errore su ba1.exe git-svn-id: svn://10.65.10.50/trunk@11541 c028cbd2-c16b-5b4b-a496-9718f37d4682
635 lines
12 KiB
C++
Executable File
635 lines
12 KiB
C++
Executable File
#include "wxinc.h"
|
|
#include "wx/print.h"
|
|
#include "wx/printdlg.h"
|
|
|
|
#include "xvt.h"
|
|
#ifdef WIN32
|
|
#include "oswin32.h"
|
|
#else
|
|
#include "oslinux.h"
|
|
#include <fstream.h>
|
|
#endif
|
|
|
|
#include "xvintern.h"
|
|
|
|
#pragma pack(4)
|
|
|
|
struct TPRINT_RCD : public PRINT_RCD
|
|
{
|
|
unsigned char m_data[16*1024];
|
|
unsigned int m_size; // Dimensione della struct DEVMODE
|
|
|
|
void SetData(void* data, unsigned int nSize);
|
|
TPRINT_RCD();
|
|
~TPRINT_RCD();
|
|
};
|
|
|
|
#pragma pack()
|
|
|
|
|
|
void TPRINT_RCD::SetData(void* data, unsigned int nSize)
|
|
{
|
|
if (nSize <= sizeof(m_data))
|
|
{
|
|
memcpy(m_data, data, nSize);
|
|
m_size = nSize;
|
|
}
|
|
}
|
|
|
|
TPRINT_RCD::TPRINT_RCD() : m_size(0)
|
|
{
|
|
pr = NULL;
|
|
memset(m_data, 0, sizeof(m_data));
|
|
}
|
|
|
|
TPRINT_RCD::~TPRINT_RCD()
|
|
{
|
|
memset(m_data, 0, sizeof(m_data));
|
|
m_size = 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TwxPrintOut
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TwxPrintOut : public wxPrintout
|
|
{
|
|
protected:
|
|
TPRINT_RCD* m_prcd;
|
|
bool m_bBadDriver;
|
|
|
|
virtual bool HasPage(int pageNum);
|
|
virtual bool OnPrintPage(int pageNum);
|
|
void ResetDC();
|
|
|
|
public:
|
|
void SetBadDriver(bool bd) { m_bBadDriver = bd; }
|
|
bool HasBadDriver() const { return m_bBadDriver; }
|
|
|
|
void InitDC(TPRINT_RCD* prcd);
|
|
TwxPrintOut(TPRINT_RCD* prcd = NULL);
|
|
virtual ~TwxPrintOut();
|
|
};
|
|
|
|
static TwxPrintOut* m_po = NULL;
|
|
|
|
bool TwxPrintOut::HasPage(int pageNum)
|
|
{ return true; }
|
|
|
|
bool TwxPrintOut::OnPrintPage(int pageNum)
|
|
{ return false; }
|
|
|
|
void TwxPrintOut::ResetDC()
|
|
{
|
|
wxDC* dc = GetDC();
|
|
if (dc != NULL)
|
|
delete dc;
|
|
}
|
|
|
|
void TwxPrintOut::InitDC(TPRINT_RCD* prcd)
|
|
{
|
|
ResetDC();
|
|
wxDC* dc = NULL;
|
|
|
|
m_prcd = prcd;
|
|
|
|
if (m_prcd == NULL)
|
|
{
|
|
wxPrinter printer;
|
|
#ifdef WIN32
|
|
dc = new wxPrinterDC(printer.GetPrintDialogData().GetPrintData());
|
|
#else
|
|
dc = new wxPostScriptDC(printer.GetPrintDialogData().GetPrintData());
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
wxPrintData data;
|
|
#ifdef WIN32
|
|
data.SetNativeData(OsWin32_ConvertToNativePrinterInfo(prcd->m_data, prcd->m_size));
|
|
data.ConvertFromNative();
|
|
dc = new wxPrinterDC(data);
|
|
#else
|
|
dc = new wxPostScriptDC(prcd->m_data);
|
|
#endif
|
|
}
|
|
|
|
wxSize s = dc->GetPPI();
|
|
SetPPIPrinter(s.x, s.y);
|
|
|
|
s = dc->GetSize();
|
|
SetPageSizePixels(s.x, s.y);
|
|
|
|
SetDC(dc);
|
|
}
|
|
|
|
TwxPrintOut::TwxPrintOut(TPRINT_RCD* prcd)
|
|
: wxPrintout(_GetAppTitle()), m_bBadDriver(false)
|
|
{
|
|
InitDC(prcd);
|
|
}
|
|
|
|
TwxPrintOut::~TwxPrintOut()
|
|
{
|
|
ResetDC();
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TwxPrintOutCache
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TwxPrintOutCache
|
|
{
|
|
unsigned long m_signature;
|
|
TwxPrintOut* m_po;
|
|
|
|
protected:
|
|
unsigned long Signature(TPRINT_RCD* prcd) const;
|
|
|
|
public:
|
|
TwxPrintOut* Get(TPRINT_RCD* prcd);
|
|
void Reset();
|
|
|
|
TwxPrintOutCache() : m_signature(0), m_po(NULL) { }
|
|
~TwxPrintOutCache() { Reset(); }
|
|
} m_PrintoutCache;
|
|
|
|
unsigned long TwxPrintOutCache::Signature(TPRINT_RCD* prcd) const
|
|
{
|
|
const unsigned char* data = (const unsigned char*)prcd;
|
|
unsigned long h = 0;
|
|
for (size_t c = 0; c < prcd->m_size; c++)
|
|
{
|
|
h = (h << 2) + data[c];
|
|
const unsigned long i = h & 0xC0000000;
|
|
if (i) h = (h ^ (i >> 12)) & 0x3FFFFFFF;
|
|
}
|
|
return h;
|
|
|
|
}
|
|
|
|
void TwxPrintOutCache::Reset()
|
|
{
|
|
if (m_po != NULL)
|
|
{
|
|
delete m_po;
|
|
m_po = NULL;
|
|
}
|
|
}
|
|
|
|
TwxPrintOut* TwxPrintOutCache::Get(TPRINT_RCD* prcd)
|
|
{
|
|
unsigned long signature = Signature(prcd);
|
|
if (m_po != NULL && m_signature == signature)
|
|
return m_po;
|
|
Reset();
|
|
m_po = new TwxPrintOut(prcd);
|
|
m_signature = signature;
|
|
|
|
return m_po;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TPrintDC
|
|
///////////////////////////////////////////////////////////
|
|
|
|
wxDC& TPrintDC::GetDC(bool)
|
|
{
|
|
_dc = m_po->GetDC(); // Forza display context corrente
|
|
if (_dirty)
|
|
_dirty = -1;
|
|
return TDC::GetDC(false);
|
|
}
|
|
|
|
TPrintDC::TPrintDC(wxWindow* owner) : TDC(owner)
|
|
{ }
|
|
|
|
TPrintDC::~TPrintDC()
|
|
{
|
|
_dc = NULL; // Evita distruzione!
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Printing management :-(((((
|
|
///////////////////////////////////////////////////////////
|
|
|
|
BOOLEAN xvt_app_escape(int esc_code, PRINT_RCD* rcd, long* ph, long* pw, long* pvr, long* phr)
|
|
{
|
|
*ph = *pw = *pvr = *phr = 0;
|
|
switch (esc_code)
|
|
{
|
|
case XVT_ESC_GET_PRINTER_INFO:
|
|
if (rcd == NULL || xvt_print_is_valid(rcd))
|
|
{
|
|
int w, h;
|
|
if (m_po == NULL)
|
|
{
|
|
TwxPrintOut* po = m_PrintoutCache.Get((TPRINT_RCD*)rcd);
|
|
po->GetPPIPrinter(&w, &h);
|
|
*phr = w; *pvr = h;
|
|
po->GetPageSizePixels(&w, &h);
|
|
*pw = w; *ph = h;
|
|
}
|
|
else
|
|
{
|
|
m_po->GetPPIPrinter(&w, &h);
|
|
*phr = w; *pvr = h;
|
|
m_po->GetPageSizePixels(&w, &h);
|
|
*pw = w; *ph = h;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOLEAN xvt_dm_post_page_setup(PRINT_RCD* precp)
|
|
{
|
|
wxPageSetupDialog dlg((wxWindow*)TASK_WIN);
|
|
TPRINT_RCD* rcd = (TPRINT_RCD*)precp;
|
|
|
|
wxPageSetupData& pdd = dlg.GetPageSetupData();
|
|
// pdd.EnablePrinter(false); // Vieta di cambiare stampante
|
|
wxPrintData& data = pdd.GetPrintData();
|
|
|
|
#ifdef WIN32
|
|
data.SetNativeData(OsWin32_ConvertToNativePrinterInfo(rcd->m_data, rcd->m_size));
|
|
data.ConvertFromNative();
|
|
#endif
|
|
|
|
if (dlg.ShowModal() == wxID_OK)
|
|
{
|
|
#ifdef WIN32
|
|
data.ConvertToNative();
|
|
void* pHandle = data.GetNativeData();
|
|
unsigned int nSize = 0;
|
|
void* ptr = OsWin32_ConvertFromNativePrinterInfo(pHandle, nSize);
|
|
rcd->SetData(ptr, nSize);
|
|
delete ptr;
|
|
#else
|
|
rcd->SetData((void *) &data, (unsigned int) sizeof(data));
|
|
#endif
|
|
m_PrintoutCache.Reset();
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
long xvt_fmap_get_family_sizes(PRINT_RCD *precp, char *family, long *size_array, BOOLEAN *scalable, long max_sizes)
|
|
{
|
|
long size = 0;
|
|
*scalable = FALSE;
|
|
|
|
if (precp != NULL)
|
|
{
|
|
#ifdef WIN32
|
|
TwxPrintOut* po = m_PrintoutCache.Get((TPRINT_RCD*)precp);
|
|
if (po->HasBadDriver())
|
|
{
|
|
HDC hdc = ::GetDC(NULL); // Screen DC
|
|
size = OsWin32_EnumerateSizes((unsigned int)hdc, family, size_array, scalable, max_sizes);
|
|
}
|
|
else
|
|
size = OsWin32_EnumerateSizes(po->GetDC()->GetHDC(), family, size_array, scalable, max_sizes);
|
|
#else
|
|
size = OsLinux_EnumerateSizes(family, size_array, scalable, max_sizes);
|
|
#endif
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
long xvt_fmap_get_families(PRINT_RCD *precp, char **family_array, long max_families)
|
|
{
|
|
long size = 0;
|
|
family_array[0] = NULL;
|
|
|
|
if (precp != NULL)
|
|
{
|
|
#ifdef WIN32
|
|
TwxPrintOut* po = m_PrintoutCache.Get((TPRINT_RCD*)precp);
|
|
size = OsWin32_EnumerateFamilies(po->GetDC()->GetHDC(), family_array, max_families);
|
|
if (size == 0)
|
|
{
|
|
po->SetBadDriver(true);
|
|
HDC hdc = ::GetDC(NULL); // Screen DC
|
|
size = OsWin32_EnumerateFamilies((unsigned int)hdc, family_array, max_families);
|
|
}
|
|
#else
|
|
size = OsLinux_EnumerateFamilies(family_array, max_families);
|
|
#endif
|
|
}
|
|
return size;
|
|
}
|
|
|
|
|
|
void xvt_print_close(void)
|
|
{
|
|
// Nothing to do ?
|
|
}
|
|
|
|
BOOLEAN xvt_print_close_page(PRINT_RCD* /*precp*/)
|
|
{
|
|
BOOLEAN ok = m_po != NULL;
|
|
if (ok)
|
|
m_po->GetDC()->EndPage();
|
|
return ok;
|
|
}
|
|
|
|
PRINT_RCD* xvt_print_create(int *sizep)
|
|
{
|
|
TPRINT_RCD* pr = NULL;
|
|
*sizep = 0;
|
|
|
|
#ifdef WIN32
|
|
void* data = OsWin32_GetPrinterInfo(*sizep, NULL);
|
|
if (data != NULL)
|
|
{
|
|
pr = new TPRINT_RCD;
|
|
pr->SetData(data, *sizep);
|
|
*sizep += 4; // Spazio per puntatore iniziale
|
|
delete data;
|
|
}
|
|
#else
|
|
wxPrinter printer;
|
|
wxPrintData &data = printer.GetPrintDialogData().GetPrintData();
|
|
|
|
data.SetPrinterName(""); //verificare
|
|
pr = new TPRINT_RCD;
|
|
pr->SetData((void *) &data, (unsigned int) sizeof(data));
|
|
#endif
|
|
|
|
return pr;
|
|
}
|
|
|
|
// Nuova funzione inventata da Aga
|
|
PRINT_RCD* xvt_print_create_by_name(int* sizep, const char* name)
|
|
{
|
|
TPRINT_RCD* pr = NULL;
|
|
*sizep = 0;
|
|
|
|
#ifdef WIN32
|
|
void* data = OsWin32_GetPrinterInfo(*sizep, name);
|
|
if (data != NULL)
|
|
{
|
|
pr = new TPRINT_RCD;
|
|
pr->SetData(data, *sizep);
|
|
*sizep += 4; // Spazio per puntatore iniziale
|
|
delete data;
|
|
}
|
|
#else
|
|
wxPrinter printer;
|
|
wxPrintData &data = printer.GetPrintDialogData().GetPrintData();
|
|
wxString PrinterName(name);
|
|
|
|
data.SetPrinterName(PrinterName); //verificare
|
|
pr = new TPRINT_RCD;
|
|
pr->SetData((void *) &data, (unsigned int) sizeof(data));
|
|
#endif
|
|
|
|
return pr;
|
|
}
|
|
|
|
|
|
WINDOW xvt_print_create_win(PRINT_RCD* precp, char* /* title */)
|
|
{
|
|
WINDOW win = NULL_WIN;
|
|
if (m_po != NULL)
|
|
{
|
|
m_po->InitDC((TPRINT_RCD*)precp);
|
|
m_po->OnBeginPrinting();
|
|
m_po->OnBeginDocument(1, 32000);
|
|
win = _print_win;
|
|
}
|
|
return win;
|
|
}
|
|
|
|
void xvt_print_destroy(PRINT_RCD* precp)
|
|
{
|
|
delete precp;
|
|
}
|
|
|
|
RCT* xvt_print_get_next_band(void)
|
|
{
|
|
static bool yes = false;
|
|
static RCT rct;
|
|
yes = !yes;
|
|
|
|
if (m_po == NULL || !yes)
|
|
return NULL;
|
|
|
|
int w, h;
|
|
m_po->GetPageSizePixels(&w, &h);
|
|
rct.left = rct.top = 0;
|
|
rct.right = w;
|
|
rct.bottom = h;
|
|
|
|
return &rct;
|
|
}
|
|
|
|
BOOLEAN xvt_print_is_valid(PRINT_RCD* precp)
|
|
{
|
|
BOOLEAN ok = precp != NULL && precp->pr == NULL;
|
|
if (ok)
|
|
{
|
|
#ifdef WIN32
|
|
TPRINT_RCD* rcd = (TPRINT_RCD*)precp;
|
|
ok = OsWin32_CheckPrinterInfo(rcd->m_data, rcd->m_size);
|
|
#else
|
|
// verificare (c'e' da fare qualcosa ?)
|
|
#endif
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
BOOLEAN xvt_print_open(void)
|
|
{
|
|
return m_po == NULL;
|
|
}
|
|
|
|
BOOLEAN xvt_print_start_thread(BOOLEAN(*print_fcn)(long), long data)
|
|
{
|
|
m_po = new TwxPrintOut;
|
|
|
|
print_fcn(data);
|
|
|
|
m_po->OnEndDocument();
|
|
m_po->OnEndPrinting();
|
|
|
|
delete m_po; m_po = NULL;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN xvt_print_open_page(PRINT_RCD* precp)
|
|
{
|
|
BOOLEAN ok = m_po != NULL;
|
|
if (ok)
|
|
{
|
|
m_po->GetDC()->StartPage();
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Added by XVAGA
|
|
///////////////////////////////////////////////////////////
|
|
|
|
#ifdef LINUX
|
|
static bool is_cups()
|
|
{
|
|
static int printer_system = -1;
|
|
|
|
if (printer_system < 0)
|
|
printer_system = xvt_fsys_file_exists("/etc/cups/printer.conf") ? 1 : 2;
|
|
return (printer_system == 1);
|
|
}
|
|
#endif
|
|
|
|
SLIST xvt_print_list_devices()
|
|
{
|
|
SLIST list = xvt_slist_create();
|
|
#ifdef WIN32
|
|
char buf[4096]; memset(buf, 0, sizeof(buf));
|
|
GetProfileString("devices", NULL, "", buf, sizeof(buf));
|
|
int start = 0;
|
|
for (int i = 0; i < sizeof(buf); i++) if (buf[i] == '\0')
|
|
{
|
|
const char* pname = buf+start;
|
|
if (*pname == '\0')
|
|
break;
|
|
xvt_slist_add_at_elt(list, NULL, pname, NULL);
|
|
start = i+1;
|
|
}
|
|
#else
|
|
if (is_cups())
|
|
{
|
|
ifstream p("/etc/cups/printer.conf"); // vedere
|
|
char line[4096];
|
|
|
|
while (p.getline(line, sizeof(line)))
|
|
{
|
|
if (line[0] == '<')
|
|
{
|
|
char * s = strstr(line, "Printer") ;
|
|
|
|
if (s != NULL)
|
|
{
|
|
s += 7;
|
|
|
|
while (isspace(*s))
|
|
s++;
|
|
|
|
if (*s)
|
|
{
|
|
char * l = s + strlen(s) - 1;
|
|
|
|
while (isspace(*l))
|
|
l--;
|
|
*(l + 1) = '\0';
|
|
xvt_slist_add_at_elt(list, NULL, s, 0L);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ifstream p("/etc/printcap"); // vedere
|
|
char line[4096];
|
|
|
|
while (p.getline(line, sizeof(line)))
|
|
{
|
|
if (line[0] != '#')
|
|
{
|
|
const int len = strlen(line);
|
|
int i;
|
|
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
const char c = line[i];
|
|
|
|
if (!(isalpha(c) || isdigit(c) || isblank(c)))
|
|
break;
|
|
}
|
|
line[i] = '\0';
|
|
xvt_slist_add_at_elt(list, NULL, line, 0L);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#endif
|
|
return list;
|
|
}
|
|
|
|
BOOLEAN xvt_print_set_default_device(const char* name)
|
|
{
|
|
BOOLEAN ok = name && *name > ' ';
|
|
#ifdef WIN32
|
|
if (ok)
|
|
{
|
|
wxString pdev(name);
|
|
if (pdev.Find(',') < 0)
|
|
{
|
|
char szDevice[256];
|
|
::GetProfileString ("devices", pdev, "", szDevice, sizeof(szDevice));
|
|
pdev << ',' << szDevice;
|
|
}
|
|
ok = ::WriteProfileString("windows", "device", pdev) != 0;
|
|
}
|
|
#else
|
|
SORRY_BOX(); //verificare
|
|
#endif
|
|
return ok;
|
|
}
|
|
|
|
BOOLEAN xvt_print_get_default_device(char* name, int namesize)
|
|
{
|
|
bool ok = FALSE;
|
|
#ifdef WIN32
|
|
ok = ::GetProfileString ("windows", "device", ",,,", name, namesize) != 0;
|
|
#else
|
|
*name = '\0';
|
|
if (is_cups())
|
|
{
|
|
ifstream p("/etc/cups/printer.conf"); // vedere
|
|
char line[4096];
|
|
|
|
while (p.getline(line, sizeof(line)))
|
|
{
|
|
if (line[0] == '<')
|
|
{
|
|
char * s = strstr(line, "ltPrinter") ;
|
|
|
|
if (s != NULL)
|
|
{
|
|
s += 9;
|
|
|
|
while (isspace(*s))
|
|
s++;
|
|
|
|
if (*s)
|
|
{
|
|
char * l = s + strlen(s) - 1;
|
|
|
|
while (isspace(*l))
|
|
l--;
|
|
*(l + 1) = '\0';
|
|
strcpy(name, s);
|
|
}
|
|
ok = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return ok;
|
|
}
|
|
|