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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26
27 #include <tools/svwin.h>
28
29 #include <vcl/sysdata.hxx>
30
31 #include <win/wincomp.hxx>
32 #include <win/saldata.hxx>
33 #include <win/salinst.h>
34 #include <win/salgdi.h>
35 #include <win/salvd.h>
36
37 // =======================================================================
38
ImplCreateVirDevBitmap(HDC hDC,long nDX,long nDY,sal_uInt16 nBitCount)39 static HBITMAP ImplCreateVirDevBitmap( HDC hDC, long nDX, long nDY,
40 sal_uInt16 nBitCount )
41 {
42 HBITMAP hBitmap;
43
44 if ( nBitCount == 1 )
45 {
46 hBitmap = CreateBitmap( (int)nDX, (int)nDY, 1, 1, NULL );
47 }
48 else
49 {
50 // #146839# Don't use CreateCompatibleBitmap() - there seem to
51 // be build-in limits for those HBITMAPs, at least this fails
52 // rather often on large displays/multi-monitor setups.
53 BITMAPINFO aBitmapInfo;
54 aBitmapInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
55 aBitmapInfo.bmiHeader.biWidth = nDX;
56 aBitmapInfo.bmiHeader.biHeight = nDY;
57 aBitmapInfo.bmiHeader.biPlanes = 1;
58 aBitmapInfo.bmiHeader.biBitCount = (WORD)GetDeviceCaps( hDC,
59 BITSPIXEL );
60 aBitmapInfo.bmiHeader.biCompression = BI_RGB;
61 aBitmapInfo.bmiHeader.biSizeImage = 0;
62 aBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
63 aBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
64 aBitmapInfo.bmiHeader.biClrUsed = 0;
65 aBitmapInfo.bmiHeader.biClrImportant = 0;
66
67 void* pDummy;
68 hBitmap = CreateDIBSection( hDC, &aBitmapInfo,
69 DIB_RGB_COLORS, &pDummy, NULL,
70 0 );
71 }
72
73 return hBitmap;
74 }
75
76 // =======================================================================
77
CreateVirtualDevice(SalGraphics * pSGraphics,long nDX,long nDY,sal_uInt16 nBitCount,const SystemGraphicsData * pData)78 SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics,
79 long nDX, long nDY,
80 sal_uInt16 nBitCount,
81 const SystemGraphicsData* pData )
82 {
83 WinSalGraphics* pGraphics = static_cast<WinSalGraphics*>(pSGraphics);
84
85 HDC hDC = NULL;
86 HBITMAP hBmp = NULL;
87 sal_Bool bOk = FALSE;
88
89 if( pData )
90 {
91 hDC = pData->hDC;
92 hBmp = NULL;
93 bOk = (hDC != NULL);
94 }
95 else
96 {
97 hDC = CreateCompatibleDC( pGraphics->getHDC() );
98 if( !hDC )
99 ImplWriteLastError( GetLastError(), "CreateCompatibleDC in CreateVirtualDevice" );
100
101 hBmp = ImplCreateVirDevBitmap( pGraphics->getHDC(),
102 nDX, nDY, nBitCount );
103 if( !hBmp )
104 ImplWriteLastError( GetLastError(), "ImplCreateVirDevBitmap in CreateVirtualDevice" );
105 // #124826# continue even if hBmp could not be created
106 // if we would return a failure in this case, the process
107 // would terminate which is not required
108
109 DBG_ASSERT( hBmp, "WinSalInstance::CreateVirtualDevice(), could not create Bitmap!" );
110
111 bOk = (hDC != NULL);
112 }
113
114 if ( bOk )
115 {
116 WinSalVirtualDevice* pVDev = new WinSalVirtualDevice;
117 SalData* pSalData = GetSalData();
118 WinSalGraphics* pVirGraphics = new WinSalGraphics;
119 pVirGraphics->SetLayout( 0 ); // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL()
120 pVirGraphics->setHDC(hDC);
121 pVirGraphics->mhWnd = 0;
122 pVirGraphics->mbPrinter = FALSE;
123 pVirGraphics->mbVirDev = TRUE;
124 pVirGraphics->mbWindow = FALSE;
125 pVirGraphics->mbScreen = pGraphics->mbScreen;
126 if ( pSalData->mhDitherPal && pVirGraphics->mbScreen )
127 {
128 pVirGraphics->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
129 RealizePalette( hDC );
130 }
131 ImplSalInitGraphics( pVirGraphics );
132
133 pVDev->setHDC(hDC);
134 pVDev->mhBmp = hBmp;
135 if( hBmp )
136 pVDev->mhDefBmp = SelectBitmap( hDC, hBmp );
137 else
138 pVDev->mhDefBmp = NULL;
139 pVDev->mpGraphics = pVirGraphics;
140 pVDev->mnBitCount = nBitCount;
141 pVDev->mbGraphics = FALSE;
142 pVDev->mbForeignDC = (pData != NULL);
143
144 // insert VirDev in VirDevList
145 pVDev->mpNext = pSalData->mpFirstVD;
146 pSalData->mpFirstVD = pVDev;
147
148 return pVDev;
149 }
150 else
151 {
152 if ( hDC && !pData )
153 DeleteDC( hDC );
154 if ( hBmp )
155 DeleteBitmap( hBmp );
156 return NULL;
157 }
158 }
159
160 // -----------------------------------------------------------------------
161
DestroyVirtualDevice(SalVirtualDevice * pDevice)162 void WinSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
163 {
164 delete pDevice;
165 }
166
167 // =======================================================================
168
WinSalVirtualDevice()169 WinSalVirtualDevice::WinSalVirtualDevice()
170 {
171 setHDC((HDC)NULL); // HDC or 0 for Cache Device
172 mhBmp = (HBITMAP) NULL; // Memory Bitmap
173 mhDefBmp = (HBITMAP) NULL; // Default Bitmap
174 mpGraphics = NULL; // current VirDev graphics
175 mpNext = NULL; // next VirDev
176 mnBitCount = 0; // BitCount (0 or 1)
177 mbGraphics = FALSE; // is Graphics used
178 mbForeignDC = FALSE; // uses a foreign DC instead of a bitmap
179 }
180
181 // -----------------------------------------------------------------------
182
~WinSalVirtualDevice()183 WinSalVirtualDevice::~WinSalVirtualDevice()
184 {
185 // remove VirDev from list of virtual devices
186 SalData* pSalData = GetSalData();
187 WinSalVirtualDevice** ppVirDev = &pSalData->mpFirstVD;
188 for(; (*ppVirDev != this) && *ppVirDev; ppVirDev = &(*ppVirDev)->mpNext );
189 if( *ppVirDev )
190 *ppVirDev = mpNext;
191
192 // destroy saved DC
193 if( mpGraphics->mhDefPal )
194 SelectPalette( mpGraphics->getHDC(), mpGraphics->mhDefPal, TRUE );
195 ImplSalDeInitGraphics( mpGraphics );
196 if( mhDefBmp )
197 SelectBitmap( mpGraphics->getHDC(), mhDefBmp );
198 if( !mbForeignDC )
199 DeleteDC( mpGraphics->getHDC() );
200 if( mhBmp )
201 DeleteBitmap( mhBmp );
202 delete mpGraphics;
203 mpGraphics = NULL;
204 }
205
206 // -----------------------------------------------------------------------
207
GetGraphics()208 SalGraphics* WinSalVirtualDevice::GetGraphics()
209 {
210 if ( mbGraphics )
211 return NULL;
212
213 if ( mpGraphics )
214 mbGraphics = TRUE;
215
216 return mpGraphics;
217 }
218
219 // -----------------------------------------------------------------------
220
ReleaseGraphics(SalGraphics *)221 void WinSalVirtualDevice::ReleaseGraphics( SalGraphics* )
222 {
223 mbGraphics = FALSE;
224 }
225
226 // -----------------------------------------------------------------------
227
SetSize(long nDX,long nDY)228 sal_Bool WinSalVirtualDevice::SetSize( long nDX, long nDY )
229 {
230 if( mbForeignDC || !mhBmp )
231 return TRUE; // ???
232 else
233 {
234 HBITMAP hNewBmp = ImplCreateVirDevBitmap( getHDC(), nDX, nDY,
235 mnBitCount );
236 if ( hNewBmp )
237 {
238 SelectBitmap( getHDC(), hNewBmp );
239 DeleteBitmap( mhBmp );
240 mhBmp = hNewBmp;
241 return TRUE;
242 }
243 else
244 {
245 ImplWriteLastError( GetLastError(), "ImplCreateVirDevBitmap in SetSize" );
246 return FALSE;
247 }
248 }
249 }
250
GetSize(long & rWidth,long & rHeight)251 void WinSalVirtualDevice::GetSize( long& rWidth, long& rHeight )
252 {
253 rWidth = GetDeviceCaps( getHDC(), HORZRES );
254 rHeight= GetDeviceCaps( getHDC(), VERTRES );
255 }
256