blob: 6190b0d31817d7f25e8a70e3d9ab9a30d3991a41 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
#include <tools/svwin.h>
#include <vcl/sysdata.hxx>
#include <win/wincomp.hxx>
#include <win/saldata.hxx>
#include <win/salinst.h>
#include <win/salgdi.h>
#include <win/salvd.h>
// =======================================================================
static HBITMAP ImplCreateVirDevBitmap( HDC hDC, long nDX, long nDY,
sal_uInt16 nBitCount )
{
HBITMAP hBitmap;
if ( nBitCount == 1 )
{
hBitmap = CreateBitmap( (int)nDX, (int)nDY, 1, 1, NULL );
}
else
{
// #146839# Don't use CreateCompatibleBitmap() - there seem to
// be build-in limits for those HBITMAPs, at least this fails
// rather often on large displays/multi-monitor setups.
BITMAPINFO aBitmapInfo;
aBitmapInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
aBitmapInfo.bmiHeader.biWidth = nDX;
aBitmapInfo.bmiHeader.biHeight = nDY;
aBitmapInfo.bmiHeader.biPlanes = 1;
aBitmapInfo.bmiHeader.biBitCount = (WORD)GetDeviceCaps( hDC,
BITSPIXEL );
aBitmapInfo.bmiHeader.biCompression = BI_RGB;
aBitmapInfo.bmiHeader.biSizeImage = 0;
aBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
aBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
aBitmapInfo.bmiHeader.biClrUsed = 0;
aBitmapInfo.bmiHeader.biClrImportant = 0;
void* pDummy;
hBitmap = CreateDIBSection( hDC, &aBitmapInfo,
DIB_RGB_COLORS, &pDummy, NULL,
0 );
}
return hBitmap;
}
// =======================================================================
SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics,
long nDX, long nDY,
sal_uInt16 nBitCount,
const SystemGraphicsData* pData )
{
WinSalGraphics* pGraphics = static_cast<WinSalGraphics*>(pSGraphics);
HDC hDC = NULL;
HBITMAP hBmp = NULL;
sal_Bool bOk = FALSE;
if( pData )
{
hDC = pData->hDC;
hBmp = NULL;
bOk = (hDC != NULL);
}
else
{
hDC = CreateCompatibleDC( pGraphics->getHDC() );
if( !hDC )
ImplWriteLastError( GetLastError(), "CreateCompatibleDC in CreateVirtualDevice" );
hBmp = ImplCreateVirDevBitmap( pGraphics->getHDC(),
nDX, nDY, nBitCount );
if( !hBmp )
ImplWriteLastError( GetLastError(), "ImplCreateVirDevBitmap in CreateVirtualDevice" );
// #124826# continue even if hBmp could not be created
// if we would return a failure in this case, the process
// would terminate which is not required
DBG_ASSERT( hBmp, "WinSalInstance::CreateVirtualDevice(), could not create Bitmap!" );
bOk = (hDC != NULL);
}
if ( bOk )
{
WinSalVirtualDevice* pVDev = new WinSalVirtualDevice;
SalData* pSalData = GetSalData();
WinSalGraphics* pVirGraphics = new WinSalGraphics;
pVirGraphics->SetLayout( 0 ); // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL()
pVirGraphics->setHDC(hDC);
pVirGraphics->mhWnd = 0;
pVirGraphics->mbPrinter = FALSE;
pVirGraphics->mbVirDev = TRUE;
pVirGraphics->mbWindow = FALSE;
pVirGraphics->mbScreen = pGraphics->mbScreen;
if ( pSalData->mhDitherPal && pVirGraphics->mbScreen )
{
pVirGraphics->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
RealizePalette( hDC );
}
ImplSalInitGraphics( pVirGraphics );
pVDev->setHDC(hDC);
pVDev->mhBmp = hBmp;
if( hBmp )
pVDev->mhDefBmp = SelectBitmap( hDC, hBmp );
else
pVDev->mhDefBmp = NULL;
pVDev->mpGraphics = pVirGraphics;
pVDev->mnBitCount = nBitCount;
pVDev->mbGraphics = FALSE;
pVDev->mbForeignDC = (pData != NULL);
// insert VirDev in VirDevList
pVDev->mpNext = pSalData->mpFirstVD;
pSalData->mpFirstVD = pVDev;
return pVDev;
}
else
{
if ( hDC && !pData )
DeleteDC( hDC );
if ( hBmp )
DeleteBitmap( hBmp );
return NULL;
}
}
// -----------------------------------------------------------------------
void WinSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
{
delete pDevice;
}
// =======================================================================
WinSalVirtualDevice::WinSalVirtualDevice()
{
setHDC((HDC)NULL); // HDC or 0 for Cache Device
mhBmp = (HBITMAP) NULL; // Memory Bitmap
mhDefBmp = (HBITMAP) NULL; // Default Bitmap
mpGraphics = NULL; // current VirDev graphics
mpNext = NULL; // next VirDev
mnBitCount = 0; // BitCount (0 or 1)
mbGraphics = FALSE; // is Graphics used
mbForeignDC = FALSE; // uses a foreign DC instead of a bitmap
}
// -----------------------------------------------------------------------
WinSalVirtualDevice::~WinSalVirtualDevice()
{
// remove VirDev from list of virtual devices
SalData* pSalData = GetSalData();
WinSalVirtualDevice** ppVirDev = &pSalData->mpFirstVD;
for(; (*ppVirDev != this) && *ppVirDev; ppVirDev = &(*ppVirDev)->mpNext );
if( *ppVirDev )
*ppVirDev = mpNext;
// destroy saved DC
if( mpGraphics->mhDefPal )
SelectPalette( mpGraphics->getHDC(), mpGraphics->mhDefPal, TRUE );
ImplSalDeInitGraphics( mpGraphics );
if( mhDefBmp )
SelectBitmap( mpGraphics->getHDC(), mhDefBmp );
if( !mbForeignDC )
DeleteDC( mpGraphics->getHDC() );
if( mhBmp )
DeleteBitmap( mhBmp );
delete mpGraphics;
mpGraphics = NULL;
}
// -----------------------------------------------------------------------
SalGraphics* WinSalVirtualDevice::GetGraphics()
{
if ( mbGraphics )
return NULL;
if ( mpGraphics )
mbGraphics = TRUE;
return mpGraphics;
}
// -----------------------------------------------------------------------
void WinSalVirtualDevice::ReleaseGraphics( SalGraphics* )
{
mbGraphics = FALSE;
}
// -----------------------------------------------------------------------
sal_Bool WinSalVirtualDevice::SetSize( long nDX, long nDY )
{
if( mbForeignDC || !mhBmp )
return TRUE; // ???
else
{
HBITMAP hNewBmp = ImplCreateVirDevBitmap( getHDC(), nDX, nDY,
mnBitCount );
if ( hNewBmp )
{
SelectBitmap( getHDC(), hNewBmp );
DeleteBitmap( mhBmp );
mhBmp = hNewBmp;
return TRUE;
}
else
{
ImplWriteLastError( GetLastError(), "ImplCreateVirDevBitmap in SetSize" );
return FALSE;
}
}
}
void WinSalVirtualDevice::GetSize( long& rWidth, long& rHeight )
{
rWidth = GetDeviceCaps( getHDC(), HORZRES );
rHeight= GetDeviceCaps( getHDC(), VERTRES );
}