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