Rev 4504 | Rev 5753 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4485 | cbradney | 1 | /* |
2 | For general Scribus (>=1.3.2) copyright and licensing information please refer |
||
3 | to the COPYING file provided with the program. Following this notice may exist |
||
4 | a copyright and/or license notice that predates the release of Scribus 1.3.2 |
||
5 | for which a new license (GPL+exception) is in place. |
||
6 | */ |
||
7 | #include "printerutil.h" |
||
4504 | cbradney | 8 | #include "scconfig.h" |
4485 | cbradney | 9 | |
10 | #if defined( HAVE_CUPS ) |
||
11 | #include <cups/cups.h> |
||
12 | #elif defined(_WIN32) |
||
13 | #include <windows.h> |
||
14 | #include <winspool.h> |
||
15 | #endif |
||
16 | |||
17 | #include <qstringlist.h> |
||
18 | #include "util.h" |
||
4506 | cbradney | 19 | #include "scribus.h" |
4485 | cbradney | 20 | |
21 | QStringList PrinterUtil::getPrinterNames() |
||
22 | { |
||
23 | QString printerName; |
||
24 | QStringList printerNames; |
||
25 | #if defined (HAVE_CUPS) |
||
26 | cups_dest_t *dests; |
||
27 | int num_dests = cupsGetDests(&dests); |
||
28 | for (int pr = 0; pr < num_dests; ++pr) |
||
29 | { |
||
30 | printerName = QString(dests[pr].name); |
||
31 | printerNames.append(printerName); |
||
32 | } |
||
33 | cupsFreeDests(num_dests, dests); |
||
34 | #elif defined(_WIN32) |
||
35 | DWORD size; |
||
36 | DWORD numPrinters; |
||
37 | PRINTER_INFO_2* printerInfos = NULL; |
||
38 | EnumPrinters ( PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS , NULL, 2, NULL, 0, &size, &numPrinters ); |
||
39 | printerInfos = (PRINTER_INFO_2*) malloc(size); |
||
40 | if ( EnumPrinters ( PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, (LPBYTE) printerInfos, size, &size, &numPrinters ) ) |
||
41 | { |
||
42 | for ( uint i = 0; i < numPrinters; i++) |
||
43 | { |
||
44 | printerName = printerInfos[i].pPrinterName; |
||
45 | printerNames.append(printerName); |
||
46 | } |
||
47 | printerNames.sort(); |
||
48 | } |
||
49 | if ( printerInfos) free(printerInfos); |
||
50 | #else |
||
51 | QString tmp; |
||
52 | QString Pcap; |
||
53 | QStringList wt; |
||
54 | if (loadText("/etc/printcap", &Pcap)) |
||
55 | { |
||
56 | QTextStream ts(&Pcap, IO_ReadOnly); |
||
57 | while(!ts.atEnd()) |
||
58 | { |
||
59 | tmp = ts.readLine(); |
||
60 | if (tmp.isEmpty()) |
||
61 | continue; |
||
62 | if ((tmp[0] != '#') && (tmp[0] != ' ') && (tmp[0] != '\n') && (tmp[0] != '\t')) |
||
63 | { |
||
64 | tmp = tmp.stripWhiteSpace(); |
||
65 | tmp = tmp.left(tmp.length() - (tmp.right(2) == ":\\" ? 2 : 1)); |
||
66 | wt = QStringList::split("|", tmp); |
||
67 | printerName = wt[0]; |
||
68 | printerNames.append(printerName); |
||
69 | } |
||
70 | } |
||
71 | } |
||
72 | #endif |
||
73 | return printerNames; |
||
74 | } |
||
4504 | cbradney | 75 | |
4506 | cbradney | 76 | #if defined(_WIN32) |
77 | bool PrinterUtil::getDefaultSettings( QString printerName, QByteArray& devModeA ) |
||
4504 | cbradney | 78 | { |
79 | bool done; |
||
80 | uint size; |
||
81 | QCString printer; |
||
82 | LONG result = IDOK+1; |
||
83 | HANDLE handle = NULL; |
||
84 | printer = printerName.local8Bit(); |
||
85 | // Get the printer handle |
||
86 | done = OpenPrinter( printer.data(), &handle, NULL ); |
||
87 | if(!done) |
||
88 | return false; |
||
89 | // Get size of DEVMODE structure (public + private data) |
||
4506 | cbradney | 90 | size = DocumentProperties( ScMW->winId(), handle, printer.data(), NULL, NULL, 0); |
4504 | cbradney | 91 | // Allocate the memory needed by the DEVMODE structure |
4506 | cbradney | 92 | devModeA.resize( size ); |
4504 | cbradney | 93 | // Retrieve printer default settings |
4506 | cbradney | 94 | result = DocumentProperties( ScMW->winId(), handle, printer.data(), (DEVMODE*) devModeA.data(), NULL, DM_OUT_BUFFER); |
4504 | cbradney | 95 | // Free the printer handle |
96 | ClosePrinter( handle ); |
||
97 | return ( result == IDOK ); |
||
4506 | cbradney | 98 | } |
4504 | cbradney | 99 | #endif |
100 | |||
4506 | cbradney | 101 | #if defined(_WIN32) |
102 | bool PrinterUtil::initDeviceSettings( QString printerName, QByteArray& devModeA ) |
||
4504 | cbradney | 103 | { |
104 | bool done; |
||
105 | uint size; |
||
106 | QCString printer; |
||
107 | LONG result = IDOK+1; |
||
108 | HANDLE handle = NULL; |
||
109 | printer = printerName.local8Bit(); |
||
110 | // Get the printer handle |
||
111 | done = OpenPrinter( printer.data(), &handle, NULL ); |
||
112 | if(!done) |
||
113 | return false; |
||
114 | // Get size of DEVMODE structure (public + private data) |
||
4506 | cbradney | 115 | size = DocumentProperties( ScMW->winId(), handle, printer.data(), NULL, NULL, 0); |
4504 | cbradney | 116 | // Compare size with DevMode structure size |
4506 | cbradney | 117 | if( devModeA.size() == size ) |
4504 | cbradney | 118 | { |
119 | // Merge printer settings |
||
4506 | cbradney | 120 | result = DocumentProperties( ScMW->winId(), handle, printer.data(), (DEVMODE*) devModeA.data(), (DEVMODE*) devModeA.data(), DM_IN_BUFFER | DM_OUT_BUFFER); |
4504 | cbradney | 121 | } |
122 | else |
||
123 | { |
||
124 | // Retrieve default settings |
||
4506 | cbradney | 125 | devModeA.resize( size ); |
126 | result = DocumentProperties( ScMW->winId(), handle, printer.data(), (DEVMODE*) devModeA.data(), NULL, DM_OUT_BUFFER); |
||
4504 | cbradney | 127 | } |
128 | done = ( result == IDOK); |
||
129 | // Free the printer handle |
||
130 | ClosePrinter( handle ); |
||
131 | return done; |
||
4506 | cbradney | 132 | } |
4504 | cbradney | 133 | #endif |
134 | |||
135 | bool PrinterUtil::getPrinterMarginValues(const QString& printerName, const QString& pageSize, double& ptsTopMargin, double& ptsBottomMargin, double& ptsLeftMargin, double& ptsRightMargin) |
||
136 | { |
||
137 | bool retVal=false; |
||
4506 | cbradney | 138 | #if defined(HAVE_CUPS) |
4504 | cbradney | 139 | const char *filename; // tmp PPD filename |
140 | filename=cupsGetPPD(printerName); |
||
141 | if (filename!=NULL) |
||
142 | { |
||
143 | ppd_file_t *ppd; // PPD data |
||
144 | ppd = ppdOpenFile(filename); |
||
145 | if (ppd!=NULL) |
||
146 | { |
||
147 | ppd_size_t *size; // page size data, null if printer doesnt support selected size |
||
148 | size = ppdPageSize(ppd, pageSize); |
||
149 | if (size!=NULL) |
||
150 | { |
||
151 | //Store in pts for returning via getNewPrinterMargins in pts |
||
152 | retVal=true; |
||
153 | ptsTopMargin=size->length-size->top; |
||
154 | ptsBottomMargin=size->bottom; |
||
155 | ptsLeftMargin=size->left; |
||
156 | ptsRightMargin=size->width-size->right; |
||
157 | } |
||
158 | ppdClose(ppd); |
||
159 | } |
||
160 | } |
||
4506 | cbradney | 161 | #elif defined(_WIN32) |
162 | DWORD nPaper; |
||
163 | DWORD nPaperNames; |
||
164 | QCString printer; |
||
165 | typedef char char64[64]; |
||
166 | printer = printerName.local8Bit(); |
||
167 | nPaper = DeviceCapabilities( printerName.data(), NULL, DC_PAPERS, NULL, NULL ); |
||
168 | nPaperNames = DeviceCapabilities( printerName.data(), NULL, DC_PAPERNAMES, NULL, NULL ); |
||
169 | if ( (nPaper > 0) && (nPaperNames > 0) && (nPaper == nPaperNames) ) |
||
170 | { |
||
171 | int paperIndex = -1; |
||
172 | DWORD *papers = new DWORD[nPaper]; |
||
173 | char64 *paperNames = new char64[nPaperNames]; |
||
174 | DWORD s1 = DeviceCapabilities( printerName.data(), NULL, DC_PAPERS, (LPSTR) papers, NULL ); |
||
175 | DWORD s2 = DeviceCapabilities( printerName.data(), NULL, DC_PAPERNAMES, (LPSTR) paperNames, NULL ); |
||
176 | for ( int i = 0; i < nPaperNames; i++ ) |
||
177 | { |
||
178 | if ( pageSize == QString(paperNames[i]) ) |
||
179 | { |
||
180 | paperIndex = i; |
||
181 | break; |
||
182 | } |
||
183 | } |
||
184 | if ( paperIndex >= 0 ) |
||
185 | { |
||
186 | HANDLE handle = NULL; |
||
187 | if( OpenPrinter( printer.data(), &handle, NULL ) ) |
||
188 | { |
||
189 | // Retrieve DEVMODE structure for selected device |
||
190 | uint size = DocumentProperties( ScMW->winId(), handle, printer.data(), NULL, NULL, 0); |
||
191 | QByteArray devModeA(size); |
||
192 | DEVMODE* devMode = (DEVMODE*) devModeA.data(); |
||
193 | DocumentProperties( ScMW->winId(), handle, printer.data(), devMode, NULL, DM_OUT_BUFFER); |
||
194 | ClosePrinter( handle ); |
||
195 | // Set paper size |
||
196 | devMode->dmPaperSize = papers[paperIndex]; |
||
197 | // Create device context |
||
198 | HDC printerDC = CreateDC( NULL, printer.data(), NULL, devMode ); |
||
199 | if( printerDC ) |
||
200 | { |
||
201 | retVal = true; |
||
202 | int logPixelsX = GetDeviceCaps( printerDC, LOGPIXELSX ); |
||
203 | int logPixelsY = GetDeviceCaps( printerDC, LOGPIXELSY ); |
||
204 | int physicalOffsetX = GetDeviceCaps( printerDC, PHYSICALOFFSETX ); |
||
205 | int physicalOffsetY = GetDeviceCaps( printerDC, PHYSICALOFFSETY ); |
||
206 | ptsLeftMargin = ptsRightMargin = ( physicalOffsetX / (double) logPixelsX * 72 ); |
||
207 | ptsTopMargin = ptsBottomMargin = ( physicalOffsetY / (double) logPixelsY * 72 ); |
||
208 | DeleteDC(printerDC); |
||
209 | } |
||
210 | } |
||
211 | } |
||
212 | delete[] papers; |
||
213 | delete[] paperNames; |
||
214 | } |
||
215 | #endif |
||
4504 | cbradney | 216 | return retVal; |
217 | } |
||
218 | |||
219 | //Parameter needed on win32.. |
||
220 | bool PrinterUtil::isPostscriptPrinter( QString printerName) |
||
221 | { |
||
222 | #ifdef _WIN32 |
||
223 | HDC dc; |
||
224 | int escapeCode; |
||
225 | char technology[MAX_PATH] = {0}; |
||
226 | QCString printer = printerName.local8Bit(); |
||
227 | |||
228 | // Create the default device context |
||
229 | dc = CreateDC( NULL, printer.data(), NULL, NULL ); |
||
230 | if ( !dc ) |
||
231 | { |
||
232 | qWarning( QString("isPostscriptPrinter() failed to create device context for %1").arg(printerName) ); |
||
233 | return false; |
||
234 | } |
||
235 | // test if printer support the POSTSCRIPT_PASSTHROUGH escape code |
||
236 | escapeCode = POSTSCRIPT_PASSTHROUGH; |
||
237 | if ( ExtEscape( dc, QUERYESCSUPPORT, sizeof(int), (LPCSTR)&escapeCode, 0, NULL ) > 0 ) |
||
238 | { |
||
239 | DeleteDC( dc ); |
||
240 | return true; |
||
241 | } |
||
242 | // test if printer support the POSTSCRIPT_DATA escape code |
||
243 | escapeCode = POSTSCRIPT_DATA; |
||
244 | if ( ExtEscape( dc, QUERYESCSUPPORT, sizeof(int), (LPCSTR)&escapeCode, 0, NULL ) > 0 ) |
||
245 | { |
||
246 | DeleteDC( dc ); |
||
247 | return true; |
||
248 | } |
||
249 | // try to get postscript support by testing the printer technology |
||
250 | escapeCode = GETTECHNOLOGY; |
||
251 | if ( ExtEscape( dc, QUERYESCSUPPORT, sizeof(int), (LPCSTR)&escapeCode, 0, NULL ) > 0 ) |
||
252 | { |
||
253 | // if GETTECHNOLOGY is supported, then ... get technology |
||
254 | if ( ExtEscape( dc, GETTECHNOLOGY, 0, NULL, MAX_PATH, (LPSTR) technology ) > 0 ) |
||
255 | { |
||
256 | // check technology string for postscript word |
||
257 | strupr( technology ); |
||
258 | if ( strstr( technology, "POSTSCRIPT" ) ) |
||
259 | { |
||
260 | DeleteDC( dc ); |
||
261 | return true; |
||
262 | } |
||
263 | } |
||
264 | } |
||
265 | DeleteDC( dc ); |
||
266 | return false; |
||
267 | #else |
||
268 | return true; |
||
269 | #endif |
||
270 | } |