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 <vcl/sysdata.hxx> 32 33 #include <tools/prex.h> 34 #include <X11/extensions/Xrender.h> 35 #include <tools/postx.h> 36 37 #include <unx/salunx.h> 38 #include <unx/saldata.hxx> 39 #include <unx/saldisp.hxx> 40 #include <unx/salgdi.h> 41 #include <unx/salvd.h> 42 43 #include <salinst.hxx> 44 45 // -=-= SalInstance =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 46 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 47 SalVirtualDevice* X11SalInstance::CreateVirtualDevice( SalGraphics* pGraphics, 48 long nDX, long nDY, 49 sal_uInt16 nBitCount, const SystemGraphicsData *pData ) 50 { 51 X11SalVirtualDevice *pVDev = new X11SalVirtualDevice(); 52 if( !nBitCount && pGraphics ) 53 nBitCount = pGraphics->GetBitCount(); 54 55 if( pData && pData->hDrawable != None ) 56 { 57 XLIB_Window aRoot; 58 int x, y; 59 unsigned int w = 0, h = 0, bw, d; 60 Display* pDisp = GetX11SalData()->GetDisplay()->GetDisplay(); 61 XGetGeometry( pDisp, pData->hDrawable, 62 &aRoot, &x, &y, &w, &h, &bw, &d ); 63 int nScreen = 0; 64 while( nScreen < ScreenCount( pDisp ) ) 65 { 66 if( RootWindow( pDisp, nScreen ) == aRoot ) 67 break; 68 nScreen++; 69 } 70 nDX = (long)w; 71 nDY = (long)h; 72 if( !pVDev->Init( GetX11SalData()->GetDisplay(), nDX, nDY, nBitCount, nScreen, pData->hDrawable, pData->pRenderFormat ) ) 73 { 74 delete pVDev; 75 return NULL; 76 } 77 } 78 else if( !pVDev->Init( GetX11SalData()->GetDisplay(), nDX, nDY, nBitCount, 79 pGraphics ? static_cast<X11SalGraphics*>(pGraphics)->GetScreenNumber() : 80 GetX11SalData()->GetDisplay()->GetDefaultScreenNumber() ) ) 81 { 82 delete pVDev; 83 return NULL; 84 } 85 86 pVDev->InitGraphics( pVDev ); 87 return pVDev; 88 } 89 90 void X11SalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice ) 91 { 92 delete pDevice; 93 } 94 95 // -=-= SalGraphicsData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 96 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 97 void X11SalGraphics::Init( X11SalVirtualDevice *pDevice, SalColormap* pColormap, bool bDeleteColormap ) 98 { 99 SalColormap *pOrigDeleteColormap = m_pDeleteColormap; 100 101 SalDisplay *pDisplay = pDevice->GetDisplay(); 102 m_nScreen = pDevice->GetScreenNumber(); 103 104 int nVisualDepth = pDisplay->GetColormap( m_nScreen ).GetVisual().GetDepth(); 105 int nDeviceDepth = pDevice->GetDepth(); 106 107 if( pColormap ) 108 { 109 m_pColormap = pColormap; 110 if( bDeleteColormap ) 111 m_pDeleteColormap = pColormap; 112 } 113 else 114 if( nDeviceDepth == nVisualDepth ) 115 m_pColormap = &pDisplay->GetColormap( m_nScreen ); 116 else 117 if( nDeviceDepth == 1 ) 118 m_pColormap = m_pDeleteColormap = new SalColormap(); 119 120 if (m_pDeleteColormap != pOrigDeleteColormap) 121 delete pOrigDeleteColormap; 122 123 const Drawable aVdevDrawable = pDevice->GetDrawable(); 124 SetDrawable( aVdevDrawable, m_nScreen ); 125 126 m_pVDev = pDevice; 127 m_pFrame = NULL; 128 129 bWindow_ = pDisplay->IsDisplay(); 130 bVirDev_ = sal_True; 131 } 132 133 // -=-= SalVirDevData / SalVirtualDevice -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 134 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 135 sal_Bool X11SalVirtualDevice::Init( SalDisplay *pDisplay, 136 long nDX, long nDY, 137 sal_uInt16 nBitCount, 138 int nScreen, 139 Pixmap hDrawable, 140 void* pRenderFormatVoid ) 141 { 142 SalColormap* pColormap = NULL; 143 bool bDeleteColormap = false; 144 145 pDisplay_ = pDisplay; 146 pGraphics_ = new X11SalGraphics(); 147 m_nScreen = nScreen; 148 if( pRenderFormatVoid ) { 149 XRenderPictFormat *pRenderFormat = ( XRenderPictFormat* )pRenderFormatVoid; 150 pGraphics_->SetXRenderFormat( pRenderFormat ); 151 if( pRenderFormat->colormap ) 152 pColormap = new SalColormap( pDisplay, pRenderFormat->colormap, m_nScreen ); 153 else 154 pColormap = new SalColormap( nBitCount ); 155 bDeleteColormap = true; 156 } 157 else if( nBitCount != pDisplay->GetVisual( m_nScreen ).GetDepth() ) 158 { 159 pColormap = new SalColormap( nBitCount ); 160 bDeleteColormap = true; 161 } 162 pGraphics_->SetLayout( 0 ); // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL() 163 nDX_ = nDX; 164 nDY_ = nDY; 165 nDepth_ = nBitCount; 166 167 if( hDrawable == None ) 168 hDrawable_ = XCreatePixmap( GetXDisplay(), 169 pDisplay_->GetDrawable( m_nScreen ), 170 nDX_, nDY_, 171 GetDepth() ); 172 else 173 { 174 hDrawable_ = hDrawable; 175 bExternPixmap_ = sal_True; 176 } 177 178 pGraphics_->Init( this, pColormap, bDeleteColormap ); 179 180 return hDrawable_ != None ? sal_True : sal_False; 181 } 182 183 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 184 X11SalVirtualDevice::X11SalVirtualDevice() 185 { 186 pDisplay_ = (SalDisplay*)ILLEGAL_POINTER; 187 pGraphics_ = NULL; 188 hDrawable_ = None; 189 nDX_ = 0; 190 nDY_ = 0; 191 nDepth_ = 0; 192 bGraphics_ = sal_False; 193 bExternPixmap_ = sal_False; 194 } 195 196 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 197 X11SalVirtualDevice::~X11SalVirtualDevice() 198 { 199 if( pGraphics_ ) 200 delete pGraphics_; 201 pGraphics_ = NULL; 202 203 if( GetDrawable() && !bExternPixmap_ ) 204 XFreePixmap( GetXDisplay(), GetDrawable() ); 205 } 206 207 SalGraphics* X11SalVirtualDevice::GetGraphics() 208 { 209 if( bGraphics_ ) 210 return NULL; 211 212 if( pGraphics_ ) 213 bGraphics_ = sal_True; 214 215 return pGraphics_; 216 } 217 218 void X11SalVirtualDevice::ReleaseGraphics( SalGraphics* ) 219 { bGraphics_ = sal_False; } 220 221 sal_Bool X11SalVirtualDevice::SetSize( long nDX, long nDY ) 222 { 223 if( bExternPixmap_ ) 224 return sal_False; 225 226 // #144688# 227 // the X protocol request CreatePixmap puts an upper bound 228 // of 16 bit to the size. Beyond that there may be implementation 229 // limits of the Xserver; which we should catch by a failed XCreatePixmap 230 // call. However extra large values should be caught here since we'd run into 231 // 16 bit truncation here without noticing. 232 if( nDX < 0 || nDX > 65535 || 233 nDY < 0 || nDY > 65535 ) 234 return sal_False; 235 236 if( !nDX ) nDX = 1; 237 if( !nDY ) nDY = 1; 238 239 Pixmap h = XCreatePixmap( GetXDisplay(), 240 pDisplay_->GetDrawable( m_nScreen ), 241 nDX, nDY, nDepth_ ); 242 243 if( !h ) 244 { 245 if( !GetDrawable() ) 246 { 247 hDrawable_ = XCreatePixmap( GetXDisplay(), 248 pDisplay_->GetDrawable( m_nScreen ), 249 1, 1, nDepth_ ); 250 nDX_ = 1; 251 nDY_ = 1; 252 } 253 return sal_False; 254 } 255 256 if( GetDrawable() ) 257 XFreePixmap( GetXDisplay(), GetDrawable() ); 258 hDrawable_ = h; 259 260 nDX_ = nDX; 261 nDY_ = nDY; 262 263 if( pGraphics_ ) 264 InitGraphics( this ); 265 266 return sal_True; 267 } 268 269 void X11SalVirtualDevice::GetSize( long& rWidth, long& rHeight ) 270 { 271 rWidth = GetWidth(); 272 rHeight = GetHeight(); 273 } 274 275