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
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.
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"
45 //---------------------------------------------------------------------------
46 // OS/2 Printing - was in libprint.cpp
47 //---------------------------------------------------------------------------
48 static HMODULE hmodRes
;
50 #define SHIFT_PTR(ptr,offset) ( *((LONG*)&ptr) += offset )
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
; }
67 PRTQUEUE
& operator = (const PRTQUEUE
& z
); // prevent copying
68 void InitWithPQI3 (const PRQINFO3
* pInfo
);
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
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
, '.');
114 strcpy (mDriverName
, pInfo
->pszDriverName
);
115 strcpy (mDeviceName
, sep
+ 1);
119 strcpy (mDriverName
, pInfo
->pszDriverName
);
120 mDeviceName
[0] = '\0';
124 sep
= strchr (pInfo
->pszPrinters
, ',');
129 strcpy (mPrinterName
, pInfo
->pszPrinters
);
133 strcpy (mPrinterName
, pInfo
->pszPrinters
);
138 //===========================================================================
144 ULONG TotalQueues
= 0;
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
)
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
;
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;
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
)
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)) {
207 tmpBuf
[cnt
] = mPQBuf
[index
];
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
;
239 ULONG
PRINTDLG::GetNumPrinters()
244 void PRINTDLG::GetPrinter(ULONG printerNdx
, char** printerName
)
246 if (printerNdx
>= mQueueCount
)
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
)
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
)
278 return mPQBuf
[printerNdx
]->PQI3().pDriverData
;
281 HDC
PRINTDLG::GetDCHandle(ULONG printerNdx
)
286 dop
.pszLogAddress
= 0;
287 dop
.pszDriverName
= (char *)mPQBuf
[printerNdx
]->DriverName();
288 dop
.pdriv
= mPQBuf
[printerNdx
]->PQI3().pDriverData
;
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
);
300 char* PRINTDLG::GetDriverType(ULONG printerNdx
)
302 return (char *)mPQBuf
[printerNdx
]->DriverName ();
305 BOOL
PRINTDLG::ShowProperties(ULONG printerNdx
)
309 PDRIVDATA pOldDrivData
;
310 PDRIVDATA pNewDrivData
= NULL
;
313 /* check size of buffer required for job properties */
314 buflen
= DevPostDeviceModes( 0 /*hab*/,
316 mPQBuf
[printerNdx
]->DriverName (),
317 mPQBuf
[printerNdx
]->DeviceName (),
318 mPQBuf
[printerNdx
]->PrinterName (),
321 /* return error to caller */
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 (),
349 rc
= (devrc
!= DPDM_ERROR
);
353 /****************************************************************************/
355 /****************************************************************************/
357 HDC
PrnOpenDC( PRTQUEUE
*pInfo
, PSZ pszApplicationName
, int copies
, int destination
, char *file
)
365 if (!pInfo
|| !pszApplicationName
)
369 pszLogAddress
= pInfo
->PQI3 ().pszName
;
370 pszDataType
= "PM_Q_STD";
371 if ( destination
== 2 )
372 dcType
= OD_METAFILE
;
377 pszLogAddress
= (PSZ
) file
;
379 pszLogAddress
= "FILE";
380 pszDataType
= "PM_Q_RAW";
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
);
399 ULONG ErrorCode
= ERRORIDERROR (::WinGetLastError (0));
400 printf ("!ERROR! - Can't open DC for printer %04lX\a\n", ErrorCode
);
407 /* find the selected form */
408 BOOL
PrnQueryHardcopyCaps( HDC hdc
, PHCINFO pHCInfo
)
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
));
439 /****************************************************************************/
440 /* Library-level data and functions -Printing */
441 /****************************************************************************/
443 BOOL
PrnInitialize( HMODULE hmodResources
)
445 hmodRes
= hmodResources
;
451 /* nop for now, may do something eventually */
455 BOOL
PrnClosePrinter( PRTQUEUE
*pPrintQueue
)