diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2000-09-18 16:07:07 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2000-09-18 16:07:07 +0000 |
commit | 8ab086b6cc054501bfbf7ef6fa509c393691e860 (patch) | |
tree | 324d51845d7f1a2f4e02a14db22fb5947137c822 /vcl/win/source/gdi/salprn.cxx | |
parent | 411e68cc54ae97eebd79ae3a9cb2971b74cb2a9e (diff) |
initial import
Diffstat (limited to 'vcl/win/source/gdi/salprn.cxx')
-rw-r--r-- | vcl/win/source/gdi/salprn.cxx | 1424 |
1 files changed, 1424 insertions, 0 deletions
diff --git a/vcl/win/source/gdi/salprn.cxx b/vcl/win/source/gdi/salprn.cxx new file mode 100644 index 000000000000..e4ac38538b51 --- /dev/null +++ b/vcl/win/source/gdi/salprn.cxx @@ -0,0 +1,1424 @@ +/************************************************************************* + * + * $RCSfile: salprn.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <string.h> +#ifndef _SVWIN_H +#include <tools/svwin.h> +#endif + +#define _SV_SALPRN_CXX + +#ifndef _SV_WINCOMP_HXX +#include <wincomp.hxx> +#endif +#ifndef _SV_SALDATA_HXX +#include <saldata.hxx> +#endif +#ifndef _SV_SALINST_HXX +#include <salinst.hxx> +#endif +#ifndef _SV_SALGDI_HXX +#include <salgdi.hxx> +#endif +#ifndef _SV_SALFRAME_HXX +#include <salframe.hxx> +#endif +#ifndef _SV_SALPTYPE_HXX +#include <salptype.hxx> +#endif +#ifndef _SV_SALPRN_HXX +#include <salprn.hxx> +#endif + +#ifndef _NEW_HXX +#include <tools/new.hxx> +#endif + +#ifndef _SV_PRINT_H +#include <print.h> +#endif +#ifndef _SV_JOBSET_H +#include <jobset.h> +#endif + +// ======================================================================= + +static char aImplWindows[] = "windows"; +static char aImplDevices[] = "devices"; +static char aImplDevice[] = "device"; + +// ======================================================================= + +static ULONG ImplWinQueueStatusToSal( DWORD nWinStatus ) +{ + ULONG nStatus = 0; + if ( nWinStatus & PRINTER_STATUS_PAUSED ) + nStatus |= QUEUE_STATUS_PAUSED; + if ( nWinStatus & PRINTER_STATUS_ERROR ) + nStatus |= QUEUE_STATUS_ERROR; + if ( nWinStatus & PRINTER_STATUS_PENDING_DELETION ) + nStatus |= QUEUE_STATUS_PENDING_DELETION; + if ( nWinStatus & PRINTER_STATUS_PAPER_JAM ) + nStatus |= QUEUE_STATUS_PAPER_JAM; + if ( nWinStatus & PRINTER_STATUS_PAPER_OUT ) + nStatus |= QUEUE_STATUS_PAPER_OUT; + if ( nWinStatus & PRINTER_STATUS_MANUAL_FEED ) + nStatus |= QUEUE_STATUS_MANUAL_FEED; + if ( nWinStatus & PRINTER_STATUS_PAPER_PROBLEM ) + nStatus |= QUEUE_STATUS_PAPER_PROBLEM; + if ( nWinStatus & PRINTER_STATUS_OFFLINE ) + nStatus |= QUEUE_STATUS_OFFLINE; + if ( nWinStatus & PRINTER_STATUS_IO_ACTIVE ) + nStatus |= QUEUE_STATUS_IO_ACTIVE; + if ( nWinStatus & PRINTER_STATUS_BUSY ) + nStatus |= QUEUE_STATUS_BUSY; + if ( nWinStatus & PRINTER_STATUS_PRINTING ) + nStatus |= QUEUE_STATUS_PRINTING; + if ( nWinStatus & PRINTER_STATUS_OUTPUT_BIN_FULL ) + nStatus |= QUEUE_STATUS_OUTPUT_BIN_FULL; + if ( nWinStatus & PRINTER_STATUS_WAITING ) + nStatus |= QUEUE_STATUS_WAITING; + if ( nWinStatus & PRINTER_STATUS_PROCESSING ) + nStatus |= QUEUE_STATUS_PROCESSING; + if ( nWinStatus & PRINTER_STATUS_INITIALIZING ) + nStatus |= QUEUE_STATUS_INITIALIZING; + if ( nWinStatus & PRINTER_STATUS_WARMING_UP ) + nStatus |= QUEUE_STATUS_WARMING_UP; + if ( nWinStatus & PRINTER_STATUS_TONER_LOW ) + nStatus |= QUEUE_STATUS_TONER_LOW; + if ( nWinStatus & PRINTER_STATUS_NO_TONER ) + nStatus |= QUEUE_STATUS_NO_TONER; + if ( nWinStatus & PRINTER_STATUS_PAGE_PUNT ) + nStatus |= QUEUE_STATUS_PAGE_PUNT; + if ( nWinStatus & PRINTER_STATUS_USER_INTERVENTION ) + nStatus |= QUEUE_STATUS_USER_INTERVENTION; + if ( nWinStatus & PRINTER_STATUS_OUT_OF_MEMORY ) + nStatus |= QUEUE_STATUS_OUT_OF_MEMORY; + if ( nWinStatus & PRINTER_STATUS_DOOR_OPEN ) + nStatus |= QUEUE_STATUS_DOOR_OPEN; + if ( nWinStatus & PRINTER_STATUS_SERVER_UNKNOWN ) + nStatus |= QUEUE_STATUS_SERVER_UNKNOWN; + if ( nWinStatus & PRINTER_STATUS_POWER_SAVE ) + nStatus |= QUEUE_STATUS_POWER_SAVE; + if ( !nStatus && !(nWinStatus & PRINTER_STATUS_NOT_AVAILABLE) ) + nStatus |= QUEUE_STATUS_READY; + return nStatus; +} + +// ----------------------------------------------------------------------- + +void SalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList ) +{ +// !!! UNICODE - NT Optimierung !!! + DWORD i; + DWORD n; + DWORD nBytes = 0; +// DWORD nInfoRet; + DWORD nInfoPrn2; + BOOL bFound = FALSE; + PRINTER_INFO_2* pWinInfo2 = NULL; + PRINTER_INFO_2* pGetInfo2; + EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &nBytes, &nInfoPrn2 ); + if ( nBytes ) + { + pWinInfo2 = (PRINTER_INFO_2*)new BYTE[nBytes]; + if ( EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pWinInfo2, nBytes, &nBytes, &nInfoPrn2 ) ) + { + pGetInfo2 = pWinInfo2; + for ( i = 0; i < nInfoPrn2; i++ ) + { + SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo; + pInfo->maPrinterName = ImplSalGetUniString( pGetInfo2->pPrinterName ); + pInfo->maDriver = ImplSalGetUniString( pGetInfo2->pDriverName ); + XubString aPortName; + if ( pGetInfo2->pPortName ) + aPortName = ImplSalGetUniString( pGetInfo2->pPortName ); + // pLocation can be 0 (the Windows docu doesn't describe this) + if ( pGetInfo2->pLocation && strlen( pGetInfo2->pLocation ) ) + pInfo->maLocation = ImplSalGetUniString( pGetInfo2->pLocation ); + else + pInfo->maLocation = aPortName; + // pComment can be 0 (the Windows docu doesn't describe this) + if ( pGetInfo2->pComment ) + pInfo->maComment = ImplSalGetUniString( pGetInfo2->pComment ); + pInfo->mnStatus = ImplWinQueueStatusToSal( pGetInfo2->Status ); + pInfo->mnJobs = pGetInfo2->cJobs; + pInfo->mpSysData = new XubString( aPortName ); + pList->Add( pInfo ); + pGetInfo2++; + } + + bFound = TRUE; + } + } + +/* Siehe Kommentar unten !!! + EnumPrinters( PRINTER_ENUM_NETWORK | PRINTER_ENUM_REMOTE, NULL, 1, NULL, 0, &nBytes, &nInfoRet ); + if ( nBytes ) + { + PRINTER_INFO_1* pWinInfo1 = (PRINTER_INFO_1*)new BYTE[nBytes]; + if ( EnumPrinters( PRINTER_ENUM_NETWORK | PRINTER_ENUM_REMOTE, NULL, 1, (LPBYTE)pWinInfo1, nBytes, &nBytes, &nInfoRet ) ) + { + PRINTER_INFO_1* pGetInfo1 = pWinInfo1; + for ( i = 0; i < nInfoRet; i++ ) + { + // Feststellen, ob Printer durch erste Abfrage schon gefunden + // wurde + BOOL bAdd = TRUE; + if ( pWinInfo2 ) + { + pGetInfo2 = pWinInfo2; + for ( n = 0; n < nInfoPrn2; n++ ) + { + if ( strcmp( pGetInfo1->pName, pGetInfo2->pPrinterName ) == 0 ) + { + bAdd = FALSE; + break; + } + pGetInfo2++; + } + } + // Wenn neuer Printer, dann aufnehmen + if ( bAdd ) + { + SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo; + XubString aPrnName( pGetInfo1->pName ); + pInfo->maPrinterName = aPrnName; + pInfo->maDriver = "winspool"; + pInfo->maComment = pGetInfo1->pComment; + pInfo->mnStatus = 0; + pInfo->mnJobs = QUEUE_JOBS_DONTKNOW; + pInfo->mpSysData = new String(); + pList->Add( pInfo ); + } + pGetInfo1++; + } + + bFound = TRUE; + } + + delete pWinInfo1; + } +*/ + +// if ( bFound ) +// return; + +// !!! UNICODE - NT Optimierung !!! + // Drucker aus WIN.INI lesen + UINT nSize = 4096; + char* pBuf = new char[nSize]; + UINT nRead = GetProfileStringA( aImplDevices, NULL, "", pBuf, nSize ); + while ( nRead >= nSize-2 ) + { + nSize += 2048; + delete pBuf; + pBuf = new char[nSize]; + nRead = GetProfileStringA( aImplDevices, NULL, "", pBuf, nSize ); + } + + // Druckernamen aus Buffer extrahieren und Liste aufbauen + char* pName = pBuf; + while ( *pName ) + { + char* pPortName; + char* pTmp; + char aPortBuf[256]; + GetProfileStringA( aImplDevices, pName, "", aPortBuf, sizeof( aPortBuf ) ); + + pPortName = aPortBuf; + + // Namen anlegen + xub_StrLen nNameLen = strlen( pName ); + XubString aName( ImplSalGetUniString( pName, nNameLen ) ); + + // Treibernamen rausfischen + pTmp = pPortName; + while ( *pTmp != ',' ) + pTmp++; + XubString aDriver( ImplSalGetUniString( pPortName, (USHORT)(pTmp-pPortName) ) ); + pPortName = pTmp; + + // Alle Portnamen raussuchen + do + { + pPortName++; + pTmp = pPortName; + while ( *pTmp && (*pTmp != ',') ) + pTmp++; + + String aPortName( ImplSalGetUniString( pPortName, (USHORT)(pTmp-pPortName) ) ); + + // Neuen Eintrag anlegen + // !!! Da ich zu bloeb bin, die Netzwerk-Printer zur 5.0 + // !!! richtig zu integrieren, gehen wir zusaetzlich + // !!! noch ueber das W16-Interface, da uns dort die + // !!! Drucker noch einfach und schnell geliefert werden + // !!! ohne das wir jetzt zu grossen Aufwand treiben muessen. + // !!! Somit sollten wir dann jedenfalls nicht schlechter sein + // !!! als in einer 4.0 SP2. + // Feststellen, ob Printer durch erste Abfrage schon gefunden + // wurde + BOOL bAdd = TRUE; + if ( pWinInfo2 ) + { + pGetInfo2 = pWinInfo2; + for ( n = 0; n < nInfoPrn2; n++ ) + { + if ( aName.EqualsIgnoreCaseAscii( pGetInfo2->pPrinterName ) ) + { + bAdd = FALSE; + break; + } + pGetInfo2++; + } + } + // Wenn neuer Printer, dann aufnehmen + if ( bAdd ) + { + SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo; + pInfo->maPrinterName = aName; + pInfo->maDriver = aDriver; + pInfo->maLocation = aPortName; + pInfo->mnStatus = 0; + pInfo->mnJobs = QUEUE_JOBS_DONTKNOW; + pInfo->mpSysData = new XubString( aPortName ); + pList->Add( pInfo ); + } + } + while ( *pTmp == ',' ); + + pName += nNameLen + 1; + } + + delete pBuf; + delete pWinInfo2; +} + +// ----------------------------------------------------------------------- + +void SalInstance::GetPrinterQueueState( SalPrinterQueueInfo* pInfo ) +{ +// !!! UNICODE - NT Optimierung !!! + DWORD nBytes = 0; + DWORD nInfoRet; + PRINTER_INFO_2* pWinInfo2; + EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &nBytes, &nInfoRet ); + if ( nBytes ) + { + pWinInfo2 = (PRINTER_INFO_2*)new BYTE[nBytes]; + if ( EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pWinInfo2, nBytes, &nBytes, &nInfoRet ) ) + { + PRINTER_INFO_2* pGetInfo2 = pWinInfo2; + for ( DWORD i = 0; i < nInfoRet; i++ ) + { + if ( pInfo->maPrinterName.EqualsAscii( pGetInfo2->pPrinterName ) && + pInfo->maDriver.EqualsAscii( pGetInfo2->pDriverName ) ) + { + if ( pGetInfo2->pLocation && strlen( pGetInfo2->pLocation ) ) + pInfo->maLocation = ImplSalGetUniString( pGetInfo2->pLocation ); + else + pInfo->maLocation = ImplSalGetUniString( pGetInfo2->pPortName ); + pInfo->mnStatus = ImplWinQueueStatusToSal( pGetInfo2->Status ); + pInfo->mnJobs = pGetInfo2->cJobs; + break; + } + + pGetInfo2++; + } + } + + delete pWinInfo2; + } +} + +// ----------------------------------------------------------------------- + +void SalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo ) +{ + delete (String*)(pInfo->mpSysData); + delete pInfo; +} + +// ----------------------------------------------------------------------- + +// !!! UNICODE - NT Optimierung !!! +XubString SalInstance::GetDefaultPrinter() +{ + // Default-Printer-String aus win.ini holen + char szBuffer[256]; + GetProfileStringA( aImplWindows, aImplDevice, "", szBuffer, sizeof( szBuffer ) ); + if ( szBuffer[0] ) + { + // Printername suchen + char* pBuf = szBuffer; + char* pTmp = pBuf; + while ( *pTmp && (*pTmp != ',') ) + pTmp++; + return ImplSalGetUniString( pBuf, (xub_StrLen)(pTmp-pBuf) ); + } + else + return XubString(); +} + +// ======================================================================= + +static DWORD ImplDeviceCaps( SalInfoPrinter* pPrinter, WORD nCaps, + LPTSTR pOutput, const ImplJobSetup* pSetupData ) +{ + DEVMODE* pDevMode; + if ( !pSetupData || !pSetupData->mpDriverData ) + pDevMode = NULL; + else + pDevMode = SAL_DEVMODE( pSetupData ); + +// !!! UNICODE - NT Optimierung !!! + return DeviceCapabilitiesA( ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(), + ImplSalGetWinAnsiString( pPrinter->maPrinterData.maPortName, TRUE ).GetBuffer(), + nCaps, (LPSTR)pOutput, pDevMode ); +} + +// ----------------------------------------------------------------------- + +static BOOL ImplTestSalJobSetup( SalInfoPrinter* pPrinter, + ImplJobSetup* pSetupData, BOOL bDelete ) +{ + if ( pSetupData && pSetupData->mpDriverData ) + { + // Signature und Groesse muss uebereinstimmen, damit wir keine + // JobSetup's von anderen Systemen setzen + if ( (pSetupData->mnSystem == JOBSETUP_SYSTEM_WINDOWS) && + (pSetupData->mnDriverDataLen > sizeof( SalDriverData )) && + (((SalDriverData*)(pSetupData->mpDriverData))->mnSysSignature == SAL_DRIVERDATA_SYSSIGN) ) + return TRUE; + else if ( bDelete ) + { + delete pSetupData->mpDriverData; + pSetupData->mpDriverData = NULL; + pSetupData->mnDriverDataLen = 0; + } + } + + return FALSE; +} + +// ----------------------------------------------------------------------- + +static BOOL ImplUpdateSalJobSetup( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData, + BOOL bIn, SalFrame* pVisibleDlgParent ) +{ + HANDLE hPrn; +// !!! UNICODE - NT Optimierung !!! + if ( !OpenPrinterA( (LPSTR)ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(), &hPrn, NULL ) ) + return FALSE; + + LONG nRet; + LONG nSysJobSize; + HWND hWnd = 0; + DWORD nMode = DM_OUT_BUFFER; + ULONG nDriverDataLen = 0; + SalDriverData* pOutBuffer = NULL; + DEVMODE* pInDevBuffer = NULL; + DEVMODE* pOutDevBuffer = NULL; + +// !!! UNICODE - NT Optimierung !!! + nSysJobSize = DocumentPropertiesA( hWnd, hPrn, + (LPSTR)ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(), + NULL, NULL, 0 ); + if ( nSysJobSize < 0 ) + { + ClosePrinter( hPrn ); + return FALSE; + } + + // Outputbuffer anlegen + nDriverDataLen = sizeof(SalDriverData)+nSysJobSize-1; + pOutBuffer = (SalDriverData*)SvMemAlloc( nDriverDataLen ); + memset( pOutBuffer, 0, nDriverDataLen ); + pOutDevBuffer = (LPDEVMODE)(pOutBuffer->maDriverData); + pOutBuffer->mnSysSignature = SAL_DRIVERDATA_SYSSIGN; + pOutBuffer->mnVersion = SAL_DRIVERDATA_VERSION; + pOutBuffer->mnDriverOffset = (USHORT)(((SalDriverData*)NULL)->maDriverData); + + // Testen, ob wir einen geeigneten Inputbuffer haben + if ( bIn && ImplTestSalJobSetup( pPrinter, pSetupData, FALSE ) ) + { + pInDevBuffer = SAL_DEVMODE( pSetupData ); + nMode |= DM_IN_BUFFER; + } + + // Testen, ob Dialog angezeigt werden soll + if ( pVisibleDlgParent ) + { + hWnd = pVisibleDlgParent->maFrameData.mhWnd; + nMode |= DM_IN_PROMPT; + } + +// !!! UNICODE - NT Optimierung !!! + // Release mutex, in the other case we don't get paints and so on + ULONG nMutexCount = ImplSalReleaseYieldMutex(); + nRet = DocumentPropertiesA( hWnd, hPrn, + (LPSTR)ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(), + pOutDevBuffer, pInDevBuffer, nMode ); + ImplSalAcquireYieldMutex( nMutexCount ); + ClosePrinter( hPrn ); + + if ( (nRet < 0) || (pVisibleDlgParent && (nRet == IDCANCEL)) ) + { + SvMemFree( pOutBuffer ); + return FALSE; + } + + // String-Buffer am Ende immer mit 0 initialisieren, damit + // die JobSetups nach Moeglichkeit bei memcmp immer + // identisch sind + if ( pOutDevBuffer->dmSize >= 32 ) + { + USHORT nLen = strlen( (const char*)pOutDevBuffer->dmDeviceName ); + if ( nLen < sizeof( pOutDevBuffer->dmDeviceName ) ) + memset( pOutDevBuffer->dmDeviceName+nLen, 0, sizeof( pOutDevBuffer->dmDeviceName )-nLen ); + } + if ( pOutDevBuffer->dmSize >= 102 ) + { + USHORT nLen = strlen( (const char*)pOutDevBuffer->dmFormName ); + if ( nLen < sizeof( pOutDevBuffer->dmFormName ) ) + memset( pOutDevBuffer->dmFormName+nLen, 0, sizeof( pOutDevBuffer->dmFormName )-nLen ); + } + + // Daten updaten + if ( pSetupData->mpDriverData ) + delete pSetupData->mpDriverData; + pSetupData->mnDriverDataLen = nDriverDataLen; + pSetupData->mpDriverData = (BYTE*)pOutBuffer; + pSetupData->mnSystem = JOBSETUP_SYSTEM_WINDOWS; + + return TRUE; +} + +// ----------------------------------------------------------------------- + +static void ImplDevModeToJobSetup( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData, ULONG nFlags ) +{ + if ( !pSetupData || !pSetupData->mpDriverData ) + return; + + DEVMODE* pDevMode = SAL_DEVMODE( pSetupData ); + + // Orientation + if ( nFlags & SAL_JOBSET_ORIENTATION ) + { + if ( pDevMode->dmOrientation == DMORIENT_PORTRAIT ) + pSetupData->meOrientation = ORIENTATION_PORTRAIT; + else if ( pDevMode->dmOrientation == DMORIENT_LANDSCAPE ) + pSetupData->meOrientation = ORIENTATION_LANDSCAPE; + } + + // PaperBin + if ( nFlags & SAL_JOBSET_PAPERBIN ) + { + ULONG nCount = ImplDeviceCaps( pPrinter, DC_BINS, NULL, pSetupData ); + + if ( nCount && (nCount != ((ULONG)-1)) ) + { + WORD* pBins = new WORD[nCount]; + memset( (BYTE*)pBins, 0, nCount*sizeof(WORD) ); + ImplDeviceCaps( pPrinter, DC_BINS, (LPTSTR)pBins, pSetupData ); + pSetupData->mnPaperBin = 0; + + // search the right bin and assign index to mnPaperBin + for( ULONG i = 0; i < nCount; i++ ) + { + if( pDevMode->dmDefaultSource == pBins[ i ] ) + { + pSetupData->mnPaperBin = (USHORT)i; + break; + } + } + + delete[] pBins; + } + } + + // PaperSize + if ( nFlags & SAL_JOBSET_PAPERSIZE ) + { + pSetupData->mnPaperWidth = pDevMode->dmPaperWidth*10; + pSetupData->mnPaperHeight = pDevMode->dmPaperLength*10; + switch( pDevMode->dmPaperSize ) + { + case( DMPAPER_A3 ): + pSetupData->mePaperFormat = PAPER_A3; + break; + case( DMPAPER_A4 ): + pSetupData->mePaperFormat = PAPER_A4; + break; + case( DMPAPER_A5 ): + pSetupData->mePaperFormat = PAPER_A5; + break; + case( DMPAPER_B4 ): + pSetupData->mePaperFormat = PAPER_B4; + break; + case( DMPAPER_B5 ): + pSetupData->mePaperFormat = PAPER_B5; + break; + case( DMPAPER_LETTER ): + pSetupData->mePaperFormat = PAPER_LETTER; + break; + case( DMPAPER_LEGAL ): + pSetupData->mePaperFormat = PAPER_LEGAL; + break; + case( DMPAPER_TABLOID ): + pSetupData->mePaperFormat = PAPER_TABLOID; + break; + default: + pSetupData->mePaperFormat = PAPER_USER; + break; + } + } +} + +// ----------------------------------------------------------------------- + +static BOOL ImplPaperSizeEqual( short nPaperWidth1, short nPaperHeight1, + short nPaperWidth2, short nPaperHeight2 ) +{ + return (((nPaperWidth1 >= nPaperWidth2-1) && (nPaperWidth1 <= nPaperWidth2+1)) && + ((nPaperHeight1 >= nPaperHeight2-1) && (nPaperHeight1 <= nPaperHeight2+1))); +} + +// ----------------------------------------------------------------------- + +static void ImplJobSetupToDevMode( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData, ULONG nFlags ) +{ + if ( !pSetupData || !pSetupData->mpDriverData ) + return; + + DEVMODE* pDevMode = SAL_DEVMODE( pSetupData ); + + // Orientation + if ( nFlags & SAL_JOBSET_ORIENTATION ) + { + pDevMode->dmFields |= DM_ORIENTATION; + if ( pSetupData->meOrientation == ORIENTATION_PORTRAIT ) + pDevMode->dmOrientation = DMORIENT_PORTRAIT; + else + pDevMode->dmOrientation = DMORIENT_LANDSCAPE; + } + + // PaperBin + if ( nFlags & SAL_JOBSET_PAPERBIN ) + { + ULONG nCount = ImplDeviceCaps( pPrinter, DC_BINS, NULL, pSetupData ); + + if ( nCount && (nCount != ((ULONG)-1)) ) + { + WORD* pBins = new WORD[nCount]; + memset( pBins, 0, nCount*sizeof(WORD) ); + ImplDeviceCaps( pPrinter, DC_BINS, (LPTSTR)pBins, pSetupData ); + pDevMode->dmFields |= DM_DEFAULTSOURCE; + pDevMode->dmDefaultSource = pBins[ pSetupData->mnPaperBin ]; + delete[] pBins; + } + } + + // PaperSize + if ( nFlags & SAL_JOBSET_PAPERSIZE ) + { + pDevMode->dmFields |= DM_PAPERSIZE; + pDevMode->dmPaperWidth = 0; + pDevMode->dmPaperLength = 0; + + switch( pDevMode->dmPaperSize ) + { + case( PAPER_A3 ): + pDevMode->dmPaperSize = DMPAPER_A3; + break; + case( PAPER_A4 ): + pDevMode->dmPaperSize = DMPAPER_A4; + break; + case( PAPER_A5 ): + pDevMode->dmPaperSize = DMPAPER_A5; + break; + case( PAPER_B4 ): + pDevMode->dmPaperSize = DMPAPER_B4; + break; + case( PAPER_B5 ): + pDevMode->dmPaperSize = DMPAPER_B5; + break; + case( PAPER_LETTER ): + pDevMode->dmPaperSize = DMPAPER_LETTER; + break; + case( PAPER_LEGAL ): + pDevMode->dmPaperSize = DMPAPER_LEGAL; + break; + case( PAPER_TABLOID ): + pDevMode->dmPaperSize = DMPAPER_TABLOID; + break; + default: + { + short nPaper = 0; + ULONG nPaperCount = ImplDeviceCaps( pPrinter, DC_PAPERS, NULL, pSetupData ); + WORD* pPapers = NULL; + ULONG nPaperSizeCount = ImplDeviceCaps( pPrinter, DC_PAPERSIZE, NULL, pSetupData ); + POINT* pPaperSizes = NULL; + if ( nPaperCount && (nPaperCount != ((ULONG)-1)) ) + { + pPapers = new WORD[nPaperCount]; + memset( pPapers, 0, nPaperCount*sizeof(WORD) ); + ImplDeviceCaps( pPrinter, DC_PAPERS, (LPTSTR)pPapers, pSetupData ); + } + if ( nPaperSizeCount && (nPaperSizeCount != ((ULONG)-1)) ) + { + pPaperSizes = new POINT[nPaperSizeCount]; + memset( pPaperSizes, 0, nPaperSizeCount*sizeof(POINT) ); + ImplDeviceCaps( pPrinter, DC_PAPERSIZE, (LPTSTR)pPaperSizes, pSetupData ); + } + if ( (nPaperSizeCount == nPaperCount) && pPapers && pPaperSizes ) + { + // Alle Papierformate vergleichen und ein passendes + // raussuchen + for ( ULONG i = 0; i < nPaperCount; i++ ) + { + if ( ImplPaperSizeEqual( (short)(pSetupData->mnPaperWidth/10), + (short)(pSetupData->mnPaperHeight/10), + (short)pPaperSizes[i].x, + (short)pPaperSizes[i].y ) ) + { + nPaper = pPapers[i]; + break; + } + } + } + if ( pPapers ) + delete pPapers; + if ( pPaperSizes ) + delete pPaperSizes; + + if ( nPaper ) + pDevMode->dmPaperSize = nPaper; + else + { + pDevMode->dmFields |= DM_PAPERLENGTH | DM_PAPERWIDTH; + pDevMode->dmPaperSize = DMPAPER_USER; + pDevMode->dmPaperWidth = pSetupData->mnPaperWidth/10; + pDevMode->dmPaperLength = pSetupData->mnPaperHeight/10; + } + } + break; + } + } +} + +// ----------------------------------------------------------------------- + +static HDC ImplCreateSalPrnIC( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData ) +{ + LPDEVMODE pDevMode; + if ( pSetupData && pSetupData->mpDriverData ) + pDevMode = SAL_DEVMODE( pSetupData ); + else + pDevMode = NULL; +// !!! UNICODE - NT Optimierung !!! + HDC hDC = CreateICA( ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDriverName, TRUE ).GetBuffer(), + ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(), + 0, + (LPDEVMODE)pDevMode ); + return hDC; +} + +// ----------------------------------------------------------------------- + +static SalGraphics* ImplCreateSalPrnGraphics( HDC hDC ) +{ + SalGraphics* pGraphics = new SalGraphics; + pGraphics->maGraphicsData.mhDC = hDC; + pGraphics->maGraphicsData.mhWnd = 0; + pGraphics->maGraphicsData.mbPrinter = TRUE; + pGraphics->maGraphicsData.mbVirDev = FALSE; + pGraphics->maGraphicsData.mbWindow = FALSE; + pGraphics->maGraphicsData.mbScreen = FALSE; + ImplSalInitGraphics( &(pGraphics->maGraphicsData) ); + return pGraphics; +} + +// ----------------------------------------------------------------------- + +static BOOL ImplUpdateSalPrnIC( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData ) +{ + HDC hNewDC = ImplCreateSalPrnIC( pPrinter, pSetupData ); + if ( !hNewDC ) + return FALSE; + + if ( pPrinter->maPrinterData.mpGraphics ) + { + ImplSalDeInitGraphics( &(pPrinter->maPrinterData.mpGraphics->maGraphicsData) ); + DeleteDC( pPrinter->maPrinterData.mpGraphics->maGraphicsData.mhDC ); + delete pPrinter->maPrinterData.mpGraphics; + } + + SalGraphics* pGraphics = ImplCreateSalPrnGraphics( hNewDC ); + pPrinter->maPrinterData.mhDC = hNewDC; + pPrinter->maPrinterData.mpGraphics = pGraphics; + + return TRUE; +} + +// ======================================================================= + +SalInfoPrinter* SalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo, + ImplJobSetup* pSetupData ) +{ + SalInfoPrinter* pPrinter = new SalInfoPrinter; + pPrinter->maPrinterData.maDriverName = pQueueInfo->maDriver; + pPrinter->maPrinterData.maDeviceName = pQueueInfo->maPrinterName; + pPrinter->maPrinterData.maPortName = *(String*)(pQueueInfo->mpSysData); + + // Testen, ob Setupdaten zum Drucker gehoeren (erst aufrufen, nachdem + // die Member gesetzt sind, da diese in dieser Routine abgefragt werden) + ImplTestSalJobSetup( pPrinter, pSetupData, TRUE ); + + HDC hDC = ImplCreateSalPrnIC( pPrinter, pSetupData ); + if ( !hDC ) + { + delete pPrinter; + return NULL; + } + + SalGraphics* pGraphics = ImplCreateSalPrnGraphics( hDC ); + pPrinter->maPrinterData.mhDC = hDC; + pPrinter->maPrinterData.mpGraphics = pGraphics; + if ( !pSetupData->mpDriverData ) + ImplUpdateSalJobSetup( pPrinter, pSetupData, FALSE, NULL ); + ImplDevModeToJobSetup( pPrinter, pSetupData, SAL_JOBSET_ALL ); + pSetupData->mnSystem = JOBSETUP_SYSTEM_WINDOWS; + + return pPrinter; +} + +// ----------------------------------------------------------------------- + +void SalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter ) +{ + delete pPrinter; +} + +// ======================================================================= + +SalInfoPrinter::SalInfoPrinter() +{ + maPrinterData.mhDC = 0; + maPrinterData.mpGraphics = NULL; + maPrinterData.mbGraphics = FALSE; +} + +// ----------------------------------------------------------------------- + +SalInfoPrinter::~SalInfoPrinter() +{ + if ( maPrinterData.mpGraphics ) + { + ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) ); + DeleteDC( maPrinterData.mpGraphics->maGraphicsData.mhDC ); + delete maPrinterData.mpGraphics; + } +} + +// ----------------------------------------------------------------------- + +SalGraphics* SalInfoPrinter::GetGraphics() +{ + if ( maPrinterData.mbGraphics ) + return NULL; + + if ( maPrinterData.mpGraphics ) + maPrinterData.mbGraphics = TRUE; + + return maPrinterData.mpGraphics; +} + +// ----------------------------------------------------------------------- + +void SalInfoPrinter::ReleaseGraphics( SalGraphics* ) +{ + maPrinterData.mbGraphics = FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL SalInfoPrinter::Setup( SalFrame* pFrame, ImplJobSetup* pSetupData ) +{ + if ( ImplUpdateSalJobSetup( this, pSetupData, TRUE, pFrame ) ) + { + ImplDevModeToJobSetup( this, pSetupData, SAL_JOBSET_ALL ); + return ImplUpdateSalPrnIC( this, pSetupData ); + } + + return FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL SalInfoPrinter::SetPrinterData( ImplJobSetup* pSetupData ) +{ + if ( !ImplTestSalJobSetup( this, pSetupData, FALSE ) ) + return FALSE; + return ImplUpdateSalPrnIC( this, pSetupData ); +} + +// ----------------------------------------------------------------------- + +BOOL SalInfoPrinter::SetData( ULONG nFlags, ImplJobSetup* pSetupData ) +{ + ImplJobSetupToDevMode( this, pSetupData, nFlags ); + if ( ImplUpdateSalJobSetup( this, pSetupData, TRUE, NULL ) ) + { + ImplDevModeToJobSetup( this, pSetupData, nFlags ); + return ImplUpdateSalPrnIC( this, pSetupData ); + } + + return FALSE; +} + +// ----------------------------------------------------------------------- + +ULONG SalInfoPrinter::GetPaperBinCount( const ImplJobSetup* pSetupData ) +{ + DWORD nRet = ImplDeviceCaps( this, DC_BINS, NULL, pSetupData ); + if ( nRet && (nRet != ((ULONG)-1)) ) + return nRet; + else + return 0; +} + +// ----------------------------------------------------------------------- + +XubString SalInfoPrinter::GetPaperBinName( const ImplJobSetup* pSetupData, ULONG nPaperBin ) +{ +// !!! UNICODE - NT Optimierung !!! + XubString aPaperBinName; + + DWORD nBins = ImplDeviceCaps( this, DC_BINNAMES, NULL, pSetupData ); + if ( (nPaperBin < nBins) && (nBins != ((ULONG)-1)) ) + { + char* pBuffer = new char[nBins*24]; + DWORD nRet = ImplDeviceCaps( this, DC_BINNAMES, pBuffer, pSetupData ); + if ( nRet && (nRet != ((ULONG)-1)) ) + aPaperBinName = ImplSalGetUniString( (const char*)(pBuffer + (nPaperBin*24)) ); + delete pBuffer; + } + + return aPaperBinName; +} + +// ----------------------------------------------------------------------- + +ULONG SalInfoPrinter::GetCapabilities( const ImplJobSetup* pSetupData, USHORT nType ) +{ + DWORD nRet; + + switch ( nType ) + { + case PRINTER_CAPABILITIES_SUPPORTDIALOG: + return TRUE; + case PRINTER_CAPABILITIES_COPIES: + nRet = ImplDeviceCaps( this, DC_COPIES, NULL, pSetupData ); + if ( nRet && (nRet != ((ULONG)-1)) ) + return nRet; + return 0; + case PRINTER_CAPABILITIES_COLLATECOPIES: + if ( aSalShlData.mbW40 ) + { + nRet = ImplDeviceCaps( this, DC_COLLATE, NULL, pSetupData ); + if ( nRet && (nRet != ((ULONG)-1)) ) + { + nRet = ImplDeviceCaps( this, DC_COPIES, NULL, pSetupData ); + if ( nRet && (nRet != ((ULONG)-1)) ) + return nRet; + } + } + return 0; + + case PRINTER_CAPABILITIES_SETORIENTATION: + nRet = ImplDeviceCaps( this, DC_ORIENTATION, NULL, pSetupData ); + if ( nRet && (nRet != ((ULONG)-1)) ) + return TRUE; + return FALSE; + + case PRINTER_CAPABILITIES_SETPAPERBIN: + nRet = ImplDeviceCaps( this, DC_BINS, NULL, pSetupData ); + if ( nRet && (nRet != ((ULONG)-1)) ) + return TRUE; + return FALSE; + + case PRINTER_CAPABILITIES_SETPAPERSIZE: + case PRINTER_CAPABILITIES_SETPAPER: + nRet = ImplDeviceCaps( this, DC_PAPERS, NULL, pSetupData ); + if ( nRet && (nRet != ((ULONG)-1)) ) + return TRUE; + return FALSE; + } + + return 0; +} + +// ----------------------------------------------------------------------- + +void SalInfoPrinter::GetPageInfo( const ImplJobSetup*, + long& rOutWidth, long& rOutHeight, + long& rPageOffX, long& rPageOffY, + long& rPageWidth, long& rPageHeight ) +{ + HDC hDC = maPrinterData.mhDC; + + rOutWidth = GetDeviceCaps( hDC, HORZRES ); + rOutHeight = GetDeviceCaps( hDC, VERTRES ); + + rPageOffX = GetDeviceCaps( hDC, PHYSICALOFFSETX ); + rPageOffY = GetDeviceCaps( hDC, PHYSICALOFFSETY ); + rPageWidth = GetDeviceCaps( hDC, PHYSICALWIDTH ); + rPageHeight = GetDeviceCaps( hDC, PHYSICALHEIGHT ); +} + +// ======================================================================= + +SalPrinter* SalInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter ) +{ + SalPrinter* pPrinter = new SalPrinter; + pPrinter->maPrinterData.mpInfoPrinter = pInfoPrinter; + return pPrinter; +} + +// ----------------------------------------------------------------------- + +void SalInstance::DestroyPrinter( SalPrinter* pPrinter ) +{ + delete pPrinter; +} + +// ======================================================================= + +WIN_BOOL CALLBACK SalPrintAbortProc( HDC hPrnDC, int /* nError */ ) +{ + SalData* pSalData = GetSalData(); + SalPrinter* pPrinter; + BOOL bWhile = TRUE; + int i = 0; + + do + { + // Messages verarbeiten + MSG aMsg; + if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) ) + { + TranslateMessage( &aMsg ); + ImplDispatchMessage( &aMsg ); + i++; + if ( i > 15 ) + bWhile = FALSE; + } + else + bWhile = FALSE; + + pPrinter = pSalData->mpFirstPrinter; + while ( pPrinter ) + { + if( pPrinter->maPrinterData.mhDC == hPrnDC ) + break; + + pPrinter = pPrinter->maPrinterData.mpNextPrinter; + } + + if ( !pPrinter || pPrinter->maPrinterData.mbAbort ) + return FALSE; + } + while ( bWhile ); + + return TRUE; +} + +// ----------------------------------------------------------------------- + +static LPDEVMODE ImplSalSetCopies( LPDEVMODE pDevMode, ULONG nCopies, BOOL bCollate ) +{ + LPDEVMODE pNewDevMode = pDevMode; + if ( pDevMode && (nCopies > 1) ) + { + if ( nCopies > 32765 ) + nCopies = 32765; + ULONG nDevSize = pDevMode->dmSize+pDevMode->dmDriverExtra; + pNewDevMode = (LPDEVMODE)new BYTE[nDevSize]; + memcpy( pNewDevMode, pDevMode, nDevSize ); + pDevMode = pNewDevMode; + pDevMode->dmFields |= DM_COPIES; + pDevMode->dmCopies = (short)(USHORT)nCopies; + if ( aSalShlData.mbW40 ) + { + pDevMode->dmFields |= DM_COLLATE; + if ( bCollate ) + pDevMode->dmCollate = DMCOLLATE_TRUE; + else + pDevMode->dmCollate = DMCOLLATE_FALSE; + } + } + + return pNewDevMode; +} + +// ----------------------------------------------------------------------- + +SalPrinter::SalPrinter() +{ + SalData* pSalData = GetSalData(); + + maPrinterData.mhDC = 0; + maPrinterData.mpGraphics = NULL; + maPrinterData.mbAbort = FALSE; + maPrinterData.mnCopies = 0; + maPrinterData.mbCollate = FALSE; + + // insert frame in framelist + maPrinterData.mpNextPrinter = pSalData->mpFirstPrinter; + pSalData->mpFirstPrinter = this; +} + +// ----------------------------------------------------------------------- + +SalPrinter::~SalPrinter() +{ + SalData* pSalData = GetSalData(); + + // DC freigeben, wenn er noch durch ein AbortJob existiert + HDC hDC = maPrinterData.mhDC; + if ( hDC ) + { + if ( maPrinterData.mpGraphics ) + { + ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) ); + delete maPrinterData.mpGraphics; + } + + DeleteDC( hDC ); + } + + // remove printer from printerlist + if ( this == pSalData->mpFirstPrinter ) + pSalData->mpFirstPrinter = maPrinterData.mpNextPrinter; + else + { + SalPrinter* pTempPrinter = pSalData->mpFirstPrinter; + + while( pTempPrinter->maPrinterData.mpNextPrinter != this ) + pTempPrinter = pTempPrinter->maPrinterData.mpNextPrinter; + + pTempPrinter->maPrinterData.mpNextPrinter = maPrinterData.mpNextPrinter; + } +} + +// ----------------------------------------------------------------------- + +BOOL SalPrinter::StartJob( const XubString* pFileName, + const XubString& rJobName, + const XubString&, + ULONG nCopies, BOOL bCollate, + ImplJobSetup* pSetupData ) +{ + maPrinterData.mnError = 0; + maPrinterData.mbAbort = FALSE; + maPrinterData.mnCopies = nCopies; + maPrinterData.mbCollate = bCollate; + + LPDEVMODE pOrgDevMode = NULL; + LPDEVMODE pDevMode; + BOOL bOwnDevMode = FALSE; + if ( pSetupData && pSetupData->mpDriverData ) + { + pOrgDevMode = SAL_DEVMODE( pSetupData ); + pDevMode = ImplSalSetCopies( pOrgDevMode, nCopies, bCollate ); + } + else + pDevMode = NULL; + +// !!! UNICODE - NT Optimierung !!! + HDC hDC = CreateDCA( ImplSalGetWinAnsiString( maPrinterData.mpInfoPrinter->maPrinterData.maDriverName, TRUE ).GetBuffer(), + ImplSalGetWinAnsiString( maPrinterData.mpInfoPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(), + 0, + (LPDEVMODEA)pDevMode ); + + if ( pDevMode != pOrgDevMode ) + delete pDevMode; + + if ( !hDC ) + { + maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR; + return FALSE; + } + + if ( SetAbortProc( hDC, SalPrintAbortProc ) <= 0 ) + { + maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR; + return FALSE; + } + + maPrinterData.mnError = 0; + maPrinterData.mbAbort = FALSE; + +// !!! UNICODE - NT Optimierung !!! + // Both strings must be exist, if StartJob() is called + ByteString aJobName( ImplSalGetWinAnsiString( rJobName, TRUE ) ); + ByteString aFileName; + + DOCINFO aInfo; + memset( &aInfo, 0, sizeof( DOCINFO ) ); + aInfo.cbSize = sizeof( aInfo ); + aInfo.lpszDocName = (LPCSTR)aJobName.GetBuffer(); + if ( pFileName ) + { + if ( pFileName->Len() ) + { + aFileName = ImplSalGetWinAnsiString( *pFileName, TRUE ); + aInfo.lpszOutput = (LPCSTR)aFileName.GetBuffer(); + } + else + aInfo.lpszOutput = "FILE:"; + } + else + aInfo.lpszOutput = NULL; + + // Wegen Telocom Balloon Fax-Treiber, der uns unsere Messages + // ansonsten oefters schickt, versuchen wir vorher alle + // zu verarbeiten und dann eine Dummy-Message reinstellen + BOOL bWhile = TRUE; + int i = 0; + do + { + // Messages verarbeiten + MSG aMsg; + if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) ) + { + TranslateMessage( &aMsg ); + ImplDispatchMessage( &aMsg ); + i++; + if ( i > 15 ) + bWhile = FALSE; + } + else + bWhile = FALSE; + } + while ( bWhile ); + ImplPostMessage( GetSalData()->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_DUMMY, 0, 0 ); + + // Job starten + int nRet = ::StartDoc( hDC, &aInfo ); + if ( nRet <= 0 ) + { + if ( (nRet == SP_USERABORT) || (nRet == SP_APPABORT) || (GetLastError() == ERROR_PRINT_CANCELLED) ) + maPrinterData.mnError = SAL_PRINTER_ERROR_ABORT; + else + maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR; + return FALSE; + } + + maPrinterData.mhDC = hDC; + return TRUE; +} + +// ----------------------------------------------------------------------- + +BOOL SalPrinter::EndJob() +{ + HDC hDC = maPrinterData.mhDC; + if ( hDC ) + { + if ( maPrinterData.mpGraphics ) + { + ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) ); + delete maPrinterData.mpGraphics; + maPrinterData.mpGraphics = NULL; + } + + ::EndDoc( hDC ); + DeleteDC( hDC ); + } + + return TRUE; +} + +// ----------------------------------------------------------------------- + +BOOL SalPrinter::AbortJob() +{ + maPrinterData.mbAbort = TRUE; + + // Abort asyncron ausloesen + HDC hDC = maPrinterData.mhDC; + if ( hDC ) + { + SalData* pSalData = GetSalData(); + ImplPostMessage( pSalData->mpFirstInstance->maInstData.mhComWnd, + SAL_MSG_PRINTABORTJOB, (WPARAM)hDC, 0 ); + } + + return TRUE; +} + +// ----------------------------------------------------------------------- + +void ImplSalPrinterAbortJobAsync( HDC hPrnDC ) +{ + SalData* pSalData = GetSalData(); + SalPrinter* pPrinter = pSalData->mpFirstPrinter; + + // Feststellen, ob Printer noch existiert + while ( pPrinter ) + { + if ( pPrinter->maPrinterData.mhDC == hPrnDC ) + break; + + pPrinter = pPrinter->maPrinterData.mpNextPrinter; + } + + // Wenn Printer noch existiert, dann den Job abbrechen + if ( pPrinter ) + { + HDC hDC = pPrinter->maPrinterData.mhDC; + if ( hDC ) + { + if ( pPrinter->maPrinterData.mpGraphics ) + { + ImplSalDeInitGraphics( &(pPrinter->maPrinterData.mpGraphics->maGraphicsData) ); + delete pPrinter->maPrinterData.mpGraphics; + pPrinter->maPrinterData.mpGraphics = NULL; + } + + ::AbortDoc( hDC ); + DeleteDC( hDC ); + } + } +} + +// ----------------------------------------------------------------------- + +SalGraphics* SalPrinter::StartPage( ImplJobSetup* pSetupData, BOOL bNewJobData ) +{ + HDC hDC = maPrinterData.mhDC; + if ( pSetupData && pSetupData->mpDriverData && bNewJobData ) + { + LPDEVMODE pOrgDevMode; + LPDEVMODE pDevMode; + pOrgDevMode = SAL_DEVMODE( pSetupData ); + pDevMode = ImplSalSetCopies( pOrgDevMode, maPrinterData.mnCopies, maPrinterData.mbCollate ); + ResetDC( hDC, pDevMode ); + if ( pDevMode != pOrgDevMode ) + delete pDevMode; + } + int nRet = ::StartPage( hDC ); + if ( nRet <= 0 ) + { + maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR; + return NULL; + } + + // Hack, damit alte PS-Treiber Leerseiten nicht wegoptimieren + HPEN hTempPen = SelectPen( hDC, GetStockPen( NULL_PEN ) ); + HBRUSH hTempBrush = SelectBrush( hDC, GetStockBrush( NULL_BRUSH ) ); + WIN_Rectangle( hDC, -8000, -8000, -7999, -7999 ); + SelectPen( hDC, hTempPen ); + SelectBrush( hDC, hTempBrush ); + + SalGraphics* pGraphics = new SalGraphics; + pGraphics->maGraphicsData.mhDC = hDC; + pGraphics->maGraphicsData.mhWnd = 0; + pGraphics->maGraphicsData.mbPrinter = TRUE; + pGraphics->maGraphicsData.mbVirDev = FALSE; + pGraphics->maGraphicsData.mbWindow = FALSE; + pGraphics->maGraphicsData.mbScreen = FALSE; + ImplSalInitGraphics( &(pGraphics->maGraphicsData) ); + maPrinterData.mpGraphics = pGraphics; + return pGraphics; +} + +// ----------------------------------------------------------------------- + +BOOL SalPrinter::EndPage() +{ + HDC hDC = maPrinterData.mhDC; + if ( hDC && maPrinterData.mpGraphics ) + { + ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) ); + delete maPrinterData.mpGraphics; + maPrinterData.mpGraphics = NULL; + } + int nRet = ::EndPage( hDC ); + if ( nRet > 0 ) + return TRUE; + else + { + maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR; + return FALSE; + } +} + +// ----------------------------------------------------------------------- + +ULONG SalPrinter::GetErrorCode() +{ + return maPrinterData.mnError; +} |