Save all modification
[mozilla-1.9/m8.git] / widget / src / os2 / nsPrintOS2.cpp
blob0ce619d5de8df668fe53195dc8ef5aae7cd1830f
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the Mozilla OS/2 libraries.
16 * The Initial Developer of the Original Code is
17 * John Fairhurst, <john_fairhurst@iname.com>.
18 * Portions created by the Initial Developer are Copyright (C) 1999
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
22 * Pierre Phaneuf <pp@ludusdesign.com>
23 * Peter Weilbacher <mozilla@weilbacher.org>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either of the GNU General Public License Version 2 or later (the "GPL"),
27 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #include "nsPrintOS2.h"
41 #include "nsOS2Uni.h"
43 #include <stdlib.h>
45 //---------------------------------------------------------------------------
46 // OS/2 Printing - was in libprint.cpp
47 //---------------------------------------------------------------------------
48 static HMODULE hmodRes;
50 #define SHIFT_PTR(ptr,offset) ( *((LONG*)&ptr) += offset )
53 class PRTQUEUE
55 public:
56 PRTQUEUE (const PRQINFO3* pPQI3) { InitWithPQI3 (pPQI3); }
57 PRTQUEUE (const PRTQUEUE& PQInfo);
58 ~PRTQUEUE (void) { free (mpPQI3); }
60 PRQINFO3& PQI3 () const { return *mpPQI3; }
61 const char* DriverName () const { return mDriverName; }
62 const char* DeviceName () const { return mDeviceName; }
63 const char* PrinterName() const { return mPrinterName; }
64 const char* QueueName () const { return mpPQI3->pszComment; }
66 private:
67 PRTQUEUE& operator = (const PRTQUEUE& z); // prevent copying
68 void InitWithPQI3 (const PRQINFO3* pInfo);
70 PRQINFO3* mpPQI3;
71 unsigned mPQI3BufSize;
72 char mDriverName [DRIV_NAME_SIZE + 1]; // Driver name
73 char mDeviceName [DRIV_DEVICENAME_SIZE + 1]; // Device name
74 char mPrinterName [PRINTERNAME_SIZE + 1]; // Printer name
78 PRTQUEUE::PRTQUEUE (const PRTQUEUE& PQInfo)
80 mPQI3BufSize = PQInfo.mPQI3BufSize;
81 mpPQI3 = (PRQINFO3*)malloc (mPQI3BufSize);
82 memcpy (mpPQI3, PQInfo.mpPQI3, mPQI3BufSize); // Copy entire buffer
84 long Diff = (long)mpPQI3 - (long)PQInfo.mpPQI3; // Calculate the difference between addresses
85 SHIFT_PTR (mpPQI3->pszName, Diff); // Modify internal pointers accordingly
86 SHIFT_PTR (mpPQI3->pszSepFile, Diff);
87 SHIFT_PTR (mpPQI3->pszPrProc, Diff);
88 SHIFT_PTR (mpPQI3->pszParms, Diff);
89 SHIFT_PTR (mpPQI3->pszComment, Diff);
90 SHIFT_PTR (mpPQI3->pszPrinters, Diff);
91 SHIFT_PTR (mpPQI3->pszDriverName, Diff);
92 SHIFT_PTR (mpPQI3->pDriverData, Diff);
94 strcpy (mDriverName, PQInfo.mDriverName);
95 strcpy (mDeviceName, PQInfo.mDeviceName);
96 strcpy (mPrinterName, PQInfo.mPrinterName);
99 void PRTQUEUE::InitWithPQI3(const PRQINFO3* pInfo)
101 // Make local copy of PPRQINFO3 object
102 ULONG SizeNeeded;
103 ::SplQueryQueue (NULL, pInfo->pszName, 3, NULL, 0, &SizeNeeded);
104 mpPQI3 = (PRQINFO3*)malloc (SizeNeeded);
105 ::SplQueryQueue (NULL, pInfo->pszName, 3, mpPQI3, SizeNeeded, &SizeNeeded);
107 mPQI3BufSize = SizeNeeded;
109 PCHAR sep = strchr (pInfo->pszDriverName, '.');
111 if (sep)
113 *sep = '\0';
114 strcpy (mDriverName, pInfo->pszDriverName);
115 strcpy (mDeviceName, sep + 1);
116 *sep = '.';
117 } else
119 strcpy (mDriverName, pInfo->pszDriverName);
120 mDeviceName [0] = '\0';
124 sep = strchr (pInfo->pszPrinters, ',');
126 if (sep)
128 *sep = '\0';
129 strcpy (mPrinterName, pInfo->pszPrinters);
130 *sep = '.';
131 } else
133 strcpy (mPrinterName, pInfo->pszPrinters);
138 //===========================================================================
140 PRINTDLG::PRINTDLG()
142 mQueueCount = 0;
144 ULONG TotalQueues = 0;
145 ULONG MemNeeded = 0;
146 SPLERR rc;
148 rc = ::SplEnumQueue(NULL, 3, NULL, 0, &mQueueCount, &TotalQueues, &MemNeeded, NULL);
149 PRQINFO3* pPQI3Buf = (PRQINFO3*) malloc (MemNeeded);
150 rc = ::SplEnumQueue(NULL, 3, pPQI3Buf, MemNeeded, &mQueueCount, &TotalQueues, &MemNeeded, NULL);
152 if (mQueueCount > MAX_PRINT_QUEUES)
153 mQueueCount = MAX_PRINT_QUEUES;
155 ULONG defaultQueue = 0;
156 for (ULONG cnt = 0; cnt < mQueueCount; cnt++) {
157 if (pPQI3Buf[cnt].fsType & PRQ3_TYPE_APPDEFAULT)
158 defaultQueue = cnt;
159 mPQBuf[cnt] = new PRTQUEUE(&pPQI3Buf[cnt]);
162 // move the entry for the default printer to index 0 (if necessary)
163 if (defaultQueue > 0) {
164 PRTQUEUE* temp = mPQBuf[0];
165 mPQBuf[0] = mPQBuf[defaultQueue];
166 mPQBuf[defaultQueue] = temp;
169 free(pPQI3Buf);
172 PRINTDLG::~PRINTDLG()
174 for (ULONG index = 0; index < mQueueCount; index++)
175 delete mPQBuf[index];
178 void PRINTDLG::RefreshPrintQueue()
180 ULONG newQueueCount = 0;
181 ULONG TotalQueues = 0;
182 ULONG MemNeeded = 0;
183 SPLERR rc;
185 rc = ::SplEnumQueue(NULL, 3, NULL, 0, &newQueueCount, &TotalQueues, &MemNeeded, NULL);
186 PRQINFO3* pPQI3Buf = (PRQINFO3*)malloc(MemNeeded);
187 rc = ::SplEnumQueue(NULL, 3, pPQI3Buf, MemNeeded, &newQueueCount, &TotalQueues, &MemNeeded, NULL);
189 if (newQueueCount > MAX_PRINT_QUEUES)
190 newQueueCount = MAX_PRINT_QUEUES;
192 PRTQUEUE* tmpBuf[MAX_PRINT_QUEUES];
194 ULONG defaultQueue = 0;
195 for (ULONG cnt = 0; cnt < newQueueCount; cnt++) {
196 if (pPQI3Buf[cnt].fsType & PRQ3_TYPE_APPDEFAULT)
197 defaultQueue = cnt;
199 BOOL found = FALSE;
200 for (ULONG index = 0; index < mQueueCount && !found; index++) {
201 //Compare printer from requeried list with what's already in Mozilla's printer list(mPQBuf)
202 //If printer is already there, use current properties; otherwise create a new printer in list
203 if (mPQBuf[index] != 0) {
204 if ((strcmp(pPQI3Buf[cnt].pszPrinters, mPQBuf[index]->PrinterName()) == 0) &&
205 (strcmp(pPQI3Buf[cnt].pszDriverName, mPQBuf[index]->PQI3().pszDriverName) == 0)) {
206 found = TRUE;
207 tmpBuf[cnt] = mPQBuf[index];
208 mPQBuf[index] = 0;
212 if (!found)
213 tmpBuf[cnt] = new PRTQUEUE(&pPQI3Buf[cnt]);
216 for (ULONG index = 0; index < newQueueCount; index++) {
217 if (mPQBuf[index] != 0)
218 delete(mPQBuf[index]);
219 mPQBuf[index] = tmpBuf[index];
222 if (mQueueCount > newQueueCount)
223 for (ULONG index = newQueueCount; index < mQueueCount; index++)
224 if (mPQBuf[index] != 0)
225 delete(mPQBuf[index]);
227 mQueueCount = newQueueCount;
229 // move the entry for the default printer to index 0 (if necessary)
230 if (defaultQueue > 0) {
231 PRTQUEUE* temp = mPQBuf[0];
232 mPQBuf[0] = mPQBuf[defaultQueue];
233 mPQBuf[defaultQueue] = temp;
236 free(pPQI3Buf);
239 ULONG PRINTDLG::GetNumPrinters()
241 return mQueueCount;
244 void PRINTDLG::GetPrinter(ULONG printerNdx, char** printerName)
246 if (printerNdx >= mQueueCount)
247 return;
249 nsCAutoString pName(mPQBuf[printerNdx]->QueueName());
251 pName.ReplaceChar('\r', ' ');
252 pName.StripChars("\n");
253 *printerName = ToNewCString(pName);
256 PRTQUEUE* PRINTDLG::SetPrinterQueue(ULONG printerNdx)
258 PRTQUEUE *pPQ = NULL;
260 if (printerNdx >= mQueueCount)
261 return NULL;
263 pPQ = mPQBuf[printerNdx];
265 return new PRTQUEUE(*pPQ);
268 LONG PRINTDLG::GetPrintDriverSize(ULONG printerNdx)
270 return mPQBuf[printerNdx]->PQI3().pDriverData->cb;
273 PDRIVDATA PRINTDLG::GetPrintDriver(ULONG printerNdx)
275 if (printerNdx >= mQueueCount)
276 return NULL;
278 return mPQBuf[printerNdx]->PQI3().pDriverData;
281 HDC PRINTDLG::GetDCHandle(ULONG printerNdx)
283 HDC hdc = 0;
284 DEVOPENSTRUC dop;
286 dop.pszLogAddress = 0;
287 dop.pszDriverName = (char *)mPQBuf[printerNdx]->DriverName();
288 dop.pdriv = mPQBuf[printerNdx]->PQI3().pDriverData;
289 dop.pszDataType = 0;
290 dop.pszComment = 0;
291 dop.pszQueueProcName = 0;
292 dop.pszQueueProcParams = 0;
293 dop.pszSpoolerParams = 0;
294 dop.pszNetworkParams = 0;
296 hdc = ::DevOpenDC(0, OD_INFO, "*", 9, (PDEVOPENDATA) &dop, NULLHANDLE);
297 return hdc;
300 char* PRINTDLG::GetDriverType(ULONG printerNdx)
302 return (char *)mPQBuf[printerNdx]->DriverName ();
305 BOOL PRINTDLG::ShowProperties(ULONG printerNdx)
307 BOOL rc = FALSE;
308 LONG devrc = FALSE;
309 PDRIVDATA pOldDrivData;
310 PDRIVDATA pNewDrivData = NULL;
311 LONG buflen;
313 /* check size of buffer required for job properties */
314 buflen = DevPostDeviceModes( 0 /*hab*/,
315 NULL,
316 mPQBuf[printerNdx]->DriverName (),
317 mPQBuf[printerNdx]->DeviceName (),
318 mPQBuf[printerNdx]->PrinterName (),
319 DPDM_POSTJOBPROP);
321 /* return error to caller */
322 if (buflen <= 0)
323 return(buflen);
325 /* allocate some memory for larger job properties and */
326 /* return error to caller */
328 if (buflen != mPQBuf[printerNdx]->PQI3().pDriverData->cb)
330 if (DosAllocMem((PPVOID)&pNewDrivData,buflen,fALLOC))
331 return(FALSE); // DPDM_ERROR
333 /* copy over old data so driver can use old job */
334 /* properties as base for job properties dialog */
335 pOldDrivData = mPQBuf[printerNdx]->PQI3().pDriverData;
336 mPQBuf[printerNdx]->PQI3().pDriverData = pNewDrivData;
337 memcpy( (PSZ)pNewDrivData, (PSZ)pOldDrivData, pOldDrivData->cb );
340 /* display job properties dialog and get updated */
341 /* job properties from driver */
343 devrc = DevPostDeviceModes( 0 /*hab*/,
344 mPQBuf[printerNdx]->PQI3().pDriverData,
345 mPQBuf[printerNdx]->DriverName (),
346 mPQBuf[printerNdx]->DeviceName (),
347 mPQBuf[printerNdx]->PrinterName (),
348 DPDM_POSTJOBPROP);
349 rc = (devrc != DPDM_ERROR);
350 return rc;
353 /****************************************************************************/
354 /* Job management */
355 /****************************************************************************/
357 HDC PrnOpenDC( PRTQUEUE *pInfo, PSZ pszApplicationName, int copies, int destination, char *file )
359 HDC hdc = 0;
360 PSZ pszLogAddress;
361 PSZ pszDataType;
362 LONG dcType;
363 DEVOPENSTRUC dop;
365 if (!pInfo || !pszApplicationName)
366 return hdc;
368 if ( destination ) {
369 pszLogAddress = pInfo->PQI3 ().pszName;
370 pszDataType = "PM_Q_STD";
371 if ( destination == 2 )
372 dcType = OD_METAFILE;
373 else
374 dcType = OD_QUEUED;
375 } else {
376 if (file && *file)
377 pszLogAddress = (PSZ) file;
378 else
379 pszLogAddress = "FILE";
380 pszDataType = "PM_Q_RAW";
381 dcType = OD_DIRECT;
384 dop.pszLogAddress = pszLogAddress;
385 dop.pszDriverName = (char*)pInfo->DriverName ();
386 dop.pdriv = pInfo->PQI3 ().pDriverData;
387 dop.pszDataType = pszDataType;
388 dop.pszComment = pszApplicationName;
389 dop.pszQueueProcName = pInfo->PQI3 ().pszPrProc;
390 dop.pszQueueProcParams = 0;
391 dop.pszSpoolerParams = 0;
392 dop.pszNetworkParams = 0;
394 hdc = ::DevOpenDC( 0, dcType, "*", 9, (PDEVOPENDATA) &dop, NULLHANDLE);
396 #ifdef DEBUG
397 if (hdc == 0)
399 ULONG ErrorCode = ERRORIDERROR (::WinGetLastError (0));
400 printf ("!ERROR! - Can't open DC for printer %04lX\a\n", ErrorCode);
402 #endif
404 return hdc;
407 /* find the selected form */
408 BOOL PrnQueryHardcopyCaps( HDC hdc, PHCINFO pHCInfo)
410 BOOL rc = FALSE;
412 if( hdc && pHCInfo)
414 PHCINFO pBuffer;
415 long lAvail, i;
417 /* query how many forms are available */
418 lAvail = ::DevQueryHardcopyCaps( hdc, 0, 0, NULL);
420 pBuffer = (PHCINFO) malloc( lAvail * sizeof(HCINFO));
422 ::DevQueryHardcopyCaps( hdc, 0, lAvail, pBuffer);
424 for( i = 0; i < lAvail; i++)
425 if( pBuffer[ i].flAttributes & HCAPS_CURRENT)
427 memcpy( pHCInfo, pBuffer + i, sizeof(HCINFO));
428 rc = TRUE;
429 break;
432 free( pBuffer);
435 return rc;
439 /****************************************************************************/
440 /* Library-level data and functions -Printing */
441 /****************************************************************************/
443 BOOL PrnInitialize( HMODULE hmodResources)
445 hmodRes = hmodResources;
446 return TRUE;
449 BOOL PrnTerminate()
451 /* nop for now, may do something eventually */
452 return TRUE;
455 BOOL PrnClosePrinter( PRTQUEUE *pPrintQueue)
457 BOOL rc = FALSE;
459 if (pPrintQueue)
461 delete pPrintQueue;
462 rc = TRUE;
465 return rc;