xref: /aoo41x/main/vcl/win/source/gdi/salvd.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_vcl.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <tools/svwin.h>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <vcl/sysdata.hxx>
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir #include <win/wincomp.hxx>
36*cdf0e10cSrcweir #include <win/saldata.hxx>
37*cdf0e10cSrcweir #include <win/salinst.h>
38*cdf0e10cSrcweir #include <win/salgdi.h>
39*cdf0e10cSrcweir #include <win/salvd.h>
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir // =======================================================================
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir static HBITMAP ImplCreateVirDevBitmap( HDC hDC, long nDX, long nDY,
44*cdf0e10cSrcweir 									   sal_uInt16 nBitCount )
45*cdf0e10cSrcweir {
46*cdf0e10cSrcweir 	HBITMAP hBitmap;
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir  	if ( nBitCount == 1 )
49*cdf0e10cSrcweir  	{
50*cdf0e10cSrcweir  		hBitmap = CreateBitmap( (int)nDX, (int)nDY, 1, 1, NULL );
51*cdf0e10cSrcweir  	}
52*cdf0e10cSrcweir  	else
53*cdf0e10cSrcweir  	{
54*cdf0e10cSrcweir         // #146839# Don't use CreateCompatibleBitmap() - there seem to
55*cdf0e10cSrcweir         // be build-in limits for those HBITMAPs, at least this fails
56*cdf0e10cSrcweir         // rather often on large displays/multi-monitor setups.
57*cdf0e10cSrcweir  		BITMAPINFO aBitmapInfo;
58*cdf0e10cSrcweir  		aBitmapInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
59*cdf0e10cSrcweir  		aBitmapInfo.bmiHeader.biWidth = nDX;
60*cdf0e10cSrcweir  		aBitmapInfo.bmiHeader.biHeight = nDY;
61*cdf0e10cSrcweir  		aBitmapInfo.bmiHeader.biPlanes = 1;
62*cdf0e10cSrcweir  		aBitmapInfo.bmiHeader.biBitCount = (WORD)GetDeviceCaps( hDC,
63*cdf0e10cSrcweir  														        BITSPIXEL );
64*cdf0e10cSrcweir  		aBitmapInfo.bmiHeader.biCompression = BI_RGB;
65*cdf0e10cSrcweir  		aBitmapInfo.bmiHeader.biSizeImage = 0;
66*cdf0e10cSrcweir  		aBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
67*cdf0e10cSrcweir  		aBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
68*cdf0e10cSrcweir  		aBitmapInfo.bmiHeader.biClrUsed = 0;
69*cdf0e10cSrcweir  		aBitmapInfo.bmiHeader.biClrImportant = 0;
70*cdf0e10cSrcweir 
71*cdf0e10cSrcweir  		void* pDummy;
72*cdf0e10cSrcweir  		hBitmap = CreateDIBSection( hDC, &aBitmapInfo,
73*cdf0e10cSrcweir  									DIB_RGB_COLORS, &pDummy, NULL,
74*cdf0e10cSrcweir  									0 );
75*cdf0e10cSrcweir  	}
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir 	return hBitmap;
78*cdf0e10cSrcweir }
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir // =======================================================================
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics,
83*cdf0e10cSrcweir                                                        long nDX, long nDY,
84*cdf0e10cSrcweir                                                        sal_uInt16 nBitCount,
85*cdf0e10cSrcweir                                                        const SystemGraphicsData* pData )
86*cdf0e10cSrcweir {
87*cdf0e10cSrcweir     WinSalGraphics* pGraphics = static_cast<WinSalGraphics*>(pSGraphics);
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir 	HDC 	hDC = NULL;
90*cdf0e10cSrcweir 	HBITMAP hBmp = NULL;
91*cdf0e10cSrcweir     sal_Bool    bOk = FALSE;
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir     if( pData )
94*cdf0e10cSrcweir     {
95*cdf0e10cSrcweir         hDC = pData->hDC;
96*cdf0e10cSrcweir         hBmp = NULL;
97*cdf0e10cSrcweir         bOk = (hDC != NULL);
98*cdf0e10cSrcweir     }
99*cdf0e10cSrcweir     else
100*cdf0e10cSrcweir     {
101*cdf0e10cSrcweir 	    hDC 	= CreateCompatibleDC( pGraphics->mhDC );
102*cdf0e10cSrcweir         if( !hDC )
103*cdf0e10cSrcweir             ImplWriteLastError( GetLastError(), "CreateCompatibleDC in CreateVirtualDevice" );
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir 	    hBmp	= ImplCreateVirDevBitmap( pGraphics->mhDC,
106*cdf0e10cSrcweir 		                                nDX, nDY, nBitCount );
107*cdf0e10cSrcweir         if( !hBmp )
108*cdf0e10cSrcweir             ImplWriteLastError( GetLastError(), "ImplCreateVirDevBitmap in CreateVirtualDevice" );
109*cdf0e10cSrcweir         // #124826# continue even if hBmp could not be created
110*cdf0e10cSrcweir         // if we would return a failure in this case, the process
111*cdf0e10cSrcweir         // would terminate which is not required
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir         DBG_ASSERT( hBmp, "WinSalInstance::CreateVirtualDevice(), could not create Bitmap!" );
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir         bOk = (hDC != NULL);
116*cdf0e10cSrcweir     }
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir 	if ( bOk )
119*cdf0e10cSrcweir 	{
120*cdf0e10cSrcweir 		WinSalVirtualDevice*	pVDev = new WinSalVirtualDevice;
121*cdf0e10cSrcweir 		SalData*                pSalData = GetSalData();
122*cdf0e10cSrcweir 		WinSalGraphics*         pVirGraphics = new WinSalGraphics;
123*cdf0e10cSrcweir         pVirGraphics->SetLayout( 0 );   // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL()
124*cdf0e10cSrcweir 		pVirGraphics->mhDC	   = hDC;
125*cdf0e10cSrcweir 		pVirGraphics->mhWnd	   = 0;
126*cdf0e10cSrcweir 		pVirGraphics->mbPrinter = FALSE;
127*cdf0e10cSrcweir 		pVirGraphics->mbVirDev  = TRUE;
128*cdf0e10cSrcweir 		pVirGraphics->mbWindow  = FALSE;
129*cdf0e10cSrcweir 		pVirGraphics->mbScreen  = pGraphics->mbScreen;
130*cdf0e10cSrcweir 		if ( pSalData->mhDitherPal && pVirGraphics->mbScreen )
131*cdf0e10cSrcweir 		{
132*cdf0e10cSrcweir 			pVirGraphics->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
133*cdf0e10cSrcweir 			RealizePalette( hDC );
134*cdf0e10cSrcweir 		}
135*cdf0e10cSrcweir 		ImplSalInitGraphics( pVirGraphics );
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir 		pVDev->mhDC		    = hDC;
138*cdf0e10cSrcweir 		pVDev->mhBmp		= hBmp;
139*cdf0e10cSrcweir         if( hBmp )
140*cdf0e10cSrcweir 		    pVDev->mhDefBmp	= SelectBitmap( hDC, hBmp );
141*cdf0e10cSrcweir         else
142*cdf0e10cSrcweir             pVDev->mhDefBmp = NULL;
143*cdf0e10cSrcweir 		pVDev->mpGraphics	= pVirGraphics;
144*cdf0e10cSrcweir 		pVDev->mnBitCount	= nBitCount;
145*cdf0e10cSrcweir 		pVDev->mbGraphics	= FALSE;
146*cdf0e10cSrcweir         pVDev->mbForeignDC  = (pData != NULL);
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir 		// insert VirDev in VirDevList
149*cdf0e10cSrcweir 		pVDev->mpNext = pSalData->mpFirstVD;
150*cdf0e10cSrcweir 		pSalData->mpFirstVD = pVDev;
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir 		return pVDev;
153*cdf0e10cSrcweir 	}
154*cdf0e10cSrcweir 	else
155*cdf0e10cSrcweir 	{
156*cdf0e10cSrcweir 		if ( hDC && !pData )
157*cdf0e10cSrcweir 			DeleteDC( hDC );
158*cdf0e10cSrcweir 		if ( hBmp )
159*cdf0e10cSrcweir 			DeleteBitmap( hBmp );
160*cdf0e10cSrcweir 		return NULL;
161*cdf0e10cSrcweir 	}
162*cdf0e10cSrcweir }
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir // -----------------------------------------------------------------------
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir void WinSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
167*cdf0e10cSrcweir {
168*cdf0e10cSrcweir 	delete pDevice;
169*cdf0e10cSrcweir }
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir // =======================================================================
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir WinSalVirtualDevice::WinSalVirtualDevice()
174*cdf0e10cSrcweir {
175*cdf0e10cSrcweir 	mhDC = (HDC) NULL;			// HDC or 0 for Cache Device
176*cdf0e10cSrcweir 	mhBmp = (HBITMAP) NULL;		// Memory Bitmap
177*cdf0e10cSrcweir 	mhDefBmp = (HBITMAP) NULL;	// Default Bitmap
178*cdf0e10cSrcweir 	mpGraphics = NULL; 			// current VirDev graphics
179*cdf0e10cSrcweir 	mpNext = NULL; 				// next VirDev
180*cdf0e10cSrcweir 	mnBitCount = 0; 			// BitCount (0 or 1)
181*cdf0e10cSrcweir 	mbGraphics = FALSE; 		// is Graphics used
182*cdf0e10cSrcweir     mbForeignDC = FALSE;        // uses a foreign DC instead of a bitmap
183*cdf0e10cSrcweir }
184*cdf0e10cSrcweir 
185*cdf0e10cSrcweir // -----------------------------------------------------------------------
186*cdf0e10cSrcweir 
187*cdf0e10cSrcweir WinSalVirtualDevice::~WinSalVirtualDevice()
188*cdf0e10cSrcweir {
189*cdf0e10cSrcweir     // remove VirDev from list of virtual devices
190*cdf0e10cSrcweir     SalData* pSalData = GetSalData();
191*cdf0e10cSrcweir     WinSalVirtualDevice** ppVirDev = &pSalData->mpFirstVD;
192*cdf0e10cSrcweir     for(; (*ppVirDev != this) && *ppVirDev; ppVirDev = &(*ppVirDev)->mpNext );
193*cdf0e10cSrcweir     if( *ppVirDev )
194*cdf0e10cSrcweir         *ppVirDev = mpNext;
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir     // destroy saved DC
197*cdf0e10cSrcweir     if( mpGraphics->mhDefPal )
198*cdf0e10cSrcweir         SelectPalette( mpGraphics->mhDC, mpGraphics->mhDefPal, TRUE );
199*cdf0e10cSrcweir     ImplSalDeInitGraphics( mpGraphics );
200*cdf0e10cSrcweir     if( mhDefBmp )
201*cdf0e10cSrcweir         SelectBitmap( mpGraphics->mhDC, mhDefBmp );
202*cdf0e10cSrcweir     if( !mbForeignDC )
203*cdf0e10cSrcweir         DeleteDC( mpGraphics->mhDC );
204*cdf0e10cSrcweir     if( mhBmp )
205*cdf0e10cSrcweir         DeleteBitmap( mhBmp );
206*cdf0e10cSrcweir     delete mpGraphics;
207*cdf0e10cSrcweir     mpGraphics = NULL;
208*cdf0e10cSrcweir }
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir // -----------------------------------------------------------------------
211*cdf0e10cSrcweir 
212*cdf0e10cSrcweir SalGraphics* WinSalVirtualDevice::GetGraphics()
213*cdf0e10cSrcweir {
214*cdf0e10cSrcweir 	if ( mbGraphics )
215*cdf0e10cSrcweir 		return NULL;
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir 	if ( mpGraphics )
218*cdf0e10cSrcweir 		mbGraphics = TRUE;
219*cdf0e10cSrcweir 
220*cdf0e10cSrcweir 	return mpGraphics;
221*cdf0e10cSrcweir }
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir // -----------------------------------------------------------------------
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir void WinSalVirtualDevice::ReleaseGraphics( SalGraphics* )
226*cdf0e10cSrcweir {
227*cdf0e10cSrcweir 	mbGraphics = FALSE;
228*cdf0e10cSrcweir }
229*cdf0e10cSrcweir 
230*cdf0e10cSrcweir // -----------------------------------------------------------------------
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir sal_Bool WinSalVirtualDevice::SetSize( long nDX, long nDY )
233*cdf0e10cSrcweir {
234*cdf0e10cSrcweir     if( mbForeignDC || !mhBmp )
235*cdf0e10cSrcweir         return TRUE;    // ???
236*cdf0e10cSrcweir     else
237*cdf0e10cSrcweir     {
238*cdf0e10cSrcweir 	    HBITMAP hNewBmp = ImplCreateVirDevBitmap( mhDC, nDX, nDY,
239*cdf0e10cSrcweir 											  mnBitCount );
240*cdf0e10cSrcweir 	    if ( hNewBmp )
241*cdf0e10cSrcweir 	    {
242*cdf0e10cSrcweir 		    SelectBitmap( mhDC, hNewBmp );
243*cdf0e10cSrcweir 		    DeleteBitmap( mhBmp );
244*cdf0e10cSrcweir 		    mhBmp = hNewBmp;
245*cdf0e10cSrcweir 		    return TRUE;
246*cdf0e10cSrcweir 	    }
247*cdf0e10cSrcweir 	    else
248*cdf0e10cSrcweir         {
249*cdf0e10cSrcweir             ImplWriteLastError( GetLastError(), "ImplCreateVirDevBitmap in SetSize" );
250*cdf0e10cSrcweir             return FALSE;
251*cdf0e10cSrcweir         }
252*cdf0e10cSrcweir     }
253*cdf0e10cSrcweir }
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir void WinSalVirtualDevice::GetSize( long& rWidth, long& rHeight )
256*cdf0e10cSrcweir {
257*cdf0e10cSrcweir     rWidth = GetDeviceCaps( mhDC, HORZRES );
258*cdf0e10cSrcweir     rHeight= GetDeviceCaps( mhDC, VERTRES );
259*cdf0e10cSrcweir }
260