1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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
)
39 hBitmap
= CreateBitmap( (int)nDX
, (int)nDY
, 1, 1, nullptr );
40 SAL_WARN_IF( !hBitmap
, "vcl", "CreateBitmap failed: " << WindowsErrorString( GetLastError() ) );
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,
67 SAL_WARN_IF( !hBitmap
, "vcl", "CreateDIBSection failed: " << WindowsErrorString( GetLastError() ) );
73 SalVirtualDevice
* WinSalInstance::CreateVirtualDevice( SalGraphics
* pSGraphics
,
76 const SystemGraphicsData
* pData
)
78 WinSalGraphics
* pGraphics
= static_cast<WinSalGraphics
*>(pSGraphics
);
83 case DeviceFormat::BITMASK
:
92 HBITMAP hBmp
= nullptr;
97 hDC
= (pData
->hDC
) ? pData
->hDC
: GetDC(pData
->hWnd
);
99 bOk
= (hDC
!= nullptr);
100 if ( bOk
&& nDX
<= 1 && nDY
<= 1 )
102 nDX
= GetDeviceCaps( hDC
, HORZRES
);
103 nDY
= GetDeviceCaps( hDC
, VERTRES
);
113 hDC
= CreateCompatibleDC( pGraphics
->getHDC() );
114 SAL_WARN_IF( !hDC
, "vcl", "CreateCompatibleDC failed: " << WindowsErrorString( GetLastError() ) );
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);
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
);
149 DeleteBitmap( hBmp
);
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
166 mhDefBmp
= SelectBitmap(hDC
, hBMP
);
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
);
186 if( mpGraphics
->getDefPal() )
187 SelectPalette( mpGraphics
->getHDC(), mpGraphics
->getDefPal(), TRUE
);
188 mpGraphics
->DeInitGraphics();
190 SelectBitmap( mpGraphics
->getHDC(), mhDefBmp
);
192 DeleteDC( mpGraphics
->getHDC() );
194 DeleteBitmap( mhBmp
);
196 mpGraphics
= nullptr;
199 SalGraphics
* WinSalVirtualDevice::AcquireGraphics()
210 void WinSalVirtualDevice::ReleaseGraphics( SalGraphics
* )
215 bool WinSalVirtualDevice::SetSize( long nDX
, long nDY
)
217 if( mbForeignDC
|| !mhBmp
)
222 HBITMAP hNewBmp
= ImplCreateVirDevBitmap(getHDC(), nDX
, nDY
, mnBitCount
, &pDummy
);
228 SelectBitmap( getHDC(), hNewBmp
);
229 DeleteBitmap( mhBmp
);
234 WinOpenGLSalGraphicsImpl
*pImpl
;
235 pImpl
= dynamic_cast< WinOpenGLSalGraphicsImpl
* >(mpGraphics
->GetImpl());
250 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */