xref: /aoo41x/main/vcl/unx/generic/gdi/salvd.cxx (revision cdf0e10c)
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