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