1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "nsPrintOS2.h"
11 //---------------------------------------------------------------------------
12 // OS/2 Printing - was in libprint.cpp
13 //---------------------------------------------------------------------------
14 static HMODULE hmodRes
;
16 #define SHIFT_PTR(ptr,offset) ( *((LONG*)&ptr) += offset )
22 PRTQUEUE (const PRQINFO3
* pPQI3
) { InitWithPQI3 (pPQI3
); }
23 PRTQUEUE (const PRTQUEUE
& PQInfo
);
24 ~PRTQUEUE (void) { free (mpPQI3
); }
26 PRQINFO3
& PQI3 () const { return *mpPQI3
; }
27 const char* DriverName () const { return mDriverName
; }
28 const char* DeviceName () const { return mDeviceName
; }
29 const char* PrinterName() const { return mPrinterName
; }
30 const char* QueueName () const { return mpPQI3
->pszComment
; }
33 PRTQUEUE
& operator = (const PRTQUEUE
& z
); // prevent copying
34 void InitWithPQI3 (const PRQINFO3
* pInfo
);
37 unsigned mPQI3BufSize
;
38 char mDriverName
[DRIV_NAME_SIZE
+ 1]; // Driver name
39 char mDeviceName
[DRIV_DEVICENAME_SIZE
+ 1]; // Device name
40 char mPrinterName
[PRINTERNAME_SIZE
+ 1]; // Printer name
44 PRTQUEUE::PRTQUEUE (const PRTQUEUE
& PQInfo
)
46 mPQI3BufSize
= PQInfo
.mPQI3BufSize
;
47 mpPQI3
= (PRQINFO3
*)malloc (mPQI3BufSize
);
48 memcpy (mpPQI3
, PQInfo
.mpPQI3
, mPQI3BufSize
); // Copy entire buffer
50 long Diff
= (long)mpPQI3
- (long)PQInfo
.mpPQI3
; // Calculate the difference between addresses
51 SHIFT_PTR (mpPQI3
->pszName
, Diff
); // Modify internal pointers accordingly
52 SHIFT_PTR (mpPQI3
->pszSepFile
, Diff
);
53 SHIFT_PTR (mpPQI3
->pszPrProc
, Diff
);
54 SHIFT_PTR (mpPQI3
->pszParms
, Diff
);
55 SHIFT_PTR (mpPQI3
->pszComment
, Diff
);
56 SHIFT_PTR (mpPQI3
->pszPrinters
, Diff
);
57 SHIFT_PTR (mpPQI3
->pszDriverName
, Diff
);
58 SHIFT_PTR (mpPQI3
->pDriverData
, Diff
);
60 strcpy (mDriverName
, PQInfo
.mDriverName
);
61 strcpy (mDeviceName
, PQInfo
.mDeviceName
);
62 strcpy (mPrinterName
, PQInfo
.mPrinterName
);
65 void PRTQUEUE::InitWithPQI3(const PRQINFO3
* pInfo
)
67 // Make local copy of PPRQINFO3 object
69 ::SplQueryQueue (nullptr, pInfo
->pszName
, 3, nullptr, 0, &SizeNeeded
);
70 mpPQI3
= (PRQINFO3
*)malloc (SizeNeeded
);
71 ::SplQueryQueue (nullptr, pInfo
->pszName
, 3, mpPQI3
, SizeNeeded
, &SizeNeeded
);
73 mPQI3BufSize
= SizeNeeded
;
75 PCHAR sep
= strchr (pInfo
->pszDriverName
, '.');
80 strcpy (mDriverName
, pInfo
->pszDriverName
);
81 strcpy (mDeviceName
, sep
+ 1);
85 strcpy (mDriverName
, pInfo
->pszDriverName
);
86 mDeviceName
[0] = '\0';
90 sep
= strchr (pInfo
->pszPrinters
, ',');
95 strcpy (mPrinterName
, pInfo
->pszPrinters
);
99 strcpy (mPrinterName
, pInfo
->pszPrinters
);
104 //===========================================================================
110 ULONG TotalQueues
= 0;
114 rc
= ::SplEnumQueue(nullptr, 3, nullptr, 0, &mQueueCount
,
115 &TotalQueues
, &MemNeeded
, nullptr);
116 PRQINFO3
* pPQI3Buf
= (PRQINFO3
*) malloc (MemNeeded
);
117 rc
= ::SplEnumQueue(nullptr, 3, pPQI3Buf
, MemNeeded
, &mQueueCount
,
118 &TotalQueues
, &MemNeeded
, nullptr);
120 if (mQueueCount
> MAX_PRINT_QUEUES
)
121 mQueueCount
= MAX_PRINT_QUEUES
;
123 ULONG defaultQueue
= 0;
124 for (ULONG cnt
= 0; cnt
< mQueueCount
; cnt
++) {
125 if (pPQI3Buf
[cnt
].fsType
& PRQ3_TYPE_APPDEFAULT
)
127 mPQBuf
[cnt
] = new PRTQUEUE(&pPQI3Buf
[cnt
]);
130 // move the entry for the default printer to index 0 (if necessary)
131 if (defaultQueue
> 0) {
132 PRTQUEUE
* temp
= mPQBuf
[0];
133 mPQBuf
[0] = mPQBuf
[defaultQueue
];
134 mPQBuf
[defaultQueue
] = temp
;
140 PRINTDLG::~PRINTDLG()
142 for (ULONG index
= 0; index
< mQueueCount
; index
++)
143 delete mPQBuf
[index
];
146 void PRINTDLG::RefreshPrintQueue()
148 ULONG newQueueCount
= 0;
149 ULONG TotalQueues
= 0;
153 rc
= ::SplEnumQueue(nullptr, 3, nullptr, 0, &newQueueCount
,
154 &TotalQueues
, &MemNeeded
, nullptr);
155 PRQINFO3
* pPQI3Buf
= (PRQINFO3
*)malloc(MemNeeded
);
156 rc
= ::SplEnumQueue(nullptr, 3, pPQI3Buf
, MemNeeded
, &newQueueCount
,
157 &TotalQueues
, &MemNeeded
, nullptr);
159 if (newQueueCount
> MAX_PRINT_QUEUES
)
160 newQueueCount
= MAX_PRINT_QUEUES
;
162 PRTQUEUE
* tmpBuf
[MAX_PRINT_QUEUES
];
164 ULONG defaultQueue
= 0;
165 for (ULONG cnt
= 0; cnt
< newQueueCount
; cnt
++) {
166 if (pPQI3Buf
[cnt
].fsType
& PRQ3_TYPE_APPDEFAULT
)
170 for (ULONG index
= 0; index
< mQueueCount
&& !found
; index
++) {
171 //Compare printer from requeried list with what's already in Mozilla's printer list(mPQBuf)
172 //If printer is already there, use current properties; otherwise create a new printer in list
173 if (mPQBuf
[index
] != 0) {
174 if ((strcmp(pPQI3Buf
[cnt
].pszPrinters
, mPQBuf
[index
]->PrinterName()) == 0) &&
175 (strcmp(pPQI3Buf
[cnt
].pszDriverName
, mPQBuf
[index
]->PQI3().pszDriverName
) == 0)) {
177 tmpBuf
[cnt
] = mPQBuf
[index
];
183 tmpBuf
[cnt
] = new PRTQUEUE(&pPQI3Buf
[cnt
]);
186 for (ULONG index
= 0; index
< newQueueCount
; index
++) {
187 if (mPQBuf
[index
] != 0)
188 delete(mPQBuf
[index
]);
189 mPQBuf
[index
] = tmpBuf
[index
];
192 if (mQueueCount
> newQueueCount
)
193 for (ULONG index
= newQueueCount
; index
< mQueueCount
; index
++)
194 if (mPQBuf
[index
] != 0)
195 delete(mPQBuf
[index
]);
197 mQueueCount
= newQueueCount
;
199 // move the entry for the default printer to index 0 (if necessary)
200 if (defaultQueue
> 0) {
201 PRTQUEUE
* temp
= mPQBuf
[0];
202 mPQBuf
[0] = mPQBuf
[defaultQueue
];
203 mPQBuf
[defaultQueue
] = temp
;
209 ULONG
PRINTDLG::GetNumPrinters()
214 void PRINTDLG::GetPrinter(ULONG printerNdx
, char** printerName
)
216 if (printerNdx
>= mQueueCount
)
219 nsAutoCString
pName(mPQBuf
[printerNdx
]->QueueName());
221 pName
.ReplaceChar('\r', ' ');
222 pName
.StripChars("\n");
223 *printerName
= ToNewCString(pName
);
226 PRTQUEUE
* PRINTDLG::SetPrinterQueue(ULONG printerNdx
)
228 PRTQUEUE
*pPQ
= nullptr;
230 if (printerNdx
>= mQueueCount
)
233 pPQ
= mPQBuf
[printerNdx
];
235 return new PRTQUEUE(*pPQ
);
238 LONG
PRINTDLG::GetPrintDriverSize(ULONG printerNdx
)
240 return mPQBuf
[printerNdx
]->PQI3().pDriverData
->cb
;
243 PDRIVDATA
PRINTDLG::GetPrintDriver(ULONG printerNdx
)
245 if (printerNdx
>= mQueueCount
)
248 return mPQBuf
[printerNdx
]->PQI3().pDriverData
;
251 HDC
PRINTDLG::GetDCHandle(ULONG printerNdx
)
256 dop
.pszLogAddress
= 0;
257 dop
.pszDriverName
= (char *)mPQBuf
[printerNdx
]->DriverName();
258 dop
.pdriv
= mPQBuf
[printerNdx
]->PQI3().pDriverData
;
261 dop
.pszQueueProcName
= 0;
262 dop
.pszQueueProcParams
= 0;
263 dop
.pszSpoolerParams
= 0;
264 dop
.pszNetworkParams
= 0;
266 hdc
= ::DevOpenDC(0, OD_INFO
, "*", 9, (PDEVOPENDATA
) &dop
, NULLHANDLE
);
270 char* PRINTDLG::GetDriverType(ULONG printerNdx
)
272 return (char *)mPQBuf
[printerNdx
]->DriverName ();
275 BOOL
PRINTDLG::ShowProperties(ULONG printerNdx
)
279 PDRIVDATA pOldDrivData
;
280 PDRIVDATA pNewDrivData
= nullptr;
283 /* check size of buffer required for job properties */
284 buflen
= DevPostDeviceModes( 0 /*hab*/,
286 mPQBuf
[printerNdx
]->DriverName (),
287 mPQBuf
[printerNdx
]->DeviceName (),
288 mPQBuf
[printerNdx
]->PrinterName (),
291 /* return error to caller */
295 /* allocate some memory for larger job properties and */
296 /* return error to caller */
298 if (buflen
!= mPQBuf
[printerNdx
]->PQI3().pDriverData
->cb
)
300 if (DosAllocMem((PPVOID
)&pNewDrivData
,buflen
,fALLOC
))
301 return(FALSE
); // DPDM_ERROR
303 /* copy over old data so driver can use old job */
304 /* properties as base for job properties dialog */
305 pOldDrivData
= mPQBuf
[printerNdx
]->PQI3().pDriverData
;
306 mPQBuf
[printerNdx
]->PQI3().pDriverData
= pNewDrivData
;
307 memcpy( (PSZ
)pNewDrivData
, (PSZ
)pOldDrivData
, pOldDrivData
->cb
);
310 /* display job properties dialog and get updated */
311 /* job properties from driver */
313 devrc
= DevPostDeviceModes( 0 /*hab*/,
314 mPQBuf
[printerNdx
]->PQI3().pDriverData
,
315 mPQBuf
[printerNdx
]->DriverName (),
316 mPQBuf
[printerNdx
]->DeviceName (),
317 mPQBuf
[printerNdx
]->PrinterName (),
319 rc
= (devrc
!= DPDM_ERROR
);
323 /****************************************************************************/
325 /****************************************************************************/
327 HDC
PrnOpenDC( PRTQUEUE
*pInfo
, PCSZ pszApplicationName
, int copies
, int destination
, char *file
)
335 if (!pInfo
|| !pszApplicationName
)
339 pszLogAddress
= pInfo
->PQI3 ().pszName
;
340 pszDataType
= "PM_Q_STD";
341 if ( destination
== 2 )
342 dcType
= OD_METAFILE
;
347 pszLogAddress
= (PSZ
) file
;
349 pszLogAddress
= "FILE";
350 pszDataType
= "PM_Q_RAW";
354 dop
.pszLogAddress
= const_cast<PSZ
>(pszLogAddress
);
355 dop
.pszDriverName
= (char*)pInfo
->DriverName ();
356 dop
.pdriv
= pInfo
->PQI3 ().pDriverData
;
357 dop
.pszDataType
= const_cast<PSZ
>(pszDataType
);
358 dop
.pszComment
= const_cast<PSZ
>(pszApplicationName
);
359 dop
.pszQueueProcName
= pInfo
->PQI3 ().pszPrProc
;
360 dop
.pszQueueProcParams
= 0;
361 dop
.pszSpoolerParams
= 0;
362 dop
.pszNetworkParams
= 0;
364 hdc
= ::DevOpenDC( 0, dcType
, "*", 9, (PDEVOPENDATA
) &dop
, NULLHANDLE
);
369 ULONG ErrorCode
= ERRORIDERROR (::WinGetLastError (0));
370 printf ("!ERROR! - Can't open DC for printer %04lX\a\n", ErrorCode
);
377 /* find the selected form */
378 BOOL
PrnQueryHardcopyCaps( HDC hdc
, PHCINFO pHCInfo
)
387 /* query how many forms are available */
388 lAvail
= ::DevQueryHardcopyCaps( hdc
, 0, 0, nullptr);
390 pBuffer
= (PHCINFO
) malloc( lAvail
* sizeof(HCINFO
));
392 ::DevQueryHardcopyCaps( hdc
, 0, lAvail
, pBuffer
);
394 for( i
= 0; i
< lAvail
; i
++)
395 if( pBuffer
[ i
].flAttributes
& HCAPS_CURRENT
)
397 memcpy( pHCInfo
, pBuffer
+ i
, sizeof(HCINFO
));
409 /****************************************************************************/
410 /* Library-level data and functions -Printing */
411 /****************************************************************************/
413 BOOL
PrnInitialize( HMODULE hmodResources
)
415 hmodRes
= hmodResources
;
421 /* nop for now, may do something eventually */
425 BOOL
PrnClosePrinter( PRTQUEUE
*pPrintQueue
)