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