xref: /AOO41X/main/vcl/unx/generic/gdi/salgdi2.cxx (revision 47148b3bc50811ceb41802e4cc50a5db21535900)
1c82f2877SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3c82f2877SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4c82f2877SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5c82f2877SAndrew Rist  * distributed with this work for additional information
6c82f2877SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7c82f2877SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8c82f2877SAndrew Rist  * "License"); you may not use this file except in compliance
9c82f2877SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11c82f2877SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13c82f2877SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14c82f2877SAndrew Rist  * software distributed under the License is distributed on an
15c82f2877SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16c82f2877SAndrew Rist  * KIND, either express or implied.  See the License for the
17c82f2877SAndrew Rist  * specific language governing permissions and limitations
18c82f2877SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20c82f2877SAndrew Rist  *************************************************************/
21c82f2877SAndrew Rist 
22c82f2877SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <stdio.h>
28cdf0e10cSrcweir #include <poll.h>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include "vcl/salbtype.hxx"
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include "unx/salunx.h"
33cdf0e10cSrcweir #include "unx/saldata.hxx"
34cdf0e10cSrcweir #include "unx/saldisp.hxx"
35cdf0e10cSrcweir #include "unx/salbmp.h"
36cdf0e10cSrcweir #include "unx/salgdi.h"
37cdf0e10cSrcweir #include "unx/salframe.h"
38cdf0e10cSrcweir #include "unx/salvd.h"
39cdf0e10cSrcweir #include "xrender_peer.hxx"
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #include "printergfx.hxx"
42cdf0e10cSrcweir 
43cdf0e10cSrcweir #include "vcl/bmpacc.hxx"
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #undef SALGDI2_TESTTRANS
46cdf0e10cSrcweir 
47cdf0e10cSrcweir // -=-= debugging =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
48cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
49cdf0e10cSrcweir #if 0
50cdf0e10cSrcweir 
51cdf0e10cSrcweir static void sal_PrintImage( char *s, XImage*p )
52cdf0e10cSrcweir {
53cdf0e10cSrcweir 	fprintf( stderr, "%s %d %d %d\n", s, p->depth, p->width, p->height );
54cdf0e10cSrcweir 	int nW = Min( 64, p->width*p->bits_per_pixel >> 3 );
55cdf0e10cSrcweir 	for( int i = 0; i < Min( 16, p->height ); i++ )
56cdf0e10cSrcweir 	{
57cdf0e10cSrcweir 		for( int j = 0; j < nW; j++ )
58cdf0e10cSrcweir 			fprintf( stderr, "%02X", (UINT8)p->data[i*p->bytes_per_line+j] );
59cdf0e10cSrcweir 		fprintf( stderr, "\n" );
60cdf0e10cSrcweir 	}
61cdf0e10cSrcweir }
62cdf0e10cSrcweir 
63cdf0e10cSrcweir #endif // DBG_UTIL
64cdf0e10cSrcweir 
65cdf0e10cSrcweir // -----------------------------------------------------------------------------
66cdf0e10cSrcweir 
67cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS
68cdf0e10cSrcweir #define DBG_TESTTRANS( _def_drawable )								\
69cdf0e10cSrcweir {																	\
70cdf0e10cSrcweir 	XCopyArea( pXDisp, _def_drawable, aDrawable, GetCopyGC(),		\
71cdf0e10cSrcweir 			   0, 0,												\
72cdf0e10cSrcweir 			   pPosAry->mnDestWidth, pPosAry->mnDestHeight,			\
73cdf0e10cSrcweir 			   0, 0 );												\
74cdf0e10cSrcweir }
75cdf0e10cSrcweir #else // (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS
76cdf0e10cSrcweir #define DBG_TESTTRANS( _def_drawable )
77cdf0e10cSrcweir #endif // (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS
78cdf0e10cSrcweir 
79cdf0e10cSrcweir // -=-= X11SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
80cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
CopyScreenArea(Display * pDisplay,Drawable aSrc,int nScreenSrc,int nSrcDepth,Drawable aDest,int nScreenDest,int nDestDepth,GC aDestGC,int src_x,int src_y,unsigned int w,unsigned int h,int dest_x,int dest_y)81cdf0e10cSrcweir void X11SalGraphics::CopyScreenArea( Display* pDisplay,
82cdf0e10cSrcweir                                Drawable aSrc, int nScreenSrc, int nSrcDepth,
83cdf0e10cSrcweir                                Drawable aDest, int nScreenDest, int nDestDepth,
84cdf0e10cSrcweir                                GC aDestGC,
85cdf0e10cSrcweir                                int src_x, int src_y,
86cdf0e10cSrcweir                                unsigned int w, unsigned int h,
87cdf0e10cSrcweir                                int dest_x, int dest_y )
88cdf0e10cSrcweir {
89cdf0e10cSrcweir     if( nSrcDepth == nDestDepth )
90cdf0e10cSrcweir     {
91cdf0e10cSrcweir         if( nScreenSrc == nScreenDest )
92cdf0e10cSrcweir             XCopyArea( pDisplay, aSrc, aDest, aDestGC,
93cdf0e10cSrcweir                        src_x, src_y, w, h, dest_x, dest_y );
94cdf0e10cSrcweir         else
95cdf0e10cSrcweir         {
96cdf0e10cSrcweir             SalXLib* pLib = GetX11SalData()->GetDisplay()->GetXLib();
97cdf0e10cSrcweir             pLib->PushXErrorLevel( true );
98cdf0e10cSrcweir             XImage* pImage = XGetImage( pDisplay, aSrc, src_x, src_y, w, h,
99cdf0e10cSrcweir                                         AllPlanes, ZPixmap );
100cdf0e10cSrcweir             if( pImage )
101cdf0e10cSrcweir             {
102cdf0e10cSrcweir                 if( pImage->data )
103cdf0e10cSrcweir                 {
104cdf0e10cSrcweir                     XPutImage( pDisplay, aDest, aDestGC, pImage,
105cdf0e10cSrcweir                                0, 0, dest_x, dest_y, w, h );
106cdf0e10cSrcweir                 }
107cdf0e10cSrcweir                 XDestroyImage( pImage );
108cdf0e10cSrcweir             }
109cdf0e10cSrcweir             pLib->PopXErrorLevel();
110cdf0e10cSrcweir         }
111cdf0e10cSrcweir     }
112cdf0e10cSrcweir     else
113cdf0e10cSrcweir     {
114cdf0e10cSrcweir         X11SalBitmap aBM;
115cdf0e10cSrcweir         aBM.ImplCreateFromDrawable( aSrc, nScreenSrc, nSrcDepth, src_x, src_y, w, h );
116cdf0e10cSrcweir         SalTwoRect aTwoRect;
117cdf0e10cSrcweir         aTwoRect.mnSrcX = aTwoRect.mnSrcY = 0;
118cdf0e10cSrcweir         aTwoRect.mnSrcWidth = aTwoRect.mnDestWidth = w;
119cdf0e10cSrcweir         aTwoRect.mnSrcHeight = aTwoRect.mnDestHeight = h;
120cdf0e10cSrcweir         aTwoRect.mnDestX = dest_x;
121cdf0e10cSrcweir         aTwoRect.mnDestY = dest_y;
122cdf0e10cSrcweir         aBM.ImplDraw( aDest, nScreenDest, nDestDepth, aTwoRect,aDestGC );
123cdf0e10cSrcweir     }
124cdf0e10cSrcweir }
125cdf0e10cSrcweir 
CreateGC(Drawable hDrawable,unsigned long nMask)126cdf0e10cSrcweir GC X11SalGraphics::CreateGC( Drawable hDrawable, unsigned long nMask )
127cdf0e10cSrcweir {
128cdf0e10cSrcweir 	XGCValues values;
129cdf0e10cSrcweir 
130cdf0e10cSrcweir 	values.graphics_exposures	= False;
131cdf0e10cSrcweir 	values.foreground			= m_pColormap->GetBlackPixel()
132cdf0e10cSrcweir 		                          ^ m_pColormap->GetWhitePixel();
133cdf0e10cSrcweir 	values.function				= GXxor;
134cdf0e10cSrcweir 	values.line_width			= 1;
135cdf0e10cSrcweir 	values.fill_style			= FillStippled;
136cdf0e10cSrcweir 	values.stipple				= GetDisplay()->GetInvert50( m_nScreen );
137cdf0e10cSrcweir     values.subwindow_mode		= ClipByChildren;
138cdf0e10cSrcweir 
139cdf0e10cSrcweir 	return XCreateGC( GetXDisplay(), hDrawable, nMask | GCSubwindowMode, &values );
140cdf0e10cSrcweir }
141cdf0e10cSrcweir 
142cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
GetMonoGC(Pixmap hPixmap)143cdf0e10cSrcweir inline GC X11SalGraphics::GetMonoGC( Pixmap hPixmap )
144cdf0e10cSrcweir {
145cdf0e10cSrcweir 	if( !pMonoGC_ )
146cdf0e10cSrcweir 		pMonoGC_ = CreateGC( hPixmap );
147cdf0e10cSrcweir 
148cdf0e10cSrcweir 	if( !bMonoGC_ )
149cdf0e10cSrcweir 	{
150cdf0e10cSrcweir 		SetClipRegion( pMonoGC_ );
151cdf0e10cSrcweir 		bMonoGC_ = sal_True;
152cdf0e10cSrcweir 	}
153cdf0e10cSrcweir 
154cdf0e10cSrcweir 	return pMonoGC_;
155cdf0e10cSrcweir }
156cdf0e10cSrcweir 
157cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
GetCopyGC()158cdf0e10cSrcweir inline GC X11SalGraphics::GetCopyGC()
159cdf0e10cSrcweir {
160cdf0e10cSrcweir 	if( bXORMode_ ) return GetInvertGC();
161cdf0e10cSrcweir 
162cdf0e10cSrcweir 	if( !pCopyGC_ )
163cdf0e10cSrcweir 		pCopyGC_ = CreateGC( GetDrawable() );
164cdf0e10cSrcweir 
165cdf0e10cSrcweir 	if( !bCopyGC_ )
166cdf0e10cSrcweir 	{
167cdf0e10cSrcweir 		SetClipRegion( pCopyGC_ );
168cdf0e10cSrcweir 		bCopyGC_ = sal_True;
169cdf0e10cSrcweir 	}
170cdf0e10cSrcweir 	return pCopyGC_;
171cdf0e10cSrcweir }
172cdf0e10cSrcweir 
173cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
GetInvertGC()174cdf0e10cSrcweir GC X11SalGraphics::GetInvertGC()
175cdf0e10cSrcweir {
176cdf0e10cSrcweir 	if( !pInvertGC_ )
177cdf0e10cSrcweir 		pInvertGC_ = CreateGC( GetDrawable(),
178cdf0e10cSrcweir 							   GCGraphicsExposures
179cdf0e10cSrcweir 							   | GCForeground
180cdf0e10cSrcweir 							   | GCFunction
181cdf0e10cSrcweir 							   | GCLineWidth );
182cdf0e10cSrcweir 
183cdf0e10cSrcweir 	if( !bInvertGC_ )
184cdf0e10cSrcweir 	{
185cdf0e10cSrcweir 		SetClipRegion( pInvertGC_ );
186cdf0e10cSrcweir 		bInvertGC_ = sal_True;
187cdf0e10cSrcweir 	}
188cdf0e10cSrcweir 	return pInvertGC_;
189cdf0e10cSrcweir }
190cdf0e10cSrcweir 
191cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
GetInvert50GC()192cdf0e10cSrcweir GC X11SalGraphics::GetInvert50GC()
193cdf0e10cSrcweir {
194cdf0e10cSrcweir 	if( !pInvert50GC_ )
195cdf0e10cSrcweir 	{
196cdf0e10cSrcweir 		XGCValues values;
197cdf0e10cSrcweir 
198cdf0e10cSrcweir 		values.graphics_exposures	= False;
199cdf0e10cSrcweir 		values.foreground			= m_pColormap->GetWhitePixel();
200cdf0e10cSrcweir 		values.background			= m_pColormap->GetBlackPixel();
201cdf0e10cSrcweir 		values.function				= GXinvert;
202cdf0e10cSrcweir 		values.line_width			= 1;
203cdf0e10cSrcweir 		values.line_style			= LineSolid;
204cdf0e10cSrcweir 		unsigned long nValueMask =
205cdf0e10cSrcweir 								  GCGraphicsExposures
206cdf0e10cSrcweir 								  | GCForeground
207cdf0e10cSrcweir 								  | GCBackground
208cdf0e10cSrcweir 								  | GCFunction
209cdf0e10cSrcweir 								  | GCLineWidth
210cdf0e10cSrcweir 								  | GCLineStyle
211cdf0e10cSrcweir 								  | GCFillStyle
212cdf0e10cSrcweir 								  | GCStipple;
213cdf0e10cSrcweir 
214cdf0e10cSrcweir 		char* pEnv = getenv( "SAL_DO_NOT_USE_INVERT50" );
215cdf0e10cSrcweir 		if( pEnv && ! strcasecmp( pEnv, "true" ) )
216cdf0e10cSrcweir 		{
217cdf0e10cSrcweir 			values.fill_style = FillSolid;
218cdf0e10cSrcweir 			nValueMask &= ~ GCStipple;
219cdf0e10cSrcweir 		}
220cdf0e10cSrcweir 		else
221cdf0e10cSrcweir 		{
222cdf0e10cSrcweir 			values.fill_style			= FillStippled;
223cdf0e10cSrcweir 			values.stipple				= GetDisplay()->GetInvert50( m_nScreen );
224cdf0e10cSrcweir 		}
225cdf0e10cSrcweir 
226cdf0e10cSrcweir 		pInvert50GC_ = XCreateGC( GetXDisplay(), GetDrawable(),
227cdf0e10cSrcweir 								  nValueMask,
228cdf0e10cSrcweir 								  &values );
229cdf0e10cSrcweir 	}
230cdf0e10cSrcweir 
231cdf0e10cSrcweir 	if( !bInvert50GC_ )
232cdf0e10cSrcweir 	{
233cdf0e10cSrcweir 		SetClipRegion( pInvert50GC_ );
234cdf0e10cSrcweir 		bInvert50GC_ = sal_True;
235cdf0e10cSrcweir 	}
236cdf0e10cSrcweir 	return pInvert50GC_;
237cdf0e10cSrcweir }
238cdf0e10cSrcweir 
239cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
GetStippleGC()240cdf0e10cSrcweir inline GC X11SalGraphics::GetStippleGC()
241cdf0e10cSrcweir {
242cdf0e10cSrcweir 	if( !pStippleGC_ )
243cdf0e10cSrcweir 		pStippleGC_ = CreateGC( GetDrawable(),
244cdf0e10cSrcweir 								GCGraphicsExposures
245cdf0e10cSrcweir 								| GCFillStyle
246cdf0e10cSrcweir 								| GCLineWidth );
247cdf0e10cSrcweir 
248cdf0e10cSrcweir 	if( !bStippleGC_ )
249cdf0e10cSrcweir 	{
250cdf0e10cSrcweir 		XSetFunction( GetXDisplay(), pStippleGC_, bXORMode_ ? GXxor : GXcopy );
251cdf0e10cSrcweir 		SetClipRegion( pStippleGC_ );
252cdf0e10cSrcweir 		bStippleGC_ = sal_True;
253cdf0e10cSrcweir 	}
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 	return pStippleGC_;
256cdf0e10cSrcweir }
257cdf0e10cSrcweir 
258cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Clip(XLIB_Region pRegion,int & nX,int & nY,unsigned int & nDX,unsigned int & nDY,int & nSrcX,int & nSrcY) const259cdf0e10cSrcweir int X11SalGraphics::Clip( XLIB_Region   pRegion,
260cdf0e10cSrcweir 								 int          &nX,
261cdf0e10cSrcweir 								 int          &nY,
262cdf0e10cSrcweir 								 unsigned int &nDX,
263cdf0e10cSrcweir 								 unsigned int &nDY,
264cdf0e10cSrcweir 								 int          &nSrcX,
265cdf0e10cSrcweir 								 int          &nSrcY ) const
266cdf0e10cSrcweir {
267cdf0e10cSrcweir 	XRectangle aRect;
268cdf0e10cSrcweir 	XClipBox( pRegion, &aRect );
269cdf0e10cSrcweir 
270cdf0e10cSrcweir 	if( int(nX + nDX) <= int(aRect.x) || nX >= int(aRect.x + aRect.width) )
271cdf0e10cSrcweir 		return RectangleOut;
272cdf0e10cSrcweir 	if( int(nY + nDY) <= int(aRect.y) || nY >= int(aRect.y + aRect.height) )
273cdf0e10cSrcweir 		return RectangleOut;
274cdf0e10cSrcweir 
275cdf0e10cSrcweir 	if( nX < aRect.x )
276cdf0e10cSrcweir 	{
277cdf0e10cSrcweir 		nSrcX += aRect.x - nX;
278cdf0e10cSrcweir 		nDX   -= aRect.x - nX;
279cdf0e10cSrcweir 		nX     = aRect.x;
280cdf0e10cSrcweir 	}
281cdf0e10cSrcweir 	else if( int(nX + nDX) > int(aRect.x + aRect.width) )
282cdf0e10cSrcweir 		nDX = aRect.x + aRect.width - nX;
283cdf0e10cSrcweir 
284cdf0e10cSrcweir 	if( nY < aRect.y )
285cdf0e10cSrcweir 	{
286cdf0e10cSrcweir 		nSrcY += aRect.y - nY;
287cdf0e10cSrcweir 		nDY   -= aRect.y - nY;
288cdf0e10cSrcweir 		nY     = aRect.y;
289cdf0e10cSrcweir 	}
290cdf0e10cSrcweir 	else if( int(nY + nDY) > int(aRect.y + aRect.height) )
291cdf0e10cSrcweir 		nDY = aRect.y + aRect.height - nY;
292cdf0e10cSrcweir 
293cdf0e10cSrcweir 	return RectangleIn;
294cdf0e10cSrcweir }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Clip(int & nX,int & nY,unsigned int & nDX,unsigned int & nDY,int & nSrcX,int & nSrcY) const297cdf0e10cSrcweir int X11SalGraphics::Clip( int          &nX,
298cdf0e10cSrcweir 								 int          &nY,
299cdf0e10cSrcweir 								 unsigned int &nDX,
300cdf0e10cSrcweir 								 unsigned int &nDY,
301cdf0e10cSrcweir 								 int          &nSrcX,
302cdf0e10cSrcweir 								 int          &nSrcY ) const
303cdf0e10cSrcweir 
304cdf0e10cSrcweir {
305cdf0e10cSrcweir 	if( pPaintRegion_
306cdf0e10cSrcweir 		&& RectangleOut == Clip( pPaintRegion_, nX, nY, nDX, nDY, nSrcX, nSrcY ) )
307cdf0e10cSrcweir 		return RectangleOut;
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 	if( mpClipRegion
310cdf0e10cSrcweir 		&& RectangleOut == Clip( mpClipRegion,  nX, nY, nDX, nDY, nSrcX, nSrcY ) )
311cdf0e10cSrcweir 		return RectangleOut;
312cdf0e10cSrcweir 
313cdf0e10cSrcweir 	int nPaint;
314cdf0e10cSrcweir 	if( pPaintRegion_ )
315cdf0e10cSrcweir 	{
316cdf0e10cSrcweir 		nPaint = XRectInRegion( pPaintRegion_, nX, nY, nDX, nDY );
317cdf0e10cSrcweir 		if( RectangleOut == nPaint )
318cdf0e10cSrcweir 			return RectangleOut;
319cdf0e10cSrcweir 	}
320cdf0e10cSrcweir 	else
321cdf0e10cSrcweir 		nPaint = RectangleIn;
322cdf0e10cSrcweir 
323cdf0e10cSrcweir 	int nClip;
324cdf0e10cSrcweir 	if( mpClipRegion )
325cdf0e10cSrcweir 	{
326cdf0e10cSrcweir 		nClip = XRectInRegion( mpClipRegion, nX, nY, nDX, nDY );
327cdf0e10cSrcweir 		if( RectangleOut == nClip )
328cdf0e10cSrcweir 			return RectangleOut;
329cdf0e10cSrcweir 	}
330cdf0e10cSrcweir 	else
331cdf0e10cSrcweir 		nClip = RectangleIn;
332cdf0e10cSrcweir 
333cdf0e10cSrcweir 	return RectangleIn == nClip && RectangleIn == nPaint
334cdf0e10cSrcweir 		   ? RectangleIn
335cdf0e10cSrcweir 		   : RectanglePart;
336cdf0e10cSrcweir }
337cdf0e10cSrcweir 
338cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
SetMask(int & nX,int & nY,unsigned int & nDX,unsigned int & nDY,int & nSrcX,int & nSrcY,Pixmap hClipMask)339cdf0e10cSrcweir GC X11SalGraphics::SetMask( int           &nX,
340cdf0e10cSrcweir 								   int           &nY,
341cdf0e10cSrcweir 								   unsigned int &nDX,
342cdf0e10cSrcweir 								   unsigned int &nDY,
343cdf0e10cSrcweir 								   int          &nSrcX,
344cdf0e10cSrcweir 								   int          &nSrcY,
345cdf0e10cSrcweir 								   Pixmap        hClipMask )
346cdf0e10cSrcweir {
347cdf0e10cSrcweir 	int n = Clip( nX, nY, nDX, nDY, nSrcX, nSrcY );
348cdf0e10cSrcweir 	if( RectangleOut == n )
349cdf0e10cSrcweir 		return NULL;
350cdf0e10cSrcweir 
351cdf0e10cSrcweir 	Display *pDisplay = GetXDisplay();
352cdf0e10cSrcweir 
353cdf0e10cSrcweir 	if( !pMaskGC_ )
354cdf0e10cSrcweir 		pMaskGC_ = CreateGC( GetDrawable() );
355cdf0e10cSrcweir 
356cdf0e10cSrcweir 	if( RectangleIn == n )
357cdf0e10cSrcweir 	{
358cdf0e10cSrcweir 		XSetClipMask( pDisplay, pMaskGC_, hClipMask );
359cdf0e10cSrcweir 		XSetClipOrigin( pDisplay, pMaskGC_, nX - nSrcX, nY - nSrcY );
360cdf0e10cSrcweir 		return pMaskGC_;
361cdf0e10cSrcweir 	}
362cdf0e10cSrcweir 
363cdf0e10cSrcweir 	// - - - - create alternate clip pixmap for region clipping - - - -
364cdf0e10cSrcweir 	Pixmap hPixmap	= XCreatePixmap( pDisplay, hClipMask, nDX, nDY, 1 );
365cdf0e10cSrcweir 
366cdf0e10cSrcweir 	if( !hPixmap )
367cdf0e10cSrcweir 	{
368cdf0e10cSrcweir #if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
369cdf0e10cSrcweir 		fprintf( stderr, "X11SalGraphics::SetMask !hPixmap\n" );
370cdf0e10cSrcweir #endif
371cdf0e10cSrcweir 		return NULL;
372cdf0e10cSrcweir 	}
373cdf0e10cSrcweir 
374cdf0e10cSrcweir 	// - - - - reset pixmap; all 0 - - - - - - - - - - - - - - - - - - -
375cdf0e10cSrcweir 	XFillRectangle( pDisplay,
376cdf0e10cSrcweir 					hPixmap,
377cdf0e10cSrcweir 					GetDisplay()->GetMonoGC( m_nScreen ),
378cdf0e10cSrcweir 					0,   0,
379cdf0e10cSrcweir 					nDX, nDY );
380cdf0e10cSrcweir 
381cdf0e10cSrcweir 	// - - - - copy pixmap only within region - - - - - - - - - - - - -
382cdf0e10cSrcweir 	GC pMonoGC = GetMonoGC( hPixmap );
383cdf0e10cSrcweir 	XSetClipOrigin( pDisplay, pMonoGC, -nX, -nY );
384cdf0e10cSrcweir 	XCopyArea( pDisplay,
385cdf0e10cSrcweir 			   hClipMask,			// Source
386cdf0e10cSrcweir 			   hPixmap,				// Destination
387cdf0e10cSrcweir 			   pMonoGC,
388cdf0e10cSrcweir 			   nSrcX, nSrcY,		// Source
389cdf0e10cSrcweir 			   nDX,   nDY,			// Width & Height
390cdf0e10cSrcweir 			   0,     0 );			// Destination
391cdf0e10cSrcweir 
392cdf0e10cSrcweir 	XSetClipMask( pDisplay, pMaskGC_, hPixmap );
393cdf0e10cSrcweir 	XSetClipOrigin( pDisplay, pMaskGC_, nX, nY );
394cdf0e10cSrcweir 
395cdf0e10cSrcweir 	XFreePixmap( pDisplay, hPixmap );
396cdf0e10cSrcweir 	return pMaskGC_;
397cdf0e10cSrcweir }
398cdf0e10cSrcweir 
399cdf0e10cSrcweir // -=-= SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
400cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
401cdf0e10cSrcweir 
402cdf0e10cSrcweir extern "C"
403cdf0e10cSrcweir {
GraphicsExposePredicate(Display *,XEvent * pEvent,XPointer pFrameWindow)404cdf0e10cSrcweir     static Bool GraphicsExposePredicate( Display*, XEvent* pEvent, XPointer pFrameWindow )
405cdf0e10cSrcweir     {
406cdf0e10cSrcweir         Bool bRet = False;
407cdf0e10cSrcweir         if( (pEvent->type == GraphicsExpose || pEvent->type == NoExpose) &&
408cdf0e10cSrcweir             pEvent->xnoexpose.drawable == (Drawable)pFrameWindow )
409cdf0e10cSrcweir         {
410cdf0e10cSrcweir             bRet = True;
411cdf0e10cSrcweir         }
412cdf0e10cSrcweir         return bRet;
413cdf0e10cSrcweir     }
414cdf0e10cSrcweir }
415cdf0e10cSrcweir 
416cdf0e10cSrcweir 
YieldGraphicsExpose()417cdf0e10cSrcweir void X11SalGraphics::YieldGraphicsExpose()
418cdf0e10cSrcweir {
419cdf0e10cSrcweir     // get frame if necessary
420cdf0e10cSrcweir     SalFrame* pFrame    = m_pFrame;
421cdf0e10cSrcweir     Display* pDisplay   = GetXDisplay();
422cdf0e10cSrcweir     XLIB_Window aWindow = GetDrawable();
423cdf0e10cSrcweir     if( ! pFrame )
424cdf0e10cSrcweir     {
425cdf0e10cSrcweir         const std::list< SalFrame* >& rFrames = GetX11SalData()->GetDisplay()->getFrames();
426cdf0e10cSrcweir         for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end() && ! pFrame; ++it )
427cdf0e10cSrcweir         {
428cdf0e10cSrcweir             const SystemEnvData* pEnvData = (*it)->GetSystemData();
429cdf0e10cSrcweir             if( Drawable(pEnvData->aWindow) == aWindow )
430cdf0e10cSrcweir                 pFrame = *it;
431cdf0e10cSrcweir         }
432cdf0e10cSrcweir         if( ! pFrame )
433cdf0e10cSrcweir             return;
434cdf0e10cSrcweir     }
435cdf0e10cSrcweir 
436cdf0e10cSrcweir     XEvent aEvent;
437cdf0e10cSrcweir     while( XCheckTypedWindowEvent( pDisplay, aWindow, Expose, &aEvent ) )
438cdf0e10cSrcweir     {
439cdf0e10cSrcweir         SalPaintEvent aPEvt( aEvent.xexpose.x, aEvent.xexpose.y, aEvent.xexpose.width+1, aEvent.xexpose.height+1 );
440cdf0e10cSrcweir         pFrame->CallCallback( SALEVENT_PAINT, &aPEvt );
441cdf0e10cSrcweir     }
442cdf0e10cSrcweir 
443cdf0e10cSrcweir     do
444cdf0e10cSrcweir     {
445cdf0e10cSrcweir         if( ! GetDisplay()->XIfEventWithTimeout( &aEvent, (XPointer)aWindow, GraphicsExposePredicate ) )
446cdf0e10cSrcweir             // this should not happen at all; still sometimes it happens
447cdf0e10cSrcweir             break;
448cdf0e10cSrcweir 
449cdf0e10cSrcweir         if( aEvent.type == NoExpose )
450cdf0e10cSrcweir             break;
451cdf0e10cSrcweir 
452cdf0e10cSrcweir         if( pFrame )
453cdf0e10cSrcweir         {
454cdf0e10cSrcweir             SalPaintEvent aPEvt( aEvent.xgraphicsexpose.x, aEvent.xgraphicsexpose.y, aEvent.xgraphicsexpose.width+1, aEvent.xgraphicsexpose.height+1 );
455cdf0e10cSrcweir             pFrame->CallCallback( SALEVENT_PAINT, &aPEvt );
456cdf0e10cSrcweir         }
457cdf0e10cSrcweir     } while( aEvent.xgraphicsexpose.count != 0 );
458cdf0e10cSrcweir }
459cdf0e10cSrcweir 
copyBits(const SalTwoRect & rPosAry,SalGraphics * pSSrcGraphics)460*5f27b83cSArmin Le Grand void X11SalGraphics::copyBits( const SalTwoRect& rPosAry,
461cdf0e10cSrcweir 								  SalGraphics	   *pSSrcGraphics )
462cdf0e10cSrcweir {
463cdf0e10cSrcweir     X11SalGraphics* pSrcGraphics = pSSrcGraphics
464cdf0e10cSrcweir         ? static_cast<X11SalGraphics*>(pSSrcGraphics)
465cdf0e10cSrcweir         : this;
466cdf0e10cSrcweir 
467*5f27b83cSArmin Le Grand     if( rPosAry.mnSrcWidth <= 0
468*5f27b83cSArmin Le Grand         || rPosAry.mnSrcHeight <= 0
469*5f27b83cSArmin Le Grand         || rPosAry.mnDestWidth <= 0
470*5f27b83cSArmin Le Grand         || rPosAry.mnDestHeight <= 0 )
471cdf0e10cSrcweir     {
472cdf0e10cSrcweir         return;
473cdf0e10cSrcweir     }
474cdf0e10cSrcweir 
475cdf0e10cSrcweir     int n;
476cdf0e10cSrcweir     if( pSrcGraphics == this )
477cdf0e10cSrcweir     {
478cdf0e10cSrcweir         n = 2;
479cdf0e10cSrcweir     }
480cdf0e10cSrcweir     else if( pSrcGraphics->bWindow_ )
481cdf0e10cSrcweir     {
482cdf0e10cSrcweir         // window or compatible virtual device
483cdf0e10cSrcweir         if( pSrcGraphics->GetDisplay() == GetDisplay() &&
484cdf0e10cSrcweir             pSrcGraphics->m_nScreen == m_nScreen &&
485cdf0e10cSrcweir             pSrcGraphics->GetVisual().GetDepth() == GetVisual().GetDepth()
486cdf0e10cSrcweir             )
487cdf0e10cSrcweir             n = 2; // same Display
488cdf0e10cSrcweir         else
489cdf0e10cSrcweir             n = 1; // printer or other display
490cdf0e10cSrcweir     }
491cdf0e10cSrcweir     else if( pSrcGraphics->bVirDev_ )
492cdf0e10cSrcweir     {
493cdf0e10cSrcweir         // printer compatible virtual device
494cdf0e10cSrcweir         if( bPrinter_ )
495cdf0e10cSrcweir             n = 2; // printer or compatible virtual device == same display
496cdf0e10cSrcweir         else
497cdf0e10cSrcweir             n = 1; // window or compatible virtual device
498cdf0e10cSrcweir     }
499cdf0e10cSrcweir     else
500cdf0e10cSrcweir         n = 0;
501cdf0e10cSrcweir 
502cdf0e10cSrcweir     if( n == 2
503*5f27b83cSArmin Le Grand         && rPosAry.mnSrcWidth	== rPosAry.mnDestWidth
504*5f27b83cSArmin Le Grand         && rPosAry.mnSrcHeight == rPosAry.mnDestHeight
505cdf0e10cSrcweir         )
506cdf0e10cSrcweir     {
507cdf0e10cSrcweir         // #i60699# Need to generate graphics exposures (to repaint
508cdf0e10cSrcweir         // obscured areas beneath overlapping windows), src and dest
509cdf0e10cSrcweir         // are the same window.
510cdf0e10cSrcweir         const bool bNeedGraphicsExposures( pSrcGraphics == this &&
511cdf0e10cSrcweir                                            !bVirDev_ &&
512cdf0e10cSrcweir                                            pSrcGraphics->bWindow_ );
513cdf0e10cSrcweir 
514cdf0e10cSrcweir         GC pCopyGC;
515cdf0e10cSrcweir 
516cdf0e10cSrcweir         if( bXORMode_
517cdf0e10cSrcweir             && !pSrcGraphics->bVirDev_
518cdf0e10cSrcweir             && (GetDisplay()->GetProperties() & PROPERTY_BUG_XCopyArea_GXxor) )
519cdf0e10cSrcweir         {
520cdf0e10cSrcweir             Pixmap hPixmap = XCreatePixmap( GetXDisplay(),
521cdf0e10cSrcweir                                             pSrcGraphics->GetDrawable(),		// source
522*5f27b83cSArmin Le Grand                                             rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
523cdf0e10cSrcweir                                             pSrcGraphics->GetBitCount() );
524cdf0e10cSrcweir 
525cdf0e10cSrcweir             pCopyGC = GetDisplay()->GetCopyGC( m_nScreen );
526cdf0e10cSrcweir 
527cdf0e10cSrcweir             if( bNeedGraphicsExposures )
528cdf0e10cSrcweir                 XSetGraphicsExposures( GetXDisplay(),
529cdf0e10cSrcweir                                        pCopyGC,
530cdf0e10cSrcweir                                        True );
531cdf0e10cSrcweir 
532cdf0e10cSrcweir             XCopyArea( GetXDisplay(),
533cdf0e10cSrcweir                        pSrcGraphics->GetDrawable(),		// source
534cdf0e10cSrcweir                        hPixmap,							// destination
535cdf0e10cSrcweir                        pCopyGC,							// no clipping
536*5f27b83cSArmin Le Grand                        rPosAry.mnSrcX,     rPosAry.mnSrcY,
537*5f27b83cSArmin Le Grand                        rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
538cdf0e10cSrcweir                        0,    				0 );			// destination
539cdf0e10cSrcweir             XCopyArea( GetXDisplay(),
540cdf0e10cSrcweir                        hPixmap,								// source
541cdf0e10cSrcweir                        GetDrawable(),						// destination
542cdf0e10cSrcweir                        GetInvertGC(),		// destination clipping
543cdf0e10cSrcweir                        0,				    0,				// source
544*5f27b83cSArmin Le Grand                        rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
545*5f27b83cSArmin Le Grand                        rPosAry.mnDestX,    rPosAry.mnDestY );
546cdf0e10cSrcweir             XFreePixmap( GetXDisplay(), hPixmap );
547cdf0e10cSrcweir         }
548cdf0e10cSrcweir         else
549cdf0e10cSrcweir         {
550cdf0e10cSrcweir             pCopyGC = GetCopyGC();
551cdf0e10cSrcweir 
552cdf0e10cSrcweir             if( bNeedGraphicsExposures )
553cdf0e10cSrcweir                 XSetGraphicsExposures( GetXDisplay(),
554cdf0e10cSrcweir                                        pCopyGC,
555cdf0e10cSrcweir                                        True );
556cdf0e10cSrcweir 
557cdf0e10cSrcweir             XCopyArea( GetXDisplay(),
558cdf0e10cSrcweir                        pSrcGraphics->GetDrawable(),		// source
559cdf0e10cSrcweir                        GetDrawable(),					// destination
560cdf0e10cSrcweir                        pCopyGC,							// destination clipping
561*5f27b83cSArmin Le Grand                        rPosAry.mnSrcX,     rPosAry.mnSrcY,
562*5f27b83cSArmin Le Grand                        rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
563*5f27b83cSArmin Le Grand                        rPosAry.mnDestX,    rPosAry.mnDestY );
564cdf0e10cSrcweir         }
565cdf0e10cSrcweir 
566cdf0e10cSrcweir         if( bNeedGraphicsExposures )
567cdf0e10cSrcweir         {
568cdf0e10cSrcweir             YieldGraphicsExpose();
569cdf0e10cSrcweir 
570cdf0e10cSrcweir             if( pCopyGC )
571cdf0e10cSrcweir                 XSetGraphicsExposures( GetXDisplay(),
572cdf0e10cSrcweir                                        pCopyGC,
573cdf0e10cSrcweir                                        False );
574cdf0e10cSrcweir         }
575cdf0e10cSrcweir     }
576cdf0e10cSrcweir     else if( n )
577cdf0e10cSrcweir     {
578cdf0e10cSrcweir         // #i60699# No chance to handle graphics exposures - we copy
579cdf0e10cSrcweir         // to a temp bitmap first, into which no repaints are
580cdf0e10cSrcweir         // technically possible.
581*5f27b83cSArmin Le Grand         SalBitmap *pDDB = pSrcGraphics->getBitmap( rPosAry.mnSrcX,
582*5f27b83cSArmin Le Grand                                                    rPosAry.mnSrcY,
583*5f27b83cSArmin Le Grand                                                    rPosAry.mnSrcWidth,
584*5f27b83cSArmin Le Grand                                                    rPosAry.mnSrcHeight );
585cdf0e10cSrcweir 
586cdf0e10cSrcweir         if( !pDDB )
587cdf0e10cSrcweir         {
588cdf0e10cSrcweir             stderr0( "SalGraphics::CopyBits !pSrcGraphics->GetBitmap()\n" );
589cdf0e10cSrcweir             return;
590cdf0e10cSrcweir         }
591cdf0e10cSrcweir 
592*5f27b83cSArmin Le Grand         SalTwoRect aPosAry( rPosAry );
593cdf0e10cSrcweir 
594cdf0e10cSrcweir         aPosAry.mnSrcX = 0,	aPosAry.mnSrcY = 0;
595*5f27b83cSArmin Le Grand         drawBitmap( aPosAry, *pDDB );
596cdf0e10cSrcweir 
597cdf0e10cSrcweir         delete pDDB;
598cdf0e10cSrcweir     }
599cdf0e10cSrcweir     else {
600cdf0e10cSrcweir         stderr0( "X11SalGraphics::CopyBits from Printer not yet implemented\n" );
601cdf0e10cSrcweir     }
602cdf0e10cSrcweir }
603cdf0e10cSrcweir 
604cdf0e10cSrcweir // --------------------------------------------------------------------------
605cdf0e10cSrcweir 
copyArea(long nDestX,long nDestY,long nSrcX,long nSrcY,long nSrcWidth,long nSrcHeight,sal_uInt16)606cdf0e10cSrcweir void X11SalGraphics::copyArea ( long nDestX,    long nDestY,
607cdf0e10cSrcweir                                 long nSrcX,     long nSrcY,
608cdf0e10cSrcweir                                 long nSrcWidth, long nSrcHeight,
609cdf0e10cSrcweir                                 sal_uInt16 )
610cdf0e10cSrcweir {
611cdf0e10cSrcweir     SalTwoRect aPosAry;
612cdf0e10cSrcweir 
613cdf0e10cSrcweir     aPosAry.mnDestX = nDestX;
614cdf0e10cSrcweir     aPosAry.mnDestY = nDestY;
615cdf0e10cSrcweir     aPosAry.mnDestWidth  = nSrcWidth;
616cdf0e10cSrcweir     aPosAry.mnDestHeight = nSrcHeight;
617cdf0e10cSrcweir 
618cdf0e10cSrcweir     aPosAry.mnSrcX = nSrcX;
619cdf0e10cSrcweir     aPosAry.mnSrcY = nSrcY;
620cdf0e10cSrcweir     aPosAry.mnSrcWidth  = nSrcWidth;
621cdf0e10cSrcweir     aPosAry.mnSrcHeight = nSrcHeight;
622cdf0e10cSrcweir 
623*5f27b83cSArmin Le Grand     copyBits ( aPosAry, 0 );
624cdf0e10cSrcweir }
625cdf0e10cSrcweir 
626cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
drawBitmap(const SalTwoRect & rPosAry,const SalBitmap & rSalBitmap)627*5f27b83cSArmin Le Grand void X11SalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
628cdf0e10cSrcweir {
629cdf0e10cSrcweir     const SalDisplay*   pSalDisp = GetDisplay();
630cdf0e10cSrcweir     Display*			pXDisp = pSalDisp->GetDisplay();
631cdf0e10cSrcweir     const Drawable		aDrawable( GetDrawable() );
632cdf0e10cSrcweir     const SalColormap&	rColMap = pSalDisp->GetColormap( m_nScreen );
633cdf0e10cSrcweir     const long			nDepth = GetDisplay()->GetVisual( m_nScreen ).GetDepth();
634cdf0e10cSrcweir     GC					aGC( GetCopyGC() );
635cdf0e10cSrcweir     XGCValues			aOldVal, aNewVal;
636cdf0e10cSrcweir     int					nValues = GCForeground | GCBackground;
637cdf0e10cSrcweir 
638cdf0e10cSrcweir     if( rSalBitmap.GetBitCount() == 1 )
639cdf0e10cSrcweir     {
640cdf0e10cSrcweir         // set foreground/background values for 1Bit bitmaps
641cdf0e10cSrcweir         XGetGCValues( pXDisp, aGC, nValues, &aOldVal );
642cdf0e10cSrcweir         aNewVal.foreground = rColMap.GetWhitePixel(), aNewVal.background = rColMap.GetBlackPixel();
643cdf0e10cSrcweir         XChangeGC( pXDisp, aGC, nValues, &aNewVal );
644cdf0e10cSrcweir     }
645cdf0e10cSrcweir 
646*5f27b83cSArmin Le Grand     static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aDrawable, m_nScreen, nDepth, rPosAry, aGC );
647cdf0e10cSrcweir 
648cdf0e10cSrcweir     if( rSalBitmap.GetBitCount() == 1 )
649cdf0e10cSrcweir         XChangeGC( pXDisp, aGC, nValues, &aOldVal );
650cdf0e10cSrcweir     XFlush( pXDisp );
651cdf0e10cSrcweir }
652cdf0e10cSrcweir 
653cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
654cdf0e10cSrcweir 
drawBitmap(const SalTwoRect & rPosAry,const SalBitmap & rSrcBitmap,const SalBitmap & rMaskBitmap)655*5f27b83cSArmin Le Grand void X11SalGraphics::drawBitmap( const SalTwoRect& rPosAry,
656cdf0e10cSrcweir                                  const SalBitmap& rSrcBitmap,
657cdf0e10cSrcweir                                  const SalBitmap& rMaskBitmap )
658cdf0e10cSrcweir {
659cdf0e10cSrcweir     DBG_ASSERT( !bPrinter_, "Drawing of transparent bitmaps on printer devices is strictly forbidden" );
660cdf0e10cSrcweir 
661cdf0e10cSrcweir     // decide if alpha masking or transparency masking is needed
662cdf0e10cSrcweir     BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rMaskBitmap).AcquireBuffer( sal_True );
663cdf0e10cSrcweir     if( pAlphaBuffer != NULL )
664cdf0e10cSrcweir     {
665cdf0e10cSrcweir         int nMaskFormat = pAlphaBuffer->mnFormat;
666cdf0e10cSrcweir         const_cast<SalBitmap&>(rMaskBitmap).ReleaseBuffer( pAlphaBuffer, sal_True );
667cdf0e10cSrcweir         if( nMaskFormat == BMP_FORMAT_8BIT_PAL )
668*5f27b83cSArmin Le Grand             drawAlphaBitmap( rPosAry, rSrcBitmap, rMaskBitmap );
669cdf0e10cSrcweir     }
670cdf0e10cSrcweir 
671*5f27b83cSArmin Le Grand     drawMaskedBitmap( rPosAry, rSrcBitmap, rMaskBitmap );
672cdf0e10cSrcweir }
673cdf0e10cSrcweir 
674cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
675cdf0e10cSrcweir 
drawMaskedBitmap(const SalTwoRect & rPosAry,const SalBitmap & rSalBitmap,const SalBitmap & rTransBitmap)676*5f27b83cSArmin Le Grand void X11SalGraphics::drawMaskedBitmap( const SalTwoRect& rPosAry,
677cdf0e10cSrcweir                                        const SalBitmap& rSalBitmap,
678cdf0e10cSrcweir                                        const SalBitmap& rTransBitmap )
679cdf0e10cSrcweir {
680cdf0e10cSrcweir     const SalDisplay*   pSalDisp = GetDisplay();
681cdf0e10cSrcweir     Display*            pXDisp = pSalDisp->GetDisplay();
682cdf0e10cSrcweir     Drawable            aDrawable( GetDrawable() );
683cdf0e10cSrcweir 
684cdf0e10cSrcweir     // figure work mode depth. If this is a VDev Drawable, use its
685cdf0e10cSrcweir     // bitdepth to create pixmaps for, otherwise, XCopyArea will
686cdf0e10cSrcweir     // refuse to work.
687cdf0e10cSrcweir     const sal_uInt16	nDepth( m_pVDev ?
688cdf0e10cSrcweir                             m_pVDev->GetDepth() :
689cdf0e10cSrcweir                             pSalDisp->GetVisual( m_nScreen ).GetDepth() );
690*5f27b83cSArmin Le Grand     Pixmap			aFG( XCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth,
691*5f27b83cSArmin Le Grand                                         rPosAry.mnDestHeight, nDepth ) );
692*5f27b83cSArmin Le Grand     Pixmap			aBG( XCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth,
693*5f27b83cSArmin Le Grand                                         rPosAry.mnDestHeight, nDepth ) );
694cdf0e10cSrcweir 
695cdf0e10cSrcweir     if( aFG && aBG )
696cdf0e10cSrcweir     {
697cdf0e10cSrcweir         GC					aTmpGC;
698cdf0e10cSrcweir         XGCValues			aValues;
699cdf0e10cSrcweir         const SalColormap&	rColMap = pSalDisp->GetColormap( m_nScreen );
700cdf0e10cSrcweir         const int			nBlack = rColMap.GetBlackPixel(), nWhite = rColMap.GetWhitePixel();
701cdf0e10cSrcweir         const int			nValues = GCFunction | GCForeground | GCBackground;
702*5f27b83cSArmin Le Grand         SalTwoRect			aTmpRect( rPosAry ); aTmpRect.mnDestX = aTmpRect.mnDestY = 0;
703cdf0e10cSrcweir 
704cdf0e10cSrcweir         // draw paint bitmap in pixmap #1
705cdf0e10cSrcweir         aValues.function = GXcopy, aValues.foreground = nWhite, aValues.background = nBlack;
706cdf0e10cSrcweir         aTmpGC = XCreateGC( pXDisp, aFG, nValues, &aValues );
707cdf0e10cSrcweir         static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aFG, m_nScreen, nDepth, aTmpRect, aTmpGC );
708cdf0e10cSrcweir         DBG_TESTTRANS( aFG );
709cdf0e10cSrcweir 
710cdf0e10cSrcweir         // draw background in pixmap #2
711cdf0e10cSrcweir         XCopyArea( pXDisp, aDrawable, aBG, aTmpGC,
712*5f27b83cSArmin Le Grand                    rPosAry.mnDestX, rPosAry.mnDestY,
713*5f27b83cSArmin Le Grand                    rPosAry.mnDestWidth, rPosAry.mnDestHeight,
714cdf0e10cSrcweir                    0, 0 );
715cdf0e10cSrcweir 
716cdf0e10cSrcweir         DBG_TESTTRANS( aBG );
717cdf0e10cSrcweir 
718cdf0e10cSrcweir         // mask out paint bitmap in pixmap #1 (transparent areas 0)
719cdf0e10cSrcweir         aValues.function = GXand, aValues.foreground = 0x00000000, aValues.background = 0xffffffff;
720cdf0e10cSrcweir         XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
721cdf0e10cSrcweir         static_cast<const X11SalBitmap&>(rTransBitmap).ImplDraw( aFG, m_nScreen, 1, aTmpRect, aTmpGC );
722cdf0e10cSrcweir 
723cdf0e10cSrcweir         DBG_TESTTRANS( aFG );
724cdf0e10cSrcweir 
725cdf0e10cSrcweir         // #105055# For XOR mode, keep background behind bitmap intact
726cdf0e10cSrcweir         if( !bXORMode_ )
727cdf0e10cSrcweir         {
728cdf0e10cSrcweir             // mask out background in pixmap #2 (nontransparent areas 0)
729cdf0e10cSrcweir             aValues.function = GXand, aValues.foreground = 0xffffffff, aValues.background = 0x00000000;
730cdf0e10cSrcweir             XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
731cdf0e10cSrcweir             static_cast<const X11SalBitmap&>(rTransBitmap).ImplDraw( aBG, m_nScreen, 1, aTmpRect, aTmpGC );
732cdf0e10cSrcweir 
733cdf0e10cSrcweir             DBG_TESTTRANS( aBG );
734cdf0e10cSrcweir         }
735cdf0e10cSrcweir 
736cdf0e10cSrcweir         // merge pixmap #1 and pixmap #2 in pixmap #2
737cdf0e10cSrcweir         aValues.function = GXxor, aValues.foreground = 0xffffffff, aValues.background = 0x00000000;
738cdf0e10cSrcweir         XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
739cdf0e10cSrcweir         XCopyArea( pXDisp, aFG, aBG, aTmpGC,
740cdf0e10cSrcweir                    0, 0,
741*5f27b83cSArmin Le Grand                    rPosAry.mnDestWidth, rPosAry.mnDestHeight,
742cdf0e10cSrcweir 				   0, 0 );
743cdf0e10cSrcweir         DBG_TESTTRANS( aBG );
744cdf0e10cSrcweir 
745cdf0e10cSrcweir         // #105055# Disable XOR temporarily
746cdf0e10cSrcweir         sal_Bool bOldXORMode( bXORMode_ );
747cdf0e10cSrcweir         bXORMode_ = sal_False;
748cdf0e10cSrcweir 
749cdf0e10cSrcweir         // copy pixmap #2 (result) to background
750cdf0e10cSrcweir         XCopyArea( pXDisp, aBG, aDrawable, GetCopyGC(),
751cdf0e10cSrcweir                    0, 0,
752*5f27b83cSArmin Le Grand                    rPosAry.mnDestWidth, rPosAry.mnDestHeight,
753*5f27b83cSArmin Le Grand                    rPosAry.mnDestX, rPosAry.mnDestY );
754cdf0e10cSrcweir 
755cdf0e10cSrcweir         DBG_TESTTRANS( aBG );
756cdf0e10cSrcweir 
757cdf0e10cSrcweir         bXORMode_ = bOldXORMode;
758cdf0e10cSrcweir 
759cdf0e10cSrcweir         XFreeGC( pXDisp, aTmpGC );
760cdf0e10cSrcweir         XFlush( pXDisp );
761cdf0e10cSrcweir     }
762cdf0e10cSrcweir     else
763*5f27b83cSArmin Le Grand         drawBitmap( rPosAry, rSalBitmap );
764cdf0e10cSrcweir 
765cdf0e10cSrcweir     if( aFG )
766cdf0e10cSrcweir         XFreePixmap( pXDisp, aFG );
767cdf0e10cSrcweir 
768cdf0e10cSrcweir     if( aBG )
769cdf0e10cSrcweir         XFreePixmap( pXDisp, aBG );
770cdf0e10cSrcweir }
771cdf0e10cSrcweir 
772cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
drawAlphaBitmap(const SalTwoRect & rTR,const SalBitmap & rSrcBitmap,const SalBitmap & rAlphaBmp)773cdf0e10cSrcweir bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
774cdf0e10cSrcweir     const SalBitmap& rSrcBitmap, const SalBitmap& rAlphaBmp )
775cdf0e10cSrcweir {
776cdf0e10cSrcweir     // non 8-bit alpha not implemented yet
777cdf0e10cSrcweir     if( rAlphaBmp.GetBitCount() != 8 )
778cdf0e10cSrcweir         return false;
779cdf0e10cSrcweir 
780cdf0e10cSrcweir     // horizontal mirroring not implemented yet
781cdf0e10cSrcweir     if( rTR.mnDestWidth < 0 )
782cdf0e10cSrcweir         return false;
783cdf0e10cSrcweir 
784cdf0e10cSrcweir     // stretched conversion is not implemented yet
785cdf0e10cSrcweir     if( rTR.mnDestWidth != rTR.mnSrcWidth )
786cdf0e10cSrcweir         return false;
787cdf0e10cSrcweir     if( rTR.mnDestHeight!= rTR.mnSrcHeight )
788cdf0e10cSrcweir         return false;
789cdf0e10cSrcweir 
790cdf0e10cSrcweir     XRenderPeer& rPeer = XRenderPeer::GetInstance();
791cdf0e10cSrcweir     if( rPeer.GetVersion() < 0x02 )
792cdf0e10cSrcweir         return false;
793cdf0e10cSrcweir 
794cdf0e10cSrcweir     // create destination picture
795cdf0e10cSrcweir     Picture aDstPic = GetXRenderPicture();
796cdf0e10cSrcweir     if( !aDstPic )
797cdf0e10cSrcweir         return false;
798cdf0e10cSrcweir 
799cdf0e10cSrcweir     const SalDisplay* pSalDisp = GetDisplay();
800cdf0e10cSrcweir     const SalVisual& rSalVis = pSalDisp->GetVisual( m_nScreen );
801cdf0e10cSrcweir     Display* pXDisplay = pSalDisp->GetDisplay();
802cdf0e10cSrcweir 
803cdf0e10cSrcweir     // create source Picture
804cdf0e10cSrcweir     int nDepth = m_pVDev ? m_pVDev->GetDepth() : rSalVis.GetDepth();
805cdf0e10cSrcweir     const X11SalBitmap& rSrcX11Bmp = static_cast<const X11SalBitmap&>( rSrcBitmap );
806cdf0e10cSrcweir     ImplSalDDB* pSrcDDB = rSrcX11Bmp.ImplGetDDB( hDrawable_, m_nScreen, nDepth, rTR );
807cdf0e10cSrcweir     if( !pSrcDDB )
808cdf0e10cSrcweir         return false;
809cdf0e10cSrcweir 
810cdf0e10cSrcweir     //#i75249# workaround for ImplGetDDB() giving us back a different depth than
811cdf0e10cSrcweir     // we requested. E.g. mask pixmaps are always compatible with the drawable
812cdf0e10cSrcweir     // TODO: find an appropriate picture format for these cases
813cdf0e10cSrcweir     //       then remove the workaround below and the one for #i75531#
814cdf0e10cSrcweir     if( nDepth != pSrcDDB->ImplGetDepth() )
815cdf0e10cSrcweir         return false;
816cdf0e10cSrcweir 
817cdf0e10cSrcweir     Pixmap aSrcPM = pSrcDDB->ImplGetPixmap();
818cdf0e10cSrcweir     if( !aSrcPM )
819cdf0e10cSrcweir         return false;
820cdf0e10cSrcweir 
821cdf0e10cSrcweir     // create source picture
822cdf0e10cSrcweir     // TODO: use scoped picture
823cdf0e10cSrcweir     Visual* pSrcXVisual = rSalVis.GetVisual();
824cdf0e10cSrcweir     XRenderPictFormat* pSrcVisFmt = rPeer.FindVisualFormat( pSrcXVisual );
825cdf0e10cSrcweir     if( !pSrcVisFmt )
826cdf0e10cSrcweir         return false;
827cdf0e10cSrcweir     Picture aSrcPic = rPeer.CreatePicture( aSrcPM, pSrcVisFmt, 0, NULL );
828cdf0e10cSrcweir     if( !aSrcPic )
829cdf0e10cSrcweir         return false;
830cdf0e10cSrcweir 
831cdf0e10cSrcweir     // create alpha Picture
832cdf0e10cSrcweir 
833cdf0e10cSrcweir     // TODO: use SalX11Bitmap functionality and caching for the Alpha Pixmap
834cdf0e10cSrcweir     // problem is that they don't provide an 8bit Pixmap on a non-8bit display
835cdf0e10cSrcweir     BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rAlphaBmp).AcquireBuffer( sal_True );
836cdf0e10cSrcweir 
837cdf0e10cSrcweir     // an XImage needs its data top_down
838cdf0e10cSrcweir     // TODO: avoid wrongly oriented images in upper layers!
839cdf0e10cSrcweir     const int nImageSize = pAlphaBuffer->mnHeight * pAlphaBuffer->mnScanlineSize;
840cdf0e10cSrcweir     const char* pSrcBits = (char*)pAlphaBuffer->mpBits;
841cdf0e10cSrcweir     char* pAlphaBits = new char[ nImageSize ];
842cdf0e10cSrcweir     if( BMP_SCANLINE_ADJUSTMENT( pAlphaBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
843cdf0e10cSrcweir         memcpy( pAlphaBits, pSrcBits, nImageSize );
844cdf0e10cSrcweir     else
845cdf0e10cSrcweir     {
846cdf0e10cSrcweir         char* pDstBits = pAlphaBits + nImageSize;
847cdf0e10cSrcweir         const int nLineSize = pAlphaBuffer->mnScanlineSize;
848cdf0e10cSrcweir         for(; (pDstBits -= nLineSize) >= pAlphaBits; pSrcBits += nLineSize )
849cdf0e10cSrcweir             memcpy( pDstBits, pSrcBits, nLineSize );
850cdf0e10cSrcweir     }
851cdf0e10cSrcweir 
852cdf0e10cSrcweir     // the alpha values need to be inverted for XRender
853cdf0e10cSrcweir     // TODO: make upper layers use standard alpha
854cdf0e10cSrcweir     long* pLDst = (long*)pAlphaBits;
855cdf0e10cSrcweir     for( int i = nImageSize/sizeof(long); --i >= 0; ++pLDst )
856cdf0e10cSrcweir         *pLDst = ~*pLDst;
857cdf0e10cSrcweir 
858cdf0e10cSrcweir     char* pCDst = (char*)pLDst;
859cdf0e10cSrcweir     for( int i = nImageSize & (sizeof(long)-1); --i >= 0; ++pCDst )
860cdf0e10cSrcweir         *pCDst = ~*pCDst;
861cdf0e10cSrcweir 
862cdf0e10cSrcweir     const XRenderPictFormat* pAlphaFormat = rPeer.GetStandardFormatA8();
863cdf0e10cSrcweir     XImage* pAlphaImg = XCreateImage( pXDisplay, pSrcXVisual, 8, ZPixmap, 0,
864cdf0e10cSrcweir         pAlphaBits, pAlphaBuffer->mnWidth, pAlphaBuffer->mnHeight,
865cdf0e10cSrcweir         pAlphaFormat->depth, pAlphaBuffer->mnScanlineSize );
866cdf0e10cSrcweir 
867cdf0e10cSrcweir     Pixmap aAlphaPM = XCreatePixmap( pXDisplay, hDrawable_,
868cdf0e10cSrcweir         rTR.mnDestWidth, rTR.mnDestHeight, 8 );
869cdf0e10cSrcweir 
870cdf0e10cSrcweir     XGCValues aAlphaGCV;
871cdf0e10cSrcweir     aAlphaGCV.function = GXcopy;
872cdf0e10cSrcweir     GC aAlphaGC = XCreateGC( pXDisplay, aAlphaPM, GCFunction, &aAlphaGCV );
873cdf0e10cSrcweir     XPutImage( pXDisplay, aAlphaPM, aAlphaGC, pAlphaImg,
874cdf0e10cSrcweir         rTR.mnSrcX, rTR.mnSrcY, 0, 0, rTR.mnDestWidth, rTR.mnDestHeight );
875cdf0e10cSrcweir     XFreeGC( pXDisplay, aAlphaGC );
876cdf0e10cSrcweir     XFree( pAlphaImg );
877cdf0e10cSrcweir     if( pAlphaBits != (char*)pAlphaBuffer->mpBits )
878cdf0e10cSrcweir         delete[] pAlphaBits;
879cdf0e10cSrcweir 
880cdf0e10cSrcweir     const_cast<SalBitmap&>(rAlphaBmp).ReleaseBuffer( pAlphaBuffer, sal_True );
881cdf0e10cSrcweir 
882cdf0e10cSrcweir     XRenderPictureAttributes aAttr;
883cdf0e10cSrcweir     aAttr.repeat = true;
884cdf0e10cSrcweir     Picture aAlphaPic = rPeer.CreatePicture( aAlphaPM, pAlphaFormat, CPRepeat, &aAttr );
885cdf0e10cSrcweir     if( !aAlphaPic )
886cdf0e10cSrcweir         return false;
887cdf0e10cSrcweir 
888cdf0e10cSrcweir     // set clipping
889cdf0e10cSrcweir     if( mpClipRegion && !XEmptyRegion( mpClipRegion ) )
890cdf0e10cSrcweir         rPeer.SetPictureClipRegion( aDstPic, mpClipRegion );
891cdf0e10cSrcweir 
892cdf0e10cSrcweir     // paint source * mask over destination picture
893cdf0e10cSrcweir     rPeer.CompositePicture( PictOpOver, aSrcPic, aAlphaPic, aDstPic,
894cdf0e10cSrcweir         rTR.mnSrcX, rTR.mnSrcY, 0, 0,
895cdf0e10cSrcweir         rTR.mnDestX, rTR.mnDestY, rTR.mnDestWidth, rTR.mnDestHeight );
896cdf0e10cSrcweir 
897cdf0e10cSrcweir     // TODO: used ScopedPic
898cdf0e10cSrcweir     rPeer.FreePicture( aAlphaPic );
899cdf0e10cSrcweir     XFreePixmap(pXDisplay, aAlphaPM);
900cdf0e10cSrcweir     rPeer.FreePicture( aSrcPic );
901cdf0e10cSrcweir     return true;
902cdf0e10cSrcweir }
903cdf0e10cSrcweir 
904cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
drawTransformedBitmap(const basegfx::B2DPoint & rNull,const basegfx::B2DPoint & rX,const basegfx::B2DPoint & rY,const SalBitmap & rSourceBitmap,const SalBitmap * pAlphaBitmap)905*5f27b83cSArmin Le Grand bool X11SalGraphics::drawTransformedBitmap(
906*5f27b83cSArmin Le Grand     const basegfx::B2DPoint& rNull,
907*5f27b83cSArmin Le Grand     const basegfx::B2DPoint& rX,
908*5f27b83cSArmin Le Grand     const basegfx::B2DPoint& rY,
909*5f27b83cSArmin Le Grand     const SalBitmap& rSourceBitmap,
910*5f27b83cSArmin Le Grand     const SalBitmap* pAlphaBitmap)
911*5f27b83cSArmin Le Grand {
912*5f27b83cSArmin Le Grand     // here direct support for transformed bitmaps can be impemented
913*5f27b83cSArmin Le Grand     (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap;
914*5f27b83cSArmin Le Grand     return false;
915*5f27b83cSArmin Le Grand }
916*5f27b83cSArmin Le Grand 
917*5f27b83cSArmin Le Grand // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
drawAlphaRect(long nX,long nY,long nWidth,long nHeight,sal_uInt8 nTransparency)918cdf0e10cSrcweir bool X11SalGraphics::drawAlphaRect( long nX, long nY, long nWidth,
919cdf0e10cSrcweir                                     long nHeight, sal_uInt8 nTransparency )
920cdf0e10cSrcweir {
921cdf0e10cSrcweir     if( ! m_pFrame && ! m_pVDev )
922cdf0e10cSrcweir         return false;
923cdf0e10cSrcweir 
924cdf0e10cSrcweir     if( bPenGC_ || !bBrushGC_ || bXORMode_ )
925cdf0e10cSrcweir         return false; // can only perform solid fills without XOR.
926cdf0e10cSrcweir 
927cdf0e10cSrcweir     if( m_pVDev && m_pVDev->GetDepth() < 8 )
928cdf0e10cSrcweir         return false;
929cdf0e10cSrcweir 
930cdf0e10cSrcweir     XRenderPeer& rPeer = XRenderPeer::GetInstance();
931cdf0e10cSrcweir     if( rPeer.GetVersion() < 0x02 ) // TODO: replace with better test
932cdf0e10cSrcweir         return false;
933cdf0e10cSrcweir 
934cdf0e10cSrcweir     Picture aDstPic = GetXRenderPicture();
935cdf0e10cSrcweir     if( !aDstPic )
936cdf0e10cSrcweir         return false;
937cdf0e10cSrcweir 
938cdf0e10cSrcweir 	const double fTransparency = (100 - nTransparency) * (1.0/100);
939cdf0e10cSrcweir 	const XRenderColor aRenderColor = GetXRenderColor( nBrushColor_ , fTransparency);
940cdf0e10cSrcweir 
941cdf0e10cSrcweir     rPeer.FillRectangle( PictOpOver,
942cdf0e10cSrcweir                          aDstPic,
943cdf0e10cSrcweir                          &aRenderColor,
944cdf0e10cSrcweir                          nX, nY,
945cdf0e10cSrcweir                          nWidth, nHeight );
946cdf0e10cSrcweir 
947cdf0e10cSrcweir     return true;
948cdf0e10cSrcweir }
949cdf0e10cSrcweir 
950cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
drawBitmap(const SalTwoRect &,const SalBitmap &,SalColor)951*5f27b83cSArmin Le Grand void X11SalGraphics::drawBitmap( const SalTwoRect&,
952cdf0e10cSrcweir                                  const SalBitmap&,
953cdf0e10cSrcweir                                  SalColor )
954cdf0e10cSrcweir {
955cdf0e10cSrcweir     DBG_ERROR( "::DrawBitmap with transparent color not supported" );
956cdf0e10cSrcweir }
957cdf0e10cSrcweir 
958cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
drawMask(const SalTwoRect & rPosAry,const SalBitmap & rSalBitmap,SalColor nMaskColor)959*5f27b83cSArmin Le Grand void X11SalGraphics::drawMask( const SalTwoRect& rPosAry,
960cdf0e10cSrcweir                                const SalBitmap &rSalBitmap,
961cdf0e10cSrcweir                                SalColor nMaskColor )
962cdf0e10cSrcweir {
963cdf0e10cSrcweir     const SalDisplay*   pSalDisp = GetDisplay();
964cdf0e10cSrcweir     Display*	        pXDisp = pSalDisp->GetDisplay();
965cdf0e10cSrcweir     Drawable            aDrawable( GetDrawable() );
966cdf0e10cSrcweir     Pixmap              aStipple( XCreatePixmap( pXDisp, aDrawable,
967*5f27b83cSArmin Le Grand                                                  rPosAry.mnDestWidth,
968*5f27b83cSArmin Le Grand                                                  rPosAry.mnDestHeight, 1 ) );
969cdf0e10cSrcweir 
970cdf0e10cSrcweir     if( aStipple )
971cdf0e10cSrcweir     {
972*5f27b83cSArmin Le Grand         SalTwoRect	aTwoRect( rPosAry ); aTwoRect.mnDestX = aTwoRect.mnDestY = 0;
973cdf0e10cSrcweir         GC			aTmpGC;
974cdf0e10cSrcweir         XGCValues	aValues;
975cdf0e10cSrcweir 
976cdf0e10cSrcweir         // create a stipple bitmap first (set bits are changed to unset bits and vice versa)
977cdf0e10cSrcweir         aValues.function = GXcopyInverted;
978cdf0e10cSrcweir         aValues.foreground = 1, aValues.background = 0;
979cdf0e10cSrcweir         aTmpGC = XCreateGC( pXDisp, aStipple, GCFunction | GCForeground | GCBackground, &aValues );
980cdf0e10cSrcweir         static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aStipple, m_nScreen, 1, aTwoRect, aTmpGC );
981cdf0e10cSrcweir 
982cdf0e10cSrcweir         XFreeGC( pXDisp, aTmpGC );
983cdf0e10cSrcweir 
984cdf0e10cSrcweir         // Set stipple and draw rectangle
985cdf0e10cSrcweir         GC	aStippleGC( GetStippleGC() );
986*5f27b83cSArmin Le Grand         int	nX = rPosAry.mnDestX, nY = rPosAry.mnDestY;
987cdf0e10cSrcweir 
988cdf0e10cSrcweir         XSetStipple( pXDisp, aStippleGC, aStipple );
989cdf0e10cSrcweir         XSetTSOrigin( pXDisp, aStippleGC, nX, nY );
990cdf0e10cSrcweir         XSetForeground( pXDisp, aStippleGC, GetPixel( nMaskColor ) );
991cdf0e10cSrcweir         XFillRectangle( pXDisp, aDrawable, aStippleGC,
992cdf0e10cSrcweir                         nX, nY,
993*5f27b83cSArmin Le Grand                         rPosAry.mnDestWidth, rPosAry.mnDestHeight );
994cdf0e10cSrcweir         XFreePixmap( pXDisp, aStipple );
995cdf0e10cSrcweir         XFlush( pXDisp );
996cdf0e10cSrcweir     }
997cdf0e10cSrcweir     else
998*5f27b83cSArmin Le Grand         drawBitmap( rPosAry, rSalBitmap );
999cdf0e10cSrcweir }
1000cdf0e10cSrcweir 
1001cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
getBitmap(long nX,long nY,long nDX,long nDY)1002cdf0e10cSrcweir SalBitmap *X11SalGraphics::getBitmap( long nX, long nY, long nDX, long nDY )
1003cdf0e10cSrcweir {
1004cdf0e10cSrcweir     if( bPrinter_ && !bVirDev_ )
1005cdf0e10cSrcweir         return NULL;
1006cdf0e10cSrcweir 
1007cdf0e10cSrcweir     bool bFakeWindowBG = false;
1008cdf0e10cSrcweir 
1009cdf0e10cSrcweir     // normalize
1010cdf0e10cSrcweir     if( nDX < 0 )
1011cdf0e10cSrcweir     {
1012cdf0e10cSrcweir         nX += nDX;
1013cdf0e10cSrcweir         nDX = -nDX;
1014cdf0e10cSrcweir     }
1015cdf0e10cSrcweir     if ( nDY < 0 )
1016cdf0e10cSrcweir     {
1017cdf0e10cSrcweir         nY += nDY;
1018cdf0e10cSrcweir         nDY = -nDY;
1019cdf0e10cSrcweir     }
1020cdf0e10cSrcweir 
1021cdf0e10cSrcweir     if( bWindow_ && !bVirDev_ )
1022cdf0e10cSrcweir     {
1023cdf0e10cSrcweir         XWindowAttributes aAttrib;
1024cdf0e10cSrcweir 
1025cdf0e10cSrcweir         XGetWindowAttributes( GetXDisplay(), GetDrawable(), &aAttrib );
1026cdf0e10cSrcweir         if( aAttrib.map_state != IsViewable )
1027cdf0e10cSrcweir             bFakeWindowBG = true;
1028cdf0e10cSrcweir         else
1029cdf0e10cSrcweir         {
1030cdf0e10cSrcweir             long nOrgDX = nDX, nOrgDY = nDY;
1031cdf0e10cSrcweir 
1032cdf0e10cSrcweir             // clip to window size
1033cdf0e10cSrcweir             if ( nX < 0 )
1034cdf0e10cSrcweir             {
1035cdf0e10cSrcweir                 nDX += nX;
1036cdf0e10cSrcweir                 nX   = 0;
1037cdf0e10cSrcweir             }
1038cdf0e10cSrcweir             if ( nY < 0 )
1039cdf0e10cSrcweir             {
1040cdf0e10cSrcweir                 nDY += nY;
1041cdf0e10cSrcweir                 nY   = 0;
1042cdf0e10cSrcweir             }
1043cdf0e10cSrcweir             if( nX + nDX > aAttrib.width )
1044cdf0e10cSrcweir                 nDX = aAttrib.width  - nX;
1045cdf0e10cSrcweir             if( nY + nDY > aAttrib.height )
1046cdf0e10cSrcweir                 nDY = aAttrib.height - nY;
1047cdf0e10cSrcweir 
1048cdf0e10cSrcweir             // inside ?
1049cdf0e10cSrcweir             if( nDX <= 0 || nDY <= 0 )
1050cdf0e10cSrcweir             {
1051cdf0e10cSrcweir                 bFakeWindowBG = true;
1052cdf0e10cSrcweir                 nDX = nOrgDX;
1053cdf0e10cSrcweir                 nDY = nOrgDY;
1054cdf0e10cSrcweir             }
1055cdf0e10cSrcweir         }
1056cdf0e10cSrcweir     }
1057cdf0e10cSrcweir 
1058cdf0e10cSrcweir     X11SalBitmap*	pSalBitmap = new X11SalBitmap;
1059cdf0e10cSrcweir     sal_uInt16			nBitCount = GetBitCount();
1060cdf0e10cSrcweir 
1061cdf0e10cSrcweir     if( &GetDisplay()->GetColormap( m_nScreen ) != &GetColormap() )
1062cdf0e10cSrcweir         nBitCount = 1;
1063cdf0e10cSrcweir 
1064cdf0e10cSrcweir     if( ! bFakeWindowBG )
1065cdf0e10cSrcweir         pSalBitmap->ImplCreateFromDrawable( GetDrawable(), m_nScreen, nBitCount, nX, nY, nDX, nDY );
1066cdf0e10cSrcweir     else
1067cdf0e10cSrcweir         pSalBitmap->Create( Size( nDX, nDY ), (nBitCount > 8) ? 24 : nBitCount, BitmapPalette( nBitCount > 8 ? nBitCount : 0 ) );
1068cdf0e10cSrcweir 
1069cdf0e10cSrcweir     return pSalBitmap;
1070cdf0e10cSrcweir }
1071cdf0e10cSrcweir 
1072cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
getPixel(long nX,long nY)1073cdf0e10cSrcweir SalColor X11SalGraphics::getPixel( long nX, long nY )
1074cdf0e10cSrcweir {
1075cdf0e10cSrcweir     if( bWindow_ && !bVirDev_ )
1076cdf0e10cSrcweir     {
1077cdf0e10cSrcweir         XWindowAttributes aAttrib;
1078cdf0e10cSrcweir 
1079cdf0e10cSrcweir         XGetWindowAttributes( GetXDisplay(), GetDrawable(), &aAttrib );
1080cdf0e10cSrcweir         if( aAttrib.map_state != IsViewable )
1081cdf0e10cSrcweir         {
1082cdf0e10cSrcweir             stderr0( "X11SalGraphics::GetPixel drawable not viewable\n" );
1083cdf0e10cSrcweir             return 0;
1084cdf0e10cSrcweir         }
1085cdf0e10cSrcweir     }
1086cdf0e10cSrcweir 
1087cdf0e10cSrcweir     XImage *pXImage = XGetImage( GetXDisplay(),
1088cdf0e10cSrcweir                                      GetDrawable(),
1089cdf0e10cSrcweir                                  nX, nY,
1090cdf0e10cSrcweir                                  1,  1,
1091cdf0e10cSrcweir                                  AllPlanes,
1092cdf0e10cSrcweir                                  ZPixmap );
1093cdf0e10cSrcweir     if( !pXImage )
1094cdf0e10cSrcweir     {
1095cdf0e10cSrcweir         stderr0( "X11SalGraphics::GetPixel !XGetImage()\n" );
1096cdf0e10cSrcweir         return 0;
1097cdf0e10cSrcweir     }
1098cdf0e10cSrcweir 
1099cdf0e10cSrcweir     XColor aXColor;
1100cdf0e10cSrcweir 
1101cdf0e10cSrcweir     aXColor.pixel = XGetPixel( pXImage, 0, 0 );
1102cdf0e10cSrcweir     XDestroyImage( pXImage );
1103cdf0e10cSrcweir 
1104cdf0e10cSrcweir     return GetColormap().GetColor( aXColor.pixel );
1105cdf0e10cSrcweir }
1106cdf0e10cSrcweir 
1107cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
invert(long nX,long nY,long nDX,long nDY,SalInvert nFlags)1108cdf0e10cSrcweir void X11SalGraphics::invert( long		nX,
1109cdf0e10cSrcweir 								long		nY,
1110cdf0e10cSrcweir 								long		nDX,
1111cdf0e10cSrcweir 								long		nDY,
1112cdf0e10cSrcweir 								SalInvert	nFlags )
1113cdf0e10cSrcweir {
1114cdf0e10cSrcweir     GC pGC;
1115cdf0e10cSrcweir     if( SAL_INVERT_50 & nFlags )
1116cdf0e10cSrcweir     {
1117cdf0e10cSrcweir         pGC = GetInvert50GC();
1118cdf0e10cSrcweir         XFillRectangle( GetXDisplay(), GetDrawable(), pGC, nX, nY, nDX, nDY );
1119cdf0e10cSrcweir     }
1120cdf0e10cSrcweir     else
1121cdf0e10cSrcweir     {
1122cdf0e10cSrcweir         if ( SAL_INVERT_TRACKFRAME & nFlags )
1123cdf0e10cSrcweir         {
1124cdf0e10cSrcweir             pGC = GetTrackingGC();
1125cdf0e10cSrcweir             XDrawRectangle( GetXDisplay(), GetDrawable(),  pGC, nX, nY, nDX, nDY );
1126cdf0e10cSrcweir         }
1127cdf0e10cSrcweir         else
1128cdf0e10cSrcweir         {
1129cdf0e10cSrcweir             pGC = GetInvertGC();
1130cdf0e10cSrcweir             XFillRectangle( GetXDisplay(), GetDrawable(),  pGC, nX, nY, nDX, nDY );
1131cdf0e10cSrcweir         }
1132cdf0e10cSrcweir     }
1133cdf0e10cSrcweir }
1134cdf0e10cSrcweir 
supportsOperation(OutDevSupportType eType) const1135cdf0e10cSrcweir bool X11SalGraphics::supportsOperation( OutDevSupportType eType ) const
1136cdf0e10cSrcweir {
1137cdf0e10cSrcweir     bool bRet = false;
1138cdf0e10cSrcweir     switch( eType )
1139cdf0e10cSrcweir     {
1140cdf0e10cSrcweir     case OutDevSupport_TransparentRect:
1141cdf0e10cSrcweir     case OutDevSupport_B2DDraw:
1142cdf0e10cSrcweir         {
1143cdf0e10cSrcweir             XRenderPeer& rPeer = XRenderPeer::GetInstance();
1144cdf0e10cSrcweir             if( rPeer.GetVersion() >= 0x02 )
1145cdf0e10cSrcweir             {
1146cdf0e10cSrcweir                 const SalDisplay* pSalDisp = GetDisplay();
1147cdf0e10cSrcweir                 const SalVisual& rSalVis = pSalDisp->GetVisual( m_nScreen );
1148cdf0e10cSrcweir 
1149cdf0e10cSrcweir                 Visual* pDstXVisual = rSalVis.GetVisual();
1150cdf0e10cSrcweir                 XRenderPictFormat* pDstVisFmt = rPeer.FindVisualFormat( pDstXVisual );
1151cdf0e10cSrcweir                 if( pDstVisFmt )
1152cdf0e10cSrcweir                     bRet = true;
1153cdf0e10cSrcweir             }
1154cdf0e10cSrcweir         }
1155cdf0e10cSrcweir         break;
1156cdf0e10cSrcweir     default: break;
1157cdf0e10cSrcweir     }
1158cdf0e10cSrcweir     return bRet;
1159cdf0e10cSrcweir }
1160cdf0e10cSrcweir 
1161