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