Subversion Repositories Scribus

Rev

Rev 4506 | 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 );
5753 jghali 176
                for ( uint i = 0; i < nPaperNames; i++ )
4506 cbradney 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
}