Subversion Repositories Scribus

Rev

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