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