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