1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // use this define to disable the DJP support 25 // #define NO_DJP 26 27 #define INCL_DOSMODULEMGR 28 #define INCL_DEV 29 #define INCL_SPL 30 #define INCL_SPLERRORS 31 #define INCL_SPLDOSPRINT 32 #define INCL_DEVDJP 33 34 #define INCL_GPI 35 #define INCL_DOSSEMAPHORES 36 #define INCL_PM 37 #include <svpm.h> 38 #include <pmdjp.h> 39 40 #include <string.h> 41 42 #include <osl/module.h> 43 44 #include <tools/urlobj.hxx> 45 #include <tools/svwin.h> 46 #ifdef __MINGW32__ 47 #include <excpt.h> 48 #endif 49 50 #include <os2/saldata.hxx> 51 #include <os2/salinst.h> 52 #include <os2/salgdi.h> 53 #include <os2/salframe.h> 54 #include <os2/salprn.h> 55 56 #include <salptype.hxx> 57 #include <print.h> 58 #include <jobset.h> 59 60 /* 61 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp> 62 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> 63 #include <com/sun/star/ui/dialogs/XFilePicker.hpp> 64 #include <com/sun/star/ui/dialogs/XFilterManager.hpp> 65 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 66 #include <com/sun/star/lang/XInitialization.hpp> 67 #include <comphelper/processfactory.hxx> 68 */ 69 70 #include <malloc.h> 71 72 /* 73 #define _SV_SALPRN_CXX 74 #include <tools/debug.hxx> 75 #include <saldata.hxx> 76 #include <salinst.h> 77 #include <salgdi.h> 78 #include <salframe.h> 79 #include <vcl/salptype.hxx> 80 #include <salprn.h> 81 #include <vcl/print.h> 82 #include <vcl/jobset.h> 83 84 */ 85 86 #ifndef __H_FT2LIB 87 #include <os2/wingdi.h> 88 #include <ft2lib.h> 89 #endif 90 91 // ======================================================================= 92 93 // ----------------------- 94 // - struct ImplFormInfo - 95 // ----------------------- 96 97 struct ImplFormInfo 98 { 99 long mnPaperWidth; 100 long mnPaperHeight; 101 #ifndef NO_DJP 102 DJPT_PAPERSIZE mnId; 103 #endif 104 }; 105 106 // ======================================================================= 107 108 // ----------------------- 109 // - struct ImplTrayInfo - 110 // ----------------------- 111 112 struct ImplTrayInfo 113 { 114 CHAR maName[32]; 115 CHAR maDisplayName[64]; 116 DJPT_TRAYTYPE mnId; 117 118 ImplTrayInfo( const char* pTrayName, 119 const char* pTrayDisplayName ) 120 { 121 strcpy( maName, pTrayName); 122 strcpy( maDisplayName, pTrayDisplayName); 123 } 124 }; 125 126 // ======================================================================= 127 128 struct ImplQueueSalSysData 129 { 130 ByteString maPrinterName; // pszPrinters 131 ByteString maName; // pszName bzw. LogAddress 132 ByteString maOrgDriverName; // pszDriverName (maDriverName.maDeviceName) 133 ByteString maDriverName; // pszDriverName bis . 134 ByteString maDeviceName; // pszDriverName nach . 135 PDRIVDATA mpDrivData; 136 137 ImplQueueSalSysData( const ByteString& rPrinterName, 138 const ByteString& rName, 139 const ByteString& rDriverName, 140 const ByteString& rDeviceName, 141 const ByteString& rOrgDriverName, 142 PDRIVDATA pDrivData ); 143 ~ImplQueueSalSysData(); 144 }; 145 146 // ----------------------------------------------------------------------- 147 148 ImplQueueSalSysData::ImplQueueSalSysData( const ByteString& rPrinterName, 149 const ByteString& rName, 150 const ByteString& rOrgDriverName, 151 const ByteString& rDriverName, 152 const ByteString& rDeviceName, 153 PDRIVDATA pDrivData ) : 154 maPrinterName( rPrinterName ), 155 maName( rName ), 156 maOrgDriverName( rName ), 157 maDriverName( rDriverName ), 158 maDeviceName( rDeviceName ) 159 { 160 if ( pDrivData ) 161 { 162 mpDrivData = (PDRIVDATA)new PM_BYTE[pDrivData->cb]; 163 memcpy( mpDrivData, pDrivData, pDrivData->cb ); 164 } 165 else 166 mpDrivData = NULL; 167 } 168 169 // ----------------------------------------------------------------------- 170 171 ImplQueueSalSysData::~ImplQueueSalSysData() 172 { 173 delete mpDrivData; 174 } 175 176 // ======================================================================= 177 178 static ULONG ImplPMQueueStatusToSal( USHORT nPMStatus ) 179 { 180 ULONG nStatus = 0; 181 if ( nPMStatus & PRQ3_PAUSED ) 182 nStatus |= QUEUE_STATUS_PAUSED; 183 if ( nPMStatus & PRQ3_PENDING ) 184 nStatus |= QUEUE_STATUS_PENDING_DELETION; 185 if ( !nStatus ) 186 nStatus |= QUEUE_STATUS_READY; 187 return nStatus; 188 } 189 190 // ----------------------------------------------------------------------- 191 192 void Os2SalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList ) 193 { 194 APIRET rc; 195 ULONG nNeeded; 196 ULONG nReturned; 197 ULONG nTotal; 198 199 // query needed size of the buffer for the QueueInfo 200 rc = SplEnumQueue( (PSZ)NULL, 3, NULL, 0, &nReturned, &nTotal, &nNeeded, NULL ); 201 if( nNeeded == 0 ) 202 return; 203 204 // create the buffer for the QueueInfo 205 PCHAR pQueueData = new CHAR[nNeeded]; 206 207 // query QueueInfos 208 rc = SplEnumQueue( (PSZ)NULL, 3, pQueueData, nNeeded, &nReturned, &nTotal, &nNeeded, NULL ); 209 210 PPRQINFO3 pPrqInfo = (PPRQINFO3)pQueueData; 211 for ( int i = 0; i < nReturned; i++ ) 212 { 213 // create entry for the QueueInfo array 214 SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo; 215 216 ByteString aOrgDriverName( pPrqInfo->pszDriverName); 217 ByteString aName( pPrqInfo->pszName); 218 #if OSL_DEBUG_LEVEL>0 219 printf("GetPrinterQueueInfo pszDriverName %s\n", pPrqInfo->pszDriverName); 220 printf("GetPrinterQueueInfo pszName %s\n", pPrqInfo->pszDriverName); 221 #endif 222 pInfo->maDriver = ::rtl::OStringToOUString (aOrgDriverName, gsl_getSystemTextEncoding()); 223 pInfo->maPrinterName = ::rtl::OStringToOUString (pPrqInfo->pszComment, gsl_getSystemTextEncoding()); 224 pInfo->maLocation = ::rtl::OStringToOUString (aName, gsl_getSystemTextEncoding()); 225 pInfo->mnStatus = ImplPMQueueStatusToSal( pPrqInfo->fsStatus ); 226 pInfo->mnJobs = pPrqInfo->cJobs; 227 // pInfo->maComment = !!! 228 229 // Feststellen, ob Name doppelt 230 PPRQINFO3 pTempPrqInfo = (PPRQINFO3)pQueueData; 231 for ( int j = 0; j < nReturned; j++ ) 232 { 233 // Wenn Name doppelt, erweitern wir diesen um die Location 234 if ( (j != i) && 235 (strcmp( pPrqInfo->pszComment, pTempPrqInfo->pszComment ) == 0) ) 236 { 237 pInfo->maPrinterName += ';'; 238 pInfo->maPrinterName += pInfo->maLocation; 239 } 240 pTempPrqInfo++; 241 } 242 243 // pszDriver in DriverName (bis .) und DeviceName (nach .) aufsplitten 244 PSZ pDriverName; 245 PSZ pDeviceName; 246 if ( (pDriverName = strchr( pPrqInfo->pszDriverName, '.' )) != 0 ) 247 { 248 *pDriverName = 0; 249 pDeviceName = pDriverName + 1; 250 } 251 else 252 pDeviceName = NULL; 253 254 // Alle Bytes hinter dem DeviceNamen auf 0 initialisieren, damit 255 // ein memcmp vom JobSetup auch funktioniert 256 if ( pPrqInfo->pDriverData && 257 (pPrqInfo->pDriverData->cb >= sizeof( pPrqInfo->pDriverData )) ) 258 { 259 int nDeviceNameLen = strlen( pPrqInfo->pDriverData->szDeviceName ); 260 memset( pPrqInfo->pDriverData->szDeviceName+nDeviceNameLen, 261 0, 262 sizeof( pPrqInfo->pDriverData->szDeviceName )-nDeviceNameLen ); 263 } 264 265 // save driver data and driver names 266 ByteString aPrinterName( pPrqInfo->pszPrinters); 267 ByteString aDriverName( pPrqInfo->pszDriverName); 268 ByteString aDeviceName; 269 if ( pDeviceName ) 270 aDeviceName = pDeviceName; 271 pInfo->mpSysData = new ImplQueueSalSysData( aPrinterName, aName, 272 aOrgDriverName, 273 aDriverName, aDeviceName, 274 pPrqInfo->pDriverData ); 275 276 // add queue to the list 277 pList->Add( pInfo ); 278 279 // increment to next element of the QueueInfo array 280 pPrqInfo++; 281 } 282 283 delete [] pQueueData; 284 } 285 286 // ----------------------------------------------------------------------- 287 288 void Os2SalInstance::GetPrinterQueueState( SalPrinterQueueInfo* pInfo ) 289 { 290 APIRET rc; 291 ULONG nNeeded; 292 ULONG nReturned; 293 ULONG nTotal; 294 295 // query needed size of the buffer for the QueueInfo 296 rc = SplEnumQueue( (PSZ)NULL, 3, NULL, 0, &nReturned, &nTotal, &nNeeded, NULL ); 297 if( nNeeded == 0 ) 298 return; 299 300 // create the buffer for the QueueInfo 301 PCHAR pQueueData = new CHAR[nNeeded]; 302 303 // query QueueInfos 304 rc = SplEnumQueue( (PSZ)NULL, 3, pQueueData, nNeeded, &nReturned, &nTotal, &nNeeded, NULL ); 305 306 PPRQINFO3 pPrqInfo = (PPRQINFO3)pQueueData; 307 for ( int i = 0; i < nReturned; i++ ) 308 { 309 ImplQueueSalSysData* pSysData = (ImplQueueSalSysData*)(pInfo->mpSysData); 310 if ( pSysData->maPrinterName.Equals( pPrqInfo->pszPrinters ) && 311 pSysData->maName.Equals( pPrqInfo->pszName ) && 312 pSysData->maOrgDriverName.Equals( pPrqInfo->pszDriverName ) ) 313 { 314 pInfo->mnStatus = ImplPMQueueStatusToSal( pPrqInfo->fsStatus ); 315 pInfo->mnJobs = pPrqInfo->cJobs; 316 break; 317 } 318 319 // increment to next element of the QueueInfo array 320 pPrqInfo++; 321 } 322 323 delete [] pQueueData; 324 } 325 326 // ----------------------------------------------------------------------- 327 328 void Os2SalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo ) 329 { 330 delete ((ImplQueueSalSysData*)(pInfo->mpSysData)); 331 delete pInfo; 332 } 333 334 // ----------------------------------------------------------------------- 335 336 XubString Os2SalInstance::GetDefaultPrinter() 337 { 338 APIRET rc; 339 ULONG nNeeded; 340 ULONG nReturned; 341 ULONG nTotal; 342 char szQueueName[255]; 343 XubString aDefaultName; 344 345 // query default queue 346 if ( !PrfQueryProfileString( HINI_PROFILE, SPL_INI_SPOOLER, "QUEUE", 0, szQueueName, sizeof( szQueueName ) ) ) 347 return aDefaultName; 348 349 // extract first queue name 350 PSZ pStr; 351 if ( (pStr = strchr( szQueueName, ';' )) != 0 ) 352 *pStr = 0; 353 354 // query needed size of the buffer for the QueueInfo 355 rc = SplEnumQueue( (PSZ)NULL, 3, NULL, 0, &nReturned, &nTotal, &nNeeded, NULL ); 356 if ( nNeeded == 0 ) 357 return aDefaultName; 358 359 // create the buffer for the QueueInfo 360 PCHAR pQueueData = new CHAR[ nNeeded ]; 361 362 // query QueueInfos 363 rc = SplEnumQueue ((PSZ)NULL, 3, pQueueData, nNeeded, &nReturned, &nTotal, &nNeeded, NULL ); 364 365 // find printer name for default queue 366 PPRQINFO3 pPrqInfo = (PPRQINFO3) pQueueData; 367 for ( int i = 0; i < nReturned; i++ ) 368 { 369 if ( strcmp( pPrqInfo->pszName, szQueueName ) == 0 ) 370 { 371 aDefaultName = ::rtl::OStringToOUString (pPrqInfo->pszComment, gsl_getSystemTextEncoding()); 372 373 // Feststellen, ob Name doppelt 374 PPRQINFO3 pTempPrqInfo = (PPRQINFO3)pQueueData; 375 for ( int j = 0; j < nReturned; j++ ) 376 { 377 // Wenn Name doppelt, erweitern wir diesen um die Location 378 if ( (j != i) && 379 (strcmp( pPrqInfo->pszComment, pTempPrqInfo->pszComment ) == 0) ) 380 { 381 String pszName( ::rtl::OStringToOUString (pPrqInfo->pszName, gsl_getSystemTextEncoding())); 382 aDefaultName += ';'; 383 aDefaultName += pszName; 384 } 385 pTempPrqInfo++; 386 } 387 break; 388 } 389 390 // increment to next element of the QueueInfo array 391 pPrqInfo++; 392 } 393 394 delete [] pQueueData; 395 396 return aDefaultName; 397 } 398 399 // ======================================================================= 400 401 static void* ImplAllocPrnMemory( size_t n ) 402 { 403 return calloc( n, 1); 404 } 405 406 // ----------------------------------------------------------------------- 407 408 inline void ImplFreePrnMemory( void* p ) 409 { 410 free( p ); 411 } 412 413 // ----------------------------------------------------------------------- 414 415 static PDRIVDATA ImplPrnDrivData( const ImplJobSetup* pSetupData ) 416 { 417 // Diese Funktion wird eingesetzt, damit Druckertreiber nicht auf 418 // unseren Daten arbeiten, da es durch Konfigurationsprobleme 419 // sein kann, das der Druckertreiber bei uns Daten ueberschreibt. 420 // Durch diese vorgehensweise werden einige Abstuerze vermieden, bzw. 421 // sind dadurch leichter zu finden 422 423 if ( !pSetupData->mpDriverData ) 424 return NULL; 425 426 DBG_ASSERT( ((PDRIVDATA)(pSetupData->mpDriverData))->cb == pSetupData->mnDriverDataLen, 427 "ImplPrnDrivData() - SetupDataLen != DriverDataLen" ); 428 429 PDRIVDATA pDrivData = (PDRIVDATA)ImplAllocPrnMemory( pSetupData->mnDriverDataLen ); 430 memcpy( pDrivData, pSetupData->mpDriverData, pSetupData->mnDriverDataLen ); 431 return pDrivData; 432 } 433 434 // ----------------------------------------------------------------------- 435 436 static void ImplUpdateSetupData( const PDRIVDATA pDrivData, ImplJobSetup* pSetupData ) 437 { 438 // Diese Funktion wird eingesetzt, damit Druckertreiber nicht auf 439 // unseren Daten arbeiten, da es durch Konfigurationsprobleme 440 // sein kann, das der Druckertreiber bei uns Daten ueberschreibt. 441 // Durch diese vorgehensweise werden einige Abstuerze vermieden, bzw. 442 // sind dadurch leichter zu finden 443 444 if ( !pDrivData || !pDrivData->cb ) 445 { 446 if ( pSetupData->mpDriverData ) 447 rtl_freeMemory( pSetupData->mpDriverData ); 448 pSetupData->mpDriverData = NULL; 449 pSetupData->mnDriverDataLen = 0; 450 } 451 else 452 { 453 // Alle Bytes hinter dem DeviceNamen auf 0 initialisieren, damit 454 // ein memcmp vom JobSetup auch funktioniert 455 if ( pDrivData->cb >= sizeof( pDrivData ) ) 456 { 457 int nDeviceNameLen = strlen( pDrivData->szDeviceName ); 458 memset( pDrivData->szDeviceName+nDeviceNameLen, 459 0, 460 sizeof( pDrivData->szDeviceName )-nDeviceNameLen ); 461 } 462 463 if ( pSetupData->mpDriverData ) 464 { 465 if ( pSetupData->mnDriverDataLen != pDrivData->cb ) 466 rtl_freeMemory( pSetupData->mpDriverData ); 467 pSetupData->mpDriverData = (sal_uInt8*)rtl_allocateMemory( pDrivData->cb); 468 } 469 else 470 pSetupData->mpDriverData = (sal_uInt8*)rtl_allocateMemory( pDrivData->cb); 471 pSetupData->mnDriverDataLen = pDrivData->cb; 472 memcpy( pSetupData->mpDriverData, pDrivData, pDrivData->cb ); 473 } 474 475 if ( pDrivData ) 476 ImplFreePrnMemory( pDrivData ); 477 } 478 479 // ----------------------------------------------------------------------- 480 481 static sal_Bool ImplPaperSizeEqual( long nPaperWidth1, long nPaperHeight1, 482 long nPaperWidth2, long nPaperHeight2 ) 483 { 484 return (((nPaperWidth1 >= nPaperWidth2-1) && (nPaperWidth1 <= nPaperWidth2+1)) && 485 ((nPaperHeight1 >= nPaperHeight2-1) && (nPaperHeight1 <= nPaperHeight2+1))); 486 } 487 488 // ----------------------------------------------------------------------- 489 490 static sal_Bool ImplIsDriverDJPEnabled( HDC hDC ) 491 { 492 #ifdef NO_DJP 493 return FALSE; 494 #else 495 // Ueber OS2-Ini kann DJP disablte werden 496 if ( !PrfQueryProfileInt( HINI_PROFILE, SAL_PROFILE_APPNAME, SAL_PROFILE_USEDJP, 1 ) ) 497 return FALSE; 498 499 // Testen, ob DJP-Interface am Drucker vorhanden 500 LONG lQuery; 501 APIRET rc; 502 503 lQuery = DEVESC_QUERYSIZE; 504 rc = DevEscape( hDC, 505 DEVESC_QUERYESCSUPPORT, 506 sizeof( lQuery ), 507 (PBYTE)&lQuery, 508 0, 509 (PBYTE)NULL ); 510 if ( DEV_OK != rc ) 511 return FALSE; 512 513 lQuery = DEVESC_QUERYJOBPROPERTIES; 514 rc = DevEscape( hDC, 515 DEVESC_QUERYESCSUPPORT, 516 sizeof( lQuery ), 517 (PBYTE)&lQuery, 518 0, 519 (PBYTE)NULL ); 520 if ( DEV_OK != rc ) 521 return FALSE; 522 523 lQuery = DEVESC_SETJOBPROPERTIES; 524 rc = DevEscape( hDC, 525 DEVESC_QUERYESCSUPPORT, 526 sizeof( lQuery ), 527 (PBYTE)&lQuery, 528 0, 529 (PBYTE)NULL ); 530 if ( DEV_OK != rc ) 531 return FALSE; 532 533 return TRUE; 534 #endif 535 } 536 537 // ----------------------------------------------------------------------- 538 539 static void ImplFormatInputList( PDJP_ITEM pDJP, PQUERYTUPLE pTuple ) 540 { 541 // Loop through the query elements 542 sal_Bool fContinue = TRUE; 543 do 544 { 545 pDJP->cb = sizeof (DJP_ITEM); 546 pDJP->ulProperty = pTuple->ulProperty; 547 pDJP->lType = pTuple->lType; 548 pDJP->ulNumReturned = 0; 549 pDJP->ulValue = DJP_NONE; 550 551 // at EOL? 552 fContinue = DJP_NONE != pTuple->ulProperty; 553 554 // Move to next item structure and tuplet 555 pDJP++; 556 pTuple++; 557 } 558 while ( fContinue ); 559 } 560 561 // ----------------------------------------------------------------------- 562 563 static void ImplFreeFormAndTrayList( Os2SalInfoPrinter* pOs2SalInfoPrinter ) 564 { 565 if ( pOs2SalInfoPrinter->mnFormCount ) 566 { 567 for ( USHORT i = 0; i < pOs2SalInfoPrinter->mnFormCount; i++ ) 568 delete pOs2SalInfoPrinter->mpFormArray[i]; 569 delete [] pOs2SalInfoPrinter->mpFormArray; 570 pOs2SalInfoPrinter->mnFormCount = 0; 571 } 572 573 if ( pOs2SalInfoPrinter->mnTrayCount ) 574 { 575 for ( USHORT i = 0; i < pOs2SalInfoPrinter->mnTrayCount; i++ ) 576 delete pOs2SalInfoPrinter->mpTrayArray[i]; 577 delete [] pOs2SalInfoPrinter->mpTrayArray; 578 pOs2SalInfoPrinter->mnTrayCount = 0; 579 } 580 } 581 582 // ----------------------------------------------------------------------- 583 584 static void ImplGetFormAndTrayList( Os2SalInfoPrinter* pOs2SalInfoPrinter, const ImplJobSetup* pSetupData ) 585 { 586 ImplFreeFormAndTrayList( pOs2SalInfoPrinter ); 587 588 LONG alQuery[] = 589 { 590 0, 0, // First two members of QUERYSIZE 591 DJP_CJ_FORM, DJP_ALL, 592 DJP_CJ_TRAYNAME, DJP_ALL, 593 DJP_NONE, DJP_NONE // EOL marker 594 }; 595 596 APIRET rc; 597 PQUERYSIZE pQuerySize = (PQUERYSIZE)alQuery; 598 PBYTE pBuffer = NULL; 599 LONG nAlloc = 0; 600 PDRIVDATA pCopyDrivData = ImplPrnDrivData( pSetupData ); 601 LONG nDrivDataSize = pCopyDrivData->cb; 602 PBYTE pDrivData = (PBYTE)pCopyDrivData; 603 604 // find out how many bytes to allocate 605 pQuerySize->cb = sizeof( alQuery ); 606 rc = DevEscape( pOs2SalInfoPrinter->mhDC, 607 DEVESC_QUERYSIZE, 608 sizeof( alQuery ), 609 (PBYTE)pQuerySize, 610 &nDrivDataSize, 611 pDrivData ); 612 if ( DEV_OK != rc ) 613 { 614 ImplFreePrnMemory( pCopyDrivData ); 615 return; 616 } 617 618 // allocate the memory 619 nAlloc = pQuerySize->ulSizeNeeded; 620 pBuffer = (PBYTE)new PM_BYTE[nAlloc]; 621 622 // set up the input 623 PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer; 624 ImplFormatInputList( pDJP, pQuerySize->aTuples ); 625 626 // do it! 627 rc = DevEscape( pOs2SalInfoPrinter->mhDC, 628 DEVESC_QUERYJOBPROPERTIES, 629 nAlloc, 630 pBuffer, 631 &nDrivDataSize, 632 pDrivData ); 633 ImplFreePrnMemory( pCopyDrivData ); 634 635 if ( (DEV_OK == rc) || (DEV_WARNING == rc) ) 636 { 637 // Loop through the query elements 638 PQUERYTUPLE pTuple = pQuerySize->aTuples; 639 while ( DJP_NONE != pTuple->ulProperty ) 640 { 641 if ( pDJP->ulProperty == DJP_CJ_FORM ) 642 { 643 if ( pDJP->ulNumReturned ) 644 { 645 PDJPT_FORM pElm = DJP_ELEMENTP( *pDJP, DJPT_FORM ); 646 647 pOs2SalInfoPrinter->mnFormCount = pDJP->ulNumReturned; 648 pOs2SalInfoPrinter->mpFormArray = new PIMPLFORMINFO[pOs2SalInfoPrinter->mnFormCount]; 649 for( int i = 0; i < pDJP->ulNumReturned; i++, pElm++ ) 650 { 651 ImplFormInfo* pInfo = new ImplFormInfo; 652 pInfo->mnPaperWidth = pElm->hcInfo.cx; 653 pInfo->mnPaperHeight = pElm->hcInfo.cy; 654 #if OSL_DEBUG_LEVEL>0 655 printf("ImplGetFormAndTrayList mnPaperWidth %d\n", pInfo->mnPaperWidth); 656 printf("ImplGetFormAndTrayList mnPaperHeight %d\n", pInfo->mnPaperHeight); 657 #endif 658 pInfo->mnId = pElm->djppsFormID; 659 pOs2SalInfoPrinter->mpFormArray[i] = pInfo; 660 } 661 } 662 } 663 else if ( pDJP->ulProperty == DJP_CJ_TRAYNAME ) 664 { 665 if ( pDJP->ulNumReturned ) 666 { 667 PDJPT_TRAYNAME pElm = DJP_ELEMENTP( *pDJP, DJPT_TRAYNAME ); 668 669 pOs2SalInfoPrinter->mnTrayCount = pDJP->ulNumReturned; 670 pOs2SalInfoPrinter->mpTrayArray = new PIMPLTRAYINFO[pOs2SalInfoPrinter->mnTrayCount]; 671 for( int i = 0; i < pDJP->ulNumReturned; i++, pElm++ ) 672 { 673 ImplTrayInfo* pInfo = new ImplTrayInfo( pElm->szTrayname, pElm->szDisplayTrayname ); 674 pInfo->mnId = pElm->djpttTrayID; 675 pOs2SalInfoPrinter->mpTrayArray[i] = pInfo; 676 } 677 } 678 } 679 680 pDJP = DJP_NEXT_STRUCTP( pDJP ); 681 pTuple++; 682 } 683 } 684 685 delete [] pBuffer; 686 } 687 688 // ----------------------------------------------------------------------- 689 690 static sal_Bool ImplGetCurrentSettings( Os2SalInfoPrinter* pOs2SalInfoPrinter, ImplJobSetup* pSetupData ) 691 { 692 // Um den aktuellen Tray zu ermitteln, brauchen wir auch die Listen dazu 693 if ( !pOs2SalInfoPrinter->mnFormCount ) 694 ImplGetFormAndTrayList( pOs2SalInfoPrinter, pSetupData ); 695 696 LONG alQuery[] = 697 { 698 0, 0, // First two members of QUERYSIZE 699 DJP_SJ_ORIENTATION, DJP_CURRENT, 700 DJP_CJ_FORM, DJP_CURRENT, 701 DJP_NONE, DJP_NONE // EOL marker 702 }; 703 704 APIRET rc; 705 PQUERYSIZE pQuerySize = (PQUERYSIZE)alQuery; 706 PBYTE pBuffer = NULL; 707 LONG nAlloc = 0; 708 PDRIVDATA pCopyDrivData = ImplPrnDrivData( pSetupData ); 709 LONG nDrivDataSize = pCopyDrivData->cb; 710 PBYTE pDrivData = (PBYTE)pCopyDrivData; 711 sal_Bool bResult; 712 713 // find out how many bytes to allocate 714 pQuerySize->cb = sizeof( alQuery ); 715 rc = DevEscape( pOs2SalInfoPrinter->mhDC, 716 DEVESC_QUERYSIZE, 717 sizeof( alQuery ), 718 (PBYTE)pQuerySize, 719 &nDrivDataSize, 720 pDrivData ); 721 if ( DEV_OK != rc ) 722 { 723 ImplFreePrnMemory( pCopyDrivData ); 724 return FALSE; 725 } 726 727 // allocate the memory 728 nAlloc = pQuerySize->ulSizeNeeded; 729 pBuffer = (PBYTE)new PM_BYTE[nAlloc]; 730 731 // set up the input 732 PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer; 733 ImplFormatInputList( pDJP, pQuerySize->aTuples ); 734 735 rc = DevEscape( pOs2SalInfoPrinter->mhDC, 736 DEVESC_QUERYJOBPROPERTIES, 737 nAlloc, 738 pBuffer, 739 &nDrivDataSize, 740 pDrivData ); 741 if ( (DEV_OK == rc) || (DEV_WARNING == rc) ) 742 { 743 // aktuelle Setup-Daten uebernehmen 744 ImplUpdateSetupData( pCopyDrivData, pSetupData ); 745 746 // Loop through the query elements 747 PQUERYTUPLE pTuple = pQuerySize->aTuples; 748 while ( DJP_NONE != pTuple->ulProperty ) 749 { 750 if ( pDJP->ulProperty == DJP_SJ_ORIENTATION ) 751 { 752 if ( pDJP->ulNumReturned ) 753 { 754 PDJPT_ORIENTATION pElm = DJP_ELEMENTP( *pDJP, DJPT_ORIENTATION ); 755 if ( (DJP_ORI_PORTRAIT == *pElm) || (DJP_ORI_REV_PORTRAIT == *pElm) ) 756 pSetupData->meOrientation = ORIENTATION_PORTRAIT; 757 else 758 pSetupData->meOrientation = ORIENTATION_LANDSCAPE; 759 } 760 } 761 else if ( pDJP->ulProperty == DJP_CJ_FORM ) 762 { 763 if ( pDJP->ulNumReturned ) 764 { 765 PDJPT_FORM pElm = DJP_ELEMENTP( *pDJP, DJPT_FORM ); 766 767 pSetupData->mnPaperWidth = pElm->hcInfo.cx*100; 768 pSetupData->mnPaperHeight = pElm->hcInfo.cy*100; 769 switch( pElm->djppsFormID ) 770 { 771 case DJP_PSI_A3: 772 pSetupData->mePaperFormat = PAPER_A3; 773 break; 774 775 case DJP_PSI_A4: 776 pSetupData->mePaperFormat = PAPER_A4; 777 break; 778 779 case DJP_PSI_A5: 780 pSetupData->mePaperFormat = PAPER_A5; 781 break; 782 783 case DJP_PSI_B4: 784 pSetupData->mePaperFormat = PAPER_B4_JIS; 785 break; 786 787 case DJP_PSI_B5: 788 pSetupData->mePaperFormat = PAPER_B5_JIS; 789 break; 790 791 case DJP_PSI_LETTER: 792 pSetupData->mePaperFormat = PAPER_LETTER; 793 break; 794 795 case DJP_PSI_LEGAL: 796 pSetupData->mePaperFormat = PAPER_LEGAL; 797 break; 798 799 case DJP_PSI_TABLOID: 800 pSetupData->mePaperFormat = PAPER_TABLOID; 801 break; 802 803 default: 804 pSetupData->mePaperFormat = PAPER_USER; 805 break; 806 } 807 808 // Wir suchen zuerst ueber den Namen/Id und dann ueber die Id 809 sal_Bool bTrayFound = FALSE; 810 USHORT j; 811 for ( j = 0; j < pOs2SalInfoPrinter->mnTrayCount; j++ ) 812 { 813 if ( (pOs2SalInfoPrinter->mpTrayArray[j]->mnId == pElm->djpttTrayID) && 814 (pOs2SalInfoPrinter->mpTrayArray[j]->maName == pElm->szTrayname) ) 815 { 816 pSetupData->mnPaperBin = j; 817 bTrayFound = TRUE; 818 break; 819 } 820 } 821 if ( !bTrayFound ) 822 { 823 for ( j = 0; j < pOs2SalInfoPrinter->mnTrayCount; j++ ) 824 { 825 if ( pOs2SalInfoPrinter->mpTrayArray[j]->mnId == pElm->djpttTrayID ) 826 { 827 pSetupData->mnPaperBin = j; 828 bTrayFound = TRUE; 829 break; 830 } 831 } 832 } 833 // Wenn wir Ihn immer noch nicht gefunden haben, setzen 834 // wir ihn auf DontKnow 835 if ( !bTrayFound ) 836 pSetupData->mnPaperBin = 0xFFFF; 837 } 838 } 839 840 pDJP = DJP_NEXT_STRUCTP( pDJP ); 841 pTuple++; 842 } 843 844 bResult = TRUE; 845 } 846 else 847 { 848 ImplFreePrnMemory( pCopyDrivData ); 849 bResult = FALSE; 850 } 851 852 delete [] pBuffer; 853 854 return bResult; 855 } 856 857 // ----------------------------------------------------------------------- 858 859 static sal_Bool ImplSetOrientation( HDC hPrinterDC, PDRIVDATA pDriverData, 860 Orientation eOrientation ) 861 { 862 LONG alQuery[] = 863 { 864 0, 0, // First two members of QUERYSIZE 865 DJP_SJ_ORIENTATION, DJP_CURRENT, 866 DJP_NONE, DJP_NONE // EOL marker 867 }; 868 869 APIRET rc; 870 PQUERYSIZE pQuerySize = (PQUERYSIZE)alQuery; 871 PBYTE pBuffer = NULL; 872 LONG nAlloc = 0; 873 LONG nDrivDataSize = pDriverData->cb; 874 875 // find out how many bytes to allocate 876 pQuerySize->cb = sizeof( alQuery ); 877 rc = DevEscape( hPrinterDC, 878 DEVESC_QUERYSIZE, 879 sizeof( alQuery ), 880 (PBYTE)pQuerySize, 881 &nDrivDataSize, 882 (PBYTE)pDriverData ); 883 if ( DEV_OK != rc ) 884 return FALSE; 885 886 // allocate the memory 887 nAlloc = pQuerySize->ulSizeNeeded; 888 pBuffer = (PBYTE)new PM_BYTE[nAlloc]; 889 890 // set up the input 891 PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer; 892 ImplFormatInputList( pDJP, pQuerySize->aTuples ); 893 894 pDJP->cb = sizeof( DJP_ITEM ); 895 pDJP->ulProperty = DJP_SJ_ORIENTATION; 896 pDJP->lType = DJP_CURRENT; 897 pDJP->ulValue = (eOrientation == ORIENTATION_PORTRAIT) 898 ? DJP_ORI_PORTRAIT 899 : DJP_ORI_LANDSCAPE; 900 901 // do it! 902 rc = DevEscape( hPrinterDC, 903 DEVESC_SETJOBPROPERTIES, 904 nAlloc, 905 pBuffer, 906 &nDrivDataSize, 907 (PBYTE)pDriverData ); 908 909 delete [] pBuffer; 910 911 return ((DEV_OK == rc) || (DEV_WARNING == rc)); 912 } 913 914 // ----------------------------------------------------------------------- 915 916 static sal_Bool ImplSetPaperSize( HDC hPrinterDC, PDRIVDATA pDriverData, 917 DJPT_PAPERSIZE nOS2PaperFormat ) 918 { 919 LONG alQuery[] = 920 { 921 0, 0, // First two members of QUERYSIZE 922 DJP_SJ_PAPERSIZE, DJP_CURRENT, 923 DJP_NONE, DJP_NONE // EOL marker 924 }; 925 926 APIRET rc; 927 PQUERYSIZE pQuerySize = (PQUERYSIZE)alQuery; 928 PBYTE pBuffer = NULL; 929 LONG nAlloc = 0; 930 LONG nDrivDataSize = pDriverData->cb; 931 932 // find out how many bytes to allocate 933 pQuerySize->cb = sizeof( alQuery ); 934 rc = DevEscape( hPrinterDC, 935 DEVESC_QUERYSIZE, 936 sizeof( alQuery ), 937 (PBYTE)pQuerySize, 938 &nDrivDataSize, 939 (PBYTE)pDriverData ); 940 if ( DEV_OK != rc ) 941 return FALSE; 942 943 // allocate the memory 944 nAlloc = pQuerySize->ulSizeNeeded; 945 pBuffer = (PBYTE)new PM_BYTE[nAlloc]; 946 947 // set up the input 948 PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer; 949 PDJP_ITEM pStartDJP = pDJP; 950 ImplFormatInputList( pDJP, pQuerySize->aTuples ); 951 952 // Neue Daten zuweisen 953 pDJP->cb = sizeof( DJP_ITEM ); 954 pDJP->ulProperty = DJP_SJ_PAPERSIZE; 955 pDJP->lType = DJP_CURRENT; 956 pDJP->ulValue = nOS2PaperFormat; 957 958 // und setzen 959 rc = DevEscape( hPrinterDC, 960 DEVESC_SETJOBPROPERTIES, 961 nAlloc, 962 pBuffer, 963 &nDrivDataSize, 964 (PBYTE)pDriverData ); 965 966 delete [] pBuffer; 967 968 return ((DEV_OK == rc) || (DEV_WARNING == rc)); 969 } 970 971 // ----------------------------------------------------------------------- 972 973 static sal_Bool ImplSetPaperBin( HDC hPrinterDC, PDRIVDATA pDriverData, 974 ImplTrayInfo* pTrayInfo ) 975 { 976 LONG alQuery[] = 977 { 978 0, 0, // First two members of QUERYSIZE 979 DJP_SJ_TRAYTYPE, DJP_CURRENT, 980 DJP_NONE, DJP_NONE // EOL marker 981 }; 982 983 APIRET rc; 984 PQUERYSIZE pQuerySize = (PQUERYSIZE)alQuery; 985 PBYTE pBuffer = NULL; 986 LONG nAlloc = 0; 987 LONG nDrivDataSize = pDriverData->cb; 988 989 // find out how many bytes to allocate 990 pQuerySize->cb = sizeof( alQuery ); 991 rc = DevEscape( hPrinterDC, 992 DEVESC_QUERYSIZE, 993 sizeof( alQuery ), 994 (PBYTE)pQuerySize, 995 &nDrivDataSize, 996 (PBYTE)pDriverData ); 997 if ( DEV_OK != rc ) 998 return FALSE; 999 1000 // allocate the memory 1001 nAlloc = pQuerySize->ulSizeNeeded; 1002 pBuffer = (PBYTE)new PM_BYTE[nAlloc]; 1003 1004 // set up the input 1005 PDJP_ITEM pDJP = (PDJP_ITEM)pBuffer; 1006 ImplFormatInputList( pDJP, pQuerySize->aTuples ); 1007 1008 // Neue Daten zuweisen 1009 pDJP->cb = sizeof( DJP_ITEM ); 1010 pDJP->ulProperty = DJP_SJ_TRAYTYPE; 1011 pDJP->lType = DJP_CURRENT; 1012 pDJP->ulValue = pTrayInfo->mnId; 1013 1014 // und setzen 1015 rc = DevEscape( hPrinterDC, 1016 DEVESC_SETJOBPROPERTIES, 1017 nAlloc, 1018 pBuffer, 1019 &nDrivDataSize, 1020 (PBYTE)pDriverData ); 1021 1022 delete [] pBuffer; 1023 1024 return ((DEV_OK == rc) || (DEV_WARNING == rc)); 1025 } 1026 1027 // ======================================================================= 1028 1029 static sal_Bool ImplSalCreateInfoPrn( Os2SalInfoPrinter* pPrinter, PDRIVDATA pDriverData, 1030 HDC& rDC, HPS& rPS ) 1031 { 1032 SalData* pSalData = GetSalData(); 1033 1034 // create info context 1035 DEVOPENSTRUC devOpenStruc; 1036 memset( &devOpenStruc, 0, sizeof( devOpenStruc ) ); 1037 devOpenStruc.pszLogAddress = (char*)pPrinter->maName.GetBuffer(); 1038 devOpenStruc.pszDriverName = (char*)pPrinter->maDriverName.GetBuffer(); 1039 devOpenStruc.pdriv = pDriverData; 1040 devOpenStruc.pszDataType = "PM_Q_STD"; 1041 1042 HDC hDC = DevOpenDC( pSalData->mhAB, OD_INFO, "*", 1043 4, (PDEVOPENDATA)&devOpenStruc, (HDC)NULL); 1044 if ( !hDC ) 1045 return FALSE; 1046 1047 // create presentation space 1048 SIZEL sizel; 1049 sizel.cx = 0; 1050 sizel.cy = 0; 1051 HPS hPS = Ft2CreatePS( pSalData->mhAB, hDC, &sizel, GPIA_ASSOC | GPIT_MICRO | PU_PELS ); 1052 if ( !hPS ) 1053 { 1054 DevCloseDC( hDC ); 1055 return FALSE; 1056 } 1057 1058 rDC = hDC; 1059 rPS = hPS; 1060 return TRUE; 1061 } 1062 1063 // ----------------------------------------------------------------------- 1064 1065 static void ImplSalDestroyInfoPrn( Os2SalInfoPrinter* pPrinter ) 1066 { 1067 ImplSalDeInitGraphics( pPrinter->mpGraphics); 1068 Ft2Associate( pPrinter->mhPS, 0 ); 1069 Ft2DestroyPS( pPrinter->mhPS ); 1070 DevCloseDC( pPrinter->mhDC ); 1071 } 1072 1073 // ======================================================================= 1074 1075 SalInfoPrinter* Os2SalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo, 1076 ImplJobSetup* pSetupData ) 1077 { 1078 ImplQueueSalSysData* pSysQueueData = (ImplQueueSalSysData*)(pQueueInfo->mpSysData); 1079 Os2SalInfoPrinter* pPrinter = new Os2SalInfoPrinter; 1080 pPrinter->maPrinterName = pSysQueueData->maPrinterName; 1081 pPrinter->maName = pSysQueueData->maName; 1082 pPrinter->maDriverName = pSysQueueData->maDriverName; 1083 pPrinter->maDeviceName = pSysQueueData->maDeviceName; 1084 1085 // Nur Setup-Daten uebernehmen, wenn Treiber und Laenge der Treiberdaten 1086 // uebereinstimmt 1087 PDRIVDATA pDriverData; 1088 sal_Bool bUpdateDriverData; 1089 if ( pSetupData->mpDriverData && pSysQueueData->mpDrivData && 1090 (pSetupData->mnSystem == JOBSETUP_SYSTEM_OS2) && 1091 (pSetupData->mnDriverDataLen == pSysQueueData->mpDrivData->cb) && 1092 (strcmp( ((PDRIVDATA)pSetupData->mpDriverData)->szDeviceName, 1093 pSysQueueData->mpDrivData->szDeviceName ) == 0) ) 1094 { 1095 pDriverData = PDRIVDATA( pSetupData->mpDriverData ); 1096 bUpdateDriverData = FALSE; 1097 } 1098 else 1099 { 1100 pDriverData = pSysQueueData->mpDrivData; 1101 bUpdateDriverData = TRUE; 1102 } 1103 if ( pDriverData ) 1104 pPrinter->maJobSetupDeviceName = pDriverData->szDeviceName; 1105 1106 if ( !ImplSalCreateInfoPrn( pPrinter, pDriverData, 1107 pPrinter->mhDC, 1108 pPrinter->mhPS ) ) 1109 { 1110 delete pPrinter; 1111 return NULL; 1112 } 1113 1114 // create graphics object for output 1115 Os2SalGraphics* pGraphics = new Os2SalGraphics; 1116 pGraphics->mhDC = pPrinter->mhDC; 1117 pGraphics->mhPS = pPrinter->mhPS; 1118 pGraphics->mhWnd = 0; 1119 pGraphics->mbPrinter = TRUE; 1120 pGraphics->mbVirDev = FALSE; 1121 pGraphics->mbWindow = FALSE; 1122 pGraphics->mbScreen = FALSE; 1123 1124 ImplSalInitGraphics( pGraphics ); 1125 pPrinter->mpGraphics = pGraphics; 1126 1127 // check printer driver for DJP support 1128 pPrinter->mbDJPSupported = ImplIsDriverDJPEnabled( pPrinter->mhDC ); 1129 1130 if ( bUpdateDriverData ) 1131 { 1132 if ( pSetupData->mpDriverData ) 1133 rtl_freeMemory( pSetupData->mpDriverData); 1134 pSetupData->mpDriverData = (sal_uInt8*)rtl_allocateMemory( pDriverData->cb); 1135 memcpy( pSetupData->mpDriverData, pDriverData, pDriverData->cb ); 1136 pSetupData->mnDriverDataLen = pDriverData->cb; 1137 } 1138 1139 // retrieve current settings from printer driver and store them to system independend data! 1140 if ( pPrinter->mbDJPSupported ) 1141 ImplGetCurrentSettings( pPrinter, pSetupData ); 1142 pSetupData->mnSystem = JOBSETUP_SYSTEM_OS2; 1143 1144 return pPrinter; 1145 } 1146 1147 // ----------------------------------------------------------------------- 1148 1149 void Os2SalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter ) 1150 { 1151 delete pPrinter; 1152 } 1153 1154 // ======================================================================= 1155 1156 Os2SalInfoPrinter::Os2SalInfoPrinter() 1157 { 1158 mhDC = 0; 1159 mhPS = 0; 1160 mpGraphics = NULL; 1161 mbGraphics = FALSE; 1162 mbDJPSupported = FALSE; 1163 mnFormCount = 0; 1164 mpFormArray = NULL; 1165 mnTrayCount = 0; 1166 mpTrayArray = NULL; 1167 } 1168 1169 // ----------------------------------------------------------------------- 1170 1171 Os2SalInfoPrinter::~Os2SalInfoPrinter() 1172 { 1173 if ( mpGraphics ) 1174 { 1175 ImplSalDestroyInfoPrn( this ); 1176 delete mpGraphics; 1177 } 1178 1179 ImplFreeFormAndTrayList( this ); 1180 } 1181 1182 // ----------------------------------------------------------------------- 1183 1184 SalGraphics* Os2SalInfoPrinter::GetGraphics() 1185 { 1186 if ( mbGraphics ) 1187 return NULL; 1188 1189 if ( mpGraphics ) 1190 mbGraphics = TRUE; 1191 1192 return mpGraphics; 1193 } 1194 1195 // ----------------------------------------------------------------------- 1196 1197 void Os2SalInfoPrinter::ReleaseGraphics( SalGraphics* ) 1198 { 1199 mbGraphics = FALSE; 1200 } 1201 1202 // ----------------------------------------------------------------------- 1203 1204 sal_Bool Os2SalInfoPrinter::Setup( SalFrame* pFrame, ImplJobSetup* pSetupData ) 1205 { 1206 PDRIVDATA pDrivData = ImplPrnDrivData( pSetupData ); 1207 if ( !pDrivData ) 1208 return FALSE; 1209 1210 APIRET rc = DevPostDeviceModes( GetSalData()->mhAB, pDrivData, 1211 maDriverName.GetBuffer(), 1212 maDeviceName.GetBuffer(), 1213 maPrinterName.GetBuffer(), 1214 DPDM_POSTJOBPROP ); 1215 if ( rc == DEV_OK ) 1216 { 1217 ImplUpdateSetupData( pDrivData, pSetupData ); 1218 1219 // update DC and PS 1220 HDC hDC; 1221 HPS hPS; 1222 if ( !ImplSalCreateInfoPrn( this, (PDRIVDATA)(pSetupData->mpDriverData), hDC, hPS ) ) 1223 return FALSE; 1224 1225 // Alten Printer DC/PS zerstoeren 1226 ImplSalDestroyInfoPrn( this ); 1227 1228 // Neue Daten setzen und initialisieren 1229 mhDC = hDC; 1230 mhPS = hPS; 1231 mpGraphics->mhDC = mhDC; 1232 mpGraphics->mhPS = mhPS; 1233 ImplSalInitGraphics( mpGraphics ); 1234 1235 // retrieve current settings from printer driver and store them to system independend data! 1236 ImplFreeFormAndTrayList( this ); 1237 if ( mbDJPSupported ) 1238 ImplGetCurrentSettings( this, pSetupData ); 1239 1240 return TRUE; 1241 } 1242 else 1243 { 1244 ImplFreePrnMemory( pDrivData ); 1245 return FALSE; 1246 } 1247 } 1248 1249 // ----------------------------------------------------------------------- 1250 1251 sal_Bool Os2SalInfoPrinter::SetPrinterData( ImplJobSetup* pSetupData ) 1252 { 1253 // Wir koennen nur Treiberdaten von OS2 setzen 1254 if ( pSetupData->mnSystem != JOBSETUP_SYSTEM_OS2 ) 1255 return FALSE; 1256 1257 PDRIVDATA pNewDrivData = (PDRIVDATA)(pSetupData->mpDriverData); 1258 if ( !pNewDrivData ) 1259 return FALSE; 1260 1261 // Testen, ob Printerdaten fuer den gleichen Printer uebergeben werden, 1262 // da einige Treiber zu Abstuerzen neigen, wenn Daten von einem anderen 1263 // Printer gesetzt werden 1264 if ( !maJobSetupDeviceName.Equals( pNewDrivData->szDeviceName )) 1265 return FALSE; 1266 1267 // update DC and PS 1268 HDC hDC; 1269 HPS hPS; 1270 if ( !ImplSalCreateInfoPrn( this, pNewDrivData, hDC, hPS ) ) 1271 return FALSE; 1272 1273 // Alten Printer DC/PS zerstoeren 1274 ImplSalDestroyInfoPrn( this ); 1275 1276 // Neue Daten setzen und initialisieren 1277 mhDC = hDC; 1278 mhPS = hPS; 1279 mpGraphics->mhDC = mhDC; 1280 mpGraphics->mhPS = mhPS; 1281 ImplSalInitGraphics( mpGraphics ); 1282 1283 // retrieve current settings from printer driver and store them to system independend data! 1284 ImplFreeFormAndTrayList( this ); 1285 if ( mbDJPSupported ) 1286 ImplGetCurrentSettings( this, pSetupData ); 1287 1288 return TRUE; 1289 } 1290 1291 // ----------------------------------------------------------------------- 1292 1293 sal_Bool Os2SalInfoPrinter::SetData( ULONG nFlags, ImplJobSetup* pSetupData ) 1294 { 1295 // needs DJP support 1296 if ( !mbDJPSupported ) 1297 return FALSE; 1298 1299 PDRIVDATA pDrivData = ImplPrnDrivData( pSetupData ); 1300 1301 if ( !pDrivData ) 1302 return FALSE; 1303 1304 sal_Bool bOK = FALSE; 1305 1306 // set orientation 1307 if ( nFlags & SAL_JOBSET_ORIENTATION ) 1308 { 1309 if ( ImplSetOrientation( mhDC, pDrivData, pSetupData->meOrientation ) ) 1310 bOK = TRUE; 1311 } 1312 1313 // set paper size 1314 if ( nFlags & SAL_JOBSET_PAPERSIZE ) 1315 { 1316 // Papierformat ermitteln 1317 DJPT_PAPERSIZE nOS2PaperFormat; 1318 switch ( pSetupData->mePaperFormat ) 1319 { 1320 case PAPER_A3: 1321 nOS2PaperFormat = DJP_PSI_A3; 1322 break; 1323 1324 case PAPER_A4: 1325 nOS2PaperFormat = DJP_PSI_A4; 1326 break; 1327 1328 case PAPER_A5: 1329 nOS2PaperFormat = DJP_PSI_A5; 1330 break; 1331 1332 case PAPER_B4_JIS: 1333 nOS2PaperFormat = DJP_PSI_B4; 1334 break; 1335 1336 case PAPER_B5_JIS: 1337 nOS2PaperFormat = DJP_PSI_B5; 1338 break; 1339 1340 case PAPER_LETTER: 1341 nOS2PaperFormat = DJP_PSI_LETTER; 1342 break; 1343 1344 case PAPER_LEGAL: 1345 nOS2PaperFormat = DJP_PSI_LEGAL; 1346 break; 1347 1348 case PAPER_TABLOID: 1349 nOS2PaperFormat = DJP_PSI_TABLOID; 1350 break; 1351 1352 default: 1353 { 1354 nOS2PaperFormat = DJP_PSI_NONE; 1355 // OS2 rechnet in Millimetern 1356 long nPaperWidth = pSetupData->mnPaperWidth / 100; 1357 long nPaperHeight = pSetupData->mnPaperHeight / 100; 1358 // Ansonsten ueber die Papiergroesse suchen 1359 for( int i = 0; i < mnFormCount; i++ ) 1360 { 1361 ImplFormInfo* pFormInfo = mpFormArray[i]; 1362 if ( ImplPaperSizeEqual( nPaperWidth, nPaperHeight, 1363 pFormInfo->mnPaperWidth, pFormInfo->mnPaperHeight ) ) 1364 { 1365 nOS2PaperFormat = pFormInfo->mnId; 1366 break; 1367 } 1368 } 1369 } 1370 break; 1371 } 1372 1373 if ( nOS2PaperFormat != DJP_PSI_NONE ) 1374 { 1375 if ( ImplSetPaperSize( mhDC, pDrivData, nOS2PaperFormat ) ) 1376 bOK = TRUE; 1377 } 1378 } 1379 1380 // set paper tray 1381 if ( (nFlags & SAL_JOBSET_PAPERBIN) && (pSetupData->mnPaperBin < mnTrayCount) ) 1382 { 1383 if ( ImplSetPaperBin( mhDC, pDrivData, 1384 mpTrayArray[pSetupData->mnPaperBin] ) ) 1385 bOK = TRUE; 1386 } 1387 1388 if ( bOK ) 1389 { 1390 ImplUpdateSetupData( pDrivData, pSetupData ); 1391 1392 // query current driver settings 1393 ImplFreeFormAndTrayList( this ); 1394 if ( ImplGetCurrentSettings( this, pSetupData ) ) 1395 { 1396 // update DC and PS 1397 HDC hDC; 1398 HPS hPS; 1399 if ( ImplSalCreateInfoPrn( this, (PDRIVDATA)(pSetupData->mpDriverData), hDC, hPS ) ) 1400 { 1401 // Alten Printer DC/PS zerstoeren 1402 ImplSalDestroyInfoPrn( this ); 1403 1404 // Neue Daten setzen und initialisieren 1405 mhDC = hDC; 1406 mhPS = hPS; 1407 mpGraphics->mhDC = mhDC; 1408 mpGraphics->mhPS = mhPS; 1409 ImplSalInitGraphics( mpGraphics ); 1410 } 1411 else 1412 bOK = FALSE; 1413 } 1414 else 1415 bOK = FALSE; 1416 } 1417 1418 return bOK; 1419 } 1420 1421 // ----------------------------------------------------------------------- 1422 1423 ULONG Os2SalInfoPrinter::GetPaperBinCount( const ImplJobSetup* pJobSetup ) 1424 { 1425 if ( !mbDJPSupported ) 1426 return 1; 1427 1428 // init paperbinlist if empty 1429 if ( !mnTrayCount ) 1430 ImplGetFormAndTrayList( this, pJobSetup ); 1431 1432 // Wir haben immer einen PaperTray und wenn, das eben einen ohne 1433 // Namen 1434 if ( !mnTrayCount ) 1435 return 1; 1436 else 1437 return mnTrayCount; 1438 } 1439 1440 // ----------------------------------------------------------------------- 1441 1442 XubString Os2SalInfoPrinter::GetPaperBinName( const ImplJobSetup* pJobSetup, 1443 ULONG nPaperBin ) 1444 { 1445 XubString aPaperBinName; 1446 1447 if ( mbDJPSupported ) 1448 { 1449 // init paperbinlist if empty 1450 if ( !mnTrayCount ) 1451 ImplGetFormAndTrayList( this, pJobSetup ); 1452 1453 if ( nPaperBin < mnTrayCount ) 1454 aPaperBinName = ::rtl::OStringToOUString (mpTrayArray[nPaperBin]->maDisplayName, gsl_getSystemTextEncoding()); 1455 } 1456 1457 return aPaperBinName; 1458 } 1459 1460 // ----------------------------------------------------------------------- 1461 1462 ULONG Os2SalInfoPrinter::GetCapabilities( const ImplJobSetup*, USHORT nType ) 1463 { 1464 switch ( nType ) 1465 { 1466 case PRINTER_CAPABILITIES_SUPPORTDIALOG: 1467 return TRUE; 1468 case PRINTER_CAPABILITIES_COPIES: 1469 return 0xFFFF; 1470 case PRINTER_CAPABILITIES_COLLATECOPIES: 1471 return 0; 1472 case PRINTER_CAPABILITIES_SETORIENTATION: 1473 case PRINTER_CAPABILITIES_SETPAPERBIN: 1474 case PRINTER_CAPABILITIES_SETPAPERSIZE: 1475 case PRINTER_CAPABILITIES_SETPAPER: 1476 return mbDJPSupported; 1477 } 1478 1479 return 0; 1480 } 1481 1482 // ----------------------------------------------------------------------- 1483 1484 void Os2SalInfoPrinter::GetPageInfo( const ImplJobSetup*, 1485 long& rOutWidth, long& rOutHeight, 1486 long& rPageOffX, long& rPageOffY, 1487 long& rPageWidth, long& rPageHeight ) 1488 { 1489 HDC hDC = mhDC; 1490 1491 // search current form 1492 HCINFO aInfo; 1493 int nForms = DevQueryHardcopyCaps( hDC, 0, 0, &aInfo ); 1494 for( int i = 0; i < nForms; i++ ) 1495 { 1496 if ( DevQueryHardcopyCaps( hDC, i, 1, &aInfo ) >= 0 ) 1497 { 1498 if ( aInfo.flAttributes & HCAPS_CURRENT ) 1499 { 1500 // query resolution 1501 long nXResolution; 1502 long nYResolution; 1503 DevQueryCaps( hDC, CAPS_HORIZONTAL_RESOLUTION, 1, &nXResolution ); 1504 DevQueryCaps( hDC, CAPS_VERTICAL_RESOLUTION, 1, &nYResolution ); 1505 rPageOffX = aInfo.xLeftClip * nXResolution / 1000; 1506 rPageOffY = (aInfo.cy-aInfo.yTopClip) * nYResolution / 1000; 1507 rPageWidth = aInfo.cx * nXResolution / 1000; 1508 rPageHeight = aInfo.cy * nYResolution / 1000; 1509 rOutWidth = aInfo.xPels; 1510 rOutHeight = aInfo.yPels; 1511 return; 1512 } 1513 } 1514 } 1515 1516 // use device caps if no form selected/found 1517 long lCapsWidth = 0; 1518 long lCapsHeight = 0; 1519 DevQueryCaps( hDC, CAPS_WIDTH, 1L, &lCapsWidth ); 1520 DevQueryCaps( hDC, CAPS_HEIGHT, 1L, &lCapsHeight ); 1521 rPageOffX = 0; 1522 rPageOffY = 0; 1523 rOutWidth = lCapsWidth; 1524 rOutHeight = lCapsHeight; 1525 rPageWidth = rOutWidth; 1526 rPageHeight = rOutHeight; 1527 } 1528 1529 // ======================================================================= 1530 1531 static sal_Bool ImplIsDriverPrintDJPEnabled( HDC hDC ) 1532 { 1533 #ifdef NO_DJP 1534 return FALSE; 1535 #else 1536 // Ueber OS2-Ini kann DJP disablte werden 1537 if ( !PrfQueryProfileInt( HINI_PROFILE, SAL_PROFILE_APPNAME, SAL_PROFILE_PRINTDJP, 1 ) ) 1538 return FALSE; 1539 1540 // Testen, ob DJP-Interface am Drucker vorhanden 1541 LONG lQuery; 1542 APIRET rc; 1543 1544 lQuery = DEVESC_QUERYSIZE; 1545 rc = DevEscape( hDC, 1546 DEVESC_QUERYESCSUPPORT, 1547 sizeof( lQuery ), 1548 (PBYTE)&lQuery, 1549 0, 1550 (PBYTE)NULL ); 1551 if ( DEV_OK != rc ) 1552 return FALSE; 1553 1554 return TRUE; 1555 #endif 1556 } 1557 1558 // ======================================================================= 1559 1560 SalPrinter* Os2SalInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter ) 1561 { 1562 Os2SalPrinter* pPrinter = new Os2SalPrinter; 1563 pPrinter->mpInfoPrinter = static_cast<Os2SalInfoPrinter*>(pInfoPrinter); 1564 return pPrinter; 1565 } 1566 1567 // ----------------------------------------------------------------------- 1568 1569 void Os2SalInstance::DestroyPrinter( SalPrinter* pPrinter ) 1570 { 1571 delete pPrinter; 1572 } 1573 1574 // ======================================================================= 1575 1576 Os2SalPrinter::Os2SalPrinter() 1577 { 1578 mhDC = 0; 1579 mhPS = 0; 1580 mpGraphics = NULL; 1581 mbAbort = FALSE; 1582 mbPrintDJPSupported = FALSE; 1583 } 1584 1585 // ----------------------------------------------------------------------- 1586 1587 Os2SalPrinter::~Os2SalPrinter() 1588 { 1589 } 1590 1591 // ----------------------------------------------------------------------- 1592 1593 sal_Bool Os2SalPrinter::StartJob( const XubString* pFileName, 1594 const XubString& rJobName, 1595 const XubString& rAppName, 1596 ULONG nCopies, 1597 bool bCollate, 1598 bool bDirect, 1599 ImplJobSetup* pSetupData ) 1600 { 1601 DEVOPENSTRUC aDevOpenStruc; 1602 LONG lType; 1603 APIRET rc; 1604 1605 // prepare queue information 1606 memset( &aDevOpenStruc, 0, sizeof( aDevOpenStruc ) ); 1607 aDevOpenStruc.pszDriverName = (PSZ)(mpInfoPrinter->maDriverName.GetBuffer()); 1608 1609 // print into file? 1610 if ( pFileName ) 1611 { 1612 aDevOpenStruc.pszLogAddress = (PSZ)pFileName->GetBuffer(); 1613 aDevOpenStruc.pszDataType = "PM_Q_RAW"; 1614 lType = OD_DIRECT; 1615 } 1616 else 1617 { 1618 aDevOpenStruc.pszLogAddress = (PSZ)(mpInfoPrinter->maName.GetBuffer()); 1619 if ( PrfQueryProfileInt( HINI_PROFILE, SAL_PROFILE_APPNAME, SAL_PROFILE_PRINTRAW, 0 ) ) 1620 aDevOpenStruc.pszDataType = "PM_Q_RAW"; 1621 else 1622 aDevOpenStruc.pszDataType = "PM_Q_STD"; 1623 lType = OD_QUEUED; 1624 } 1625 1626 #if 0 // YD FIXME 1627 // Set comment (AppName nur bis zum 1. Space-Zeichen nehmen) 1628 const xub_Unicode* pComment = rAppName; 1629 USHORT nCommentLen = 0; 1630 memset( maCommentBuf, 0, sizeof( maCommentBuf ) ); 1631 while ( (nCommentLen < 32) && 1632 (((*pComment >= 'a') && (*pComment <= 'z')) || 1633 ((*pComment >= 'A') && (*pComment <= 'Z')) || 1634 ((*pComment >= '0') && (*pComment <= '9')) || 1635 (*pComment == '-'))) 1636 { 1637 maCommentBuf[nCommentLen] = (char)(*pComment); 1638 nCommentLen++; 1639 pComment++; 1640 } 1641 aDevOpenStruc.pszComment = (PSZ)maCommentBuf; 1642 #endif 1643 ByteString jobName( rJobName, gsl_getSystemTextEncoding()); 1644 aDevOpenStruc.pszComment = (PSZ)jobName.GetBuffer(); 1645 1646 // Kopien 1647 if ( nCopies > 1 ) 1648 { 1649 // OS2 kann maximal 999 Kopien 1650 if ( nCopies > 999 ) 1651 nCopies = 999; 1652 sprintf( maCopyBuf, "COP=%d", nCopies); 1653 aDevOpenStruc.pszQueueProcParams = (PSZ)maCopyBuf; 1654 } 1655 1656 // open device context 1657 SalData* pSalData = GetSalData(); 1658 HAB hAB = pSalData->mhAB; 1659 aDevOpenStruc.pdriv = (PDRIVDATA)pSetupData->mpDriverData; 1660 mhDC = DevOpenDC( hAB, 1661 lType, 1662 "*", 1663 7, 1664 (PDEVOPENDATA)&aDevOpenStruc, 1665 0 ); 1666 if ( mhDC == 0 ) 1667 { 1668 ERRORID nLastError = WinGetLastError( hAB ); 1669 if ( (nLastError & 0xFFFF) == PMERR_SPL_PRINT_ABORT ) 1670 mnError = SAL_PRINTER_ERROR_ABORT; 1671 else 1672 mnError = SAL_PRINTER_ERROR_GENERALERROR; 1673 return FALSE; 1674 } 1675 1676 // open presentation space 1677 SIZEL sizel; 1678 sizel.cx = 0; 1679 sizel.cy = 0; 1680 mhPS = Ft2CreatePS( hAB, mhDC, &sizel, GPIA_ASSOC | GPIT_MICRO | PU_PELS ); 1681 if ( !mhPS ) 1682 { 1683 DevCloseDC( mhDC ); 1684 mnError = SAL_PRINTER_ERROR_GENERALERROR; 1685 return NULL; 1686 } 1687 1688 // Can we print with DJP 1689 mbPrintDJPSupported = ImplIsDriverPrintDJPEnabled( mhDC ); 1690 1691 // JobName ermitteln und Job starten 1692 PSZ pszJobName = NULL; 1693 int nJobNameLen = 0; 1694 if ( jobName.Len() > 0 ) 1695 { 1696 pszJobName = (PSZ)jobName.GetBuffer(); 1697 nJobNameLen = jobName.Len(); 1698 } 1699 rc = DevEscape( mhDC, 1700 DEVESC_STARTDOC, 1701 nJobNameLen, (PBYTE)pszJobName, 1702 0, (PBYTE)NULL ); 1703 1704 if ( rc != DEV_OK ) 1705 { 1706 ERRORID nLastError = WinGetLastError( hAB ); 1707 if ( (nLastError & 0xFFFF) == PMERR_SPL_PRINT_ABORT ) 1708 mnError = SAL_PRINTER_ERROR_ABORT; 1709 else 1710 mnError = SAL_PRINTER_ERROR_GENERALERROR; 1711 Ft2Associate( mhPS, NULL ); 1712 Ft2DestroyPS( mhPS ); 1713 DevCloseDC( mhDC ); 1714 return FALSE; 1715 } 1716 1717 // init for first page 1718 mbFirstPage = TRUE; 1719 mnError = 0; 1720 1721 return TRUE; 1722 } 1723 1724 // ----------------------------------------------------------------------- 1725 1726 sal_Bool Os2SalPrinter::EndJob() 1727 { 1728 APIRET rc; 1729 rc = DevEscape( mhDC, 1730 DEVESC_ENDDOC, 1731 0, NULL, 1732 0, NULL); 1733 1734 // destroy presentation space and device context 1735 Ft2Associate( mhPS, NULL ); 1736 Ft2DestroyPS( mhPS ); 1737 DevCloseDC( mhDC ); 1738 return TRUE; 1739 } 1740 1741 // ----------------------------------------------------------------------- 1742 1743 sal_Bool Os2SalPrinter::AbortJob() 1744 { 1745 APIRET rc; 1746 1747 rc = DevEscape( mhDC, 1748 DEVESC_ABORTDOC, 1749 0, NULL, 1750 0, NULL ); 1751 1752 // destroy SalGraphics 1753 if ( mpGraphics ) 1754 { 1755 ImplSalDeInitGraphics( mpGraphics ); 1756 delete mpGraphics; 1757 mpGraphics = NULL; 1758 } 1759 1760 // destroy presentation space and device context 1761 Ft2Associate( mhPS, NULL ); 1762 Ft2DestroyPS( mhPS ); 1763 DevCloseDC( mhDC ); 1764 return TRUE; 1765 } 1766 1767 // ----------------------------------------------------------------------- 1768 1769 SalGraphics* Os2SalPrinter::StartPage( ImplJobSetup* pSetupData, sal_Bool bNewJobSetup ) 1770 { 1771 APIRET rc; 1772 1773 if ( mbFirstPage ) 1774 mbFirstPage = FALSE; 1775 else 1776 { 1777 PBYTE pJobData; 1778 LONG nJobDataSize; 1779 LONG nEscape; 1780 if ( mbPrintDJPSupported && bNewJobSetup ) 1781 { 1782 nEscape = DEVESC_NEWFRAME_WPROP; 1783 nJobDataSize = ((PDRIVDATA)(pSetupData->mpDriverData))->cb; 1784 pJobData = (PBYTE)(pSetupData->mpDriverData); 1785 } 1786 else 1787 { 1788 nEscape = DEVESC_NEWFRAME; 1789 nJobDataSize = 0; 1790 pJobData = NULL; 1791 } 1792 rc = DevEscape( mhDC, 1793 nEscape, 1794 0, NULL, 1795 &nJobDataSize, pJobData ); 1796 1797 if ( rc != DEV_OK ) 1798 { 1799 DevEscape( mhDC, DEVESC_ENDDOC, 0, NULL, 0, NULL); 1800 Ft2Associate( mhPS, NULL ); 1801 Ft2DestroyPS( mhPS ); 1802 DevCloseDC( mhDC ); 1803 mnError = SAL_PRINTER_ERROR_GENERALERROR; 1804 return NULL; 1805 } 1806 } 1807 1808 // create SalGraphics with copy of hPS 1809 Os2SalGraphics* pGraphics = new Os2SalGraphics; 1810 pGraphics->mhDC = mhDC; 1811 pGraphics->mhPS = mhPS; 1812 pGraphics->mhWnd = 0; 1813 pGraphics->mbPrinter = TRUE; 1814 pGraphics->mbVirDev = FALSE; 1815 pGraphics->mbWindow = FALSE; 1816 pGraphics->mbScreen = FALSE; 1817 pGraphics->mnHeight = 0; 1818 // search current form for actual page height 1819 HCINFO aInfo; 1820 int nForms = DevQueryHardcopyCaps( mhDC, 0, 0, &aInfo ); 1821 for( int i = 0; i < nForms; i++ ) 1822 { 1823 if ( DevQueryHardcopyCaps( mhDC, i, 1, &aInfo ) >= 0 ) 1824 { 1825 if ( aInfo.flAttributes & HCAPS_CURRENT ) 1826 pGraphics->mnHeight = aInfo.yPels; 1827 } 1828 } 1829 // use device caps if no form selected/found 1830 if ( !pGraphics->mnHeight ) 1831 DevQueryCaps( mhDC, CAPS_HEIGHT, 1L, &pGraphics->mnHeight ); 1832 1833 ImplSalInitGraphics( pGraphics ); 1834 mpGraphics = pGraphics; 1835 1836 return pGraphics; 1837 } 1838 1839 // ----------------------------------------------------------------------- 1840 1841 sal_Bool Os2SalPrinter::EndPage() 1842 { 1843 if ( mpGraphics ) 1844 { 1845 // destroy SalGraphics 1846 ImplSalDeInitGraphics( mpGraphics ); 1847 delete mpGraphics; 1848 mpGraphics = NULL; 1849 } 1850 1851 return TRUE; 1852 } 1853 1854 // ----------------------------------------------------------------------- 1855 1856 ULONG Os2SalPrinter::GetErrorCode() 1857 { 1858 return mnError; 1859 } 1860 1861 void Os2SalInfoPrinter::InitPaperFormats( const ImplJobSetup* pSetupData ) 1862 { 1863 printf("Os2SalInfoPrinter::InitPaperFormats\n"); 1864 } 1865 int Os2SalInfoPrinter::GetLandscapeAngle( const ImplJobSetup* pSetupData ) 1866 { 1867 printf("Os2SalInfoPrinter::GetLandscapeAngle\n"); 1868 return 0; 1869 } 1870 1871