bump product version to 6.4.0.3
[LibreOffice.git] / vcl / win / gdi / salvd.cxx
blob57ad9581b1c42abfbda076c8f1eb4455ca4d5e7f
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>
32 #include <sal/log.hxx>
33 #include <o3tl/temporary.hxx>
35 HBITMAP WinSalVirtualDevice::ImplCreateVirDevBitmap(HDC hDC, long nDX, long nDY, sal_uInt16 nBitCount, void **ppData)
37 HBITMAP hBitmap;
39 if ( nBitCount == 1 )
41 hBitmap = CreateBitmap( static_cast<int>(nDX), static_cast<int>(nDY), 1, 1, nullptr );
42 SAL_WARN_IF( !hBitmap, "vcl", "CreateBitmap failed: " << WindowsErrorString( GetLastError() ) );
43 ppData = nullptr;
45 else
47 if (nBitCount == 0)
48 nBitCount = static_cast<WORD>(GetDeviceCaps(hDC, BITSPIXEL));
50 // #146839# Don't use CreateCompatibleBitmap() - there seem to
51 // be built-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 = nBitCount;
59 aBitmapInfo.bmiHeader.biCompression = BI_RGB;
60 aBitmapInfo.bmiHeader.biSizeImage = 0;
61 aBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
62 aBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
63 aBitmapInfo.bmiHeader.biClrUsed = 0;
64 aBitmapInfo.bmiHeader.biClrImportant = 0;
66 hBitmap = CreateDIBSection( hDC, &aBitmapInfo,
67 DIB_RGB_COLORS, ppData, nullptr,
68 0 );
69 SAL_WARN_IF( !hBitmap, "vcl", "CreateDIBSection failed: " << WindowsErrorString( GetLastError() ) );
72 return hBitmap;
75 std::unique_ptr<SalVirtualDevice> WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics,
76 long &nDX, long &nDY,
77 DeviceFormat eFormat,
78 const SystemGraphicsData* pData )
80 WinSalGraphics* pGraphics = static_cast<WinSalGraphics*>(pSGraphics);
81 HDC hDC = nullptr;
83 if( pData )
85 hDC = (pData->hDC) ? pData->hDC : GetDC(pData->hWnd);
86 if (hDC)
88 nDX = GetDeviceCaps( hDC, HORZRES );
89 nDY = GetDeviceCaps( hDC, VERTRES );
91 else
93 nDX = 0;
94 nDY = 0;
97 else
99 hDC = CreateCompatibleDC( pGraphics->getHDC() );
100 SAL_WARN_IF( !hDC, "vcl", "CreateCompatibleDC failed: " << WindowsErrorString( GetLastError() ) );
103 if (!hDC)
104 return nullptr;
106 sal_uInt16 nBitCount = (eFormat == DeviceFormat::BITMASK) ? 1 : 0;
108 HBITMAP hBmp = nullptr;
109 if (!pData)
111 // #124826# continue even if hBmp could not be created
112 // if we would return a failure in this case, the process
113 // would terminate which is not required
114 hBmp = WinSalVirtualDevice::ImplCreateVirDevBitmap(pGraphics->getHDC(),
115 nDX, nDY, nBitCount,
116 &o3tl::temporary<void*>(nullptr));
119 const bool bForeignDC = pData != nullptr && pData->hDC != nullptr;
120 const SalData* pSalData = GetSalData();
122 WinSalVirtualDevice* pVDev = new WinSalVirtualDevice(hDC, hBmp, nBitCount,
123 bForeignDC, nDX, nDY);
125 WinSalGraphics* pVirGraphics = new WinSalGraphics(WinSalGraphics::VIRTUAL_DEVICE,
126 pGraphics->isScreen(), nullptr, pVDev);
128 // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL()
129 pVirGraphics->SetLayout( SalLayoutFlags::NONE );
130 pVirGraphics->setHDC(hDC);
132 if ( pSalData->mhDitherPal && pVirGraphics->isScreen() )
134 pVirGraphics->setDefPal(SelectPalette( hDC, pSalData->mhDitherPal, TRUE ));
135 RealizePalette( hDC );
138 pVirGraphics->InitGraphics();
139 pVDev->setGraphics(pVirGraphics);
141 return std::unique_ptr<SalVirtualDevice>(pVDev);
144 WinSalVirtualDevice::WinSalVirtualDevice(HDC hDC, HBITMAP hBMP, sal_uInt16 nBitCount, bool bForeignDC, long nWidth, long nHeight)
145 : mhLocalDC(hDC), // HDC or 0 for Cache Device
146 mhBmp(hBMP), // Memory Bitmap
147 mnBitCount(nBitCount), // BitCount (0 or 1)
148 mbGraphics(false), // is Graphics used
149 mbForeignDC(bForeignDC), // uses a foreign DC instead of a bitmap
150 mnWidth(nWidth),
151 mnHeight(nHeight)
153 // Default Bitmap
154 if (hBMP)
155 mhDefBmp = SelectBitmap(hDC, hBMP);
156 else
157 mhDefBmp = nullptr;
159 // insert VirDev into list of virtual devices
160 SalData* pSalData = GetSalData();
161 mpNext = pSalData->mpFirstVD;
162 pSalData->mpFirstVD = this;
165 WinSalVirtualDevice::~WinSalVirtualDevice()
167 // remove VirDev from list of virtual devices
168 SalData* pSalData = GetSalData();
169 WinSalVirtualDevice** ppVirDev = &pSalData->mpFirstVD;
170 for(; (*ppVirDev != this) && *ppVirDev; ppVirDev = &(*ppVirDev)->mpNext );
171 if( *ppVirDev )
172 *ppVirDev = mpNext;
174 // destroy saved DC
175 if( mpGraphics->getDefPal() )
176 SelectPalette( mpGraphics->getHDC(), mpGraphics->getDefPal(), TRUE );
177 mpGraphics->DeInitGraphics();
178 if( mhDefBmp )
179 SelectBitmap( mpGraphics->getHDC(), mhDefBmp );
180 if( !mbForeignDC )
181 DeleteDC( mpGraphics->getHDC() );
184 SalGraphics* WinSalVirtualDevice::AcquireGraphics()
186 if ( mbGraphics )
187 return nullptr;
189 if ( mpGraphics )
190 mbGraphics = true;
192 return mpGraphics.get();
195 void WinSalVirtualDevice::ReleaseGraphics( SalGraphics* )
197 mbGraphics = false;
200 bool WinSalVirtualDevice::SetSize( long nDX, long nDY )
202 if( mbForeignDC || !mhBmp )
203 return true; // ???
205 HBITMAP hNewBmp = ImplCreateVirDevBitmap(getHDC(), nDX, nDY, mnBitCount,
206 &o3tl::temporary<void*>(nullptr));
207 if (!hNewBmp)
209 mnWidth = 0;
210 mnHeight = 0;
211 return false;
214 mnWidth = nDX;
215 mnHeight = nDY;
217 SelectBitmap(getHDC(), hNewBmp);
218 mhBmp.reset(hNewBmp);
220 if (mpGraphics)
222 WinOpenGLSalGraphicsImpl *pImpl;
223 pImpl = dynamic_cast< WinOpenGLSalGraphicsImpl * >(mpGraphics->GetImpl());
224 if (pImpl)
225 pImpl->Init();
228 return true;
231 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */