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