#include "wxinc.h" #include "wx/print.h" #include "wx/printdlg.h" #include "xvt.h" #include "oswin32.h" #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: virtual bool HasPage(int pageNum); virtual bool OnPrintPage(int pageNum); TPRINT_RCD* m_prcd; public: 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::InitDC(TPRINT_RCD* prcd) { wxDC* dc = GetDC(); if (dc != NULL) delete dc; m_prcd = prcd; if (m_prcd == NULL) { wxPrinter printer; dc = new wxPrinterDC(printer.GetPrintDialogData().GetPrintData()); } else { wxPrintData data; #ifdef WIN32 data.SetNativeData(OsWin32_ConvertToNativePrinterInfo(prcd->m_data, prcd->m_size)); #else data.SetNativeData(prcd->m_data); #endif data.ConvertFromNative(); dc = new wxPrinterDC(data); } wxSize s = dc->GetPPI(); SetPPIPrinter(s.x, s.y); s = dc->GetSize(); SetPageSizePixels(s.x, s.y); SetDC(dc); } TwxPrintOut::TwxPrintOut(TPRINT_RCD* prcd) { InitDC(prcd); } TwxPrintOut::~TwxPrintOut() { wxDC* dc = GetDC(); if (dc != NULL) delete dc; } /////////////////////////////////////////////////////////// // 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)) { const bool temp = m_po == NULL; if (temp) m_po = new TwxPrintOut((TPRINT_RCD*)rcd); int w, h; m_po->GetPPIPrinter(&w, &h); *phr = w; *pvr = h; m_po->GetPageSizePixels(&w, &h); *pw = w; *ph = h; if (temp) { delete m_po; m_po = NULL; } 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)); #else data.SetNativeData(rcd->m_data); #endif data.ConvertFromNative(); if (dlg.ShowModal() == wxID_OK) { data.ConvertToNative(); void* pHandle = data.GetNativeData(); #ifdef WIN32 unsigned int nSize = 0; void* ptr = OsWin32_ConvertFromNativePrinterInfo(pHandle, nSize); rcd->SetData(ptr, nSize); delete ptr; #else rcd->SetData(pHandle, 1024); #endif 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 = 1; size_array[0] = 13; *scalable = FALSE; #ifdef WIN32 if (precp != NULL) { TwxPrintOut* po = new TwxPrintOut((TPRINT_RCD*)precp); size = OsWin32_EnumerateSizes(po->GetDC()->GetHDC(), 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 = 1; family_array[0] = xvt_str_duplicate(XVT_FFN_COURIER); #ifdef WIN32 if (precp != NULL) { TwxPrintOut* po = new TwxPrintOut((TPRINT_RCD*)precp); size = OsWin32_EnumerateFamilies(po->GetDC()->GetHDC(), 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; } #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; } #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) { // Nothing to do! } 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); #endif } return ok; } BOOLEAN xvt_print_open(void) { return m_po == NULL; } BOOLEAN xvt_print_start_thread(BOOLEAN(*print_fcn)(long), long data) { wxWindow* tw = (wxWindow*)TASK_WIN; 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 /////////////////////////////////////////////////////////// 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 xvt_slist_add_at_elt(list, NULL, "/dev/prn", NULL); // TBI #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; } #endif return ok; } BOOLEAN xvt_print_get_default_device(char* name, int namesize) { bool ok = TRUE; #ifdef WIN32 ok = ::GetProfileString ("windows", "device", ",,,", name, namesize) != 0; #else strcpy(name, "/dev/prn"); #endif return ok; }