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