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