build fix
[LibreOffice.git] / vcl / win / gdi / salvd.cxx
blob191c0eb0763cd9db6e83ceda3f4bb654656cca8e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svsys.h>
22 #include <comphelper/windowserrorstring.hxx>
24 #include <vcl/sysdata.hxx>
26 #include <win/wincomp.hxx>
27 #include <win/saldata.hxx>
28 #include <win/salinst.h>
29 #include <win/salgdi.h>
30 #include <win/salvd.h>
31 #include "opengl/win/gdiimpl.hxx"
33 HBITMAP WinSalVirtualDevice::ImplCreateVirDevBitmap(HDC hDC, long nDX, long nDY, sal_uInt16 nBitCount, void **ppData)
35 HBITMAP hBitmap;
37 if ( nBitCount == 1 )
39 hBitmap = CreateBitmap( (int)nDX, (int)nDY, 1, 1, nullptr );
40 SAL_WARN_IF( !hBitmap, "vcl", "CreateBitmap failed: " << WindowsErrorString( GetLastError() ) );
41 ppData = nullptr;
43 else
45 if (nBitCount == 0)
46 nBitCount = (WORD)GetDeviceCaps(hDC, BITSPIXEL);
48 // #146839# Don't use CreateCompatibleBitmap() - there seem to
49 // be build-in limits for those HBITMAPs, at least this fails
50 // rather often on large displays/multi-monitor setups.
51 BITMAPINFO aBitmapInfo;
52 aBitmapInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
53 aBitmapInfo.bmiHeader.biWidth = nDX;
54 aBitmapInfo.bmiHeader.biHeight = nDY;
55 aBitmapInfo.bmiHeader.biPlanes = 1;
56 aBitmapInfo.bmiHeader.biBitCount = nBitCount;
57 aBitmapInfo.bmiHeader.biCompression = BI_RGB;
58 aBitmapInfo.bmiHeader.biSizeImage = 0;
59 aBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
60 aBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
61 aBitmapInfo.bmiHeader.biClrUsed = 0;
62 aBitmapInfo.bmiHeader.biClrImportant = 0;
64 hBitmap = CreateDIBSection( hDC, &aBitmapInfo,
65 DIB_RGB_COLORS, ppData, nullptr,
66 0 );
67 SAL_WARN_IF( !hBitmap, "vcl", "CreateDIBSection failed: " << WindowsErrorString( GetLastError() ) );
70 return hBitmap;
73 SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics,
74 long &nDX, long &nDY,
75 DeviceFormat eFormat,
76 const SystemGraphicsData* pData )
78 WinSalGraphics* pGraphics = static_cast<WinSalGraphics*>(pSGraphics);
80 sal_uInt16 nBitCount;
81 switch (eFormat)
83 case DeviceFormat::BITMASK:
84 nBitCount = 1;
85 break;
86 default:
87 nBitCount = 0;
88 break;
91 HDC hDC = nullptr;
92 HBITMAP hBmp = nullptr;
93 bool bOk = FALSE;
95 if( pData )
97 hDC = (pData->hDC) ? pData->hDC : GetDC(pData->hWnd);
98 hBmp = nullptr;
99 bOk = (hDC != nullptr);
100 if ( bOk && nDX <= 1 && nDY <= 1 )
102 nDX = GetDeviceCaps( hDC, HORZRES );
103 nDY = GetDeviceCaps( hDC, VERTRES );
105 else if ( !bOk )
107 nDX = 0;
108 nDY = 0;
111 else
113 hDC = CreateCompatibleDC( pGraphics->getHDC() );
114 SAL_WARN_IF( !hDC, "vcl", "CreateCompatibleDC failed: " << WindowsErrorString( GetLastError() ) );
116 void *pDummy;
117 hBmp = WinSalVirtualDevice::ImplCreateVirDevBitmap(pGraphics->getHDC(), nDX, nDY, nBitCount, &pDummy);
119 // #124826# continue even if hBmp could not be created
120 // if we would return a failure in this case, the process
121 // would terminate which is not required
123 bOk = (hDC != nullptr);
126 if ( bOk )
128 WinSalVirtualDevice* pVDev = new WinSalVirtualDevice(hDC, hBmp, nBitCount, (pData != nullptr && pData->hDC != nullptr ), nDX, nDY);
129 SalData* pSalData = GetSalData();
130 WinSalGraphics* pVirGraphics = new WinSalGraphics(WinSalGraphics::VIRTUAL_DEVICE, pGraphics->isScreen(), nullptr, pVDev);
131 pVirGraphics->SetLayout( SalLayoutFlags::NONE ); // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL()
132 pVirGraphics->setHDC(hDC);
133 if ( pSalData->mhDitherPal && pVirGraphics->isScreen() )
135 pVirGraphics->setDefPal(SelectPalette( hDC, pSalData->mhDitherPal, TRUE ));
136 RealizePalette( hDC );
138 pVirGraphics->InitGraphics();
140 pVDev->setGraphics(pVirGraphics);
142 return pVDev;
144 else
146 if ( hDC && !pData )
147 DeleteDC( hDC );
148 if ( hBmp )
149 DeleteBitmap( hBmp );
150 return nullptr;
154 WinSalVirtualDevice::WinSalVirtualDevice(HDC hDC, HBITMAP hBMP, sal_uInt16 nBitCount, bool bForeignDC, long nWidth, long nHeight)
155 : mhLocalDC(hDC), // HDC or 0 for Cache Device
156 mhBmp(hBMP), // Memory Bitmap
157 mpGraphics(nullptr), // current VirDev graphics
158 mnBitCount(nBitCount), // BitCount (0 or 1)
159 mbGraphics(false), // is Graphics used
160 mbForeignDC(bForeignDC), // uses a foreign DC instead of a bitmap
161 mnWidth(nWidth),
162 mnHeight(nHeight)
164 // Default Bitmap
165 if (hBMP)
166 mhDefBmp = SelectBitmap(hDC, hBMP);
167 else
168 mhDefBmp = nullptr;
170 // insert VirDev into list of virtual devices
171 SalData* pSalData = GetSalData();
172 mpNext = pSalData->mpFirstVD;
173 pSalData->mpFirstVD = this;
176 WinSalVirtualDevice::~WinSalVirtualDevice()
178 // remove VirDev from list of virtual devices
179 SalData* pSalData = GetSalData();
180 WinSalVirtualDevice** ppVirDev = &pSalData->mpFirstVD;
181 for(; (*ppVirDev != this) && *ppVirDev; ppVirDev = &(*ppVirDev)->mpNext );
182 if( *ppVirDev )
183 *ppVirDev = mpNext;
185 // destroy saved DC
186 if( mpGraphics->getDefPal() )
187 SelectPalette( mpGraphics->getHDC(), mpGraphics->getDefPal(), TRUE );
188 mpGraphics->DeInitGraphics();
189 if( mhDefBmp )
190 SelectBitmap( mpGraphics->getHDC(), mhDefBmp );
191 if( !mbForeignDC )
192 DeleteDC( mpGraphics->getHDC() );
193 if( mhBmp )
194 DeleteBitmap( mhBmp );
195 delete mpGraphics;
196 mpGraphics = nullptr;
199 SalGraphics* WinSalVirtualDevice::AcquireGraphics()
201 if ( mbGraphics )
202 return nullptr;
204 if ( mpGraphics )
205 mbGraphics = true;
207 return mpGraphics;
210 void WinSalVirtualDevice::ReleaseGraphics( SalGraphics* )
212 mbGraphics = false;
215 bool WinSalVirtualDevice::SetSize( long nDX, long nDY )
217 if( mbForeignDC || !mhBmp )
218 return true; // ???
219 else
221 void *pDummy;
222 HBITMAP hNewBmp = ImplCreateVirDevBitmap(getHDC(), nDX, nDY, mnBitCount, &pDummy);
223 if ( hNewBmp )
225 mnWidth = nDX;
226 mnHeight = nDY;
228 SelectBitmap( getHDC(), hNewBmp );
229 DeleteBitmap( mhBmp );
230 mhBmp = hNewBmp;
232 if (mpGraphics)
234 WinOpenGLSalGraphicsImpl *pImpl;
235 pImpl = dynamic_cast< WinOpenGLSalGraphicsImpl * >(mpGraphics->GetImpl());
236 if (pImpl)
237 pImpl->Init();
239 return true;
241 else
243 mnWidth = 0;
244 mnHeight = 0;
245 return false;
250 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */